Example #1
0
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
    
#if !ENABLE(JIT)
    UNUSED_PARAM(jitType);
#endif
    JSObject* exception = 0;
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    
    if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) {
        BytecodeDestructionBlocker blocker(m_evalCodeBlock.get());
        OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release()));
        m_evalCodeBlock = newCodeBlock.release();
    } else {
        if (!lexicalGlobalObject->evalEnabled())
            return throwError(exec, createEvalError(exec, "Eval is disabled"));
        RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
        if (!evalNode) {
            ASSERT(exception);
            return exception;
        }
        recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
        
        JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
        
        OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
        m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
        OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
        if ((exception = generator->generate())) {
            m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
            evalNode->destroyData();
            return exception;
        }
        
        evalNode->destroyData();
        m_evalCodeBlock->copyPostParseDataFromAlternative();
    }

#if ENABLE(JIT)
    if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
        return 0;
#endif

#if ENABLE(JIT)
#if ENABLE(INTERPRETER)
    if (!m_jitCodeForCall)
        Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
    else
#endif
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size());
#else
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
#endif

    return 0;
}
Example #2
0
JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex)
{
    SamplingRegion samplingRegion(samplingDescription(jitType));
    
#if !ENABLE(JIT)
    UNUSED_PARAM(jitType);
    UNUSED_PARAM(bytecodeIndex);
#endif
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    
    if (!!m_evalCodeBlock) {
        OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release()));
        m_evalCodeBlock = newCodeBlock.release();
    } else {
        UNUSED_PARAM(scope);
        UNUSED_PARAM(globalData);
        UNUSED_PARAM(lexicalGlobalObject);
        if (!lexicalGlobalObject->evalEnabled())
            return throwError(exec, createEvalError(exec, lexicalGlobalObject->evalDisabledErrorMessage()));

        JSObject* exception = 0;
        UnlinkedEvalCodeBlock* unlinkedEvalCode = lexicalGlobalObject->createEvalCodeBlock(exec, this, &exception);
        if (!unlinkedEvalCode)
            return exception;

        OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
        m_unlinkedEvalCodeBlock.set(*globalData, this, unlinkedEvalCode);
        m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, unlinkedEvalCode, lexicalGlobalObject, source().provider(), scope->localDepth(), previousCodeBlock.release()));
        m_evalCodeBlock->copyPostParseDataFromAlternative();
    }

#if ENABLE(JIT)
    if (!prepareForExecution(exec, m_evalCodeBlock, m_jitCodeForCall, jitType, bytecodeIndex))
        return 0;
#endif

#if ENABLE(JIT)
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size());
#else
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
#endif

    return 0;
}
Example #3
0
EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)
{
    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    if (!globalObject->evalEnabled()) {
        exec->vm().throwException(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
        return 0;
    }

    EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
    executable->finishCreation(exec->vm());

    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, variablesUnderTDZ);
    if (!unlinkedEvalCode)
        return 0;

    executable->m_unlinkedEvalCodeBlock.set(exec->vm(), executable, unlinkedEvalCode);

    return executable;
}
JSValue JSInjectedScriptHost::evaluate(ExecState* exec)
{
    JSValue expression = exec->argument(0);
    if (!expression.isString())
        return throwError(exec, createError(exec, "String argument expected."));
    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    JSFunction* evalFunction = globalObject->evalFunction();
    CallData callData;
    CallType callType = evalFunction->methodTable()->getCallData(evalFunction, callData);
    if (callType == CallTypeNone)
        return jsUndefined();
    MarkedArgumentBuffer args;
    args.append(expression);

    bool wasEvalEnabled = globalObject->evalEnabled();
    globalObject->setEvalEnabled(true);
    JSValue result = JSC::call(exec, evalFunction, callType, callData, exec->globalThisValue(), args);
    globalObject->setEvalEnabled(wasEvalEnabled);

    return result;
}
Example #5
0
EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, DerivedContextType derivedContextType, bool isArrowFunctionContext, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    if (!globalObject->evalEnabled()) {
        throwException(exec, scope, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
        return 0;
    }

    EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext, derivedContextType, isArrowFunctionContext, evalContextType);
    executable->finishCreation(vm);

    UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, variablesUnderTDZ);
    if (!unlinkedEvalCode)
        return 0;

    executable->m_unlinkedEvalCodeBlock.set(vm, executable, unlinkedEvalCode);

    return executable;
}
Example #6
0
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
#if !ENABLE(JIT)
    UNUSED_PARAM(jitType);
#endif
    JSObject* exception = 0;
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    if (!lexicalGlobalObject->evalEnabled())
        return throwError(exec, createEvalError(exec, "Eval is disabled"));
    RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
    if (!evalNode) {
        ASSERT(exception);
        return exception;
    }
    recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());

    JSGlobalObject* globalObject = scopeChainNode->globalObject.get();

    OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
    ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    if ((exception = generator->generate())) {
        m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
        evalNode->destroyData();
        return exception;
    }

    evalNode->destroyData();
    m_evalCodeBlock->copyDataFromAlternative();

#if ENABLE(JIT)
    if (exec->globalData().canUseJIT()) {
        bool dfgCompiled = false;
        if (jitType == JITCode::DFGJIT)
            dfgCompiled = DFG::tryCompile(exec, m_evalCodeBlock.get(), m_jitCodeForCall);
        if (dfgCompiled)
            ASSERT(!m_evalCodeBlock->alternative() || !m_evalCodeBlock->alternative()->hasIncomingCalls());
        else {
            if (m_evalCodeBlock->alternative()) {
                // There is already an alternative piece of code compiled with a different
                // JIT, so we can silently fail.
                m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
                return 0;
            }
            m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock.get());
        }
#if !ENABLE(OPCODE_SAMPLING)
        if (!BytecodeGenerator::dumpsGeneratedCode())
            m_evalCodeBlock->discardBytecode();
#endif
        m_evalCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
    }
#endif

#if ENABLE(JIT)
#if ENABLE(INTERPRETER)
    if (!m_jitCodeForCall)
        Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
    else
#endif
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size());
#else
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
#endif

    return 0;
}