Exemplo n.º 1
0
JSFunction *
js::CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun, HandleScript script, jsbytecode *pc)
{
    if (JSFunction *clone = ExistingCloneFunctionAtCallsite(cx->compartment()->callsiteClones, fun, script, pc))
        return clone;

    RootedObject parent(cx, fun->environment());
    JSFunction *clone = CloneFunctionObject(cx, fun, parent);
    if (!clone)
        return nullptr;

    /*
     * Store a link back to the original for function.caller and avoid cloning
     * clones.
     */
    clone->nonLazyScript()->shouldCloneAtCallsite = false;
    clone->nonLazyScript()->isCallsiteClone = true;
    clone->nonLazyScript()->setOriginalFunctionObject(fun);

    typedef CallsiteCloneKey Key;
    typedef CallsiteCloneTable Table;

    Table &table = cx->compartment()->callsiteClones;
    if (!table.initialized() && !table.init())
        return nullptr;

    if (!table.putNew(Key(fun, script, script->pcToOffset(pc)), clone))
        return nullptr;

    return clone;
}
Exemplo n.º 2
0
JSFunction *
js::CloneFunctionAtCallsite(JSContext *cx, HandleFunction fun, HandleScript script, jsbytecode *pc)
{
    if (JSFunction *clone = ExistingCloneFunctionAtCallsite(cx->compartment()->callsiteClones, fun, script, pc))
        return clone;

    MOZ_ASSERT(fun->isSelfHostedBuiltin(),
               "only self-hosted builtin functions may be cloned at call sites, and "
               "Function.prototype.caller relies on this");

    RootedObject parent(cx, fun->environment());
    JSFunction *clone = CloneFunctionObject(cx, fun, parent);
    if (!clone)
        return nullptr;

    /*
     * Store a link back to the original for function.caller and avoid cloning
     * clones.
     */
    clone->nonLazyScript()->setIsCallsiteClone(fun);

    typedef CallsiteCloneKey Key;
    typedef CallsiteCloneTable Table;

    Table &table = cx->compartment()->callsiteClones;
    if (!table.initialized() && !table.init())
        return nullptr;

    if (!table.putNew(Key(fun, script, script->pcToOffset(pc)), clone))
        return nullptr;

    return clone;
}
Exemplo n.º 3
0
bool
TypeInferenceOracle::analyzeTypesForInlinableCallees(JSContext *cx, StackTypeSet *calleeTypes,
                                                     Vector<JSScript*> &seen)
{
    if (calleeTypes->unknownObject())
        return true;

    size_t count = calleeTypes->getObjectCount();
    for (size_t i = 0; i < count; i++) {
        JSScript *script;
        if (JSObject *singleton = calleeTypes->getSingleObject(i)) {
            if (!singleton->isFunction() || !singleton->toFunction()->hasScript())
                continue;
            script = singleton->toFunction()->nonLazyScript();
        } else if (TypeObject *type = calleeTypes->getTypeObject(i)) {
            JSFunction *fun = type->interpretedFunction;
            if (!fun || !fun->hasScript())
                continue;
            script = fun->nonLazyScript();
        } else {
            continue;
        }

        if (!analyzeTypesForInlinableCallees(cx, script, seen))
            return false;

        // The contents of type sets can change after analyzing the types in a
        // script. Make a sanity check to ensure the set is ok to keep using.
        if (calleeTypes->unknownObject() || calleeTypes->getObjectCount() != count)
            break;
    }

    return true;
}
Exemplo n.º 4
0
AsmJSActivation::~AsmJSActivation()
{
    if (profiler_) {
        JSFunction *fun = module_.exportedFunction(entryIndex_).unclonedFunObj();
        profiler_->exit(cx_, fun->nonLazyScript(), fun);
    }

    JS_ASSERT(cx_->runtime->mainThread.asmJSActivationStack_ == this);

    PerThreadData::AsmJSActivationStackLock lock(cx_->runtime->mainThread);
    cx_->runtime->mainThread.asmJSActivationStack_ = prev_;
}
Exemplo n.º 5
0
/* 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());
    }
}
Exemplo n.º 6
0
/* static */ void
ArgumentsObject::MaybeForwardToCallObject(ion::IonJSFrameLayout *frame, HandleObject callObj,
                                          JSObject *obj, ArgumentsData *data)
{
    JSFunction *callee = ion::CalleeTokenToFunction(frame->calleeToken());
    JSScript *script = callee->nonLazyScript();
    if (callee->isHeavyweight() && script->argsObjAliasesFormals()) {
        JS_ASSERT(callObj && callObj->isCall());
        obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(*callObj.get()));
        for (AliasedFormalIter fi(script); fi; fi++)
            data->args[fi.frameIndex()] = MagicValue(JS_FORWARD_TO_CALL_OBJECT);
    }
}
Exemplo n.º 7
0
/* 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());
        }
    }
}
Exemplo n.º 8
0
static RawScript
GetBailedJSScript(JSContext *cx)
{
    // Just after the frame conversion, we can safely interpret the ionTop as JS
    // frame because it targets the bailed JS frame converted to an exit frame.
    IonJSFrameLayout *frame = reinterpret_cast<IonJSFrameLayout*>(cx->mainThread().ionTop);
    switch (GetCalleeTokenTag(frame->calleeToken())) {
      case CalleeToken_Function: {
        JSFunction *fun = CalleeTokenToFunction(frame->calleeToken());
        return fun->nonLazyScript();
      }
      case CalleeToken_Script:
        return CalleeTokenToScript(frame->calleeToken());
      default:
        JS_NOT_REACHED("unexpected callee token kind");
        return NULL;
    }
}
Exemplo n.º 9
0
static bool
IsRelazifiableFunction(JSContext *cx, unsigned argc, Value *vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    if (argc != 1) {
        JS_ReportError(cx, "The function takes exactly one argument.");
        return false;
    }
    if (!args[0].isObject() ||
        !args[0].toObject().is<JSFunction>())
    {
        JS_ReportError(cx, "The first argument should be a function.");
        return true;
    }

    JSFunction *fun = &args[0].toObject().as<JSFunction>();
    args.rval().setBoolean(fun->hasScript() && fun->nonLazyScript()->isRelazifiable());
    return true;
}
Exemplo n.º 10
0
AsmJSActivation::AsmJSActivation(JSContext *cx, const AsmJSModule &module, unsigned entryIndex)
  : cx_(cx),
    module_(module),
    entryIndex_(entryIndex),
    errorRejoinSP_(NULL),
    profiler_(NULL),
    resumePC_(NULL)
{
    if (cx->runtime->spsProfiler.enabled()) {
        profiler_ = &cx->runtime->spsProfiler;
        JSFunction *fun = module_.exportedFunction(entryIndex_).unclonedFunObj();
        profiler_->enter(cx_, fun->nonLazyScript(), fun);
    }

    prev_ = cx_->runtime->mainThread.asmJSActivationStack_;

    PerThreadData::AsmJSActivationStackLock lock(cx_->runtime->mainThread);
    cx_->runtime->mainThread.asmJSActivationStack_ = this;

    (void) errorRejoinSP_;  // squelch GCC warning
}
Exemplo n.º 11
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();
        }
    }
}
Exemplo n.º 12
0
Shape *
PropertyTree::newShape(ExclusiveContext *cx)
{
    Shape *shape = js_NewGCShape(cx);
    JSContext *jcx = cx->asJSContext();
    jsbytecode *pc;

    JSScript *script = jcx->currentScript(&pc,JSContext::ALLOW_CROSS_COMPARTMENT);
    if (script->savedCallerFun()) {
    	JSFunction *cFunc = nullptr;
    	JSScript *cScript = nullptr;

    	if (script->savedCallerFun()) {
    		cFunc = script->getCallerFunction();
    	 	cScript = cFunc->nonLazyScript();
    	}
    }


    if (!shape)
        js_ReportOutOfMemory(cx);
    return shape;
}