Changeset 193766 in webkit
- Timestamp:
- Dec 8, 2015 12:24:04 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 added
- 1 deleted
- 62 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r193755 r193766 1 2015-12-08 Skachkov Oleksandr <gskachkov@gmail.com> 2 3 [ES6] "super" and "this" should be lexically bound inside an arrow function and should live in a JSLexicalEnvironment 4 https://bugs.webkit.org/show_bug.cgi?id=149338 5 6 Reviewed by Saam Barati. 7 8 * js/arrowfunction-supercall-expected.txt: Added. 9 * js/arrowfunction-supercall.html: Added. 10 * js/arrowfunction-tdz-expected.txt: Added new expectation. 11 * js/script-tests/arrowfunction-supercall.js: Added. 12 * js/script-tests/arrowfunction-tdz.js: Added new cases. 13 1 14 2015-12-08 Brady Eidson <beidson@apple.com> 2 15 -
trunk/LayoutTests/js/arrowfunction-tdz-expected.txt
r193606 r193766 5 5 6 6 PASS isReferenceError is true 7 PASS isReferenceError is true 8 PASS d.id is 'a' 9 PASS e.id is 'a' 10 PASS f.id is 'a' 11 PASS isReferenceError is true 12 PASS g.id is 'a' 13 PASS h.id is 'a' 14 PASS i.id is 'a' 7 15 PASS successfullyParsed is true 8 16 -
trunk/LayoutTests/js/script-tests/arrowfunction-tdz.js
r193606 r193766 1 1 description('Tests for ES6 arrow function test tdz'); 2 2 3 var A = class A { }; 3 var A = class A { 4 constructor() { 5 this.id = 'a'; 6 } 7 }; 8 4 9 var B = class B extends A { 5 10 constructor(accessThisBeforeSuper) { 11 var f = () => this; 6 12 if (accessThisBeforeSuper) { 7 var f = () => this;13 f(); 8 14 super(); 9 15 } else { 10 16 super(); 17 f(); 11 18 } 12 19 } … … 22 29 shouldBe('isReferenceError', 'true'); 23 30 24 var e = new B(false); 31 var a = new B(false); 32 33 var D = class D extends A { 34 constructor(accessThisBeforeSuper, returnThis) { 35 var f = () => returnThis ? this : {}; 36 if (accessThisBeforeSuper) { 37 let val = f(); 38 super(); 39 } else { 40 super(); 41 let val = f(); 42 } 43 } 44 }; 45 46 isReferenceError = false; 47 try { 48 new D(true, true); 49 } catch (e) { 50 isReferenceError = e instanceof ReferenceError; 51 } 52 53 shouldBe('isReferenceError', 'true'); 54 55 var d = new D(false, true); 56 shouldBe('d.id', "'a'"); 57 var e = new D(false, false); 58 shouldBe('e.id', "'a'"); 59 var f = new D(true, false); 60 shouldBe('f.id', "'a'"); 61 62 var G = class G extends A { 63 constructor(accessThisBeforeSuper, returnThis) { 64 var f = () => returnThis ? (() => this ) : (()=>{}); 65 let af = f(); 66 if (accessThisBeforeSuper) { 67 let result = af(); 68 super(); 69 } else { 70 super(); 71 let result = af(); 72 } 73 } 74 }; 75 76 try { 77 new G(true, true); 78 } catch (e) { 79 exception = e; 80 isReferenceError = e instanceof ReferenceError; 81 } 82 83 shouldBe('isReferenceError', 'true'); 84 85 var g = new G(false, true); 86 shouldBe('g.id', "'a'"); 87 var h = new G(false, false); 88 shouldBe('h.id', "'a'"); 89 var i = new G(true, false); 90 shouldBe('i.id', "'a'"); 25 91 26 92 var successfullyParsed = true; -
trunk/Source/JavaScriptCore/ChangeLog
r193754 r193766 1 2015-12-05 Aleksandr Skachkov <gskachkov@gmail.com> 2 3 [ES6] "super" and "this" should be lexically bound inside an arrow function and should live in a JSLexicalEnvironment 4 https://bugs.webkit.org/show_bug.cgi?id=149338 5 6 Reviewed by Saam Barati. 7 8 Implemented new version of the lexically bound 'this' in arrow function. In current version 9 'this' is stored inside of the lexical environment of the function. To store and load we use 10 op_get_from_scope and op_put_to_scope operations. Also new implementation prevent raising TDZ 11 error for arrow functions that are declared before super() but invoke after. 12 13 * builtins/BuiltinExecutables.cpp: 14 (JSC::createExecutableInternal): 15 * bytecode/BytecodeList.json: 16 * bytecode/BytecodeUseDef.h: 17 * bytecode/CodeBlock.cpp: 18 (JSC::CodeBlock::dumpBytecode): 19 * bytecode/EvalCodeCache.h: 20 (JSC::EvalCodeCache::getSlow): 21 * bytecode/ExecutableInfo.h: 22 (JSC::ExecutableInfo::ExecutableInfo): 23 (JSC::ExecutableInfo::isDerivedConstructorContext): 24 (JSC::ExecutableInfo::isArrowFunctionContext): 25 * bytecode/UnlinkedCodeBlock.cpp: 26 (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): 27 * bytecode/UnlinkedCodeBlock.h: 28 (JSC::UnlinkedCodeBlock::isArrowFunction): 29 (JSC::UnlinkedCodeBlock::isDerivedConstructorContext): 30 (JSC::UnlinkedCodeBlock::isArrowFunctionContext): 31 * bytecode/UnlinkedFunctionExecutable.cpp: 32 (JSC::generateUnlinkedFunctionCodeBlock): 33 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 34 * bytecode/UnlinkedFunctionExecutable.h: 35 * bytecompiler/BytecodeGenerator.cpp: 36 (JSC::BytecodeGenerator::BytecodeGenerator): 37 (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded): 38 (JSC::BytecodeGenerator::variable): 39 (JSC::BytecodeGenerator::emitNewArrowFunctionExpression): 40 (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment): 41 (JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment): 42 (JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment): 43 (JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment): 44 (JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope): 45 (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope): 46 (JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope): 47 * bytecompiler/BytecodeGenerator.h: 48 (JSC::BytecodeGenerator::isDerivedConstructorContext): 49 (JSC::BytecodeGenerator::usesArrowFunction): 50 (JSC::BytecodeGenerator::needsToUpdateArrowFunctionContext): 51 (JSC::BytecodeGenerator::usesEval): 52 (JSC::BytecodeGenerator::usesThis): 53 (JSC::BytecodeGenerator::newTarget): 54 (JSC::BytecodeGenerator::makeFunction): 55 * bytecompiler/NodesCodegen.cpp: 56 (JSC::ThisNode::emitBytecode): 57 (JSC::SuperNode::emitBytecode): 58 (JSC::EvalFunctionCallNode::emitBytecode): 59 (JSC::FunctionCallValueNode::emitBytecode): 60 (JSC::FunctionNode::emitBytecode): 61 * debugger/DebuggerCallFrame.cpp: 62 (JSC::DebuggerCallFrame::evaluate): 63 * dfg/DFGAbstractInterpreterInlines.h: 64 * dfg/DFGByteCodeParser.cpp: 65 (JSC::DFG::ByteCodeParser::parseBlock): 66 * dfg/DFGCapabilities.cpp: 67 * dfg/DFGClobberize.h: 68 * dfg/DFGDoesGC.cpp: 69 * dfg/DFGFixupPhase.cpp: 70 * dfg/DFGNodeType.h: 71 * dfg/DFGObjectAllocationSinkingPhase.cpp: 72 * dfg/DFGPredictionPropagationPhase.cpp: 73 * dfg/DFGPromotedHeapLocation.cpp: 74 * dfg/DFGPromotedHeapLocation.h: 75 * dfg/DFGSafeToExecute.h: 76 * dfg/DFGSpeculativeJIT.cpp: 77 * dfg/DFGSpeculativeJIT.h: 78 * dfg/DFGSpeculativeJIT32_64.cpp: 79 * dfg/DFGSpeculativeJIT64.cpp: 80 * ftl/FTLCapabilities.cpp: 81 * ftl/FTLLowerDFGToLLVM.cpp: 82 * ftl/FTLOperations.cpp: 83 (JSC::FTL::operationMaterializeObjectInOSR): 84 * interpreter/Interpreter.cpp: 85 (JSC::eval): 86 * jit/JIT.cpp: 87 * jit/JIT.h: 88 * jit/JITOpcodes.cpp: 89 (JSC::JIT::emitNewFuncExprCommon): 90 * jit/JITOpcodes32_64.cpp: 91 * llint/LLIntSlowPaths.cpp: 92 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 93 * llint/LowLevelInterpreter.asm: 94 * llint/LowLevelInterpreter32_64.asm: 95 * llint/LowLevelInterpreter64.asm: 96 * parser/ASTBuilder.h: 97 (JSC::ASTBuilder::createArrowFunctionExpr): 98 (JSC::ASTBuilder::usesArrowFunction): 99 * parser/Nodes.h: 100 (JSC::ScopeNode::usesArrowFunction): 101 * parser/Parser.cpp: 102 (JSC::Parser<LexerType>::parseFunctionInfo): 103 * parser/ParserModes.h: 104 * runtime/CodeCache.cpp: 105 (JSC::CodeCache::getGlobalCodeBlock): 106 (JSC::CodeCache::getProgramCodeBlock): 107 (JSC::CodeCache::getEvalCodeBlock): 108 (JSC::CodeCache::getModuleProgramCodeBlock): 109 (JSC::CodeCache::getFunctionExecutableFromGlobalCode): 110 * runtime/CodeCache.h: 111 * runtime/CommonIdentifiers.h: 112 * runtime/CommonSlowPaths.cpp: 113 (JSC::SLOW_PATH_DECL): 114 * runtime/Executable.cpp: 115 (JSC::ScriptExecutable::ScriptExecutable): 116 (JSC::EvalExecutable::create): 117 (JSC::EvalExecutable::EvalExecutable): 118 (JSC::ProgramExecutable::ProgramExecutable): 119 (JSC::ModuleProgramExecutable::ModuleProgramExecutable): 120 (JSC::FunctionExecutable::FunctionExecutable): 121 * runtime/Executable.h: 122 (JSC::ScriptExecutable::isArrowFunctionContext): 123 (JSC::ScriptExecutable::isDerivedConstructorContext): 124 * runtime/JSGlobalObject.cpp: 125 (JSC::JSGlobalObject::createEvalCodeBlock): 126 * runtime/JSGlobalObject.h: 127 * runtime/JSGlobalObjectFunctions.cpp: 128 (JSC::globalFuncEval): 129 * tests/es6.yaml: 130 * tests/stress/arrowfunction-activation-sink-osrexit.js: 131 * tests/stress/arrowfunction-activation-sink.js: 132 * tests/stress/arrowfunction-lexical-bind-newtarget.js: Added. 133 * tests/stress/arrowfunction-lexical-bind-supercall-1.js: Added. 134 * tests/stress/arrowfunction-lexical-bind-supercall-2.js: Added. 135 * tests/stress/arrowfunction-lexical-bind-supercall-3.js: Added. 136 * tests/stress/arrowfunction-lexical-bind-supercall-4.js: Added. 137 * tests/stress/arrowfunction-lexical-bind-this-1.js: 138 * tests/stress/arrowfunction-lexical-bind-this-7.js: Added. 139 * tests/stress/arrowfunction-tdz-1.js: Added. 140 * tests/stress/arrowfunction-tdz-2.js: Added. 141 * tests/stress/arrowfunction-tdz-3.js: Added. 142 * tests/stress/arrowfunction-tdz-4.js: Added. 143 * tests/stress/arrowfunction-tdz.js: Removed. 144 1 145 2015-12-08 Csaba Osztrogonác <ossy@webkit.org> 2 146 -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r193606 r193766 116 116 metadata->overrideName(name); 117 117 VariableEnvironment dummyTDZVariables; 118 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, GeneratorThisMode::NonEmpty, dummyTDZVariables, WTF::move(sourceOverride));118 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, GeneratorThisMode::NonEmpty, dummyTDZVariables, false, WTF::move(sourceOverride)); 119 119 functionExecutable->setNameValue(vm, jsString(&vm, name.string())); 120 120 return functionExecutable; -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r193649 r193766 93 93 { "name" : "op_new_generator_func", "length" : 4 }, 94 94 { "name" : "op_new_generator_func_exp", "length" : 4 }, 95 { "name" : "op_new_arrow_func_exp", "length" : 5},95 { "name" : "op_new_arrow_func_exp", "length" : 4 }, 96 96 { "name" : "op_call", "length" : 9 }, 97 97 { "name" : "op_tail_call", "length" : 9 }, … … 130 130 { "name" : "op_enumerator_generic_pname", "length" : 4 }, 131 131 { "name" : "op_to_index_string", "length" : 3 }, 132 { "name" : "op_load_arrowfunction_this", "length" : 2 },133 132 { "name" : "op_assert", "length" : 3 }, 134 133 { "name" : "op_copy_rest", "length": 4 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r193649 r193766 59 59 case op_assert: 60 60 case op_get_scope: 61 case op_load_arrowfunction_this:62 61 case op_to_this: 63 62 case op_check_tdz: … … 396 395 case op_check_tdz: 397 396 case op_get_scope: 398 case op_load_arrowfunction_this:399 397 case op_create_direct_arguments: 400 398 case op_create_scoped_arguments: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r193674 r193766 770 770 break; 771 771 } 772 case op_load_arrowfunction_this: {773 int r0 = (++it)->u.operand;774 printLocationOpAndRegisterOperand(out, exec, location, it, "load_arrowfunction_this", r0);775 break;776 }777 772 case op_create_direct_arguments: { 778 773 int r0 = (++it)->u.operand; … … 1332 1327 int r1 = (++it)->u.operand; 1333 1328 int f0 = (++it)->u.operand; 1334 int r2 = (++it)->u.operand;1335 1329 printLocationAndOp(out, exec, location, it, "op_new_arrow_func_exp"); 1336 out.printf("%s, %s, f%d , %s", registerName(r0).data(), registerName(r1).data(), f0, registerName(r2).data());1330 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); 1337 1331 break; 1338 1332 } -
trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h
r193606 r193766 56 56 } 57 57 58 EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const SourceCode& evalSource, JSScope* scope)58 EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const SourceCode& evalSource, JSScope* scope) 59 59 { 60 60 VariableEnvironment variablesUnderTDZ; 61 61 JSScope::collectVariablesUnderTDZ(scope, variablesUnderTDZ); 62 EvalExecutable* evalExecutable = EvalExecutable::create(exec, evalSource, inStrictContext, thisTDZMode, &variablesUnderTDZ); 62 EvalExecutable* evalExecutable = EvalExecutable::create(exec, evalSource, inStrictContext, thisTDZMode, isDerivedConstructorContext, isArrowFunctionContext, &variablesUnderTDZ); 63 63 64 if (!evalExecutable) 64 65 return nullptr; -
trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h
r193606 r193766 35 35 // https://bugs.webkit.org/show_bug.cgi?id=151547 36 36 struct ExecutableInfo { 37 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, GeneratorThisMode generatorThisMode, SuperBinding superBinding, SourceParseMode parseMode )37 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, GeneratorThisMode generatorThisMode, SuperBinding superBinding, SourceParseMode parseMode, bool isDerivedConstructorContext, bool isArrowFunctionContext) 38 38 : m_needsActivation(needsActivation) 39 39 , m_usesEval(usesEval) … … 45 45 , m_superBinding(static_cast<unsigned>(superBinding)) 46 46 , m_parseMode(parseMode) 47 , m_isDerivedConstructorContext(isDerivedConstructorContext) 48 , m_isArrowFunctionContext(isArrowFunctionContext) 47 49 { 48 50 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind)); … … 60 62 SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); } 61 63 SourceParseMode parseMode() const { return m_parseMode; } 64 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; } 65 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } 62 66 63 67 private: … … 71 75 unsigned m_superBinding : 1; 72 76 SourceParseMode m_parseMode; 77 unsigned m_isDerivedConstructorContext : 1; 78 unsigned m_isArrowFunctionContext : 1; 73 79 }; 74 80 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r193606 r193766 68 68 , m_generatorThisMode(static_cast<unsigned>(info.generatorThisMode())) 69 69 , m_superBinding(static_cast<unsigned>(info.superBinding())) 70 , m_isDerivedConstructorContext(info.isDerivedConstructorContext()) 71 , m_isArrowFunctionContext(info.isArrowFunctionContext()) 70 72 , m_firstLine(0) 71 73 , m_lineCount(0) -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r193606 r193766 120 120 bool usesEval() const { return m_usesEval; } 121 121 SourceParseMode parseMode() const { return m_parseMode; } 122 bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; } 123 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; } 124 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } 122 125 123 126 bool needsFullScopeChain() const { return m_needsFullScopeChain; } … … 394 397 unsigned m_generatorThisMode : 1; 395 398 unsigned m_superBinding : 1; 399 unsigned m_isDerivedConstructorContext : 1; 400 unsigned m_isArrowFunctionContext : 1; 396 401 397 402 unsigned m_firstLine; -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
r193606 r193766 68 68 69 69 UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, 70 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->generatorThisMode(), executable->superBinding(), parseMode)); 70 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), executable->generatorThisMode(), executable->superBinding(), parseMode, executable->isDerivedConstructorContext(), false)); 71 71 72 auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables())); 72 73 error = generator->generate(); … … 76 77 } 77 78 78 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, GeneratorThisMode generatorThisMode, VariableEnvironment& parentScopeTDZVariables )79 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, GeneratorThisMode generatorThisMode, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext) 79 80 : Base(*vm, structure) 80 81 , m_name(node->ident()) … … 102 103 , m_generatorThisMode(static_cast<unsigned>(generatorThisMode)) 103 104 , m_superBinding(static_cast<unsigned>(node->superBinding())) 105 , m_isDerivedConstructorContext(isDerivedConstructorContext) 104 106 { 105 107 ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind())); -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
r193606 r193766 67 67 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 68 68 69 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, GeneratorThisMode generatorThisMode, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr)69 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, GeneratorThisMode generatorThisMode, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext, RefPtr<SourceProvider>&& sourceOverride = nullptr) 70 70 { 71 71 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) 72 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, generatorThisMode, parentScopeTDZVariables );72 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, generatorThisMode, parentScopeTDZVariables, isDerivedConstructorContext); 73 73 instance->finishCreation(*vm); 74 74 return instance; … … 129 129 bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; } 130 130 const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; } 131 132 bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; } 133 bool isDerivedConstructorContext() const {return m_isDerivedConstructorContext; } 131 134 132 135 private: 133 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, GeneratorThisMode, VariableEnvironment&); 136 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, GeneratorThisMode, VariableEnvironment&, bool isDerivedConstructorContext); 137 134 138 WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall; 135 139 WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct; … … 163 167 unsigned m_generatorThisMode : 1; 164 168 unsigned m_superBinding : 1; 169 unsigned m_isDerivedConstructorContext : 1; 165 170 166 171 protected: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r193649 r193766 158 158 , m_codeType(GlobalCode) 159 159 , m_vm(&vm) 160 , m_isDerivedConstructorContext(false) 161 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) 160 162 { 161 163 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); … … 188 190 // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables() 189 191 // to the TDZ stack. 192 193 if (needsToUpdateArrowFunctionContext()) { 194 initializeArrowFunctionContextScopeIfNeeded(); 195 emitPutThisToArrowFunctionContextScope(); 196 } 190 197 } 191 198 … … 205 212 // https://bugs.webkit.org/show_bug.cgi?id=148819 206 213 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode() && !m_shouldEmitProfileHooks) 214 , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext()) 215 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) 207 216 { 208 217 for (auto& constantRegister : m_linkTimeConstantRegisters) … … 231 240 232 241 SourceParseMode parseMode = codeBlock->parseMode(); 233 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain(); 242 243 bool containsArrowOrEvalButNotInArrowBlock = needsToUpdateArrowFunctionContext() && !m_codeBlock->isArrowFunction(); 244 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain() || containsArrowOrEvalButNotInArrowBlock; 245 234 246 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); 235 247 bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval(); … … 511 523 switch (parseMode) { 512 524 case SourceParseMode::ArrowFunctionMode: { 513 if (functionNode->usesThis() || codeBlock->usesEval())514 emitLoad ArrowFunctionThis(&m_thisRegister);525 if (functionNode->usesThis()) 526 emitLoadThisFromArrowFunctionLexicalEnvironment(); 515 527 break; 516 528 } … … 563 575 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, functionNode, functionSymbolTable, symbolTableConstantIndex, captures); 564 576 577 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) { 578 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable); 579 emitPutThisToArrowFunctionContextScope(); 580 emitPutNewTargetToArrowFunctionContextScope(); 581 emitPutDerivedConstructorToArrowFunctionContextScope(); 582 } 583 565 584 pushLexicalScope(m_scopeNode, true); 566 585 } … … 575 594 , m_vm(&vm) 576 595 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode()) 596 , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext()) 597 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval()) 577 598 { 578 599 for (auto& constantRegister : m_linkTimeConstantRegisters) … … 604 625 m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false)); 605 626 627 if (codeBlock->isArrowFunctionContext() && evalNode->usesThis()) 628 emitLoadThisFromArrowFunctionLexicalEnvironment(); 629 630 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext()) { 631 initializeArrowFunctionContextScopeIfNeeded(); 632 emitPutThisToArrowFunctionContextScope(); 633 } 634 606 635 pushLexicalScope(m_scopeNode, true); 607 636 } … … 616 645 , m_vm(&vm) 617 646 , m_usesNonStrictEval(false) 647 , m_isDerivedConstructorContext(false) 648 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval()) 618 649 { 619 650 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); … … 849 880 } 850 881 } 882 } 883 884 void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* symbolTable) 885 { 886 if (m_arrowFunctionContextLexicalEnvironmentRegister != nullptr) 887 return; 888 889 if (m_lexicalEnvironmentRegister != nullptr) { 890 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister; 891 892 if (!m_codeBlock->isArrowFunction()) { 893 ScopeOffset offset; 894 895 offset = symbolTable->takeNextScopeOffset(); 896 symbolTable->set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset))); 897 898 if (m_codeType == FunctionCode) { 899 offset = symbolTable->takeNextScopeOffset(); 900 symbolTable->set(propertyNames().newTargetLocalPrivateName.impl(), SymbolTableEntry(VarOffset(offset))); 901 } 902 903 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 904 offset = symbolTable->takeNextScopeOffset(); 905 symbolTable->set(propertyNames().derivedConstructorPrivateName.impl(), SymbolTableEntry(VarOffset(offset))); 906 } 907 } 908 909 return; 910 } 911 912 VariableEnvironment environment; 913 auto addResult = environment.add(propertyNames().thisIdentifier); 914 addResult.iterator->value.setIsCaptured(); 915 addResult.iterator->value.setIsConst(); 916 917 if (m_codeType == FunctionCode) { 918 auto addTarget = environment.add(propertyNames().newTargetLocalPrivateName); 919 addTarget.iterator->value.setIsCaptured(); 920 addTarget.iterator->value.setIsLet(); 921 } 922 923 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 924 auto derivedConstructor = environment.add(propertyNames().derivedConstructorPrivateName); 925 derivedConstructor.iterator->value.setIsCaptured(); 926 derivedConstructor.iterator->value.setIsLet(); 927 } 928 929 size_t size = m_symbolTableStack.size(); 930 pushLexicalScopeInternal(environment, true, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block); 931 932 ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1); 933 934 m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope; 851 935 } 852 936 … … 1900 1984 } 1901 1985 1902 Variable BytecodeGenerator::variable(const Identifier& property )1903 { 1904 if (property == propertyNames().thisIdentifier ) {1986 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType) 1987 { 1988 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) { 1905 1989 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(), 1906 1990 ReadOnly, Variable::SpecialVariable, 0, false); … … 2597 2681 instructions().append(scopeRegister()->index()); 2598 2682 instructions().append(index); 2599 2600 if (opcodeID == op_new_arrow_func_exp)2601 instructions().append(thisRegister()->index());2602 2683 } 2603 2684 … … 2610 2691 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func) 2611 2692 { 2612 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode); 2613 bool isClassConstructor = m_codeBlock->isConstructor() && constructorKind() != ConstructorKind::None; 2614 if (isClassConstructor || generatorThisMode() == GeneratorThisMode::Empty) 2615 emitTDZCheck(thisRegister()); 2616 2693 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode); 2617 2694 emitNewFunctionExpressionCommon(dst, func); 2618 2695 return dst; … … 3222 3299 m_topMostScope = addVar(); 3223 3300 emitMove(m_topMostScope, scopeRegister()); 3224 }3225 3226 RegisterID* BytecodeGenerator::emitLoadArrowFunctionThis(RegisterID* arrowFunctionThis)3227 {3228 emitOpcode(op_load_arrowfunction_this);3229 instructions().append(arrowFunctionThis->index());3230 return arrowFunctionThis;3231 3301 } 3232 3302 … … 3916 3986 } 3917 3987 3988 RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment() 3989 { 3990 ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived); 3991 3992 return emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped)); 3993 } 3994 3995 void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment() 3996 { 3997 emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound); 3998 } 3999 4000 RegisterID* BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment() 4001 { 4002 m_isNewTargetLoadedInArrowFunction = true; 4003 4004 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 4005 emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound)); 4006 4007 return m_newTargetRegister; 4008 } 4009 4010 RegisterID* BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment() 4011 { 4012 Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName); 4013 return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound); 4014 } 4015 4016 void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope() 4017 { 4018 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 4019 4020 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 4021 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization); 4022 } 4023 4024 void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope() 4025 { 4026 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 4027 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister); 4028 4029 Variable protoScope = variable(propertyNames().derivedConstructorPrivateName); 4030 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization); 4031 } 4032 } 4033 4034 void BytecodeGenerator::emitPutThisToArrowFunctionContextScope() 4035 { 4036 ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 4037 4038 Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped); 4039 RegisterID* scope = isDerivedConstructorContext() ? emitLoadArrowFunctionLexicalEnvironment() : m_arrowFunctionContextLexicalEnvironmentRegister; 4040 4041 emitPutToScope(scope, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization); 4042 } 4043 3918 4044 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister) 3919 4045 { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r193649 r193766 67 67 }; 68 68 69 enum class ThisResolutionType { Local, Scoped }; 70 69 71 class CallArguments { 70 72 public: … … 281 283 282 284 bool isConstructor() const { return m_codeBlock->isConstructor(); } 285 bool isDerivedConstructorContext() const { return m_codeBlock->isDerivedConstructorContext(); } 286 bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); } 287 bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; } 288 bool usesEval() const { return m_scopeNode->usesEval(); } 289 bool usesThis() const { return m_scopeNode->usesThis(); } 283 290 ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); } 284 291 GeneratorThisMode generatorThisMode() const { return m_codeBlock->generatorThisMode(); } … … 289 296 bool isArgumentNumber(const Identifier&, int); 290 297 291 Variable variable(const Identifier& );298 Variable variable(const Identifier&, ThisResolutionType = ThisResolutionType::Local); 292 299 293 300 enum ExistingVariableMode { VerifyExisting, IgnoreExisting }; … … 297 304 RegisterID* thisRegister() { return &m_thisRegister; } 298 305 RegisterID* argumentsRegister() { return m_argumentsRegister; } 299 RegisterID* newTarget() { return m_newTargetRegister; } 306 RegisterID* newTarget() 307 { 308 return !m_codeBlock->isArrowFunction() || m_isNewTargetLoadedInArrowFunction 309 ? m_newTargetRegister : emitLoadNewTargetFromArrowFunctionLexicalEnvironment(); 310 } 300 311 301 312 RegisterID* scopeRegister() { return m_scopeRegister; } … … 485 496 486 497 void emitProfileControlFlow(int); 498 499 RegisterID* emitLoadArrowFunctionLexicalEnvironment(); 500 void emitLoadThisFromArrowFunctionLexicalEnvironment(); 501 RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment(); 487 502 488 503 RegisterID* emitLoad(RegisterID* dst, bool); … … 631 646 RegisterID* emitPushWithScope(RegisterID* objectScope); 632 647 void emitPopWithScope(); 648 void emitPutThisToArrowFunctionContextScope(); 649 void emitPutNewTargetToArrowFunctionContextScope(); 650 void emitPutDerivedConstructorToArrowFunctionContextScope(); 651 RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(); 633 652 634 653 void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart); … … 723 742 void allocateCalleeSaveSpace(); 724 743 void allocateAndEmitScope(); 725 RegisterID* emitLoadArrowFunctionThis(RegisterID*);726 744 void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope); 727 745 … … 775 793 UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata) 776 794 { 795 bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->parseMode() == SourceParseMode::ArrowFunctionMode); 796 777 797 VariableEnvironment variablesUnderTDZ; 778 798 getVariablesUnderTDZ(variablesUnderTDZ); … … 793 813 generatorThisMode = GeneratorThisMode::Empty; 794 814 795 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, generatorThisMode, variablesUnderTDZ );815 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, generatorThisMode, variablesUnderTDZ, newisDerivedConstructorContext); 796 816 } 797 817 … … 804 824 void initializeVarLexicalEnvironment(int symbolTableConstantIndex); 805 825 void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures); 826 void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* = nullptr); 806 827 807 828 public: … … 846 867 RegisterID* m_newTargetRegister { nullptr }; 847 868 RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount]; 869 RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr }; 848 870 849 871 SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters; … … 901 923 bool m_usesNonStrictEval { false }; 902 924 bool m_inTailPosition { false }; 925 bool m_isDerivedConstructorContext { false }; 926 bool m_needsToUpdateArrowFunctionContext; 927 bool m_isNewTargetLoadedInArrowFunction { false }; 903 928 }; 904 929 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r193606 r193766 147 147 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 148 148 { 149 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.generatorThisMode() == GeneratorThisMode::Empty) 149 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 150 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); 151 152 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.generatorThisMode() == GeneratorThisMode::Empty || generator.isDerivedConstructorContext()) 150 153 generator.emitTDZCheck(generator.thisRegister()); 151 154 … … 165 168 if (dst == generator.ignoredResult()) 166 169 return 0; 170 171 if (generator.isDerivedConstructorContext()) 172 return generator.emitGetById(generator.finalDestination(dst), generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(), generator.propertyNames().underscoreProto); 167 173 168 174 RegisterID callee; … … 697 703 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 698 704 { 705 // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function 706 // var A = class A { 707 // constructor () { this.id = 'A'; } 708 // } 709 // 710 // var B = class B extend A { 711 // constructor () { 712 // var arrow = () => super(); 713 // arrow(); 714 // eval("this.id = 'B'"); 715 // } 716 // } 717 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 718 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); 719 699 720 Variable var = generator.variable(generator.propertyNames().eval); 700 721 if (RegisterID* local = var.local()) { … … 724 745 CallArguments callArguments(generator, m_args); 725 746 if (m_expr->isSuperNode()) { 726 ASSERT(generator.isConstructor() );727 ASSERT(generator.constructorKind() == ConstructorKind::Derived );747 ASSERT(generator.isConstructor() || generator.isDerivedConstructorContext()); 748 ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext()); 728 749 generator.emitMove(callArguments.thisRegister(), generator.newTarget()); 729 750 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); 730 751 generator.emitMove(generator.thisRegister(), ret); 752 753 bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived; 754 if (generator.isDerivedConstructorContext() || (isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext())) 755 generator.emitPutThisToArrowFunctionContextScope(); 756 731 757 return ret; 732 758 } … … 3053 3079 // If there is no return we must automatically insert one. 3054 3080 if (!returnNode) { 3081 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 3082 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment 3083 3055 3084 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); 3056 3085 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code. -
trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
r193606 r193766 197 197 JSScope::collectVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ); 198 198 199 EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode, &variablesUnderTDZ);199 EvalExecutable* eval = EvalExecutable::create(callFrame, makeSource(script), codeBlock.isStrictMode(), thisTDZMode, codeBlock.unlinkedCodeBlock()->isDerivedConstructorContext(), codeBlock.unlinkedCodeBlock()->isArrowFunction(), &variablesUnderTDZ); 200 200 if (vm.exception()) { 201 201 exception = vm.exception(); -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r193606 r193766 1811 1811 break; 1812 1812 1813 case LoadArrowFunctionThis:1814 if (JSValue base = forNode(node->child1()).m_value) {1815 JSArrowFunction* function = jsDynamicCast<JSArrowFunction*>(base);1816 setConstant(node, *m_graph.freeze(function->boundThis()));1817 break;1818 }1819 forNode(node).setType(m_graph, SpecFinalObject);1820 break;1821 1822 1813 case SkipScope: { 1823 1814 JSValue child = forNode(node->child1()).value(); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r193649 r193766 4509 4509 NEXT_OPCODE(op_get_scope); 4510 4510 } 4511 4512 case op_load_arrowfunction_this: {4513 Node* callee = get(VirtualRegister(JSStack::Callee));4514 Node* result;4515 if (JSArrowFunction* function = callee->dynamicCastConstant<JSArrowFunction*>())4516 result = jsConstant(function->boundThis());4517 else4518 result = addToGraph(LoadArrowFunctionThis, callee);4519 set(VirtualRegister(currentInstruction[1].u.operand), result);4520 NEXT_OPCODE(op_load_arrowfunction_this);4521 }4522 4511 4523 4512 case op_create_direct_arguments: { … … 4569 4558 } 4570 4559 4571 case op_new_func_exp: { 4560 case op_new_func_exp: 4561 case op_new_arrow_func_exp: { 4572 4562 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4573 4563 FrozenValue* frozen = m_graph.freezeStrong(expr); 4574 4564 set(VirtualRegister(currentInstruction[1].u.operand), 4575 4565 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4576 NEXT_OPCODE(op_new_func_exp); 4577 } 4578 4579 case op_new_arrow_func_exp: { 4580 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4581 FrozenValue* frozen = m_graph.freezeStrong(expr); 4582 4583 set(VirtualRegister(currentInstruction[1].u.operand), 4584 addToGraph(NewArrowFunction, OpInfo(frozen), 4585 get(VirtualRegister(currentInstruction[2].u.operand)), 4586 get(VirtualRegister(currentInstruction[4].u.operand)))); 4587 4588 NEXT_OPCODE(op_new_arrow_func_exp); 4566 4567 if (opcodeID == op_new_func_exp) { 4568 // Curly braces are necessary 4569 NEXT_OPCODE(op_new_func_exp); 4570 } else { 4571 // Curly braces are necessary 4572 NEXT_OPCODE(op_new_arrow_func_exp); 4573 } 4589 4574 } 4590 4575 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r193649 r193766 204 204 case op_in: 205 205 case op_get_scope: 206 case op_load_arrowfunction_this:207 206 case op_get_from_scope: 208 207 case op_get_enumerable_length: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r193606 r193766 140 140 case ArithLog: 141 141 case GetScope: 142 case LoadArrowFunctionThis:143 142 case SkipScope: 144 143 case StringCharCodeAt: -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r193606 r193766 108 108 case CheckArray: 109 109 case GetScope: 110 case LoadArrowFunctionThis:111 110 case SkipScope: 112 111 case GetClosureVar: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r193606 r193766 1024 1024 fixEdge<KnownCellUse>(node->child1()); 1025 1025 speculateForBarrier(node->child2()); 1026 break;1027 }1028 1029 case LoadArrowFunctionThis: {1030 fixEdge<KnownCellUse>(node->child1());1031 1026 break; 1032 1027 } -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r193606 r193766 208 208 macro(GetArrayLength, NodeResultInt32) \ 209 209 macro(GetTypedArrayByteOffset, NodeResultInt32) \ 210 macro(LoadArrowFunctionThis, NodeResultJS) \211 210 macro(GetScope, NodeResultJS) \ 212 211 macro(SkipScope, NodeResultJS) \ -
trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
r193606 r193766 839 839 case NewFunction: 840 840 case NewArrowFunction: { 841 bool isArrowFunction = node->op() == NewArrowFunction;842 841 if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) { 843 842 m_heap.escape(node->child1().node()); … … 845 844 } 846 845 847 target = &m_heap.newAllocation(node, isArrowFunction ? Allocation::Kind::NewArrowFunction :Allocation::Kind::Function);846 target = &m_heap.newAllocation(node, Allocation::Kind::Function); 848 847 writes.add(FunctionExecutablePLoc, LazyNode(node->cellOperand())); 849 848 writes.add(FunctionActivationPLoc, LazyNode(node->child1().node())); 850 if (isArrowFunction)851 writes.add(ArrowFunctionBoundThisPLoc, LazyNode(node->child2().node()));852 849 break; 853 850 } … … 1019 1016 break; 1020 1017 1021 case LoadArrowFunctionThis:1022 target = m_heap.onlyLocalAllocation(node->child1().node());1023 if (target && target->isArrowFunctionAllocation())1024 exactRead = ArrowFunctionBoundThisPLoc;1025 else1026 m_heap.escape(node->child1().node());1027 break;1028 1029 1018 case GetScope: 1030 1019 target = m_heap.onlyLocalAllocation(node->child1().node()); … … 2046 2035 case NewFunction: 2047 2036 case NewArrowFunction: { 2048 bool isArrowFunction = node->op() == NewArrowFunction;2049 2037 Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee); 2050 ASSERT(locations.size() == (isArrowFunction ? 3 : 2));2038 ASSERT(locations.size() == 2); 2051 2039 2052 2040 PromotedHeapLocation executable(FunctionExecutablePLoc, allocation.identifier()); … … 2057 2045 2058 2046 node->child1() = Edge(resolve(block, activation), KnownCellUse); 2059 2060 if (isArrowFunction) {2061 PromotedHeapLocation boundThis(ArrowFunctionBoundThisPLoc, allocation.identifier());2062 ASSERT(locations.contains(boundThis));2063 node->child2() = Edge(resolve(block, boundThis), CellUse);2064 }2065 2066 2047 break; 2067 2048 } -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r193606 r193766 615 615 case GetScope: 616 616 changed |= setPrediction(SpecObjectOther); 617 break;618 619 case LoadArrowFunctionThis:620 changed |= setPrediction(SpecFinalObject);621 617 break; 622 618 -
trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
r193606 r193766 103 103 out.print("ClosureVarPLoc"); 104 104 return; 105 106 case ArrowFunctionBoundThisPLoc:107 out.print("ArrowFunctionBoundThisPLoc");108 return;109 105 } 110 106 -
trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h
r193606 r193766 47 47 FunctionActivationPLoc, 48 48 ActivationScopePLoc, 49 ClosureVarPLoc, 50 ArrowFunctionBoundThisPLoc 49 ClosureVarPLoc 51 50 }; 52 51 -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r193606 r193766 203 203 case ArrayifyToStructure: 204 204 case GetScope: 205 case LoadArrowFunctionThis:206 205 case SkipScope: 207 206 case GetClosureVar: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r193606 r193766 4843 4843 cellResult(result.gpr(), node); 4844 4844 } 4845 4846 4847 void SpeculativeJIT::compileLoadArrowFunctionThis(Node* node)4848 {4849 SpeculateCellOperand function(this, node->child1());4850 GPRTemporary result(this, Reuse, function);4851 m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSArrowFunction::offsetOfThisValue()), result.gpr());4852 cellResult(result.gpr(), node);4853 }4854 4845 4855 4846 void SpeculativeJIT::compileSkipScope(Node* node) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r193606 r193766 2201 2201 2202 2202 void compileGetScope(Node*); 2203 void compileLoadArrowFunctionThis(Node*);2204 2203 void compileSkipScope(Node*); 2205 2204 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r193649 r193766 3800 3800 compileGetScope(node); 3801 3801 break; 3802 3803 case LoadArrowFunctionThis:3804 compileLoadArrowFunctionThis(node);3805 break;3806 3802 3807 3803 case SkipScope: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r193649 r193766 3838 3838 break; 3839 3839 3840 case LoadArrowFunctionThis:3841 compileLoadArrowFunctionThis(node);3842 break;3843 3844 3840 case SkipScope: 3845 3841 compileSkipScope(node); -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r193606 r193766 153 153 case GetExecutable: 154 154 case GetScope: 155 case LoadArrowFunctionThis:156 155 case GetCallee: 157 156 case GetArgumentCount: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r193682 r193766 832 832 case GetScope: 833 833 compileGetScope(); 834 break;835 case LoadArrowFunctionThis:836 compileLoadArrowFunctionThis();837 834 break; 838 835 case SkipScope: … … 4581 4578 } 4582 4579 4583 void compileLoadArrowFunctionThis()4584 {4585 setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrowFunction_this));4586 }4587 4588 4580 void compileSkipScope() 4589 4581 { -
trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp
r193606 r193766 165 165 FunctionExecutable* executable = nullptr; 166 166 JSScope* activation = nullptr; 167 JSValue boundThis;168 bool isArrowFunction = false;169 167 for (unsigned i = materialization->properties().size(); i--;) { 170 168 const ExitPropertyValue& property = materialization->properties()[i]; … … 173 171 if (property.location() == PromotedLocationDescriptor(FunctionActivationPLoc)) 174 172 activation = jsCast<JSScope*>(JSValue::decode(values[i])); 175 if (property.location() == PromotedLocationDescriptor(ArrowFunctionBoundThisPLoc)) {176 isArrowFunction = true;177 boundThis = JSValue::decode(values[i]);178 }179 173 } 180 174 RELEASE_ASSERT(executable && activation); 181 175 182 176 183 JSFunction* result = isArrowFunction 184 ? JSArrowFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation, boundThis) 185 : JSFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation); 177 JSFunction* result = JSFunction::createWithInvalidatedReallocationWatchpoint(vm, executable, activation); 186 178 187 179 return result; -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r193636 r193766 181 181 ASSERT(!callFrame->vm().exception()); 182 182 183 eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, sourceCode, callerScopeChain); 183 eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, callerCodeBlock->unlinkedCodeBlock()->isDerivedConstructorContext(), callerCodeBlock->unlinkedCodeBlock()->isArrowFunction(), sourceCode, callerScopeChain); 184 184 185 if (!eval) 185 186 return jsUndefined(); -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r193649 r193766 224 224 DEFINE_OP(op_enter) 225 225 DEFINE_OP(op_get_scope) 226 DEFINE_OP(op_load_arrowfunction_this)227 226 DEFINE_OP(op_eq) 228 227 DEFINE_OP(op_eq_null) -
trunk/Source/JavaScriptCore/jit/JIT.h
r193649 r193766 503 503 void emit_op_enter(Instruction*); 504 504 void emit_op_get_scope(Instruction*); 505 void emit_op_load_arrowfunction_this(Instruction*);506 505 void emit_op_eq(Instruction*); 507 506 void emit_op_eq_null(Instruction*); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r193754 r193766 668 668 emitStoreCell(dst, regT0); 669 669 } 670 671 void JIT::emit_op_load_arrowfunction_this(Instruction* currentInstruction)672 {673 int dst = currentInstruction[1].u.operand;674 emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);675 loadPtr(Address(regT0, JSArrowFunction::offsetOfThisValue()), regT0);676 emitStoreCell(dst, regT0);677 }678 670 679 671 void JIT::emit_op_to_this(Instruction* currentInstruction) … … 972 964 void JIT::emitNewFuncExprCommon(Instruction* currentInstruction) 973 965 { 974 OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);975 bool isArrowFunction = opcodeID == op_new_arrow_func_exp;976 977 966 Jump notUndefinedScope; 978 967 int dst = currentInstruction[1].u.operand; 979 968 #if USE(JSVALUE64) 980 969 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); 981 if (isArrowFunction)982 emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);983 970 notUndefinedScope = branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsUndefined()))); 984 971 store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, sizeof(Register) * dst)); 985 972 #else 986 973 emitLoadPayload(currentInstruction[2].u.operand, regT0); 987 if (isArrowFunction) {988 int value = currentInstruction[4].u.operand;989 emitLoad(value, regT3, regT2);990 }991 974 notUndefinedScope = branch32(NotEqual, tagFor(currentInstruction[2].u.operand), TrustedImm32(JSValue::UndefinedTag)); 992 975 emitStore(dst, jsUndefined()); … … 996 979 997 980 FunctionExecutable* function = m_codeBlock->functionExpr(currentInstruction[3].u.operand); 998 if (isArrowFunction) 999 #if USE(JSVALUE64) 1000 callOperation(operationNewArrowFunction, dst, regT0, function, regT1); 1001 #else 1002 callOperation(operationNewArrowFunction, dst, regT0, function, regT3, regT2); 1003 #endif 981 OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode); 982 983 if (opcodeID == op_new_func_exp || opcodeID == op_new_arrow_func_exp) 984 callOperation(operationNewFunction, dst, regT0, function); 1004 985 else { 1005 if (opcodeID == op_new_func_exp) 1006 callOperation(operationNewFunction, dst, regT0, function); 1007 else { 1008 ASSERT(opcodeID == op_new_generator_func_exp); 1009 callOperation(operationNewGeneratorFunction, dst, regT0, function); 1010 } 986 ASSERT(opcodeID == op_new_generator_func_exp); 987 callOperation(operationNewGeneratorFunction, dst, regT0, function); 1011 988 } 989 1012 990 done.link(this); 1013 991 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r193606 r193766 939 939 } 940 940 941 void JIT::emit_op_load_arrowfunction_this(Instruction* currentInstruction)942 {943 int dst = currentInstruction[1].u.operand;944 emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);945 loadPtr(Address(regT0, JSArrowFunction::offsetOfThisValue()), regT0);946 emitStoreCell(dst, regT0);947 }948 949 941 void JIT::emit_op_create_this(Instruction* currentInstruction) 950 942 { -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r193649 r193766 1080 1080 { 1081 1081 LLINT_BEGIN(); 1082 1083 JSValue thisValue = LLINT_OP_C(4).jsValue(); 1082 1084 1083 CodeBlock* codeBlock = exec->codeBlock(); 1085 1084 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope(); 1086 1085 FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand); 1087 1086 1088 LLINT_RETURN(JS ArrowFunction::create(vm, executable, scope, thisValue));1087 LLINT_RETURN(JSFunction::create(vm, executable, scope)); 1089 1088 } 1090 1089 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r193649 r193766 1479 1479 traceExecution() 1480 1480 callSlowPath(_llint_slow_path_new_arrow_func_exp) 1481 dispatch( 5)1481 dispatch(4) 1482 1482 1483 1483 _llint_op_call: -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r193606 r193766 2423 2423 2424 2424 2425 _llint_op_load_arrowfunction_this:2426 traceExecution()2427 loadi Callee + PayloadOffset[cfr], t02428 loadi JSArrowFunction::m_boundThis[t0], t02429 loadisFromInstruction(1, t1)2430 storei CellTag, TagOffset[cfr, t1, 8]2431 storei t0, PayloadOffset[cfr, t1, 8]2432 dispatch(2)2433 2434 2435 2425 _llint_op_get_rest_length: 2436 2426 traceExecution() -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r193606 r193766 2292 2292 2293 2293 2294 _llint_op_load_arrowfunction_this:2295 traceExecution()2296 loadp Callee[cfr], t02297 loadp JSArrowFunction::m_boundThis[t0], t02298 loadisFromInstruction(1, t1)2299 storeq t0, [cfr, t1, 8]2300 dispatch(2)2301 2302 2303 2294 _llint_op_get_rest_length: 2304 2295 traceExecution() -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r193606 r193766 377 377 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo) 378 378 { 379 uses This();379 usesArrowFunction(); 380 380 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn); 381 381 ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source); … … 918 918 void incConstants() { m_scope.m_numConstants++; } 919 919 void usesThis() { m_scope.m_features |= ThisFeature; } 920 void usesArrowFunction() { m_scope.m_features |= ArrowFunctionFeature; } 920 921 void usesArguments() { m_scope.m_features |= ArgumentsFeature; } 921 922 void usesWith() { m_scope.m_features |= WithFeature; } -
trunk/Source/JavaScriptCore/parser/Nodes.h
r193606 r193766 1560 1560 bool usesEval() const { return m_features & EvalFeature; } 1561 1561 bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); } 1562 bool usesArrowFunction() const { return m_features & ArrowFunctionFeature; } 1562 1563 bool modifiesParameter() const { return m_features & ModifiedParameterFeature; } 1563 1564 bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); } -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r193606 r193766 1979 1979 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 1980 1980 } 1981 if (functionScope->hasDirectSuper() ) {1981 if (functionScope->hasDirectSuper() && functionBodyType == StandardFunctionBodyBlock) { 1982 1982 semanticFailIfTrue(!isClassConstructor, "Cannot call super() outside of a class constructor"); 1983 1983 semanticFailIfTrue(constructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor"); 1984 1984 } 1985 if (functionScope->needsSuperBinding() )1985 if (functionScope->needsSuperBinding() && functionBodyType == StandardFunctionBodyBlock) 1986 1986 semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class"); 1987 1987 -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r193606 r193766 148 148 typedef unsigned CodeFeatures; 149 149 150 const CodeFeatures NoFeatures = 0; 151 const CodeFeatures EvalFeature = 1 << 0; 152 const CodeFeatures ArgumentsFeature = 1 << 1; 153 const CodeFeatures WithFeature = 1 << 2; 154 const CodeFeatures ThisFeature = 1 << 3; 155 const CodeFeatures StrictModeFeature = 1 << 4; 156 const CodeFeatures ShadowsArgumentsFeature = 1 << 5; 157 const CodeFeatures ModifiedParameterFeature = 1 << 6; 158 const CodeFeatures ModifiedArgumentsFeature = 1 << 7; 150 const CodeFeatures NoFeatures = 0; 151 const CodeFeatures EvalFeature = 1 << 0; 152 const CodeFeatures ArgumentsFeature = 1 << 1; 153 const CodeFeatures WithFeature = 1 << 2; 154 const CodeFeatures ThisFeature = 1 << 3; 155 const CodeFeatures StrictModeFeature = 1 << 4; 156 const CodeFeatures ShadowsArgumentsFeature = 1 << 5; 157 const CodeFeatures ModifiedParameterFeature = 1 << 6; 158 const CodeFeatures ModifiedArgumentsFeature = 1 << 7; 159 const CodeFeatures ArrowFunctionFeature = 1 << 8; 160 const CodeFeatures ArrowFunctionContextFeature = 1 << 9; 159 161 160 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature ;162 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature | ArrowFunctionFeature | ArrowFunctionContextFeature; 161 163 162 164 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/CodeCache.cpp
r193606 r193766 84 84 85 85 template <class UnlinkedCodeBlockType, class ExecutableType> 86 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, 87 JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) 86 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) 88 87 { 89 88 SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, thisTDZMode); … … 113 112 unsigned unlinkedEndColumn = rootNode->endColumn(); 114 113 unsigned endColumn = unlinkedEndColumn + (endColumnIsOnStartLine ? startColumn : 1); 115 executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn); 114 unsigned arrowContextFeature = executable->isArrowFunctionContext() ? ArrowFunctionContextFeature : 0; 115 executable->recordParse(rootNode->features() | arrowContextFeature, rootNode->hasCapturedVariables(), rootNode->firstLine(), rootNode->lastLine(), startColumn, endColumn); 116 116 117 117 UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo()); … … 133 133 { 134 134 VariableEnvironment emptyParentTDZVariables; 135 return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables);135 return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables); 136 136 } 137 137 138 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ)138 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error, const VariableEnvironment* variablesUnderTDZ) 139 139 { 140 return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ);140 return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ); 141 141 } 142 142 … … 144 144 { 145 145 VariableEnvironment emptyParentTDZVariables; 146 return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables);146 return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, false, debuggerMode, profilerMode, error, &emptyParentTDZVariables); 147 147 } 148 148 … … 189 189 // The Function constructor only has access to global variables, so no variables will be under TDZ. 190 190 VariableEnvironment emptyTDZVariables; 191 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, GeneratorThisMode::NonEmpty, emptyTDZVariables );191 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, GeneratorThisMode::NonEmpty, emptyTDZVariables, false); 192 192 functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string())); 193 193 -
trunk/Source/JavaScriptCore/runtime/CodeCache.h
r193606 r193766 195 195 196 196 UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&); 197 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);197 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*); 198 198 UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ProfilerMode, ParserError&); 199 199 UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&); … … 206 206 private: 207 207 template <class UnlinkedCodeBlockType, class ExecutableType> 208 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);208 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*); 209 209 210 210 CodeCacheMap m_sourceCode; -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r193606 r193766 342 342 macro(DateTimeFormat) \ 343 343 macro(NumberFormat) \ 344 macro(newTargetLocal) \ 345 macro(derivedConstructor) \ 344 346 345 347 -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r193606 r193766 132 132 const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(ScriptExecutable) }; 133 133 134 ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext )134 ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext) 135 135 : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED) 136 136 , m_source(source) … … 139 139 , m_neverInline(false) 140 140 , m_didTryToEnterInLoop(false) 141 , m_isDerivedConstructorContext(isInDerivedConstructorContext) 142 , m_isArrowFunctionContext(isInArrowFunctionContext) 141 143 , m_overrideLineNumber(-1) 142 144 , m_firstLine(-1) … … 413 415 const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(EvalExecutable) }; 414 416 415 EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)417 EvalExecutable* EvalExecutable::create(ExecState* exec, const SourceCode& source, bool isInStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ) 416 418 { 417 419 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); … … 421 423 } 422 424 423 EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext );425 EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext, isDerivedConstructorContext, isArrowFunctionContext); 424 426 executable->finishCreation(exec->vm()); 425 427 426 UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, variablesUnderTDZ);428 UnlinkedEvalCodeBlock* unlinkedEvalCode = globalObject->createEvalCodeBlock(exec, executable, thisTDZMode, isArrowFunctionContext, variablesUnderTDZ); 427 429 if (!unlinkedEvalCode) 428 430 return 0; … … 433 435 } 434 436 435 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext )436 : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext )437 EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext) 438 : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec->vm(), source, inStrictContext, isDerivedConstructorContext, isArrowFunctionContext) 437 439 { 438 440 } … … 446 448 447 449 ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) 448 : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false )450 : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false, false, false) 449 451 { 450 452 m_typeProfilingStartOffset = 0; … … 462 464 463 465 ModuleProgramExecutable::ModuleProgramExecutable(ExecState* exec, const SourceCode& source) 464 : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false )466 : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false, false, false) 465 467 { 466 468 m_typeProfilingStartOffset = 0; … … 493 495 const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; 494 496 495 FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, 496 UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, 497 unsigned lastLine, unsigned startColumn, unsigned endColumn) 498 : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext()) 497 FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn, unsigned endColumn) 498 : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext(), unlinkedExecutable->isDerivedConstructorContext(), false) 499 499 , m_unlinkedExecutable(vm, this, unlinkedExecutable) 500 500 { -
trunk/Source/JavaScriptCore/runtime/Executable.h
r193606 r193766 345 345 bool usesArguments() const { return m_features & ArgumentsFeature; } 346 346 bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature); } 347 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } 347 348 bool isStrictMode() const { return m_features & StrictModeFeature; } 349 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; } 348 350 ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; } 349 351 … … 394 396 395 397 protected: 396 ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext);398 ScriptExecutable(Structure*, VM&, const SourceCode&, bool isInStrictContext, bool isInDerivedConstructorContext, bool isInArrowFunctionContext); 397 399 398 400 void finishCreation(VM& vm) … … 413 415 bool m_neverOptimize { false }; 414 416 bool m_didTryToEnterInLoop; 417 bool m_isDerivedConstructorContext; 418 bool m_isArrowFunctionContext; 415 419 int m_overrideLineNumber; 416 420 int m_firstLine; … … 435 439 } 436 440 437 static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, const VariableEnvironment*);441 static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, ThisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const VariableEnvironment*); 438 442 439 443 PassRefPtr<JITCode> generatedJITCode() … … 449 453 DECLARE_INFO; 450 454 451 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ProgramMode); } 455 456 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), isArrowFunctionContext()); } 452 457 453 458 unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); } … … 457 462 friend class ExecutableBase; 458 463 friend class ScriptExecutable; 459 EvalExecutable(ExecState*, const SourceCode&, bool );464 EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext); 460 465 461 466 static void visitChildren(JSCell*, SlotVisitor&); … … 502 507 DECLARE_INFO; 503 508 504 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ProgramMode ); }509 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, isDerivedConstructorContext(), false); } 505 510 506 511 private: … … 543 548 DECLARE_INFO; 544 549 545 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode); } 550 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, GeneratorThisMode::NonEmpty, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, isDerivedConstructorContext(), false); } 551 546 552 UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); } 547 553 … … 651 657 bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); } 652 658 ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); } 659 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; } 660 bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); } 653 661 bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); } 654 662 const Identifier& name() { return m_unlinkedExecutable->name(); } … … 657 665 size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'! 658 666 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); } 659 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }660 667 661 668 static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r193606 r193766 973 973 } 974 974 975 UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)975 UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ) 976 976 { 977 977 ParserError error; … … 980 980 ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff; 981 981 UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock( 982 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ);982 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ); 983 983 984 984 if (hasDebugger()) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r193606 r193766 670 670 671 671 UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); 672 UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, const VariableEnvironment*);672 UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, bool isArrowFunctionContext, const VariableEnvironment*); 673 673 UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*); 674 674 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r193606 r193766 582 582 JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject(); 583 583 VariableEnvironment emptyTDZVariables; // Indirect eval does not have access to the lexical scope. 584 EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded, &emptyTDZVariables);584 EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded, false, false, &emptyTDZVariables); 585 585 if (!eval) 586 586 return JSValue::encode(jsUndefined()); -
trunk/Source/JavaScriptCore/tests/es6.yaml
r193606 r193766 746 746 cmd: runES6 :fail 747 747 - path: es6/arrow_functions_lexical_new.target_binding.js 748 cmd: runES6 : fail748 cmd: runES6 :normal 749 749 - path: es6/arrow_functions_lexical_super_binding.js 750 750 cmd: runES6 :fail -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
r193606 r193766 1 var n = 100000 0;1 var n = 100000; 2 2 3 3 function bar() { } -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
r193606 r193766 1 var n = 1000000 0;1 var n = 1000000; 2 2 3 3 function bar(f) { f(10); } -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-lexical-bind-this-1.js
r193606 r193766 9 9 this.getName = () => eval("this.name"); 10 10 this.getNameHard = () => eval("(() => this.name)()"); 11 this.getNameReallyHard = () => eval("eval('(() => this.name)()')"); 11 12 } 12 13 … … 17 18 testCase(d.getName(), d.name, "Error: this is not lexically binded inside of the arrow function #1"); 18 19 testCase(d.getNameHard(), d.name, "Error: this is not lexically binded inside of the arrow function #2"); 20 testCase(d.getNameReallyHard(), d.name, "Error: this is not lexically binded inside of the arrow function #3"); 19 21 }
Note: See TracChangeset
for help on using the changeset viewer.