Index: Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp =================================================================== --- Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (revision 268822) +++ Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (working copy) @@ -72,9 +72,9 @@ static UnlinkedFunctionCodeBlock* genera UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(vm, FunctionCode, ExecutableInfo(function->usesEval(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), executable->needsClassFieldInitializer(), false, isClassContext, EvalContextType::FunctionEvalContext), codeGenerationMode); - VariableEnvironment parentScopeTDZVariables = executable->parentScopeTDZVariables(); + auto parentScopeTDZVariables = executable->parentScopeTDZVariables(); ECMAMode ecmaMode = executable->isInStrictContext() ? ECMAMode::strict() : ECMAMode::sloppy(); - error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, &parentScopeTDZVariables, ecmaMode); + error = BytecodeGenerator::generate(vm, function.get(), source, result, codeGenerationMode, parentScopeTDZVariables, ecmaMode); if (error.isValid()) return nullptr; @@ -82,7 +82,7 @@ static UnlinkedFunctionCodeBlock* genera return result; } -UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, Optional parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor) +UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM& vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, Optional> parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor) : Base(vm, structure) , m_firstLineOffset(node->firstLine() - parentSource.firstLine().oneBasedInt()) , m_isInStrictContext(node->isInStrictContext()) Index: Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h =================================================================== --- Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (revision 268822) +++ Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (working copy) @@ -70,7 +70,7 @@ public: return &vm.unlinkedFunctionExecutableSpace.space; } - static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, Optional parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor = false) + static UnlinkedFunctionExecutable* create(VM& vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, Optional> parentScopeTDZVariables, DerivedContextType derivedContextType, NeedsClassFieldInitializer needsClassFieldInitializer, bool isBuiltinDefaultClassConstructor = false) { UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell(vm.heap)) UnlinkedFunctionExecutable(vm, vm.unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, scriptMode, WTFMove(parentScopeTDZVariables), derivedContextType, needsClassFieldInitializer, isBuiltinDefaultClassConstructor); @@ -168,11 +168,11 @@ public: return !m_rareData->m_classSource.isNull(); } - VariableEnvironment parentScopeTDZVariables() const + Vector parentScopeTDZVariables() const { - if (!m_rareData || !m_rareData->m_parentScopeTDZVariables) - return VariableEnvironment(); - return m_rareData->m_parentScopeTDZVariables.environment().toVariableEnvironment(); + if (!m_rareData || m_rareData->m_parentScopeTDZVariables.isEmpty()) + return { }; + return m_rareData->m_parentScopeTDZVariables; } bool isArrowFunction() const { return isArrowFunctionParseMode(parseMode()); } @@ -208,7 +208,7 @@ public: SourceCode m_classSource; String m_sourceURLDirective; String m_sourceMappingURLDirective; - CompactVariableMap::Handle m_parentScopeTDZVariables; + Vector m_parentScopeTDZVariables; Vector m_instanceFieldLocations; }; @@ -229,7 +229,7 @@ public: } private: - UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, Optional, JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, bool isBuiltinDefaultClassConstructor); + UnlinkedFunctionExecutable(VM&, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, Optional>, JSC::DerivedContextType, JSC::NeedsClassFieldInitializer, bool isBuiltinDefaultClassConstructor); UnlinkedFunctionExecutable(Decoder&, const CachedFunctionExecutable&); static void visitChildren(JSCell*, SlotVisitor&); Index: Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp =================================================================== --- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (revision 268822) +++ Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (working copy) @@ -48,6 +48,7 @@ #include "Options.h" #include "PrivateFieldPutKind.h" #include "StrongInlines.h" +#include "SuperSampler.h" #include "UnlinkedCodeBlock.h" #include "UnlinkedEvalCodeBlock.h" #include "UnlinkedFunctionCodeBlock.h" @@ -288,7 +289,7 @@ ParserError BytecodeGenerator::generate( return ParserError(ParserError::ErrorNone); } -BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables, ECMAMode ecmaMode) +BytecodeGenerator::BytecodeGenerator(VM& vm, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, OptionSet codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) : BytecodeGeneratorBase(makeUnique(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) , m_codeGenerationMode(codeGenerationMode) , m_scopeNode(programNode) @@ -300,11 +301,10 @@ BytecodeGenerator::BytecodeGenerator(VM& , m_isBuiltinFunction(false) , m_usesNonStrictEval(false) , m_inTailPosition(false) - , m_hasCachedVariablesUnderTDZ(false) , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) , m_ecmaMode(ecmaMode) { - ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); + ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables.size()); m_codeBlock->setNumParameters(1); // Allocate space for "this" @@ -336,7 +336,7 @@ BytecodeGenerator::BytecodeGenerator(VM& } } -BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet codeGenerationMode, const VariableEnvironment* parentScopeTDZVariables, ECMAMode ecmaMode) +BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, OptionSet codeGenerationMode, const CachedTDZStack& parentScopeTDZVariables, ECMAMode ecmaMode) : BytecodeGeneratorBase(makeUnique(vm, codeBlock), CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()) , m_codeGenerationMode(codeGenerationMode) , m_scopeNode(functionNode) @@ -355,7 +355,6 @@ BytecodeGenerator::BytecodeGenerator(VM& // // Note that we intentionally enable tail call for naked constructors since it does not have special code for "return". , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && ecmaMode.isStrict()) - , m_hasCachedVariablesUnderTDZ(false) , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) , m_ecmaMode(ecmaMode) , m_derivedContextType(codeBlock->derivedContextType()) @@ -364,6 +363,9 @@ BytecodeGenerator::BytecodeGenerator(VM& functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval); int symbolTableConstantIndex = 0; + m_parentScopeTDZVariables = parentScopeTDZVariables; + m_cachedVariablesUnderTDZ = m_parentScopeTDZVariables; + FunctionParameters& parameters = *functionNode->parameters(); // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation // This implements IsSimpleParameterList in the Ecma 2015 spec. @@ -770,10 +772,6 @@ BytecodeGenerator::BytecodeGenerator(VM& emitPutDerivedConstructorToArrowFunctionContextScope(); } - // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called - // because a function's default parameter ExpressionNodes will use temporary registers. - pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize, TDZRequirement::UnderTDZ); - Ref