Changeset 192876 in webkit
- Timestamp:
- Dec 1, 2015 1:46:12 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 added
- 1 deleted
- 63 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r192874 r192876 1 2015-12-01 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-01 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 15 -
trunk/LayoutTests/js/arrowfunction-tdz-expected.txt
r188545 r192876 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
r188545 r192876 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
r192874 r192876 1 2015-12-01 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::isDerivedConstructorContext): 29 (JSC::UnlinkedCodeBlock::isArrowFunctionContext): 30 * bytecode/UnlinkedFunctionExecutable.cpp: 31 (JSC::generateUnlinkedFunctionCodeBlock): 32 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 33 * bytecode/UnlinkedFunctionExecutable.h: 34 * bytecompiler/BytecodeGenerator.cpp: 35 (JSC::BytecodeGenerator::BytecodeGenerator): 36 (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded): 37 (JSC::BytecodeGenerator::variable): 38 (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment): 39 (JSC::BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment): 40 (JSC::BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment): 41 (JSC::BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment): 42 (JSC::BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope): 43 (JSC::BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope): 44 (JSC::BytecodeGenerator::emitPutThisToArrowFunctionContextScope): 45 * bytecompiler/BytecodeGenerator.h: 46 (JSC::BytecodeGenerator::isDerivedConstructorContext): 47 (JSC::BytecodeGenerator::usesArrowFunction): 48 (JSC::BytecodeGenerator::needsToUpdateArrowFunctionContext): 49 (JSC::BytecodeGenerator::usesEval): 50 (JSC::BytecodeGenerator::usesThis): 51 (JSC::BytecodeGenerator::newTarget): 52 (JSC::BytecodeGenerator::makeFunction): 53 * bytecompiler/NodesCodegen.cpp: 54 (JSC::ThisNode::emitBytecode): 55 (JSC::SuperNode::emitBytecode): 56 (JSC::EvalFunctionCallNode::emitBytecode): 57 (JSC::FunctionCallValueNode::emitBytecode): 58 (JSC::FunctionNode::emitBytecode): 59 * debugger/DebuggerCallFrame.cpp: 60 (JSC::DebuggerCallFrame::evaluate): 61 * dfg/DFGAbstractInterpreterInlines.h: 62 * dfg/DFGByteCodeParser.cpp: 63 (JSC::DFG::ByteCodeParser::parseBlock): 64 * dfg/DFGCapabilities.cpp: 65 * dfg/DFGClobberize.h: 66 * dfg/DFGDoesGC.cpp: 67 * dfg/DFGFixupPhase.cpp: 68 * dfg/DFGNodeType.h: 69 * dfg/DFGObjectAllocationSinkingPhase.cpp: 70 * dfg/DFGPredictionPropagationPhase.cpp: 71 * dfg/DFGPromotedHeapLocation.cpp: 72 * dfg/DFGPromotedHeapLocation.h: 73 * dfg/DFGSafeToExecute.h: 74 * dfg/DFGSpeculativeJIT.cpp: 75 * dfg/DFGSpeculativeJIT.h: 76 * dfg/DFGSpeculativeJIT32_64.cpp: 77 * dfg/DFGSpeculativeJIT64.cpp: 78 * ftl/FTLCapabilities.cpp: 79 * ftl/FTLLowerDFGToLLVM.cpp: 80 * ftl/FTLOperations.cpp: 81 (JSC::FTL::operationMaterializeObjectInOSR): 82 * interpreter/Interpreter.cpp: 83 (JSC::eval): 84 * jit/JIT.cpp: 85 * jit/JIT.h: 86 * jit/JITOpcodes.cpp: 87 (JSC::JIT::emitNewFuncExprCommon): 88 * jit/JITOpcodes32_64.cpp: 89 * llint/LLIntSlowPaths.cpp: 90 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 91 * llint/LowLevelInterpreter.asm: 92 * llint/LowLevelInterpreter32_64.asm: 93 * llint/LowLevelInterpreter64.asm: 94 * parser/ASTBuilder.h: 95 (JSC::ASTBuilder::createArrowFunctionExpr): 96 (JSC::ASTBuilder::usesArrowFunction): 97 * parser/Nodes.h: 98 (JSC::ScopeNode::usesArrowFunction): 99 * parser/Parser.cpp: 100 (JSC::Parser<LexerType>::parseFunctionInfo): 101 * parser/ParserModes.h: 102 * runtime/CodeCache.cpp: 103 (JSC::CodeCache::getGlobalCodeBlock): 104 (JSC::CodeCache::getProgramCodeBlock): 105 (JSC::CodeCache::getEvalCodeBlock): 106 (JSC::CodeCache::getModuleProgramCodeBlock): 107 (JSC::CodeCache::getFunctionExecutableFromGlobalCode): 108 * runtime/CodeCache.h: 109 * runtime/CommonIdentifiers.h: 110 * runtime/CommonSlowPaths.cpp: 111 (JSC::SLOW_PATH_DECL): 112 * runtime/Executable.cpp: 113 (JSC::ScriptExecutable::ScriptExecutable): 114 (JSC::EvalExecutable::create): 115 (JSC::EvalExecutable::EvalExecutable): 116 (JSC::ProgramExecutable::ProgramExecutable): 117 (JSC::ModuleProgramExecutable::ModuleProgramExecutable): 118 (JSC::FunctionExecutable::FunctionExecutable): 119 * runtime/Executable.h: 120 (JSC::ScriptExecutable::isArrowFunctionContext): 121 (JSC::ScriptExecutable::isDerivedConstructorContext): 122 * runtime/JSGlobalObject.cpp: 123 (JSC::JSGlobalObject::createEvalCodeBlock): 124 * runtime/JSGlobalObject.h: 125 * runtime/JSGlobalObjectFunctions.cpp: 126 (JSC::globalFuncEval): 127 * tests/es6.yaml: 128 * tests/stress/arrowfunction-activation-sink-osrexit.js: 129 * tests/stress/arrowfunction-activation-sink.js: 130 * tests/stress/arrowfunction-lexical-bind-newtarget.js: Added. 131 * tests/stress/arrowfunction-lexical-bind-supercall-1.js: Added. 132 * tests/stress/arrowfunction-lexical-bind-supercall-2.js: Added. 133 * tests/stress/arrowfunction-lexical-bind-supercall-3.js: Added. 134 * tests/stress/arrowfunction-lexical-bind-supercall-4.js: Added. 135 * tests/stress/arrowfunction-lexical-bind-this-1.js: 136 * tests/stress/arrowfunction-lexical-bind-this-7.js: Added. 137 * tests/stress/arrowfunction-tdz-1.js: Added. 138 * tests/stress/arrowfunction-tdz-2.js: Added. 139 * tests/stress/arrowfunction-tdz-3.js: Added. 140 * tests/stress/arrowfunction-tdz-4.js: Added. 141 * tests/stress/arrowfunction-tdz.js: Removed. 142 1 143 2015-12-01 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 144 -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r191433 r192876 116 116 metadata->overrideName(name); 117 117 VariableEnvironment dummyTDZVariables; 118 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, WTF::move(sourceOverride));118 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, false, WTF::move(sourceOverride)); 119 119 functionExecutable->setNameValue(vm, jsString(&vm, name.string())); 120 120 return functionExecutable; -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r192814 r192876 91 91 { "name" : "op_new_func", "length" : 4 }, 92 92 { "name" : "op_new_func_exp", "length" : 4 }, 93 { "name" : "op_new_arrow_func_exp", "length" : 5},93 { "name" : "op_new_arrow_func_exp", "length" : 4 }, 94 94 { "name" : "op_call", "length" : 9 }, 95 95 { "name" : "op_tail_call", "length" : 9 }, … … 128 128 { "name" : "op_enumerator_generic_pname", "length" : 4 }, 129 129 { "name" : "op_to_index_string", "length" : 3 }, 130 { "name" : "op_load_arrowfunction_this", "length" : 2 },131 130 { "name" : "op_assert", "length" : 3 }, 132 131 { "name" : "op_copy_rest", "length": 4 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r192814 r192876 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: … … 372 371 case op_check_tdz: 373 372 case op_get_scope: 374 case op_load_arrowfunction_this:375 373 case op_create_direct_arguments: 376 374 case op_create_scoped_arguments: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r192814 r192876 758 758 break; 759 759 } 760 case op_load_arrowfunction_this: {761 int r0 = (++it)->u.operand;762 printLocationOpAndRegisterOperand(out, exec, location, it, "load_arrowfunction_this", r0);763 break;764 }765 760 case op_create_direct_arguments: { 766 761 int r0 = (++it)->u.operand; … … 1308 1303 int r1 = (++it)->u.operand; 1309 1304 int f0 = (++it)->u.operand; 1310 int r2 = (++it)->u.operand;1311 1305 printLocationAndOp(out, exec, location, it, "op_new_arrow_func_exp"); 1312 out.printf("%s, %s, f%d , %s", registerName(r0).data(), registerName(r1).data(), f0, registerName(r2).data());1306 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); 1313 1307 break; 1314 1308 } -
trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h
r190827 r192876 51 51 return 0; 52 52 } 53 54 EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)53 54 EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, bool isDerivedConstructorContext, bool isArrowFunctionContext, const String& evalSource, JSScope* scope) 55 55 { 56 56 VariableEnvironment variablesUnderTDZ; 57 57 JSScope::collectVariablesUnderTDZ(scope, variablesUnderTDZ); 58 EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext, thisTDZMode, &variablesUnderTDZ);58 EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext, thisTDZMode, isDerivedConstructorContext, isArrowFunctionContext, &variablesUnderTDZ); 59 59 if (!evalExecutable) 60 60 return 0; -
trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h
r188545 r192876 32 32 33 33 struct ExecutableInfo { 34 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, bool isArrowFunction )34 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, bool isArrowFunction, bool isDerivedConstructorContext, bool isArrowFunctionContext) 35 35 : m_needsActivation(needsActivation) 36 36 , m_usesEval(usesEval) … … 40 40 , m_constructorKind(static_cast<unsigned>(constructorKind)) 41 41 , m_isArrowFunction(isArrowFunction) 42 , m_isDerivedConstructorContext(isDerivedConstructorContext) 43 , m_isArrowFunctionContext(isArrowFunctionContext) 42 44 { 43 45 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind)); … … 51 53 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 52 54 bool isArrowFunction() const { return m_isArrowFunction; } 55 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; } 56 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } 53 57 54 58 private: … … 60 64 unsigned m_constructorKind : 2; 61 65 unsigned m_isArrowFunction : 1; 66 unsigned m_isDerivedConstructorContext : 1; 67 unsigned m_isArrowFunctionContext : 1; 62 68 }; 63 69 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r189339 r192876 67 67 , m_constructorKind(static_cast<unsigned>(info.constructorKind())) 68 68 , m_isArrowFunction(info.isArrowFunction()) 69 , m_isDerivedConstructorContext(info.isDerivedConstructorContext()) 70 , m_isArrowFunctionContext(info.isArrowFunctionContext()) 69 71 , m_firstLine(0) 70 72 , m_lineCount(0) -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r190076 r192876 118 118 bool usesEval() const { return m_usesEval; } 119 119 bool isArrowFunction() const { return m_isArrowFunction; } 120 bool isDerivedConstructorContext() const { return m_isDerivedConstructorContext; } 121 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; } 120 122 121 123 bool needsFullScopeChain() const { return m_needsFullScopeChain; } … … 389 391 unsigned m_constructorKind : 2; 390 392 unsigned m_isArrowFunction : 1; 393 unsigned m_isDerivedConstructorContext : 1; 394 unsigned m_isArrowFunctionContext : 1; 391 395 392 396 unsigned m_firstLine; -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
r190108 r192876 68 68 69 69 UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, 70 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), isArrowFunction ));70 ExecutableInfo(function->needsActivation(), function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), isArrowFunction, executable->isDerivedConstructorContext(), false)); 71 71 auto generator(std::make_unique<BytecodeGenerator>(vm, function.get(), result, debuggerMode, profilerMode, executable->parentScopeTDZVariables())); 72 72 error = generator->generate(); … … 76 76 } 77 77 78 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables )78 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext) 79 79 : Base(*vm, structure) 80 80 , m_name(node->ident()) … … 101 101 , m_functionMode(node->functionMode()) 102 102 , m_isArrowFunction(node->isArrowFunction()) 103 , m_isDerivedConstructorContext(isDerivedConstructorContext) 103 104 { 104 105 ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind())); -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
r190155 r192876 66 66 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 67 67 68 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr)68 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, bool isDerivedConstructorContext, RefPtr<SourceProvider>&& sourceOverride = nullptr) 69 69 { 70 70 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) 71 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables );71 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables, isDerivedConstructorContext); 72 72 instance->finishCreation(*vm); 73 73 return instance; … … 127 127 const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; } 128 128 bool isArrowFunction() const { return m_isArrowFunction; } 129 bool isDerivedConstructorContext() const {return m_isDerivedConstructorContext; } 129 130 130 131 private: 131 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment& );132 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&, bool isDerivedConstructorContext); 132 133 WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall; 133 134 WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct; … … 160 161 unsigned m_functionMode : 1; // FunctionMode 161 162 unsigned m_isArrowFunction : 1; 163 unsigned m_isDerivedConstructorContext : 1; 162 164 163 165 protected: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r192814 r192876 156 156 , m_codeType(GlobalCode) 157 157 , m_vm(&vm) 158 , m_isDerivedConstructorContext(false) 159 , m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) 158 160 { 159 161 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); … … 186 188 // additional TDZ checks on top of those. This is why we can omit pushing programNode->lexicalVariables() 187 189 // to the TDZ stack. 190 191 if (needsToUpdateArrowFunctionContext()) { 192 initializeArrowFunctionContextScopeIfNeeded(); 193 emitPutThisToArrowFunctionContextScope(); 194 } 188 195 } 189 196 … … 203 210 // https://bugs.webkit.org/show_bug.cgi?id=148819 204 211 , m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && isStrictMode() && !m_shouldEmitProfileHooks) 212 , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext()) 213 , m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) 205 214 { 206 215 for (auto& constantRegister : m_linkTimeConstantRegisters) … … 227 236 } 228 237 } 229 230 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain(); 238 239 bool containsArrowOrEvalButNotInArrowBlock = needsToUpdateArrowFunctionContext() && !m_codeBlock->isArrowFunction(); 240 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain() || containsArrowOrEvalButNotInArrowBlock; 231 241 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); 232 242 bool needsArguments = functionNode->usesArguments() || codeBlock->usesEval(); … … 493 503 instructions().append(0); 494 504 } 495 } else { 496 if (functionNode->usesThis() || codeBlock->usesEval()) 497 emitLoadArrowFunctionThis(&m_thisRegister); 498 } 505 } else if (functionNode->usesThis()) 506 emitLoadThisFromArrowFunctionLexicalEnvironment(); 499 507 500 508 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called … … 502 510 m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false)); 503 511 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, functionNode, functionSymbolTable, symbolTableConstantIndex, captures); 512 513 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) { 514 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable); 515 emitPutThisToArrowFunctionContextScope(); 516 emitPutNewTargetToArrowFunctionContextScope(); 517 emitPutDerivedConstructorToArrowFunctionContextScope(); 518 } 504 519 505 520 pushLexicalScope(m_scopeNode, true); … … 515 530 , m_vm(&vm) 516 531 , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode()) 532 , m_isDerivedConstructorContext(codeBlock->isDerivedConstructorContext()) 533 , m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval()) 517 534 { 518 535 for (auto& constantRegister : m_linkTimeConstantRegisters) … … 544 561 m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false)); 545 562 563 if (codeBlock->isArrowFunctionContext() && evalNode->usesThis()) 564 emitLoadThisFromArrowFunctionLexicalEnvironment(); 565 566 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunctionContext()) { 567 initializeArrowFunctionContextScopeIfNeeded(); 568 emitPutThisToArrowFunctionContextScope(); 569 } 570 546 571 pushLexicalScope(m_scopeNode, true); 547 572 } … … 556 581 , m_vm(&vm) 557 582 , m_usesNonStrictEval(false) 583 , m_isDerivedConstructorContext(false) 584 , m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval()) 558 585 { 559 586 ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); … … 789 816 } 790 817 } 818 } 819 820 void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* symbolTable) 821 { 822 if (m_arrowFunctionContextLexicalEnvironmentRegister != nullptr) 823 return; 824 825 if (m_lexicalEnvironmentRegister != nullptr) { 826 m_arrowFunctionContextLexicalEnvironmentRegister = m_lexicalEnvironmentRegister; 827 828 if (!m_codeBlock->isArrowFunction()) { 829 ScopeOffset offset; 830 831 offset = symbolTable->takeNextScopeOffset(); 832 symbolTable->set(propertyNames().thisIdentifier.impl(), SymbolTableEntry(VarOffset(offset))); 833 834 if (m_codeType == FunctionCode) { 835 offset = symbolTable->takeNextScopeOffset(); 836 symbolTable->set(propertyNames().newTargetLocalPrivateName.impl(), SymbolTableEntry(VarOffset(offset))); 837 } 838 839 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 840 offset = symbolTable->takeNextScopeOffset(); 841 symbolTable->set(propertyNames().derivedConstructorPrivateName.impl(), SymbolTableEntry(VarOffset(offset))); 842 } 843 } 844 845 return; 846 } 847 848 VariableEnvironment environment; 849 auto addResult = environment.add(propertyNames().thisIdentifier); 850 addResult.iterator->value.setIsCaptured(); 851 addResult.iterator->value.setIsConst(); 852 853 if (m_codeType == FunctionCode) { 854 auto addTarget = environment.add(propertyNames().newTargetLocalPrivateName); 855 addTarget.iterator->value.setIsCaptured(); 856 addTarget.iterator->value.setIsLet(); 857 } 858 859 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 860 auto derivedConstructor = environment.add(propertyNames().derivedConstructorPrivateName); 861 derivedConstructor.iterator->value.setIsCaptured(); 862 derivedConstructor.iterator->value.setIsLet(); 863 } 864 865 size_t size = m_symbolTableStack.size(); 866 pushLexicalScopeInternal(environment, true, nullptr, TDZRequirement::UnderTDZ, ScopeType::LetConstScope, ScopeRegisterType::Block); 867 868 ASSERT_UNUSED(size, m_symbolTableStack.size() == size + 1); 869 870 m_arrowFunctionContextLexicalEnvironmentRegister = m_symbolTableStack.last().m_scope; 791 871 } 792 872 … … 1817 1897 } 1818 1898 1819 Variable BytecodeGenerator::variable(const Identifier& property )1820 { 1821 if (property == propertyNames().thisIdentifier ) {1899 Variable BytecodeGenerator::variable(const Identifier& property, ThisResolutionType thisResolutionType) 1900 { 1901 if (property == propertyNames().thisIdentifier && thisResolutionType == ThisResolutionType::Local) { 1822 1902 return Variable(property, VarOffset(thisRegister()->virtualRegister()), thisRegister(), 1823 1903 ReadOnly, Variable::SpecialVariable, 0, false); … … 2516 2596 instructions().append(scopeRegister()->index()); 2517 2597 instructions().append(index); 2518 2519 if (opcodeID == op_new_arrow_func_exp)2520 instructions().append(thisRegister()->index());2521 2598 } 2522 2599 … … 2529 2606 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func) 2530 2607 { 2531 bool isClassConstructor = m_codeBlock->isConstructor() && constructorKind() != ConstructorKind::None;2532 if (isClassConstructor)2533 emitTDZCheck(thisRegister());2534 2535 2608 emitNewFunctionCommon(dst, func, op_new_arrow_func_exp); 2536 2609 return dst; … … 3127 3200 m_topMostScope = addVar(); 3128 3201 emitMove(m_topMostScope, scopeRegister()); 3129 }3130 3131 RegisterID* BytecodeGenerator::emitLoadArrowFunctionThis(RegisterID* arrowFunctionThis)3132 {3133 emitOpcode(op_load_arrowfunction_this);3134 instructions().append(arrowFunctionThis->index());3135 return arrowFunctionThis;3136 3202 } 3137 3203 … … 3803 3869 } 3804 3870 3871 RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment() 3872 { 3873 ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived); 3874 3875 m_resolvedArrowFunctionScopeContextRegister = emitResolveScope(nullptr, variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped)); 3876 return m_resolvedArrowFunctionScopeContextRegister.get(); 3877 } 3878 3879 void BytecodeGenerator::emitLoadThisFromArrowFunctionLexicalEnvironment() 3880 { 3881 emitGetFromScope(thisRegister(), emitLoadArrowFunctionLexicalEnvironment(), variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped), DoNotThrowIfNotFound); 3882 } 3883 3884 RegisterID* BytecodeGenerator::emitLoadNewTargetFromArrowFunctionLexicalEnvironment() 3885 { 3886 m_isNewTargetLoadedInArrowFunction = true; 3887 3888 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 3889 emitMove(m_newTargetRegister, emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), newTargetVar, ThrowIfNotFound)); 3890 3891 return m_newTargetRegister; 3892 } 3893 3894 RegisterID* BytecodeGenerator::emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment() 3895 { 3896 Variable protoScopeVar = variable(propertyNames().derivedConstructorPrivateName); 3897 return emitGetFromScope(newTemporary(), emitLoadArrowFunctionLexicalEnvironment(), protoScopeVar, ThrowIfNotFound); 3898 } 3899 3900 void BytecodeGenerator::emitPutNewTargetToArrowFunctionContextScope() 3901 { 3902 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 3903 3904 Variable newTargetVar = variable(propertyNames().newTargetLocalPrivateName); 3905 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, newTargetVar, newTarget(), DoNotThrowIfNotFound, Initialization); 3906 } 3907 3908 void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope() 3909 { 3910 if (isConstructor() && constructorKind() == ConstructorKind::Derived) { 3911 ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 3912 3913 Variable protoScope = variable(propertyNames().derivedConstructorPrivateName); 3914 emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, Initialization); 3915 } 3916 } 3917 3918 void BytecodeGenerator::emitPutThisToArrowFunctionContextScope() 3919 { 3920 ASSERT(isDerivedConstructorContext() || m_arrowFunctionContextLexicalEnvironmentRegister != nullptr); 3921 3922 if (isDerivedConstructorContext()) 3923 emitLoadArrowFunctionLexicalEnvironment(); 3924 3925 Variable thisVar = variable(propertyNames().thisIdentifier, ThisResolutionType::Scoped); 3926 emitPutToScope(isDerivedConstructorContext() ? m_resolvedArrowFunctionScopeContextRegister.get() : m_arrowFunctionContextLexicalEnvironmentRegister, thisVar, thisRegister(), DoNotThrowIfNotFound, NotInitialization); 3927 } 3928 3805 3929 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister) 3806 3930 { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r192814 r192876 66 66 }; 67 67 68 enum class ThisResolutionType { Local, Scoped }; 69 68 70 class CallArguments { 69 71 public: … … 280 282 281 283 bool isConstructor() const { return m_codeBlock->isConstructor(); } 284 bool isDerivedConstructorContext() const { return m_codeBlock->isDerivedConstructorContext(); } 285 bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); } 286 bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; } 287 bool usesEval() const { return m_scopeNode->usesEval(); } 288 bool usesThis() const { return m_scopeNode->usesThis(); } 282 289 ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); } 283 290 … … 286 293 bool isArgumentNumber(const Identifier&, int); 287 294 288 Variable variable(const Identifier& );295 Variable variable(const Identifier&, ThisResolutionType = ThisResolutionType::Local); 289 296 290 297 enum ExistingVariableMode { VerifyExisting, IgnoreExisting }; … … 294 301 RegisterID* thisRegister() { return &m_thisRegister; } 295 302 RegisterID* argumentsRegister() { return m_argumentsRegister; } 296 RegisterID* newTarget() { return m_newTargetRegister; } 303 RegisterID* newTarget() 304 { 305 return !m_codeBlock->isArrowFunction() || m_isNewTargetLoadedInArrowFunction 306 ? m_newTargetRegister : emitLoadNewTargetFromArrowFunctionLexicalEnvironment(); 307 } 297 308 298 309 RegisterID* scopeRegister() { return m_scopeRegister; } … … 480 491 481 492 void emitProfileControlFlow(int); 493 494 RegisterID* emitLoadArrowFunctionLexicalEnvironment(); 495 void emitLoadThisFromArrowFunctionLexicalEnvironment(); 496 RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment(); 482 497 483 498 RegisterID* emitLoad(RegisterID* dst, bool); … … 624 639 RegisterID* emitPushWithScope(RegisterID* objectScope); 625 640 void emitPopWithScope(); 641 void emitPutThisToArrowFunctionContextScope(); 642 void emitPutNewTargetToArrowFunctionContextScope(); 643 void emitPutDerivedConstructorToArrowFunctionContextScope(); 644 RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(); 626 645 627 646 void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart); … … 699 718 void allocateCalleeSaveSpace(); 700 719 void allocateAndEmitScope(); 701 RegisterID* emitLoadArrowFunctionThis(RegisterID*);702 720 void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope); 703 721 … … 751 769 UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata) 752 770 { 771 bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->isArrowFunction()); 772 753 773 VariableEnvironment variablesUnderTDZ; 754 774 getVariablesUnderTDZ(variablesUnderTDZ); … … 759 779 constructAbility = ConstructAbility::CannotConstruct; 760 780 761 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, variablesUnderTDZ );781 return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, variablesUnderTDZ, newisDerivedConstructorContext); 762 782 } 763 783 … … 769 789 void initializeVarLexicalEnvironment(int symbolTableConstantIndex); 770 790 void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures); 791 void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* = nullptr); 771 792 772 793 public: … … 810 831 RegisterID* m_newTargetRegister { nullptr }; 811 832 RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount]; 833 RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr }; 834 RefPtr<RegisterID> m_resolvedArrowFunctionScopeContextRegister; 812 835 813 836 SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters; … … 864 887 bool m_usesNonStrictEval { false }; 865 888 bool m_inTailPosition { false }; 889 bool m_isDerivedConstructorContext { false }; 890 bool m_needsToUpdateArrowFunctionContext; 891 bool m_isNewTargetLoadedInArrowFunction { false }; 866 892 }; 867 893 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r192814 r192876 146 146 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 147 147 { 148 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived) 148 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 149 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); 150 151 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext()) 149 152 generator.emitTDZCheck(generator.thisRegister()); 150 153 … … 165 168 return 0; 166 169 167 RegisterID callee; 168 callee.setIndex(JSStack::Callee); 169 170 return generator.emitGetById(generator.finalDestination(dst), &callee, generator.propertyNames().underscoreProto); 170 RegisterID* scopeId; 171 if (generator.isDerivedConstructorContext()) 172 scopeId = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(); 173 else { 174 RegisterID callee; 175 callee.setIndex(JSStack::Callee); 176 177 scopeId = &callee; 178 } 179 180 return generator.emitGetById(generator.finalDestination(dst), scopeId, generator.propertyNames().underscoreProto); 171 181 } 172 182 … … 692 702 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 693 703 { 704 // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function 705 // var A = class A { 706 // constructor () { this.id = 'A'; } 707 // } 708 // 709 // var B = class B extend A { 710 // constructor () { 711 // var arrow = () => super(); 712 // arrow(); 713 // eval("this.id = 'B'"); 714 // } 715 // } 716 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 717 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); 718 694 719 Variable var = generator.variable(generator.propertyNames().eval); 695 720 if (RegisterID* local = var.local()) { … … 719 744 CallArguments callArguments(generator, m_args); 720 745 if (m_expr->isSuperNode()) { 721 ASSERT(generator.isConstructor() );722 ASSERT(generator.constructorKind() == ConstructorKind::Derived );746 ASSERT(generator.isConstructor() || generator.isDerivedConstructorContext()); 747 ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.isDerivedConstructorContext()); 723 748 generator.emitMove(callArguments.thisRegister(), generator.newTarget()); 724 749 RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); 725 750 generator.emitMove(generator.thisRegister(), ret); 751 752 bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived; 753 if (generator.isDerivedConstructorContext() || (isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext())) 754 generator.emitPutThisToArrowFunctionContextScope(); 755 726 756 return ret; 727 757 } … … 2981 3011 // If there is no return we must automatically insert one. 2982 3012 if (!returnNode) { 3013 if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext()) 3014 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment 3015 2983 3016 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); 2984 3017 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
r189123 r192876 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
r192814 r192876 1806 1806 break; 1807 1807 1808 case LoadArrowFunctionThis:1809 if (JSValue base = forNode(node->child1()).m_value) {1810 JSArrowFunction* function = jsDynamicCast<JSArrowFunction*>(base);1811 setConstant(node, *m_graph.freeze(function->boundThis()));1812 break;1813 }1814 forNode(node).setType(m_graph, SpecFinalObject);1815 break;1816 1817 1808 case SkipScope: { 1818 1809 JSValue child = forNode(node->child1()).value(); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r192814 r192876 4515 4515 NEXT_OPCODE(op_get_scope); 4516 4516 } 4517 4518 case op_load_arrowfunction_this: {4519 Node* callee = get(VirtualRegister(JSStack::Callee));4520 Node* result;4521 if (JSArrowFunction* function = callee->dynamicCastConstant<JSArrowFunction*>())4522 result = jsConstant(function->boundThis());4523 else4524 result = addToGraph(LoadArrowFunctionThis, callee);4525 set(VirtualRegister(currentInstruction[1].u.operand), result);4526 NEXT_OPCODE(op_load_arrowfunction_this);4527 }4528 4517 4529 4518 case op_create_direct_arguments: { … … 4575 4564 } 4576 4565 4577 case op_new_func_exp: { 4566 case op_new_func_exp: 4567 case op_new_arrow_func_exp: { 4578 4568 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4579 4569 FrozenValue* frozen = m_graph.freezeStrong(expr); 4580 4570 set(VirtualRegister(currentInstruction[1].u.operand), 4581 4571 addToGraph(NewFunction, OpInfo(frozen), get(VirtualRegister(currentInstruction[2].u.operand)))); 4582 NEXT_OPCODE(op_new_func_exp); 4583 } 4584 4585 case op_new_arrow_func_exp: { 4586 FunctionExecutable* expr = m_inlineStackTop->m_profiledBlock->functionExpr(currentInstruction[3].u.operand); 4587 FrozenValue* frozen = m_graph.freezeStrong(expr); 4588 4589 set(VirtualRegister(currentInstruction[1].u.operand), 4590 addToGraph(NewArrowFunction, OpInfo(frozen), 4591 get(VirtualRegister(currentInstruction[2].u.operand)), 4592 get(VirtualRegister(currentInstruction[4].u.operand)))); 4593 4594 NEXT_OPCODE(op_new_arrow_func_exp); 4572 4573 if (opcodeID == op_new_func_exp) { 4574 // Curly braces are necessary 4575 NEXT_OPCODE(op_new_func_exp); 4576 } else { 4577 // Curly braces are necessary 4578 NEXT_OPCODE(op_new_arrow_func_exp); 4579 } 4595 4580 } 4596 4581 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r192814 r192876 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
r192814 r192876 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
r192814 r192876 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
r192814 r192876 1010 1010 fixEdge<KnownCellUse>(node->child1()); 1011 1011 speculateForBarrier(node->child2()); 1012 break;1013 }1014 1015 case LoadArrowFunctionThis: {1016 fixEdge<KnownCellUse>(node->child1());1017 1012 break; 1018 1013 } -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r192814 r192876 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
r191870 r192876 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
r192814 r192876 593 593 case GetScope: 594 594 changed |= setPrediction(SpecObjectOther); 595 break;596 597 case LoadArrowFunctionThis:598 changed |= setPrediction(SpecFinalObject);599 595 break; 600 596 -
trunk/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.cpp
r188545 r192876 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
r188545 r192876 47 47 FunctionActivationPLoc, 48 48 ActivationScopePLoc, 49 ClosureVarPLoc, 50 ArrowFunctionBoundThisPLoc 49 ClosureVarPLoc 51 50 }; 52 51 -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r192814 r192876 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
r192842 r192876 4740 4740 cellResult(result.gpr(), node); 4741 4741 } 4742 4743 4744 void SpeculativeJIT::compileLoadArrowFunctionThis(Node* node)4745 {4746 SpeculateCellOperand function(this, node->child1());4747 GPRTemporary result(this, Reuse, function);4748 m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSArrowFunction::offsetOfThisValue()), result.gpr());4749 cellResult(result.gpr(), node);4750 }4751 4742 4752 4743 void SpeculativeJIT::compileSkipScope(Node* node) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r192814 r192876 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
r192814 r192876 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
r192814 r192876 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
r192814 r192876 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
r192856 r192876 810 810 case GetScope: 811 811 compileGetScope(); 812 break;813 case LoadArrowFunctionThis:814 compileLoadArrowFunctionThis();815 812 break; 816 813 case SkipScope: … … 4508 4505 } 4509 4506 4510 void compileLoadArrowFunctionThis()4511 {4512 setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrowFunction_this));4513 }4514 4515 4507 void compileSkipScope() 4516 4508 { -
trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp
r190896 r192876 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
r192203 r192876 173 173 174 174 ThisTDZMode thisTDZMode = callerCodeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded; 175 eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);175 eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, callerCodeBlock->unlinkedCodeBlock()->isDerivedConstructorContext(), callerCodeBlock->unlinkedCodeBlock()->isArrowFunction(), programSource, callerScopeChain); 176 176 if (!eval) 177 177 return jsUndefined(); -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r192814 r192876 222 222 DEFINE_OP(op_enter) 223 223 DEFINE_OP(op_get_scope) 224 DEFINE_OP(op_load_arrowfunction_this)225 224 DEFINE_OP(op_eq) 226 225 DEFINE_OP(op_eq_null) -
trunk/Source/JavaScriptCore/jit/JIT.h
r192836 r192876 501 501 void emit_op_enter(Instruction*); 502 502 void emit_op_get_scope(Instruction*); 503 void emit_op_load_arrowfunction_this(Instruction*);504 503 void emit_op_eq(Instruction*); 505 504 void emit_op_eq_null(Instruction*); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r192814 r192876 685 685 emitStoreCell(dst, regT0); 686 686 } 687 688 void JIT::emit_op_load_arrowfunction_this(Instruction* currentInstruction)689 {690 int dst = currentInstruction[1].u.operand;691 emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0);692 loadPtr(Address(regT0, JSArrowFunction::offsetOfThisValue()), regT0);693 emitStoreCell(dst, regT0);694 }695 687 696 688 void JIT::emit_op_to_this(Instruction* currentInstruction) … … 989 981 void JIT::emitNewFuncExprCommon(Instruction* currentInstruction) 990 982 { 991 OpcodeID opcodeID = m_vm->interpreter->getOpcodeID(currentInstruction->u.opcode);992 bool isArrowFunction = opcodeID == op_new_arrow_func_exp;993 994 983 Jump notUndefinedScope; 995 984 int dst = currentInstruction[1].u.operand; 996 985 #if USE(JSVALUE64) 997 986 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); 998 if (isArrowFunction)999 emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);1000 987 notUndefinedScope = branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsUndefined()))); 1001 988 store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, sizeof(Register) * dst)); 1002 989 #else 1003 990 emitLoadPayload(currentInstruction[2].u.operand, regT0); 1004 if (isArrowFunction) {1005 int value = currentInstruction[4].u.operand;1006 emitLoad(value, regT3, regT2);1007 }1008 991 notUndefinedScope = branch32(NotEqual, tagFor(currentInstruction[2].u.operand), TrustedImm32(JSValue::UndefinedTag)); 1009 992 emitStore(dst, jsUndefined()); … … 1013 996 1014 997 FunctionExecutable* function = m_codeBlock->functionExpr(currentInstruction[3].u.operand); 1015 if (isArrowFunction) 1016 #if USE(JSVALUE64) 1017 callOperation(operationNewArrowFunction, dst, regT0, function, regT1); 1018 #else 1019 callOperation(operationNewArrowFunction, dst, regT0, function, regT3, regT2); 1020 #endif 1021 else 1022 callOperation(operationNewFunction, dst, regT0, function); 998 callOperation(operationNewFunction, dst, regT0, function); 1023 999 done.link(this); 1024 1000 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r192155 r192876 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
r191897 r192876 1056 1056 { 1057 1057 LLINT_BEGIN(); 1058 1059 JSValue thisValue = LLINT_OP_C(4).jsValue(); 1058 1060 1059 CodeBlock* codeBlock = exec->codeBlock(); 1061 1060 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope(); 1062 1061 FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand); 1063 1062 1064 LLINT_RETURN(JS ArrowFunction::create(vm, executable, scope, thisValue));1063 LLINT_RETURN(JSFunction::create(vm, executable, scope)); 1065 1064 } 1066 1065 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r192814 r192876 1462 1462 traceExecution() 1463 1463 callSlowPath(_llint_slow_path_new_arrow_func_exp) 1464 dispatch( 5)1464 dispatch(4) 1465 1465 1466 1466 _llint_op_call: -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r192814 r192876 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
r192814 r192876 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
r192768 r192876 375 375 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo) 376 376 { 377 uses This();377 usesArrowFunction(); 378 378 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.bodyStartColumn); 379 379 ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source); … … 913 913 void incConstants() { m_scope.m_numConstants++; } 914 914 void usesThis() { m_scope.m_features |= ThisFeature; } 915 void usesArrowFunction() { m_scope.m_features |= ArrowFunctionFeature; } 915 916 void usesArguments() { m_scope.m_features |= ArgumentsFeature; } 916 917 void usesWith() { m_scope.m_features |= WithFeature; } -
trunk/Source/JavaScriptCore/parser/Nodes.h
r192768 r192876 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
r192768 r192876 1877 1877 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 1878 1878 } 1879 if (functionScope->hasDirectSuper() ) {1879 if (functionScope->hasDirectSuper() && functionBodyType == StandardFunctionBodyBlock) { 1880 1880 semanticFailIfTrue(!isClassConstructor, "Cannot call super() outside of a class constructor"); 1881 1881 semanticFailIfTrue(constructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor"); 1882 1882 } 1883 if (functionScope->needsSuperBinding() )1883 if (functionScope->needsSuperBinding() && functionBodyType == StandardFunctionBodyBlock) 1884 1884 semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class"); 1885 1885 -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r191875 r192876 144 144 typedef unsigned CodeFeatures; 145 145 146 const CodeFeatures NoFeatures = 0; 147 const CodeFeatures EvalFeature = 1 << 0; 148 const CodeFeatures ArgumentsFeature = 1 << 1; 149 const CodeFeatures WithFeature = 1 << 2; 150 const CodeFeatures ThisFeature = 1 << 3; 151 const CodeFeatures StrictModeFeature = 1 << 4; 152 const CodeFeatures ShadowsArgumentsFeature = 1 << 5; 153 const CodeFeatures ModifiedParameterFeature = 1 << 6; 154 const CodeFeatures ModifiedArgumentsFeature = 1 << 7; 146 const CodeFeatures NoFeatures = 0; 147 const CodeFeatures EvalFeature = 1 << 0; 148 const CodeFeatures ArgumentsFeature = 1 << 1; 149 const CodeFeatures WithFeature = 1 << 2; 150 const CodeFeatures ThisFeature = 1 << 3; 151 const CodeFeatures StrictModeFeature = 1 << 4; 152 const CodeFeatures ShadowsArgumentsFeature = 1 << 5; 153 const CodeFeatures ModifiedParameterFeature = 1 << 6; 154 const CodeFeatures ModifiedArgumentsFeature = 1 << 7; 155 const CodeFeatures ArrowFunctionFeature = 1 << 8; 156 const CodeFeatures ArrowFunctionContextFeature = 1 << 9; 155 157 156 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature ;158 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ModifiedParameterFeature | ArrowFunctionFeature | ArrowFunctionContextFeature; 157 159 158 160 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/CodeCache.cpp
r189201 r192876 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, emptyTDZVariables );191 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, false); 192 192 functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string())); 193 193 -
trunk/Source/JavaScriptCore/runtime/CodeCache.h
r190267 r192876 259 259 260 260 UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&); 261 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);261 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*); 262 262 UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ProfilerMode, ParserError&); 263 263 UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&); … … 270 270 private: 271 271 template <class UnlinkedCodeBlockType, class ExecutableType> 272 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);272 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, bool, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*); 273 273 274 274 CodeCacheMap m_sourceCode; -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r192874 r192876 331 331 macro(Float32Array) \ 332 332 macro(Float64Array) \ 333 macro(newTargetLocal) \ 334 macro(derivedConstructor) \ 335 333 336 334 337 -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r192814 r192876 226 226 #if !ASSERT_DISABLED 227 227 ConstructData constructData; 228 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS );228 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS || constructor->jsExecutable()->isArrowFunction()); 229 229 #endif 230 230 -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r191530 r192876 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
r190827 r192876 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, false ); }455 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), isArrowFunctionContext()); } 452 456 453 457 unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); } … … 457 461 friend class ExecutableBase; 458 462 friend class ScriptExecutable; 459 EvalExecutable(ExecState*, const SourceCode&, bool );463 EvalExecutable(ExecState*, const SourceCode&, bool inStrictContext, bool isDerivedConstructorContext, bool isArrowFunctionContext); 460 464 461 465 static void visitChildren(JSCell*, SlotVisitor&); … … 502 506 DECLARE_INFO; 503 507 504 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false ); }508 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), false); } 505 509 506 510 private: … … 543 547 DECLARE_INFO; 544 548 545 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); } 549 ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false, isDerivedConstructorContext(), false); } 550 546 551 UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); } 547 552 … … 652 657 ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); } 653 658 bool isArrowFunction() const { return m_unlinkedExecutable->isArrowFunction(); } 659 bool isDerivedConstructorContext() const { return m_unlinkedExecutable->isDerivedConstructorContext(); } 654 660 bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); } 655 661 const Identifier& name() { return m_unlinkedExecutable->name(); } -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r192874 r192876 950 950 } 951 951 952 UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, const VariableEnvironment* variablesUnderTDZ)952 UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, ThisTDZMode thisTDZMode, bool isArrowFunctionContext, const VariableEnvironment* variablesUnderTDZ) 953 953 { 954 954 ParserError error; … … 957 957 ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff; 958 958 UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock( 959 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ);959 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, thisTDZMode, isArrowFunctionContext, debuggerMode, profilerMode, error, variablesUnderTDZ); 960 960 961 961 if (hasDebugger()) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r190601 r192876 662 662 663 663 UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); 664 UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, const VariableEnvironment*);664 UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, bool isArrowFunctionContext, const VariableEnvironment*); 665 665 UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*); 666 666 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r189279 r192876 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
r192768 r192876 744 744 cmd: runES6 :fail 745 745 - path: es6/arrow_functions_lexical_new.target_binding.js 746 cmd: runES6 : fail746 cmd: runES6 :normal 747 747 - path: es6/arrow_functions_lexical_super_binding.js 748 748 cmd: runES6 :fail -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink-osrexit.js
r188545 r192876 1 var n = 100000 0;1 var n = 100000; 2 2 3 3 function bar() { } -
trunk/Source/JavaScriptCore/tests/stress/arrowfunction-activation-sink.js
r188545 r192876 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
r188545 r192876 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.