Changeset 193584 in webkit
- Timestamp:
- Dec 6, 2015 12:56:30 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 added
- 1 deleted
- 63 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r193513 r193584 1 2015-12-06 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-05 David Kilzer <ddkilzer@apple.com> 2 15 -
trunk/LayoutTests/js/arrowfunction-tdz-expected.txt
r192882 r193584 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
r192882 r193584 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
r193566 r193584 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-05 Benjamin Poulain <bpoulain@apple.com> 2 146 -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r192937 r193584 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
r192937 r193584 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
r192937 r193584 58 58 case op_assert: 59 59 case op_get_scope: 60 case op_load_arrowfunction_this:61 60 case op_to_this: 62 61 case op_check_tdz: … … 394 393 case op_check_tdz: 395 394 case op_get_scope: 396 case op_load_arrowfunction_this:397 395 case op_create_direct_arguments: 398 396 case op_create_scoped_arguments: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r193491 r193584 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; … … 1328 1323 int r1 = (++it)->u.operand; 1329 1324 int f0 = (++it)->u.operand; 1330 int r2 = (++it)->u.operand;1331 1325 printLocationAndOp(out, exec, location, it, "op_new_arrow_func_exp"); 1332 out.printf("%s, %s, f%d , %s", registerName(r0).data(), registerName(r1).data(), f0, registerName(r2).data());1326 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); 1333 1327 break; 1334 1328 } -
trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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 … … 1893 1977 } 1894 1978 1895 Variable BytecodeGenerator::variable(const Identifier& property )1896 { 1897 if (property == propertyNames().thisIdentifier ) {1979 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType) 1980 { 1981 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) { 1898 1982 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(), 1899 1983 ReadOnly, Variable::SpecialVariable, 0, false); … … 2590 2674 instructions().append(scopeRegister()->index()); 2591 2675 instructions().append(index); 2592 2593 if (opcodeID == op_new_arrow_func_exp)2594 instructions().append(thisRegister()->index());2595 2676 } 2596 2677 … … 2603 2684 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func) 2604 2685 { 2605 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode); 2606 bool isClassConstructor = m_codeBlock->isConstructor() && constructorKind() != ConstructorKind::None; 2607 if (isClassConstructor || generatorThisMode() == GeneratorThisMode::Empty) 2608 emitTDZCheck(thisRegister()); 2609 2686 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode); 2610 2687 emitNewFunctionExpressionCommon(dst, func); 2611 2688 return dst; … … 3215 3292 m_topMostScope = addVar(); 3216 3293 emitMove(m_topMostScope, scopeRegister()); 3217 }3218 3219 RegisterID* BytecodeGenerator::emitLoadArrowFunctionThis(RegisterID* arrowFunctionThis)3220 {3221 emitOpcode(op_load_arrowfunction_this);3222 instructions().append(arrowFunctionThis->index());3223 return arrowFunctionThis;3224 3294 } 3225 3295 … … 3909 3979 } 3910 3980 3981 RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment() 3982 { 3983 ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived); 3984 3985 m_resolvedArrowFunctionScopeContextRegister = emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped)); 3986 return m_resolvedArrowFunctionScopeContextRegister.get(); 3987 } 3988 3989 void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment() 3990 { 3991 emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound); 3992 } 3993 3994 RegisterID* BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment() 3995 { 3996 m_isNewTargetLoadedInArrowFunction = true; 3997 3998 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 3999 emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound)); 4000 4001 return m_newTargetRegister; 4002 } 4003 4004 RegisterID* BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment() 4005 { 4006 Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName); 4007 return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound); 4008 } 4009 4010 void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope() 4011 { 4012 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 4013 4014 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 4015 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization); 4016 } 4017 4018 void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope() 4019 { 4020 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 4021 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 4022 4023 Variable protoScope = variable(propertyNames().derivedConstructorPrivateName); 4024 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization); 4025 } 4026 } 4027 4028 void BytecodeGenerator::emitPutThisToArrowFunctionContextScope() 4029 { 4030 ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 4031 4032 if (isDerivedConstructorContext()) 4033 emitLoadArrowFunctionLexicalEnvironment(); 4034 4035 Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped); 4036 emitPutToScope(isDerivedConstructorContext() ? m_resolvedArrowFunctionScopeContextRegister.get() : m_arrowFunctionContextLexicalEnvironmentRegister, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization); 4037 } 4038 3911 4039 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister) 3912 4040 { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r192937 r193584 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); … … 629 644 RegisterID* emitPushWithScope(RegisterID* objectScope); 630 645 void emitPopWithScope(); 646 void emitPutThisToArrowFunctionContextScope(); 647 void emitPutNewTargetToArrowFunctionContextScope(); 648 void emitPutDerivedConstructorToArrowFunctionContextScope(); 649 RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(); 631 650 632 651 void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart); … … 721 740 void allocateCalleeSaveSpace(); 722 741 void allocateAndEmitScope(); 723 RegisterID* emitLoadArrowFunctionThis(RegisterID*);724 742 void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope); 725 743 … … 773 791 UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata) 774 792 { 793 bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->parseMode() == SourceParseMode::ArrowFunctionMode); 794 775 795 VariableEnvironment variablesUnderTDZ; 776 796 getVariablesUnderTDZ(variablesUnderTDZ); … … 791 811 generatorThisMode = GeneratorThisMode::Empty; 792 812 793 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, generatorThisMode, variablesUnderTDZ );813 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, generatorThisMode, variablesUnderTDZ, newisDerivedConstructorContext); 794 814 } 795 815 … … 802 822 void initializeVarLexicalEnvironment(int symbolTableConstantIndex); 803 823 void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures); 824 void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* = nullptr); 804 825 805 826 public: … … 844 865 RegisterID* m_newTargetRegister { nullptr }; 845 866 RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount]; 867 RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr }; 868 RefPtr<RegisterID> m_resolvedArrowFunctionScopeContextRegister; 846 869 847 870 SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters; … … 899 922 bool m_usesNonStrictEval { false }; 900 923 bool m_inTailPosition { false }; 924 bool m_isDerivedConstructorContext { false }; 925 bool m_needsToUpdateArrowFunctionContext; 926 bool m_isNewTargetLoadedInArrowFunction { false }; 901 927 }; 902 928 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r192937 r193584 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
r192882 r193584 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
r192993 r193584 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
r193470 r193584 4508 4508 NEXT_OPCODE(op_get_scope); 4509 4509 } 4510 4511 case op_load_arrowfunction_this: {4512 Node* callee = get(VirtualRegister(JSStack::Callee));4513 Node* result;4514 if (JSArrowFunction* function = callee->dynamicCastConstant<JSArrowFunction*>())4515 result = jsConstant(function->boundThis());4516 else4517 result = addToGraph(LoadArrowFunctionThis, callee);4518 set(VirtualRegister(currentInstruction[1].u.operand), result);4519 NEXT_OPCODE(op_load_arrowfunction_this);4520 }4521 4510 4522 4511 case op_create_direct_arguments: { … … 4568 4557 } 4569 4558 4570 case op_new_func_exp: { 4559 case op_new_func_exp: 4560 case op_new_arrow_func_exp: { 4571 4561 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4572 4562 FrozenValue* frozen = m_graph.freezeStrong(expr); 4573 4563 set(VirtualRegister(currentInstruction[1].u.operand), 4574 4564 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4575 NEXT_OPCODE(op_new_func_exp); 4576 } 4577 4578 case op_new_arrow_func_exp: { 4579 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4580 FrozenValue* frozen = m_graph.freezeStrong(expr); 4581 4582 set(VirtualRegister(currentInstruction[1].u.operand), 4583 addToGraph(NewArrowFunction, OpInfo(frozen), 4584 get(VirtualRegister(currentInstruction[2].u.operand)), 4585 get(VirtualRegister(currentInstruction[4].u.operand)))); 4586 4587 NEXT_OPCODE(op_new_arrow_func_exp); 4565 4566 if (opcodeID == op_new_func_exp) { 4567 // Curly braces are necessary 4568 NEXT_OPCODE(op_new_func_exp); 4569 } else { 4570 // Curly braces are necessary 4571 NEXT_OPCODE(op_new_arrow_func_exp); 4572 } 4588 4573 } 4589 4574 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r192882 r193584 203 203 case op_in: 204 204 case op_get_scope: 205 case op_load_arrowfunction_this:206 205 case op_get_from_scope: 207 206 case op_get_enumerable_length: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r192993 r193584 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
r192882 r193584 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
r193470 r193584 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
r192882 r193584 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
r192882 r193584 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
r192993 r193584 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
r192882 r193584 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
r192882 r193584 47 47 FunctionActivationPLoc, 48 48 ActivationScopePLoc, 49 ClosureVarPLoc, 50 ArrowFunctionBoundThisPLoc 49 ClosureVarPLoc 51 50 }; 52 51 -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r192882 r193584 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
r193424 r193584 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
r192882 r193584 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
r192882 r193584 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
r192882 r193584 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
r192882 r193584 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
r193506 r193584 812 812 case GetScope: 813 813 compileGetScope(); 814 break;815 case LoadArrowFunctionThis:816 compileLoadArrowFunctionThis();817 814 break; 818 815 case SkipScope: … … 4561 4558 } 4562 4559 4563 void compileLoadArrowFunctionThis()4564 {4565 setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrowFunction_this));4566 }4567 4568 4560 void compileSkipScope() 4569 4561 { -
trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp
r192882 r193584 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
r192937 r193584 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
r192937 r193584 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
r193471 r193584 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
r193471 r193584 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) … … 970 962 void JIT::emitNewFuncExprCommon(Instruction* currentInstruction) 971 963 { 972 OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);973 bool isArrowFunction = opcodeID == op_new_arrow_func_exp;974 975 964 Jump notUndefinedScope; 976 965 int dst = currentInstruction[1].u.operand; 977 966 #if USE(JSVALUE64) 978 967 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); 979 if (isArrowFunction)980 emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);981 968 notUndefinedScope = branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsUndefined()))); 982 969 store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, sizeof(Register) * dst)); 983 970 #else 984 971 emitLoadPayload(currentInstruction[2].u.operand, regT0); 985 if (isArrowFunction) {986 int value = currentInstruction[4].u.operand;987 emitLoad(value, regT3, regT2);988 }989 972 notUndefinedScope = branch32(NotEqual, tagFor(currentInstruction[2].u.operand), TrustedImm32(JSValue::UndefinedTag)); 990 973 emitStore(dst, jsUndefined()); … … 994 977 995 978 FunctionExecutable* function = m_codeBlock->functionExpr(currentInstruction[3].u.operand); 996 if (isArrowFunction) 997 #if USE(JSVALUE64) 998 callOperation(operationNewArrowFunction, dst, regT0, function, regT1); 999 #else 1000 callOperation(operationNewArrowFunction, dst, regT0, function, regT3, regT2); 1001 #endif 979 OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode); 980 981 if (opcodeID == op_new_func_exp || opcodeID == op_new_arrow_func_exp) 982 callOperation(operationNewFunction, dst, regT0, function); 1002 983 else { 1003 if (opcodeID == op_new_func_exp) 1004 callOperation(operationNewFunction, dst, regT0, function); 1005 else { 1006 ASSERT(opcodeID == op_new_generator_func_exp); 1007 callOperation(operationNewGeneratorFunction, dst, regT0, function); 1008 } 984 ASSERT(opcodeID == op_new_generator_func_exp); 985 callOperation(operationNewGeneratorFunction, dst, regT0, function); 1009 986 } 987 1010 988 done.link(this); 1011 989 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r192882 r193584 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
r192937 r193584 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
r192937 r193584 1473 1473 traceExecution() 1474 1474 callSlowPath(_llint_slow_path_new_arrow_func_exp) 1475 dispatch( 5)1475 dispatch(4) 1476 1476 1477 1477 _llint_op_call: -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r192882 r193584 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
r192882 r193584 2285 2285 dispatch(6) 2286 2286 2287 2288 2287 2289 _llint_op_profile_control_flow: 2288 2290 traceExecution() … … 2290 2292 addq 1, BasicBlockLocation::m_executionCount[t0] 2291 2293 dispatch(2) 2292 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 2294 2303 2295 _llint_op_get_rest_length: -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r192937 r193584 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
r193493 r193584 342 342 macro(DateTimeFormat) \ 343 343 macro(NumberFormat) \ 344 macro(newTargetLocal) \ 345 macro(derivedConstructor) \ 344 346 345 347 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r192937 r193584 225 225 JSFunction* constructor = jsCast<JSFunction*>(OP(2).jsValue().asCell()); 226 226 227 #if !ASSERT_DISABLED 228 ConstructData constructData; 229 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS || constructor->jsExecutable()->isArrowFunction()); 230 #endif 231 227 232 auto& cacheWriteBarrier = pc[4].u.jsCell; 228 233 if (!cacheWriteBarrier) -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r192937 r193584 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
r192937 r193584 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 // TODO:Think about avoid using isArrowFunction veriabl 660 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; } 661 bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); } 653 662 bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); } 654 663 const Identifier& name() { return m_unlinkedExecutable->name(); } … … 657 666 size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'! 658 667 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); } 659 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }660 668 661 669 static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r193493 r193584 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
r192937 r193584 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
r192882 r193584 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
r192937 r193584 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
r192882 r193584 1 var n = 100000 0;1 var n = 100000; 2 2 3 3 function bar() { } -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
r192882 r193584 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
r192882 r193584 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.