Loading js/src/debugger/Debugger.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -965,14 +965,19 @@ NativeResumeMode DebugAPI::slowPathOnNativeCall(JSContext* cx, // The onNativeCall hook is fired when self hosted functions are called, // and any other self hosted function or C++ native that is directly called // by the self hosted function is considered to be part of the same // native call, except for callContentFunction and constructContentFunction, // which uses CallReason::CallContent. // native call, except for the following 2 cases: // // * callContentFunction and constructContentFunction, // which uses CallReason::CallContent // * Function.prototype.call and Function.prototype.apply, // which uses CallReason::FunCall // // We check this only after checking that debuggerList has items in order // to avoid unnecessary calls to cx->currentScript(), which can be expensive // when the top frame is in jitcode. JSScript* script = cx->currentScript(); if (script && script->selfHosted() && reason != CallReason::CallContent) { if (script && script->selfHosted() && reason != CallReason::CallContent && reason != CallReason::FunCall) { return NativeResumeMode::Continue; } Loading Loading @@ -2304,6 +2309,9 @@ bool Debugger::fireNativeCall(JSContext* cx, const CallArgs& args, case CallReason::CallContent: reasonAtom = cx->names().call; break; case CallReason::FunCall: reasonAtom = cx->names().call; break; case CallReason::Getter: reasonAtom = cx->names().get; break; Loading js/src/jit-test/tests/debug/Debugger-onNativeCall-07.js 0 → 100644 +33 −0 Original line number Diff line number Diff line // Test that the onNativeCall hook is called when native function is // called inside self-hosted JS with Function.prototype.{call,apply}. load(libdir + 'eqArrayHelper.js'); var g = newGlobal({ newCompartment: true }); var dbg = new Debugger(); var gdbg = dbg.addDebuggee(g); const rv = []; dbg.onNativeCall = (callee, reason) => { rv.push(callee.name); }; gdbg.executeInGlobal(` // Directly call. dateNow.call(); dateNow.apply(); // Call via bind. Function.prototype.call.bind(Function.prototype.call)(dateNow); Function.prototype.apply.bind(Function.prototype.apply)(dateNow); // Call via std_Function_apply Reflect.apply(dateNow, null, []); `); assertEqArray(rv, [ "call", "dateNow", "apply", "dateNow", "bind", "call", "call", "call", "dateNow", "bind", "apply", "apply", "apply", "dateNow", "apply", "dateNow", ]); js/src/vm/Interpreter.h +2 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ enum class CallReason { Call, // callContentFunction or constructContentFunction in self-hosted JS. CallContent, // Function.prototype.call or Function.prototype.apply. FunCall, Getter, Setter, }; Loading js/src/vm/JSFunction.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -979,7 +979,7 @@ bool js::fun_call(JSContext* cx, unsigned argc, Value* vp) { iargs[i].set(args[i + 1]); } return Call(cx, func, args.get(0), iargs, args.rval()); return Call(cx, func, args.get(0), iargs, args.rval(), CallReason::FunCall); } // ES5 15.3.4.3 Loading Loading @@ -1031,7 +1031,7 @@ bool js::fun_apply(JSContext* cx, unsigned argc, Value* vp) { } // Step 9. return Call(cx, fval, args[0], args2, args.rval()); return Call(cx, fval, args[0], args2, args.rval(), CallReason::FunCall); } static const JSFunctionSpec function_methods[] = { Loading Loading
js/src/debugger/Debugger.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -965,14 +965,19 @@ NativeResumeMode DebugAPI::slowPathOnNativeCall(JSContext* cx, // The onNativeCall hook is fired when self hosted functions are called, // and any other self hosted function or C++ native that is directly called // by the self hosted function is considered to be part of the same // native call, except for callContentFunction and constructContentFunction, // which uses CallReason::CallContent. // native call, except for the following 2 cases: // // * callContentFunction and constructContentFunction, // which uses CallReason::CallContent // * Function.prototype.call and Function.prototype.apply, // which uses CallReason::FunCall // // We check this only after checking that debuggerList has items in order // to avoid unnecessary calls to cx->currentScript(), which can be expensive // when the top frame is in jitcode. JSScript* script = cx->currentScript(); if (script && script->selfHosted() && reason != CallReason::CallContent) { if (script && script->selfHosted() && reason != CallReason::CallContent && reason != CallReason::FunCall) { return NativeResumeMode::Continue; } Loading Loading @@ -2304,6 +2309,9 @@ bool Debugger::fireNativeCall(JSContext* cx, const CallArgs& args, case CallReason::CallContent: reasonAtom = cx->names().call; break; case CallReason::FunCall: reasonAtom = cx->names().call; break; case CallReason::Getter: reasonAtom = cx->names().get; break; Loading
js/src/jit-test/tests/debug/Debugger-onNativeCall-07.js 0 → 100644 +33 −0 Original line number Diff line number Diff line // Test that the onNativeCall hook is called when native function is // called inside self-hosted JS with Function.prototype.{call,apply}. load(libdir + 'eqArrayHelper.js'); var g = newGlobal({ newCompartment: true }); var dbg = new Debugger(); var gdbg = dbg.addDebuggee(g); const rv = []; dbg.onNativeCall = (callee, reason) => { rv.push(callee.name); }; gdbg.executeInGlobal(` // Directly call. dateNow.call(); dateNow.apply(); // Call via bind. Function.prototype.call.bind(Function.prototype.call)(dateNow); Function.prototype.apply.bind(Function.prototype.apply)(dateNow); // Call via std_Function_apply Reflect.apply(dateNow, null, []); `); assertEqArray(rv, [ "call", "dateNow", "apply", "dateNow", "bind", "call", "call", "call", "dateNow", "bind", "apply", "apply", "apply", "dateNow", "apply", "dateNow", ]);
js/src/vm/Interpreter.h +2 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ enum class CallReason { Call, // callContentFunction or constructContentFunction in self-hosted JS. CallContent, // Function.prototype.call or Function.prototype.apply. FunCall, Getter, Setter, }; Loading
js/src/vm/JSFunction.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -979,7 +979,7 @@ bool js::fun_call(JSContext* cx, unsigned argc, Value* vp) { iargs[i].set(args[i + 1]); } return Call(cx, func, args.get(0), iargs, args.rval()); return Call(cx, func, args.get(0), iargs, args.rval(), CallReason::FunCall); } // ES5 15.3.4.3 Loading Loading @@ -1031,7 +1031,7 @@ bool js::fun_apply(JSContext* cx, unsigned argc, Value* vp) { } // Step 9. return Call(cx, fval, args[0], args2, args.rval()); return Call(cx, fval, args[0], args2, args.rval(), CallReason::FunCall); } static const JSFunctionSpec function_methods[] = { Loading