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;