UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, bool bodyIncludesBraces, ParserError& error) { switch (specializationKind) { case CodeForCall: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) return codeBlock; break; case CodeForConstruct: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) return codeBlock; break; } UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, this, source, specializationKind, debuggerMode, profilerMode, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, bodyIncludesBraces, error); if (error.m_type != ParserError::ErrorNone) return 0; switch (specializationKind) { case CodeForCall: m_codeBlockForCall.set(vm, this, result); m_symbolTableForCall.set(vm, this, result->symbolTable()); break; case CodeForConstruct: m_codeBlockForConstruct.set(vm, this, result); m_symbolTableForConstruct.set(vm, this, result->symbolTable()); break; } return result; }
UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData& globalData, JSScope* scope, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { switch (specializationKind) { case CodeForCall: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) return codeBlock; break; case CodeForConstruct: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) return codeBlock; break; } UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(globalData, scope, this, source, specializationKind, debuggerMode, profilerMode, error); if (error.m_type != ParserError::ErrorNone) return 0; switch (specializationKind) { case CodeForCall: m_codeBlockForCall.set(globalData, this, result); m_symbolTableForCall.set(globalData, this, result->symbolTable()); break; case CodeForConstruct: m_codeBlockForConstruct.set(globalData, this, result); m_symbolTableForConstruct.set(globalData, this, result->symbolTable()); break; } return result; }
UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor( VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, bool isArrowFunction) { switch (specializationKind) { case CodeForCall: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) return codeBlock; break; case CodeForConstruct: if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) return codeBlock; break; } UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock( vm, this, source, specializationKind, debuggerMode, profilerMode, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, error, isArrowFunction); if (error.isValid()) return nullptr; switch (specializationKind) { case CodeForCall: m_codeBlockForCall.set(vm, this, result); break; case CodeForConstruct: m_codeBlockForConstruct.set(vm, this, result); break; } return result; }
UnlinkedFunctionCodeBlock* CodeCache::getFunctionCodeBlock(JSGlobalData& globalData, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { if (debuggerMode == DebuggerOn || profilerMode == ProfilerOn) return generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error); SourceCode functionSource(source.provider(), executable->functionStartOffset(), source.endOffset(), source.firstLine()); CodeBlockKey key = makeCodeBlockKey(functionSource, kind == CodeForCall ? FunctionCallType : FunctionConstructType, executable->isInStrictContext() ? JSParseStrict : JSParseNormal); if (const Strong<UnlinkedFunctionCodeBlock>* cacheEntry = m_cachedFunctionExecutables.find(key)) { if (cacheEntry) { UnlinkedFunctionCodeBlock* unlinkedCode = cacheEntry->get(); unsigned firstLine = source.firstLine() + unlinkedCode->firstLine(); executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount()); m_recentlyUsedFunctionCode.add(unlinkedCode, *cacheEntry); return unlinkedCode; } } UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error); m_cachedFunctionExecutables.add(key, Strong<UnlinkedFunctionCodeBlock>(globalData, result)); return result; }
UnlinkedFunctionCodeBlock* CodeCache::getFunctionCodeBlock(JSGlobalData& globalData, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) { return generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error); }