Changeset 183789 in webkit
- Timestamp:
- May 4, 2015 8:27:09 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r183787 r183789 1 2015-05-04 Saam Barati <saambarati1@gmail.com> 2 3 Global functions should be initialized as JSFunctions in byte code 4 https://bugs.webkit.org/show_bug.cgi?id=144178 5 6 Reviewed by Geoffrey Garen. 7 8 This patch makes the initialization of global functions more explicit by 9 moving initialization into bytecode. It also prepares JSC for having ES6 10 style lexical scoping because initializing global functions in bytecode 11 easily allows global functions to be initialized with the proper scope that 12 will have access to global lexical variables. Global lexical variables 13 should be visible to global functions but don't live on the global object. 14 15 * bytecode/UnlinkedCodeBlock.cpp: 16 (JSC::UnlinkedProgramCodeBlock::visitChildren): 17 * bytecode/UnlinkedCodeBlock.h: 18 * bytecompiler/BytecodeGenerator.cpp: 19 (JSC::BytecodeGenerator::generate): 20 (JSC::BytecodeGenerator::BytecodeGenerator): 21 * bytecompiler/BytecodeGenerator.h: 22 * runtime/Executable.cpp: 23 (JSC::ProgramExecutable::initializeGlobalProperties): 24 * runtime/JSGlobalObject.cpp: 25 (JSC::JSGlobalObject::addGlobalVar): 26 (JSC::JSGlobalObject::addFunction): 27 * runtime/JSGlobalObject.h: 28 1 29 2015-05-04 Filip Pizlo <fpizlo@apple.com> 2 30 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r183570 r183789 472 472 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 473 473 Base::visitChildren(thisObject, visitor); 474 for (size_t i = 0, end = thisObject->m_functionDeclarations.size(); i != end; i++)475 visitor.append(&thisObject->m_functionDeclarations[i].second);476 474 } 477 475 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r183570 r183789 655 655 static void destroy(JSCell*); 656 656 657 void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)658 {659 m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));660 }661 662 657 void addVariableDeclaration(const Identifier& name, bool isConstant) 663 658 { … … 666 661 667 662 typedef Vector<std::pair<Identifier, bool>> VariableDeclations; 668 typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;669 663 670 664 const VariableDeclations& variableDeclarations() const { return m_varDeclarations; } 671 const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }672 665 673 666 static void visitChildren(JSCell*, SlotVisitor&); … … 680 673 681 674 VariableDeclations m_varDeclarations; 682 FunctionDeclations m_functionDeclarations;683 675 684 676 public: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r183570 r183789 78 78 { 79 79 RefPtr<RegisterID> temp = newTemporary(); 80 for (FunctionBodyNode* functionBody : m_functionsToInitialize) { 80 RefPtr<RegisterID> globalScope = scopeRegister(); // FIXME: With lexical scoping, this won't always be the global object: https://bugs.webkit.org/show_bug.cgi?id=142944 81 for (auto functionPair : m_functionsToInitialize) { 82 FunctionBodyNode* functionBody = functionPair.first; 83 FunctionVariableType functionType = functionPair.second; 81 84 emitNewFunction(temp.get(), functionBody); 82 initializeVariable(variable(functionBody->ident()), temp.get()); 85 if (functionType == NormalFunctionVariable) 86 initializeVariable(variable(functionBody->ident()) , temp.get()); 87 else if (functionType == GlobalFunctionVariable) 88 emitPutToScope(globalScope.get(), Variable(functionBody->ident()), temp.get(), ThrowIfNotFound); 89 else 90 RELEASE_ASSERT_NOT_REACHED(); 83 91 } 84 92 } … … 164 172 for (size_t i = 0; i < functionStack.size(); ++i) { 165 173 FunctionBodyNode* function = functionStack[i]; 166 UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function); 167 codeBlock->addFunctionDeclaration(*m_vm, function->ident(), unlinkedFunction); 174 m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable)); 168 175 } 169 176 … … 385 392 const Identifier& ident = function->ident(); 386 393 createVariable(ident, varKind(ident.impl()), IsVariable); 387 m_functionsToInitialize.append( function);394 m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable)); 388 395 } 389 396 for (auto& entry : functionNode->varStack()) { -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r183570 r183789 745 745 Vector<TryContext> m_tryContextStack; 746 746 Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters; 747 Vector<FunctionBodyNode*> m_functionsToInitialize; 747 enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable }; 748 Vector<std::pair<FunctionBodyNode*, FunctionVariableType>> m_functionsToInitialize; 748 749 bool m_needToInitializeArguments { false }; 749 750 -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r182759 r183789 511 511 512 512 const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); 513 const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations(); 514 515 for (size_t i = 0; i < functionDeclarations.size(); ++i) { 516 UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get(); 517 JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, m_source), scope); 518 globalObject->addFunction(callFrame, functionDeclarations[i].first, value); 513 514 for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { 515 UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); 516 ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); 517 globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); 519 518 if (vm.typeProfiler() || vm.controlFlowProfiler()) { 520 519 vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r183785 r183789 503 503 } 504 504 505 JSGlobalObject::NewGlobalVarJSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)505 void JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode) 506 506 { 507 507 ConcurrentJITLocker locker(symbolTable()->m_lock); 508 508 SymbolTableEntry entry = symbolTable()->get(locker, ident.impl()); 509 if (!entry.isNull()) { 510 NewGlobalVar result; 511 result.offset = entry.scopeOffset(); 512 result.set = entry.watchpointSet(); 513 return result; 514 } 509 if (!entry.isNull()) 510 return; 515 511 516 512 ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker); … … 524 520 ScopeOffset offsetForAssert = addVariables(1); 525 521 RELEASE_ASSERT(offsetForAssert == offset); 526 527 NewGlobalVar var; 528 var.offset = offset; 529 var.set = newEntry.watchpointSet(); 530 return var; 531 } 532 533 void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName, JSValue value) 522 } 523 524 void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName) 534 525 { 535 526 VM& vm = exec->vm(); 536 527 removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties. 537 NewGlobalVar var = addGlobalVar(propertyName, IsVariable); 538 variableAt(var.offset).set(exec->vm(), this, value); 539 if (var.set) 540 var.set->touch(VariableWriteFireDetail(this, propertyName)); 528 addGlobalVar(propertyName, IsVariable); 541 529 } 542 530 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r183787 r183789 339 339 } 340 340 341 struct NewGlobalVar { 342 ScopeOffset offset; 343 WatchpointSet* set; 344 }; 345 NewGlobalVar addGlobalVar(const Identifier&, ConstantMode); 341 void addGlobalVar(const Identifier&, ConstantMode); 346 342 347 343 public: … … 375 371 addGlobalVar(propertyName, IsConstant); 376 372 } 377 void addFunction(ExecState*, const Identifier& , JSValue);373 void addFunction(ExecState*, const Identifier&); 378 374 379 375 // The following accessors return pristine values, even if a script
Note: See TracChangeset
for help on using the changeset viewer.