static bool CreateLazyScriptsForCompartment(JSContext *cx) { AutoObjectVector lazyFunctions(cx); // Find all root lazy functions in the compartment: those which have not been // compiled and which have a source object, indicating that their parent has // been compiled. for (gc::CellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject *obj = i.get<JSObject>(); if (obj->compartment() == cx->compartment() && obj->is<JSFunction>()) { JSFunction *fun = &obj->as<JSFunction>(); if (fun->isInterpretedLazy()) { LazyScript *lazy = fun->lazyScriptOrNull(); if (lazy && lazy->sourceObject() && !lazy->maybeScript()) { if (!lazyFunctions.append(fun)) return false; } } } } // Create scripts for each lazy function, updating the list of functions to // process with any newly exposed inner functions in created scripts. // A function cannot be delazified until its outer script exists. for (size_t i = 0; i < lazyFunctions.length(); i++) { JSFunction *fun = &lazyFunctions[i]->as<JSFunction>(); // lazyFunctions may have been populated with multiple functions for // a lazy script. if (!fun->isInterpretedLazy()) continue; JSScript *script = fun->getOrCreateScript(cx); if (!script) return false; if (!AddInnerLazyFunctionsFromScript(script, lazyFunctions)) return false; } // Repoint any clones of the original functions to their new script. for (gc::CellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject *obj = i.get<JSObject>(); if (obj->compartment() == cx->compartment() && obj->is<JSFunction>()) { JSFunction *fun = &obj->as<JSFunction>(); if (fun->isInterpretedLazy()) { LazyScript *lazy = fun->lazyScriptOrNull(); if (lazy && lazy->maybeScript()) fun->existingScript(); } } } return true; }
static bool CreateLazyScriptsForCompartment(JSContext* cx) { AutoObjectVector lazyFunctions(cx); // Find all live root lazy functions in the compartment: those which // have not been compiled, which have a source object, indicating that // they have a parent, and which do not have an uncompiled enclosing // script. The last condition is so that we don't compile lazy scripts // whose enclosing scripts failed to compile, indicating that the lazy // script did not escape the script. // // Note that while we ideally iterate over LazyScripts, LazyScripts do not // currently stand in 1-1 relation with JSScripts; JSFunctions with the // same LazyScript may create different JSScripts due to relazification of // clones. See bug 1105306. for (gc::ZoneCellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) { JSObject* obj = i.get<JSObject>(); if (obj->compartment() == cx->compartment() && obj->is<JSFunction>()) { JSFunction* fun = &obj->as<JSFunction>(); if (fun->isInterpretedLazy()) { LazyScript* lazy = fun->lazyScriptOrNull(); if (lazy && lazy->sourceObject() && !lazy->maybeScript() && !lazy->hasUncompiledEnclosingScript()) { if (!lazyFunctions.append(fun)) return false; } } } } // Create scripts for each lazy function, updating the list of functions to // process with any newly exposed inner functions in created scripts. // A function cannot be delazified until its outer script exists. for (size_t i = 0; i < lazyFunctions.length(); i++) { JSFunction* fun = &lazyFunctions[i]->as<JSFunction>(); // lazyFunctions may have been populated with multiple functions for // a lazy script. if (!fun->isInterpretedLazy()) continue; LazyScript* lazy = fun->lazyScript(); bool lazyScriptHadNoScript = !lazy->maybeScript(); JSScript* script = fun->getOrCreateScript(cx); if (!script) return false; if (lazyScriptHadNoScript && !AddInnerLazyFunctionsFromScript(script, lazyFunctions)) return false; } return true; }
bool CreateThis(JSContext *cx, HandleObject callee, MutableHandleValue rval) { rval.set(MagicValue(JS_IS_CONSTRUCTING)); if (callee->isFunction()) { JSFunction *fun = callee->toFunction(); if (fun->isInterpreted()) { JSScript *script = fun->getOrCreateScript(cx); if (!script || !script->ensureHasTypes(cx)) return false; rval.set(ObjectValue(*CreateThisForFunction(cx, callee, false))); } } return true; }
static bool CreateLazyScriptsForCompartment(JSContext *cx) { AutoObjectVector lazyFunctions(cx); // Find all live lazy scripts in the compartment, and via them all root // lazy functions in the compartment: those which have not been compiled, // which have a source object, indicating that they have a parent, and // which do not have an uncompiled enclosing script. The last condition is // so that we don't compile lazy scripts whose enclosing scripts failed to // compile, indicating that the lazy script did not escape the script. for (gc::ZoneCellIter i(cx->zone(), gc::FINALIZE_LAZY_SCRIPT); !i.done(); i.next()) { LazyScript *lazy = i.get<LazyScript>(); JSFunction *fun = lazy->functionNonDelazifying(); if (fun->compartment() == cx->compartment() && lazy->sourceObject() && !lazy->maybeScript() && !lazy->hasUncompiledEnclosingScript()) { MOZ_ASSERT(fun->isInterpretedLazy()); MOZ_ASSERT(lazy == fun->lazyScriptOrNull()); if (!lazyFunctions.append(fun)) return false; } } // Create scripts for each lazy function, updating the list of functions to // process with any newly exposed inner functions in created scripts. // A function cannot be delazified until its outer script exists. for (size_t i = 0; i < lazyFunctions.length(); i++) { JSFunction *fun = &lazyFunctions[i]->as<JSFunction>(); // lazyFunctions may have been populated with multiple functions for // a lazy script. if (!fun->isInterpretedLazy()) continue; JSScript *script = fun->getOrCreateScript(cx); if (!script) return false; if (!AddInnerLazyFunctionsFromScript(script, lazyFunctions)) return false; } return true; }
bool CreateThis(JSContext *cx, HandleObject callee, MutableHandleValue rval) { rval.set(MagicValue(JS_IS_CONSTRUCTING)); if (callee->is<JSFunction>()) { JSFunction *fun = &callee->as<JSFunction>(); if (fun->isInterpretedConstructor()) { JSScript *script = fun->getOrCreateScript(cx); if (!script || !script->ensureHasTypes(cx)) return false; JSObject *thisObj = CreateThisForFunction(cx, callee, GenericObject); if (!thisObj) return false; rval.set(ObjectValue(*thisObj)); } } return true; }
static bool CreateLazyScriptsForCompartment(JSContext* cx) { AutoObjectVector lazyFunctions(cx); if (!AddLazyFunctionsForCompartment(cx, lazyFunctions, AllocKind::FUNCTION)) return false; // Methods, for instance {get method() {}}, are extended functions that can // be relazified, so we need to handle those as well. if (!AddLazyFunctionsForCompartment(cx, lazyFunctions, AllocKind::FUNCTION_EXTENDED)) return false; // Create scripts for each lazy function, updating the list of functions to // process with any newly exposed inner functions in created scripts. // A function cannot be delazified until its outer script exists. for (size_t i = 0; i < lazyFunctions.length(); i++) { JSFunction* fun = &lazyFunctions[i]->as<JSFunction>(); // lazyFunctions may have been populated with multiple functions for // a lazy script. if (!fun->isInterpretedLazy()) continue; LazyScript* lazy = fun->lazyScript(); bool lazyScriptHadNoScript = !lazy->maybeScript(); JSScript* script = fun->getOrCreateScript(cx); if (!script) return false; if (lazyScriptHadNoScript && !AddInnerLazyFunctionsFromScript(script, lazyFunctions)) return false; } return true; }