Title: [214919] trunk/Source
Revision
214919
Author
[email protected]
Date
2017-04-04 17:55:54 -0700 (Tue, 04 Apr 2017)

Log Message

WebAssembly: ModuleInformation should be a ref counted thing that can be shared across threads.
https://bugs.webkit.org/show_bug.cgi?id=170478

Reviewed by Saam Barati.

Source/_javascript_Core:

ModuleInformation has been moved to its own file and is now
ThreadSafeRefCounted.  All the Strings we used to keep in the
ModuleInformation have been switched to Vector<LChar> this has the
advantage that it can be passed across threads. However, this does
mean that we need to decode the utf8 strings in each thread. This
is likely not a problem because:

1) most modules have few imports/exports/custom sections.
2) most of the time they are ascii so the conversion is cheap.
3) we only have to do it once per thread, and there shouldn't be too many.

This patch also removes
moduleSignatureIndicesToUniquedSignatureIndices since that
information can already be recovered from the
SignatureInformation.

* _javascript_Core.xcodeproj/project.pbxproj:
* jsc.cpp:
(functionTestWasmModuleFunctions):
* runtime/Identifier.h:
(JSC::Identifier::fromString):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::parseAndCompile):
* wasm/WasmB3IRGenerator.h:
* wasm/WasmFormat.cpp:
(JSC::Wasm::makeString):
(JSC::Wasm::ModuleInformation::~ModuleInformation): Deleted.
* wasm/WasmFormat.h:
(JSC::Wasm::makeString):
(JSC::Wasm::ModuleInformation::functionIndexSpaceSize): Deleted.
(JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace): Deleted.
(JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace): Deleted.
(JSC::Wasm::ModuleInformation::importFunctionCount): Deleted.
(JSC::Wasm::ModuleInformation::internalFunctionCount): Deleted.
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::FunctionParser):
* wasm/WasmModuleInformation.cpp: Copied from Source/_javascript_Core/wasm/WasmValidate.h.
(JSC::Wasm::ModuleInformation::~ModuleInformation):
* wasm/WasmModuleInformation.h: Added.
(JSC::Wasm::ModuleInformation::functionIndexSpaceSize):
(JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace):
(JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace):
(JSC::Wasm::ModuleInformation::importFunctionCount):
(JSC::Wasm::ModuleInformation::internalFunctionCount):
(JSC::Wasm::ModuleInformation::ModuleInformation):
* wasm/WasmModuleParser.cpp:
* wasm/WasmModuleParser.h:
(JSC::Wasm::ModuleParser::ModuleParser):
* wasm/WasmParser.h:
(JSC::Wasm::Parser<SuccessType>::consumeUTF8String):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::parseAndValidateModule):
(JSC::Wasm::Plan::prepare):
(JSC::Wasm::Plan::compileFunctions):
(JSC::Wasm::Plan::complete):
(JSC::Wasm::Plan::cancel):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::internalFunctionCount):
(JSC::Wasm::Plan::takeModuleInformation):
* wasm/WasmSignature.cpp:
(JSC::Wasm::SignatureInformation::get):
* wasm/WasmSignature.h:
* wasm/WasmValidate.cpp:
(JSC::Wasm::validateFunction):
* wasm/WasmValidate.h:
* wasm/js/JSWebAssemblyHelpers.h:
(JSC::createSourceBufferFromValue):
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::createStub):
(JSC::JSWebAssemblyModule::JSWebAssemblyModule):
(JSC::JSWebAssemblyModule::finishCreation):
* wasm/js/JSWebAssemblyModule.h:
(JSC::JSWebAssemblyModule::moduleInformation):
(JSC::JSWebAssemblyModule::source):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::WebAssemblyModuleConstructor::createModule):
* wasm/js/WebAssemblyModulePrototype.cpp:
(JSC::webAssemblyModuleProtoCustomSections):
(JSC::webAssemblyModuleProtoImports):
(JSC::webAssemblyModuleProtoExports):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
* wasm/js/WebAssemblyModuleRecord.h:
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyCompileFunc):
(JSC::instantiate):
(JSC::compileAndInstantiate):

Source/WTF:

This adds a new String::fromUTF8 that converts a vector of characters to
a string.

Also, it cleans up some style.

* wtf/text/WTFString.h:
(WTF::String::fromUTF8):
* wtf/unicode/UTF8.cpp:
(WTF::Unicode::convertLatin1ToUTF8):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (214918 => 214919)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2017-04-05 00:55:54 UTC (rev 214919)
@@ -943,6 +943,7 @@
     wasm/WasmFormat.cpp
     wasm/WasmMemory.cpp
     wasm/WasmMemoryInformation.cpp
+    wasm/WasmModuleInformation.cpp
     wasm/WasmModuleParser.cpp
     wasm/WasmPageCount.cpp
     wasm/WasmPlan.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (214918 => 214919)


--- trunk/Source/_javascript_Core/ChangeLog	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-04-05 00:55:54 UTC (rev 214919)
@@ -1,3 +1,101 @@
+2017-04-04  Keith Miller  <[email protected]>
+
+        WebAssembly: ModuleInformation should be a ref counted thing that can be shared across threads.
+        https://bugs.webkit.org/show_bug.cgi?id=170478
+
+        Reviewed by Saam Barati.
+
+        ModuleInformation has been moved to its own file and is now
+        ThreadSafeRefCounted.  All the Strings we used to keep in the
+        ModuleInformation have been switched to Vector<LChar> this has the
+        advantage that it can be passed across threads. However, this does
+        mean that we need to decode the utf8 strings in each thread. This
+        is likely not a problem because:
+
+        1) most modules have few imports/exports/custom sections.
+        2) most of the time they are ascii so the conversion is cheap.
+        3) we only have to do it once per thread, and there shouldn't be too many.
+
+        This patch also removes
+        moduleSignatureIndicesToUniquedSignatureIndices since that
+        information can already be recovered from the
+        SignatureInformation.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * jsc.cpp:
+        (functionTestWasmModuleFunctions):
+        * runtime/Identifier.h:
+        (JSC::Identifier::fromString):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmB3IRGenerator.h:
+        * wasm/WasmFormat.cpp:
+        (JSC::Wasm::makeString):
+        (JSC::Wasm::ModuleInformation::~ModuleInformation): Deleted.
+        * wasm/WasmFormat.h:
+        (JSC::Wasm::makeString):
+        (JSC::Wasm::ModuleInformation::functionIndexSpaceSize): Deleted.
+        (JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace): Deleted.
+        (JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace): Deleted.
+        (JSC::Wasm::ModuleInformation::importFunctionCount): Deleted.
+        (JSC::Wasm::ModuleInformation::internalFunctionCount): Deleted.
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser<Context>::FunctionParser):
+        * wasm/WasmModuleInformation.cpp: Copied from Source/_javascript_Core/wasm/WasmValidate.h.
+        (JSC::Wasm::ModuleInformation::~ModuleInformation):
+        * wasm/WasmModuleInformation.h: Added.
+        (JSC::Wasm::ModuleInformation::functionIndexSpaceSize):
+        (JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace):
+        (JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace):
+        (JSC::Wasm::ModuleInformation::importFunctionCount):
+        (JSC::Wasm::ModuleInformation::internalFunctionCount):
+        (JSC::Wasm::ModuleInformation::ModuleInformation):
+        * wasm/WasmModuleParser.cpp:
+        * wasm/WasmModuleParser.h:
+        (JSC::Wasm::ModuleParser::ModuleParser):
+        * wasm/WasmParser.h:
+        (JSC::Wasm::Parser<SuccessType>::consumeUTF8String):
+        * wasm/WasmPlan.cpp:
+        (JSC::Wasm::Plan::Plan):
+        (JSC::Wasm::Plan::parseAndValidateModule):
+        (JSC::Wasm::Plan::prepare):
+        (JSC::Wasm::Plan::compileFunctions):
+        (JSC::Wasm::Plan::complete):
+        (JSC::Wasm::Plan::cancel):
+        * wasm/WasmPlan.h:
+        (JSC::Wasm::Plan::internalFunctionCount):
+        (JSC::Wasm::Plan::takeModuleInformation):
+        * wasm/WasmSignature.cpp:
+        (JSC::Wasm::SignatureInformation::get):
+        * wasm/WasmSignature.h:
+        * wasm/WasmValidate.cpp:
+        (JSC::Wasm::validateFunction):
+        * wasm/WasmValidate.h:
+        * wasm/js/JSWebAssemblyHelpers.h:
+        (JSC::createSourceBufferFromValue):
+        * wasm/js/JSWebAssemblyModule.cpp:
+        (JSC::JSWebAssemblyModule::createStub):
+        (JSC::JSWebAssemblyModule::JSWebAssemblyModule):
+        (JSC::JSWebAssemblyModule::finishCreation):
+        * wasm/js/JSWebAssemblyModule.h:
+        (JSC::JSWebAssemblyModule::moduleInformation):
+        (JSC::JSWebAssemblyModule::source):
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::constructJSWebAssemblyInstance):
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::WebAssemblyModuleConstructor::createModule):
+        * wasm/js/WebAssemblyModulePrototype.cpp:
+        (JSC::webAssemblyModuleProtoCustomSections):
+        (JSC::webAssemblyModuleProtoImports):
+        (JSC::webAssemblyModuleProtoExports):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        * wasm/js/WebAssemblyModuleRecord.h:
+        * wasm/js/WebAssemblyPrototype.cpp:
+        (JSC::webAssemblyCompileFunc):
+        (JSC::instantiate):
+        (JSC::compileAndInstantiate):
+
 2017-04-04  Filip Pizlo  <[email protected]>
 
         B3::fixSSA() needs a tune-up

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (214918 => 214919)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-04-05 00:55:54 UTC (rev 214919)
@@ -1371,6 +1371,8 @@
 		53C6FEF11E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53C6FEF01E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp */; };
 		53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
 		53D444DE1DAF09A000B92784 /* B3WasmAddressValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */; };
+		53E777E31E92E265007CBEC4 /* WasmModuleInformation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */; };
+		53E777E41E92E265007CBEC4 /* WasmModuleInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */; };
 		53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WasmSections.h */; };
 		53F40E8B1D5901BB0099A1B6 /* WasmFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */; };
 		53F40E8D1D5901F20099A1B6 /* WasmParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8C1D5901F20099A1B6 /* WasmParser.h */; };
@@ -3883,6 +3885,8 @@
 		53C6FEF01E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOpcodeOrigin.cpp; sourceTree = "<group>"; };
 		53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmAddressValue.h; path = b3/B3WasmAddressValue.h; sourceTree = "<group>"; };
 		53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmAddressValue.cpp; path = b3/B3WasmAddressValue.cpp; sourceTree = "<group>"; };
+		53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModuleInformation.cpp; sourceTree = "<group>"; };
+		53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmModuleInformation.h; sourceTree = "<group>"; };
 		53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
 		53F40E841D58F9770099A1B6 /* WasmSections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSections.h; sourceTree = "<group>"; };
 		53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmFunctionParser.h; sourceTree = "<group>"; };
@@ -6324,6 +6328,8 @@
 				535557131D9D9EA5006D583B /* WasmMemory.h */,
 				79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */,
 				79B759721DFA4C600052174C /* WasmMemoryInformation.h */,
+				53E777E11E92E265007CBEC4 /* WasmModuleInformation.cpp */,
+				53E777E21E92E265007CBEC4 /* WasmModuleInformation.h */,
 				53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */,
 				53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */,
 				ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */,
@@ -8444,6 +8450,7 @@
 				0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
 				0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
 				0F8F2B9A172F0501007DBDA5 /* DFGDesiredIdentifiers.h in Headers */,
+				53E777E41E92E265007CBEC4 /* WasmModuleInformation.h in Headers */,
 				0FFC92141B94E83E0071DD66 /* DFGDesiredInferredType.h in Headers */,
 				C2C0F7CE17BBFC5B00464FE4 /* DFGDesiredTransitions.h in Headers */,
 				0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */,
@@ -10271,6 +10278,7 @@
 				0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
 				0F7025A91714B0FA00382C0E /* DFGOSRExitCompilerCommon.cpp in Sources */,
 				0F392C891B46188400844728 /* DFGOSRExitFuzz.cpp in Sources */,
+				53E777E31E92E265007CBEC4 /* WasmModuleInformation.cpp in Sources */,
 				0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */,
 				0F235BED17178E7300690C7F /* DFGOSRExitPreparation.cpp in Sources */,
 				0F6237971AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/jsc.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/jsc.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/jsc.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -3214,7 +3214,7 @@
                 lastIndex = calleeIndex;
             });
     }
-    std::unique_ptr<Wasm::ModuleInformation> moduleInformation = plan->takeModuleInformation();
+    Ref<Wasm::ModuleInformation> moduleInformation = plan->takeModuleInformation();
     RELEASE_ASSERT(!moduleInformation->memory);
 
     for (uint32_t i = 0; i < functionCount; ++i) {

Modified: trunk/Source/_javascript_Core/runtime/Identifier.h (214918 => 214919)


--- trunk/Source/_javascript_Core/runtime/Identifier.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/runtime/Identifier.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -122,6 +122,7 @@
     static Identifier fromString(ExecState*, const AtomicString&);
     static Identifier fromString(ExecState*, const String&);
     static Identifier fromString(ExecState*, const char*);
+    static Identifier fromString(VM* vm, const Vector<LChar>& characters) { return fromString(vm, characters.data(), characters.size()); }
 
     static Identifier fromUid(VM*, UniquedStringImpl* uid);
     static Identifier fromUid(ExecState*, UniquedStringImpl* uid);

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -205,7 +205,7 @@
 
     // Calls
     PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature&, Vector<ExpressionType>& args, ExpressionType& result);
-    PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature&, SignatureIndex, Vector<ExpressionType>& args, ExpressionType& result);
+    PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature&, Vector<ExpressionType>& args, ExpressionType& result);
     PartialResult WARN_UNUSED_RETURN addUnreachable();
 
     void dump(const Vector<ControlEntry>& controlStack, const ExpressionList* expressionStack);
@@ -968,9 +968,8 @@
     return { };
 }
 
-auto B3IRGenerator::addCallIndirect(const Signature& signature, SignatureIndex signatureIndex, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult
+auto B3IRGenerator::addCallIndirect(const Signature& signature, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult
 {
-    ASSERT(signatureIndex != Signature::invalidIndex);
     ExpressionType calleeIndex = args.takeLast();
     ASSERT(signature.argumentCount() == args.size());
 
@@ -1017,7 +1016,7 @@
 
     // Check the signature matches the value we expect.
     {
-        ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, origin(), signatureIndex);
+        ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, origin(), SignatureInformation::get(signature));
         CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
             m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), calleeSignatureIndex, expectedSignatureIndex));
 
@@ -1269,7 +1268,7 @@
     return bitwise_cast<Origin>(OpcodeOrigin(m_parser->currentOpcode(), m_parser->currentOpcodeStartingOffset()));
 }
 
-Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(CompilationContext& compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ModuleInformation& info, const Vector<SignatureIndex>& moduleSignatureIndicesToUniquedSignatureIndices, MemoryMode mode, unsigned optLevel)
+Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(CompilationContext& compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, unsigned optLevel)
 {
     auto result = std::make_unique<WasmInternalFunction>();
 
@@ -1292,7 +1291,7 @@
     procedure.setOptLevel(optLevel);
 
     B3IRGenerator context(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode);
-    FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, info, moduleSignatureIndicesToUniquedSignatureIndices);
+    FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, info);
     WASM_FAIL_IF_HELPER_FAILS(parser.parse());
 
     context.insertConstants();

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -30,8 +30,8 @@
 #include "B3Common.h"
 #include "B3Compilation.h"
 #include "CCallHelpers.h"
-#include "WasmFormat.h"
 #include "WasmMemory.h"
+#include "WasmModuleInformation.h"
 #include <wtf/Expected.h>
 
 extern "C" void dumpProcedure(void*);
@@ -48,7 +48,7 @@
     CCallHelpers::Call jsEntrypointToWasmEntrypointCall;
 };
 
-Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(CompilationContext&, const uint8_t*, size_t, const Signature&, Vector<UnlinkedWasmToWasmCall>&, const ModuleInformation&, const Vector<SignatureIndex>&, MemoryMode, unsigned optLevel);
+Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(CompilationContext&, const uint8_t*, size_t, const Signature&, Vector<UnlinkedWasmToWasmCall>&, const ModuleInformation&, MemoryMode, unsigned optLevel);
 
 } } // namespace JSC::Wasm
 

Modified: trunk/Source/_javascript_Core/wasm/WasmFormat.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmFormat.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmFormat.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -55,7 +55,12 @@
     return Ptr(segment, &Segment::destroy);
 }
 
-JS_EXPORT_PRIVATE ModuleInformation::~ModuleInformation() { }
+String makeString(const Vector<LChar>& characters)
+{
+    String result = String::fromUTF8(characters);
+    ASSERT(result);
+    return result;
+}
 
 } } // namespace JSC::Wasm
 

Modified: trunk/Source/_javascript_Core/wasm/WasmFormat.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmFormat.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmFormat.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -89,7 +89,7 @@
 static_assert(static_cast<int>(ExternalKind::Memory)   == 2, "Wasm needs Memory to have the value 2");
 static_assert(static_cast<int>(ExternalKind::Global)   == 3, "Wasm needs Global to have the value 3");
 
-static inline const char* makeString(ExternalKind kind)
+inline const char* makeString(ExternalKind kind)
 {
     switch (kind) {
     case ExternalKind::Function: return "function";
@@ -102,18 +102,20 @@
 }
 
 struct Import {
-    String module;
-    String field;
+    const Vector<LChar> module;
+    const Vector<LChar> field;
     ExternalKind kind;
     unsigned kindIndex; // Index in the vector of the corresponding kind.
 };
 
 struct Export {
-    String field;
+    const Vector<LChar> field;
     ExternalKind kind;
     unsigned kindIndex; // Index in the vector of the corresponding kind.
 };
 
+String makeString(const Vector<LChar>& characters);
+
 struct Global {
     enum Mutability : uint8_t {
         // FIXME auto-generate this. https://bugs.webkit.org/show_bug.cgi?id=165231
@@ -226,46 +228,10 @@
 };
     
 struct CustomSection {
-    String name;
+    Vector<LChar> name;
     Vector<uint8_t> payload;
 };
 
-struct ModuleInformation {
-    Vector<Import> imports;
-    Vector<SignatureIndex> importFunctionSignatureIndices;
-    Vector<SignatureIndex> internalFunctionSignatureIndices;
-    Vector<Ref<Signature>> usedSignatures;
-
-    MemoryInformation memory;
-
-    Vector<Export> exports;
-    std::optional<uint32_t> startFunctionIndexSpace;
-    Vector<Segment::Ptr> data;
-    Vector<Element> elements;
-    TableInformation tableInformation;
-    Vector<Global> globals;
-    unsigned firstInternalGlobal { 0 };
-    Vector<CustomSection> customSections;
-
-    size_t functionIndexSpaceSize() const { return importFunctionSignatureIndices.size() + internalFunctionSignatureIndices.size(); }
-    bool isImportedFunctionFromFunctionIndexSpace(size_t functionIndex) const
-    {
-        ASSERT(functionIndex < functionIndexSpaceSize());
-        return functionIndex < importFunctionSignatureIndices.size();
-    }
-    SignatureIndex signatureIndexFromFunctionIndexSpace(size_t functionIndex) const
-    {
-        return isImportedFunctionFromFunctionIndexSpace(functionIndex)
-            ? importFunctionSignatureIndices[functionIndex]
-            : internalFunctionSignatureIndices[functionIndex - importFunctionSignatureIndices.size()];
-    }
-
-    uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); }
-    uint32_t internalFunctionCount() const { return internalFunctionSignatureIndices.size(); }
-
-    ~ModuleInformation();
-};
-
 struct UnlinkedWasmToWasmCall {
     CodeLocationCall callLocation;
     size_t functionIndex;

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -46,7 +46,7 @@
     typedef typename Context::ControlType ControlType;
     typedef typename Context::ExpressionList ExpressionList;
 
-    FunctionParser(Context&, const uint8_t* functionStart, size_t functionLength, const Signature&, const ModuleInformation&, const Vector<SignatureIndex>&);
+    FunctionParser(Context&, const uint8_t* functionStart, size_t functionLength, const Signature&, const ModuleInformation&);
 
     Result WARN_UNUSED_RETURN parse();
 
@@ -86,7 +86,6 @@
     Vector<ControlEntry> m_controlStack;
     const Signature& m_signature;
     const ModuleInformation& m_info;
-    const Vector<SignatureIndex>& m_moduleSignatureIndicesToUniquedSignatureIndices;
 
     OpType m_currentOpcode;
     size_t m_currentOpcodeStartingOffset { 0 };
@@ -95,12 +94,11 @@
 };
 
 template<typename Context>
-FunctionParser<Context>::FunctionParser(Context& context, const uint8_t* functionStart, size_t functionLength, const Signature& signature, const ModuleInformation& info, const Vector<SignatureIndex>& moduleSignatureIndicesToUniquedSignatureIndices)
+FunctionParser<Context>::FunctionParser(Context& context, const uint8_t* functionStart, size_t functionLength, const Signature& signature, const ModuleInformation& info)
     : Parser(functionStart, functionLength)
     , m_context(context)
     , m_signature(signature)
     , m_info(info)
-    , m_moduleSignatureIndicesToUniquedSignatureIndices(moduleSignatureIndicesToUniquedSignatureIndices)
 {
     if (verbose)
         dataLogLn("Parsing function starting at: ", (uintptr_t)functionStart, " of length: ", functionLength);
@@ -350,10 +348,9 @@
         WASM_PARSER_FAIL_IF(!parseVarUInt32(signatureIndex), "can't get call_indirect's signature index");
         WASM_PARSER_FAIL_IF(!parseVarUInt1(reserved), "can't get call_indirect's reserved byte");
         WASM_PARSER_FAIL_IF(reserved, "call_indirect's 'reserved' varuint1 must be 0x0");
-        WASM_PARSER_FAIL_IF(m_moduleSignatureIndicesToUniquedSignatureIndices.size() <= signatureIndex, "call_indirect's signature index ", signatureIndex, " exceeds known signatures ", m_moduleSignatureIndicesToUniquedSignatureIndices.size());
+        WASM_PARSER_FAIL_IF(m_info.usedSignatures.size() <= signatureIndex, "call_indirect's signature index ", signatureIndex, " exceeds known signatures ", m_info.usedSignatures.size());
 
-        SignatureIndex calleeSignatureIndex = m_moduleSignatureIndicesToUniquedSignatureIndices[signatureIndex];
-        const Signature& calleeSignature = SignatureInformation::get(calleeSignatureIndex);
+        const Signature& calleeSignature = m_info.usedSignatures[signatureIndex].get();
         size_t argumentCount = calleeSignature.argumentCount() + 1; // Add the callee's index.
         WASM_PARSER_FAIL_IF(argumentCount > m_expressionStack.size(), "call_indirect expects ", argumentCount, " arguments, but the _expression_ stack currently holds ", m_expressionStack.size(), " values");
 
@@ -365,7 +362,7 @@
         m_expressionStack.shrink(firstArgumentIndex);
 
         ExpressionType result = Context::emptyExpression;
-        WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, calleeSignatureIndex, args, result));
+        WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, args, result));
 
         if (result != Context::emptyExpression)
             m_expressionStack.append(result);

Copied: trunk/Source/_javascript_Core/wasm/WasmModuleInformation.cpp (from rev 214918, trunk/Source/_javascript_Core/wasm/WasmValidate.h) (0 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmModuleInformation.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleInformation.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "config.h"
+#include "WasmModuleInformation.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC { namespace Wasm {
+
+ModuleInformation::~ModuleInformation() { }
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)

Added: trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h (0 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmFormat.h"
+
+namespace JSC { namespace Wasm {
+
+struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
+    size_t functionIndexSpaceSize() const { return importFunctionSignatureIndices.size() + internalFunctionSignatureIndices.size(); }
+    bool isImportedFunctionFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        ASSERT(functionIndex < functionIndexSpaceSize());
+        return functionIndex < importFunctionSignatureIndices.size();
+    }
+    SignatureIndex signatureIndexFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        return isImportedFunctionFromFunctionIndexSpace(functionIndex)
+            ? importFunctionSignatureIndices[functionIndex]
+            : internalFunctionSignatureIndices[functionIndex - importFunctionSignatureIndices.size()];
+    }
+
+    uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); }
+    uint32_t internalFunctionCount() const { return internalFunctionSignatureIndices.size(); }
+
+    ModuleInformation(Vector<uint8_t>&& sourceBytes)
+        : source(WTFMove(sourceBytes))
+    {
+    }
+
+    JS_EXPORT_PRIVATE ~ModuleInformation();
+
+    const Vector<uint8_t> source;
+
+    Vector<Import> imports;
+    Vector<SignatureIndex> importFunctionSignatureIndices;
+    Vector<SignatureIndex> internalFunctionSignatureIndices;
+    Vector<Ref<Signature>> usedSignatures;
+
+    MemoryInformation memory;
+
+    Vector<FunctionLocationInBinary> functionLocationInBinary;
+
+    Vector<Export> exports;
+    std::optional<uint32_t> startFunctionIndexSpace;
+    Vector<Segment::Ptr> data;
+    Vector<Element> elements;
+    TableInformation tableInformation;
+    Vector<Global> globals;
+    unsigned firstInternalGlobal { 0 };
+    Vector<CustomSection> customSections;
+
+};
+
+    
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -49,7 +49,6 @@
 
 auto ModuleParser::parse() -> Result
 {
-    m_result.module = std::make_unique<ModuleInformation>();
     const size_t minSize = 8;
     uint32_t versionNumber;
 
@@ -98,7 +97,7 @@
         previousSection = section;
     }
 
-    return WTFMove(m_result);
+    return { };
 }
 
 auto ModuleParser::parseType() -> PartialResult
@@ -107,8 +106,7 @@
 
     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count");
     WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Type section's count is too big ", count);
-    WASM_PARSER_FAIL_IF(!m_result.moduleSignatureIndicesToUniquedSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
-    WASM_PARSER_FAIL_IF(!m_result.module->usedSignatures.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
+    WASM_PARSER_FAIL_IF(!m_info->usedSignatures.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
 
     for (uint32_t i = 0; i < count; ++i) {
         int8_t type;
@@ -141,8 +139,7 @@
         signature->returnType() = returnType;
 
         std::pair<SignatureIndex, Ref<Signature>> result = SignatureInformation::adopt(WTFMove(signature));
-        m_result.moduleSignatureIndicesToUniquedSignatureIndices.uncheckedAppend(result.first);
-        m_result.module->usedSignatures.uncheckedAppend(WTFMove(result.second));
+        m_info->usedSignatures.uncheckedAppend(WTFMove(result.second));
     }
     return { };
 }
@@ -152,34 +149,33 @@
     uint32_t importCount;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(importCount), "can't get Import section's count");
     WASM_PARSER_FAIL_IF(importCount == std::numeric_limits<uint32_t>::max(), "Import section's count is too big ", importCount);
-    WASM_PARSER_FAIL_IF(!m_result.module->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below.
-    WASM_PARSER_FAIL_IF(!m_result.module->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below.
-    WASM_PARSER_FAIL_IF(!m_result.module->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below.
+    WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below.
+    WASM_PARSER_FAIL_IF(!m_info->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below.
+    WASM_PARSER_FAIL_IF(!m_info->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below.
 
     for (uint32_t importNumber = 0; importNumber < importCount; ++importNumber) {
-        Import imp;
         uint32_t moduleLen;
         uint32_t fieldLen;
-        String moduleString;
-        String fieldString;
+        Vector<LChar> moduleString;
+        Vector<LChar> fieldString;
+        ExternalKind kind;
+        unsigned kindIndex { 0 };
 
         WASM_PARSER_FAIL_IF(!parseVarUInt32(moduleLen), "can't get ", importNumber, "th Import's module name length");
         WASM_PARSER_FAIL_IF(!consumeUTF8String(moduleString, moduleLen), "can't get ", importNumber, "th Import's module name of length ", moduleLen);
-        imp.module = moduleString;
 
         WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", importNumber, "th Import's field name length in module '", moduleString, "'");
         WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", importNumber, "th Import's field name of length ", moduleLen, " in module '", moduleString, "'");
-        imp.field = fieldString;
 
-        WASM_PARSER_FAIL_IF(!parseExternalKind(imp.kind), "can't get ", importNumber, "th Import's kind in module '", moduleString, "' field '", fieldString, "'");
-        switch (imp.kind) {
+        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", importNumber, "th Import's kind in module '", moduleString, "' field '", fieldString, "'");
+        switch (kind) {
         case ExternalKind::Function: {
             uint32_t functionSignatureIndex;
             WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSignatureIndex), "can't get ", importNumber, "th Import's function signature in module '", moduleString, "' field '", fieldString, "'");
-            WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), " in module '", moduleString, "' field '", fieldString, "'");
-            imp.kindIndex = m_result.module->importFunctionSignatureIndices.size();
-            SignatureIndex signatureIndex = m_result.moduleSignatureIndicesToUniquedSignatureIndices[functionSignatureIndex];
-            m_result.module->importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
+            WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_info->usedSignatures.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_info->usedSignatures.size(), " in module '", moduleString, "' field '", fieldString, "'");
+            kindIndex = m_info->importFunctionSignatureIndices.size();
+            SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[functionSignatureIndex]);
+            m_info->importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
             break;
         }
         case ExternalKind::Table: {
@@ -201,16 +197,16 @@
             WASM_FAIL_IF_HELPER_FAILS(parseGlobalType(global));
             WASM_PARSER_FAIL_IF(global.mutability == Global::Mutable, "Mutable Globals aren't supported");
 
-            imp.kindIndex = m_result.module->globals.size();
-            m_result.module->globals.uncheckedAppend(WTFMove(global));
+            kindIndex = m_info->globals.size();
+            m_info->globals.uncheckedAppend(WTFMove(global));
             break;
         }
         }
 
-        m_result.module->imports.uncheckedAppend(imp);
+        m_info->imports.uncheckedAppend({ WTFMove(moduleString), WTFMove(fieldString), kind, kindIndex });
     }
 
-    m_result.module->firstInternalGlobal = m_result.module->globals.size();
+    m_info->firstInternalGlobal = m_info->globals.size();
     return { };
 }
 
@@ -219,20 +215,20 @@
     uint32_t count;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count");
     WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Function section's count is too big ", count);
-    WASM_PARSER_FAIL_IF(!m_result.module->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");
-    WASM_PARSER_FAIL_IF(!m_result.functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
+    WASM_PARSER_FAIL_IF(!m_info->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");
+    WASM_PARSER_FAIL_IF(!m_info->functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
 
     for (uint32_t i = 0; i < count; ++i) {
         uint32_t typeNumber;
         WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", i, "th Function's type number");
-        WASM_PARSER_FAIL_IF(typeNumber >= m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), i, "th Function type number is invalid ", typeNumber);
+        WASM_PARSER_FAIL_IF(typeNumber >= m_info->usedSignatures.size(), i, "th Function type number is invalid ", typeNumber);
 
-        SignatureIndex signatureIndex = m_result.moduleSignatureIndicesToUniquedSignatureIndices[typeNumber];
+        SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[typeNumber]);
         // The Code section fixes up start and end.
         size_t start = 0;
         size_t end = 0;
-        m_result.module->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
-        m_result.functionLocationInBinary.uncheckedAppend({ start, end });
+        m_info->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
+        m_info->functionLocationInBinary.uncheckedAppend({ start, end });
     }
 
     return { };
@@ -275,7 +271,7 @@
 
     ASSERT(!maximum || *maximum >= initial);
 
-    m_result.module->tableInformation = TableInformation(initial, maximum, isImport);
+    m_info->tableInformation = TableInformation(initial, maximum, isImport);
 
     return { };
 }
@@ -296,7 +292,7 @@
 
 auto ModuleParser::parseMemoryHelper(bool isImport) -> PartialResult
 {
-    WASM_PARSER_FAIL_IF(!!m_result.module->memory, "Memory section cannot exist if an Import has a memory");
+    WASM_PARSER_FAIL_IF(!!m_info->memory, "Memory section cannot exist if an Import has a memory");
 
     PageCount initialPageCount;
     PageCount maximumPageCount;
@@ -319,7 +315,7 @@
     ASSERT(initialPageCount);
     ASSERT(!maximumPageCount || maximumPageCount >= initialPageCount);
 
-    m_result.module->memory = MemoryInformation(initialPageCount, maximumPageCount, isImport);
+    m_info->memory = MemoryInformation(initialPageCount, maximumPageCount, isImport);
     return { };
 }
 
@@ -341,7 +337,7 @@
 {
     uint32_t globalCount;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(globalCount), "can't get Global section's count");
-    WASM_PARSER_FAIL_IF(!m_result.module->globals.tryReserveCapacity(globalCount + m_result.module->firstInternalGlobal), "can't allocate memory for ", globalCount + m_result.module->firstInternalGlobal, " globals");
+    WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(globalCount + m_info->firstInternalGlobal), "can't allocate memory for ", globalCount + m_info->firstInternalGlobal, " globals");
 
     for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) {
         Global global;
@@ -356,7 +352,7 @@
             global.initializationType = Global::FromExpression;
         WASM_PARSER_FAIL_IF(typeForInitOpcode != global.type, "Global init_expr opcode of type ", typeForInitOpcode, " doesn't match global's type ", global.type);
 
-        m_result.module->globals.uncheckedAppend(WTFMove(global));
+        m_info->globals.uncheckedAppend(WTFMove(global));
     }
 
     return { };
@@ -367,45 +363,46 @@
     uint32_t exportCount;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(exportCount), "can't get Export section's count");
     WASM_PARSER_FAIL_IF(exportCount == std::numeric_limits<uint32_t>::max(), "Export section's count is too big ", exportCount);
-    WASM_PARSER_FAIL_IF(!m_result.module->exports.tryReserveCapacity(exportCount), "can't allocate enough memory for ", exportCount, " exports");
+    WASM_PARSER_FAIL_IF(!m_info->exports.tryReserveCapacity(exportCount), "can't allocate enough memory for ", exportCount, " exports");
 
     HashSet<String> exportNames;
     for (uint32_t exportNumber = 0; exportNumber < exportCount; ++exportNumber) {
-        Export exp;
         uint32_t fieldLen;
-        String fieldString;
+        Vector<LChar> fieldString;
+        ExternalKind kind;
+        unsigned kindIndex;
 
         WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", exportNumber, "th Export's field name length");
         WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", exportNumber, "th Export's field name of length ", fieldLen);
-        WASM_PARSER_FAIL_IF(exportNames.contains(fieldString), "duplicate export: '", fieldString, "'");
-        exportNames.add(fieldString);
-        exp.field = fieldString;
+        String fieldName = String::fromUTF8(fieldString);
+        WASM_PARSER_FAIL_IF(exportNames.contains(fieldName), "duplicate export: '", fieldString, "'");
+        exportNames.add(fieldName);
 
-        WASM_PARSER_FAIL_IF(!parseExternalKind(exp.kind), "can't get ", exportNumber, "th Export's kind, named '", fieldString, "'");
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(exp.kindIndex), "can't get ", exportNumber, "th Export's kind index, named '", fieldString, "'");
-        switch (exp.kind) {
+        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", exportNumber, "th Export's kind, named '", fieldString, "'");
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(kindIndex), "can't get ", exportNumber, "th Export's kind index, named '", fieldString, "'");
+        switch (kind) {
         case ExternalKind::Function: {
-            WASM_PARSER_FAIL_IF(exp.kindIndex >= m_result.module->functionIndexSpaceSize(), exportNumber, "th Export has invalid function number ", exp.kindIndex, " it exceeds the function index space ", m_result.module->functionIndexSpaceSize(), ", named '", fieldString, "'");
+            WASM_PARSER_FAIL_IF(kindIndex >= m_info->functionIndexSpaceSize(), exportNumber, "th Export has invalid function number ", kindIndex, " it exceeds the function index space ", m_info->functionIndexSpaceSize(), ", named '", fieldString, "'");
             break;
         }
         case ExternalKind::Table: {
             WASM_PARSER_FAIL_IF(!m_hasTable, "can't export a non-existent Table");
-            WASM_PARSER_FAIL_IF(exp.kindIndex, "can't export Table ", exp.kindIndex, " only zero-index Table is currently supported");
+            WASM_PARSER_FAIL_IF(kindIndex, "can't export Table ", kindIndex, " only zero-index Table is currently supported");
             break;
         }
         case ExternalKind::Memory: {
-            WASM_PARSER_FAIL_IF(!m_result.module->memory, "can't export a non-existent Memory");
-            WASM_PARSER_FAIL_IF(exp.kindIndex, "can't export Memory ", exp.kindIndex, " only one Table is currently supported");
+            WASM_PARSER_FAIL_IF(!m_info->memory, "can't export a non-existent Memory");
+            WASM_PARSER_FAIL_IF(kindIndex, "can't export Memory ", kindIndex, " only one Table is currently supported");
             break;
         }
         case ExternalKind::Global: {
-            WASM_PARSER_FAIL_IF(exp.kindIndex >= m_result.module->globals.size(), exportNumber, "th Export has invalid global number ", exp.kindIndex, " it exceeds the globals count ", m_result.module->globals.size(), ", named '", fieldString, "'");
-            WASM_PARSER_FAIL_IF(m_result.module->globals[exp.kindIndex].mutability != Global::Immutable, exportNumber, "th Export isn't immutable, named '", fieldString, "'");
+            WASM_PARSER_FAIL_IF(kindIndex >= m_info->globals.size(), exportNumber, "th Export has invalid global number ", kindIndex, " it exceeds the globals count ", m_info->globals.size(), ", named '", fieldString, "'");
+            WASM_PARSER_FAIL_IF(m_info->globals[kindIndex].mutability != Global::Immutable, exportNumber, "th Export isn't immutable, named '", fieldString, "'");
             break;
         }
         }
 
-        m_result.module->exports.uncheckedAppend(exp);
+        m_info->exports.uncheckedAppend({ WTFMove(fieldString), kind, kindIndex });
     }
 
     return { };
@@ -415,12 +412,12 @@
 {
     uint32_t startFunctionIndex;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), "can't get Start index");
-    WASM_PARSER_FAIL_IF(startFunctionIndex >= m_result.module->functionIndexSpaceSize(), "Start index ", startFunctionIndex, " exceeds function index space ", m_result.module->functionIndexSpaceSize());
-    SignatureIndex signatureIndex = m_result.module->signatureIndexFromFunctionIndexSpace(startFunctionIndex);
+    WASM_PARSER_FAIL_IF(startFunctionIndex >= m_info->functionIndexSpaceSize(), "Start index ", startFunctionIndex, " exceeds function index space ", m_info->functionIndexSpaceSize());
+    SignatureIndex signatureIndex = m_info->signatureIndexFromFunctionIndexSpace(startFunctionIndex);
     const Signature& signature = SignatureInformation::get(signatureIndex);
     WASM_PARSER_FAIL_IF(signature.argumentCount(), "Start function can't have arguments");
     WASM_PARSER_FAIL_IF(signature.returnType() != Void, "Start function can't return a value");
-    m_result.module->startFunctionIndexSpace = startFunctionIndex;
+    m_info->startFunctionIndexSpace = startFunctionIndex;
     return { };
 }
 
@@ -431,7 +428,7 @@
     uint32_t elementCount;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(elementCount), "can't get Element section's count");
     WASM_PARSER_FAIL_IF(elementCount == std::numeric_limits<uint32_t>::max(), "Element section's count is too big ", elementCount);
-    WASM_PARSER_FAIL_IF(!m_result.module->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements");
+    WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements");
     for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) {
         uint32_t tableIndex;
         uint64_t initExprBits;
@@ -446,7 +443,7 @@
         WASM_PARSER_FAIL_IF(!parseVarUInt32(indexCount), "can't get ", elementNum, "th index count for Element section");
         WASM_PARSER_FAIL_IF(indexCount == std::numeric_limits<uint32_t>::max(), "Element section's ", elementNum, "th index count is too big ", indexCount);
 
-        ASSERT(!!m_result.module->tableInformation);
+        ASSERT(!!m_info->tableInformation);
 
         Element element(makeI32InitExpr(initOpcode, initExprBits));
         WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices");
@@ -454,12 +451,12 @@
         for (unsigned index = 0; index < indexCount; ++index) {
             uint32_t functionIndex;
             WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index");
-            WASM_PARSER_FAIL_IF(functionIndex >= m_result.module->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_result.module->functionIndexSpaceSize());
+            WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize());
 
             element.functionIndices.uncheckedAppend(functionIndex);
         }
 
-        m_result.module->elements.uncheckedAppend(WTFMove(element));
+        m_info->elements.uncheckedAppend(WTFMove(element));
     }
 
     return { };
@@ -470,7 +467,7 @@
     uint32_t count;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Code section's count");
     WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", count);
-    WASM_PARSER_FAIL_IF(count != m_result.functionLocationInBinary.size(), "Code section count ", count, " exceeds the declared number of functions ", m_result.functionLocationInBinary.size());
+    WASM_PARSER_FAIL_IF(count != m_info->functionLocationInBinary.size(), "Code section count ", count, " exceeds the declared number of functions ", m_info->functionLocationInBinary.size());
 
     for (uint32_t i = 0; i < count; ++i) {
         uint32_t functionSize;
@@ -478,9 +475,9 @@
         WASM_PARSER_FAIL_IF(functionSize > length(), "Code function's size ", functionSize, " exceeds the module's size ", length());
         WASM_PARSER_FAIL_IF(functionSize > length() - m_offset, "Code function's size ", functionSize, " exceeds the module's remaining size", length() - m_offset);
 
-        m_result.functionLocationInBinary[i].start = m_offset;
-        m_result.functionLocationInBinary[i].end = m_offset + functionSize;
-        m_offset = m_result.functionLocationInBinary[i].end;
+        m_info->functionLocationInBinary[i].start = m_offset;
+        m_info->functionLocationInBinary[i].end = m_offset + functionSize;
+        m_offset = m_info->functionLocationInBinary[i].end;
     }
 
     return { };
@@ -527,11 +524,11 @@
         uint32_t index;
         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get get_global's index");
 
-        WASM_PARSER_FAIL_IF(index >= m_result.module->globals.size(), "get_global's index ", index, " exceeds the number of globals ", m_result.module->globals.size());
-        WASM_PARSER_FAIL_IF(index >= m_result.module->firstInternalGlobal, "get_global import kind index ", index, " exceeds the first internal global ", m_result.module->firstInternalGlobal);
+        WASM_PARSER_FAIL_IF(index >= m_info->globals.size(), "get_global's index ", index, " exceeds the number of globals ", m_info->globals.size());
+        WASM_PARSER_FAIL_IF(index >= m_info->firstInternalGlobal, "get_global import kind index ", index, " exceeds the first internal global ", m_info->firstInternalGlobal);
 
-        ASSERT(m_result.module->globals[index].mutability == Global::Immutable);
-        resultType = m_result.module->globals[index].type;
+        ASSERT(m_info->globals[index].mutability == Global::Immutable);
+        resultType = m_info->globals[index].type;
         bitsOrImportNumber = index;
         break;
     }
@@ -559,10 +556,10 @@
 auto ModuleParser::parseData() -> PartialResult
 {
     uint32_t segmentCount;
-    WASM_PARSER_FAIL_IF(!m_result.module->memory, "Data section cannot exist without a Memory section or Import");
+    WASM_PARSER_FAIL_IF(!m_info->memory, "Data section cannot exist without a Memory section or Import");
     WASM_PARSER_FAIL_IF(!parseVarUInt32(segmentCount), "can't get Data section's count");
     WASM_PARSER_FAIL_IF(segmentCount == std::numeric_limits<uint32_t>::max(), "Data section's count is too big ", segmentCount);
-    WASM_PARSER_FAIL_IF(!m_result.module->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");
+    WASM_PARSER_FAIL_IF(!m_info->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");
 
     for (uint32_t segmentNumber = 0; segmentNumber < segmentCount; ++segmentNumber) {
         uint32_t index;
@@ -580,7 +577,7 @@
 
         Segment* segment = Segment::create(makeI32InitExpr(initOpcode, initExprBits), dataByteLength);
         WASM_PARSER_FAIL_IF(!segment, "can't allocate enough memory for ", segmentNumber, "th Data segment of size ", dataByteLength);
-        m_result.module->data.uncheckedAppend(Segment::adoptPtr(segment));
+        m_info->data.uncheckedAppend(Segment::adoptPtr(segment));
         for (uint32_t dataByte = 0; dataByte < dataByteLength; ++dataByte) {
             uint8_t byte;
             WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", dataByte, "th data byte from ", segmentNumber, "th Data segment");
@@ -595,9 +592,9 @@
     const uint32_t customSectionStartOffset = m_offset;
 
     CustomSection section;
-    uint32_t customSectionNumber = m_result.module->customSections.size() + 1;
+    uint32_t customSectionNumber = m_info->customSections.size() + 1;
     uint32_t nameLen;
-    WASM_PARSER_FAIL_IF(!m_result.module->customSections.tryReserveCapacity(customSectionNumber), "can't allocate enough memory for ", customSectionNumber, "th custom section");
+    WASM_PARSER_FAIL_IF(!m_info->customSections.tryReserveCapacity(customSectionNumber), "can't allocate enough memory for ", customSectionNumber, "th custom section");
     WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get ", customSectionNumber, "th custom section's name length");
     WASM_PARSER_FAIL_IF(!consumeUTF8String(section.name, nameLen), "nameLen get ", customSectionNumber, "th custom section's name of length ", nameLen);
 
@@ -609,7 +606,7 @@
         section.payload.uncheckedAppend(byte);
     }
     
-    m_result.module->customSections.uncheckedAppend(WTFMove(section));
+    m_info->customSections.uncheckedAppend(WTFMove(section));
 
     return { };
 }

Modified: trunk/Source/_javascript_Core/wasm/WasmModuleParser.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmModuleParser.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleParser.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -35,18 +35,11 @@
 
 namespace JSC { namespace Wasm {
 
-struct ModuleParserResult {
-    std::unique_ptr<ModuleInformation> module;
-    Vector<FunctionLocationInBinary> functionLocationInBinary;
-    Vector<SignatureIndex> moduleSignatureIndicesToUniquedSignatureIndices;
-};
-
-class ModuleParser : public Parser<ModuleParserResult> {
+class ModuleParser : public Parser<void> {
 public:
-
-
-    ModuleParser(const uint8_t* sourceBuffer, size_t sourceLength)
+    ModuleParser(const uint8_t* sourceBuffer, size_t sourceLength, ModuleInformation& info)
         : Parser(sourceBuffer, sourceLength)
+        , m_info(info)
     {
     }
 
@@ -65,7 +58,7 @@
     PartialResult WARN_UNUSED_RETURN parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum);
     PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&, Type& initExprType);
 
-    ModuleParserResult m_result;
+    Ref<ModuleInformation> m_info;
     bool m_hasTable { false };
 };
 

Modified: trunk/Source/_javascript_Core/wasm/WasmParser.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmParser.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmParser.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -30,6 +30,7 @@
 #include "B3Compilation.h"
 #include "B3Procedure.h"
 #include "WasmFormat.h"
+#include "WasmModuleInformation.h"
 #include "WasmOps.h"
 #include "WasmSections.h"
 #include <type_traits>
@@ -37,6 +38,7 @@
 #include <wtf/LEBDecoder.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/WTFString.h>
+#include <wtf/unicode/UTF8.h>
 
 namespace JSC { namespace Wasm {
 
@@ -60,7 +62,7 @@
 
     bool WARN_UNUSED_RETURN consumeCharacter(char);
     bool WARN_UNUSED_RETURN consumeString(const char*);
-    bool WARN_UNUSED_RETURN consumeUTF8String(String&, size_t);
+    bool WARN_UNUSED_RETURN consumeUTF8String(Vector<LChar>&, size_t);
 
     bool WARN_UNUSED_RETURN parseVarUInt1(uint8_t&);
     bool WARN_UNUSED_RETURN parseInt7(int8_t&);
@@ -140,18 +142,29 @@
 }
 
 template<typename SuccessType>
-ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(String& result, size_t stringLength)
+ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(Vector<LChar>& result, size_t stringLength)
 {
-    if (stringLength == 0) {
-        result = emptyString();
-        return true;
-    }
     if (length() < stringLength || m_offset > length() - stringLength)
         return false;
-    result = String::fromUTF8(static_cast<const LChar*>(&source()[m_offset]), stringLength);
+    if (!result.tryReserveCapacity(stringLength))
+        return false;
+
+    const uint8_t* stringStart = source() + m_offset;
+
+    // We don't cache the UTF-16 characters since it seems likely the string is ascii.
+    if (UNLIKELY(!charactersAreAllASCII(stringStart, stringLength))) {
+        Vector<UChar, 1024> buffer(stringLength);
+        UChar* bufferStart = buffer.data();
+
+        UChar* bufferCurrent = bufferStart;
+        const char* stringCurrent = reinterpret_cast<const char*>(stringStart);
+        if (WTF::Unicode::convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char *>(stringStart + stringLength), &bufferCurrent, bufferCurrent + buffer.size()) != WTF::Unicode::conversionOK)
+            return false;
+    }
+
+    result.grow(stringLength);
+    memcpy(result.data(), stringStart, stringLength);
     m_offset += stringLength;
-    if (result.isEmpty())
-        return false;
     return true;
 }
 

Modified: trunk/Source/_javascript_Core/wasm/WasmPlan.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmPlan.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmPlan.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -50,21 +50,30 @@
 
 static const bool verbose = false;
 
-Plan::Plan(VM& vm, ArrayBuffer& source, AsyncWork work, CompletionTask&& task)
-    : Plan(vm, reinterpret_cast<uint8_t*>(source.data()), source.byteLength(), work, WTFMove(task))
+Plan::Plan(VM& vm, Ref<ModuleInformation> info, AsyncWork work, CompletionTask&& task)
+    : m_moduleInformation(WTFMove(info))
+    , m_vm(vm)
+    , m_completionTask(task)
+    , m_source(m_moduleInformation->source.data())
+    , m_sourceLength(m_moduleInformation->source.size())
+    , m_state(State::Validated)
+    , m_asyncWork(work)
 {
 }
 
-Plan::Plan(VM& vm, Vector<uint8_t>& source, AsyncWork work, CompletionTask&& task)
-    : Plan(vm, source.data(), source.size(), work, WTFMove(task))
+Plan::Plan(VM& vm, Vector<uint8_t>&& source, AsyncWork work, CompletionTask&& task)
+    : Plan(vm, makeRef(*new ModuleInformation(WTFMove(source))), work, WTFMove(task))
 {
+    m_state = State::Initial;
 }
 
 Plan::Plan(VM& vm, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task)
-    : m_vm(vm)
+    : m_moduleInformation(makeRef(*new ModuleInformation(Vector<uint8_t>())))
+    , m_vm(vm)
     , m_completionTask(task)
     , m_source(source)
     , m_sourceLength(sourceLength)
+    , m_state(State::Initial)
     , m_asyncWork(work)
 {
 }
@@ -97,7 +106,9 @@
 
 bool Plan::parseAndValidateModule()
 {
-    ASSERT(m_state == State::Initial);
+    if (m_state != State::Initial)
+        return true;
+
     dataLogLnIf(verbose, "starting validation");
     MonotonicTime startTime;
     if (verbose || Options::reportCompileTimes())
@@ -104,26 +115,24 @@
         startTime = MonotonicTime::now();
 
     {
-        ModuleParser moduleParser(m_source, m_sourceLength);
+        ModuleParser moduleParser(m_source, m_sourceLength, m_moduleInformation);
         auto parseResult = moduleParser.parse();
         if (!parseResult) {
             fail(holdLock(m_lock), WTFMove(parseResult.error()));
             return false;
         }
-        m_moduleInformation = WTFMove(parseResult->module);
-        m_functionLocationInBinary = WTFMove(parseResult->functionLocationInBinary);
-        m_moduleSignatureIndicesToUniquedSignatureIndices = WTFMove(parseResult->moduleSignatureIndicesToUniquedSignatureIndices);
     }
 
-    for (unsigned functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); ++functionIndex) {
-        dataLogLnIf(verbose, "Processing function starting at: ", m_functionLocationInBinary[functionIndex].start, " and ending at: ", m_functionLocationInBinary[functionIndex].end);
-        const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
-        size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
+    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
+    for (unsigned functionIndex = 0; functionIndex < functionLocations.size(); ++functionIndex) {
+        dataLogLnIf(verbose, "Processing function starting at: ", functionLocations[functionIndex].start, " and ending at: ", functionLocations[functionIndex].end);
+        const uint8_t* functionStart = m_source + functionLocations[functionIndex].start;
+        size_t functionLength = functionLocations[functionIndex].end - functionLocations[functionIndex].start;
         ASSERT(functionLength <= m_sourceLength);
         SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
         const Signature& signature = SignatureInformation::get(signatureIndex);
 
-        auto validationResult = validateFunction(functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices);
+        auto validationResult = validateFunction(functionStart, functionLength, signature, m_moduleInformation.get());
         if (!validationResult) {
             if (verbose) {
                 for (unsigned i = 0; i < functionLength; ++i)
@@ -163,15 +172,16 @@
         return true;
     };
 
+    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
     if (!tryReserveCapacity(m_wasmExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to _javascript_ stubs")
-        || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), " unlinked WebAssembly to WebAssembly calls")
-        || !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), " WebAssembly functions")
-        || !tryReserveCapacity(m_compilationContexts, m_functionLocationInBinary.size(), " compilation contexts"))
+        || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, functionLocations.size(), " unlinked WebAssembly to WebAssembly calls")
+        || !tryReserveCapacity(m_wasmInternalFunctions, functionLocations.size(), " WebAssembly functions")
+        || !tryReserveCapacity(m_compilationContexts, functionLocations.size(), " compilation contexts"))
         return;
 
-    m_unlinkedWasmToWasmCalls.resize(m_functionLocationInBinary.size());
-    m_wasmInternalFunctions.resize(m_functionLocationInBinary.size());
-    m_compilationContexts.resize(m_functionLocationInBinary.size());
+    m_unlinkedWasmToWasmCalls.resize(functionLocations.size());
+    m_wasmInternalFunctions.resize(functionLocations.size());
+    m_compilationContexts.resize(functionLocations.size());
 
     for (unsigned importIndex = 0; importIndex < m_moduleInformation->imports.size(); ++importIndex) {
         Import* import = &m_moduleInformation->imports[importIndex];
@@ -178,7 +188,7 @@
         if (import->kind != ExternalKind::Function)
             continue;
         unsigned importFunctionIndex = m_wasmExitStubs.size();
-        dataLogLnIf(verbose, "Processing import function number ", importFunctionIndex, ": ", import->module, ": ", import->field);
+        dataLogLnIf(verbose, "Processing import function number ", importFunctionIndex, ": ", makeString(import->module), ": ", makeString(import->field));
         SignatureIndex signatureIndex = m_moduleInformation->importFunctionSignatureIndices.at(import->kindIndex);
         m_wasmExitStubs.uncheckedAppend(exitStubGenerator(&m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex));
     }
@@ -219,6 +229,7 @@
     ThreadCountHolder holder(*this);
 
     size_t bytesCompiled = 0;
+    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
     while (true) {
         if (effort == Partial && bytesCompiled >= Options::webAssemblyPartialCompileLimit())
             return;
@@ -226,7 +237,7 @@
         uint32_t functionIndex;
         {
             auto locker = holdLock(m_lock);
-            if (m_currentIndex >= m_functionLocationInBinary.size()) {
+            if (m_currentIndex >= functionLocations.size()) {
                 if (hasWork())
                     moveToState(State::Compiled);
                 return;
@@ -235,17 +246,17 @@
             ++m_currentIndex;
         }
 
-        const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
-        size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
+        const uint8_t* functionStart = m_source + functionLocations[functionIndex].start;
+        size_t functionLength = functionLocations[functionIndex].end - functionLocations[functionIndex].start;
         ASSERT(functionLength <= m_sourceLength);
         SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
         const Signature& signature = SignatureInformation::get(signatureIndex);
         unsigned functionIndexSpace = m_wasmExitStubs.size() + functionIndex;
         ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex);
-        ASSERT(validateFunction(functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices));
+        ASSERT(validateFunction(functionStart, functionLength, signature, m_moduleInformation.get()));
 
         m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
-        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices, m_mode, Options::webAssemblyB3OptimizationLevel());
+        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, Options::webAssemblyB3OptimizationLevel());
 
         if (UNLIKELY(!parseAndCompileResult)) {
             auto locker = holdLock(m_lock);
@@ -253,7 +264,7 @@
                 // Multiple compiles could fail simultaneously. We arbitrarily choose the first.
                 fail(locker, makeString(parseAndCompileResult.error(), ", in function at index ", String::number(functionIndex))); // FIXME make this an Expected.
             }
-            m_currentIndex = m_functionLocationInBinary.size();
+            m_currentIndex = functionLocations.size();
             return;
         }
 
@@ -264,11 +275,11 @@
 
 void Plan::complete(const AbstractLocker&)
 {
-    ASSERT(m_state != State::Compiled || m_currentIndex >= m_functionLocationInBinary.size());
+    ASSERT(m_state != State::Compiled || m_currentIndex >= m_moduleInformation->functionLocationInBinary.size());
     dataLogLnIf(verbose, "Starting Completion");
 
     if (m_state == State::Compiled) {
-        for (uint32_t functionIndex = 0; functionIndex < m_functionLocationInBinary.size(); functionIndex++) {
+        for (uint32_t functionIndex = 0; functionIndex < m_moduleInformation->functionLocationInBinary.size(); functionIndex++) {
             {
                 CompilationContext& context = m_compilationContexts[functionIndex];
                 SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
@@ -324,7 +335,7 @@
 {
     LockHolder locker(m_lock);
     if (m_state != State::Completed) {
-        m_currentIndex = m_functionLocationInBinary.size();
+        m_currentIndex = m_moduleInformation->functionLocationInBinary.size();
         fail(locker, ASCIILiteral("WebAssembly Plan was canceled. If you see this error message please file a bug at bugs.webkit.org!"));
     }
 }

Modified: trunk/Source/_javascript_Core/wasm/WasmPlan.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmPlan.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmPlan.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -30,7 +30,7 @@
 #include "CompilationResult.h"
 #include "VM.h"
 #include "WasmB3IRGenerator.h"
-#include "WasmFormat.h"
+#include "WasmModuleInformation.h"
 #include <wtf/Bag.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/Vector.h>
@@ -49,8 +49,10 @@
     typedef std::function<void(Plan&)> CompletionTask;
     enum AsyncWork : uint8_t { FullCompile, Validation };
     // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
-    Plan(VM&, ArrayBuffer&, AsyncWork, CompletionTask&&);
-    JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t>&, AsyncWork, CompletionTask&&);
+    Plan(VM&, Ref<ModuleInformation>, AsyncWork, CompletionTask&&);
+    JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t>&&, AsyncWork, CompletionTask&&);
+    // Note: This constructor should only be used if you are not actually building a module e.g. validation/function tests
+    // FIXME: When we get rid of function tests we should remove AsyncWork from this constructor.
     JS_EXPORT_PRIVATE Plan(VM&, const uint8_t*, size_t, AsyncWork, CompletionTask&&);
     JS_EXPORT_PRIVATE ~Plan();
 
@@ -72,10 +74,10 @@
     size_t internalFunctionCount() const
     {
         RELEASE_ASSERT(!failed() && !hasWork());
-        return m_functionLocationInBinary.size();
+        return m_moduleInformation->internalFunctionCount();
     }
 
-    std::unique_ptr<ModuleInformation>&& takeModuleInformation()
+    Ref<ModuleInformation>&& takeModuleInformation()
     {
         RELEASE_ASSERT(!failed() && !hasWork());
         return WTFMove(m_moduleInformation);
@@ -130,9 +132,7 @@
 
     const char* stateString(State);
 
-    std::unique_ptr<ModuleInformation> m_moduleInformation;
-    Vector<FunctionLocationInBinary> m_functionLocationInBinary;
-    Vector<SignatureIndex> m_moduleSignatureIndicesToUniquedSignatureIndices;
+    Ref<ModuleInformation> m_moduleInformation;
     Bag<CallLinkInfo> m_callLinkInfos;
     Vector<WasmExitStubs> m_wasmExitStubs;
     Vector<std::unique_ptr<WasmInternalFunction>> m_wasmInternalFunctions;
@@ -149,7 +149,7 @@
     MemoryMode m_mode { MemoryMode::BoundsChecking };
     Lock m_lock;
     Condition m_completed;
-    State m_state { State::Initial };
+    State m_state;
     const AsyncWork m_asyncWork;
     uint8_t m_numberOfActiveThreads { 0 };
     uint32_t m_currentIndex { 0 };

Modified: trunk/Source/_javascript_Core/wasm/WasmSignature.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmSignature.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmSignature.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -127,6 +127,16 @@
     return *info.m_indexMap.get(index);
 }
 
+SignatureIndex SignatureInformation::get(const Signature& signature)
+{
+    SignatureInformation& info = singleton();
+    LockHolder lock(info.m_lock);
+
+    auto result = info.m_signatureMap.get(SignatureHash { &signature });
+    ASSERT(result != Signature::invalidIndex);
+    return result;
+}
+
 void SignatureInformation::tryCleanup()
 {
     SignatureInformation& info = singleton();

Modified: trunk/Source/_javascript_Core/wasm/WasmSignature.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmSignature.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmSignature.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -168,6 +168,7 @@
 
     static std::pair<SignatureIndex, Ref<Signature>> WARN_UNUSED_RETURN adopt(Ref<Signature>&&);
     static const Signature& WARN_UNUSED_RETURN get(SignatureIndex);
+    static SignatureIndex WARN_UNUSED_RETURN get(const Signature&);
     static void tryCleanup();
 
 private:

Modified: trunk/Source/_javascript_Core/wasm/WasmValidate.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmValidate.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmValidate.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -139,7 +139,7 @@
 
     // Calls
     Result WARN_UNUSED_RETURN addCall(unsigned calleeIndex, const Signature&, const Vector<ExpressionType>& args, ExpressionType& result);
-    Result WARN_UNUSED_RETURN addCallIndirect(const Signature&, SignatureIndex, const Vector<ExpressionType>& args, ExpressionType& result);
+    Result WARN_UNUSED_RETURN addCallIndirect(const Signature&, const Vector<ExpressionType>& args, ExpressionType& result);
 
     bool hasMemory() const { return !!m_module.memory; }
 
@@ -335,10 +335,8 @@
     return { };
 }
 
-auto Validate::addCallIndirect(const Signature& signature, SignatureIndex signatureIndex, const Vector<ExpressionType>& args, ExpressionType& result) -> Result
+auto Validate::addCallIndirect(const Signature& signature, const Vector<ExpressionType>& args, ExpressionType& result) -> Result
 {
-    UNUSED_PARAM(signatureIndex);
-    ASSERT(signatureIndex != Signature::invalidIndex);
     const auto argumentCount = signature.argumentCount();
     WASM_VALIDATOR_FAIL_IF(argumentCount != args.size() - 1, "arity mismatch in call_indirect, got ", args.size() - 1, " arguments, expected ", argumentCount);
 
@@ -382,10 +380,10 @@
     dataLogLn();
 }
 
-Expected<void, String> validateFunction(const uint8_t* source, size_t length, const Signature& signature, const ModuleInformation& module, const Vector<SignatureIndex>& moduleSignatureIndicesToUniquedSignatureIndices)
+Expected<void, String> validateFunction(const uint8_t* source, size_t length, const Signature& signature, const ModuleInformation& module)
 {
     Validate context(module);
-    FunctionParser<Validate> validator(context, source, length, signature, module, moduleSignatureIndicesToUniquedSignatureIndices);
+    FunctionParser<Validate> validator(context, source, length, signature, module);
     WASM_FAIL_IF_HELPER_FAILS(validator.parse());
     return { };
 }

Modified: trunk/Source/_javascript_Core/wasm/WasmValidate.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/WasmValidate.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/WasmValidate.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBASSEMBLY)
 
-#include "WasmFormat.h"
+#include "WasmModuleInformation.h"
 #include <wtf/Expected.h>
 
 namespace JSC {
@@ -34,7 +34,7 @@
 
 namespace Wasm {
 
-Expected<void, String> validateFunction(const uint8_t*, size_t, const Signature&, const ModuleInformation&, const Vector<SignatureIndex>&);
+Expected<void, String> validateFunction(const uint8_t*, size_t, const Signature&, const ModuleInformation&);
 
 } } // namespace JSC::Wasm
 

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyHelpers.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -73,20 +73,23 @@
     return arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());
 }
 
-ALWAYS_INLINE RefPtr<ArrayBuffer> createSourceBufferFromValue(VM& vm, ExecState* exec, JSValue value)
+ALWAYS_INLINE Vector<uint8_t> createSourceBufferFromValue(VM& vm, ExecState* exec, JSValue value)
 {
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     size_t byteOffset;
     size_t byteSize;
     uint8_t* data = "" value, byteOffset, byteSize);
-    RETURN_IF_EXCEPTION(throwScope, nullptr);
+    RETURN_IF_EXCEPTION(throwScope, Vector<uint8_t>());
 
-    auto buffer = ArrayBuffer::tryCreate(data + byteOffset, byteSize);
-    if (buffer)
-        return buffer;
+    Vector<uint8_t> result;
+    if (!result.tryReserveCapacity(byteSize)) {
+        throwException(exec, throwScope, createOutOfMemoryError(exec));
+        return result;
+    }
 
-    throwException(exec, throwScope, createOutOfMemoryError(exec));
-    return nullptr;
+    result.grow(byteSize);
+    memcpy(result.data(), data + byteOffset, byteSize);
+    return result;
 }
 
 ALWAYS_INLINE bool isWebAssemblyHostFunction(VM& vm, JSObject* object, WebAssemblyFunction*& wasmFunction, WebAssemblyWrapperFunction*& wasmWrapperFunction)

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -43,7 +43,7 @@
 
 const ClassInfo JSWebAssemblyModule::s_info = { "WebAssembly.Module", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyModule) };
 
-JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, RefPtr<ArrayBuffer>&& source, RefPtr<Wasm::Plan>&& plan)
+JSWebAssemblyModule* JSWebAssemblyModule::createStub(VM& vm, ExecState* exec, Structure* structure, RefPtr<Wasm::Plan>&& plan)
 {
     ASSERT(!plan->hasWork());
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -52,8 +52,8 @@
         return nullptr;
     }
 
-    auto* module = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, WTFMove(source));
-    module->finishCreation(vm, WTFMove(plan));
+    auto* module = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, *plan.get());
+    module->finishCreation(vm);
     return module;
 }
 
@@ -62,37 +62,23 @@
     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 }
 
-JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, RefPtr<ArrayBuffer>&& source)
+JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, Wasm::Plan& plan)
     : Base(vm, structure)
-    , m_sourceBuffer(source.releaseNonNull())
+    , m_moduleInformation(plan.takeModuleInformation())
 {
 }
 
-void JSWebAssemblyModule::finishCreation(VM& vm, RefPtr<Wasm::Plan>&& plan)
+void JSWebAssemblyModule::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
 
-    std::unique_ptr<Wasm::ModuleInformation> moduleInformation = plan->takeModuleInformation();
-    for (auto& exp : moduleInformation->exports) {
-        ASSERT(exp.field.isSafeToSendToAnotherThread());
-        exp.field = AtomicString(exp.field);
-    }
-    for (auto& imp : moduleInformation->imports) {
-        ASSERT(imp.field.isSafeToSendToAnotherThread());
-        imp.field = AtomicString(imp.field);
-        ASSERT(imp.module.isSafeToSendToAnotherThread());
-        imp.module = AtomicString(imp.module);
-    }
-
-    m_moduleInformation = WTFMove(moduleInformation);
-
     // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.
     SymbolTable* exportSymbolTable = SymbolTable::create(vm);
     for (auto& exp : m_moduleInformation->exports) {
         auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
-        ASSERT(exp.field.impl()->isAtomic());
-        exportSymbolTable->set(NoLockingNecessary, static_cast<AtomicStringImpl*>(exp.field.impl()), SymbolTableEntry(VarOffset(offset)));
+        String field = String::fromUTF8(exp.field);
+        exportSymbolTable->set(NoLockingNecessary, AtomicString(field).impl(), SymbolTableEntry(VarOffset(offset)));
     }
 
     m_exportSymbolTable.set(vm, this, exportSymbolTable);

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -31,7 +31,7 @@
 #include "JSObject.h"
 #include "JSWebAssemblyCodeBlock.h"
 #include "UnconditionalFinalizer.h"
-#include "WasmFormat.h"
+#include "WasmModuleInformation.h"
 #include <wtf/Bag.h>
 #include <wtf/Vector.h>
 
@@ -49,12 +49,12 @@
 public:
     typedef JSDestructibleObject Base;
 
-    static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, RefPtr<ArrayBuffer>&& source, RefPtr<Wasm::Plan>&&);
+    static JSWebAssemblyModule* createStub(VM&, ExecState*, Structure*, RefPtr<Wasm::Plan>&&);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_INFO;
 
-    const Wasm::ModuleInformation& moduleInformation() const { return *m_moduleInformation.get(); }
+    const Wasm::ModuleInformation& moduleInformation() const { return m_moduleInformation.get(); }
     SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); }
     Wasm::SignatureIndex signatureIndexFromFunctionIndexSpace(unsigned functionIndexSpace) const
     {
@@ -64,7 +64,7 @@
 
     JSWebAssemblyCodeBlock* codeBlock(Wasm::MemoryMode mode) { return m_codeBlocks[static_cast<size_t>(mode)].get(); }
 
-    ArrayBuffer& source() const { return m_sourceBuffer.get(); }
+    const Vector<uint8_t>& source() const { return moduleInformation().source; }
 
 private:
     friend class JSWebAssemblyCodeBlock;
@@ -71,13 +71,12 @@
 
     void setCodeBlock(VM&, Wasm::MemoryMode, JSWebAssemblyCodeBlock*);
 
-    JSWebAssemblyModule(VM&, Structure*, RefPtr<ArrayBuffer>&&);
-    void finishCreation(VM&, RefPtr<Wasm::Plan>&&);
+    JSWebAssemblyModule(VM&, Structure*, Wasm::Plan&);
+    void finishCreation(VM&);
     static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    Ref<ArrayBuffer> m_sourceBuffer;
-    std::unique_ptr<const Wasm::ModuleInformation> m_moduleInformation;
+    Ref<Wasm::ModuleInformation> m_moduleInformation;
     WriteBarrier<SymbolTable> m_exportSymbolTable;
     WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes];
     WriteBarrier<WebAssemblyToJSCallee> m_callee;

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyInstanceConstructor.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyInstanceConstructor.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyInstanceConstructor.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -87,7 +87,7 @@
         if (instance->codeBlock())
             Wasm::ensureWorklist().completePlanSynchronously(instance->codeBlock()->plan());
         else {
-            Ref<Wasm::Plan> plan = adoptRef(*new Plan(vm, module->source(), Plan::FullCompile, Plan::dontFinalize));
+            Ref<Wasm::Plan> plan = adoptRef(*new Plan(vm, makeRef(const_cast<Wasm::ModuleInformation&>(module->moduleInformation())), Plan::FullCompile, Plan::dontFinalize));
             plan->setModeAndPromise(instance->memoryMode(), nullptr);
             instance->addUnitializedCodeBlock(vm, plan.copyRef());
 

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleConstructor.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleConstructor.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleConstructor.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -75,13 +75,13 @@
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    RefPtr<ArrayBuffer> source = createSourceBufferFromValue(vm, exec, buffer);
+    Vector<uint8_t> source = createSourceBufferFromValue(vm, exec, buffer);
     RETURN_IF_EXCEPTION(scope, { });
 
-    RefPtr<Wasm::Plan> plan = adoptRef(new Wasm::Plan(vm, *source, Wasm::Plan::Validation, Wasm::Plan::dontFinalize));
+    RefPtr<Wasm::Plan> plan = adoptRef(new Wasm::Plan(vm, WTFMove(source), Wasm::Plan::Validation, Wasm::Plan::dontFinalize));
     if (!plan->parseAndValidateModule())
         return throwException(exec, scope, JSWebAssemblyCompileError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyCompileErrorStructure(), plan->errorMessage()));
-    return JSWebAssemblyModule::createStub(vm, exec, structure, WTFMove(source), WTFMove(plan));
+    return JSWebAssemblyModule::createStub(vm, exec, structure, WTFMove(plan));
 }
 
 WebAssemblyModuleConstructor* WebAssemblyModuleConstructor::create(VM& vm, Structure* structure, WebAssemblyModulePrototype* thisPrototype)

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModulePrototype.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -73,7 +73,7 @@
 
     const auto& customSections = module->moduleInformation().customSections;
     for (const Wasm::CustomSection& section : customSections) {
-        if (section.name == sectionNameString) {
+        if (String::fromUTF8(section.name) == sectionNameString) {
             auto buffer = ArrayBuffer::tryCreate(section.payload.data(), section.payload.size());
             if (!buffer)
                 return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
@@ -110,8 +110,8 @@
         for (const Wasm::Import& imp : imports) {
             JSObject* obj = constructEmptyObject(exec);
             RETURN_IF_EXCEPTION(throwScope, { });
-            obj->putDirect(vm, module, jsString(exec, imp.module));
-            obj->putDirect(vm, name, jsString(exec, imp.field));
+            obj->putDirect(vm, module, jsString(exec, String::fromUTF8(imp.module)));
+            obj->putDirect(vm, name, jsString(exec, String::fromUTF8(imp.field)));
             obj->putDirect(vm, kind, jsString(exec, String(makeString(imp.kind))));
             result->push(exec, obj);
             RETURN_IF_EXCEPTION(throwScope, { });
@@ -141,7 +141,7 @@
         for (const Wasm::Export& exp : exports) {
             JSObject* obj = constructEmptyObject(exec);
             RETURN_IF_EXCEPTION(throwScope, { });
-            obj->putDirect(vm, name, jsString(exec, exp.field));
+            obj->putDirect(vm, name, jsString(exec, String::fromUTF8(exp.field)));
             obj->putDirect(vm, kind, jsString(exec, String(makeString(exp.kind))));
             result->push(exec, obj);
             RETURN_IF_EXCEPTION(throwScope, { });

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -37,7 +37,6 @@
 #include "JSWebAssemblyLinkError.h"
 #include "JSWebAssemblyModule.h"
 #include "ProtoCallFrame.h"
-#include "WasmFormat.h"
 #include "WasmSignature.h"
 #include "WebAssemblyFunction.h"
 #include <limits>
@@ -129,7 +128,7 @@
                 Wasm::Callee& wasmEntrypointCallee = codeBlock->wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
                 Wasm::SignatureIndex signatureIndex = module->signatureIndexFromFunctionIndexSpace(exp.kindIndex);
                 const Wasm::Signature& signature = Wasm::SignatureInformation::get(signatureIndex);
-                WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), exp.field, instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
+                WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature.argumentCount(), String::fromUTF8(exp.field), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
                 exportedValue = function;
             }
             break;

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -28,7 +28,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "AbstractModuleRecord.h"
-#include "WasmFormat.h"
+#include "WasmModuleInformation.h"
 
 namespace JSC {
 

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyPrototype.cpp (214918 => 214919)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyPrototype.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyPrototype.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -83,7 +83,7 @@
     JSPromiseDeferred* promise = JSPromiseDeferred::create(exec, globalObject);
     RETURN_IF_EXCEPTION(scope, { });
 
-    RefPtr<ArrayBuffer> source = createSourceBufferFromValue(vm, exec, exec->argument(0));
+    Vector<uint8_t> source = createSourceBufferFromValue(vm, exec, exec->argument(0));
     RETURN_IF_EXCEPTION(scope, { });
 
     Vector<Strong<JSCell>> dependencies;
@@ -90,13 +90,13 @@
     dependencies.append(Strong<JSCell>(vm, globalObject));
     vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
 
-    Ref<Plan> plan = adoptRef(*new Plan(vm, *source, Plan::Validation, [source, promise, globalObject] (Plan& p) mutable {
+    Ref<Plan> plan = adoptRef(*new Plan(vm, WTFMove(source), Plan::Validation, [promise, globalObject] (Plan& p) mutable {
         RefPtr<Plan> plan = makeRef(p);
-        plan->vm().promiseDeferredTimer->scheduleWorkSoon(promise, [source, promise, globalObject, plan = WTFMove(plan)] () mutable {
+        plan->vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, globalObject, plan = WTFMove(plan)] () mutable {
             VM& vm = plan->vm();
             auto scope = DECLARE_CATCH_SCOPE(vm);
             ExecState* exec = globalObject->globalExec();
-            JSValue module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove(source), WTFMove(plan));
+            JSValue module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove(plan));
             if (scope.exception()) {
                 reject(exec, scope, promise);
                 return;
@@ -167,7 +167,7 @@
 
     // FIXME: This re-parses the module header, which shouldn't be necessary.
     // https://bugs.webkit.org/show_bug.cgi?id=170205
-    Ref<Plan> plan = adoptRef(*new Plan(vm, module->source(), Plan::FullCompile, [promise, instance, module, entries] (Plan& p) {
+    Ref<Plan> plan = adoptRef(*new Plan(vm, makeRef(const_cast<Wasm::ModuleInformation&>(module->moduleInformation())), Plan::FullCompile, [promise, instance, module, entries] (Plan& p) {
         RefPtr<Plan> plan = makeRef(p);
         plan->vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, instance, module, entries, plan = WTFMove(plan)] () {
             VM& vm = plan->vm();
@@ -184,7 +184,7 @@
 static void compileAndInstantiate(VM& vm, ExecState* exec, JSPromiseDeferred* promise, JSValue buffer, JSObject* importObject)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
-    RefPtr<ArrayBuffer> source = createSourceBufferFromValue(vm, exec, buffer);
+    Vector<uint8_t> source = createSourceBufferFromValue(vm, exec, buffer);
     RETURN_IF_EXCEPTION(scope, void());
 
     auto* globalObject = exec->lexicalGlobalObject();
@@ -193,13 +193,13 @@
     dependencies.append(Strong<JSCell>(vm, importObject));
     vm.promiseDeferredTimer->addPendingPromise(promise, WTFMove(dependencies));
 
-    Ref<Plan> plan = adoptRef(*new Plan(vm, *source, Plan::Validation, [source, promise, importObject, globalObject] (Plan& p) mutable {
+    Ref<Plan> plan = adoptRef(*new Plan(vm, WTFMove(source), Plan::Validation, [promise, importObject, globalObject] (Plan& p) mutable {
         RefPtr<Plan> plan = makeRef(p);
-        plan->vm().promiseDeferredTimer->scheduleWorkSoon(promise, [source, promise, importObject, globalObject, plan = WTFMove(plan)] () mutable {
+        plan->vm().promiseDeferredTimer->scheduleWorkSoon(promise, [promise, importObject, globalObject, plan = WTFMove(plan)] () mutable {
             VM& vm = plan->vm();
             auto scope = DECLARE_CATCH_SCOPE(vm);
             ExecState* exec = globalObject->globalExec();
-            JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), WTFMove(source), plan.copyRef());
+            JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, exec, globalObject->WebAssemblyModuleStructure(), plan.copyRef());
             if (scope.exception()) {
                 reject(exec, scope, promise);
                 return;

Modified: trunk/Source/WTF/ChangeLog (214918 => 214919)


--- trunk/Source/WTF/ChangeLog	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/WTF/ChangeLog	2017-04-05 00:55:54 UTC (rev 214919)
@@ -1,3 +1,20 @@
+2017-04-04  Keith Miller  <[email protected]>
+
+        WebAssembly: ModuleInformation should be a ref counted thing that can be shared across threads.
+        https://bugs.webkit.org/show_bug.cgi?id=170478
+
+        Reviewed by Saam Barati.
+
+        This adds a new String::fromUTF8 that converts a vector of characters to
+        a string.
+
+        Also, it cleans up some style.
+
+        * wtf/text/WTFString.h:
+        (WTF::String::fromUTF8):
+        * wtf/unicode/UTF8.cpp:
+        (WTF::Unicode::convertLatin1ToUTF8):
+
 2017-04-04  Filip Pizlo  <[email protected]>
 
         B3::fixSSA() needs a tune-up

Modified: trunk/Source/WTF/wtf/text/WTFString.h (214918 => 214919)


--- trunk/Source/WTF/wtf/text/WTFString.h	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/WTF/wtf/text/WTFString.h	2017-04-05 00:55:54 UTC (rev 214919)
@@ -433,6 +433,7 @@
     static String fromUTF8(const char* s, size_t length) { return fromUTF8(reinterpret_cast<const LChar*>(s), length); };
     static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast<const LChar*>(s)); };
     WTF_EXPORT_STRING_API static String fromUTF8(const CString&);
+    static String fromUTF8(const Vector<LChar>& characters);
 
     // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8.
     WTF_EXPORT_STRING_API static String fromUTF8WithLatin1Fallback(const LChar*, size_t);
@@ -694,6 +695,13 @@
 // Shared global empty string.
 WTF_EXPORT_STRING_API const String& emptyString();
 
+inline String String::fromUTF8(const Vector<LChar>& characters)
+{
+    if (characters.isEmpty())
+        return emptyString();
+    return fromUTF8(characters.data(), characters.size());
+}
+
 template<unsigned length> inline bool equalLettersIgnoringASCIICase(const String& string, const char (&lowercaseLetters)[length])
 {
     return equalLettersIgnoringASCIICase(string.impl(), lowercaseLetters);

Modified: trunk/Source/WTF/wtf/unicode/UTF8.cpp (214918 => 214919)


--- trunk/Source/WTF/wtf/unicode/UTF8.cpp	2017-04-05 00:48:25 UTC (rev 214918)
+++ trunk/Source/WTF/wtf/unicode/UTF8.cpp	2017-04-05 00:55:54 UTC (rev 214919)
@@ -126,8 +126,8 @@
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 
 ConversionResult convertLatin1ToUTF8(
-                                     const LChar** sourceStart, const LChar* sourceEnd, 
-                                     char** targetStart, char* targetEnd)
+    const LChar** sourceStart, const LChar* sourceEnd, 
+    char** targetStart, char* targetEnd)
 {
     ConversionResult result = conversionOK;
     const LChar* source = *sourceStart;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to