Changeset 215986 in webkit
- Timestamp:
- Apr 30, 2017, 7:51:27 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r215984 r215986 1 2017-04-30 Oleksandr Skachkov <gskachkov@gmail.com> 2 3 We initialize functions too early in an eval 4 https://bugs.webkit.org/show_bug.cgi?id=161099 5 6 Reviewed by Saam Barati. 7 8 * stress/eval-func-decl-with-let-const-class.js: Added. 9 1 10 2017-04-30 Oleksandr Skachkov <gskachkov@gmail.com> 2 11 -
trunk/Source/JavaScriptCore/ChangeLog
r215984 r215986 1 2017-04-30 Oleksandr Skachkov <gskachkov@gmail.com> 2 3 We initialize functions too early in an eval 4 https://bugs.webkit.org/show_bug.cgi?id=161099 5 6 Reviewed by Saam Barati. 7 8 Current patch allow to fix problem with scope in function that is 9 declared within eval. Before scope was set inside Interpretator.cpp and it 10 was scope where eval is executed, but in this case function would not 11 see let/const variables and classes declated in eval. 12 This patch devide declaration and binding in two operation, first just declare 13 variable with function name, and second bind variable to function with correct 14 scope 15 16 * bytecompiler/BytecodeGenerator.cpp: 17 (JSC::BytecodeGenerator::generate): 18 (JSC::BytecodeGenerator::BytecodeGenerator): 19 * bytecompiler/BytecodeGenerator.h: 20 * interpreter/Interpreter.cpp: 21 (JSC::Interpreter::execute): 22 1 23 2017-04-30 Oleksandr Skachkov <gskachkov@gmail.com> 2 24 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r215984 r215986 107 107 { 108 108 RefPtr<RegisterID> temp = newTemporary(); 109 RefPtr<RegisterID> globalScope;109 RefPtr<RegisterID> tolLevelScope; 110 110 for (auto functionPair : m_functionsToInitialize) { 111 111 FunctionMetadataNode* metadata = functionPair.first; … … 114 114 if (functionType == NormalFunctionVariable) 115 115 initializeVariable(variable(metadata->ident()), temp.get()); 116 else if (functionType == GlobalFunctionVariable) {117 if (! globalScope) {118 // We know this will resolve to the global object because our parser/global initialization code116 else if (functionType == TopLevelFunctionVariable) { 117 if (!tolLevelScope) { 118 // We know this will resolve to the top level scope or global object because our parser/global initialization code 119 119 // doesn't allow let/const/class variables to have the same names as functions. 120 RefPtr<RegisterID> globalObjectScope = emitResolveScope(nullptr, Variable(metadata->ident())); 121 globalScope = newBlockScopeVariable(); 122 emitMove(globalScope.get(), globalObjectScope.get()); 120 // This is a top level function, and it's an error to ever create a top level function 121 // name that would resolve to a lexical variable. E.g: 122 // ``` 123 // function f() { 124 // { 125 // let x; 126 // { 127 // //// error thrown here 128 // eval("function x(){}"); 129 // } 130 // } 131 // } 132 // ``` 133 // Therefore, we're guaranteed to have this resolve to a top level variable. 134 RefPtr<RegisterID> tolLevelObjectScope = emitResolveScope(nullptr, Variable(metadata->ident())); 135 tolLevelScope = newBlockScopeVariable(); 136 emitMove(tolLevelScope.get(), tolLevelObjectScope.get()); 123 137 } 124 emitPutToScope( globalScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, InitializationMode::NotInitialization);138 emitPutToScope(tolLevelScope.get(), Variable(metadata->ident()), temp.get(), ThrowIfNotFound, InitializationMode::NotInitialization); 125 139 } else 126 140 RELEASE_ASSERT_NOT_REACHED(); … … 208 222 209 223 for (auto* function : functionStack) 210 m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));224 m_functionsToInitialize.append(std::make_pair(function, TopLevelFunctionVariable)); 211 225 212 226 if (Options::validateBytecode()) { … … 765 779 emitCheckTraps(); 766 780 767 for (FunctionMetadataNode* function : evalNode->functionStack()) 781 for (FunctionMetadataNode* function : evalNode->functionStack()) { 768 782 m_codeBlock->addFunctionDecl(makeFunction(function)); 783 m_functionsToInitialize.append(std::make_pair(function, TopLevelFunctionVariable)); 784 } 769 785 770 786 const VariableEnvironment& varDeclarations = evalNode->varDeclarations(); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r215984 r215986 1112 1112 int m_generatorFrameSymbolTableIndex { 0 }; 1113 1113 1114 enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };1114 enum FunctionVariableType : uint8_t { NormalFunctionVariable, TopLevelFunctionVariable }; 1115 1115 Vector<std::pair<FunctionMetadataNode*, FunctionVariableType>> m_functionsToInitialize; 1116 1116 bool m_needToInitializeArguments { false }; -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r215984 r215986 1179 1179 FunctionExecutable* function = codeBlock->functionDecl(i); 1180 1180 PutPropertySlot slot(variableObject); 1181 variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot); 1181 // We need create this variables because it will be used to emits code by bytecode generator 1182 variableObject->methodTable()->put(variableObject, callFrame, function->name(), jsUndefined(), slot); 1182 1183 } 1183 1184 } else { … … 1188 1189 return checkedReturn(throwSyntaxError(callFrame, throwScope, makeString("Can't create duplicate variable in eval: '", String(function->name().impl()), "'"))); 1189 1190 PutPropertySlot slot(variableObject); 1190 variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot); 1191 // We need create this variables because it will be used to emits code by bytecode generator 1192 variableObject->methodTable()->put(variableObject, callFrame, function->name(), jsUndefined(), slot); 1191 1193 RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception())); 1192 1194 }
Note:
See TracChangeset
for help on using the changeset viewer.