UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, ParserError& error) { GlobalFunctionKey key = makeGlobalFunctionKey(source, name.string()); const Strong<UnlinkedFunctionExecutable>* result = m_cachedGlobalFunctions.find(key); if (result) return result->get(); RefPtr<ProgramNode> program = parse<ProgramNode>(&globalData, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error); if (!program) { ASSERT(error.m_type != ParserError::ErrorNone); return 0; } // This function assumes an input string that would result in a single anonymous function expression. 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); ASSERT(body->ident().isNull()); UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&globalData, source, body); functionExecutable->m_nameValue.set(globalData, functionExecutable, jsString(&globalData, name.string())); m_cachedGlobalFunctions.add(key, Strong<UnlinkedFunctionExecutable>(globalData, functionExecutable)); return functionExecutable; }
UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, ParserError& error) { SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal); CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue()); if (!addResult.isNewEntry) return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get()); RefPtr<ProgramNode> program = parse<ProgramNode>(&globalData, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error); if (!program) { ASSERT(error.m_type != ParserError::ErrorNone); m_sourceCode.remove(addResult.iterator); return 0; } // This function assumes an input string that would result in a single anonymous function expression. StatementNode* exprStatement = program->singleStatement(); ASSERT(exprStatement); ASSERT(exprStatement->isExprStatement()); ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); ASSERT(funcExpr); RELEASE_ASSERT(funcExpr->isFuncExprNode()); FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); ASSERT(body); ASSERT(body->ident().isNull()); UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&globalData, source, body); functionExecutable->m_nameValue.set(globalData, functionExecutable, jsString(&globalData, name.string())); addResult.iterator->value = SourceCodeValue(globalData, functionExecutable, m_sourceCode.age()); return functionExecutable; }
void WebDebugListenerImpl::sourceParsedFunctions(ExecState* execState, intptr_t sourceId, JSC::ParserArenaData<DeclarationStacks::FunctionStack>* funcStack) { if (m_listener && !m_inDebug) { m_inDebug = true; MarkedArgumentBuffer funcList; ArgList empty; Identifier functionName (execState, "functionName"); Identifier firstLine (execState, "firstLine"); Identifier lastLine (execState, "lastLine"); for(size_t i=0, l=funcStack->data.size(); i<l; i++) { FunctionBodyNode *funcBody = funcStack->data[i]; ASSERT(funcBody); if (!funcBody) continue; JSObject* funcObj = JSC::constructEmptyObject(execState); JSC::PutPropertySlot slot; funcObj->put(execState, functionName, jsString( execState, funcBody->ident().ustring() ), slot ); funcObj->put(execState, firstLine, jsNumber ( execState, funcBody->firstLine() ), slot ); funcObj->put(execState, lastLine, jsNumber ( execState, funcBody->lastLine() ), slot); funcList.append(funcObj); } JSObject* functions = JSC::constructArray(execState, funcList); WebScriptProxyVariant* functionsVariant = WebCore::ApolloScriptBridging::getApolloVariantForJSValue(execState, functions); m_listener->m_pVTable->sourceParsedFunctions(m_listener, sourceId, functionsVariant); m_inDebug = false; } }