/* static */ void ArgumentsObject::MaybeForwardToCallObject(jit::JitFrameLayout* frame, HandleObject callObj, ArgumentsObject* obj, ArgumentsData* data) { JSFunction* callee = jit::CalleeTokenToFunction(frame->calleeToken()); JSScript* script = callee->nonLazyScript(); if (callee->needsCallObject() && script->argsObjAliasesFormals()) { MOZ_ASSERT(callObj && callObj->is<CallObject>()); obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(*callObj.get())); for (AliasedFormalIter fi(script); fi; fi++) data->args[fi.frameIndex()] = MagicScopeSlotValue(fi.scopeSlot()); } }
/* static */ void ArgumentsObject::MaybeForwardToCallObject(jit::JitFrameLayout* frame, HandleObject callObj, ArgumentsObject* obj, ArgumentsData* data) { JSFunction* callee = jit::CalleeTokenToFunction(frame->calleeToken()); JSScript* script = callee->nonLazyScript(); if (callee->needsCallObject() && script->argumentsAliasesFormals()) { MOZ_ASSERT(callObj && callObj->is<CallObject>()); obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(*callObj.get())); for (PositionalFormalParameterIter fi(script); fi; fi++) { if (fi.closedOver()) data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot()); } } }
/* static */ ArgumentsObject* ArgumentsObject::finishForIon(JSContext* cx, jit::JitFrameLayout* frame, JSObject* scopeChain, ArgumentsObject* obj) { // JIT code calls this directly (no callVM), because it's faster, so we're // not allowed to GC in here. JS::AutoCheckCannotGC nogc; JSFunction* callee = jit::CalleeTokenToFunction(frame->calleeToken()); RootedObject callObj(cx, scopeChain->is<CallObject>() ? scopeChain : nullptr); CopyJitFrameArgs copy(frame, callObj); unsigned numActuals = frame->numActualArgs(); unsigned numFormals = callee->nargs(); unsigned numArgs = Max(numActuals, numFormals); unsigned numBytes = ArgumentsData::bytesRequired(numArgs); ArgumentsData* data = reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes)); if (!data) { // Make the object safe for GC. Don't report OOM, the slow path will // retry the allocation. cx->recoverFromOutOfMemory(); obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr)); return nullptr; } data->numArgs = numArgs; data->rareData = nullptr; obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT)); obj->initFixedSlot(DATA_SLOT, PrivateValue(data)); obj->initFixedSlot(MAYBE_CALL_SLOT, UndefinedValue()); obj->initFixedSlot(CALLEE_SLOT, ObjectValue(*callee)); copy.copyArgs(cx, data->args, numArgs); if (callObj && callee->needsCallObject()) copy.maybeForwardToCallObject(obj, data); MOZ_ASSERT(obj->initialLength() == numActuals); MOZ_ASSERT(!obj->hasOverriddenLength()); return obj; }