RESOLVED FIXED 148581
[ES6] Introduce ModuleProgramExecutable families and compile Module code to bytecode
https://bugs.webkit.org/show_bug.cgi?id=148581
Summary [ES6] Introduce ModuleProgramExecutable families and compile Module code to b...
Yusuke Suzuki
Reported 2015-08-28 11:24:24 PDT
Introduce ModuleProgramExecutable families (ModuleProgramExecutable, UnlinkedModuleProgramCodeBlock, ModuleProgramCodeBlock, etc.)
Attachments
Patch (76.15 KB, patch)
2015-08-28 15:50 PDT, Yusuke Suzuki
no flags
Patch (76.13 KB, patch)
2015-08-28 17:19 PDT, Yusuke Suzuki
no flags
Patch (76.39 KB, patch)
2015-08-28 17:27 PDT, Yusuke Suzuki
no flags
Patch (76.56 KB, patch)
2015-08-28 23:04 PDT, Yusuke Suzuki
saam: review+
Yusuke Suzuki
Comment 1 2015-08-28 13:49:32 PDT
CodeBlock linking will not be included in this patch yet, because it involves JSModuleEnvironment instantiation.
Yusuke Suzuki
Comment 2 2015-08-28 15:50:05 PDT
Yusuke Suzuki
Comment 3 2015-08-28 17:19:56 PDT
Yusuke Suzuki
Comment 4 2015-08-28 17:20:14 PDT
Build fix for Internals.cpp in WebCore.
Yusuke Suzuki
Comment 5 2015-08-28 17:27:10 PDT
Created attachment 260198 [details] Patch slightly update the code comment
Yusuke Suzuki
Comment 6 2015-08-28 22:59:19 PDT
I'll just modify one thing, calling makeFunction after putting the correct variable environment to the TDZ stack.
Yusuke Suzuki
Comment 7 2015-08-28 23:04:29 PDT
Created attachment 260219 [details] Patch Fix the makeFunction timing. It should be called after the TDZ stack is set
Saam Barati
Comment 8 2015-08-31 13:27:53 PDT
Comment on attachment 260219 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=260219&action=review r=me > Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:-415 > - WriteBarrier<SymbolTable> m_symbolTable; This was unused before? > Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:544 > + // The unlinked module program code block only holds the symbol table. Not holds the module environment. So while "Not holds the module environment" => "It does not hold the module environment." > Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:566 > + WriteBarrier<SymbolTable> m_symbolTable; Nit: Since a CodeBlock may own many SymbolTables in its constant pool, maybe we can give this a more descriptive name? Maybe something like "moduleEnvironmentSymbolTable" > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:582 > + { It seems like this code has a lot in common with pushLexicalScope. I wonder if we can find a way to abstract it nicely. > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:617 > + m_symbolTableStack.append(SymbolTableStackEntry { Strong<SymbolTable>(*m_vm, symbolTable), m_scopeRegister, false, constantSymbolTable->index() }); I think this may be wrong. We really want a dedicated scope register for this environment. m_scopeRegister won't always refer to the "module scope" because as we push other lexical scopes on top of this, m_scopeRegister will take on those values. Maybe one solution is to do this: RegisterID* moduleScope = addVar(); emitMove(moduleScope, m_scopeRegister); and then pass this value into m_symbolTableStack.append(.) Another approach is to use m_topMostScope (which basically does that I stated above). > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:621 > + for (auto& entry : lexicalVariables) { Same here. We can probably abstract this somehow. Maybe we can create a function that acccepts a filter function which causes some entries to be accepter/ignored? > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:679 > + // Module EntryPoint (executed last): I like these comments. I'd also add link order as well as execution order, so maybe here: "(executed last, linked first)" > Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2898 > +void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) Nit: This looks identical to ProgramNode::emitBytecode. Maybe we can abstract them into both calling a static function.
Yusuke Suzuki
Comment 9 2015-08-31 15:48:59 PDT
Comment on attachment 260219 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=260219&action=review >> Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:-415 >> - WriteBarrier<SymbolTable> m_symbolTable; > > This was unused before? Yup! It was the dead code. >> Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:544 >> + // The unlinked module program code block only holds the symbol table. Not holds the module environment. So while > > "Not holds the module environment" => "It does not hold the module environment." Oops. Fixed. >> Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:566 >> + WriteBarrier<SymbolTable> m_symbolTable; > > Nit: Since a CodeBlock may own many SymbolTables in its constant pool, maybe we can give this a more descriptive name? > Maybe something like "moduleEnvironmentSymbolTable" Sounds very nice. Descriptive name is always fine. I've changed it. >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:582 >> + { > > It seems like this code has a lot in common with pushLexicalScope. I wonder if we can find a way to abstract it nicely. Yup. These 2 parts are similar to pushLexicalScopeInternal. The difference between this function and pushLexicalScopeInternal are, 1. pushLexicalScopeInternal creates the SymbolTable 2. pushLexicalScopeInternal emit the byte code to create the scope and the same part is, 1. add entries to SymbolTable 2. append symbol table to the symbol table stack 3. append TDZ stack and fill the TDZ stack values So I'll extract 1, 2, 3 functions from the pushLexicalScopeInternal and use it in pushLexicalScopeInternal and module symbol table instantiation phase. >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:617 >> + m_symbolTableStack.append(SymbolTableStackEntry { Strong<SymbolTable>(*m_vm, symbolTable), m_scopeRegister, false, constantSymbolTable->index() }); > > I think this may be wrong. We really want a dedicated scope register for this environment. > m_scopeRegister won't always refer to the "module scope" because as we push > other lexical scopes on top of this, m_scopeRegister will take on those values. > Maybe one solution is to do this: > RegisterID* moduleScope = addVar(); > emitMove(moduleScope, m_scopeRegister); > and then pass this value into m_symbolTableStack.append(.) > > Another approach is to use m_topMostScope (which basically does that I stated above). Using m_topMostScope is nice because the module environment is always the top most scope under the module. >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:621 >> + for (auto& entry : lexicalVariables) { > > Same here. We can probably abstract this somehow. Maybe we can create a function that acccepts a filter function which causes some entries to be accepter/ignored? Yeah, extracted function will take a filter function. >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:679 >> + // Module EntryPoint (executed last): > > I like these comments. I'd also add link order as well as execution order, > so maybe here: > "(executed last, linked first)" Nice. I've added it. >> Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2898 >> +void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) > > Nit: This looks identical to ProgramNode::emitBytecode. > Maybe we can abstract them into both calling a static function. Looks nice. Fixed.
Yusuke Suzuki
Comment 10 2015-08-31 18:23:23 PDT
Comment on attachment 260219 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=260219&action=review >>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:582 >>> + { >> >> It seems like this code has a lot in common with pushLexicalScope. I wonder if we can find a way to abstract it nicely. > > Yup. These 2 parts are similar to pushLexicalScopeInternal. > The difference between this function and pushLexicalScopeInternal are, > 1. pushLexicalScopeInternal creates the SymbolTable > 2. pushLexicalScopeInternal emit the byte code to create the scope > and the same part is, > 1. add entries to SymbolTable > 2. append symbol table to the symbol table stack > 3. append TDZ stack and fill the TDZ stack values > > So I'll extract 1, 2, 3 functions from the pushLexicalScopeInternal and use it in pushLexicalScopeInternal and module symbol table instantiation phase. At least, extracting (3) was nice. So, in the meantime, I just extracted the (3). >>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:679 >>> + // Module EntryPoint (executed last): >> >> I like these comments. I'd also add link order as well as execution order, >> so maybe here: >> "(executed last, linked first)" > > Nice. I've added it. Technically, "Link" order is the same to the execution order. But, the "link" order is not so important because when linking we already instantiated the all module environment. And when executing, we already linked the all modules. The interesting point is this. When the execution starts, the all linking is already finished. So function bindings are already instantiated. This causes the above crazy behavior :-)
Yusuke Suzuki
Comment 11 2015-08-31 18:56:50 PDT
Comment on attachment 260219 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=260219&action=review >>>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:582 >>>> + { >>> >>> It seems like this code has a lot in common with pushLexicalScope. I wonder if we can find a way to abstract it nicely. >> >> Yup. These 2 parts are similar to pushLexicalScopeInternal. >> The difference between this function and pushLexicalScopeInternal are, >> 1. pushLexicalScopeInternal creates the SymbolTable >> 2. pushLexicalScopeInternal emit the byte code to create the scope >> and the same part is, >> 1. add entries to SymbolTable >> 2. append symbol table to the symbol table stack >> 3. append TDZ stack and fill the TDZ stack values >> >> So I'll extract 1, 2, 3 functions from the pushLexicalScopeInternal and use it in pushLexicalScopeInternal and module symbol table instantiation phase. > > At least, extracting (3) was nice. So, in the meantime, I just extracted the (3). After considering about this, I also extracted (1). But extracting (2) is not so good (because its so small). So I've just extracted (1) & (3).
Yusuke Suzuki
Comment 12 2015-08-31 19:05:50 PDT
Note You need to log in before you can comment on or make changes to this bug.