Changeset 188099 in webkit


Ignore:
Timestamp:
Aug 6, 2015 5:21:45 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Parse the entire WebAssembly modules
https://bugs.webkit.org/show_bug.cgi?id=147393

Patch by Sukolsak Sakshuwong <Sukolsak Sakshuwong> on 2015-08-06
Reviewed by Geoffrey Garen.

Parse the entire WebAssembly modules from files produced by pack-asmjs
<https://github.com/WebAssembly/polyfill-prototype-1>. This patch can only
parse modules whose function definition section contains only functions that
have "return 0;" as their only statement. Parsing of any functions will be
implemented in a subsequent patch.

(JSC::JSWASMModule::destroy):

  • wasm/JSWASMModule.h:

(JSC::JSWASMModule::i32Constants):
(JSC::JSWASMModule::f32Constants):
(JSC::JSWASMModule::f64Constants):
(JSC::JSWASMModule::signatures):
(JSC::JSWASMModule::functionImports):
(JSC::JSWASMModule::functionImportSignatures):
(JSC::JSWASMModule::globalVariableTypes):
(JSC::JSWASMModule::functionDeclarations):
(JSC::JSWASMModule::functionPointerTables):

  • wasm/WASMFormat.h: Added.
  • wasm/WASMModuleParser.cpp:

(JSC::WASMModuleParser::parse):
(JSC::WASMModuleParser::parseModule):
(JSC::WASMModuleParser::parseConstantPoolSection):
(JSC::WASMModuleParser::parseSignatureSection):
(JSC::WASMModuleParser::parseFunctionImportSection):
(JSC::WASMModuleParser::parseGlobalSection):
(JSC::WASMModuleParser::parseFunctionDeclarationSection):
(JSC::WASMModuleParser::parseFunctionPointerTableSection):
(JSC::WASMModuleParser::parseFunctionDefinitionSection):
(JSC::WASMModuleParser::parseFunctionDefinition):
(JSC::WASMModuleParser::parseExportSection):

  • wasm/WASMModuleParser.h:
  • wasm/WASMReader.cpp:

(JSC::WASMReader::readUInt32):
(JSC::WASMReader::readCompactUInt32):
(JSC::WASMReader::readString):
(JSC::WASMReader::readType):
(JSC::WASMReader::readExpressionType):
(JSC::WASMReader::readExportFormat):
(JSC::WASMReader::readByte):
(JSC::WASMReader::readUnsignedInt32): Deleted.

  • wasm/WASMReader.h:
Location:
trunk/Source/JavaScriptCore
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r188086 r188099  
     12015-08-06  Sukolsak Sakshuwong  <sukolsak@gmail.com>
     2
     3        Parse the entire WebAssembly modules
     4        https://bugs.webkit.org/show_bug.cgi?id=147393
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Parse the entire WebAssembly modules from files produced by pack-asmjs
     9        <https://github.com/WebAssembly/polyfill-prototype-1>. This patch can only
     10        parse modules whose function definition section contains only functions that
     11        have "return 0;" as their only statement. Parsing of any functions will be
     12        implemented in a subsequent patch.
     13
     14        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     15        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     16        * JavaScriptCore.xcodeproj/project.pbxproj:
     17        * wasm/JSWASMModule.cpp:
     18        (JSC::JSWASMModule::destroy):
     19        * wasm/JSWASMModule.h:
     20        (JSC::JSWASMModule::i32Constants):
     21        (JSC::JSWASMModule::f32Constants):
     22        (JSC::JSWASMModule::f64Constants):
     23        (JSC::JSWASMModule::signatures):
     24        (JSC::JSWASMModule::functionImports):
     25        (JSC::JSWASMModule::functionImportSignatures):
     26        (JSC::JSWASMModule::globalVariableTypes):
     27        (JSC::JSWASMModule::functionDeclarations):
     28        (JSC::JSWASMModule::functionPointerTables):
     29        * wasm/WASMFormat.h: Added.
     30        * wasm/WASMModuleParser.cpp:
     31        (JSC::WASMModuleParser::parse):
     32        (JSC::WASMModuleParser::parseModule):
     33        (JSC::WASMModuleParser::parseConstantPoolSection):
     34        (JSC::WASMModuleParser::parseSignatureSection):
     35        (JSC::WASMModuleParser::parseFunctionImportSection):
     36        (JSC::WASMModuleParser::parseGlobalSection):
     37        (JSC::WASMModuleParser::parseFunctionDeclarationSection):
     38        (JSC::WASMModuleParser::parseFunctionPointerTableSection):
     39        (JSC::WASMModuleParser::parseFunctionDefinitionSection):
     40        (JSC::WASMModuleParser::parseFunctionDefinition):
     41        (JSC::WASMModuleParser::parseExportSection):
     42        * wasm/WASMModuleParser.h:
     43        * wasm/WASMReader.cpp:
     44        (JSC::WASMReader::readUInt32):
     45        (JSC::WASMReader::readCompactUInt32):
     46        (JSC::WASMReader::readString):
     47        (JSC::WASMReader::readType):
     48        (JSC::WASMReader::readExpressionType):
     49        (JSC::WASMReader::readExportFormat):
     50        (JSC::WASMReader::readByte):
     51        (JSC::WASMReader::readUnsignedInt32): Deleted.
     52        * wasm/WASMReader.h:
     53
    1542015-08-06  Keith Miller  <keith_miller@apple.com>
    255
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r187969 r188099  
    17591759    <ClInclude Include="..\tools\TieredMMapArray.h" />
    17601760    <ClInclude Include="..\wasm\JSWASMModule.h" />
     1761    <ClInclude Include="..\wasm\WASMFormat.h" />
    17611762    <ClInclude Include="..\wasm\WASMMagicNumber.h" />
    17621763    <ClInclude Include="..\wasm\WASMModuleParser.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r187969 r188099  
    43494349      <Filter>wasm</Filter>
    43504350    </ClInclude>
     4351    <ClInclude Include="..\wasm\WASMFormat.h">
     4352      <Filter>wasm</Filter>
     4353    </ClInclude>
    43514354    <ClInclude Include="..\wasm\WASMMagicNumber.h">
    43524355      <Filter>wasm</Filter>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r187969 r188099  
    10351035                7B98D1361B60CD5F0023B1A4 /* JSWASMModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */; };
    10361036                7B98D1371B60CD620023B1A4 /* JSWASMModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1037                7BC547D31B6959A100959B58 /* WASMFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC547D21B69599B00959B58 /* WASMFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10371038                7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
    10381039                7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    28162817                7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWASMModule.cpp; sourceTree = "<group>"; };
    28172818                7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWASMModule.h; sourceTree = "<group>"; };
     2819                7BC547D21B69599B00959B58 /* WASMFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFormat.h; sourceTree = "<group>"; };
    28182820                7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
    28192821                7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = "<group>"; };
     
    43804382                                7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
    43814383                                7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
     4384                                7BC547D21B69599B00959B58 /* WASMFormat.h */,
    43824385                                7B7A5E261B6828840027CAD0 /* WASMMagicNumber.h */,
    43834386                                7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */,
     
    66836686                                BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
    66846687                                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
     6688                                7BC547D31B6959A100959B58 /* WASMFormat.h in Headers */,
    66856689                                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
    66866690                                0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
  • trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp

    r187254 r188099  
    3636const ClassInfo JSWASMModule::s_info = { "WASMModule", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWASMModule) };
    3737
     38void JSWASMModule::destroy(JSCell* cell)
     39{
     40    JSWASMModule* thisObject = jsCast<JSWASMModule*>(cell);
     41    thisObject->JSWASMModule::~JSWASMModule();
     42}
     43
    3844void JSWASMModule::visitChildren(JSCell* cell, SlotVisitor& visitor)
    3945{
  • trunk/Source/JavaScriptCore/wasm/JSWASMModule.h

    r187283 r188099  
    3030
    3131#include "JSDestructibleObject.h"
     32#include "WASMFormat.h"
    3233
    3334namespace JSC {
     
    5152    }
    5253
     54    static void destroy(JSCell*);
    5355    static void visitChildren(JSCell*, SlotVisitor&);
     56
     57    Vector<uint32_t>& i32Constants() { return m_i32Constants; }
     58    Vector<float>& f32Constants() { return m_f32Constants; }
     59    Vector<double>& f64Constants() { return m_f64Constants; }
     60    Vector<WASMSignature>& signatures() { return m_signatures; }
     61    Vector<WASMFunctionImport>& functionImports() { return m_functionImports; }
     62    Vector<WASMFunctionImportSignature>& functionImportSignatures() { return m_functionImportSignatures; }
     63    Vector<WASMType>& globalVariableTypes() { return m_globalVariableTypes; }
     64    Vector<WASMFunctionDeclaration>& functionDeclarations() { return m_functionDeclarations; }
     65    Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; }
    5466
    5567private:
     
    5870    {
    5971    }
     72
     73    Vector<uint32_t> m_i32Constants;
     74    Vector<float> m_f32Constants;
     75    Vector<double> m_f64Constants;
     76    Vector<WASMSignature> m_signatures;
     77    Vector<WASMFunctionImport> m_functionImports;
     78    Vector<WASMFunctionImportSignature> m_functionImportSignatures;
     79    Vector<WASMType> m_globalVariableTypes;
     80    Vector<WASMFunctionDeclaration> m_functionDeclarations;
     81    Vector<WASMFunctionPointerTable> m_functionPointerTables;
    6082
    6183    Vector<WriteBarrier<JSFunction>> m_functions;
  • trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp

    r187677 r188099  
    3131#include "JSCInlines.h"
    3232#include "JSWASMModule.h"
     33#include "StrongInlines.h"
    3334#include "WASMMagicNumber.h"
    34 
    35 #define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return false; } while (0)
    36 #define READ_UNSIGNED_INT32_OR_FAIL(x, errorMessage) do { if (!m_reader.readUnsignedInt32(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    37 #define READ_FLOAT_OR_FAIL(x, errorMessage) do { if (!m_reader.readFloat(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    38 #define READ_DOUBLE_OR_FAIL(x, errorMessage) do { if (!m_reader.readDouble(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     35#include <wtf/MathExtras.h>
     36
     37#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return; } while (0)
     38#define READ_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     39#define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     40#define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     41#define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     42#define READ_STRING_OR_FAIL(result, errorMessage) do { if (!m_reader.readString(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     43#define READ_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     44#define READ_EXPRESSION_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readExpressionType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     45#define READ_EXPORT_FORMAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readExportFormat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
    3946#define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
     47#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return; } while (0)
    4048
    4149namespace JSC {
     
    4856JSWASMModule* WASMModuleParser::parse(VM& vm, JSGlobalObject* globalObject, String& errorMessage)
    4957{
    50     JSWASMModule* module = JSWASMModule::create(vm, globalObject->wasmModuleStructure());
     58    m_module.set(vm, JSWASMModule::create(vm, globalObject->wasmModuleStructure()));
    5159    parseModule();
    5260    if (!m_errorMessage.isNull()) {
     
    5462        return nullptr;
    5563    }
    56     return module;
    57 }
    58 
    59 bool WASMModuleParser::parseModule()
     64    return m_module.get();
     65}
     66
     67void WASMModuleParser::parseModule()
    6068{
    6169    uint32_t magicNumber;
    62     READ_UNSIGNED_INT32_OR_FAIL(magicNumber, "Cannot read the magic number.");
     70    READ_UINT32_OR_FAIL(magicNumber, "Cannot read the magic number.");
    6371    FAIL_IF_FALSE(magicNumber == wasmMagicNumber, "The magic number is incorrect.");
    6472
    65     // TODO: parse the rest
    66 
    67     return true;
     73    uint32_t outputSizeInASMJS;
     74    READ_UINT32_OR_FAIL(outputSizeInASMJS, "Cannot read the output size in asm.js format.");
     75
     76    parseConstantPoolSection();
     77    PROPAGATE_ERROR();
     78    parseSignatureSection();
     79    PROPAGATE_ERROR();
     80    parseFunctionImportSection();
     81    PROPAGATE_ERROR();
     82    parseGlobalSection();
     83    PROPAGATE_ERROR();
     84    parseFunctionDeclarationSection();
     85    PROPAGATE_ERROR();
     86    parseFunctionPointerTableSection();
     87    PROPAGATE_ERROR();
     88    parseFunctionDefinitionSection();
     89    PROPAGATE_ERROR();
     90    parseExportSection();
     91}
     92
     93void WASMModuleParser::parseConstantPoolSection()
     94{
     95    uint32_t numberOfI32Constants;
     96    uint32_t numberOfF32Constants;
     97    uint32_t numberOfF64Constants;
     98    READ_COMPACT_UINT32_OR_FAIL(numberOfI32Constants, "Cannot read the number of int32 constants.");
     99    READ_COMPACT_UINT32_OR_FAIL(numberOfF32Constants, "Cannot read the number of float32 constants.");
     100    READ_COMPACT_UINT32_OR_FAIL(numberOfF64Constants, "Cannot read the number of float64 constants.");
     101    m_module->i32Constants().reserveInitialCapacity(numberOfI32Constants);
     102    m_module->f32Constants().reserveInitialCapacity(numberOfF32Constants);
     103    m_module->f64Constants().reserveInitialCapacity(numberOfF64Constants);
     104
     105    for (uint32_t i = 0; i < numberOfI32Constants; ++i) {
     106        uint32_t constant;
     107        READ_COMPACT_UINT32_OR_FAIL(constant, "Cannot read an int32 constant.");
     108        m_module->i32Constants().uncheckedAppend(constant);
     109    }
     110    for (uint32_t i = 0; i < numberOfF32Constants; ++i) {
     111        float constant;
     112        READ_FLOAT_OR_FAIL(constant, "Cannot read a float32 constant.");
     113        m_module->f32Constants().uncheckedAppend(constant);
     114    }
     115    for (uint32_t i = 0; i < numberOfF64Constants; ++i) {
     116        double constant;
     117        READ_DOUBLE_OR_FAIL(constant, "Cannot read a float64 constant.");
     118        m_module->f64Constants().uncheckedAppend(constant);
     119    }
     120}
     121
     122void WASMModuleParser::parseSignatureSection()
     123{
     124    uint32_t numberOfSignatures;
     125    READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
     126    m_module->signatures().reserveInitialCapacity(numberOfSignatures);
     127    for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
     128        WASMSignature signature;
     129        READ_EXPRESSION_TYPE_OR_FAIL(signature.returnType, "Cannot read the return type.");
     130        uint32_t argumentCount;
     131        READ_COMPACT_UINT32_OR_FAIL(argumentCount, "Cannot read the number of arguments.");
     132        signature.arguments.reserveInitialCapacity(argumentCount);
     133        for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
     134            WASMType type;
     135            READ_TYPE_OR_FAIL(type, "Cannot read the type of an argument.");
     136            signature.arguments.uncheckedAppend(type);
     137        }
     138        m_module->signatures().uncheckedAppend(signature);
     139    }
     140}
     141
     142void WASMModuleParser::parseFunctionImportSection()
     143{
     144    uint32_t numberOfFunctionImports;
     145    uint32_t numberOfFunctionImportSignatures;
     146    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImports, "Cannot read the number of function imports.");
     147    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, "Cannot read the number of function import signatures.");
     148    m_module->functionImports().reserveInitialCapacity(numberOfFunctionImports);
     149    m_module->functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);
     150
     151    for (uint32_t functionImportIndex = 0; functionImportIndex < numberOfFunctionImports; ++functionImportIndex) {
     152        WASMFunctionImport functionImport;
     153        READ_STRING_OR_FAIL(functionImport.functionName, "Cannot read the function import name.");
     154        m_module->functionImports().uncheckedAppend(functionImport);
     155
     156        uint32_t numberOfSignatures;
     157        READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
     158        FAIL_IF_FALSE(numberOfSignatures <= numberOfFunctionImportSignatures - m_module->functionImportSignatures().size(), "The number of signatures is incorrect.");
     159
     160        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
     161            WASMFunctionImportSignature functionImportSignature;
     162            READ_COMPACT_UINT32_OR_FAIL(functionImportSignature.signatureIndex, "Cannot read the signature index.");
     163            FAIL_IF_FALSE(functionImportSignature.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
     164            functionImportSignature.functionImportIndex = functionImportIndex;
     165            m_module->functionImportSignatures().uncheckedAppend(functionImportSignature);
     166        }
     167    }
     168    FAIL_IF_FALSE(m_module->functionImportSignatures().size() == numberOfFunctionImportSignatures, "The number of function import signatures is incorrect.");
     169}
     170
     171void WASMModuleParser::parseGlobalSection()
     172{
     173    uint32_t numberOfInternalI32GlobalVariables;
     174    uint32_t numberOfInternalF32GlobalVariables;
     175    uint32_t numberOfInternalF64GlobalVariables;
     176    uint32_t numberOfImportedI32GlobalVariables;
     177    uint32_t numberOfImportedF32GlobalVariables;
     178    uint32_t numberOfImportedF64GlobalVariables;
     179    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalI32GlobalVariables, "Cannot read the number of internal int32 global variables.");
     180    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF32GlobalVariables, "Cannot read the number of internal float32 global variables.");
     181    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF64GlobalVariables, "Cannot read the number of internal float64 global variables.");
     182    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedI32GlobalVariables, "Cannot read the number of imported int32 global variables.");
     183    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF32GlobalVariables, "Cannot read the number of imported float32 global variables.");
     184    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF64GlobalVariables, "Cannot read the number of imported float64 global variables.");
     185    uint32_t numberOfGlobalVariables = numberOfInternalI32GlobalVariables + numberOfInternalF32GlobalVariables + numberOfInternalF64GlobalVariables +
     186        numberOfImportedI32GlobalVariables + numberOfImportedF32GlobalVariables + numberOfImportedF64GlobalVariables;
     187
     188    Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
     189    globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
     190    for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i)
     191        globalVariableTypes.uncheckedAppend(WASMType::I32);
     192    for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i)
     193        globalVariableTypes.uncheckedAppend(WASMType::F32);
     194    for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i)
     195        globalVariableTypes.uncheckedAppend(WASMType::F64);
     196    for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
     197        String importName;
     198        READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
     199        globalVariableTypes.uncheckedAppend(WASMType::I32);
     200    }
     201    for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
     202        String importName;
     203        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
     204        globalVariableTypes.uncheckedAppend(WASMType::F32);
     205    }
     206    for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
     207        String importName;
     208        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
     209        globalVariableTypes.uncheckedAppend(WASMType::F64);
     210    }
     211}
     212
     213void WASMModuleParser::parseFunctionDeclarationSection()
     214{
     215    uint32_t numberOfFunctionDeclarations;
     216    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, "Cannot read the number of function declarations.");
     217    m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
     218    for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
     219        WASMFunctionDeclaration functionDeclaration;
     220        READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, "Cannot read the signature index.");
     221        FAIL_IF_FALSE(functionDeclaration.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
     222        m_module->functionDeclarations().uncheckedAppend(functionDeclaration);
     223    }
     224}
     225
     226void WASMModuleParser::parseFunctionPointerTableSection()
     227{
     228    uint32_t numberOfFunctionPointerTables;
     229    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionPointerTables, "Cannot read the number of function pointer tables.");
     230    m_module->functionPointerTables().reserveInitialCapacity(numberOfFunctionPointerTables);
     231    for (uint32_t i = 0; i < numberOfFunctionPointerTables; ++i) {
     232        WASMFunctionPointerTable functionPointerTable;
     233        READ_COMPACT_UINT32_OR_FAIL(functionPointerTable.signatureIndex, "Cannot read the signature index.");
     234        FAIL_IF_FALSE(functionPointerTable.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
     235        uint32_t numberOfElements;
     236        READ_COMPACT_UINT32_OR_FAIL(numberOfElements, "Cannot read the number of elements of a function pointer table.");
     237        FAIL_IF_FALSE(hasOneBitSet(numberOfElements), "The number of elements must be a power of two.");
     238        functionPointerTable.elements.reserveInitialCapacity(numberOfElements);
     239        for (uint32_t j = 0; j < numberOfElements; ++j) {
     240            uint32_t element;
     241            READ_COMPACT_UINT32_OR_FAIL(element, "Cannot read an element of a function pointer table.");
     242            functionPointerTable.elements.uncheckedAppend(element);
     243        }
     244        m_module->functionPointerTables().uncheckedAppend(functionPointerTable);
     245    }
     246}
     247
     248void WASMModuleParser::parseFunctionDefinitionSection()
     249{
     250    for (size_t i = 0; i < m_module->functionDeclarations().size(); ++i) {
     251        parseFunctionDefinition();
     252        PROPAGATE_ERROR();
     253    }
     254}
     255
     256void WASMModuleParser::parseFunctionDefinition()
     257{
     258    // FIXME: Support any functions. https://bugs.webkit.org/show_bug.cgi?id=147738
     259    // Currently, we only support functions that have "return 0;" as their only statement.
     260    // These functions consist of exactly 4 bytes, i.e.
     261    // 1. The number of local variables (0) [0x80]
     262    // 2. The number of statements (1) [0x01]
     263    // 3. The return statement [0x0f]
     264    // 4. The immediate expression (0) [0xa0]
     265    uint32_t functionDefinitionBytes;
     266    READ_UINT32_OR_FAIL(functionDefinitionBytes, "Cannot read the function definition.");
     267    FAIL_IF_FALSE(functionDefinitionBytes == 0xa00f0180, "Only functions that have \"return 0;\" "
     268        "as their only statement are supported at the moment.");
     269}
     270
     271void WASMModuleParser::parseExportSection()
     272{
     273    WASMExportFormat exportFormat;
     274    READ_EXPORT_FORMAT_OR_FAIL(exportFormat, "Cannot read the export format.");
     275    switch (exportFormat) {
     276    case WASMExportFormat::Default: {
     277        uint32_t functionIndex;
     278        READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
     279        FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
     280        // FIXME: Export the function.
     281        break;
     282    }
     283    case WASMExportFormat::Record: {
     284        uint32_t numberOfExports;
     285        READ_COMPACT_UINT32_OR_FAIL(numberOfExports, "Cannot read the number of exports.");
     286        for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
     287            String exportName;
     288            READ_STRING_OR_FAIL(exportName, "Cannot read the function export name.");
     289            // FIXME: Check that exportName is legal.
     290            uint32_t functionIndex;
     291            READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
     292            FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
     293            // FIXME: Export the function.
     294        }
     295        break;
     296    }
     297    default:
     298        ASSERT_NOT_REACHED();
     299    }
    68300}
    69301
  • trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h

    r187677 r188099  
    2929#if ENABLE(WEBASSEMBLY)
    3030
     31#include "Strong.h"
    3132#include "WASMReader.h"
    3233#include <wtf/text/WTFString.h>
     
    4647
    4748private:
    48     bool parseModule();
     49    void parseModule();
     50    void parseConstantPoolSection();
     51    void parseSignatureSection();
     52    void parseFunctionImportSection();
     53    void parseGlobalSection();
     54    void parseFunctionDeclarationSection();
     55    void parseFunctionPointerTableSection();
     56    void parseFunctionDefinitionSection();
     57    void parseFunctionDefinition();
     58    void parseExportSection();
    4959
    5060    WASMReader m_reader;
     61    Strong<JSWASMModule> m_module;
    5162    String m_errorMessage;
    5263};
  • trunk/Source/JavaScriptCore/wasm/WASMReader.cpp

    r187677 r188099  
    2929#if ENABLE(WEBASSEMBLY)
    3030
     31#include <wtf/text/StringBuilder.h>
     32
    3133#define CHECK_READ(length) do { if (m_cursor + length > m_buffer.end()) return false; } while (0)
    3234
    3335namespace JSC {
    3436
    35 bool WASMReader::readUnsignedInt32(uint32_t& result)
     37bool WASMReader::readUInt32(uint32_t& result)
    3638{
    3739    CHECK_READ(4);
     
    7779}
    7880
     81bool WASMReader::readCompactUInt32(uint32_t& result)
     82{
     83    uint32_t sum = 0;
     84    unsigned shift = 0;
     85    do {
     86        CHECK_READ(1);
     87        uint32_t byte = *m_cursor++;
     88        if (byte < 0x80) {
     89            if ((shift == 28 && byte >= 0x10) || (shift && !byte))
     90                return false;
     91            result = sum | (byte << shift);
     92            return true;
     93        }
     94        sum |= (byte & firstSevenBitsMask) << shift;
     95        shift += 7;
     96    } while (shift < 35);
     97    return false;
     98}
     99
     100bool WASMReader::readString(String& result)
     101{
     102    StringBuilder builder;
     103    while (true) {
     104        CHECK_READ(1);
     105        char c = *m_cursor++;
     106        if (!c)
     107            break;
     108        builder.append(c);
     109    }
     110    result = builder.toString();
     111    return true;
     112}
     113
     114bool WASMReader::readType(WASMType& result)
     115{
     116    return readByte<WASMType>(result, (uint8_t)WASMType::NumberOfTypes);
     117}
     118
     119bool WASMReader::readExpressionType(WASMExpressionType& result)
     120{
     121    return readByte<WASMExpressionType>(result, (uint8_t)WASMExpressionType::NumberOfExpressionTypes);
     122}
     123
     124bool WASMReader::readExportFormat(WASMExportFormat& result)
     125{
     126    return readByte<WASMExportFormat>(result, (uint8_t)WASMExportFormat::NumberOfExportFormats);
     127}
     128
     129template <class T> bool WASMReader::readByte(T& result, uint8_t numberOfValues)
     130{
     131    CHECK_READ(1);
     132    uint8_t byte = *m_cursor++;
     133    if (byte >= numberOfValues)
     134        return false;
     135    result = T(byte);
     136    return true;
     137}
     138
    79139} // namespace JSC
    80140
  • trunk/Source/JavaScriptCore/wasm/WASMReader.h

    r187677 r188099  
    2929#if ENABLE(WEBASSEMBLY)
    3030
     31#include "WASMFormat.h"
    3132#include <wtf/Vector.h>
    3233
     
    4142    }
    4243
    43     bool readUnsignedInt32(uint32_t& result);
     44    bool readUInt32(uint32_t& result);
    4445    bool readFloat(float& result);
    4546    bool readDouble(double& result);
     47    bool readCompactUInt32(uint32_t& result);
     48    bool readString(String& result);
     49    bool readType(WASMType& result);
     50    bool readExpressionType(WASMExpressionType& result);
     51    bool readExportFormat(WASMExportFormat& result);
    4652
    4753private:
     54    static const uint32_t firstSevenBitsMask = 0x7f;
     55
     56    template <class T> bool readByte(T& result, uint8_t numberOfValues);
     57
    4858    const Vector<uint8_t>& m_buffer;
    4959    const uint8_t* m_cursor;
Note: See TracChangeset for help on using the changeset viewer.