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;
};