void JavaScriptDebugServer::recompileAllJSFunctions(Timer<JavaScriptDebugServer>*)
{
    JSLock lock(false);
    JSGlobalData* globalData = JSDOMWindow::commonJSGlobalData();

    // If JavaScript is running, it's not safe to recompile, since we'll end
    // up throwing away code that is live on the stack.
    ASSERT(!globalData->dynamicGlobalObject);
    if (globalData->dynamicGlobalObject)
        return;

    Vector<ProtectedPtr<JSFunction> > functions;
    Heap::iterator heapEnd = globalData->heap.primaryHeapEnd();
    for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) {
        if ((*it)->isObject(&JSFunction::info))
            functions.append(static_cast<JSFunction*>(*it));
    }

    typedef HashMap<RefPtr<FunctionBodyNode>, RefPtr<FunctionBodyNode> > FunctionBodyMap;
    typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;

    FunctionBodyMap functionBodies;
    SourceProviderMap sourceProviders;

    size_t size = functions.size();
    for (size_t i = 0; i < size; ++i) {
        JSFunction* function = functions[i];

        FunctionBodyNode* oldBody = function->body();
        pair<FunctionBodyMap::iterator, bool> result = functionBodies.add(oldBody, 0);
        if (!result.second) {
            function->setBody(result.first->second.get());
            continue;
        }

        ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec();
        const SourceCode& sourceCode = oldBody->source();

        RefPtr<FunctionBodyNode> newBody = globalData->parser->parse<FunctionBodyNode>(exec, 0, sourceCode);
        ASSERT(newBody);
        newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount());

        result.first->second = newBody;
        function->setBody(newBody.release());

        if (hasListeners())
            sourceProviders.add(sourceCode.provider(), exec);
    }

    // Call sourceParsed() after reparsing all functions because it will execute
    // JavaScript in the inspector.
    SourceProviderMap::const_iterator end = sourceProviders.end();
    for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
        sourceParsed((*iter).second, SourceCode((*iter).first), -1, 0);
}
Exemplo n.º 2
0
FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception);
    if (!program) {
        ASSERT(*exception);
        return 0;
    }

    // Uses of this function that would not result in a single function expression are invalid.
    StatementNode* exprStatement = program->singleStatement();
    ASSERT(exprStatement);
    ASSERT(exprStatement->isExprStatement());
    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    ASSERT(funcExpr);
    ASSERT(funcExpr->isFuncExprNode());
    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    ASSERT(body);

    return FunctionExecutable::create(exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
Exemplo n.º 3
0
PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
{
    RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg);
    if (!program)
        return 0;

    StatementNode* exprStatement = program->singleStatement();
    ASSERT(exprStatement);
    ASSERT(exprStatement->isExprStatement());
    if (!exprStatement || !exprStatement->isExprStatement())
        return 0;

    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
    ASSERT(funcExpr);
    ASSERT(funcExpr->isFuncExprNode());
    if (!funcExpr || !funcExpr->isFuncExprNode())
        return 0;

    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
    ASSERT(body);
    return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
}