Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (204483 => 204484)
--- trunk/Source/_javascript_Core/ChangeLog 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-08-15 21:35:07 UTC (rev 204484)
@@ -1,3 +1,99 @@
+2016-08-15 Keith Miller <[email protected]>
+
+ Implement WASM Parser and B3 IR generator
+ https://bugs.webkit.org/show_bug.cgi?id=160681
+
+ Reviewed by Benjamin Poulain.
+
+ This patch adds the skeleton for a WebAssembly pipeline. The
+ pipeline is designed in order to make it easy to have as much of
+ the compilation process threaded as possible. The flow of the
+ pipeline roughly goes as follows:
+
+ 1) Create a WASMPlan with the VM and a Vector of the
+ assembly. Currently the plan will process all the work
+ synchronously, however, in the future this can be offloaded to
+ other threads.
+
+ 2) The plan will run the WASMModuleParser, which collates all the
+ information needed to compile each module function
+ independently. Since, we are still in the early phases, the only
+ information is the starting and ending byte of the function's
+ body. The module parser, however, still scans both and
+ semi-validates the type and the function sections.
+
+ 3) Each function is decoded and compiled. In the future this
+ should also include a opcode validation phase. The
+ WASMFunctionParser is templatized so that a validator should be
+ able to use most of the same code the B3 IR generator does.
+
+ 4) When the plan has finished it will fill a Vector of
+ B3::Compilation objects that correspond to the respective function
+ in the WASM module.
+
+
+ The current testing plan for the modules is to inline the the
+ binary generated by the spec's OCaml prototype. The inlined binary
+ is passed to a WASMPlan then invoked to check the result of the
+ function. In the future we should add a more robust testing
+ infrastructure.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * testWASM.cpp:
+ (printUsageStatement):
+ (CommandLine::parseArguments):
+ (invoke):
+ (runWASMTests):
+ (main):
+ * wasm/JSWASMModule.h:
+ (JSC::JSWASMModule::globalVariableTypes):
+ * wasm/WASMB3IRGenerator.cpp: Added.
+ (JSC::WASM::B3IRGenerator::B3IRGenerator):
+ (JSC::WASM::B3IRGenerator::addLocal):
+ (JSC::WASM::B3IRGenerator::binaryOp):
+ (JSC::WASM::B3IRGenerator::addConstant):
+ (JSC::WASM::B3IRGenerator::addBlock):
+ (JSC::WASM::B3IRGenerator::endBlock):
+ (JSC::WASM::B3IRGenerator::addReturn):
+ (JSC::WASM::B3IRGenerator::unify):
+ (JSC::WASM::B3IRGenerator::initializeIncommingTypes):
+ (JSC::WASM::B3IRGenerator::unifyValuesWithLevel):
+ (JSC::WASM::B3IRGenerator::stackForControlLevel):
+ (JSC::WASM::B3IRGenerator::blockForControlLevel):
+ (JSC::WASM::parseAndCompile):
+ * wasm/WASMB3IRGenerator.h: Copied from Source/WTF/wtf/DataLog.h.
+ * wasm/WASMFormat.h:
+ * wasm/WASMFunctionParser.h: Added.
+ (JSC::WASM::WASMFunctionParser<Context>::WASMFunctionParser):
+ (JSC::WASM::WASMFunctionParser<Context>::parse):
+ (JSC::WASM::WASMFunctionParser<Context>::parseBlock):
+ (JSC::WASM::WASMFunctionParser<Context>::parseExpression):
+ * wasm/WASMModuleParser.cpp: Added.
+ (JSC::WASM::WASMModuleParser::parse):
+ (JSC::WASM::WASMModuleParser::parseFunctionTypes):
+ (JSC::WASM::WASMModuleParser::parseFunctionSignatures):
+ (JSC::WASM::WASMModuleParser::parseFunctionDefinitions):
+ * wasm/WASMModuleParser.h: Copied from Source/WTF/wtf/DataLog.h.
+ (JSC::WASM::WASMModuleParser::WASMModuleParser):
+ (JSC::WASM::WASMModuleParser::functionInformation):
+ * wasm/WASMOps.h: Copied from Source/WTF/wtf/DataLog.h.
+ * wasm/WASMParser.h: Added.
+ (JSC::WASM::WASMParser::parseVarUInt32):
+ (JSC::WASM::WASMParser::WASMParser):
+ (JSC::WASM::WASMParser::consumeCharacter):
+ (JSC::WASM::WASMParser::consumeString):
+ (JSC::WASM::WASMParser::parseUInt32):
+ (JSC::WASM::WASMParser::parseUInt7):
+ (JSC::WASM::WASMParser::parseVarUInt1):
+ (JSC::WASM::WASMParser::parseValueType):
+ * wasm/WASMPlan.cpp: Copied from Source/WTF/wtf/DataLog.h.
+ (JSC::WASM::Plan::Plan):
+ * wasm/WASMPlan.h: Copied from Source/WTF/wtf/DataLog.h.
+ * wasm/WASMSections.cpp: Copied from Source/WTF/wtf/DataLog.h.
+ (JSC::WASM::WASMSections::lookup):
+ * wasm/WASMSections.h: Copied from Source/WTF/wtf/DataLog.h.
+ (JSC::WASM::WASMSections::validateOrder):
+
2016-08-15 Benjamin Poulain <[email protected]>
[JSC] B3 Neg opcode should support float
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (204483 => 204484)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-08-15 21:35:07 UTC (rev 204484)
@@ -1178,6 +1178,8 @@
52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
+ 531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WASMPlan.h */; };
+ 531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */; };
53486BB71C1795C300F6F3AF /* JSTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 53486BB61C1795C300F6F3AF /* JSTypedArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */; };
534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */; };
@@ -1191,6 +1193,15 @@
539EB07A1D55607000C82EF7 /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* _javascript_Core.framework */; };
539EB0811D55608A00C82EF7 /* testWASM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 539EB0711D553DF800C82EF7 /* testWASM.cpp */; };
539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
+ 53F40E851D58F9770099A1B6 /* WASMSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WASMSections.h */; };
+ 53F40E871D58F9D60099A1B6 /* WASMSections.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F40E861D58F9D60099A1B6 /* WASMSections.cpp */; };
+ 53F40E8B1D5901BB0099A1B6 /* WASMFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */; };
+ 53F40E8D1D5901F20099A1B6 /* WASMParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8C1D5901F20099A1B6 /* WASMParser.h */; };
+ 53F40E8F1D5902820099A1B6 /* WASMB3IRGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */; };
+ 53F40E911D5903020099A1B6 /* WASMOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E901D5903020099A1B6 /* WASMOps.h */; };
+ 53F40E931D5A4AB30099A1B6 /* WASMB3IRGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */; };
+ 53F40E951D5A7AEF0099A1B6 /* WASMModuleParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E941D5A7AEF0099A1B6 /* WASMModuleParser.h */; };
+ 53F40E971D5A7BEC0099A1B6 /* WASMModuleParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F40E961D5A7BEC0099A1B6 /* WASMModuleParser.cpp */; };
53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */; };
@@ -3353,6 +3364,8 @@
52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
+ 531374BC1D5CE67600AF7A0B /* WASMPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMPlan.h; sourceTree = "<group>"; };
+ 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMPlan.cpp; sourceTree = "<group>"; };
53486BB61C1795C300F6F3AF /* JSTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArray.h; sourceTree = "<group>"; };
53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArray.cpp; sourceTree = "<group>"; };
534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypedArrayCTest.cpp; path = API/tests/TypedArrayCTest.cpp; sourceTree = "<group>"; };
@@ -3370,6 +3383,15 @@
539EB0801D55607000C82EF7 /* testWASM */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testWASM; sourceTree = BUILT_PRODUCTS_DIR; };
539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.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>"; };
+ 53F40E861D58F9D60099A1B6 /* WASMSections.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMSections.cpp; sourceTree = "<group>"; };
+ 53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionParser.h; sourceTree = "<group>"; };
+ 53F40E8C1D5901F20099A1B6 /* WASMParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMParser.h; sourceTree = "<group>"; };
+ 53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMB3IRGenerator.cpp; sourceTree = "<group>"; };
+ 53F40E901D5903020099A1B6 /* WASMOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMOps.h; sourceTree = "<group>"; };
+ 53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMB3IRGenerator.h; sourceTree = "<group>"; };
+ 53F40E941D5A7AEF0099A1B6 /* WASMModuleParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMModuleParser.h; sourceTree = "<group>"; };
+ 53F40E961D5A7BEC0099A1B6 /* WASMModuleParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMModuleParser.cpp; sourceTree = "<group>"; };
53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = "<group>"; };
53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
@@ -5539,7 +5561,18 @@
children = (
7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
+ 53F40E901D5903020099A1B6 /* WASMOps.h */,
7BC547D21B69599B00959B58 /* WASMFormat.h */,
+ 53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
+ 53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */,
+ 53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */,
+ 53F40E961D5A7BEC0099A1B6 /* WASMModuleParser.cpp */,
+ 53F40E941D5A7AEF0099A1B6 /* WASMModuleParser.h */,
+ 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */,
+ 531374BC1D5CE67600AF7A0B /* WASMPlan.h */,
+ 53F40E8C1D5901F20099A1B6 /* WASMParser.h */,
+ 53F40E861D58F9D60099A1B6 /* WASMSections.cpp */,
+ 53F40E841D58F9770099A1B6 /* WASMSections.h */,
);
path = wasm;
sourceTree = "<group>";
@@ -7211,6 +7244,7 @@
0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */,
C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */,
+ 53F40E951D5A7AEF0099A1B6 /* WASMModuleParser.h in Headers */,
6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */,
0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
@@ -7296,6 +7330,7 @@
BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
6AD2CB4D19B9140100065719 /* DebuggerEvalEnabler.h in Headers */,
FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */,
+ 53F40E851D58F9770099A1B6 /* WASMSections.h in Headers */,
DC9A0C1F1D2D9CB10085124E /* B3CaseCollectionInlines.h in Headers */,
0F2D4DDE19832D34007D4B19 /* DebuggerScope.h in Headers */,
0F136D4D174AD69E0075B354 /* DeferGC.h in Headers */,
@@ -7442,6 +7477,7 @@
0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
+ 53F40E8D1D5901F20099A1B6 /* WASMParser.h in Headers */,
0F40E4A81C497F7400A577FA /* AirOpcodeGenerated.h in Headers */,
0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
0F6237981AE45CA700D402EA /* DFGPhantomInsertionPhase.h in Headers */,
@@ -7596,6 +7632,7 @@
0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */,
0F2B66AE17B6B54500A7AE3F /* GCIncomingRefCountedSet.h in Headers */,
0F2B66AF17B6B54500A7AE3F /* GCIncomingRefCountedSetInlines.h in Headers */,
+ 531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */,
2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
0F2BBD981C5FF3F50023EF23 /* B3Variable.h in Headers */,
A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */,
@@ -7807,6 +7844,7 @@
0F2B66F617B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */,
797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */,
BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
+ 53F40E8B1D5901BB0099A1B6 /* WASMFunctionParser.h in Headers */,
996B731D1BDA08EF00331B84 /* JSGlobalObject.lut.h in Headers */,
A5FD0086189B1B7E00633231 /* JSGlobalObjectConsoleAgent.h in Headers */,
A5C3A1A618C0490200C9593A /* JSGlobalObjectConsoleClient.h in Headers */,
@@ -7866,6 +7904,7 @@
A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */,
0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
+ 53F40E911D5903020099A1B6 /* WASMOps.h in Headers */,
A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
BC18C45E0E16F5CD00B34460 /* CLoopStack.h in Headers */,
@@ -7914,6 +7953,7 @@
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
99DA00B01BD5994E00F4575C /* lazywriter.py in Headers */,
BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */,
+ 53F40E931D5A4AB30099A1B6 /* WASMB3IRGenerator.h in Headers */,
BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */,
DCF3D56B1CD29472003D5C65 /* LazyClassStructureInlines.h in Headers */,
FE187A021BFBE5610038BBCA /* JITMulGenerator.h in Headers */,
@@ -8947,6 +8987,7 @@
0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
A7D89CF517A0B8CC00773AD8 /* DFGCriticalEdgeBreakingPhase.cpp in Sources */,
0F6183291C45BF070072450B /* AirCCallingConvention.cpp in Sources */,
+ 53F40E871D58F9D60099A1B6 /* WASMSections.cpp in Sources */,
0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
0F338E121BF0276C0013C88F /* B3OpaqueByproducts.cpp in Sources */,
@@ -9160,6 +9201,7 @@
9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */,
A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */,
A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */,
+ 531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */,
A58E35911860DECF001F24FE /* InjectedScriptHost.cpp in Sources */,
A513E5CA185F9624007E95AD /* InjectedScriptManager.cpp in Sources */,
A5840E20187B7B8600843B10 /* InjectedScriptModule.cpp in Sources */,
@@ -9536,6 +9578,7 @@
E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */,
FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */,
FE187A011BFBE55E0038BBCA /* JITMulGenerator.cpp in Sources */,
+ 53F40E8F1D5902820099A1B6 /* WASMB3IRGenerator.cpp in Sources */,
26718BA41BE99F780052017B /* AirIteratedRegisterCoalescing.cpp in Sources */,
FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
@@ -9545,6 +9588,7 @@
A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
0F338DF91BE96AA80013C88F /* B3CCallValue.cpp in Sources */,
A7CA3AEB17DA5168006538AF /* WeakMapData.cpp in Sources */,
+ 53F40E971D5A7BEC0099A1B6 /* WASMModuleParser.cpp in Sources */,
A7CA3AE517DA41AE006538AF /* WeakMapPrototype.cpp in Sources */,
14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
709FB8691AE335C60039D069 /* WeakSetConstructor.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/testWASM.cpp (204483 => 204484)
--- trunk/Source/_javascript_Core/testWASM.cpp 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/_javascript_Core/testWASM.cpp 2016-08-15 21:35:07 UTC (rev 204484)
@@ -25,7 +25,11 @@
#include "config.h"
+#include "B3Compilation.h"
+#include "InitializeThreading.h"
#include "JSString.h"
+#include "VM.h"
+#include "WASMPlan.h"
#include <wtf/DataLog.h>
#include <wtf/LEBDecoder.h>
@@ -38,6 +42,7 @@
Vector<String> m_arguments;
bool m_runLEBTests { false };
+ bool m_runWASMTests { false };
void parseArguments(int, char**);
};
@@ -47,6 +52,7 @@
fprintf(stderr, "Usage: testWASM [options]\n");
fprintf(stderr, " -h|--help Prints this help message\n");
fprintf(stderr, " -l|--leb Runs the LEB decoder tests\n");
+ fprintf(stderr, " -w|--web Run the WASM tests\n");
fprintf(stderr, "\n");
exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
@@ -63,6 +69,9 @@
if (!strcmp(arg, "-l") || !strcmp(arg, "--leb"))
m_runLEBTests = true;
+
+ if (!strcmp(arg, "-w") || !strcmp(arg, "--web"))
+ m_runWASMTests = true;
}
for (; i < argc; ++i)
@@ -109,7 +118,7 @@
Vector<uint8_t> vector = Vector<uint8_t> init; \
size_t offset = startOffset; \
uint32_t result; \
- bool status = decodeUInt32(vector, offset, result); \
+ bool status = decodeUInt32(vector.data(), vector.size(), offset, result); \
RELEASE_ASSERT(status == expectedStatus); \
if (expectedStatus) { \
RELEASE_ASSERT(result == expectedResult); \
@@ -157,7 +166,7 @@
Vector<uint8_t> vector = Vector<uint8_t> init; \
size_t offset = startOffset; \
int32_t result; \
- bool status = decodeInt32(vector, offset, result); \
+ bool status = decodeInt32(vector.data(), vector.size(), offset, result); \
RELEASE_ASSERT(status == expectedStatus); \
if (expectedStatus) { \
int32_t expected = expectedResult; \
@@ -173,7 +182,118 @@
FOR_EACH_SIGNED_LEB_TEST(TEST_SIGNED_LEB_DECODE)
}
+#if ENABLE(WEBASSEMBLY)
+static JSC::VM* vm;
+
+using namespace JSC;
+using namespace WASM;
+using namespace B3;
+
+template<typename T, typename... Arguments>
+T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments)
+{
+ T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress());
+ return function(arguments...);
+}
+
+template<typename T, typename... Arguments>
+T invoke(const Compilation& code, Arguments... arguments)
+{
+ return invoke<T>(code.code(), arguments...);
+}
+
+// For now we inline the test files.
+static void runWASMTests()
+{
+ {
+ // Generated from: (module (func "return-i32" (result i32) (return (i32.const 5))) )
+ Vector<uint8_t> vector = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x85, 0x80, 0x80,
+ 0x00, 0x01, 0x40, 0x00, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x82,
+ 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x8d, 0x80, 0x80, 0x00,
+ 0x01, 0x00, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x69, 0x33, 0x32, 0x04, 0x63, 0x6f,
+ 0x64, 0x65, 0x8b, 0x80, 0x80, 0x00, 0x01, 0x86, 0x80, 0x80, 0x00, 0x00, 0x10, 0x05, 0x09, 0x01,
+ 0x0f
+ };
+
+ Plan plan(*vm, vector);
+ if (plan.result.size() != 1 || !plan.result[0]) {
+ dataLogLn("Module failed to compile correctly.");
+ CRASH();
+ }
+
+ // Test this doesn't crash.
+ RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 5);
+ }
+
+
+ {
+ // Generated from: (module (func "return-i32" (result i32) (return (i32.add (i32.const 5) (i32.const 6)))) )
+ Vector<uint8_t> vector = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x85, 0x80, 0x80,
+ 0x00, 0x01, 0x40, 0x00, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x82,
+ 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x8d, 0x80, 0x80, 0x00,
+ 0x01, 0x00, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x69, 0x33, 0x32, 0x04, 0x63, 0x6f,
+ 0x64, 0x65, 0x8e, 0x80, 0x80, 0x00, 0x01, 0x89, 0x80, 0x80, 0x00, 0x00, 0x10, 0x05, 0x10, 0x06,
+ 0x40, 0x09, 0x01, 0x0f
+ };
+
+ Plan plan(*vm, vector);
+ if (plan.result.size() != 1 || !plan.result[0]) {
+ dataLogLn("Module failed to compile correctly.");
+ CRASH();
+ }
+
+ // Test this doesn't crash.
+ RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ }
+
+ {
+ // Generated from: (module (func "return-i32" (result i32) (return (i32.add (i32.add (i32.const 5) (i32.const 3)) (i32.const 3)))) )
+ Vector<uint8_t> vector = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x85, 0x80, 0x80,
+ 0x00, 0x01, 0x40, 0x00, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x82,
+ 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x8d, 0x80, 0x80, 0x00,
+ 0x01, 0x00, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x69, 0x33, 0x32, 0x04, 0x63, 0x6f,
+ 0x64, 0x65, 0x91, 0x80, 0x80, 0x00, 0x01, 0x8c, 0x80, 0x80, 0x00, 0x00, 0x10, 0x05, 0x10, 0x03,
+ 0x40, 0x10, 0x03, 0x40, 0x09, 0x01, 0x0f
+ };
+
+ Plan plan(*vm, vector);
+ if (plan.result.size() != 1 || !plan.result[0]) {
+ dataLogLn("Module failed to compile correctly.");
+ CRASH();
+ }
+
+ // Test this doesn't crash.
+ RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ }
+
+ {
+ // Generated from: (module (func "return-i32" (result i32) (block (return (i32.add (i32.add (i32.const 5) (i32.const 3)) (i32.const 3))))) )
+ Vector<uint8_t> vector = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x85, 0x80, 0x80,
+ 0x00, 0x01, 0x40, 0x00, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x82,
+ 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x8d, 0x80, 0x80, 0x00,
+ 0x01, 0x00, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x69, 0x33, 0x32, 0x04, 0x63, 0x6f,
+ 0x64, 0x65, 0x93, 0x80, 0x80, 0x00, 0x01, 0x8e, 0x80, 0x80, 0x00, 0x00, 0x01, 0x10, 0x05, 0x10,
+ 0x03, 0x40, 0x10, 0x03, 0x40, 0x09, 0x01, 0x0f, 0x0f
+ };
+
+ Plan plan(*vm, vector);
+ if (plan.result.size() != 1 || !plan.result[0]) {
+ dataLogLn("Module failed to compile correctly.");
+ CRASH();
+ }
+
+ // Test this doesn't crash.
+ RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ }
+}
+
+#endif // ENABLE(WEBASSEMBLY)
+
int main(int argc, char** argv)
{
CommandLine options(argc, argv);
@@ -181,6 +301,18 @@
if (options.m_runLEBTests)
runLEBTests();
+
+ if (options.m_runWASMTests) {
+#if ENABLE(WEBASSEMBLY)
+ JSC::initializeThreading();
+ vm = &JSC::VM::create(JSC::LargeHeap).leakRef();
+ runWASMTests();
+#else
+ dataLogLn("WASM is not enabled!");
+ return EXIT_FAILURE;
+#endif // ENABLE(WEBASSEMBLY)
+ }
+
return EXIT_SUCCESS;
}
Modified: trunk/Source/_javascript_Core/wasm/JSWASMModule.h (204483 => 204484)
--- trunk/Source/_javascript_Core/wasm/JSWASMModule.h 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/_javascript_Core/wasm/JSWASMModule.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -79,7 +79,7 @@
Vector<WASMSignature>& signatures() { return m_signatures; }
Vector<WASMFunctionImport>& functionImports() { return m_functionImports; }
Vector<WASMFunctionImportSignature>& functionImportSignatures() { return m_functionImportSignatures; }
- Vector<WASMType>& globalVariableTypes() { return m_globalVariableTypes; }
+ Vector<WASMValueType>& globalVariableTypes() { return m_globalVariableTypes; }
Vector<WASMFunctionDeclaration>& functionDeclarations() { return m_functionDeclarations; }
Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; }
@@ -99,7 +99,7 @@
Vector<WASMSignature> m_signatures;
Vector<WASMFunctionImport> m_functionImports;
Vector<WASMFunctionImportSignature> m_functionImportSignatures;
- Vector<WASMType> m_globalVariableTypes;
+ Vector<WASMValueType> m_globalVariableTypes;
Vector<WASMFunctionDeclaration> m_functionDeclarations;
Vector<WASMFunctionPointerTable> m_functionPointerTables;
Added: trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 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 "WASMB3IRGenerator.h"
+
+#include "B3BasicBlockInlines.h"
+#include "B3ValueInlines.h"
+#include "B3Variable.h"
+#include "B3VariableValue.h"
+#include "WASMFunctionParser.h"
+#include <wtf/Optional.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+using namespace B3;
+
+class B3IRGenerator {
+public:
+ typedef Value* ExpressionType;
+
+ B3IRGenerator(Procedure&);
+
+ void addLocal(WASMValueType, uint32_t);
+ ExpressionType addConstant(WASMValueType, uint64_t);
+
+ bool WARN_UNUSED_RETURN binaryOp(WASMBinaryOpType, ExpressionType left, ExpressionType right, ExpressionType& result);
+
+ bool WARN_UNUSED_RETURN addBlock();
+ bool WARN_UNUSED_RETURN endBlock(Vector<ExpressionType>& expressionStack);
+ bool WARN_UNUSED_RETURN addReturn(const Vector<ExpressionType, 1>& returnValues);
+
+private:
+ Optional<Vector<Variable*>>& stackForControlLevel(unsigned);
+ BasicBlock* blockForControlLevel(unsigned);
+ void unify(Variable* target, const ExpressionType source);
+ Vector<Variable*> initializeIncommingTypes(BasicBlock*, const Vector<ExpressionType>&);
+ void unifyValuesWithLevel(const Vector<ExpressionType>& resultStack, unsigned);
+
+ Procedure& m_proc;
+ BasicBlock* m_currentBlock;
+ // This is a pair of the continuation and the types expected on the stack for that continuation.
+ Vector<std::pair<BasicBlock*, Optional<Vector<Variable*>>>> m_controlStack;
+};
+
+B3IRGenerator::B3IRGenerator(Procedure& procedure)
+ : m_proc(procedure)
+{
+ m_currentBlock = m_proc.addBlock();
+}
+
+void B3IRGenerator::addLocal(WASMValueType, uint32_t)
+{
+ // TODO: Add locals.
+}
+
+bool B3IRGenerator::binaryOp(WASMBinaryOpType op, ExpressionType left, ExpressionType right, ExpressionType& result)
+{
+ switch (op) {
+ case WASMBinaryOpType::I32Add: {
+ ASSERT(left->type() == B3::Int32 && right->type() == B3::Int32);
+ result = m_currentBlock->appendNew<Value>(m_proc, Add, Origin(), left, right);
+ return true;
+ }
+ }
+}
+
+B3IRGenerator::ExpressionType B3IRGenerator::addConstant(WASMValueType type, uint64_t value)
+{
+ switch (type) {
+ case WASMValueType::I32:
+ return m_currentBlock->appendNew<Const32Value>(m_proc, Origin(), static_cast<int32_t>(value));
+ case WASMValueType::I64:
+ return m_currentBlock->appendNew<Const64Value>(m_proc, Origin(), value);
+ case WASMValueType::F32:
+ return m_currentBlock->appendNew<ConstFloatValue>(m_proc, Origin(), bitwise_cast<float>(static_cast<int32_t>(value)));
+ case WASMValueType::F64:
+ return m_currentBlock->appendNew<ConstDoubleValue>(m_proc, Origin(), bitwise_cast<double>(value));
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+}
+
+bool B3IRGenerator::addBlock()
+{
+ m_controlStack.append(std::make_pair(m_proc.addBlock(), Nullopt));
+ return true;
+}
+
+bool B3IRGenerator::endBlock(Vector<ExpressionType>& expressionStack)
+{
+ // This means that we are exiting the function.
+ if (!m_controlStack.size()) {
+ // FIXME: Should this require the stack is empty? It's not clear from the current spec.
+ return !expressionStack.size();
+ }
+
+ unifyValuesWithLevel(expressionStack, 0);
+
+ m_currentBlock = m_controlStack.takeLast().first;
+ return true;
+}
+
+bool B3IRGenerator::addReturn(const Vector<ExpressionType, 1>& returnValues)
+{
+ ASSERT(returnValues.size() <= 1);
+ if (returnValues.size())
+ m_currentBlock->appendNewControlValue(m_proc, B3::Return, Origin(), returnValues[0]);
+ else
+ m_currentBlock->appendNewControlValue(m_proc, B3::Return, Origin());
+ return true;
+}
+
+void B3IRGenerator::unify(Variable* variable, ExpressionType source)
+{
+ m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), variable, source);
+}
+
+Vector<Variable*> B3IRGenerator::initializeIncommingTypes(BasicBlock* block, const Vector<ExpressionType>& source)
+{
+ Vector<Variable*> result;
+ result.reserveInitialCapacity(source.size());
+ for (ExpressionType expr : source) {
+ ASSERT(expr->type() != Void);
+ Variable* var = m_proc.addVariable(expr->type());
+ result.append(var);
+ block->appendNew<VariableValue>(m_proc, B3::Get, Origin(), var);
+ }
+
+ return result;
+}
+
+void B3IRGenerator::unifyValuesWithLevel(const Vector<ExpressionType>& resultStack, unsigned level)
+{
+ ASSERT(level < m_controlStack.size());
+
+ Optional<Vector<Variable*>>& expectedStack = stackForControlLevel(level);
+ if (!expectedStack) {
+ expectedStack = initializeIncommingTypes(blockForControlLevel(level), resultStack);
+ return;
+ }
+
+ ASSERT(expectedStack.value().size() != resultStack.size());
+
+ for (size_t i = 0; i < resultStack.size(); ++i)
+ unify(expectedStack.value()[i], resultStack[i]);
+}
+
+Optional<Vector<Variable*>>& B3IRGenerator::stackForControlLevel(unsigned level)
+{
+ return m_controlStack[m_controlStack.size() - 1 - level].second;
+}
+
+BasicBlock* B3IRGenerator::blockForControlLevel(unsigned level)
+{
+ return m_controlStack[m_controlStack.size() - 1 - level].first;
+}
+
+std::unique_ptr<Compilation> parseAndCompile(VM& vm, Vector<uint8_t>& source, WASMFunctionInformation info, unsigned optLevel)
+{
+ Procedure procedure;
+ B3IRGenerator context(procedure);
+ WASMFunctionParser<B3IRGenerator> parser(context, source, info);
+ if (!parser.parse())
+ RELEASE_ASSERT_NOT_REACHED();
+
+ return std::make_unique<Compilation>(vm, procedure, optLevel);
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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
+
+#include "B3Compilation.h"
+#include "VM.h"
+#include "WASMFormat.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+std::unique_ptr<B3::Compilation> parseAndCompile(VM&, Vector<uint8_t>&, WASMFunctionInformation, unsigned optLevel = 1);
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WASMFormat.h (204483 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMFormat.h 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/_javascript_Core/wasm/WASMFormat.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -52,15 +52,17 @@
class JSFunction;
-enum class WASMType : uint8_t {
+enum class WASMValueType : uint8_t {
I32,
+ I64,
F32,
F64,
NumberOfTypes
};
-enum class WASMExpressionType : uint8_t {
+enum class WASMFunctionReturnType : uint8_t {
I32,
+ I64,
F32,
F64,
Void,
@@ -68,8 +70,8 @@
};
struct WASMSignature {
- WASMExpressionType returnType;
- Vector<WASMType> arguments;
+ WASMFunctionReturnType returnType;
+ Vector<WASMValueType> arguments;
};
struct WASMFunctionImport {
@@ -91,6 +93,11 @@
Vector<JSFunction*> functions;
};
+struct WASMFunctionInformation {
+ size_t start;
+ size_t end;
+};
+
} // namespace JSC
#endif // ENABLE(WEBASSEMBLY)
Added: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2016 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
+
+#include "WASMParser.h"
+#include <wtf/DataLog.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+template<typename Context>
+class WASMFunctionParser : public WASMParser {
+public:
+ typedef typename Context::ExpressionType ExpressionType;
+
+ WASMFunctionParser(Context&, const Vector<uint8_t>& sourceBuffer, const WASMFunctionInformation&);
+
+ bool WARN_UNUSED_RETURN parse();
+
+private:
+ static const bool verbose = false;
+
+ bool WARN_UNUSED_RETURN parseBlock();
+ bool WARN_UNUSED_RETURN parseExpression(WASMOpType);
+ bool WARN_UNUSED_RETURN unifyControl(Vector<ExpressionType>&, unsigned level);
+
+ Optional<Vector<ExpressionType>>& stackForControlLevel(unsigned level);
+
+ Context& m_context;
+ Vector<ExpressionType> m_expressionStack;
+};
+
+template<typename Context>
+WASMFunctionParser<Context>::WASMFunctionParser(Context& context, const Vector<uint8_t>& sourceBuffer, const WASMFunctionInformation& info)
+ : WASMParser(sourceBuffer, info.start, info.end)
+ , m_context(context)
+{
+}
+
+template<typename Context>
+bool WASMFunctionParser<Context>::parse()
+{
+ uint32_t localCount;
+ if (!parseVarUInt32(localCount))
+ return false;
+
+ for (uint32_t i = 0; i < localCount; ++i) {
+ uint32_t numberOfLocalsWithType;
+ if (!parseUInt32(numberOfLocalsWithType))
+ return false;
+
+ WASMValueType typeOfLocal;
+ if (!parseValueType(typeOfLocal))
+ return false;
+
+ m_context.addLocal(typeOfLocal, numberOfLocalsWithType);
+ }
+
+ return parseBlock();
+}
+
+template<typename Context>
+bool WASMFunctionParser<Context>::parseBlock()
+{
+ while (true) {
+ uint8_t op;
+ if (!parseUInt7(op))
+ return false;
+
+ if (!parseExpression(static_cast<WASMOpType>(op))) {
+ if (verbose)
+ dataLogLn("failed to process op:", op);
+ return false;
+ }
+
+ if (op == WASMOpType::End)
+ break;
+ }
+
+ return true;
+}
+
+template<typename Context>
+bool WASMFunctionParser<Context>::parseExpression(WASMOpType op)
+{
+ switch (op) {
+#define CREATE_CASE(name, value) case name:
+ FOR_EACH_WASM_BINARY_OP(CREATE_CASE) {
+#undef CREATE_CASE
+ ExpressionType left = m_expressionStack.takeLast();
+ ExpressionType right = m_expressionStack.takeLast();
+ ExpressionType result;
+ if (!m_context.binaryOp(static_cast<WASMBinaryOpType>(op), left, right, result))
+ return false;
+ m_expressionStack.append(result);
+ return true;
+ }
+
+ case WASMOpType::I32Const: {
+ uint32_t constant;
+ if (!parseVarUInt32(constant))
+ return false;
+ m_expressionStack.append(m_context.addConstant(WASMValueType::I32, constant));
+ return true;
+ }
+
+ case WASMOpType::Block: {
+ if (!m_context.addBlock())
+ return false;
+ return parseBlock();
+ }
+
+ case WASMOpType::Return: {
+ uint8_t returnCount;
+ if (!parseVarUInt1(returnCount))
+ return false;
+ Vector<ExpressionType, 1> returnValues;
+ if (returnCount)
+ returnValues.append(m_expressionStack.takeLast());
+
+ return m_context.addReturn(returnValues);
+ }
+
+ case WASMOpType::End:
+ return m_context.endBlock(m_expressionStack);
+
+ }
+
+ // Unknown opcode.
+ return false;
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Added: trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2016 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 "WASMModuleParser.h"
+
+#include "WASMFormat.h"
+#include "WASMOps.h"
+#include "WASMSections.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+static const bool verbose = false;
+
+bool WASMModuleParser::parse()
+{
+ if (m_sourceLength < 8)
+ return false;
+ if (!consumeCharacter(0))
+ return false;
+ if (!consumeString("asm"))
+ return false;
+
+ // Skip the version number for now since we don't do anything with it.
+ uint32_t versionNumber;
+ if (!parseUInt32(versionNumber))
+ return false;
+
+ if (versionNumber != magicNumber)
+ return false;
+
+
+ if (verbose)
+ dataLogLn("Passed processing header.");
+
+ WASMSections::Section previousSection = WASMSections::Section::Unknown;
+ while (m_offset < m_sourceLength) {
+ if (verbose)
+ dataLogLn("Starting to parse next section at offset: ", m_offset);
+ uint32_t sectionNameLength;
+ if (!parseVarUInt32(sectionNameLength))
+ return false;
+
+ // Make sure we can read up to the section's size.
+ if (m_offset + sectionNameLength + maxLEBByteLength >= m_sourceLength)
+ return false;
+
+ WASMSections::Section section = WASMSections::lookup(m_source.data() + m_offset, sectionNameLength);
+ if (!WASMSections::validateOrder(previousSection, section))
+ return false;
+ m_offset += sectionNameLength;
+
+ uint32_t sectionLength;
+ if (!parseVarUInt32(sectionLength))
+ return false;
+
+ unsigned end = m_offset + sectionLength;
+
+ switch (section) {
+ case WASMSections::Section::End:
+ return true;
+
+ case WASMSections::Section::FunctionTypes: {
+ if (verbose)
+ dataLogLn("Parsing types.");
+ if (!parseFunctionTypes())
+ return false;
+ break;
+ }
+
+ case WASMSections::Section::Signatures: {
+ if (verbose)
+ dataLogLn("Parsing function signatures.");
+ if (!parseFunctionSignatures())
+ return false;
+ break;
+ }
+
+ case WASMSections::Section::Definitions: {
+ if (verbose)
+ dataLogLn("Parsing function definitions.");
+ if (!parseFunctionDefinitions())
+ return false;
+ break;
+ }
+
+ case WASMSections::Section::Unknown: {
+ if (verbose)
+ dataLogLn("Unknown section, skipping.");
+ m_offset += sectionLength;
+ break;
+ }
+ }
+
+ if (verbose)
+ dataLogLn("Finished parsing section.");
+
+ if (end != m_offset)
+ return false;
+
+ previousSection = section;
+ }
+
+ // TODO
+ return true;
+}
+
+bool WASMModuleParser::parseFunctionTypes()
+{
+ uint32_t count;
+ if (!parseVarUInt32(count))
+ return false;
+
+ if (verbose)
+ dataLogLn("count: ", count);
+
+ for (uint32_t i = 0; i < count; ++i) {
+ uint8_t type;
+ if (!parseUInt7(type))
+ return false;
+ if (type != 0x40) // Function type constant.
+ return false;
+
+ if (verbose)
+ dataLogLn("Got function type.");
+
+ uint32_t argumentCount;
+ if (!parseVarUInt32(argumentCount))
+ return false;
+
+ if (verbose)
+ dataLogLn("argumentCount: ", argumentCount);
+
+ Vector<WASMValueType> argumentTypes;
+ for (unsigned i = 0; i < argumentCount; ++i) {
+ if (!parseUInt7(type) || type >= static_cast<uint8_t>(WASMValueType::NumberOfTypes))
+ return false;
+ argumentTypes.append(static_cast<WASMValueType>(type));
+ }
+
+ if (!parseVarUInt1(type))
+ return false;
+ WASMFunctionReturnType returnType;
+
+ if (verbose)
+ dataLogLn(type);
+
+ if (type) {
+ WASMValueType value;
+ if (!parseValueType(value))
+ return false;
+ returnType = static_cast<WASMFunctionReturnType>(value);
+ } else
+ returnType = WASMFunctionReturnType::Void;
+
+ // TODO: Actually do something with this data...
+ }
+ return true;
+}
+
+bool WASMModuleParser::parseFunctionSignatures()
+{
+ uint32_t count;
+ if (!parseVarUInt32(count))
+ return false;
+
+ m_functions.resize(count);
+
+ for (uint32_t i = 0; i < count; ++i) {
+ uint32_t typeNumber;
+ if (!parseVarUInt32(typeNumber))
+ return false;
+ }
+
+ return true;
+}
+
+bool WASMModuleParser::parseFunctionDefinitions()
+{
+ uint32_t count;
+ if (!parseVarUInt32(count))
+ return false;
+
+ if (count != m_functions.size())
+ return false;
+
+ for (uint32_t i = 0; i < count; ++i) {
+ uint32_t functionSize;
+ if (!parseVarUInt32(functionSize))
+ return false;
+
+ WASMFunctionInformation& info = m_functions[i];
+ info.start = m_offset;
+ info.end = m_offset + functionSize;
+ m_offset = info.end;
+ }
+
+ return true;
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 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
+
+#include "WASMOps.h"
+#include "WASMParser.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+class WASMModuleParser : public WASMParser {
+public:
+
+ static const unsigned magicNumber = 0xc;
+
+ WASMModuleParser(const Vector<uint8_t>& sourceBuffer)
+ : WASMParser(sourceBuffer, 0, sourceBuffer.size())
+ {
+ }
+
+ bool WARN_UNUSED_RETURN parse();
+
+ const Vector<WASMFunctionInformation>& functionInformation() { return m_functions; }
+
+private:
+ bool WARN_UNUSED_RETURN parseFunctionTypes();
+ bool WARN_UNUSED_RETURN parseFunctionSignatures();
+ bool WARN_UNUSED_RETURN parseFunctionDefinitions();
+ bool WARN_UNUSED_RETURN parseFunctionDefinition(uint32_t number);
+ bool WARN_UNUSED_RETURN parseBlock();
+ bool WARN_UNUSED_RETURN parseExpression(WASMOpType);
+
+ Vector<WASMFunctionInformation> m_functions;
+};
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMOps.h (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMOps.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMOps.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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)
+
+namespace JSC {
+
+namespace WASM {
+
+#define FOR_EACH_WASM_SPECIAL_OP(macro) \
+ macro(I32Const, 0x10)
+
+#define FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
+ macro(Block, 0x01) \
+ macro(Return, 0x09) \
+ macro(End, 0x0f)
+
+#define FOR_EACH_WASM_UNARY_OP(macro)
+
+#define FOR_EACH_WASM_BINARY_OP(macro) \
+ macro(I32Add, 0x40)
+
+#define FOR_EACH_WASM_OP(macro) \
+ FOR_EACH_WASM_SPECIAL_OP(macro) \
+ FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
+ FOR_EACH_WASM_UNARY_OP(macro) \
+ FOR_EACH_WASM_BINARY_OP(macro)
+
+#define CREATE_ENUM_VALUE(name, id) name = id,
+
+enum WASMOpType : uint8_t {
+ FOR_EACH_WASM_OP(CREATE_ENUM_VALUE)
+};
+
+
+
+enum class WASMBinaryOpType : uint8_t {
+ FOR_EACH_WASM_BINARY_OP(CREATE_ENUM_VALUE)
+};
+
+} // namespace WASM
+
+} // namespace JSC
+
+#undef CREATE_ENUM_VALUE
+
+#endif // ENABLE(WEBASSEMBLY)
Added: trunk/Source/_javascript_Core/wasm/WASMParser.h (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMParser.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMParser.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 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
+
+#include "B3Compilation.h"
+#include "B3Procedure.h"
+#include "WASMFormat.h"
+#include "WASMOps.h"
+#include "WASMSections.h"
+#include <wtf/LEBDecoder.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+class WASMParser {
+protected:
+ WASMParser(const Vector<uint8_t>&, size_t start, size_t end);
+
+ bool WARN_UNUSED_RETURN consumeCharacter(char);
+ bool WARN_UNUSED_RETURN consumeString(const char*);
+
+ bool WARN_UNUSED_RETURN parseVarUInt1(uint8_t& result);
+ bool WARN_UNUSED_RETURN parseUInt7(uint8_t& result);
+ bool WARN_UNUSED_RETURN parseUInt32(uint32_t& result);
+ bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t& result) { return decodeUInt32(m_source.data(), m_sourceLength, m_offset, result); }
+
+
+ bool WARN_UNUSED_RETURN parseValueType(WASMValueType& result);
+
+ const Vector<uint8_t>& m_source;
+ size_t m_sourceLength;
+ size_t m_offset;
+};
+
+ALWAYS_INLINE WASMParser::WASMParser(const Vector<uint8_t>& sourceBuffer, size_t start, size_t end)
+ : m_source(sourceBuffer)
+ , m_sourceLength(end)
+ , m_offset(start)
+{
+ ASSERT(end <= sourceBuffer.size());
+ ASSERT(start < end);
+}
+
+ALWAYS_INLINE bool WASMParser::consumeCharacter(char c)
+{
+ if (m_offset >= m_sourceLength)
+ return false;
+ if (c == m_source[m_offset]) {
+ m_offset++;
+ return true;
+ }
+ return false;
+}
+
+ALWAYS_INLINE bool WASMParser::consumeString(const char* str)
+{
+ unsigned start = m_offset;
+ for (unsigned i = 0; str[i]; i++) {
+ if (!consumeCharacter(str[i])) {
+ m_offset = start;
+ return false;
+ }
+ }
+ return true;
+}
+
+ALWAYS_INLINE bool WASMParser::parseUInt32(uint32_t& result)
+{
+ if (m_offset + 4 >= m_sourceLength)
+ return false;
+ result = *reinterpret_cast<const uint32_t*>(m_source.data() + m_offset);
+ m_offset += 4;
+ return true;
+}
+
+ALWAYS_INLINE bool WASMParser::parseUInt7(uint8_t& result)
+{
+ if (m_offset >= m_sourceLength)
+ return false;
+ result = m_source[m_offset++];
+ return result < 0x80;
+}
+
+ALWAYS_INLINE bool WASMParser::parseVarUInt1(uint8_t& result)
+{
+ uint32_t temp;
+ if (!parseVarUInt32(temp))
+ return false;
+ result = static_cast<uint8_t>(temp);
+ return temp <= 1;
+}
+
+ALWAYS_INLINE bool WASMParser::parseValueType(WASMValueType& result)
+{
+ uint8_t value;
+ if (!parseUInt7(value))
+ return false;
+ if (value >= static_cast<uint8_t>(WASMValueType::NumberOfTypes))
+ return false;
+ result = static_cast<WASMValueType>(value);
+ return true;
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMPlan.cpp (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMPlan.cpp (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMPlan.cpp 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 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 "WASMPlan.h"
+
+#include "B3Compilation.h"
+#include "WASMB3IRGenerator.h"
+#include "WASMModuleParser.h"
+#include <wtf/DataLog.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+static const bool verbose = false;
+
+Plan::Plan(VM& vm, Vector<uint8_t> source)
+{
+ if (verbose)
+ dataLogLn("Starting plan.");
+ WASMModuleParser moduleParser(source);
+ if (!moduleParser.parse()) {
+ dataLogLn("Parsing module failed.");
+ return;
+ }
+
+ if (verbose)
+ dataLogLn("Parsed module.");
+
+ for (const WASMFunctionInformation& info : moduleParser.functionInformation()) {
+ if (verbose)
+ dataLogLn("Processing funcion starting at: ", info.start, " and ending at: ", info.end);
+ result.append(parseAndCompile(vm, source, info));
+ }
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMPlan.h (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMPlan.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMPlan.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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
+
+#include "CompilationResult.h"
+#include "VM.h"
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace B3 {
+class Compilation;
+} // namespace B3
+
+namespace WASM {
+
+// TODO: This should create a WASM Module not a list of functions.
+class Plan {
+public:
+ JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t> source);
+
+ Vector<std::unique_ptr<B3::Compilation>> result;
+};
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMSections.cpp (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMSections.cpp (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMSections.cpp 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 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 "WASMSections.h"
+
+#include <wtf/DataLog.h>
+#include <wtf/text/WTFString.h>
+
+#if ENABLE(WEBASSEMBLY)
+
+namespace JSC {
+
+namespace WASM {
+
+struct SectionData {
+ unsigned length;
+ const char* name;
+};
+
+static const bool verbose = false;
+
+static const unsigned sectionDataLength = static_cast<unsigned>(WASMSections::Section::Unknown);
+static const SectionData sectionData[sectionDataLength] {
+#define CREATE_SECTION_DATA(name, str) { sizeof(str) - 1, str },
+ FOR_EACH_WASM_SECTION_TYPE(CREATE_SECTION_DATA)
+#undef CREATE_SECTION_DATA
+};
+
+WASMSections::Section WASMSections::lookup(const uint8_t* name, unsigned length)
+{
+ if (verbose)
+ dataLogLn("Decoding section with name: ", String(name, length));
+ for (unsigned i = 0; i < sectionDataLength; ++i) {
+ if (sectionData[i].length != length)
+ continue;
+ if (!memcmp(name, sectionData[i].name, length))
+ return static_cast<WASMSections::Section>(i);
+ }
+ return WASMSections::Section::Unknown;
+}
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Copied: trunk/Source/_javascript_Core/wasm/WASMSections.h (from rev 204483, trunk/Source/WTF/wtf/DataLog.h) (0 => 204484)
--- trunk/Source/_javascript_Core/wasm/WASMSections.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMSections.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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)
+
+namespace JSC {
+
+namespace WASM {
+
+// These should be in the order that we expect them to be in the binary.
+#define FOR_EACH_WASM_SECTION_TYPE(macro) \
+ macro(FunctionTypes, "type") \
+ macro(Signatures, "function") \
+ macro(Definitions, "code") \
+ macro(End, "end")
+
+struct WASMSections {
+ enum class Section {
+#define CREATE_SECTION_ENUM(name, str) name,
+ FOR_EACH_WASM_SECTION_TYPE(CREATE_SECTION_ENUM)
+#undef CREATE_SECTION_ENUM
+ Unknown
+ };
+ static Section lookup(const uint8_t*, unsigned);
+ static bool validateOrder(Section previous, Section next)
+ {
+ // This allows unknown sections after End, which I doubt will ever be supported but
+ // there is no reason to potentially break backwards compatability.
+ if (previous == Section::Unknown)
+ return true;
+ return previous < next;
+ }
+};
+
+} // namespace WASM
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/WTF/ChangeLog (204483 => 204484)
--- trunk/Source/WTF/ChangeLog 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/WTF/ChangeLog 2016-08-15 21:35:07 UTC (rev 204484)
@@ -1,3 +1,18 @@
+2016-08-15 Keith Miller <[email protected]>
+
+ Implement WASM Parser and B3 IR generator
+ https://bugs.webkit.org/show_bug.cgi?id=160681
+
+ Reviewed by Benjamin Poulain.
+
+ * wtf/DataLog.h:
+ (WTF::dataLogLn): Add a new dataLog function, dataLogLn that
+ automagically includes a new line at the end of the print.
+ * wtf/LEBDecoder.h:
+ (decodeUInt32):
+ (decodeInt32): Change the LEBDecoder to take a pointer and length
+ rather than a Vector.
+
2016-08-15 Keith Rollin <[email protected]>
Rename LOG_ALWAYS
Modified: trunk/Source/WTF/wtf/DataLog.h (204483 => 204484)
--- trunk/Source/WTF/wtf/DataLog.h 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/WTF/wtf/DataLog.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -45,9 +45,16 @@
dataFile().print(values...);
}
+template<typename... Types>
+void dataLogLn(const Types&... values)
+{
+ dataFile().print(values..., "\n");
+}
+
} // namespace WTF
using WTF::dataLog;
+using WTF::dataLogLn;
using WTF::dataLogF;
using WTF::dataLogFString;
Modified: trunk/Source/WTF/wtf/LEBDecoder.h (204483 => 204484)
--- trunk/Source/WTF/wtf/LEBDecoder.h 2016-08-15 21:23:32 UTC (rev 204483)
+++ trunk/Source/WTF/wtf/LEBDecoder.h 2016-08-15 21:35:07 UTC (rev 204484)
@@ -26,11 +26,8 @@
#pragma once
#include "Compiler.h"
-#include "Vector.h"
#include <algorithm>
-#include "DataLog.h"
-
// This file contains a bunch of helper functions for decoding LEB numbers.
// See https://en.wikipedia.org/wiki/LEB128 for more information about the
// LEB format.
@@ -37,12 +34,12 @@
const size_t maxLEBByteLength = 5;
-inline bool WARN_UNUSED_RETURN decodeUInt32(const Vector<uint8_t>& bytes, size_t& offset, uint32_t& result)
+inline bool WARN_UNUSED_RETURN decodeUInt32(const uint8_t* bytes, size_t length, size_t& offset, uint32_t& result)
{
- ASSERT(bytes.size() > offset);
+ ASSERT(length > offset);
result = 0;
unsigned shift = 0;
- size_t last = std::min(maxLEBByteLength, bytes.size() - offset - 1);
+ size_t last = std::min(maxLEBByteLength, length - offset - 1);
for (unsigned i = 0; true; ++i) {
uint8_t byte = bytes[offset++];
result |= (byte & 0x7f) << shift;
@@ -56,12 +53,12 @@
return true;
}
-inline bool WARN_UNUSED_RETURN decodeInt32(const Vector<uint8_t>& bytes, size_t& offset, int32_t& result)
+inline bool WARN_UNUSED_RETURN decodeInt32(const uint8_t* bytes, size_t length, size_t& offset, int32_t& result)
{
- ASSERT(bytes.size() > offset);
+ ASSERT(length > offset);
result = 0;
unsigned shift = 0;
- size_t last = std::min(maxLEBByteLength, bytes.size() - offset - 1);
+ size_t last = std::min(maxLEBByteLength, length - offset - 1);
uint8_t byte;
for (unsigned i = 0; true; ++i) {
byte = bytes[offset++];