static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock( VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, UnlinkedFunctionKind functionKind, ParserError& error, bool isArrowFunction) { JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin; JSParserStrictMode strictMode = executable->isInStrictContext() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; ASSERT(isFunctionParseMode(executable->parseMode())); std::unique_ptr<FunctionNode> function = parse<FunctionNode>( &vm, source, executable->name(), builtinMode, strictMode, executable->parseMode(), error, nullptr); if (!function) { ASSERT(error.isValid()); return nullptr; } function->finishParsing(executable->name(), executable->functionMode()); executable->recordParse(function->features(), function->hasCapturedVariables()); UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), isArrowFunction)); auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables())); error = generator->generate(); if (error.isValid()) return nullptr; return result; }
static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock( VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, UnlinkedFunctionKind functionKind, ParserError& error, SourceParseMode parseMode) { JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin; JSParserStrictMode strictMode = executable->isInStrictContext() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; ASSERT(isFunctionParseMode(executable->parseMode())); std::unique_ptr<FunctionNode> function = parse<FunctionNode>( &vm, source, executable->name(), builtinMode, strictMode, executable->parseMode(), executable->superBinding(), error, nullptr); if (!function) { ASSERT(error.isValid()); return nullptr; } function->finishParsing(executable->name(), executable->functionMode()); executable->recordParse(function->features(), function->hasCapturedVariables()); bool isClassContext = executable->superBinding() == SuperBinding::Needed; UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, EvalContextType::FunctionEvalContext), debuggerMode); error = BytecodeGenerator::generate(vm, function.get(), result, debuggerMode, executable->parentScopeTDZVariables()); if (error.isValid()) return nullptr; return result; }
// Evaluate some JavaScript code in the scope of this frame. JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSObject* scopeExtensionObject, NakedPtr<Exception>& exception) { ASSERT(isValid()); CallFrame* callFrame = m_validMachineFrame; if (!callFrame) return jsUndefined(); VM& vm = callFrame->vm(); JSLockHolder lock(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); CodeBlock* codeBlock = nullptr; if (isTailDeleted()) codeBlock = m_shadowChickenFrame.codeBlock; else codeBlock = callFrame->codeBlock(); if (!codeBlock) return jsUndefined(); DebuggerEvalEnabler evalEnabler(callFrame); EvalContextType evalContextType; if (isFunctionParseMode(codeBlock->unlinkedCodeBlock()->parseMode())) evalContextType = EvalContextType::FunctionEvalContext; else if (codeBlock->unlinkedCodeBlock()->codeType() == EvalCode) evalContextType = codeBlock->unlinkedCodeBlock()->evalContextType(); else evalContextType = EvalContextType::None; VariableEnvironment variablesUnderTDZ; JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ); EvalExecutable* eval = DirectEvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); return jsUndefined(); } JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject(); if (scopeExtensionObject) { JSScope* ignoredPreviousScope = globalObject->globalScope(); globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope)); } JSValue thisValue = this->thisValue(); JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope()); if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } if (scopeExtensionObject) globalObject->clearGlobalScopeExtension(); ASSERT(result); return result; }