Пример #1
0
/* static */ void
ArgumentsObject::MaybeForwardToCallObject(ion::IonJSFrameLayout *frame, HandleObject callObj,
                                          JSObject *obj, ArgumentsData *data)
{
    RawFunction callee = ion::CalleeTokenToFunction(frame->calleeToken());
    RawScript 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);
    }
}
Пример #2
0
bool
TypeInferenceOracle::canEnterInlinedFunction(RawScript caller, jsbytecode *pc, RawFunction target)
{
    RootedScript targetScript(cx, target->nonLazyScript());

    // Make sure empty script has type information, to allow inlining in more cases.
    if (targetScript->length == 1) {
        if (!targetScript->ensureRanInference(cx))
            return false;
    }

    if (!targetScript->hasAnalysis() ||
        !targetScript->analysis()->ranInference() ||
        !targetScript->analysis()->ranSSA())
    {
        return false;
    }

    if (!targetScript->analysis()->ionInlineable())
        return false;

    if (targetScript->needsArgsObj())
        return false;

    if (!targetScript->compileAndGo)
        return false;

    if (targetScript->analysis()->usesScopeChain())
        return false;

    types::TypeObject *targetType = target->getType(cx);
    if (!targetType || targetType->unknownProperties())
        return false;

    JSOp op = JSOp(*pc);
    TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript);
    TypeSet *callReturn = getCallReturn(caller, pc);
    if (op == JSOP_NEW) {
        if (!returnTypes->isSubsetIgnorePrimitives(callReturn))
            return false;
    } else {
        if (!returnTypes->isSubset(callReturn))
            return false;
    }

    // TI calls ObjectStateChange to trigger invalidation of the caller.
    HeapTypeSet::WatchObjectStateChange(cx, targetType);
    return true;
}
Пример #3
0
bool
TypeInferenceOracle::callArgsTypeSetIntersects(types::StackTypeSet *thisType, Vector<types::StackTypeSet *> &argvType, RawFunction callee)
{
    RootedScript targetScript(cx, callee->nonLazyScript());
    types::TypeSet *calleeType;

    size_t nargs = Min<size_t>(callee->nargs, argvType.length());

    // This
    if (thisType) {
        calleeType = types::TypeScript::ThisTypes(targetScript);
        if (thisType->intersectionEmpty(calleeType))
            return false;
    }

    // Arguments
    for (size_t i = 0; i < nargs; i++) {
        calleeType = types::TypeScript::ArgTypes(targetScript, i);
        if (argvType[i]->intersectionEmpty(calleeType))
            return false;
    }

    // Arguments that weren't provided will be Undefined
    for (size_t i = nargs; i < callee->nargs; i++) {
        calleeType = types::TypeScript::ArgTypes(targetScript, i);
        if (calleeType->unknown() ||
            !calleeType->hasType(types::Type::UndefinedType()))
        {
            return false;
        }
    }

    return true;
}
Пример #4
0
bool
TypeInferenceOracle::canEnterInlinedFunction(RawFunction target)
{
    RootedScript targetScript(cx, target->nonLazyScript());

    // Make sure empty script has type information, to allow inlining in more cases.
    if (targetScript->length == 1) {
        if (!targetScript->ensureRanInference(cx))
            return false;
    }

    if (!targetScript->hasAnalysis() ||
        !targetScript->analysis()->ranInference() ||
        !targetScript->analysis()->ranSSA())
    {
        return false;
    }

    if (!targetScript->analysis()->ionInlineable())
        return false;

    if (targetScript->needsArgsObj())
        return false;

    if (!targetScript->compileAndGo)
        return false;

    if (targetScript->analysis()->usesScopeChain())
        return false;

    types::TypeObject *targetType = target->getType(cx);
    if (!targetType || targetType->unknownProperties())
        return false;

    // TI calls ObjectStateChange to trigger invalidation of the caller.
    HeapTypeSet::WatchObjectStateChange(cx, targetType);
    return true;
}
Пример #5
0
bool
TypeInferenceOracle::callReturnTypeSetMatches(RawScript callerScript, jsbytecode *callerPc,
                                              RawFunction callee)
{
    RootedScript targetScript(cx, callee->nonLazyScript());

    JSOp op = JSOp(*callerPc);
    TypeSet *returnTypes = TypeScript::ReturnTypes(targetScript);
    TypeSet *callReturn = getCallReturn(callerScript, callerPc);
    if (op == JSOP_NEW) {
        if (!returnTypes->isSubsetIgnorePrimitives(callReturn))
            return false;
    } else {
        if (!returnTypes->isSubset(callReturn))
            return false;
    }

    return true;
}