示例#1
0
static void TraverseInnerLazyScriptsForLazyScript(
    JSContext* cx, void* data, LazyScript* enclosingLazyScript,
    IterateLazyScriptCallback lazyScriptCallback,
    const JS::AutoRequireNoGC& nogc) {
  GCPtrFunction* innerFunctions = enclosingLazyScript->innerFunctions();
  for (size_t i = 0, len = enclosingLazyScript->numInnerFunctions(); i < len;
       i++) {
    JSFunction* fun = innerFunctions[i];

    // LazyScript::CreateForXDR temporarily initializes innerFunctions with
    // its own function, but it should be overwritten with correct
    // inner functions before getting inserted into parent's innerFunctions.
    MOZ_ASSERT(fun != enclosingLazyScript->functionNonDelazifying());

    if (!fun->isInterpretedLazy()) {
      return;
    }

    LazyScript* lazyScript = fun->lazyScript();
    MOZ_ASSERT(lazyScript->hasEnclosingScope() ||
               lazyScript->hasEnclosingLazyScript());
    MOZ_ASSERT_IF(lazyScript->hasEnclosingLazyScript(),
                  lazyScript->enclosingLazyScript() == enclosingLazyScript);

    lazyScriptCallback(cx->runtime(), data, lazyScript, nogc);

    TraverseInnerLazyScriptsForLazyScript(cx, data, lazyScript,
                                          lazyScriptCallback, nogc);
  }
}
示例#2
0
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;
}
示例#3
0
static void
MarkFunctionsWithinEvalScript(JSScript *script)
{
    // Mark top level functions in an eval script as being within an eval and,
    // if applicable, inside a with statement.

    if (!script->hasObjects())
        return;

    ObjectArray *objects = script->objects();
    size_t start = script->innerObjectsStart();

    for (size_t i = start; i < objects->length; i++) {
        JSObject *obj = objects->vector[i];
        if (obj->is<JSFunction>()) {
            JSFunction *fun = &obj->as<JSFunction>();
            if (fun->hasScript())
                fun->nonLazyScript()->setDirectlyInsideEval();
            else if (fun->isInterpretedLazy())
                fun->lazyScript()->setDirectlyInsideEval();
        }
    }
}
示例#4
0
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;
}