Title: [188099] trunk/Source/_javascript_Core
Revision
188099
Author
commit-qu...@webkit.org
Date
2015-08-06 17:21:45 -0700 (Thu, 06 Aug 2015)

Log Message

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

Patch by Sukolsak Sakshuwong <sukol...@gmail.com> 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.

* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
* _javascript_Core.xcodeproj/project.pbxproj:
* wasm/JSWASMModule.cpp:
(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:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (188098 => 188099)


--- trunk/Source/_javascript_Core/ChangeLog	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-08-07 00:21:45 UTC (rev 188099)
@@ -1,3 +1,56 @@
+2015-08-06  Sukolsak Sakshuwong  <sukol...@gmail.com>
+
+        Parse the entire WebAssembly modules
+        https://bugs.webkit.org/show_bug.cgi?id=147393
+
+        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.
+
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * wasm/JSWASMModule.cpp:
+        (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:
+
 2015-08-06  Keith Miller  <keith_mil...@apple.com>
 
         The typedArrayLength function in FTLLowerDFGToLLVM is dead code.

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (188098 => 188099)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-08-07 00:21:45 UTC (rev 188099)
@@ -1758,6 +1758,7 @@
     <ClInclude Include="..\tools\ProfileTreeNode.h" />
     <ClInclude Include="..\tools\TieredMMapArray.h" />
     <ClInclude Include="..\wasm\JSWASMModule.h" />
+    <ClInclude Include="..\wasm\WASMFormat.h" />
     <ClInclude Include="..\wasm\WASMMagicNumber.h" />
     <ClInclude Include="..\wasm\WASMModuleParser.h" />
     <ClInclude Include="..\wasm\WASMReader.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (188098 => 188099)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters	2015-08-07 00:21:45 UTC (rev 188099)
@@ -4348,6 +4348,9 @@
     <ClInclude Include="..\wasm\JSWASMModule.h">
       <Filter>wasm</Filter>
     </ClInclude>
+    <ClInclude Include="..\wasm\WASMFormat.h">
+      <Filter>wasm</Filter>
+    </ClInclude>
     <ClInclude Include="..\wasm\WASMMagicNumber.h">
       <Filter>wasm</Filter>
     </ClInclude>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (188098 => 188099)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-08-07 00:21:45 UTC (rev 188099)
@@ -1034,6 +1034,7 @@
 		7B7A5E271B68288C0027CAD0 /* WASMMagicNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7A5E261B6828840027CAD0 /* WASMMagicNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7B98D1361B60CD5F0023B1A4 /* JSWASMModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */; };
 		7B98D1371B60CD620023B1A4 /* JSWASMModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		7BC547D31B6959A100959B58 /* WASMFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC547D21B69599B00959B58 /* WASMFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
 		7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C008CE7187631B600955C24 /* Microtask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CE5187631B600955C24 /* Microtask.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2815,6 +2816,7 @@
 		7B7A5E261B6828840027CAD0 /* WASMMagicNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMMagicNumber.h; sourceTree = "<group>"; };
 		7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWASMModule.cpp; sourceTree = "<group>"; };
 		7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWASMModule.h; sourceTree = "<group>"; };
+		7BC547D21B69599B00959B58 /* WASMFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFormat.h; sourceTree = "<group>"; };
 		7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
 		7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = "<group>"; };
 		7C008CE5187631B600955C24 /* Microtask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Microtask.h; sourceTree = "<group>"; };
@@ -4379,6 +4381,7 @@
 			children = (
 				7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
 				7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
+				7BC547D21B69599B00959B58 /* WASMFormat.h */,
 				7B7A5E261B6828840027CAD0 /* WASMMagicNumber.h */,
 				7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */,
 				7B39F76A1B62DE2200360FB4 /* WASMModuleParser.h */,
@@ -6682,6 +6685,7 @@
 				0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
 				BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
 				FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
+				7BC547D31B6959A100959B58 /* WASMFormat.h in Headers */,
 				FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
 				0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
 				142E313C134FF0A600AFADB5 /* Weak.h in Headers */,

Modified: trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp	2015-08-07 00:21:45 UTC (rev 188099)
@@ -35,6 +35,12 @@
 
 const ClassInfo JSWASMModule::s_info = { "WASMModule", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWASMModule) };
 
+void JSWASMModule::destroy(JSCell* cell)
+{
+    JSWASMModule* thisObject = jsCast<JSWASMModule*>(cell);
+    thisObject->JSWASMModule::~JSWASMModule();
+}
+
 void JSWASMModule::visitChildren(JSCell* cell, SlotVisitor& visitor)
 {
     JSWASMModule* thisObject = jsCast<JSWASMModule*>(cell);

Modified: trunk/Source/_javascript_Core/wasm/JSWASMModule.h (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/JSWASMModule.h	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/JSWASMModule.h	2015-08-07 00:21:45 UTC (rev 188099)
@@ -29,6 +29,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "JSDestructibleObject.h"
+#include "WASMFormat.h"
 
 namespace JSC {
 
@@ -50,14 +51,35 @@
         return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
     }
 
+    static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
 
+    Vector<uint32_t>& i32Constants() { return m_i32Constants; }
+    Vector<float>& f32Constants() { return m_f32Constants; }
+    Vector<double>& f64Constants() { return m_f64Constants; }
+    Vector<WASMSignature>& signatures() { return m_signatures; }
+    Vector<WASMFunctionImport>& functionImports() { return m_functionImports; }
+    Vector<WASMFunctionImportSignature>& functionImportSignatures() { return m_functionImportSignatures; }
+    Vector<WASMType>& globalVariableTypes() { return m_globalVariableTypes; }
+    Vector<WASMFunctionDeclaration>& functionDeclarations() { return m_functionDeclarations; }
+    Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; }
+
 private:
     JSWASMModule(VM& vm, Structure* structure)
         : Base(vm, structure)
     {
     }
 
+    Vector<uint32_t> m_i32Constants;
+    Vector<float> m_f32Constants;
+    Vector<double> m_f64Constants;
+    Vector<WASMSignature> m_signatures;
+    Vector<WASMFunctionImport> m_functionImports;
+    Vector<WASMFunctionImportSignature> m_functionImportSignatures;
+    Vector<WASMType> m_globalVariableTypes;
+    Vector<WASMFunctionDeclaration> m_functionDeclarations;
+    Vector<WASMFunctionPointerTable> m_functionPointerTables;
+
     Vector<WriteBarrier<JSFunction>> m_functions;
 };
 

Added: trunk/Source/_javascript_Core/wasm/WASMFormat.h (0 => 188099)


--- trunk/Source/_javascript_Core/wasm/WASMFormat.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMFormat.h	2015-08-07 00:21:45 UTC (rev 188099)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * =========================================================================
+ *
+ * Copyright (c) 2015 by the repository authors of
+ * WebAssembly/polyfill-prototype-1.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WASMFormat_h
+#define WASMFormat_h
+
+#if ENABLE(WEBASSEMBLY)
+
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+enum class WASMType : uint8_t {
+    I32,
+    F32,
+    F64,
+    NumberOfTypes
+};
+
+enum class WASMExpressionType : uint8_t {
+    I32,
+    F32,
+    F64,
+    Void,
+    NumberOfExpressionTypes
+};
+
+enum class WASMExportFormat : uint8_t {
+    Default,
+    Record,
+    NumberOfExportFormats
+};
+
+struct WASMSignature {
+    WASMExpressionType returnType;
+    Vector<WASMType> arguments;
+};
+
+struct WASMFunctionImport {
+    String functionName;
+};
+
+struct WASMFunctionImportSignature {
+    uint32_t signatureIndex;
+    uint32_t functionImportIndex;
+};
+
+struct WASMFunctionDeclaration {
+    uint32_t signatureIndex;
+};
+
+struct WASMFunctionPointerTable {
+    uint32_t signatureIndex;
+    Vector<uint32_t> elements;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
+
+#endif // WASMFormat_h

Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp	2015-08-07 00:21:45 UTC (rev 188099)
@@ -30,13 +30,21 @@
 
 #include "JSCInlines.h"
 #include "JSWASMModule.h"
+#include "StrongInlines.h"
 #include "WASMMagicNumber.h"
+#include <wtf/MathExtras.h>
 
-#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return false; } while (0)
-#define READ_UNSIGNED_INT32_OR_FAIL(x, errorMessage) do { if (!m_reader.readUnsignedInt32(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_FLOAT_OR_FAIL(x, errorMessage) do { if (!m_reader.readFloat(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_DOUBLE_OR_FAIL(x, errorMessage) do { if (!m_reader.readDouble(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return; } while (0)
+#define READ_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_STRING_OR_FAIL(result, errorMessage) do { if (!m_reader.readString(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_EXPRESSION_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readExpressionType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define READ_EXPORT_FORMAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readExportFormat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
 #define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
+#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return; } while (0)
 
 namespace JSC {
 
@@ -47,26 +55,250 @@
 
 JSWASMModule* WASMModuleParser::parse(VM& vm, JSGlobalObject* globalObject, String& errorMessage)
 {
-    JSWASMModule* module = JSWASMModule::create(vm, globalObject->wasmModuleStructure());
+    m_module.set(vm, JSWASMModule::create(vm, globalObject->wasmModuleStructure()));
     parseModule();
     if (!m_errorMessage.isNull()) {
         errorMessage = m_errorMessage;
         return nullptr;
     }
-    return module;
+    return m_module.get();
 }
 
-bool WASMModuleParser::parseModule()
+void WASMModuleParser::parseModule()
 {
     uint32_t magicNumber;
-    READ_UNSIGNED_INT32_OR_FAIL(magicNumber, "Cannot read the magic number.");
+    READ_UINT32_OR_FAIL(magicNumber, "Cannot read the magic number.");
     FAIL_IF_FALSE(magicNumber == wasmMagicNumber, "The magic number is incorrect.");
 
-    // TODO: parse the rest
+    uint32_t outputSizeInASMJS;
+    READ_UINT32_OR_FAIL(outputSizeInASMJS, "Cannot read the output size in asm.js format.");
 
-    return true;
+    parseConstantPoolSection();
+    PROPAGATE_ERROR();
+    parseSignatureSection();
+    PROPAGATE_ERROR();
+    parseFunctionImportSection();
+    PROPAGATE_ERROR();
+    parseGlobalSection();
+    PROPAGATE_ERROR();
+    parseFunctionDeclarationSection();
+    PROPAGATE_ERROR();
+    parseFunctionPointerTableSection();
+    PROPAGATE_ERROR();
+    parseFunctionDefinitionSection();
+    PROPAGATE_ERROR();
+    parseExportSection();
 }
 
+void WASMModuleParser::parseConstantPoolSection()
+{
+    uint32_t numberOfI32Constants;
+    uint32_t numberOfF32Constants;
+    uint32_t numberOfF64Constants;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfI32Constants, "Cannot read the number of int32 constants.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfF32Constants, "Cannot read the number of float32 constants.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfF64Constants, "Cannot read the number of float64 constants.");
+    m_module->i32Constants().reserveInitialCapacity(numberOfI32Constants);
+    m_module->f32Constants().reserveInitialCapacity(numberOfF32Constants);
+    m_module->f64Constants().reserveInitialCapacity(numberOfF64Constants);
+
+    for (uint32_t i = 0; i < numberOfI32Constants; ++i) {
+        uint32_t constant;
+        READ_COMPACT_UINT32_OR_FAIL(constant, "Cannot read an int32 constant.");
+        m_module->i32Constants().uncheckedAppend(constant);
+    }
+    for (uint32_t i = 0; i < numberOfF32Constants; ++i) {
+        float constant;
+        READ_FLOAT_OR_FAIL(constant, "Cannot read a float32 constant.");
+        m_module->f32Constants().uncheckedAppend(constant);
+    }
+    for (uint32_t i = 0; i < numberOfF64Constants; ++i) {
+        double constant;
+        READ_DOUBLE_OR_FAIL(constant, "Cannot read a float64 constant.");
+        m_module->f64Constants().uncheckedAppend(constant);
+    }
+}
+
+void WASMModuleParser::parseSignatureSection()
+{
+    uint32_t numberOfSignatures;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
+    m_module->signatures().reserveInitialCapacity(numberOfSignatures);
+    for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
+        WASMSignature signature;
+        READ_EXPRESSION_TYPE_OR_FAIL(signature.returnType, "Cannot read the return type.");
+        uint32_t argumentCount;
+        READ_COMPACT_UINT32_OR_FAIL(argumentCount, "Cannot read the number of arguments.");
+        signature.arguments.reserveInitialCapacity(argumentCount);
+        for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
+            WASMType type;
+            READ_TYPE_OR_FAIL(type, "Cannot read the type of an argument.");
+            signature.arguments.uncheckedAppend(type);
+        }
+        m_module->signatures().uncheckedAppend(signature);
+    }
+}
+
+void WASMModuleParser::parseFunctionImportSection()
+{
+    uint32_t numberOfFunctionImports;
+    uint32_t numberOfFunctionImportSignatures;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImports, "Cannot read the number of function imports.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, "Cannot read the number of function import signatures.");
+    m_module->functionImports().reserveInitialCapacity(numberOfFunctionImports);
+    m_module->functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);
+
+    for (uint32_t functionImportIndex = 0; functionImportIndex < numberOfFunctionImports; ++functionImportIndex) {
+        WASMFunctionImport functionImport;
+        READ_STRING_OR_FAIL(functionImport.functionName, "Cannot read the function import name.");
+        m_module->functionImports().uncheckedAppend(functionImport);
+
+        uint32_t numberOfSignatures;
+        READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
+        FAIL_IF_FALSE(numberOfSignatures <= numberOfFunctionImportSignatures - m_module->functionImportSignatures().size(), "The number of signatures is incorrect.");
+
+        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
+            WASMFunctionImportSignature functionImportSignature;
+            READ_COMPACT_UINT32_OR_FAIL(functionImportSignature.signatureIndex, "Cannot read the signature index.");
+            FAIL_IF_FALSE(functionImportSignature.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
+            functionImportSignature.functionImportIndex = functionImportIndex;
+            m_module->functionImportSignatures().uncheckedAppend(functionImportSignature);
+        }
+    }
+    FAIL_IF_FALSE(m_module->functionImportSignatures().size() == numberOfFunctionImportSignatures, "The number of function import signatures is incorrect.");
+}
+
+void WASMModuleParser::parseGlobalSection()
+{
+    uint32_t numberOfInternalI32GlobalVariables;
+    uint32_t numberOfInternalF32GlobalVariables;
+    uint32_t numberOfInternalF64GlobalVariables;
+    uint32_t numberOfImportedI32GlobalVariables;
+    uint32_t numberOfImportedF32GlobalVariables;
+    uint32_t numberOfImportedF64GlobalVariables;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalI32GlobalVariables, "Cannot read the number of internal int32 global variables.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF32GlobalVariables, "Cannot read the number of internal float32 global variables.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF64GlobalVariables, "Cannot read the number of internal float64 global variables.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedI32GlobalVariables, "Cannot read the number of imported int32 global variables.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF32GlobalVariables, "Cannot read the number of imported float32 global variables.");
+    READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF64GlobalVariables, "Cannot read the number of imported float64 global variables.");
+    uint32_t numberOfGlobalVariables = numberOfInternalI32GlobalVariables + numberOfInternalF32GlobalVariables + numberOfInternalF64GlobalVariables +
+        numberOfImportedI32GlobalVariables + numberOfImportedF32GlobalVariables + numberOfImportedF64GlobalVariables;
+
+    Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
+    globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
+    for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i)
+        globalVariableTypes.uncheckedAppend(WASMType::I32);
+    for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i)
+        globalVariableTypes.uncheckedAppend(WASMType::F32);
+    for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i)
+        globalVariableTypes.uncheckedAppend(WASMType::F64);
+    for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
+        String importName;
+        READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
+        globalVariableTypes.uncheckedAppend(WASMType::I32);
+    }
+    for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
+        String importName;
+        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
+        globalVariableTypes.uncheckedAppend(WASMType::F32);
+    }
+    for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
+        String importName;
+        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
+        globalVariableTypes.uncheckedAppend(WASMType::F64);
+    }
+}
+
+void WASMModuleParser::parseFunctionDeclarationSection()
+{
+    uint32_t numberOfFunctionDeclarations;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, "Cannot read the number of function declarations.");
+    m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
+    for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
+        WASMFunctionDeclaration functionDeclaration;
+        READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, "Cannot read the signature index.");
+        FAIL_IF_FALSE(functionDeclaration.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
+        m_module->functionDeclarations().uncheckedAppend(functionDeclaration);
+    }
+}
+
+void WASMModuleParser::parseFunctionPointerTableSection()
+{
+    uint32_t numberOfFunctionPointerTables;
+    READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionPointerTables, "Cannot read the number of function pointer tables.");
+    m_module->functionPointerTables().reserveInitialCapacity(numberOfFunctionPointerTables);
+    for (uint32_t i = 0; i < numberOfFunctionPointerTables; ++i) {
+        WASMFunctionPointerTable functionPointerTable;
+        READ_COMPACT_UINT32_OR_FAIL(functionPointerTable.signatureIndex, "Cannot read the signature index.");
+        FAIL_IF_FALSE(functionPointerTable.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
+        uint32_t numberOfElements;
+        READ_COMPACT_UINT32_OR_FAIL(numberOfElements, "Cannot read the number of elements of a function pointer table.");
+        FAIL_IF_FALSE(hasOneBitSet(numberOfElements), "The number of elements must be a power of two.");
+        functionPointerTable.elements.reserveInitialCapacity(numberOfElements);
+        for (uint32_t j = 0; j < numberOfElements; ++j) {
+            uint32_t element;
+            READ_COMPACT_UINT32_OR_FAIL(element, "Cannot read an element of a function pointer table.");
+            functionPointerTable.elements.uncheckedAppend(element);
+        }
+        m_module->functionPointerTables().uncheckedAppend(functionPointerTable);
+    }
+}
+
+void WASMModuleParser::parseFunctionDefinitionSection()
+{
+    for (size_t i = 0; i < m_module->functionDeclarations().size(); ++i) {
+        parseFunctionDefinition();
+        PROPAGATE_ERROR();
+    }
+}
+
+void WASMModuleParser::parseFunctionDefinition()
+{
+    // FIXME: Support any functions. https://bugs.webkit.org/show_bug.cgi?id=147738
+    // Currently, we only support functions that have "return 0;" as their only statement.
+    // These functions consist of exactly 4 bytes, i.e.
+    // 1. The number of local variables (0) [0x80]
+    // 2. The number of statements (1) [0x01]
+    // 3. The return statement [0x0f]
+    // 4. The immediate _expression_ (0) [0xa0]
+    uint32_t functionDefinitionBytes;
+    READ_UINT32_OR_FAIL(functionDefinitionBytes, "Cannot read the function definition.");
+    FAIL_IF_FALSE(functionDefinitionBytes == 0xa00f0180, "Only functions that have \"return 0;\" "
+        "as their only statement are supported at the moment.");
+}
+
+void WASMModuleParser::parseExportSection()
+{
+    WASMExportFormat exportFormat;
+    READ_EXPORT_FORMAT_OR_FAIL(exportFormat, "Cannot read the export format.");
+    switch (exportFormat) {
+    case WASMExportFormat::Default: {
+        uint32_t functionIndex;
+        READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
+        FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
+        // FIXME: Export the function.
+        break;
+    }
+    case WASMExportFormat::Record: {
+        uint32_t numberOfExports;
+        READ_COMPACT_UINT32_OR_FAIL(numberOfExports, "Cannot read the number of exports.");
+        for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
+            String exportName;
+            READ_STRING_OR_FAIL(exportName, "Cannot read the function export name.");
+            // FIXME: Check that exportName is legal.
+            uint32_t functionIndex;
+            READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
+            FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
+            // FIXME: Export the function.
+        }
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
 JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, String& errorMessage)
 {
     WASMModuleParser WASMModuleParser(source);

Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.h	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.h	2015-08-07 00:21:45 UTC (rev 188099)
@@ -28,6 +28,7 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "Strong.h"
 #include "WASMReader.h"
 #include <wtf/text/WTFString.h>
 
@@ -45,9 +46,19 @@
     JSWASMModule* parse(VM&, JSGlobalObject*, String& errorMessage);
 
 private:
-    bool parseModule();
+    void parseModule();
+    void parseConstantPoolSection();
+    void parseSignatureSection();
+    void parseFunctionImportSection();
+    void parseGlobalSection();
+    void parseFunctionDeclarationSection();
+    void parseFunctionPointerTableSection();
+    void parseFunctionDefinitionSection();
+    void parseFunctionDefinition();
+    void parseExportSection();
 
     WASMReader m_reader;
+    Strong<JSWASMModule> m_module;
     String m_errorMessage;
 };
 

Modified: trunk/Source/_javascript_Core/wasm/WASMReader.cpp (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/WASMReader.cpp	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/WASMReader.cpp	2015-08-07 00:21:45 UTC (rev 188099)
@@ -28,11 +28,13 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include <wtf/text/StringBuilder.h>
+
 #define CHECK_READ(length) do { if (m_cursor + length > m_buffer.end()) return false; } while (0)
 
 namespace JSC {
 
-bool WASMReader::readUnsignedInt32(uint32_t& result)
+bool WASMReader::readUInt32(uint32_t& result)
 {
     CHECK_READ(4);
     result = m_cursor[0] | m_cursor[1] << 8 | m_cursor[2] << 16 | m_cursor[3] << 24;
@@ -76,6 +78,64 @@
     return true;
 }
 
+bool WASMReader::readCompactUInt32(uint32_t& result)
+{
+    uint32_t sum = 0;
+    unsigned shift = 0;
+    do {
+        CHECK_READ(1);
+        uint32_t byte = *m_cursor++;
+        if (byte < 0x80) {
+            if ((shift == 28 && byte >= 0x10) || (shift && !byte))
+                return false;
+            result = sum | (byte << shift);
+            return true;
+        }
+        sum |= (byte & firstSevenBitsMask) << shift;
+        shift += 7;
+    } while (shift < 35);
+    return false;
+}
+
+bool WASMReader::readString(String& result)
+{
+    StringBuilder builder;
+    while (true) {
+        CHECK_READ(1);
+        char c = *m_cursor++;
+        if (!c)
+            break;
+        builder.append(c);
+    }
+    result = builder.toString();
+    return true;
+}
+
+bool WASMReader::readType(WASMType& result)
+{
+    return readByte<WASMType>(result, (uint8_t)WASMType::NumberOfTypes);
+}
+
+bool WASMReader::readExpressionType(WASMExpressionType& result)
+{
+    return readByte<WASMExpressionType>(result, (uint8_t)WASMExpressionType::NumberOfExpressionTypes);
+}
+
+bool WASMReader::readExportFormat(WASMExportFormat& result)
+{
+    return readByte<WASMExportFormat>(result, (uint8_t)WASMExportFormat::NumberOfExportFormats);
+}
+
+template <class T> bool WASMReader::readByte(T& result, uint8_t numberOfValues)
+{
+    CHECK_READ(1);
+    uint8_t byte = *m_cursor++;
+    if (byte >= numberOfValues)
+        return false;
+    result = T(byte);
+    return true;
+}
+
 } // namespace JSC
 
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMReader.h (188098 => 188099)


--- trunk/Source/_javascript_Core/wasm/WASMReader.h	2015-08-07 00:03:33 UTC (rev 188098)
+++ trunk/Source/_javascript_Core/wasm/WASMReader.h	2015-08-07 00:21:45 UTC (rev 188099)
@@ -28,6 +28,7 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "WASMFormat.h"
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -40,11 +41,20 @@
     {
     }
 
-    bool readUnsignedInt32(uint32_t& result);
+    bool readUInt32(uint32_t& result);
     bool readFloat(float& result);
     bool readDouble(double& result);
+    bool readCompactUInt32(uint32_t& result);
+    bool readString(String& result);
+    bool readType(WASMType& result);
+    bool readExpressionType(WASMExpressionType& result);
+    bool readExportFormat(WASMExportFormat& result);
 
 private:
+    static const uint32_t firstSevenBitsMask = 0x7f;
+
+    template <class T> bool readByte(T& result, uint8_t numberOfValues);
+
     const Vector<uint8_t>& m_buffer;
     const uint8_t* m_cursor;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to