Commit 391f85d9 authored by Jan de Mooij's avatar Jan de Mooij
Browse files

Bug 1823042 - Switch to bound function target's realm before creating |this|. r=iain

For non-constructing calls it's simpler and faster to switch after pushing the arguments
and loading the bound function's target, but for constructor calls this needs to happen
earlier.

Differential Revision: https://phabricator.services.mozilla.com/D173281
parent 3b70eeaa
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
function f() {
    var g = newGlobal({sameCompartmentAs: this});
    g.evaluate(`function f() {}`);
    var boundF = g.f.bind(null);
    for (var i = 0; i < 50; i++) {
        var obj = new boundF();
        assertEq(objectGlobal(obj), g);
    }
}
f();
+10 −2
Original line number Diff line number Diff line
@@ -3422,7 +3422,16 @@ bool BaselineCacheIRCompiler::emitCallBoundScriptedFunction(
  AutoStubFrame stubFrame(*this);
  stubFrame.enter(masm, scratch);

  Address boundTarget(calleeReg, BoundFunctionObject::offsetOfTargetSlot());

  // If we're constructing, switch to the target's realm and create |this|. If
  // we're not constructing, we switch to the target's realm after pushing the
  // arguments and loading the target.
  if (isConstructing) {
    if (!isSameRealm) {
      masm.unboxObject(boundTarget, scratch);
      masm.switchToObjectRealm(scratch, scratch);
    }
    createThis(argcReg, calleeReg, scratch, flags,
               /* isBoundFunction = */ true);
  }
@@ -3432,10 +3441,9 @@ bool BaselineCacheIRCompiler::emitCallBoundScriptedFunction(
                             numBoundArgs, /* isJitCall = */ true);

  // Load the target JSFunction.
  Address boundTarget(calleeReg, BoundFunctionObject::offsetOfTargetSlot());
  masm.unboxObject(boundTarget, calleeReg);

  if (!isSameRealm) {
  if (!isConstructing && !isSameRealm) {
    masm.switchToObjectRealm(calleeReg, scratch);
  }