Changeset 189284 in webkit


Ignore:
Timestamp:
Sep 3, 2015 1:32:35 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Initial implementation of WebAssembly function compiler
https://bugs.webkit.org/show_bug.cgi?id=148734

Patch by Sukolsak Sakshuwong <Sukolsak Sakshuwong> on 2015-09-03
Reviewed by Filip Pizlo.

This patch introduces WASMFunctionCompiler, a class for generating
baseline JIT code for WebAssembly functions. The source for each
WebAssembly function is parsed in two passes.

  • The first pass is done by WASMFunctionSyntaxChecker when the WebAssembly module is initialized. It validates the syntax, determines the start and the end offsets in the source, and calculates the stack height of the function.
  • The second pass is done by WASMFunctionCompiler when the function is about to be executed.

This patch doesn't calculate the correct stack height nor generate
the correct code. That will be done in a subsequent patch.

(JSC::JSWASMModule::functionStartOffsetsInSource):
(JSC::JSWASMModule::functionStackHeights):

  • wasm/WASMFunctionCompiler.h: Added.

(JSC::WASMFunctionCompiler::WASMFunctionCompiler):
(JSC::WASMFunctionCompiler::startFunction):
(JSC::WASMFunctionCompiler::endFunction):
(JSC::WASMFunctionCompiler::throwStackOverflowError):
(JSC::WASMFunctionCompiler::localAddress):

  • wasm/WASMFunctionParser.cpp:

(JSC::WASMFunctionParser::checkSyntax):
(JSC::WASMFunctionParser::compile):
(JSC::WASMFunctionParser::parseFunction):

  • wasm/WASMFunctionParser.h:
  • wasm/WASMFunctionSyntaxChecker.h:

(JSC::WASMFunctionSyntaxChecker::startFunction):
(JSC::WASMFunctionSyntaxChecker::endFunction):
(JSC::WASMFunctionSyntaxChecker::stackHeight):

  • wasm/WASMModuleParser.cpp:

(JSC::WASMModuleParser::parseFunctionDeclarationSection):
(JSC::WASMModuleParser::parseFunctionDefinition):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r189279 r189284  
     12015-09-03  Sukolsak Sakshuwong  <sukolsak@gmail.com>
     2
     3        Initial implementation of WebAssembly function compiler
     4        https://bugs.webkit.org/show_bug.cgi?id=148734
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch introduces WASMFunctionCompiler, a class for generating
     9        baseline JIT code for WebAssembly functions. The source for each
     10        WebAssembly function is parsed in two passes.
     11        - The first pass is done by WASMFunctionSyntaxChecker when the
     12          WebAssembly module is initialized. It validates the syntax,
     13          determines the start and the end offsets in the source, and
     14          calculates the stack height of the function.
     15        - The second pass is done by WASMFunctionCompiler when the function
     16          is about to be executed.
     17        This patch doesn't calculate the correct stack height nor generate
     18        the correct code. That will be done in a subsequent patch.
     19
     20        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     21        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     22        * JavaScriptCore.xcodeproj/project.pbxproj:
     23        * wasm/JSWASMModule.h:
     24        (JSC::JSWASMModule::functionStartOffsetsInSource):
     25        (JSC::JSWASMModule::functionStackHeights):
     26        * wasm/WASMFunctionCompiler.h: Added.
     27        (JSC::WASMFunctionCompiler::WASMFunctionCompiler):
     28        (JSC::WASMFunctionCompiler::startFunction):
     29        (JSC::WASMFunctionCompiler::endFunction):
     30        (JSC::WASMFunctionCompiler::throwStackOverflowError):
     31        (JSC::WASMFunctionCompiler::localAddress):
     32        * wasm/WASMFunctionParser.cpp:
     33        (JSC::WASMFunctionParser::checkSyntax):
     34        (JSC::WASMFunctionParser::compile):
     35        (JSC::WASMFunctionParser::parseFunction):
     36        * wasm/WASMFunctionParser.h:
     37        * wasm/WASMFunctionSyntaxChecker.h:
     38        (JSC::WASMFunctionSyntaxChecker::startFunction):
     39        (JSC::WASMFunctionSyntaxChecker::endFunction):
     40        (JSC::WASMFunctionSyntaxChecker::stackHeight):
     41        * wasm/WASMModuleParser.cpp:
     42        (JSC::WASMModuleParser::parseFunctionDeclarationSection):
     43        (JSC::WASMModuleParser::parseFunctionDefinition):
     44
    1452015-09-03  Saam barati  <sbarati@apple.com>
    246
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r189279 r189284  
    18021802    <ClInclude Include="..\wasm\WASMConstants.h" />
    18031803    <ClInclude Include="..\wasm\WASMFormat.h" />
     1804    <ClInclude Include="..\wasm\WASMFunctionCompiler.h" />
    18041805    <ClInclude Include="..\wasm\WASMFunctionParser.h" />
    18051806    <ClInclude Include="..\wasm\WASMFunctionSyntaxChecker.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r189279 r189284  
    44584458      <Filter>wasm</Filter>
    44594459    </ClInclude>
     4460    <ClInclude Include="..\wasm\WASMFunctionCompiler.h">
     4461      <Filter>wasm</Filter>
     4462    </ClInclude>
    44604463    <ClInclude Include="..\wasm\WASMFunctionParser.h">
    44614464      <Filter>wasm</Filter>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r189279 r189284  
    10431043                7B0247571B8682E400542440 /* WASMFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B0247541B8682D500542440 /* WASMFunctionParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10441044                7B0247591B868EB700542440 /* WASMFunctionSyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B0247581B868EAE00542440 /* WASMFunctionSyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1045                7B2E010E1B97AA6900EF5D5C /* WASMFunctionCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */; };
    10451046                7B39F76D1B62DE2E00360FB4 /* WASMModuleParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */; };
    10461047                7B39F76E1B62DE3200360FB4 /* WASMModuleParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B39F76A1B62DE2200360FB4 /* WASMModuleParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    28682869                7B0247541B8682D500542440 /* WASMFunctionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionParser.h; sourceTree = "<group>"; };
    28692870                7B0247581B868EAE00542440 /* WASMFunctionSyntaxChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionSyntaxChecker.h; sourceTree = "<group>"; };
     2871                7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionCompiler.h; sourceTree = "<group>"; };
    28702872                7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMModuleParser.cpp; sourceTree = "<group>"; };
    28712873                7B39F76A1B62DE2200360FB4 /* WASMModuleParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMModuleParser.h; sourceTree = "<group>"; };
     
    44784480                                7B0247521B8682D500542440 /* WASMConstants.h */,
    44794481                                7BC547D21B69599B00959B58 /* WASMFormat.h */,
     4482                                7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */,
    44804483                                7B0247531B8682D500542440 /* WASMFunctionParser.cpp */,
    44814484                                7B0247541B8682D500542440 /* WASMFunctionParser.h */,
     
    68716874                                451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
    68726875                                86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
     6876                                7B2E010E1B97AA6900EF5D5C /* WASMFunctionCompiler.h in Headers */,
    68736877                                86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
    68746878                                86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
  • trunk/Source/JavaScriptCore/wasm/JSWASMModule.h

    r189123 r189284  
    6666
    6767    Vector<WriteBarrier<JSFunction>>& functions() { return m_functions; }
     68    Vector<unsigned>& functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; }
     69    Vector<unsigned>& functionStackHeights() { return m_functionStackHeights; }
    6870
    6971private:
     
    8486
    8587    Vector<WriteBarrier<JSFunction>> m_functions;
     88    Vector<unsigned> m_functionStartOffsetsInSource;
     89    Vector<unsigned> m_functionStackHeights;
    8690};
    8791
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp

    r189123 r189284  
    2929#if ENABLE(WEBASSEMBLY)
    3030
    31 #include "CCallHelpers.h"
    3231#include "JSWASMModule.h"
    33 #include "LinkBuffer.h"
     32#include "WASMFunctionCompiler.h"
    3433#include "WASMFunctionSyntaxChecker.h"
    3534
     
    4847namespace JSC {
    4948
    50 bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, String& errorMessage)
     49bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage)
    5150{
    5251    WASMFunctionParser parser(module, source, functionIndex);
     
    5958    }
    6059    endOffsetInSource = parser.m_reader.offset();
     60    stackHeight = syntaxChecker.stackHeight();
    6161    return true;
    6262}
    6363
    64 void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode&, size_t functionIndex)
    65 {
    66     // FIXME: Actually compile the code.
    67     CCallHelpers jit(&vm, codeBlock);
    68     MacroAssembler::Label beginLabel = jit.label();
    69     jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), GPRInfo::returnValueGPR);
    70     jit.ret();
    71     MacroAssembler::Label arityCheck = jit.label();
    72     jit.jump(beginLabel);
    73 
    74     LinkBuffer patchBuffer(vm, jit, codeBlock, JITCompilationMustSucceed);
    75     MacroAssemblerCodePtr withArityCheck = patchBuffer.locationOf(arityCheck);
    76     MacroAssembler::CodeRef result = FINALIZE_CODE(patchBuffer, ("Baseline JIT code for WebAssembly"));
    77     codeBlock->setJITCode(adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
    78     codeBlock->capabilityLevel();
    79 
    80     uint32_t signatureIndex = module->functionDeclarations()[functionIndex].signatureIndex;
    81     const WASMSignature& signature = module->signatures()[signatureIndex];
    82     codeBlock->setNumParameters(1 + signature.arguments.size());
     64void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode& source, size_t functionIndex)
     65{
     66    WASMFunctionParser parser(module, source, functionIndex);
     67    WASMFunctionCompiler compiler(vm, codeBlock, module->functionStackHeights()[functionIndex]);
     68    parser.m_reader.setOffset(module->functionStartOffsetsInSource()[functionIndex]);
     69    parser.parseFunction(compiler);
     70    ASSERT(parser.m_errorMessage.isNull());
    8371}
    8472
     
    10391        m_localTypes.append(WASMType::F64);
    10492
     93    context.startFunction(arguments, m_numberOfI32LocalVariables, m_numberOfF32LocalVariables, m_numberOfF64LocalVariables);
     94
    10595    parseBlockStatement(context);
     96    PROPAGATE_ERROR();
     97
     98    context.endFunction();
    10699    return true;
    107100}
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h

    r189123 r189284  
    4343class WASMFunctionParser {
    4444public:
    45     static bool checkSyntax(JSWASMModule*, const SourceCode&, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, String& errorMessage);
     45    static bool checkSyntax(JSWASMModule*, const SourceCode&, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage);
    4646    static void compile(VM&, CodeBlock*, JSWASMModule*, const SourceCode&, size_t functionIndex);
    4747
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h

    r188778 r189284  
    3535    typedef int Expression;
    3636    typedef int Statement;
     37
     38    void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
     39    {
     40        // FIXME: Need to include the number of temporaries used.
     41        m_stackHeight = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
     42    }
     43
     44    void endFunction() { }
     45
     46    unsigned stackHeight() { return m_stackHeight; }
     47
     48private:
     49    unsigned m_stackHeight;
    3750};
    3851
  • trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp

    r189123 r189284  
    221221    m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
    222222    m_module->functions().reserveInitialCapacity(numberOfFunctionDeclarations);
     223    m_module->functionStartOffsetsInSource().reserveInitialCapacity(numberOfFunctionDeclarations);
     224    m_module->functionStackHeights().reserveInitialCapacity(numberOfFunctionDeclarations);
    223225    for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
    224226        WASMFunctionDeclaration functionDeclaration;
     
    263265    unsigned startOffsetInSource = m_reader.offset();
    264266    unsigned endOffsetInSource;
     267    unsigned stackHeight;
    265268    String errorMessage;
    266     if (!WASMFunctionParser::checkSyntax(m_module.get(), m_source, functionIndex, startOffsetInSource, endOffsetInSource, errorMessage)) {
     269    if (!WASMFunctionParser::checkSyntax(m_module.get(), m_source, functionIndex, startOffsetInSource, endOffsetInSource, stackHeight, errorMessage)) {
    267270        m_errorMessage = errorMessage;
    268271        return;
     
    273276    JSFunction* function = JSFunction::create(m_vm, webAssemblyExecutable, m_globalObject.get());
    274277    m_module->functions().uncheckedAppend(WriteBarrier<JSFunction>(m_vm, m_module.get(), function));
     278    m_module->functionStartOffsetsInSource().uncheckedAppend(startOffsetInSource);
     279    m_module->functionStackHeights().uncheckedAppend(stackHeight);
    275280}
    276281
Note: See TracChangeset for help on using the changeset viewer.