diff options
Diffstat (limited to 'js/src/vm/Interpreter.cpp')
-rw-r--r-- | js/src/vm/Interpreter.cpp | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 0f83c3435..030f0f3b6 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -261,11 +261,16 @@ SetPropertyOperation(JSContext* cx, JSOp op, HandleValue lval, HandleId id, Hand } static JSFunction* -MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto) +MakeDefaultConstructor(JSContext* cx, HandleScript script, jsbytecode* pc, HandleObject proto) { + JSOp op = JSOp(*pc); + JSAtom* atom = script->getAtom(pc); bool derived = op == JSOP_DERIVEDCONSTRUCTOR; MOZ_ASSERT(derived == !!proto); + jssrcnote* classNote = GetSrcNote(cx, script, pc); + MOZ_ASSERT(classNote && SN_TYPE(classNote) == SRC_CLASS_SPAN); + PropertyName* lookup = derived ? cx->names().DefaultDerivedClassConstructor : cx->names().DefaultBaseClassConstructor; @@ -285,6 +290,17 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto) MOZ_ASSERT(ctor->infallibleIsDefaultClassConstructor(cx)); + // Create the script now, as the source span needs to be overridden for + // toString. Calling toString on a class constructor must not return the + // source for just the constructor function. + JSScript *ctorScript = JSFunction::getOrCreateScript(cx, ctor); + if (!ctorScript) + return nullptr; + uint32_t classStartOffset = GetSrcNoteOffset(classNote, 0); + uint32_t classEndOffset = GetSrcNoteOffset(classNote, 1); + ctorScript->setDefaultClassConstructorSpan(script->sourceObject(), classStartOffset, + classEndOffset); + return ctor; } @@ -373,7 +389,7 @@ js::RunScript(JSContext* cx, RunState& state) SPSEntryMarker marker(cx->runtime(), state.script()); - state.script()->ensureNonLazyCanonicalFunction(cx); + state.script()->ensureNonLazyCanonicalFunction(); if (jit::IsIonEnabled(cx)) { jit::MethodStatus status = jit::CanEnter(cx, state); @@ -446,7 +462,7 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct } /* Invoke native functions. */ - JSFunction* fun = &args.callee().as<JSFunction>(); + RootedFunction fun(cx, &args.callee().as<JSFunction>()); if (construct != CONSTRUCT && fun->isClassConstructor()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CALL_CLASS_CONSTRUCTOR); return false; @@ -454,10 +470,16 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct if (fun->isNative()) { MOZ_ASSERT_IF(construct, !fun->isConstructor()); - return CallJSNative(cx, fun->native(), args); + JSNative native = fun->native(); + if (!construct && args.ignoresReturnValue()) { + const JSJitInfo* jitInfo = fun->jitInfo(); + if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative) + native = jitInfo->ignoresReturnValueMethod; + } + return CallJSNative(cx, native, args); } - if (!fun->getOrCreateScript(cx)) + if (!JSFunction::getOrCreateScript(cx, fun)) return false; /* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */ @@ -1543,7 +1565,7 @@ SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleId id, HandleVa } } - if (obj->isNative() && !JSID_IS_INT(id) && !obj->setHadElementsAccess(cx)) + if (obj->isNative() && !JSID_IS_INT(id) && !JSObject::setHadElementsAccess(cx, obj)) return false; ObjectOpResult result; @@ -2959,6 +2981,7 @@ CASE(JSOP_FUNAPPLY) CASE(JSOP_NEW) CASE(JSOP_CALL) +CASE(JSOP_CALL_IGNORES_RV) CASE(JSOP_CALLITER) CASE(JSOP_SUPERCALL) CASE(JSOP_FUNCALL) @@ -2967,10 +2990,11 @@ CASE(JSOP_FUNCALL) cx->runtime()->spsProfiler.updatePC(script, REGS.pc); MaybeConstruct construct = MaybeConstruct(*REGS.pc == JSOP_NEW || *REGS.pc == JSOP_SUPERCALL); + bool ignoresReturnValue = *REGS.pc == JSOP_CALL_IGNORES_RV; unsigned argStackSlots = GET_ARGC(REGS.pc) + construct; MOZ_ASSERT(REGS.stackDepth() >= 2u + GET_ARGC(REGS.pc)); - CallArgs args = CallArgsFromSp(argStackSlots, REGS.sp, construct); + CallArgs args = CallArgsFromSp(argStackSlots, REGS.sp, construct, ignoresReturnValue); JSFunction* maybeFun; bool isFunction = IsFunctionObject(args.calleev(), &maybeFun); @@ -3000,7 +3024,7 @@ CASE(JSOP_FUNCALL) { MOZ_ASSERT(maybeFun); ReservedRooted<JSFunction*> fun(&rootFunction0, maybeFun); - ReservedRooted<JSScript*> funScript(&rootScript0, fun->getOrCreateScript(cx)); + ReservedRooted<JSScript*> funScript(&rootScript0, JSFunction::getOrCreateScript(cx, fun)); if (!funScript) goto error; @@ -4174,8 +4198,8 @@ CASE(JSOP_DERIVEDCONSTRUCTOR) MOZ_ASSERT(REGS.sp[-1].isObject()); ReservedRooted<JSObject*> proto(&rootObject0, ®S.sp[-1].toObject()); - JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc), - proto); + JSFunction* constructor = MakeDefaultConstructor(cx, script, REGS.pc, proto); + if (!constructor) goto error; @@ -4185,8 +4209,7 @@ END_CASE(JSOP_DERIVEDCONSTRUCTOR) CASE(JSOP_CLASSCONSTRUCTOR) { - JSFunction* constructor = MakeDefaultConstructor(cx, JSOp(*REGS.pc), script->getAtom(REGS.pc), - nullptr); + JSFunction* constructor = MakeDefaultConstructor(cx, script, REGS.pc, nullptr); if (!constructor) goto error; PUSH_OBJECT(*constructor); @@ -4725,7 +4748,8 @@ js::RunOnceScriptPrologue(JSContext* cx, HandleScript script) // Force instantiation of the script's function's group to ensure the flag // is preserved in type information. - if (!script->functionNonDelazifying()->getGroup(cx)) + RootedFunction fun(cx, script->functionNonDelazifying()); + if (!JSObject::getGroup(cx, fun)) return false; MarkObjectGroupFlags(cx, script->functionNonDelazifying(), OBJECT_FLAG_RUNONCE_INVALIDATED); |