Skip to content

Commit 6e24711

Browse files
committed
Web Inspector: Debugger: symbolic breakpoints should work with intrinsic functions
https://bugs.webkit.org/show_bug.cgi?id=243994 <rdar://problem/99037335> Reviewed by Yusuke Suzuki. This should bring symbolic breakpoint "coverage" up even higher, possibly even to 100%. * Source/JavaScriptCore/jit/ThunkGenerator.h: * Source/JavaScriptCore/jit/ThunkGenerators.h: * Source/JavaScriptCore/jit/ThunkGenerators.cpp: (JSC::handleExceptionGenerator): (JSC::handleExceptionWithCallFrameRollbackGenerator): (JSC::popThunkStackPreservesAndHandleExceptionGenerator): (JSC::checkExceptionGenerator): (JSC::throwExceptionFromCallSlowPathGenerator): (JSC::linkCallThunkGenerator): (JSC::linkPolymorphicCallThunkGenerator): (JSC::virtualThunkFor): (JSC::virtualThunkForRegularCall): (JSC::virtualThunkForTailCall): (JSC::virtualThunkForConstructConstruct): (JSC::nativeForGenerator): (JSC::nativeCallGenerator): (JSC::nativeTailCallGenerator): (JSC::nativeTailCallWithoutSavedTagsGenerator): (JSC::nativeConstructGenerator): (JSC::internalFunctionCallGenerator): (JSC::internalFunctionConstructGenerator): (JSC::arityFixupGenerator): (JSC::unreachableGenerator): (JSC::stringGetByValGenerator): (JSC::charCodeAtThunkGenerator): (JSC::charAtThunkGenerator): (JSC::fromCharCodeThunkGenerator): (JSC::stringPrototypeCodePointAtThunkGenerator): (JSC::clz32ThunkGenerator): (JSC::sqrtThunkGenerator): (JSC::floorThunkGenerator): (JSC::ceilThunkGenerator): (JSC::truncThunkGenerator): (JSC::roundThunkGenerator): (JSC::expThunkGenerator): (JSC::logThunkGenerator): (JSC::absThunkGenerator): (JSC::imulThunkGenerator): (JSC::randomThunkGenerator): (JSC::boundFunctionCallGenerator): (JSC::remoteFunctionCallGenerator): (JSC::nativeCallWithDebuggerHookGenerator): Deleted. (JSC::nativeConstructWithDebuggerHookGenerator): Deleted. * Source/JavaScriptCore/jit/JITThunks.h: * Source/JavaScriptCore/jit/JITThunks.cpp: (JSC::JITThunks::ctiNativeCall): (JSC::JITThunks::ctiNativeConstruct): (JSC::JITThunks::ctiNativeTailCall): (JSC::JITThunks::ctiNativeTailCallWithoutSavedTags): (JSC::JITThunks::ctiInternalFunctionCall): (JSC::JITThunks::ctiInternalFunctionConstruct): (JSC::JITThunks::ctiStubImpl): (JSC::JITThunks::ctiStub): (JSC::JITThunks::ctiSlowPathFunctionStub): (JSC::JITThunks::hostFunctionStub): (JSC::JITThunks::ctiNativeCallWithDebuggerHook): Deleted. (JSC::JITThunks::ctiNativeConstructWithDebuggerHook): Deleted. * Source/JavaScriptCore/dfg/DFGThunks.h: * Source/JavaScriptCore/dfg/DFGThunks.cpp: (JSC::DFG::osrExitGenerationThunkGenerator): (JSC::DFG::osrEntryThunkGenerator): * Source/JavaScriptCore/ftl/FTLThunks.h: * Source/JavaScriptCore/ftl/FTLThunks.cpp: (JSC::FTL::osrExitGenerationThunkGenerator): (JSC::FTL::lazySlowPathGenerationThunkGenerator): * Source/JavaScriptCore/jit/JIT.h: * Source/JavaScriptCore/jit/JIT.cpp: (JSC::JIT::consistencyCheckGenerator): * Source/JavaScriptCore/jit/JITCall.cpp: (JSC::JIT::returnFromBaselineGenerator): * Source/JavaScriptCore/jit/JITOpcodes.cpp: (JSC::JIT::valueIsFalseyGenerator): (JSC::JIT::valueIsTruthyGenerator): (JSC::JIT::op_throw_handlerGenerator): (JSC::JIT::op_enter_handlerGenerator): (JSC::JIT::op_check_traps_handlerGenerator): * Source/JavaScriptCore/jit/JITPropertyAccess.cpp: (JSC::JIT::slow_op_get_by_val_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_get_private_name_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_put_by_val_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_put_private_name_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_del_by_id_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_del_by_val_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_get_by_id_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_get_by_id_with_this_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::slow_op_put_by_id_callSlowOperationThenCheckExceptionGenerator): (JSC::JIT::generateOpResolveScopeThunk): (JSC::JIT::slow_op_resolve_scopeGenerator): (JSC::JIT::generateOpGetFromScopeThunk): (JSC::JIT::slow_op_get_from_scopeGenerator): (JSC::JIT::slow_op_put_to_scopeGenerator): (JSC::JIT::slow_op_get_by_val_with_this_callSlowOperationThenCheckExceptionGenerator): * Source/JavaScriptCore/runtime/VM.h: * Source/JavaScriptCore/runtime/VM.cpp: (JSC::VM::thunkGeneratorForIntrinsic): (JSC::VM::getCTIStub): (JSC::VM::getHostFunction): (JSC::VM::getCTIInternalFunctionTrampolineFor): Instead of having entirely separate ways to generate JIT thunks with debugger hooks (e.g. having a `ctiNativeCallWithDebuggerHook` alongside a `ctiNativeCall`), require that all `ThunkGenerator` have a `IncludeDebuggerHook` as a second paramenter, including that in the hash when caching the result. This way, there only one path to generating JIT thunks (and future engineers will be reminded to consider the debugging story (if any) instead of potentially leaving that aside). Only JIT thunks generated by generators defined in `VM::thunkGeneratorForIntrinsic` currently need to use this new `IncludeDebuggerHook` parameter, as otherwise they either aren't a `NativeExecutable` entry point or go down the already supported path for `NativeJITCode`/`NativeDOMJITCode`. * Source/JavaScriptCore/jit/JSInterfaceJIT.h: (JSC::JSInterfaceJIT::emitDebuggerHook): Added. Add a utility function to emit JIT code that calls into `operationDebuggerWillCallNativeExecutable`. * Source/JavaScriptCore/jit/SpecializedThunkJIT.h: (JSC::SpecializedThunkJIT::checkArgCount): Added. Separate the argument count check into it's own callable utility function so that the existing callsites can wait to invoke it until after any debugger hooks are added. * Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp: (Inspector::functionName): (Inspector::ReplacedThunk::~ReplacedThunk): (Inspector::InspectorDebuggerAgent::addSymbolicBreakpoint): (Inspector::InspectorDebuggerAgent::didCreateNativeExecutable): * Source/JavaScriptCore/jit/JITCode.h: (JSC::JITCode::canSwapCodePtrWithArityCheckForDebugger const): Added. * Source/JavaScriptCore/jit/JITCode.cpp: (JSC::JITCode::swapCodePtrWithArityCheckForDebugger): Added. (JSC::DirectJITCode::swapCodePtrWithArityCheckForDebugger): Added. Add a way for the `Debugger` (really the `InspectorDebuggerAgent`) to replace the `m_withArityCheck` of `DirectJITCode` with a version generated with `IncludeDebuggerHook::Yes`. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-exact-case-insensitive.html: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-exact-case-insensitive-expected.txt: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-exact-case-sensitive.html: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-exact-case-sensitive-expected.txt: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-regex-case-insensitive.html: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-regex-case-insensitive-expected.txt: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-regex-case-sensitive.html: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-intrinsic-js-regex-case-sensitive-expected.txt: Added. * LayoutTests/inspector/debugger/symbolic-breakpoint-native-js-exact-case-insensitive.html: Drive-by: Fix incorrect symbol name. Canonical link: https://commits.webkit.org/254576@main
1 parent 4949001 commit 6e24711

30 files changed

Lines changed: 1556 additions & 289 deletions
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
CONSOLE MESSAGE: BREAKPOINT ACTION LOG 1
2+
CONSOLE MESSAGE: BREAKPOINT ACTION LOG 2
3+
CONSOLE MESSAGE: BREAKPOINT ACTION LOG 3
4+
CONSOLE MESSAGE: BREAKPOINT ACTION LOG 4
5+
Tests for SymbolicBreakpoint.
6+
7+
8+
== Running test suite: SymbolicBreakpoint
9+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.Condition
10+
11+
Setting condition to 'false'...
12+
13+
Triggering breakpoint...
14+
PASS: Should not pause.
15+
16+
Triggering breakpoint...
17+
PASS: Should not pause.
18+
19+
Setting condition to 'true'...
20+
21+
Triggering breakpoint...
22+
PASS: Should pause.
23+
24+
Triggering breakpoint...
25+
PASS: Should pause.
26+
27+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.Condition.ConsoleCommandLineAPI
28+
Adding saved console value 'false'...
29+
30+
Setting condition to saved console value...
31+
32+
Triggering breakpoint...
33+
PASS: Should not pause.
34+
35+
Triggering breakpoint...
36+
PASS: Should not pause.
37+
38+
Adding saved console value 'true'...
39+
Setting condition to saved console value...
40+
41+
Triggering breakpoint...
42+
PASS: Should pause.
43+
44+
Triggering breakpoint...
45+
PASS: Should pause.
46+
47+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.IgnoreCount
48+
49+
Setting ignoreCount to '2'...
50+
51+
Triggering breakpoint...
52+
PASS: Should not pause.
53+
54+
Triggering breakpoint...
55+
PASS: Should not pause.
56+
57+
Triggering breakpoint...
58+
PASS: Should pause.
59+
60+
Triggering breakpoint...
61+
PASS: Should pause.
62+
63+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.Action.Log
64+
65+
Adding log action...
66+
67+
Triggering breakpoint...
68+
PASS: Should execute breakpoint action.
69+
PASS: Should pause.
70+
71+
Editing log action...
72+
73+
Triggering breakpoint...
74+
PASS: Should execute breakpoint action.
75+
PASS: Should pause.
76+
77+
Editing log action...
78+
Enabling auto-continue...
79+
80+
Triggering breakpoint...
81+
PASS: Should execute breakpoint action.
82+
PASS: Should not pause.
83+
84+
Editing log action...
85+
86+
Triggering breakpoint...
87+
PASS: Should execute breakpoint action.
88+
PASS: Should not pause.
89+
90+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.Actions.Evaluate
91+
92+
Adding evaluate action...
93+
94+
Triggering breakpoint...
95+
PASS: Should execute breakpoint action.
96+
PASS: Should pause.
97+
98+
Editing evaluate action...
99+
100+
Triggering breakpoint...
101+
PASS: Should execute breakpoint action.
102+
PASS: Should pause.
103+
104+
Editing evaluate action...
105+
Enabling auto-continue...
106+
107+
Triggering breakpoint...
108+
PASS: Should execute breakpoint action.
109+
PASS: Should not pause.
110+
111+
Editing evaluate action...
112+
113+
Triggering breakpoint...
114+
PASS: Should execute breakpoint action.
115+
PASS: Should not pause.
116+
117+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Hit.Options.Actions.Evaluate.ConsoleCommandLineAPI
118+
Adding saved console value '1'...
119+
120+
Adding evaluate action using saved console value...
121+
122+
Triggering breakpoint...
123+
PASS: Should execute breakpoint action.
124+
PASS: Should pause.
125+
126+
Adding saved console value '2'...
127+
Editing evaluate action using saved console value...
128+
129+
Triggering breakpoint...
130+
PASS: Should execute breakpoint action.
131+
PASS: Should pause.
132+
133+
Adding saved console value '3'...
134+
Editing evaluate action using saved console value...
135+
Enabling auto-continue...
136+
137+
Triggering breakpoint...
138+
PASS: Should execute breakpoint action.
139+
PASS: Should not pause.
140+
141+
Adding saved console value '4'...
142+
Editing evaluate action using saved console value...
143+
144+
Triggering breakpoint...
145+
PASS: Should execute breakpoint action.
146+
PASS: Should not pause.
147+
148+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Miss
149+
Adding breakpoint...
150+
Triggering breakpoint...
151+
PASS: Should not pause.
152+
153+
Removing breakpoint...
154+
Triggering breakpoint...
155+
PASS: Should not pause.
156+
157+
-- Running test case: SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Disabled
158+
Adding breakpoint...
159+
Triggering breakpoint...
160+
PASS: Should not pause.
161+
162+
Removing breakpoint...
163+
Triggering breakpoint...
164+
PASS: Should not pause.
165+
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
5+
<script src="resources/breakpoint-options-utilities.js"></script>
6+
<script>
7+
function triggerSymbolicBreakpoint() {
8+
"test".charCodeAt(0);
9+
TestPage.dispatchEventToFrontend("TestPage-SymbolicBreakpoint");
10+
}
11+
12+
function test()
13+
{
14+
function triggerBreakpoint() {
15+
return Promise.all([
16+
InspectorTest.awaitEvent("TestPage-SymbolicBreakpoint"),
17+
InspectorTest.evaluateInPage(`triggerSymbolicBreakpoint()`),
18+
]);
19+
}
20+
21+
let suite = InspectorTest.createAsyncSuite("SymbolicBreakpoint");
22+
23+
InspectorTest.BreakpointOptions.addTestCases(suite, {
24+
testCaseNamePrefix: "ExactCaseInsensitive.Intrinsic.JS.Hit.",
25+
createBreakpoint() {
26+
let breakpoint = new WI.SymbolicBreakpoint("cHaRcOdEaT", {caseSensitive: false});
27+
WI.debuggerManager.addSymbolicBreakpoint(breakpoint);
28+
return breakpoint;
29+
},
30+
triggerBreakpoint,
31+
});
32+
33+
suite.addTestCase({
34+
name: "SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Miss",
35+
async test() {
36+
let pauseCount = 0;
37+
let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
38+
++pauseCount;
39+
WI.debuggerManager.resume();
40+
});
41+
42+
InspectorTest.log("Adding breakpoint...");
43+
let breakpoint = new WI.SymbolicBreakpoint("cHaRcOdE", {caseSensitive: false});
44+
WI.debuggerManager.addSymbolicBreakpoint(breakpoint);
45+
InspectorTest.assert(!WI.debuggerManager.symbolicBreakpointsForSymbol("charCodeAt").length, "Should not match breakpoint.");
46+
47+
InspectorTest.log("Triggering breakpoint...");
48+
await triggerBreakpoint();
49+
InspectorTest.expectEqual(pauseCount, 0, "Should not pause.");
50+
51+
InspectorTest.newline();
52+
53+
InspectorTest.log("Removing breakpoint...");
54+
breakpoint.remove();
55+
56+
InspectorTest.log("Triggering breakpoint...");
57+
await triggerBreakpoint();
58+
InspectorTest.expectEqual(pauseCount, 0, "Should not pause.");
59+
60+
WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
61+
},
62+
});
63+
64+
suite.addTestCase({
65+
name: "SymbolicBreakpoint.ExactCaseInsensitive.Intrinsic.JS.Disabled",
66+
async test() {
67+
let pauseCount = 0;
68+
let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
69+
++pauseCount;
70+
WI.debuggerManager.resume();
71+
});
72+
73+
InspectorTest.log("Adding breakpoint...");
74+
let breakpoint = new WI.SymbolicBreakpoint("cHaRcOdEaT", {caseSensitive: false, disabled: true});
75+
WI.debuggerManager.addSymbolicBreakpoint(breakpoint);
76+
InspectorTest.assert(!WI.debuggerManager.symbolicBreakpointsForSymbol("charCodeAt").length, "Should not match breakpoint.");
77+
78+
InspectorTest.log("Triggering breakpoint...");
79+
await triggerBreakpoint();
80+
InspectorTest.expectEqual(pauseCount, 0, "Should not pause.");
81+
82+
InspectorTest.newline();
83+
84+
InspectorTest.log("Removing breakpoint...");
85+
breakpoint.remove();
86+
87+
InspectorTest.log("Triggering breakpoint...");
88+
await triggerBreakpoint();
89+
InspectorTest.expectEqual(pauseCount, 0, "Should not pause.");
90+
91+
WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
92+
},
93+
});
94+
95+
suite.runTestCasesAndFinish();
96+
}
97+
</script>
98+
</head>
99+
<body onload="runTest()">
100+
<p>Tests for SymbolicBreakpoint.</p>
101+
</body>
102+
</html>

0 commit comments

Comments
 (0)