author | Till Schneidereit <tschneidereit@gmail.com> |
Tue, 18 Sep 2012 22:11:37 +0200 | |
changeset 113096 | 862f9cd7eb0bebf5fcc4e7a6a550bfbe0b1740db |
parent 113095 | 67fd0ece8d38020c1f9b82c14195953d682e7e7f |
child 113097 | 3da143341145b12a1a42b46b1d669731f096436f |
push id | 17944 |
push user | tschneidereit@gmail.com |
push date | Tue, 13 Nov 2012 17:56:25 +0000 |
treeherder | mozilla-inbound@3da143341145 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | luke |
bugs | 791850 |
milestone | 19.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2660,17 +2660,17 @@ frontend::EmitFunctionScript(JSContext * bool singleton = cx->typeInferenceEnabled() && bce->parent && bce->parent->checkSingletonContext(); /* Initialize fun->script() so that the debugger has a valid fun->script(). */ RootedFunction fun(cx, bce->script->function()); JS_ASSERT(fun->isInterpreted()); - JS_ASSERT(!fun->script().unsafeGet()); + JS_ASSERT(!fun->hasScript()); fun->setScript(bce->script); if (!JSFunction::setTypeForScriptedFunction(cx, fun, singleton)) return false; bce->tellDebuggerAboutCompiledScript(cx); return true; } @@ -4830,17 +4830,17 @@ EmitFor(JSContext *cx, BytecodeEmitter * } static JS_NEVER_INLINE bool EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) { AssertCanGC(); RootedFunction fun(cx, pn->pn_funbox->function()); JS_ASSERT(fun->isInterpreted()); - if (fun->script().unsafeGet()) { + if (fun->hasScript()) { /* * This second pass is needed to emit JSOP_NOP with a source note * for the already-emitted function definition prolog opcode. See * comments in EmitStatementList. */ JS_ASSERT(pn->functionIsHoisted()); JS_ASSERT(bce->sc->isFunction); return EmitFunctionDefNop(cx, bce, pn->pn_index);
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4990,18 +4990,18 @@ JS_DefineFunctions(JSContext *cx, JSObje if (!ctor) { ctor = JS_GetConstructor(cx, obj); if (!ctor) return JS_FALSE; } flags &= ~JSFUN_GENERIC_NATIVE; JSFunction *fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher, - fs->nargs + 1, flags, NullPtr(), - JSFunction::ExtendedFinalizeKind); + fs->nargs + 1, flags, + JSFunction::ExtendedFinalizeKind); if (!fun) return JS_FALSE; /* * As jsapi.h notes, fs must point to storage that lives as long * as fun->object lives. */ fun->setExtendedSlot(0, PrivateValue(fs)); @@ -5012,29 +5012,36 @@ JS_DefineFunctions(JSContext *cx, JSObje * self-hosted functions, as that means we're currently setting up * the global object that that the self-hosted code is then compiled * in. Self-hosted functions can access each other via their names, * but not via the builtin classes they get installed into. */ if (fs->selfHostedName && cx->runtime->isSelfHostedGlobal(cx->global())) return JS_TRUE; - Rooted<PropertyName*> selfHostedPropertyName(cx); + /* + * Delay cloning self-hosted functions until they are called. This is + * achieved by passing js_DefineFunction a NULL JSNative which + * produces an interpreted JSFunction where !hasScript. Interpreted + * call paths then call InitializeLazyFunctionScript if !hasScript. + */ if (fs->selfHostedName) { - JSAtom *selfHostedAtom = Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)); - if (!selfHostedAtom) + JSFunction *fun = js_DefineFunction(cx, obj, id, /* native = */ NULL, fs->nargs, 0, + JSFunction::ExtendedFinalizeKind); + if (!fun) return JS_FALSE; - selfHostedPropertyName = selfHostedAtom->asPropertyName(); + fun->setIsSelfHostedBuiltin(); + fun->setExtendedSlot(0, PrivateValue(fs)); + } else { + JSFunction *fun = js_DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags); + if (!fun) + return JS_FALSE; + if (fs->call.info) + fun->setJitInfo(fs->call.info); } - JSFunction *fun = js_DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags, - selfHostedPropertyName); - if (!fun) - return JS_FALSE; - if (fs->call.info) - fun->setJitInfo(fs->call.info); } return JS_TRUE; } JS_PUBLIC_API(JSFunction *) JS_DefineFunction(JSContext *cx, JSObject *objArg, const char *name, JSNative call, unsigned nargs, unsigned attrs) {
--- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -376,52 +376,72 @@ JSRuntime::initSelfHosting(JSContext *cx } void JSRuntime::markSelfHostedGlobal(JSTracer *trc) { MarkObjectRoot(trc, &selfHostedGlobal_, "self-hosting global"); } -JSFunction * -JSRuntime::getSelfHostedFunction(JSContext *cx, Handle<PropertyName*> name) +bool +JSRuntime::getUnclonedSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, + MutableHandleValue vp) { - RootedObject holder(cx, cx->global()->getIntrinsicsHolder()); - RootedId id(cx, NameToId(name)); - RootedValue funVal(cx, NullValue()); - if (!cloneSelfHostedValueById(cx, id, holder, &funVal)) - return NULL; - return funVal.toObject().toFunction(); + RootedObject shg(cx, selfHostedGlobal_); + AutoCompartment ac(cx, shg); + return JS_GetPropertyById(cx, shg, NameToId(name), vp.address()); } bool -JSRuntime::cloneSelfHostedValueById(JSContext *cx, HandleId id, HandleObject holder, MutableHandleValue vp) +JSRuntime::cloneSelfHostedFunctionScript(JSContext *cx, Handle<PropertyName*> name, + Handle<JSFunction*> targetFun) { - Value funVal; - { - RootedObject shg(cx, selfHostedGlobal_); - AutoCompartment ac(cx, shg); - if (!JS_GetPropertyById(cx, shg, id, &funVal) || !funVal.isObject()) - return false; - } + RootedValue funVal(cx); + if (!getUnclonedSelfHostedValue(cx, name, &funVal)) + return false; + + Rooted<JSScript*> sourceScript(cx, funVal.toObject().toFunction()->script()); + JS_ASSERT(!sourceScript->enclosingStaticScope()); + RawScript cscript = CloneScript(cx, NullPtr(), targetFun, sourceScript); + if (!cscript) + return false; + targetFun->setScript(cscript); + cscript->setFunction(targetFun); + if (!JSFunction::setTypeForScriptedFunction(cx, targetFun)) + return false; + + RootedValue targetFunVal(cx, OBJECT_TO_JSVAL(targetFun)); + DebugOnly<bool> ok = JS_DefinePropertyById(cx, cx->global()->getIntrinsicsHolder(), + NameToId(name), targetFunVal, NULL, NULL, 0); + JS_ASSERT(ok); + return true; +} + +bool +JSRuntime::cloneSelfHostedValue(JSContext *cx, Handle<PropertyName*> name, HandleObject holder, + MutableHandleValue vp) +{ + RootedValue funVal(cx); + if (!getUnclonedSelfHostedValue(cx, name, &funVal)) + return false; /* * We don't clone if we're operating in the self-hosting global, as that * means we're currently executing the self-hosting script while * initializing the runtime (see JSRuntime::initSelfHosting). */ if (cx->global() == selfHostedGlobal_) { - vp.set(ObjectValue(funVal.toObject())); + vp.set(funVal); } else { RootedObject clone(cx, JS_CloneFunctionObject(cx, &funVal.toObject(), cx->global())); if (!clone) return false; vp.set(ObjectValue(*clone)); } - DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, id, vp, NULL, NULL, 0); + DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, NameToId(name), vp, NULL, NULL, 0); JS_ASSERT(ok); return true; } JSContext * js::NewContext(JSRuntime *rt, size_t stackChunkSize) { JS_AbortIfWrongThread(rt);
--- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -530,19 +530,22 @@ struct JSRuntime : js::RuntimeFriendFiel } #endif bool initSelfHosting(JSContext *cx); void markSelfHostedGlobal(JSTracer *trc); bool isSelfHostedGlobal(js::HandleObject global) { return global == selfHostedGlobal_; } - JSFunction *getSelfHostedFunction(JSContext *cx, js::Handle<js::PropertyName*> name); - bool cloneSelfHostedValueById(JSContext *cx, js::HandleId id, js::HandleObject holder, - js::MutableHandleValue vp); + bool getUnclonedSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name, + js::MutableHandleValue vp); + bool cloneSelfHostedFunctionScript(JSContext *cx, js::Handle<js::PropertyName*> name, + js::Handle<JSFunction*> targetFun); + bool cloneSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name, + js::HandleObject holder, js::MutableHandleValue vp); /* Base address of the native stack for the current thread. */ uintptr_t nativeStackBase; /* The native stack size limit that runtime should not exceed. */ size_t nativeStackQuota; /*
--- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -397,17 +397,17 @@ js::DefineFunctionWithReserved(JSContext RootedObject obj(cx, objArg); JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); JSAtom *atom = Atomize(cx, name, strlen(name)); if (!atom) return NULL; Rooted<jsid> id(cx, AtomToId(atom)); - return js_DefineFunction(cx, obj, id, call, nargs, attrs, NullPtr(), JSFunction::ExtendedFinalizeKind); + return js_DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind); } JS_FRIEND_API(JSFunction *) js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags, JSObject *parentArg, const char *name) { RootedObject parent(cx, parentArg); JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
--- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -321,17 +321,18 @@ fun_resolve(JSContext *cx, HandleObject return true; } if (JSID_IS_ATOM(id, cx->names().length) || JSID_IS_ATOM(id, cx->names().name)) { JS_ASSERT(!IsInternalFunctionObject(obj)); RootedValue v(cx); if (JSID_IS_ATOM(id, cx->names().length)) { - uint16_t defaults = fun->isInterpreted() ? fun->script()->ndefaults : 0; + //FIXME: bug 810715 - deal with lazy interpreted functions with default args + uint16_t defaults = fun->hasScript() ? fun->script()->ndefaults : 0; v.setInt32(fun->nargs - defaults - fun->hasRest()); } else { v.setString(fun->atom() == NULL ? cx->runtime->emptyString : fun->atom()); } if (!DefineNativeProperty(cx, fun, id, v, JS_PropertyStub, JS_StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) { return false; @@ -478,16 +479,28 @@ js::CloneInterpretedFunction(JSContext * if (!JSFunction::setTypeForScriptedFunction(cx, clone)) return NULL; RootedScript cloneScript(cx, clone->script()); js_CallNewScriptHook(cx, cloneScript, clone); return clone; } +bool +js::InitializeLazyFunctionScript(JSContext *cx, HandleFunction fun) +{ + JS_ASSERT(fun->isLazy()); + JSFunctionSpec *fs = static_cast<JSFunctionSpec *>(fun->getExtendedSlot(0).toPrivate()); + RootedAtom funAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName))); + if (!funAtom) + return false; + Rooted<PropertyName *> funName(cx, funAtom->asPropertyName()); + return cx->runtime->cloneSelfHostedFunctionScript(cx, funName, fun); +} + /* * [[HasInstance]] internal method for Function objects: fetch the .prototype * property of its 'this' parameter, and walks the prototype chain of v (only * if v is an object) returning true if .prototype is found. */ static JSBool fun_hasInstance(JSContext *cx, HandleObject objArg, MutableHandleValue v, JSBool *bp) { @@ -528,17 +541,17 @@ JSFunction::trace(JSTracer *trc) MarkValueRange(trc, ArrayLength(toExtended()->extendedSlots), toExtended()->extendedSlots, "nativeReserved"); } if (atom_) MarkString(trc, &atom_, "atom"); if (isInterpreted()) { - if (u.i.script_) + if (hasScript()) MarkScriptUnbarriered(trc, &u.i.script_, "script"); if (u.i.env_) MarkObjectUnbarriered(trc, &u.i.env_, "fun_callscope"); } } static void fun_trace(JSTracer *trc, RawObject obj) @@ -619,26 +632,27 @@ FindBody(JSContext *cx, HandleFunction f JSString * js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen) { AssertCanGC(); StringBuffer out(cx); RootedScript script(cx); - if (fun->isInterpreted()) + if (fun->hasScript()) { script = fun->script(); - - if (fun->isInterpreted() && script->isGeneratorExp) { - if ((!bodyOnly && !out.append("function genexp() {")) || - !out.append("\n [generator expression]\n") || - (!bodyOnly && !out.append("}"))) { - return NULL; + if (script->isGeneratorExp) { + if ((!bodyOnly && !out.append("function genexp() {")) || + !out.append("\n [generator expression]\n") || + (!bodyOnly && !out.append("}"))) + { + return NULL; + } + return out.finishString(); } - return out.finishString(); } if (!bodyOnly) { // If we're not in pretty mode, put parentheses around lambda functions. if (fun->isInterpreted() && !lambdaParen && fun->isLambda()) { if (!out.append("(")) return NULL; } if (!out.append("function ")) @@ -1119,17 +1133,17 @@ fun_isGenerator(JSContext *cx, unsigned RawFunction fun; if (!IsFunctionObject(vp[1], &fun)) { JS_SET_RVAL(cx, vp, BooleanValue(false)); return true; } bool result = false; - if (fun->isInterpreted()) { + if (fun->hasScript()) { RawScript script = fun->script().get(nogc); JS_ASSERT(script->length != 0); result = script->isGenerator; } JS_SET_RVAL(cx, vp, BooleanValue(result)); return true; } @@ -1525,17 +1539,16 @@ js_CloneFunctionObject(JSContext *cx, Ha /* * Across compartments we have to clone the script for interpreted * functions. Cross-compartment cloning only happens via JSAPI * (JS_CloneFunctionObject) which dynamically ensures that 'script' has * no enclosing lexical scope (only the global scope). */ if (clone->isInterpreted()) { RootedScript script(cx, clone->script()); - JS_ASSERT(script); JS_ASSERT(script->compartment() == fun->compartment()); JS_ASSERT_IF(script->compartment() != cx->compartment, !script->enclosingStaticScope()); RootedObject scope(cx, script->enclosingStaticScope()); clone->mutableScript().init(NULL); @@ -1553,17 +1566,17 @@ js_CloneFunctionObject(JSContext *cx, Ha Debugger::onNewScript(cx, script, global); } } return clone; } JSFunction * js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native, - unsigned nargs, unsigned flags, Handle<PropertyName*> selfHostedName, AllocKind kind) + unsigned nargs, unsigned flags, AllocKind kind) { PropertyOp gop; StrictPropertyOp sop; RootedFunction fun(cx); if (flags & JSFUN_STUB_GSOPS) { /* @@ -1575,33 +1588,23 @@ js_DefineFunction(JSContext *cx, HandleO flags &= ~JSFUN_STUB_GSOPS; gop = JS_PropertyStub; sop = JS_StrictPropertyStub; } else { gop = NULL; sop = NULL; } - /* - * To support specifying both native and self-hosted functions using - * JSFunctionSpec, js_DefineFunction can be invoked with either native - * or selfHostedName set. It is assumed that selfHostedName is set if - * native isn't. - */ - if (native) { - JS_ASSERT(!selfHostedName); - RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL); - JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags); - fun = js_NewFunction(cx, NullPtr(), native, nargs, - funFlags, obj, atom, kind); - } else { - JS_ASSERT(!cx->runtime->isSelfHostedGlobal(cx->global())); - fun = cx->runtime->getSelfHostedFunction(cx, selfHostedName); - fun->initAtom(JSID_TO_ATOM(id)); - } + JSFunction::Flags funFlags; + if (!native) + funFlags = JSFunction::INTERPRETED; + else + funFlags = JSAPIToJSFunctionFlags(flags); + RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL); + fun = js_NewFunction(cx, NullPtr(), native, nargs, funFlags, obj, atom, kind); if (!fun) return NULL; RootedValue funVal(cx, ObjectValue(*fun)); if (!JSObject::defineGeneric(cx, obj, id, funVal, gop, sop, flags & ~JSFUN_FLAGS_MASK)) return NULL; return fun;
--- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -79,16 +79,18 @@ struct JSFunction : public JSObject bool isNative() const { return !(flags & INTERPRETED); } /* Possible attributes of a native function: */ bool isNativeConstructor() const { return flags & NATIVE_CTOR; } /* Possible attributes of an interpreted function: */ bool isHeavyweight() const { return flags & HEAVYWEIGHT; } bool isFunctionPrototype() const { return flags & IS_FUN_PROTO; } + bool isLazy() const { return isInterpreted() && !hasScript(); } + bool hasScript() const { return isInterpreted() && u.i.script_; } bool isExprClosure() const { return flags & EXPR_CLOSURE; } bool hasGuessedAtom() const { return flags & HAS_GUESSED_ATOM; } bool isLambda() const { return flags & LAMBDA; } bool isSelfHostedBuiltin() const { return flags & SELF_HOSTED; } bool isSelfHostedConstructor() const { return flags & SELF_HOSTED_CTOR; } bool hasRest() const { return flags & HAS_REST; } bool hasDefaults() const { return flags & HAS_DEFAULTS; } @@ -162,17 +164,17 @@ struct JSFunction : public JSObject inline JSObject *environment() const; inline void setEnvironment(JSObject *obj); inline void initEnvironment(JSObject *obj); static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); } static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); } js::Return<JSScript*> script() const { - JS_ASSERT(isInterpreted()); + JS_ASSERT(hasScript()); return JS::HandleScript::fromMarkedLocation(&u.i.script_); } js::HeapPtrScript &mutableScript() { JS_ASSERT(isInterpreted()); return *(js::HeapPtrScript *)&u.i.script_; } @@ -283,17 +285,17 @@ js_NewFunction(JSContext *cx, js::Handle extern JSFunction * JS_FASTCALL js_CloneFunctionObject(JSContext *cx, js::HandleFunction fun, js::HandleObject parent, js::HandleObject proto, js::gc::AllocKind kind = JSFunction::FinalizeKind); extern JSFunction * js_DefineFunction(JSContext *cx, js::HandleObject obj, js::HandleId id, JSNative native, - unsigned nargs, unsigned flags, js::Handle<js::PropertyName*> selfHostedName = JS::NullPtr(), + unsigned nargs, unsigned flags, js::gc::AllocKind kind = JSFunction::FinalizeKind); namespace js { /* * Function extended with reserved slots for use by various kinds of functions. * Most functions do not have these extensions, but enough are that efficient * storage is required (no malloc'ed reserved slots). @@ -329,16 +331,19 @@ JSString *FunctionToString(JSContext *cx template<XDRMode mode> bool XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript, MutableHandleObject objp); extern JSObject * CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleFunction fun); +bool +InitializeLazyFunctionScript(JSContext *cx, HandleFunction fun); + /* * Report an error that call.thisv is not compatible with the specified class, * assuming that the method (clasp->name).prototype.<name of callee function> * is what was called. */ extern void ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp);
--- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -363,16 +363,19 @@ js::InvokeKernel(JSContext *cx, CallArgs } /* Invoke native functions. */ RootedFunction fun(cx, callee.toFunction()); JS_ASSERT_IF(construct, !fun->isNativeConstructor()); if (fun->isNative()) return CallJSNative(cx, fun->native(), args); + if (fun->isLazy() && !InitializeLazyFunctionScript(cx, fun)) + return false; + if (!TypeMonitorCall(cx, args, construct)) return false; /* Get pointer to new frame/slots, prepare arguments. */ InvokeFrameGuard ifg; if (!cx->stack.pushInvokeFrame(cx, args, initial, &ifg)) return false; @@ -2334,16 +2337,18 @@ BEGIN_CASE(JSOP_FUNCALL) DO_NEXT_OP(len); } if (!TypeMonitorCall(cx, args, construct)) goto error; InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE; bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc); + if (fun->isLazy() && !InitializeLazyFunctionScript(cx, fun)) + goto error; RawScript funScript = fun->script().unsafeGet(); if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial)) goto error; SET_SCRIPT(regs.fp()->script()); #ifdef JS_METHODJIT script->resetLoopCount(); #endif
--- a/js/src/jsinterpinlines.h +++ b/js/src/jsinterpinlines.h @@ -1015,17 +1015,17 @@ class FastInvokeGuard #endif { initFunction(fval); } void initFunction(const Value &fval) { if (fval.isObject() && fval.toObject().isFunction()) { JSFunction *fun = fval.toObject().toFunction(); - if (fun->isInterpreted()) { + if (fun->hasScript()) { fun_ = fun; script_ = fun->script(); } } } InvokeArgsGuard &args() { return args_;
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -5278,17 +5278,17 @@ dumpValue(const Value &v) else if (v.isObject() && v.toObject().isFunction()) { JSFunction *fun = v.toObject().toFunction(); if (fun->displayAtom()) { fputs("<function ", stderr); FileEscapedString(stderr, fun->displayAtom(), 0); } else { fputs("<unnamed function", stderr); } - if (fun->isInterpreted()) { + if (fun->hasScript()) { JSScript *script = fun->script().get(nogc); fprintf(stderr, " (%s:%u)", script->filename ? script->filename : "", script->lineno); } fprintf(stderr, " at %p>", (void *) fun); } else if (v.isObject()) { JSObject *obj = &v.toObject(); Class *clasp = obj->getClass();
--- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -1108,17 +1108,17 @@ js_NewPrinter(JSContext *cx, const char jp->grouped = !!grouped; jp->strict = !!strict; jp->script = NULL; jp->dvgfence = NULL; jp->pcstack = NULL; jp->fun = fun; jp->localNames = NULL; jp->decompiledOpcodes = NULL; - if (fun && fun->isInterpreted()) { + if (fun && fun->hasScript()) { if (!SetPrinterLocalNames(cx, fun->script().unsafeGet(), jp)) { js_DestroyPrinter(jp); return NULL; } } return jp; }
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1836,30 +1836,28 @@ JSScript::isShortRunning() && getMaxLoopCount() < 40 #endif ; } bool JSScript::enclosingScriptsCompiledSuccessfully() const { - AutoAssertNoGC nogc; - /* * When a nested script is succesfully compiled, it is eagerly given the * static JSFunction of its enclosing script. The enclosing function's * 'script' field will be NULL until the enclosing script successfully * compiles. Thus, we can detect failed compilation by looking for * JSFunctions in the enclosingScope chain without scripts. */ RawObject enclosing = enclosingScope_; while (enclosing) { if (enclosing->isFunction()) { RawFunction fun = enclosing->toFunction(); - if (!fun->script().get(nogc)) + if (!fun->hasScript()) return false; enclosing = fun->script()->enclosingScope_; } else { enclosing = enclosing->asStaticBlock().enclosingStaticScope(); } } return true; }
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2361,17 +2361,17 @@ static JSObject * LambdaIsGetElem(JSObject &lambda) { AutoAssertNoGC nogc; if (!lambda.isFunction()) return NULL; JSFunction *fun = lambda.toFunction(); - if (!fun->isInterpreted()) + if (!fun->hasScript()) return NULL; RawScript script = fun->script().get(nogc); jsbytecode *pc = script->code; /* * JSOP_GETALIASEDVAR tells us exactly where to find the base object 'b'. * Rule out the (unlikely) possibility of a heavyweight function since it
--- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -279,16 +279,20 @@ ShouldJaegerCompileCallee(JSContext *cx, static inline bool UncachedInlineCall(VMFrame &f, InitialFrameFlags initial, void **pret, bool *unjittable, uint32_t argc) { AssertCanGC(); JSContext *cx = f.cx; CallArgs args = CallArgsFromSp(argc, f.regs.sp); RootedFunction newfun(cx, args.callee().toFunction()); + + if (newfun->isLazy() && !InitializeLazyFunctionScript(cx, newfun)) + return false; + RootedScript newscript(cx, newfun->script()); bool construct = InitialFrameFlagsAreConstructing(initial); RootedScript fscript(cx, f.script()); bool newType = construct && cx->typeInferenceEnabled() && types::UseNewType(cx, fscript, f.pc());
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2207,17 +2207,17 @@ Clone(JSContext *cx, unsigned argc, jsva JSFunction *fun = JS_ValueToFunction(cx, argv[0]); if (!fun) return false; funobj = JS_GetFunctionObject(fun); } } if (funobj->compartment() != cx->compartment) { JSFunction *fun = funobj->toFunction(); - if (fun->isInterpreted() && fun->script()->compileAndGo) { + if (fun->hasScript() && fun->script()->compileAndGo) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE, "function", "compile-and-go"); return false; } } if (argc > 1) { if (!JS_ValueToObject(cx, argv[1], parent.address()))
--- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -387,23 +387,18 @@ class GlobalObject : public JSObject return HasDataProperty(cx, self, NameToId(name), &fun); } bool getIntrinsicValue(JSContext *cx, PropertyName *name, MutableHandleValue value) { RootedObject holder(cx, &getSlotRef(INTRINSICS).toObject()); RootedId id(cx, NameToId(name)); if (HasDataProperty(cx, holder, id, value.address())) return true; - bool ok = cx->runtime->cloneSelfHostedValueById(cx, id, holder, value); - if (!ok) - return false; - - ok = JS_DefinePropertyById(cx, holder, id, value, NULL, NULL, 0); - JS_ASSERT(ok); - return true; + Rooted<PropertyName*> rootedName(cx, name); + return cx->runtime->cloneSelfHostedValue(cx, rootedName, holder, value); } inline RegExpStatics *getRegExpStatics() const; JSObject *getThrowTypeError() const { JS_ASSERT(functionObjectClassesInitialized()); return &getSlot(THROWTYPEERROR).toObject(); }