forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 11
Readme Update #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…string Note:destructors not handled yet
…string Note:destructors not handled yet
For now have ignored the case of posting a message to main run loop. So it isn't doing much yet.
Who wants to use fork/exec when we have much nicer native APIs?
We need a MIME signature so the roster can find it.
- Added a message handler to look out for incoming messages to runloop - Created new aux support so we can attach all handlers to the main apps looper - Added a message stashing feature so it stashes the messages and interprets them when the loop is ready to run - used maps to store loopers and BApplications to forward message to appropriate loopers - Created a message from ui process to network process that notifies the pid of webprocess - Added NetworkSession so it doesnt crash
- Some fixes for ANGLE but keep it disabled (we don't need it) - Fix various minor things in Haiku specific files - A bit more cleanup of include files and forwarding headers management
1)This makes few important changes in adding the view 2)Partial mouse events which is kept aside now as main focus is put on webpage rendering
1) Few callbacks for finished loading and forward and backward stop etc is now fully functional 2) status text is partially done 3)shared memory done with mapping part pending(i need to understand a little bit more)
Fix various include path, do not include ANGLE headers when not needed. Some headers are added to the forwarding headers that probably shouldn't need to be there (date time chooser stuff, and not sure about image and image buffer). But it gets things working at least and it's more clean than what we had before.
1) removed unwanted comments 2) removed unwanted methods
1) Loading, changing title and adding redirected url are added to minibrowser 2) Get data and run on main thread - fixes network process run on main thread problem
1) Put widgets in window thread 2) webkit events on main thread
2) Shareable Bitmap to get data and initialize a bitmap 3) Added few drawing mechanisms to webview 4) Backing store update Coordinated graphics was briefly enabled here, but it is not needed and it breaks WebKitLegacy, so for now we keep it off.
1) Loading, changing title and adding redirected url are added to minibrowser 2) Get data and run on main thread - fixes network process run on main thread problem
It breaks the build.
…iku [WIP] Do we need this or can we use the standard one?
Do we still need this? Or can we make this work normally
Still fails to link because somehow WTF is not added to the command line.
Not sure why the cross platform way to do it isn't working for us...
Not sure if useful or not. But it doesn't seem to break the build.
Make it more similar to other platforms.
-Replaced GCC8 with GCC11 -Added note for disabling ASLR if system runs out of memory
pulkomandy
pushed a commit
that referenced
this pull request
Jul 8, 2022
https://bugs.webkit.org/show_bug.cgi?id=241905 Reviewed by Yusuke Suzuki. offlineasm used to emit this LLInt code: ".loc 1 996\n" "ldr x19, [x0] \n" // LowLevelInterpreter.asm:996 ".loc 1 997\n" "ldr x20, [x0, #8] \n" // LowLevelInterpreter.asm:997 ".loc 1 998\n" "ldr x21, [x0, #16] \n" // LowLevelInterpreter.asm:998 ".loc 1 999\n" "ldr x22, [x0, #24] \n" // LowLevelInterpreter.asm:999 ... ".loc 1 1006\n" "ldr d8, [x0, WebKit#80] \n" // LowLevelInterpreter.asm:1006 ".loc 1 1007\n" "ldr d9, [x0, WebKit#88] \n" // LowLevelInterpreter.asm:1007 ".loc 1 1008\n" "ldr d10, [x0, WebKit#96] \n" // LowLevelInterpreter.asm:1008 ".loc 1 1009\n" "ldr d11, [x0, WebKit#104] \n" // LowLevelInterpreter.asm:1009 ... Now, it can emit this instead: ".loc 1 996\n" "ldp x19, x20, [x0, #0] \n" // LowLevelInterpreter.asm:996 ".loc 1 997\n" "ldp x21, x22, [x0, #16] \n" // LowLevelInterpreter.asm:997 ... ".loc 1 1001\n" "ldp d8, d9, [x0, WebKit#80] \n" // LowLevelInterpreter.asm:1001 ".loc 1 1002\n" "ldp d10, d11, [x0, WebKit#96] \n" // LowLevelInterpreter.asm:1002 ... Also, there was some code that kept recomputing the base address of a sequence of load/store instructions. For example, ".loc 6 902\n" "add x13, sp, x10, lsl #3 \n" // WebAssembly.asm:902 "ldr x0, [x13, #48] \n" "add x13, sp, x10, lsl #3 \n" "ldr x1, [x13, #56] \n" "add x13, sp, x10, lsl #3 \n" "ldr x2, [x13, #64] \n" "add x13, sp, x10, lsl #3 \n" "ldr x3, [x13, WebKit#72] \n" ... For such places, we observe that the base address is the same for every load/store instruction in the sequence, and precompute it in the LLInt asm code to help out the offline asm. This allows the offlineasm to now emit this more efficient code instead: ".loc 6 896\n" "add x10, sp, x10, lsl #3 \n" // WebAssembly.asm:896 ".loc 6 898\n" "ldp x0, x1, [x10, #48] \n" // WebAssembly.asm:898 "ldp x2, x3, [x10, #64] \n" ... * Source/JavaScriptCore/llint/LowLevelInterpreter.asm: * Source/JavaScriptCore/llint/WebAssembly.asm: * Source/JavaScriptCore/offlineasm/arm64.rb: * Source/JavaScriptCore/offlineasm/instructions.rb: Canonical link: https://commits.webkit.org/251799@main
pulkomandy
pushed a commit
that referenced
this pull request
Nov 22, 2022
…a rejected promise https://bugs.webkit.org/show_bug.cgi?id=247785 rdar://102325201 Reviewed by Yusuke Suzuki. Rest parameter should be caught in async function. So, running this JavaScript program should print "caught". ``` async function f(...[[]]) { } f().catch(e => print("caught")); ``` V8 (used console.log) ``` $ node input.js caught ``` GraalJS ``` $ js input.js caught ``` https://tc39.es/ecma262/#sec-async-function-definitions ... AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } ... According to the spec, it indicates `FormalParameters` is used for Async Function, where `FormalParameters` can be converted to `FunctionRestParameter`. https://tc39.es/ecma262/#sec-parameter-lists ... FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] ... And based on RS: EvaluateAsyncFunctionBody, it will invoke the promise.reject callback function with abrupt value ([[value]] of non-normal completion record). https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncfunctionbody ... 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)). 3. If declResult is an abrupt completion, then a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »). ... In that case, any non-normal results of evaluating rest parameters should be caught and passed to the reject callback function. To resolve this problem, we should allow the emitted RestParameterNode be wrapped by the catch handler for promise. However, we should remove `m_restParameter` and emit rest parameter byte code in `initializeDefaultParameterValuesAndSetupFunctionScopeStack` if we can prove that change has no side effect. In that case, we can only use one exception handler. Current fix is to add another exception handler. And move the handler byte codes to the bottom of code block in order to make other byte codes as much compact as possible. Input: ``` async function f(arg0, ...[[]]) { } f(); ``` Dumped Byte Codes: ``` ... bb#2 Predecessors: [ #1 ] [ 20] mov dst:loc9, src:<JSValue()>(const0) ... bb#3 Predecessors: [ #2 ] [ 29] get_rest_length dst:loc11, numParametersToSkip:1 ... bb#12 Predecessors: [ #8 #9 #10 ] [ 138] new_func_exp dst:loc10, scope:loc4, functionDecl:0 ... bb#13 Predecessors: [ ] [ 170] catch exception:loc10, thrownValue:loc8 [ 174] jmp targetLabel:8(->182) Successors: [ #15 ] bb#14 Predecessors: [ #7 #11 ] [ 176] catch exception:loc10, thrownValue:loc8 [ 180] jmp targetLabel:2(->182) Successors: [ #15 ] bb#15 Predecessors: [ #13 #14 ] [ 182] mov dst:loc12, src:Undefined(const1) ... Exception Handlers: 1: { start: [ 20] end: [ 29] target: [ 170] } synthesized catch 2: { start: [ 29] end: [ 138] target: [ 176] } synthesized catch ``` * JSTests/stress/catch-rest-parameter.js: Added. (throwError): (shouldThrow): (async f): (throwError.async f): (throwError.async let): (async let): (x.async f): (x): (async shouldThrow): * Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): (JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack): * Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h: Canonical link: https://commits.webkit.org/256864@main
pulkomandy
pushed a commit
that referenced
this pull request
Mar 5, 2023
https://bugs.webkit.org/show_bug.cgi?id=251063 rdar://104585575 Reviewed by Mark Lam and Justin Michaud. This patch enhances CallFrame::dump to support wasm frames in btjs stacktrace. The example is as follows. frame #0: 0x00000001035fca78 JavaScriptCore`JSC::functionBreakpoint(globalObject=0x000000012f410068, callFrame=0x000000016fdfa9d0) at JSDollarVM.cpp:2273:9 [opt] frame #1: 0x000000010ec44204 0x10eccc5dc frame #2: 0x000000010eccc5dc callback#Dwaxn6 [Baseline bc#50](Undefined) frame #3: 0x000000010ec4ca84 wasm-stub [WasmToJS](Wasm::Instance: 0x10d29da40) frame #4: 0x000000010ed0c060 <?>.wasm-function[1] [OMG](Wasm::Instance: 0x10d29da40) frame #5: 0x000000010ed100d0 jsToWasm#CWTx6k [FTL bc#22](Cell[JSModuleEnvironment]: 0x12f524540, Cell[WebAssemblyFunction]: 0x10d06a3a8, 1, 2, 3) frame #6: 0x000000010ec881b0 #D5ymZE [Baseline bc#733](Undefined, Cell[Generator]: 0x12f55c180, 1, Cell[Object]: 0x12f69dfc0, 0, Cell[JSLexicalEnvironment]: 0x12f52cee0) frame #7: 0x000000010ec3c008 asyncFunctionResume#A4ayYg [LLInt bc#49](Undefined, Cell[Generator]: 0x12f55c180, Cell[Object]: 0x12f69dfc0, 0) frame #8: 0x000000010ec3c008 promiseReactionJobWithoutPromise#D0yDF1 [LLInt bc#25](Undefined, Cell[Function]: 0x12f44f3c0, Cell[Object]: 0x12f69dfc0, Cell[Generator]: 0x12f55c180) frame #9: 0x000000010ec80ec0 promiseReactionJob#EdShZz [Baseline bc#74](Undefined, Undefined, Cell[Function]: 0x12f44f3c0, Cell[Object]: 0x12f69dfc0, Cell[Generator]: 0x12f55c180) frame #10: 0x000000010ec3c728 frame #11: 0x0000000103137560 JavaScriptCore`JSC::Interpreter::executeCall(JSC::JSGlobalObject*, JSC::JSObject*, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) [inlined] JSC::JITCode::execute(this=<unavailable>, vm=<unavailable>, protoCallFrame=<unavailable>) at JITCodeInlines.h:42:38 [opt] frame #12: 0x0000000103137524 JavaScriptCore`JSC::Interpreter::executeCall(this=<unavailable>, lexicalGlobalObject=<unavailable>, function=<unavailable>, callData=<unavailable>, thisValue=<unavailable>, args=<unavailable>) at Interpreter.cpp:1093:27 [opt] frame #13: 0x000000010349d6d0 JavaScriptCore`JSC::runJSMicrotask(globalObject=0x000000012f410068, identifier=(m_identifier = 81), job=JSValue @ x22, argument0=JSValue @ x26, argument1=JSValue @ x25, argument2=<unavailable>, argument3=<unavailable>) at JSMicrotask.cpp:98:9 [opt] frame #14: 0x00000001039dfc54 JavaScriptCore`JSC::VM::drainMicrotasks() (.cold.1) at VM.cpp:0:9 [opt] frame #15: 0x00000001035e58a4 JavaScriptCore`JSC::VM::drainMicrotasks() [inlined] JSC::MicrotaskQueue::dequeue(this=<unavailable>) at VM.cpp:0:9 [opt] frame #16: 0x00000001035e5894 JavaScriptCore`JSC::VM::drainMicrotasks(this=0x000000012f000000) at VM.cpp:1255:46 [opt] ... * Source/JavaScriptCore/interpreter/CallFrame.cpp: (JSC::CallFrame::dump const): Canonical link: https://commits.webkit.org/259262@main
pulkomandy
pushed a commit
that referenced
this pull request
Jan 12, 2025
https://bugs.webkit.org/show_bug.cgi?id=281902 rdar://136486349 Reviewed by Mike Wyrzykowski. Metal: Ensure potentially infinite loops have defined behavior The MSL compiler would omit infinite loops and assume number domains based on the omission logic. This would induce incorrect number domains in case the infinite loops would be invokable. Infinite loops are undefined in C++ and thus in MSL. It is the job of the programmer to ensure undefined behavior cannot happen. Consider GLSL loop like: uniform float i; ... if (i != 0.5) for(;;) { } gl_FragColor = vec4(i); Historically this would emit MSL loop in spirit of: if (i != 0.5) { bool c = true; while (c) { } } ANGLE_fragmentOut.gl_FragColor = metal::float4(i, i, i, i); Since This could cause the MSL compiler to optimize the function to equivalent of: ANGLE_fragmentOut.gl_FragColor = metal::float4(0.5, 0.5, 0.5, 0.5); Presumably this loop omission would happen at the clang frontend part. Before, was worked around by emitting asm statements to the MSL: bool c = true; while (c) { __asm__(""); } The asm injection would would work for this particular source pattern, presumably because injecting the asm would avoid the loop omission at the clang frontend part. The MSL/C++ code is still UB, though. The asm statement does not cause anything that C++ would consider as "forward progress" of the loop. The success was just due to how the backend worked. The bitcode produced would be similar to: 4: tail call void asm sideeffect "", ""() #6, !srcloc !28 br label %4, !llvm.loop !29 Here, the compiler can be seen to simply fail to detect a loop that does not make forward progress. Considering GLSL of form: uniform int f; ... for (;;) { if (f <= 1) break; } With asm injection to the loop, this would produce: 5: tail call void asm sideeffect "", ""() #8, !srcloc !29 %6 = load i32, i32 addrspace(2)* %4, align 4, !tbaa !30 %7 = icmp slt i32 %6, 2 br i1 %7, label %8, label %5 8: This code is still assumed to make progress. The backend optimizer is free to assume that the condition holds, since the load to break the loop is from constant address space. I.e. uniform f does not change its value during the loop. Instead of injecting asm, inject a read of unused volatile variable. The volatile variable access is defined in C++ as forward progress. This means infinite loop containing such read is considered defined. To simplify the implementation and to avoid volatile writes, the read is to a dummy variable instead of the loop condition bool. The tests here do not pass completely for MSL backend. In case the compiler would omit the infinite loop (unpatched code), they would fail with demonstration of how the values behave. After fixing, the loops cause timeout but Metal backend does not have implementation to report context loss. Also, the ReadPixels is just for demostration purposes of the unpatched code. * Source/ThirdParty/ANGLE/src/compiler/translator/msl/EmitMetal.cpp: (GenMetalTraverser::GenMetalTraverser): (GenMetalTraverser::emitLoopBody): (GenMetalTraverser::emitForwardProgressStore): (GenMetalTraverser::emitForwardProgressSignal): (GenMetalTraverser::visitForLoop): (GenMetalTraverser::visitWhileLoop): (GenMetalTraverser::visitDoWhileLoop): * Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni: * Source/ThirdParty/ANGLE/src/tests/gl_tests/TimeoutDrawTest.cpp: Added. (angle::TimeoutDrawTest::TimeoutDrawTest): (angle::TEST_P): Originally-landed-as: 283286.350@safari-7620-branch (b82d94e). rdar://141318430 Canonical link: https://commits.webkit.org/288020@main
pulkomandy
pushed a commit
that referenced
this pull request
Feb 22, 2025
https://bugs.webkit.org/show_bug.cgi?id=288102 rdar://145222010 Reviewed by Yusuke Suzuki. Added the notion of a string list to a parsed RegExp that is in the form of /^(?:break|case|which|do|for)/ with an optional trailing $. Such a RegExp will not backtrack and therefore we can streamline the code we emit for such a pattern. This change involves recognizing beginning of string anchored alternations of strings while parsing and then treating the generation of JIT code differently for these patterns. This includes changing how conditional branching works, specifically that instead of the "fall through on match" for each term, to a "jump on match" for the whole alternation. The current code generated for the "case" elternative is: 8:Term PatternCharacter checked-offset:(3) 'c' <156> 0x11381430c: add w1, w1, #2 <160> 0x113814310: cmp w1, w2 <164> 0x113814314: b.hi 0x113814444 -> <468> 10:Term PatternCharacter checked-offset:(4) 'c' <168> 0x113814318: sub x17, x0, #4 <172> 0x11381431c: ldr w17, [x17, x1] <176> 0x113814320: movz w16, #0x6163 <180> 0x113814324: movk w16, #0x6573, lsl #16 -> 0x65736163 <184> 0x113814328: cmp w17, w16 <188> 0x11381432c: b.ne 0x113814444 -> <468> 11:Term PatternCharacter checked-offset:(4) 'a' already handled 12:Term PatternCharacter checked-offset:(4) 's' already handled 13:Term PatternCharacter checked-offset:(4) 'e' already handled 14:NestedAlternativeNext minimum-size:(5),checked-offset:(5) <192> 0x113814330: movz x16, #0x4444 <196> 0x113814334: movk x16, #0x1381, lsl #16 <200> 0x113814338: movk x16, #0x8001, lsl #32 <204> 0x11381433c: movk x16, #0xc973, lsl #48 -> 0x113814444 JIT PC <208> 0x113814340: stur x16, [sp, #8] <212> 0x113814344: b 0x113814404 -> <404> With some additional backtracking code: 9:NestedAlternativeNext minimum-size:(4),checked-offset:(4) <468> 0x113814444: sub w1, w1, #2 <472> 0x113814448: b 0x113814348 -> <216> With this change, the processing of "case" becomes: 9:StringListAlternativeNext minimum-size:(4),checked-offset:(4) <132> 0x12a8285c4: sub w1, w1, #1 <136> 0x12a8285c8: cmp w1, w2 <140> 0x12a8285cc: b.hi 0x12a8285e8 -> <168> 10:Term PatternCharacter checked-offset:(4) 'c' <144> 0x12a8285d0: sub x17, x0, #4 <148> 0x12a8285d4: ldr w17, [x17, x1] <152> 0x12a8285d8: movz w16, #0x6163 <156> 0x12a8285dc: movk w16, #0x6573, lsl #16 -> 0x65736163 <160> 0x12a8285e0: cmp w17, w16 <164> 0x12a8285e4: b.eq 0x12a82866c -> <300> 11:Term PatternCharacter checked-offset:(4) 'a' already handled 12:Term PatternCharacter checked-offset:(4) 's' already handled 13:Term PatternCharacter checked-offset:(4) 'e' already handled 14:StringListAlternativeNext minimum-size:(5),checked-offset:(5) With no backtracking code. We are able to eliminate one branch and the saving of the continuation PC for backtracking. The code size to process these string list RegExp is reduces. For the example RegExp above, the prior version created 1940 bytes (485 instructions) of code while the code created with this 1392 bytes (345 instructions) of code, a nearly 30% reduction in code. This change is a ~18% progression on the new regexp-keyword-parsing microbenchmark: Baseline YarrStringList regexp-keyword-parsing 136.7065+-0.9807 ^ 116.0161+-1.1791 ^ definitely 1.1783x faster <geometric> 136.7065+-0.9807 ^ 116.0161+-1.1791 ^ definitely 1.1783x faster * JSTests/microbenchmarks/regexp-keyword-parsing.js: Added. (arrayToString): (objectToString): (dumpValue): (compareArray): (compareGroups): (testRegExp): (testRegExpSyntaxError): (let.re.break.case.catch.continue.debugger.default.else.finally.if): (let.re1.break.case.catch.continue.debugger.default.else.finally.if): * JSTests/stress/regexp-parsing-tokens.js: Added. (arrayToString): (objectToString): (dumpValue): (compareArray): (compareGroups): (testRegExp): (testRegExpSyntaxError): * Source/JavaScriptCore/yarr/YarrJIT.cpp: * Source/JavaScriptCore/yarr/YarrPattern.cpp: (JSC::Yarr::YarrPatternConstructor::atomParenthesesEnd): (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses): (JSC::Yarr::PatternAlternative::dump): (JSC::Yarr::PatternTerm::dump): * Source/JavaScriptCore/yarr/YarrPattern.h: (JSC::Yarr::PatternTerm::PatternTerm): (JSC::Yarr::PatternAlternative::PatternAlternative): Canonical link: https://commits.webkit.org/290791@main
pulkomandy
pushed a commit
that referenced
this pull request
Mar 15, 2025
https://bugs.webkit.org/show_bug.cgi?id=288102 rdar://145222010 Reviewed by Yusuke Suzuki. Added the notion of a string list to a parsed RegExp that is in the form of /^(?:break|case|which|do|for)/ with an optional trailing $. Such a RegExp will not backtrack and therefore we can streamline the code we emit for such a pattern. This change involves recognizing beginning of string anchored alternations of strings while parsing and then treating the generation of JIT code differently for these patterns. This includes changing how conditional branching works, specifically that instead of the "fall through on match" for each term, to a "jump on match" for the whole alternation. Fixed a bug in the original version where we weren't properly checking the nested alternatives to see if they only contain fixed single count PatternCharacter terms. The current code generated for the "case" elternative is: 8:Term PatternCharacter checked-offset:(3) 'c' <156> 0x11381430c: add w1, w1, #2 <160> 0x113814310: cmp w1, w2 <164> 0x113814314: b.hi 0x113814444 -> <468> 10:Term PatternCharacter checked-offset:(4) 'c' <168> 0x113814318: sub x17, x0, #4 <172> 0x11381431c: ldr w17, [x17, x1] <176> 0x113814320: movz w16, #0x6163 <180> 0x113814324: movk w16, #0x6573, lsl #16 -> 0x65736163 <184> 0x113814328: cmp w17, w16 <188> 0x11381432c: b.ne 0x113814444 -> <468> 11:Term PatternCharacter checked-offset:(4) 'a' already handled 12:Term PatternCharacter checked-offset:(4) 's' already handled 13:Term PatternCharacter checked-offset:(4) 'e' already handled 14:NestedAlternativeNext minimum-size:(5),checked-offset:(5) <192> 0x113814330: movz x16, #0x4444 <196> 0x113814334: movk x16, #0x1381, lsl #16 <200> 0x113814338: movk x16, #0x8001, lsl #32 <204> 0x11381433c: movk x16, #0xc973, lsl #48 -> 0x113814444 JIT PC <208> 0x113814340: stur x16, [sp, #8] <212> 0x113814344: b 0x113814404 -> <404> With some additional backtracking code: 9:NestedAlternativeNext minimum-size:(4),checked-offset:(4) <468> 0x113814444: sub w1, w1, #2 <472> 0x113814448: b 0x113814348 -> <216> With this change, the processing of "case" becomes: 9:StringListAlternativeNext minimum-size:(4),checked-offset:(4) <132> 0x12a8285c4: sub w1, w1, #1 <136> 0x12a8285c8: cmp w1, w2 <140> 0x12a8285cc: b.hi 0x12a8285e8 -> <168> 10:Term PatternCharacter checked-offset:(4) 'c' <144> 0x12a8285d0: sub x17, x0, #4 <148> 0x12a8285d4: ldr w17, [x17, x1] <152> 0x12a8285d8: movz w16, #0x6163 <156> 0x12a8285dc: movk w16, #0x6573, lsl #16 -> 0x65736163 <160> 0x12a8285e0: cmp w17, w16 <164> 0x12a8285e4: b.eq 0x12a82866c -> <300> 11:Term PatternCharacter checked-offset:(4) 'a' already handled 12:Term PatternCharacter checked-offset:(4) 's' already handled 13:Term PatternCharacter checked-offset:(4) 'e' already handled 14:StringListAlternativeNext minimum-size:(5),checked-offset:(5) With no backtracking code. We are able to eliminate one branch and the saving of the continuation PC for backtracking. The code size to process these string list RegExp is reduces. For the example RegExp above, the prior version created 1940 bytes (485 instructions) of code while the code created with this 1392 bytes (345 instructions) of code, a nearly 30% reduction in code. This change is a ~18% progression on the new regexp-keyword-parsing microbenchmark: Baseline YarrStringList regexp-keyword-parsing 136.7065+-0.9807 ^ 116.0161+-1.1791 ^ definitely 1.1783x faster <geometric> 136.7065+-0.9807 ^ 116.0161+-1.1791 ^ definitely 1.1783x faster * JSTests/microbenchmarks/regexp-keyword-parsing.js: Added. (arrayToString): (objectToString): (dumpValue): (compareArray): (compareGroups): (testRegExp): (testRegExpSyntaxError): (let.re.break.case.catch.continue.debugger.default.else.finally.if): (let.re1.break.case.catch.continue.debugger.default.else.finally.if): * JSTests/stress/regexp-parsing-tokens.js: Added. (arrayToString): (objectToString): (dumpValue): (compareArray): (compareGroups): (testRegExp): (testRegExpSyntaxError): * Source/JavaScriptCore/yarr/YarrJIT.cpp: * Source/JavaScriptCore/yarr/YarrPattern.cpp: (JSC::Yarr::YarrPatternConstructor::atomParenthesesEnd): (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses): (JSC::Yarr::PatternAlternative::dump): (JSC::Yarr::PatternTerm::dump): * Source/JavaScriptCore/yarr/YarrPattern.h: (JSC::Yarr::PatternTerm::PatternTerm): (JSC::Yarr::PatternAlternative::PatternAlternative): Canonical link: https://commits.webkit.org/290982@main
pulkomandy
pushed a commit
that referenced
this pull request
Jun 20, 2025
https://bugs.webkit.org/show_bug.cgi?id=294344 rdar://153095450 Reviewed by Keith Miller. Relanding Keith's change with some fixes for x64. In x64, we cannot directly get label address, so instead of doing it, we store them into JSCConfig and load it. This patch hardens how IPInt dispatches opcodes for better CFI protection. Since IPInt does an offset based dispatch the previous dispatch was something like: ``` macro dispatchToNextIPIntInstruction() // x7 is set to _ipInt_instruction_base on entry to IPInt entry/call return. loadb [PC], x0 emit "add x0, x7, x0, lsl #8" emit "br x0" end align 256 _ipint_dispatch_base: .first_wasm_bytecode: // stuff dispatchToNextIPIntInstruction() align 256 .second_wasm_bytecode: // stuff dispatchToNextIPIntInstruction() ... align 256 .255_wasm_bytecode: // stuff dispatchToNextIPIntInstruction() ``` In the old system no matter what value [PC] points to there are 256 offsets reachable, all of which are either a valid opcode or a slab of `brk`s. However, this still means if an attacker is able to return to the IPInt interpreter on some path that doesn't reset x7 then they'll be able to implement a JOP attack. One example would be to build a fake object with a vtable pointing to one of the "C function" labels (e.g. _first_wasm_bytecode_validate, which is used for offset validation). After this change dispatch is now: ``` macro dispatchToNextIPIntInstruction() loadb something, x0 pcrtoaddr _ipint_dispatch_base, x7 emit "add x0, x7, x0, lsl #8" emit "br x0" end ``` which makes it clearly impossible to get a PAC bypass in IPInt dispatch. Since there's no longer a semi-pinned register with the base pointer this patch removes all that associated code. Additionally, this change adds a names for all the dispatch starts to make the code a bit easier to read. Lastly, the SIMD prefix opcode was missing a security guard so this patch adds that too. * Source/JavaScriptCore/llint/InPlaceInterpreter.asm: * Source/JavaScriptCore/llint/InPlaceInterpreter.cpp: (JSC::IPInt::initialize): * Source/JavaScriptCore/llint/InPlaceInterpreter.h: * Source/JavaScriptCore/llint/InPlaceInterpreter32_64.asm: * Source/JavaScriptCore/llint/InPlaceInterpreter64.asm: * Source/JavaScriptCore/llint/LowLevelInterpreter.asm: * Source/JavaScriptCore/runtime/JSCConfig.h: Canonical link: https://commits.webkit.org/296121@main
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.