Skip to content

Commit

Permalink
Bug 1781061 - Part 7: Use JSOp::CallContentIter instead of JSOp::Call…
Browse files Browse the repository at this point in the history
…Iter in self-hosted JS. r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D153160
  • Loading branch information
arai-a committed Aug 4, 2022
1 parent 82d68e1 commit 3b7c043
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
37 changes: 32 additions & 5 deletions js/src/frontend/BytecodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2837,6 +2837,24 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring(
return true;
}

JSOp BytecodeEmitter::getIterCallOp(JSOp callOp,
SelfHostedIter selfHostedIter) {
if (emitterMode == BytecodeEmitter::SelfHosting) {
MOZ_ASSERT(selfHostedIter == SelfHostedIter::Allow);

switch (callOp) {
case JSOp::Call:
return JSOp::CallContent;
case JSOp::CallIter:
return JSOp::CallContentIter;
default:
MOZ_CRASH("Unknown iterator call op");
}
}

return callOp;
}

bool BytecodeEmitter::emitIteratorNext(
const Maybe<uint32_t>& callSourceCoordOffset,
IteratorKind iterKind /* = IteratorKind::Sync */,
Expand All @@ -2846,10 +2864,16 @@ bool BytecodeEmitter::emitIteratorNext(
".next() iteration is prohibited in self-hosted code because it"
"can run user-modifiable iteration code");

MOZ_ASSERT(selfHostedIter == SelfHostedIter::Allow ||
emitterMode != BytecodeEmitter::SelfHosting,
".next() iteration is prohibited in self-hosted code because it"
"can run user-modifiable iteration code");

// [stack] ... NEXT ITER
MOZ_ASSERT(bytecodeSection().stackDepth() >= 2);

if (!emitCall(JSOp::Call, 0, callSourceCoordOffset)) {
if (!emitCall(getIterCallOp(JSOp::Call, selfHostedIter), 0,
callSourceCoordOffset)) {
// [stack] ... RESULT
return false;
}
Expand Down Expand Up @@ -2955,7 +2979,7 @@ bool BytecodeEmitter::emitIteratorCloseInScope(
return false;
}

if (!emitCall(JSOp::Call, 0)) {
if (!emitCall(getIterCallOp(JSOp::Call, selfHostedIter), 0)) {
// [stack] ... RESULT
return false;
}
Expand Down Expand Up @@ -5094,6 +5118,7 @@ bool BytecodeEmitter::emitCopyDataProperties(CopyOption option) {
return false;
}
}
// Callee is always self-hosted instrinsic, and cannot be content function.
if (!emitCall(JSOp::CallIgnoresRv, argc)) {
// [stack] IGNORED
return false;
Expand Down Expand Up @@ -5140,7 +5165,7 @@ bool BytecodeEmitter::emitIterator(
// [stack] ITERFN OBJ
return false;
}
if (!emitCall(JSOp::CallIter, 0)) {
if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
// [stack] ITER
return false;
}
Expand Down Expand Up @@ -5214,7 +5239,7 @@ bool BytecodeEmitter::emitAsyncIterator(
// [stack] ITERFN OBJ
return false;
}
if (!emitCall(JSOp::CallIter, 0)) {
if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
// [stack] ITER
return false;
}
Expand Down Expand Up @@ -5246,7 +5271,7 @@ bool BytecodeEmitter::emitAsyncIterator(
// [stack] ITERFN OBJ
return false;
}
if (!emitCall(JSOp::CallIter, 0)) {
if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
// [stack] ITER
return false;
}
Expand Down Expand Up @@ -9835,6 +9860,7 @@ bool BytecodeEmitter::emitInitializeInstanceMembers(
return false;
}

// Callee is always internal function.
if (!emitCall(JSOp::CallIgnoresRv, 0)) {
// [stack] ARRAY? RVAL
return false;
Expand Down Expand Up @@ -9893,6 +9919,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) {
return false;
}

// Callee is always internal function.
if (!emitCall(JSOp::CallIgnoresRv, 0)) {
// [stack] CTOR ARRAY? RVAL
return false;
Expand Down
2 changes: 2 additions & 0 deletions js/src/frontend/BytecodeEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
// two in the latter case) elements from the stack.
[[nodiscard]] bool emitCopyDataProperties(CopyOption option);

JSOp getIterCallOp(JSOp callOp, SelfHostedIter selfHostedIter);

// emitIterator expects the iterable to already be on the stack.
// It will replace that stack value with the corresponding iterator
[[nodiscard]] bool emitIterator(
Expand Down
24 changes: 24 additions & 0 deletions js/src/jit-test/tests/debug/Debugger-onNativeCall-08.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Test that the onNativeCall hook is called when native function is
// called inside self-hosted JS as part of iteration.

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(`
Array.from([1, 2, 3]);
`);
assertEqArray(rv, [
"from",
// FIXME: This is internal function (bug 1782677).
"IteratorMethod",
"values",
"next", "next", "next", "next",
]);

0 comments on commit 3b7c043

Please sign in to comment.