| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +158 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2015-07-10  Sukolsak Sakshuwong  <sukolsak@gmail.com>
2
3
        JSC should natively support WebAssembly
4
        https://bugs.webkit.org/show_bug.cgi?id=146064
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * JavaScriptCore.xcodeproj/project.pbxproj:
9
        * bytecode/CodeBlock.cpp:
10
        (JSC::CodeBlock::CodeBlock):
11
        (JSC::WebAssemblyCodeBlock::replacement):
12
        (JSC::WebAssemblyCodeBlock::capabilityLevelInternal):
13
        * bytecode/CodeBlock.h:
14
        (JSC::WebAssemblyCodeBlock::WebAssemblyCodeBlock):
15
        * jit/JITOperations.cpp:
16
        * jsc.cpp:
17
        (GlobalObject::finishCreation):
18
        (functionLoadWebAssembly):
19
        * llint/LLIntSlowPaths.cpp:
20
        (JSC::LLInt::setUpCall):
21
        * runtime/Executable.cpp:
22
        (JSC::ScriptExecutable::installCode):
23
        (JSC::ScriptExecutable::newCodeBlockFor):
24
        (JSC::ScriptExecutable::prepareForExecutionImpl):
25
        (JSC::WebAssemblyExecutable::WebAssemblyExecutable):
26
        (JSC::WebAssemblyExecutable::finishCreation):
27
        (JSC::WebAssemblyExecutable::destroy):
28
        (JSC::WebAssemblyExecutable::baselineCodeBlockFor):
29
        (JSC::WebAssemblyExecutable::visitChildren):
30
        (JSC::WebAssemblyExecutable::symbolTable):
31
        (JSC::WebAssemblyExecutable::clearCode):
32
        (JSC::WebAssemblyExecutable::unlinkCalls):
33
        * runtime/Executable.h:
34
        (JSC::ExecutableBase::isWebAssemblyExecutable):
35
        * runtime/JSFunction.cpp:
36
        (JSC::JSFunction::create):
37
        * runtime/JSFunction.h:
38
        (JSC::JSFunction::createImpl):
39
        * runtime/JSFunctionInlines.h:
40
        (JSC::JSFunction::JSFunction):
41
        (JSC::JSFunction::isHostFunction):
42
        * runtime/JSType.h:
43
        * runtime/VM.cpp:
44
        (JSC::VM::VM):
45
        * runtime/VM.h:
46
        * wasm/WasmJITCompiler.cpp: Added.
47
        (JSC::Wasm::JumpScope::JumpScope):
48
        (JSC::Wasm::JumpScope::jump):
49
        (JSC::Wasm::JumpScope::link):
50
        (JSC::Wasm::JITCompiler::compileFunction):
51
        (JSC::Wasm::JITCompiler::allocateSpaceOnStack):
52
        (JSC::Wasm::JITCompiler::deallocateSpaceOnStack):
53
        (JSC::Wasm::JITCompiler::parseArguments):
54
        (JSC::Wasm::JITCompiler::parseVars):
55
        (JSC::Wasm::JITCompiler::parseStmt):
56
        (JSC::Wasm::JITCompiler::parseGetLocal):
57
        (JSC::Wasm::JITCompiler::parseSetLocal):
58
        (JSC::Wasm::JITCompiler::parseReturnStmt):
59
        (JSC::Wasm::JITCompiler::parseStmtList):
60
        (JSC::Wasm::JITCompiler::parseBlockStmt):
61
        (JSC::Wasm::JITCompiler::parseIfStmt):
62
        (JSC::Wasm::JITCompiler::parseIfElseStmt):
63
        (JSC::Wasm::JITCompiler::parseWhileStmt):
64
        (JSC::Wasm::JITCompiler::parseDoStmt):
65
        (JSC::Wasm::JITCompiler::parseLabelStmt):
66
        (JSC::Wasm::JITCompiler::parseBreakStmt):
67
        (JSC::Wasm::JITCompiler::parseBreakLabelStmt):
68
        (JSC::Wasm::JITCompiler::parseContinueStmt):
69
        (JSC::Wasm::JITCompiler::parseContinueLabelStmt):
70
        (JSC::Wasm::JITCompiler::parseSwitchStmt):
71
        (JSC::Wasm::JITCompiler::parseExpr):
72
        (JSC::Wasm::JITCompiler::parseExprI32):
73
        (JSC::Wasm::JITCompiler::parseExprF64):
74
        (JSC::Wasm::getInternalFunction):
75
        (JSC::Wasm::JITCompiler::parseCallInternal):
76
        (JSC::Wasm::getImportedFunction):
77
        (JSC::Wasm::JITCompiler::parseCallImport):
78
        (JSC::Wasm::JITCompiler::callFunctionSlowCase):
79
        (JSC::Wasm::JITCompiler::parseCallArguments):
80
        (JSC::Wasm::JITCompiler::parseBinaryOp):
81
        (JSC::Wasm::JITCompiler::parseUnaryOp):
82
        (JSC::Wasm::JITCompiler::parseRelationalOpI32):
83
        (JSC::Wasm::JITCompiler::parseRelationalOpF64):
84
        (JSC::Wasm::JITCompiler::parseComma):
85
        (JSC::Wasm::JITCompiler::parseCond):
86
        * wasm/WasmJITCompiler.h: Added.
87
        (JSC::Wasm::JITCompiler::JITCompiler):
88
        (JSC::Wasm::JITCompiler::stackAddress):
89
        (JSC::Wasm::JITCompiler::temporaryAddress):
90
        (JSC::Wasm::JITCompiler::pushContinueLabelLabel):
91
        (JSC::Wasm::JITCompiler::popContinueLabelLabel):
92
        (JSC::Wasm::JITCompiler::continueLabelLabel):
93
        (JSC::Wasm::JITCompiler::pushBreakLabelJumpList):
94
        (JSC::Wasm::JITCompiler::popBreakLabelJumpList):
95
        (JSC::Wasm::JITCompiler::breakLabelJumpList):
96
        (JSC::Wasm::JITCompiler::pushContinueJumpScope):
97
        (JSC::Wasm::JITCompiler::popContinueJumpScope):
98
        (JSC::Wasm::JITCompiler::topContinueJumpScope):
99
        (JSC::Wasm::JITCompiler::pushBreakJumpList):
100
        (JSC::Wasm::JITCompiler::popBreakJumpList):
101
        (JSC::Wasm::JITCompiler::topBreakJumpList):
102
        * wasm/WasmModule.cpp: Added.
103
        (JSC::Wasm::Module::compile):
104
        (JSC::Wasm::Module::parseConstantPoolSection):
105
        (JSC::Wasm::Module::parseSignatureSection):
106
        (JSC::Wasm::Module::parseFunctionImportSection):
107
        (JSC::Wasm::Module::parseGlobalSection):
108
        (JSC::Wasm::Module::parseFunctionDeclarationSection):
109
        (JSC::Wasm::Module::parseFunctionPointerTables):
110
        (JSC::Wasm::Module::parseFunctionDefinitionSection):
111
        (JSC::Wasm::Module::parseExportSection):
112
        (JSC::Wasm::Module::parseFunctionDefinition):
113
        (JSC::Wasm::Module::internalFunction):
114
        (JSC::Wasm::Module::visitChildren):
115
        (JSC::Wasm::compile):
116
        * wasm/WasmModule.h: Added.
117
        (JSC::Wasm::Module::Module):
118
        (JSC::Wasm::Module::create):
119
        (JSC::Wasm::Module::createStructure):
120
        (JSC::Wasm::Module::functionImportName):
121
        * wasm/WasmOpcodes.h: Added.
122
        (JSC::Wasm::operator| ):
123
        (JSC::Wasm::operator&):
124
        (JSC::Wasm::Expr::Expr):
125
        (JSC::Wasm::Expr::type):
126
        (JSC::Wasm::Expr::i32):
127
        (JSC::Wasm::Expr::f32):
128
        (JSC::Wasm::Expr::f64):
129
        (JSC::Wasm::Expr::operator==):
130
        (JSC::Wasm::Expr::operator!=):
131
        (JSC::Wasm::PackOpWithImm):
132
        (JSC::Wasm::UnpackOpWithImm):
133
        (JSC::Wasm::ExprWithImm::ExprWithImm):
134
        (JSC::Wasm::ExprWithImm::type):
135
        (JSC::Wasm::ExprWithImm::i32):
136
        (JSC::Wasm::ExprWithImm::f32):
137
        (JSC::Wasm::ExprWithImm::f64):
138
        (JSC::Wasm::Signature::Signature):
139
        (JSC::Wasm::Signature::operator==):
140
        (JSC::Wasm::Signature::operator!=):
141
        (JSC::Wasm::Signature::Hash::operator()):
142
        (JSC::Wasm::Reader::Reader):
143
        (JSC::Wasm::Reader::stmt):
144
        (JSC::Wasm::Reader::switchCase):
145
        (JSC::Wasm::Reader::voidExpr):
146
        (JSC::Wasm::Reader::exportFormat):
147
        (JSC::Wasm::Reader::type):
148
        (JSC::Wasm::Reader::rtype):
149
        (JSC::Wasm::Reader::singleChar):
150
        (JSC::Wasm::Reader::u8):
151
        (JSC::Wasm::Reader::fixedWidth<uint32_t>):
152
        (JSC::Wasm::Reader::fixedWidth<float>):
153
        (JSC::Wasm::Reader::fixedWidth<double>):
154
        (JSC::Wasm::Reader::code):
155
        (JSC::Wasm::Reader::immU32):
156
        (JSC::Wasm::Reader::immS32):
157
        (JSC::Wasm::Reader::ifI32Lit):
158
1
2015-07-08  Joseph Pecoraro  <pecoraro@apple.com>
159
2015-07-08  Joseph Pecoraro  <pecoraro@apple.com>
2
160
3
        Fix grammar issue in TypeError attempting to change an unconfigurable property
161
        Fix grammar issue in TypeError attempting to change an unconfigurable property
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +28 lines
Lines 1020-1025 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
1020
		70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
1020
		70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
1021
		70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
1021
		70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
1022
		70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
1022
		70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
1023
		7BD10C421B4ED43C00BD541A /* WasmJITCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BD10C3D1B4ED43900BD541A /* WasmJITCompiler.cpp */; };
1024
		7BD10C431B4ED44000BD541A /* WasmJITCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD10C3E1B4ED43900BD541A /* WasmJITCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
1025
		7BD10C441B4ED44500BD541A /* WasmModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7BD10C3F1B4ED43900BD541A /* WasmModule.cpp */; };
1026
		7BD10C451B4ED44900BD541A /* WasmModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD10C401B4ED43900BD541A /* WasmModule.h */; settings = {ATTRIBUTES = (Private, ); }; };
1027
		7BD10C461B4ED44E00BD541A /* WasmOpcodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD10C411B4ED43900BD541A /* WasmOpcodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
1023
		7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
1028
		7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
1024
		7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
1029
		7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
1025
		7C008CE7187631B600955C24 /* Microtask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CE5187631B600955C24 /* Microtask.h */; settings = {ATTRIBUTES = (Private, ); }; };
1030
		7C008CE7187631B600955C24 /* Microtask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CE5187631B600955C24 /* Microtask.h */; settings = {ATTRIBUTES = (Private, ); }; };
Lines 2762-2767 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
2762
		70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
2767
		70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
2763
		70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
2768
		70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
2764
		70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
2769
		70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
2770
		7BD10C3D1B4ED43900BD541A /* WasmJITCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmJITCompiler.cpp; sourceTree = "<group>"; };
2771
		7BD10C3E1B4ED43900BD541A /* WasmJITCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmJITCompiler.h; sourceTree = "<group>"; };
2772
		7BD10C3F1B4ED43900BD541A /* WasmModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModule.cpp; sourceTree = "<group>"; };
2773
		7BD10C401B4ED43900BD541A /* WasmModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmModule.h; sourceTree = "<group>"; };
2774
		7BD10C411B4ED43900BD541A /* WasmOpcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOpcodes.h; sourceTree = "<group>"; };
2765
		7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
2775
		7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
2766
		7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = "<group>"; };
2776
		7C008CD9187124BB00955C24 /* JSPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseDeferred.h; sourceTree = "<group>"; };
2767
		7C008CE5187631B600955C24 /* Microtask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Microtask.h; sourceTree = "<group>"; };
2777
		7C008CE5187631B600955C24 /* Microtask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Microtask.h; sourceTree = "<group>"; };
Lines 3617-3622 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
3617
				7EF6E0BB0EB7A1EC0079AFAF /* runtime */,
3627
				7EF6E0BB0EB7A1EC0079AFAF /* runtime */,
3618
				141211000A48772600480255 /* tests */,
3628
				141211000A48772600480255 /* tests */,
3619
				8603CEF014C753EF00AE59E3 /* tools */,
3629
				8603CEF014C753EF00AE59E3 /* tools */,
3630
				7BD10C3C1B4ED41D00BD541A /* wasm */,
3620
				86EAC48C0F93E8B9008EC948 /* yarr */,
3631
				86EAC48C0F93E8B9008EC948 /* yarr */,
3621
			);
3632
			);
3622
			name = JavaScriptCore;
3633
			name = JavaScriptCore;
Lines 4279-4284 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
4279
			path = disassembler/ARMv7;
4290
			path = disassembler/ARMv7;
4280
			sourceTree = "<group>";
4291
			sourceTree = "<group>";
4281
		};
4292
		};
4293
		7BD10C3C1B4ED41D00BD541A /* wasm */ = {
4294
			isa = PBXGroup;
4295
			children = (
4296
				7BD10C3D1B4ED43900BD541A /* WasmJITCompiler.cpp */,
4297
				7BD10C3E1B4ED43900BD541A /* WasmJITCompiler.h */,
4298
				7BD10C3F1B4ED43900BD541A /* WasmModule.cpp */,
4299
				7BD10C401B4ED43900BD541A /* WasmModule.h */,
4300
				7BD10C411B4ED43900BD541A /* WasmOpcodes.h */,
4301
			);
4302
			path = wasm;
4303
			sourceTree = "<group>";
4304
		};
4282
		7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
4305
		7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
4283
			isa = PBXGroup;
4306
			isa = PBXGroup;
4284
			children = (
4307
			children = (
Lines 6011-6016 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
6011
				BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
6034
				BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
6012
				BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
6035
				BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
6013
				0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
6036
				0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
6037
				7BD10C451B4ED44900BD541A /* WasmModule.h in Headers */,
6014
				70EC0EC71AA0D7DA00B6AAFA /* StringIteratorPrototype.h in Headers */,
6038
				70EC0EC71AA0D7DA00B6AAFA /* StringIteratorPrototype.h in Headers */,
6015
				0F2B66AC17B6B53F00A7AE3F /* GCIncomingRefCounted.h in Headers */,
6039
				0F2B66AC17B6B53F00A7AE3F /* GCIncomingRefCounted.h in Headers */,
6016
				0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */,
6040
				0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */,
Lines 6145-6150 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
6145
				BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
6169
				BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
6146
				86E3C613167BABD7006D760A /* JSContext.h in Headers */,
6170
				86E3C613167BABD7006D760A /* JSContext.h in Headers */,
6147
				86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */,
6171
				86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */,
6172
				7BD10C431B4ED44000BD541A /* WasmJITCompiler.h in Headers */,
6148
				BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
6173
				BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
6149
				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
6174
				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
6150
				A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
6175
				A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
Lines 6154-6159 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
6154
				978801411471AD920041B016 /* JSDateMath.h in Headers */,
6179
				978801411471AD920041B016 /* JSDateMath.h in Headers */,
6155
				C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
6180
				C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
6156
				86E3C614167BABD7006D760A /* JSExport.h in Headers */,
6181
				86E3C614167BABD7006D760A /* JSExport.h in Headers */,
6182
				7BD10C461B4ED44E00BD541A /* WasmOpcodes.h in Headers */,
6157
				A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
6183
				A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
6158
				0F2B66EF17B6B5AB00A7AE3F /* JSFloat32Array.h in Headers */,
6184
				0F2B66EF17B6B5AB00A7AE3F /* JSFloat32Array.h in Headers */,
6159
				0F2B66F017B6B5AB00A7AE3F /* JSFloat64Array.h in Headers */,
6185
				0F2B66F017B6B5AB00A7AE3F /* JSFloat64Array.h in Headers */,
Lines 7152-7157 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
7152
				0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
7178
				0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
7153
				86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
7179
				86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
7154
				A7D89CFD17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp in Sources */,
7180
				A7D89CFD17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp in Sources */,
7181
				7BD10C421B4ED43C00BD541A /* WasmJITCompiler.cpp in Sources */,
7155
				0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
7182
				0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
7156
				0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
7183
				0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
7157
				FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */,
7184
				FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */,
Lines 7188-7193 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
7188
				0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
7215
				0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
7189
				0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
7216
				0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
7190
				709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
7217
				709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
7218
				7BD10C441B4ED44500BD541A /* WasmModule.cpp in Sources */,
7191
				0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
7219
				0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
7192
				0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
7220
				0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
7193
				0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
7221
				0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +72 lines
Lines 2183-2188 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin a/Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec1
2183
    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
2183
    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
2184
}
2184
}
2185
2185
2186
CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, JSGlobalObject* globalObject)
2187
    : m_globalObject(globalObject->vm(), ownerExecutable, globalObject)
2188
    , m_heap(&m_globalObject->vm().heap)
2189
    , m_numCalleeRegisters(0) // FIXME
2190
    , m_numVars(0) // FIXME
2191
    , m_isConstructor(false) // FIXME
2192
    , m_shouldAlwaysBeInlined(true)
2193
    , m_didFailFTLCompilation(false)
2194
    , m_hasBeenCompiledWithFTL(false)
2195
    // , m_unlinkedCode(m_globalObject->vm(), ownerExecutable, unlinkedCodeBlock)
2196
    , m_hasDebuggerStatement(false)
2197
    , m_steppingMode(SteppingModeDisabled)
2198
    , m_numBreakpoints(0)
2199
    , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
2200
    , m_vm(&m_globalObject->vm()) // FIXME
2201
    , m_thisRegister(VirtualRegister()) // FIXME
2202
    , m_scopeRegister(VirtualRegister()) // FIXME
2203
    , m_lexicalEnvironmentRegister(VirtualRegister()) // FIXME
2204
    , m_isStrictMode(false) // FIXME
2205
    , m_needsActivation(false)
2206
    , m_mayBeExecuting(false)
2207
    , m_source(nullptr)
2208
    , m_sourceOffset(0)
2209
    , m_firstLineColumnOffset(0)
2210
    , m_codeType(FunctionCode) // FIXME
2211
    , m_osrExitCounter(0)
2212
    , m_optimizationDelayCounter(0)
2213
    , m_reoptimizationRetryCounter(0)
2214
#if ENABLE(JIT)
2215
    , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
2216
#endif
2217
{
2218
    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
2219
2220
    ASSERT(m_heap->isDeferred());
2221
2222
    /*
2223
    ASSERT(m_scopeRegister.isLocal());
2224
2225
    bool didCloneSymbolTable = false;
2226
2227
    if (SymbolTable* symbolTable = unlinkedCodeBlock->symbolTable()) {
2228
        if (m_vm->typeProfiler()) {
2229
            ConcurrentJITLocker locker(symbolTable->m_lock);
2230
            symbolTable->prepareForTypeProfiling(locker);
2231
        }
2232
2233
        if (codeType() == FunctionCode && symbolTable->scopeSize()) {
2234
            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneScopePart(*m_vm));
2235
            didCloneSymbolTable = true;
2236
        } else
2237
            m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
2238
    }
2239
    */
2240
2241
    // FIXME:
2242
    setNumParameters(0);
2243
2244
    m_heap->m_codeBlocks.add(this);
2245
    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
2246
}
2247
2186
CodeBlock::~CodeBlock()
2248
CodeBlock::~CodeBlock()
2187
{
2249
{
2188
    if (m_vm->m_perBytecodeProfiler)
2250
    if (m_vm->m_perBytecodeProfiler)
Lines 3057-3062 CodeBlock* FunctionCodeBlock::replacement() a/Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec2
3057
    return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
3119
    return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
3058
}
3120
}
3059
3121
3122
CodeBlock* WebAssemblyCodeBlock::replacement()
3123
{
3124
    return jsCast<WebAssemblyExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
3125
}
3126
3060
DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
3127
DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
3061
{
3128
{
3062
    return DFG::programCapabilityLevel(this);
3129
    return DFG::programCapabilityLevel(this);
Lines 3073-3078 DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal() a/Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec3
3073
        return DFG::functionForConstructCapabilityLevel(this);
3140
        return DFG::functionForConstructCapabilityLevel(this);
3074
    return DFG::functionForCallCapabilityLevel(this);
3141
    return DFG::functionForCallCapabilityLevel(this);
3075
}
3142
}
3143
3144
DFG::CapabilityLevel WebAssemblyCodeBlock::capabilityLevelInternal()
3145
{
3146
    return DFG::CannotCompile;
3147
}
3076
#endif
3148
#endif
3077
3149
3078
void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
3150
void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
- a/Source/JavaScriptCore/bytecode/CodeBlock.h +23 lines
Lines 97-102 protected: a/Source/JavaScriptCore/bytecode/CodeBlock.h_sec1
97
        
97
        
98
    CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
98
    CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
99
99
100
    CodeBlock(ScriptExecutable* ownerExecutable, JSGlobalObject*);
101
100
    WriteBarrier<JSGlobalObject> m_globalObject;
102
    WriteBarrier<JSGlobalObject> m_globalObject;
101
    Heap* m_heap;
103
    Heap* m_heap;
102
104
Lines 1142-1147 protected: a/Source/JavaScriptCore/bytecode/CodeBlock.h_sec2
1142
#endif
1144
#endif
1143
};
1145
};
1144
1146
1147
class WebAssemblyCodeBlock : public CodeBlock {
1148
public:
1149
    WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
1150
        : CodeBlock(CopyParsedBlock, other)
1151
    {
1152
    }
1153
1154
    WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
1155
        : CodeBlock(ownerExecutable, globalObject)
1156
    {
1157
    }
1158
1159
protected:
1160
    virtual void finalizeUnconditionally() override { };
1161
1162
#if ENABLE(JIT)
1163
    virtual CodeBlock* replacement() override;
1164
    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1165
#endif
1166
};
1167
1145
inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
1168
inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
1146
{
1169
{
1147
    RELEASE_ASSERT(inlineCallFrame);
1170
    RELEASE_ASSERT(inlineCallFrame);
- a/Source/JavaScriptCore/jit/JITOperations.cpp -6 / +12 lines
Lines 778-784 inline char* linkFor( a/Source/JavaScriptCore/jit/JITOperations.cpp_sec1
778
778
779
    MacroAssemblerCodePtr codePtr;
779
    MacroAssemblerCodePtr codePtr;
780
    CodeBlock* codeBlock = 0;
780
    CodeBlock* codeBlock = 0;
781
    if (executable->isHostFunction())
781
    if (executable->isWebAssemblyExecutable()) {
782
        // FIXME: Should we really use RegisterPreservationNotRequired?
783
        codePtr = executable->entrypointFor(*vm, kind, ArityCheckNotRequired, RegisterPreservationNotRequired);
784
    } else if (executable->isHostFunction())
782
        codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, registers);
785
        codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, registers);
783
    else {
786
    else {
784
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
787
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
Lines 795-810 inline char* linkFor( a/Source/JavaScriptCore/jit/JITOperations.cpp_sec2
795
        }
798
        }
796
        codeBlock = functionExecutable->codeBlockFor(kind);
799
        codeBlock = functionExecutable->codeBlockFor(kind);
797
        ArityCheckMode arity;
800
        ArityCheckMode arity;
798
        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo->callType() == CallLinkInfo::CallVarargs || callLinkInfo->callType() == CallLinkInfo::ConstructVarargs)
801
        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || (callLinkInfo && (callLinkInfo->callType() == CallLinkInfo::CallVarargs || callLinkInfo->callType() == CallLinkInfo::ConstructVarargs)))
799
            arity = MustCheckArity;
802
            arity = MustCheckArity;
800
        else
803
        else
801
            arity = ArityCheckNotRequired;
804
            arity = ArityCheckNotRequired;
802
        codePtr = functionExecutable->entrypointFor(*vm, kind, arity, registers);
805
        codePtr = functionExecutable->entrypointFor(*vm, kind, arity, registers);
803
    }
806
    }
804
    if (!callLinkInfo->seenOnce())
807
    // TODO: support repatching
805
        callLinkInfo->setSeen();
808
    if (callLinkInfo) {
806
    else
809
        if (!callLinkInfo->seenOnce())
807
        linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr, kind, registers);
810
            callLinkInfo->setSeen();
811
        else
812
            linkFor(execCallee, *callLinkInfo, codeBlock, callee, codePtr, kind, registers);
813
    }
808
    
814
    
809
    return reinterpret_cast<char*>(codePtr.executableAddress());
815
    return reinterpret_cast<char*>(codePtr.executableAddress());
810
}
816
}
- a/Source/JavaScriptCore/jsc.cpp +14 lines
Lines 49-54 a/Source/JavaScriptCore/jsc.cpp_sec1
49
#include "StructureRareDataInlines.h"
49
#include "StructureRareDataInlines.h"
50
#include "TestRunnerUtils.h"
50
#include "TestRunnerUtils.h"
51
#include "TypeProfilerLog.h"
51
#include "TypeProfilerLog.h"
52
#include "WasmJITCompiler.h"
52
#include <math.h>
53
#include <math.h>
53
#include <stdio.h>
54
#include <stdio.h>
54
#include <stdlib.h>
55
#include <stdlib.h>
Lines 491-496 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*); a/Source/JavaScriptCore/jsc.cpp_sec2
491
static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
492
static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
492
static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
493
static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
493
static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
494
static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
495
static EncodedJSValue JSC_HOST_CALL functionLoadWebAssembly(ExecState*);
494
496
495
#if ENABLE(SAMPLING_FLAGS)
497
#if ENABLE(SAMPLING_FLAGS)
496
static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
498
static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
Lines 653-658 protected: a/Source/JavaScriptCore/jsc.cpp_sec3
653
        addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
655
        addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
654
656
655
        addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
657
        addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
658
659
        addFunction(vm, "loadWebAssembly", functionLoadWebAssembly, 1);
656
        
660
        
657
        JSArray* array = constructEmptyArray(globalExec(), 0);
661
        JSArray* array = constructEmptyArray(globalExec(), 0);
658
        for (size_t i = 0; i < arguments.size(); ++i)
662
        for (size_t i = 0; i < arguments.size(); ++i)
Lines 1182-1187 EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*) a/Source/JavaScriptCore/jsc.cpp_sec4
1182
    return JSValue::encode(jsUndefined());
1186
    return JSValue::encode(jsUndefined());
1183
}
1187
}
1184
1188
1189
EncodedJSValue JSC_HOST_CALL functionLoadWebAssembly(ExecState* exec)
1190
{
1191
    String fileName = exec->argument(0).toString(exec)->value(exec);
1192
    Vector<char> buffer;
1193
    if (!fillBufferWithContentsOfFile(fileName, buffer))
1194
        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
1195
    JSValue result = Wasm::compile(exec, buffer);
1196
    return JSValue::encode(result);
1197
}
1198
1185
// Use SEH for Release builds only to get rid of the crash report dialog
1199
// Use SEH for Release builds only to get rid of the crash report dialog
1186
// (luckily the same tests fail in Release and Debug builds so far). Need to
1200
// (luckily the same tests fail in Release and Debug builds so far). Need to
1187
// be in a separate main function because the jscmain function requires object
1201
// be in a separate main function because the jscmain function requires object
- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp -1 / +3 lines
Lines 1119-1125 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp_sec1
1119
    
1119
    
1120
    MacroAssemblerCodePtr codePtr;
1120
    MacroAssemblerCodePtr codePtr;
1121
    CodeBlock* codeBlock = 0;
1121
    CodeBlock* codeBlock = 0;
1122
    if (executable->isHostFunction())
1122
    if (executable->isWebAssemblyExecutable())
1123
        codePtr = executable->entrypointFor(vm, kind, ArityCheckNotRequired, RegisterPreservationNotRequired);
1124
    else if (executable->isHostFunction())
1123
        codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
1125
        codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
1124
    else {
1126
    else {
1125
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1127
        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- a/Source/JavaScriptCore/runtime/Executable.cpp +97 lines
Lines 149-154 void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) a/Source/JavaScriptCore/runtime/Executable.cpp_sec1
149
        break;
149
        break;
150
    }
150
    }
151
    
151
    
152
    if (isWebAssemblyExecutable()) {
153
        WebAssemblyExecutable* executable = jsCast<WebAssemblyExecutable*>(this);
154
        WebAssemblyCodeBlock* codeBlock = static_cast<WebAssemblyCodeBlock*>(genericCodeBlock);
155
        switch (kind) {
156
        case CodeForCall:
157
            executable->m_codeBlockForCall = codeBlock;
158
            break;
159
        case CodeForConstruct:
160
            ASSERT_NOT_REACHED();
161
            executable->m_codeBlockForConstruct = codeBlock;
162
            break;
163
        }
164
        
165
        // FIXME: this is just to make isHostFunction() happy.
166
        // But this will make isHostFunction() return true.
167
        m_numParametersForCall = 0;
168
        m_numParametersForConstruct = 0;
169
    } else {
170
171
        // FIXME: need to deal with codeType()
152
    switch (genericCodeBlock->codeType()) {
172
    switch (genericCodeBlock->codeType()) {
153
    case GlobalCode: {
173
    case GlobalCode: {
154
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
174
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
Lines 192-197 void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) a/Source/JavaScriptCore/runtime/Executable.cpp_sec2
192
    if (oldCodeBlock)
212
    if (oldCodeBlock)
193
        oldCodeBlock->unlinkIncomingCalls();
213
        oldCodeBlock->unlinkIncomingCalls();
194
214
215
    }
216
    
195
    Debugger* debugger = genericCodeBlock->globalObject()->debugger();
217
    Debugger* debugger = genericCodeBlock->globalObject()->debugger();
196
    if (debugger)
218
    if (debugger)
197
        debugger->registerCodeBlock(genericCodeBlock);
219
        debugger->registerCodeBlock(genericCodeBlock);
Lines 228-233 RefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor( a/Source/JavaScriptCore/runtime/Executable.cpp_sec3
228
            executable->source().provider(), executable->source().startColumn()));
250
            executable->source().provider(), executable->source().startColumn()));
229
    }
251
    }
230
    
252
    
253
    ASSERT(!isWebAssemblyExecutable());
254
    
231
    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
255
    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
232
    RELEASE_ASSERT(function);
256
    RELEASE_ASSERT(function);
233
    FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
257
    FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
Lines 323-328 static void setupJIT(VM& vm, CodeBlock* codeBlock) a/Source/JavaScriptCore/runtime/Executable.cpp_sec4
323
JSObject* ScriptExecutable::prepareForExecutionImpl(
347
JSObject* ScriptExecutable::prepareForExecutionImpl(
324
    ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
348
    ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
325
{
349
{
350
    ASSERT(!isWebAssemblyExecutable());
351
    
326
    VM& vm = exec->vm();
352
    VM& vm = exec->vm();
327
    DeferGC deferGC(vm.heap);
353
    DeferGC deferGC(vm.heap);
328
    
354
    
Lines 425-430 void FunctionExecutable::destroy(JSCell* cell) a/Source/JavaScriptCore/runtime/Executable.cpp_sec5
425
    static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
451
    static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
426
}
452
}
427
453
454
const ClassInfo WebAssemblyExecutable::s_info = { "WebAssemblyExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(WebAssemblyExecutable) };
455
456
WebAssemblyExecutable::WebAssemblyExecutable(VM& vm, const SourceCode& source)
457
    : ScriptExecutable(vm.webAssemblyExecutableStructure.get(), vm, source, /*isInStrictContext*/ false )
458
{
459
    /*
460
    RELEASE_ASSERT(!source.isNull());
461
    ASSERT(source.length());
462
    m_firstLine = firstLine;
463
    m_lastLine = lastLine;
464
    m_startColumn = startColumn;
465
    m_endColumn = endColumn;
466
    m_parametersStartOffset = unlinkedExecutable->parametersStartOffset();
467
    m_typeProfilingStartOffset = unlinkedExecutable->typeProfilingStartOffset();
468
    m_typeProfilingEndOffset = unlinkedExecutable->typeProfilingEndOffset();
469
    */
470
}
471
472
void WebAssemblyExecutable::finishCreation(VM& vm)
473
{
474
    Base::finishCreation(vm);
475
    m_singletonFunction.set(vm, this, InferredValue::create(vm));
476
}
477
478
void WebAssemblyExecutable::destroy(JSCell* cell)
479
{
480
    static_cast<WebAssemblyExecutable*>(cell)->WebAssemblyExecutable::~WebAssemblyExecutable();
481
}
482
428
inline const char* samplingDescription(JITCode::JITType jitType)
483
inline const char* samplingDescription(JITCode::JITType jitType)
429
{
484
{
430
    switch (jitType) {
485
    switch (jitType) {
Lines 619-624 FunctionExecutable* FunctionExecutable::fromGlobalCode( a/Source/JavaScriptCore/runtime/Executable.cpp_sec6
619
    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
674
    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
620
}
675
}
621
676
677
WebAssemblyCodeBlock* WebAssemblyExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)
678
{
679
    WebAssemblyCodeBlock* result;
680
    if (kind == CodeForCall)
681
        result = m_codeBlockForCall.get();
682
    else {
683
        RELEASE_ASSERT(kind == CodeForConstruct);
684
        result = m_codeBlockForConstruct.get();
685
    }
686
    if (!result)
687
        return 0;
688
    return static_cast<WebAssemblyCodeBlock*>(result->baselineAlternative());
689
}
690
691
void WebAssemblyExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
692
{
693
    WebAssemblyExecutable* thisObject = jsCast<WebAssemblyExecutable*>(cell);
694
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
695
    ScriptExecutable::visitChildren(thisObject, visitor);
696
    if (thisObject->m_codeBlockForCall)
697
        thisObject->m_codeBlockForCall->visitAggregate(visitor);
698
    if (thisObject->m_codeBlockForConstruct)
699
        thisObject->m_codeBlockForConstruct->visitAggregate(visitor);
700
    visitor.append(&thisObject->m_singletonFunction);
701
}
702
703
SymbolTable* WebAssemblyExecutable::symbolTable(CodeSpecializationKind kind)
704
{
705
    return codeBlockFor(kind)->symbolTable();
706
}
707
708
void WebAssemblyExecutable::clearCode()
709
{
710
    m_codeBlockForCall = nullptr;
711
    m_codeBlockForConstruct = nullptr;
712
    Base::clearCode();
713
}
714
715
void WebAssemblyExecutable::unlinkCalls()
716
{
717
}
718
622
void ExecutableBase::dump(PrintStream& out) const
719
void ExecutableBase::dump(PrintStream& out) const
623
{
720
{
624
    ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
721
    ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
- a/Source/JavaScriptCore/runtime/Executable.h +121 lines
Lines 50-55 class EvalCodeBlock; a/Source/JavaScriptCore/runtime/Executable.h_sec1
50
class FunctionCodeBlock;
50
class FunctionCodeBlock;
51
class LLIntOffsetsExtractor;
51
class LLIntOffsetsExtractor;
52
class ProgramCodeBlock;
52
class ProgramCodeBlock;
53
class WebAssemblyCodeBlock;
53
class JSScope;
54
class JSScope;
54
    
55
    
55
enum CompilationKind { FirstCompilation, OptimizingCompilation };
56
enum CompilationKind { FirstCompilation, OptimizingCompilation };
Lines 98-103 public: a/Source/JavaScriptCore/runtime/Executable.h_sec2
98
    {
99
    {
99
        return type() == FunctionExecutableType;
100
        return type() == FunctionExecutableType;
100
    }
101
    }
102
    bool isWebAssemblyExecutable()
103
    {
104
        return type() == WebAssemblyExecutableType;
105
    }
101
    bool isProgramExecutable()
106
    bool isProgramExecutable()
102
    {
107
    {
103
        return type() == ProgramExecutableType;
108
        return type() == ProgramExecutableType;
Lines 678-683 private: a/Source/JavaScriptCore/runtime/Executable.h_sec3
678
    WriteBarrier<InferredValue> m_singletonFunction;
683
    WriteBarrier<InferredValue> m_singletonFunction;
679
};
684
};
680
685
686
class WebAssemblyExecutable final : public ScriptExecutable {
687
    friend class JIT;
688
    friend class LLIntOffsetsExtractor;
689
public:
690
    typedef ScriptExecutable Base;
691
    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
692
693
    static WebAssemblyExecutable* create(VM& vm, const SourceCode& source)
694
    {
695
        WebAssemblyExecutable* executable = new (NotNull, allocateCell<WebAssemblyExecutable>(vm.heap)) WebAssemblyExecutable(vm, source);
696
        executable->finishCreation(vm);
697
        return executable;
698
    }
699
    // static WebAssemblyExecutable* fromGlobalCode(const Identifier& name, ExecState&, const SourceCode&, JSObject*& exception, int overrideLineNumber);
700
701
    static void destroy(JSCell*);
702
        
703
    bool isGeneratedForCall() const
704
    {
705
        return m_codeBlockForCall;
706
    }
707
708
    WebAssemblyCodeBlock* codeBlockForCall()
709
    {
710
        return m_codeBlockForCall.get();
711
    }
712
713
    bool isGeneratedForConstruct() const
714
    {
715
        return m_codeBlockForConstruct;
716
    }
717
718
    WebAssemblyCodeBlock* codeBlockForConstruct()
719
    {
720
        return m_codeBlockForConstruct.get();
721
    }
722
        
723
    bool isGeneratedFor(CodeSpecializationKind kind)
724
    {
725
        if (kind == CodeForCall)
726
            return isGeneratedForCall();
727
        ASSERT(kind == CodeForConstruct);
728
        return isGeneratedForConstruct();
729
    }
730
        
731
    WebAssemblyCodeBlock* codeBlockFor(CodeSpecializationKind kind)
732
    {
733
        if (kind == CodeForCall)
734
            return codeBlockForCall();
735
        ASSERT(kind == CodeForConstruct);
736
        return codeBlockForConstruct();
737
    }
738
739
    WebAssemblyCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
740
        
741
    WebAssemblyCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
742
    {
743
        return baselineCodeBlockFor(kind);
744
    }
745
746
    RefPtr<TypeSet> returnStatementTypeSet() 
747
    {
748
        if (!m_returnStatementTypeSet)
749
            m_returnStatementTypeSet = TypeSet::create();
750
751
        return m_returnStatementTypeSet;
752
    }
753
        
754
    // FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
755
    // bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
756
    // bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
757
    // const Identifier& name() { return m_unlinkedExecutable->name(); }
758
    // const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
759
    // JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
760
    // size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
761
    SymbolTable* symbolTable(CodeSpecializationKind);
762
763
    static void visitChildren(JSCell*, SlotVisitor&);
764
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
765
    {
766
        return Structure::create(vm, globalObject, proto, TypeInfo(WebAssemblyExecutableType, StructureFlags), info());
767
    }
768
769
    unsigned parametersStartOffset() const { return m_parametersStartOffset; }
770
771
    /*
772
    void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset)
773
    {
774
        m_parametersStartOffset = parametersStartOffset;
775
        m_typeProfilingStartOffset = typeProfilingStartOffset;
776
        m_typeProfilingEndOffset = typeProfilingEndOffset;
777
    }
778
    */
779
780
    DECLARE_INFO;
781
        
782
    void unlinkCalls();
783
784
    void clearCode();
785
    
786
    InferredValue* singletonFunction() { return m_singletonFunction.get(); }
787
788
private:
789
    WebAssemblyExecutable(VM&, const SourceCode&);
790
    
791
    void finishCreation(VM&);
792
793
    friend class ScriptExecutable;
794
795
    RefPtr<WebAssemblyCodeBlock> m_codeBlockForCall;
796
    RefPtr<WebAssemblyCodeBlock> m_codeBlockForConstruct;
797
    RefPtr<TypeSet> m_returnStatementTypeSet;
798
    unsigned m_parametersStartOffset;
799
    WriteBarrier<InferredValue> m_singletonFunction;
800
};
801
681
inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
802
inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
682
{
803
{
683
    switch (executable->type()) {
804
    switch (executable->type()) {
- a/Source/JavaScriptCore/runtime/JSFunction.cpp -2 / +3 lines
Lines 60-69 bool JSFunction::isHostFunctionNonInline() const a/Source/JavaScriptCore/runtime/JSFunction.cpp_sec1
60
    return isHostFunction();
60
    return isHostFunction();
61
}
61
}
62
62
63
JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
63
JSFunction* JSFunction::create(VM& vm, ExecutableBase* executable, JSScope* scope)
64
{
64
{
65
    JSFunction* result = createImpl(vm, executable, scope);
65
    JSFunction* result = createImpl(vm, executable, scope);
66
    executable->singletonFunction()->notifyWrite(vm, result, "Allocating a function");
66
    if (executable->isFunctionExecutable())
67
        static_cast<FunctionExecutable*>(executable)->singletonFunction()->notifyWrite(vm, result, "Allocating a function");
67
    return result;
68
    return result;
68
}
69
}
69
70
- a/Source/JavaScriptCore/runtime/JSFunction.h -3 / +3 lines
Lines 72-78 public: a/Source/JavaScriptCore/runtime/JSFunction.h_sec1
72
    static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*);
72
    static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*);
73
    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeStdFunction&&, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
73
    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeStdFunction&&, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
74
74
75
    static JSFunction* create(VM&, FunctionExecutable*, JSScope*);
75
    static JSFunction* create(VM&, ExecutableBase*, JSScope*);
76
76
77
    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
77
    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
78
    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name);
78
    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name);
Lines 140-146 public: a/Source/JavaScriptCore/runtime/JSFunction.h_sec2
140
140
141
protected:
141
protected:
142
    JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
142
    JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
143
    JSFunction(VM&, FunctionExecutable*, JSScope*);
143
    JSFunction(VM&, ExecutableBase*, JSScope*);
144
144
145
    void finishCreation(VM&, NativeExecutable*, int length, const String& name);
145
    void finishCreation(VM&, NativeExecutable*, int length, const String& name);
146
    using Base::finishCreation;
146
    using Base::finishCreation;
Lines 159-165 protected: a/Source/JavaScriptCore/runtime/JSFunction.h_sec3
159
    static void visitChildren(JSCell*, SlotVisitor&);
159
    static void visitChildren(JSCell*, SlotVisitor&);
160
160
161
private:
161
private:
162
    static JSFunction* createImpl(VM& vm, FunctionExecutable* executable, JSScope* scope)
162
    static JSFunction* createImpl(VM& vm, ExecutableBase* executable, JSScope* scope)
163
    {
163
    {
164
        JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
164
        JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
165
        ASSERT(function->structure()->globalObject());
165
        ASSERT(function->structure()->globalObject());
- a/Source/JavaScriptCore/runtime/JSFunctionInlines.h -1 / +3 lines
Lines 38-44 inline JSFunction* JSFunction::createWithInvalidatedReallocationWatchpoint( a/Source/JavaScriptCore/runtime/JSFunctionInlines.h_sec1
38
    return createImpl(vm, executable, scope);
38
    return createImpl(vm, executable, scope);
39
}
39
}
40
40
41
inline JSFunction::JSFunction(VM& vm, FunctionExecutable* executable, JSScope* scope)
41
inline JSFunction::JSFunction(VM& vm, ExecutableBase* executable, JSScope* scope)
42
    : Base(vm, scope, scope->globalObject()->functionStructure())
42
    : Base(vm, scope, scope->globalObject()->functionStructure())
43
    , m_executable(vm, this, executable)
43
    , m_executable(vm, this, executable)
44
    , m_rareData()
44
    , m_rareData()
Lines 54-59 inline FunctionExecutable* JSFunction::jsExecutable() const a/Source/JavaScriptCore/runtime/JSFunctionInlines.h_sec2
54
inline bool JSFunction::isHostFunction() const
54
inline bool JSFunction::isHostFunction() const
55
{
55
{
56
    ASSERT(m_executable);
56
    ASSERT(m_executable);
57
    if (m_executable->isWebAssemblyExecutable()) // FIXME: hacky
58
        return true;
57
    return m_executable->isHostFunction();
59
    return m_executable->isHostFunction();
58
}
60
}
59
61
- a/Source/JavaScriptCore/runtime/JSType.h +2 lines
Lines 74-79 enum JSType : uint8_t { a/Source/JavaScriptCore/runtime/JSType.h_sec1
74
74
75
    NameScopeObjectType,
75
    NameScopeObjectType,
76
76
77
    WebAssemblyExecutableType, // FIXME: Move it above.
78
77
    GlobalObjectType,
79
    GlobalObjectType,
78
    ActivationObjectType,
80
    ActivationObjectType,
79
81
- a/Source/JavaScriptCore/runtime/VM.cpp +1 lines
Lines 220-225 VM::VM(VMType vmType, HeapType heapType) a/Source/JavaScriptCore/runtime/VM.cpp_sec1
220
    evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
220
    evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
221
    programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
221
    programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
222
    functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
222
    functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
223
    webAssemblyExecutableStructure.set(*this, WebAssemblyExecutable::createStructure(*this, 0, jsNull()));
223
    regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
224
    regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
224
    symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
225
    symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
225
    symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
226
    symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
- a/Source/JavaScriptCore/runtime/VM.h +1 lines
Lines 259-264 public: a/Source/JavaScriptCore/runtime/VM.h_sec1
259
    Strong<Structure> evalExecutableStructure;
259
    Strong<Structure> evalExecutableStructure;
260
    Strong<Structure> programExecutableStructure;
260
    Strong<Structure> programExecutableStructure;
261
    Strong<Structure> functionExecutableStructure;
261
    Strong<Structure> functionExecutableStructure;
262
    Strong<Structure> webAssemblyExecutableStructure;
262
    Strong<Structure> regExpStructure;
263
    Strong<Structure> regExpStructure;
263
    Strong<Structure> symbolStructure;
264
    Strong<Structure> symbolStructure;
264
    Strong<Structure> symbolTableStructure;
265
    Strong<Structure> symbolTableStructure;
- a/Source/JavaScriptCore/wasm/WasmJITCompiler.cpp +1027 lines
Line 0 a/Source/JavaScriptCore/wasm/WasmJITCompiler.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
/*
27
 Licensed under the Apache License, Version 2.0 (the "License");
28
 you may not use this file except in compliance with the License.
29
 You may obtain a copy of the License at
30
31
 http://www.apache.org/licenses/LICENSE-2.0
32
33
 Unless required by applicable law or agreed to in writing, software
34
 distributed under the License is distributed on an "AS IS" BASIS,
35
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
 See the License for the specific language governing permissions and
37
 limitations under the License.
38
*/
39
40
#include "config.h"
41
#include "WasmJITCompiler.h"
42
43
#include "JITCode.h"
44
#include "JSCJSValueInlines.h"
45
#include "LinkBuffer.h"
46
#include "MaxFrameExtentForSlowPathCall.h"
47
#include "Register.h"
48
49
namespace JSC {
50
51
namespace Wasm {
52
53
class JumpScope {
54
public:
55
    JumpScope(MacroAssembler* macroAssembler)
56
        : m_macroAssembler(macroAssembler)
57
        , m_linked(false)
58
    {
59
    }
60
61
    JumpScope(MacroAssembler* macroAssembler, const MacroAssembler::Label& label)
62
        : m_macroAssembler(macroAssembler)
63
        , m_linked(true)
64
        , m_label(label)
65
    {
66
    }
67
68
    void jump()
69
    {
70
        if (m_linked)
71
            m_macroAssembler->jump(m_label);
72
        else
73
            m_jumpList.append(m_macroAssembler->jump());
74
    }
75
76
    void link()
77
    {
78
        ASSERT(!m_linked);
79
        m_jumpList.link(m_macroAssembler);
80
    }
81
82
private:
83
    MacroAssembler* m_macroAssembler;
84
    bool m_linked;
85
    MacroAssembler::Label m_label;
86
    MacroAssembler::JumpList m_jumpList;
87
};
88
89
RefPtr<JITCode> JITCompiler::compileFunction(VM& vm, size_t functionIndex)
90
{
91
    emitFunctionPrologue();
92
    // FIXME: need to do this!
93
    // emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
94
95
    const Signature& signature = m_module->m_signatures[m_module->m_funcSignatures[functionIndex]];
96
    m_currentReturnType = signature.returnType;
97
    parseArguments(signature);
98
99
    // FIXME: Calculate the actual height. (Be careful about calls.)
100
    m_stackHeight = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), signature.arguments.size() + 8) * sizeof(Register);
101
    allocateSpaceOnStack();
102
103
    parseVars();
104
    parseStmtList();
105
106
    LinkBuffer patchBuffer(vm, *this, 0, JITCompilationMustSucceed);
107
108
    MacroAssemblerCodePtr withArityCheck;
109
    CodeRef result = FINALIZE_CODE(patchBuffer, ("Baseline JIT code for WebAssembly"));
110
    return adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT));
111
}
112
113
void JITCompiler::allocateSpaceOnStack()
114
{
115
    addPtr(TrustedImm32(-m_stackHeight), stackPointerRegister);
116
}
117
118
void JITCompiler::deallocateSpaceOnStack()
119
{
120
    addPtr(TrustedImm32(m_stackHeight), stackPointerRegister);
121
}
122
123
void JITCompiler::parseArguments(const Signature& signature)
124
{
125
    size_t argumentCount = signature.arguments.size();
126
    for (uint32_t argIndex = 0; argIndex < argumentCount; ++argIndex) {
127
        Type type = signature.arguments[argIndex];
128
        m_currentLocalTypes.append(type);
129
        switch (type) {
130
        case Type::I32:
131
            load32(Address(GPRInfo::callFrameRegister, (argIndex + 1 + CallFrame::thisArgumentOffset()) * sizeof(Register)), GPRInfo::regT0);
132
            store32(GPRInfo::regT0, stackAddress(argIndex));
133
            break;
134
        case Type::F32:
135
            RELEASE_ASSERT_NOT_REACHED();
136
        case Type::F64:
137
            load64(Address(GPRInfo::callFrameRegister, (argIndex + 1 + CallFrame::thisArgumentOffset()) * sizeof(Register)), GPRInfo::regT0);
138
            unboxDoubleWithoutAssertions(GPRInfo::regT0, FPRInfo::fpRegT0);
139
            storeDouble(FPRInfo::fpRegT0, stackAddress(argIndex));
140
            break;
141
        default:
142
            RELEASE_ASSERT_NOT_REACHED();
143
        }
144
    }
145
}
146
147
void JITCompiler::parseVars()
148
{
149
    uint32_t numberOfI32Vars = 0;
150
    uint32_t numberOfF32Vars = 0;
151
    uint32_t numberOfF64Vars = 0;
152
153
    VarTypes varTypes;
154
    VarTypesWithImm varTypesWithImm;
155
    uint8_t imm;
156
    if (m_module->m_reader.code(&varTypes, &varTypesWithImm, &imm)) {
157
        if (varTypes & VarTypes::I32)
158
            numberOfI32Vars = m_module->m_reader.immU32();
159
        if (varTypes & VarTypes::F32)
160
            numberOfF32Vars = m_module->m_reader.immU32();
161
        if (varTypes & VarTypes::F64)
162
            numberOfF64Vars = m_module->m_reader.immU32();
163
    } else
164
        numberOfI32Vars = imm;
165
166
    uint32_t numberOfVars = numberOfI32Vars + numberOfF32Vars + numberOfF64Vars;
167
    if (numberOfVars > 0) {
168
        uint32_t localIndex = m_currentLocalTypes.size();
169
        for (uint32_t i = 0; i < numberOfI32Vars; ++i) {
170
            m_currentLocalTypes.append(Type::I32);
171
            store32(TrustedImm32(0), stackAddress(localIndex++));
172
        }
173
        for (uint32_t i = 0; i < numberOfF32Vars; ++i) {
174
            m_currentLocalTypes.append(Type::F32);
175
            store32(TrustedImm32(0), stackAddress(localIndex++));
176
        }
177
        for (uint32_t i = 0; i < numberOfF64Vars; ++i) {
178
            m_currentLocalTypes.append(Type::F64);
179
            store64(TrustedImm64(0), stackAddress(localIndex++));
180
        }
181
    }
182
}
183
184
void JITCompiler::parseStmt()
185
{
186
    Stmt stmt;
187
    StmtWithImm stmtWithImm;
188
    uint8_t imm;
189
    if (m_module->m_reader.code(&stmt, &stmtWithImm, &imm)) {
190
        switch (stmt) {
191
        case Stmt::SetLoc:
192
            parseSetLocal(0);
193
            break;
194
        case Stmt::SetGlo:
195
        case Stmt::I32Store8:
196
        case Stmt::I32StoreOff8:
197
        case Stmt::I32Store16:
198
        case Stmt::I32StoreOff16:
199
        case Stmt::I32Store32:
200
        case Stmt::I32StoreOff32:
201
        case Stmt::F32Store:
202
        case Stmt::F32StoreOff:
203
        case Stmt::F64Store:
204
        case Stmt::F64StoreOff:
205
        case Stmt::CallInt:
206
        case Stmt::CallInd:
207
            RELEASE_ASSERT_NOT_REACHED();
208
        case Stmt::CallImp:
209
            parseCallImport(ReturnType::Void, 0); // FIXME: Is it really Void?
210
            break;
211
        case Stmt::Ret:
212
            parseReturnStmt();
213
            return;
214
        case Stmt::Block:
215
            parseBlockStmt();
216
            return;
217
        case Stmt::IfThen:
218
            parseIfStmt();
219
            return;
220
        case Stmt::IfElse:
221
            parseIfElseStmt();
222
            return;
223
        case Stmt::While:
224
            parseWhileStmt();
225
            return;
226
        case Stmt::Do:
227
            parseDoStmt();
228
            return;
229
        case Stmt::Label:
230
            parseLabelStmt();
231
            return;
232
        case Stmt::Break:
233
            parseBreakStmt();
234
            return;
235
        case Stmt::BreakLabel:
236
            parseBreakLabelStmt();
237
            return;
238
        case Stmt::Continue:
239
            parseContinueStmt();
240
            break;
241
        case Stmt::ContinueLabel:
242
            parseContinueLabelStmt();
243
            return;
244
        case Stmt::Switch:
245
            parseSwitchStmt();
246
            break;
247
        default:
248
            RELEASE_ASSERT_NOT_REACHED();
249
        }
250
    } else {
251
        switch (stmtWithImm) {
252
        case StmtWithImm::SetLoc:
253
            parseSetLocal(imm, 0);
254
            break;
255
        case StmtWithImm::SetGlo:
256
        default:
257
            RELEASE_ASSERT_NOT_REACHED();
258
        }
259
    }
260
}
261
262
void JITCompiler::parseGetLocal(int dst)
263
{
264
    uint32_t imm = m_module->m_reader.immU32();
265
    switch (m_currentLocalTypes[imm]) {
266
    case Type::I32:
267
    case Type::F32:
268
        load32(stackAddress(imm), GPRInfo::regT0);
269
        store32(GPRInfo::regT0, temporaryAddress(dst));
270
        break;
271
    case Type::F64:
272
        load64(stackAddress(imm), GPRInfo::regT0);
273
        store64(GPRInfo::regT0, temporaryAddress(dst));
274
        break;
275
    default:
276
        RELEASE_ASSERT_NOT_REACHED();
277
    }
278
}
279
280
void JITCompiler::parseSetLocal(uint32_t imm, int dst)
281
{
282
    Type type = m_currentLocalTypes[imm];
283
    parseExpr(ReturnType(type), dst);
284
    switch (type) {
285
    case Type::I32:
286
    case Type::F32:
287
        load32(temporaryAddress(dst), GPRInfo::regT0);
288
        store32(GPRInfo::regT0, stackAddress(imm));
289
        break;
290
    case Type::F64:
291
        load64(temporaryAddress(dst), GPRInfo::regT0);
292
        store64(GPRInfo::regT0, stackAddress(imm));
293
        break;
294
    default:
295
        RELEASE_ASSERT_NOT_REACHED();
296
    }
297
}
298
299
void JITCompiler::parseSetLocal(int dst)
300
{
301
    parseSetLocal(m_module->m_reader.immU32(), dst);
302
}
303
304
void JITCompiler::parseReturnStmt()
305
{
306
    switch (m_currentReturnType) {
307
    case ReturnType::I32:
308
        parseExpr(ReturnType::I32, 0);
309
        load32(temporaryAddress(0), GPRInfo::returnValueGPR);
310
        or64(GPRInfo::tagTypeNumberRegister, GPRInfo::returnValueGPR);
311
        break;
312
    case ReturnType::F32:
313
        parseExpr(ReturnType::F32, 0);
314
        loadDouble(temporaryAddress(0), FPRInfo::fpRegT0); // FIXME: This loads 64 bits!
315
        convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
316
        boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
317
        break;
318
    case ReturnType::F64:
319
        parseExpr(ReturnType::F64, 0);
320
        loadDouble(temporaryAddress(0), FPRInfo::fpRegT0);
321
        boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
322
        break;
323
    case ReturnType::Void:
324
        break;
325
    }
326
327
    deallocateSpaceOnStack();
328
    emitFunctionEpilogue();
329
    ret();
330
}
331
332
void JITCompiler::parseStmtList()
333
{
334
    uint32_t numberOfStmts = m_module->m_reader.immU32();
335
    for (uint32_t i = 0; i < numberOfStmts; ++i)
336
        parseStmt();
337
}
338
339
void JITCompiler::parseBlockStmt()
340
{
341
    parseStmtList();
342
}
343
344
void JITCompiler::parseIfStmt()
345
{
346
    parseExpr(ReturnType::I32, 0);
347
    load32(temporaryAddress(0), GPRInfo::regT0);
348
    Jump end = branchTest32(Zero, GPRInfo::regT0);
349
    parseStmt();
350
    end.link(this);
351
}
352
353
void JITCompiler::parseIfElseStmt()
354
{
355
    parseExpr(ReturnType::I32, 0);
356
    load32(temporaryAddress(0), GPRInfo::regT0);
357
    Jump els = branchTest32(Zero, GPRInfo::regT0);
358
    parseStmt();
359
    Jump end = jump();
360
    els.link(this);
361
    parseStmt();
362
    end.link(this);
363
}
364
365
void JITCompiler::parseWhileStmt()
366
{
367
    JumpScope continueJumpScope(this, label());
368
    pushContinueJumpScope(&continueJumpScope);
369
370
    JumpList breakJumpList;
371
    pushBreakJumpList(&breakJumpList);
372
373
    parseExpr(ReturnType::I32, 0);
374
    load32(temporaryAddress(0), GPRInfo::regT0);
375
    Jump end = branchTest32(Zero, GPRInfo::regT0);
376
    parseStmt();
377
    continueJumpScope.jump();
378
    end.link(this);
379
    breakJumpList.link(this);
380
381
    popBreakJumpList();
382
383
    popContinueJumpScope();
384
}
385
386
void JITCompiler::parseDoStmt()
387
{
388
    JumpScope continueJumpScope(this);
389
    pushContinueJumpScope(&continueJumpScope);
390
391
    JumpList breakJumpList;
392
    pushBreakJumpList(&breakJumpList);
393
394
    Label start = label();
395
    parseStmt();
396
    continueJumpScope.link();
397
    parseExpr(ReturnType::I32, 0);
398
    load32(temporaryAddress(0), GPRInfo::regT0);
399
    Jump jumpToStart = branchTest32(NonZero, GPRInfo::regT0);
400
    jumpToStart.linkTo(start, this);
401
    breakJumpList.link(this);
402
403
    popBreakJumpList();
404
405
    popContinueJumpScope();
406
}
407
408
void JITCompiler::parseLabelStmt()
409
{
410
    Label continueLabel = label();
411
    JumpList breakJumpList;
412
    pushContinueLabelLabel(&continueLabel);
413
    pushBreakLabelJumpList(&breakJumpList);
414
    parseStmt();
415
    breakJumpList.link(this);
416
    popBreakLabelJumpList();
417
    popContinueLabelLabel();
418
}
419
420
void JITCompiler::parseBreakStmt()
421
{
422
    topBreakJumpList()->append(jump());
423
}
424
425
void JITCompiler::parseBreakLabelStmt()
426
{
427
    uint32_t index = m_module->m_reader.immU32();
428
    breakLabelJumpList(index)->append(jump());
429
}
430
431
void JITCompiler::parseContinueStmt()
432
{
433
    topContinueJumpScope()->jump();
434
}
435
436
void JITCompiler::parseContinueLabelStmt()
437
{
438
    uint32_t index = m_module->m_reader.immU32();
439
    jump(*continueLabelLabel(index));
440
}
441
442
void JITCompiler::parseSwitchStmt()
443
{
444
    JumpList breakJumpList;
445
    pushBreakJumpList(&breakJumpList);
446
447
    uint32_t numberOfCases = m_module->m_reader.immU32();
448
    parseExpr(ReturnType::I32, 0);
449
    load32(temporaryAddress(0), GPRInfo::regT0);
450
451
    Jump table = jump();
452
453
    Vector<Label> labels;
454
    Vector<int32_t> imms;
455
    Label defaultLabel;
456
    bool hasDefault = false;
457
458
    for (uint32_t i = 0; i < numberOfCases; ++i) {
459
        switch (m_module->m_reader.switchCase()) {
460
        case SwitchCase::Case0:
461
            labels.append(label());
462
            imms.append(m_module->m_reader.immS32());
463
            break;
464
        case SwitchCase::Case1:
465
            labels.append(label());
466
            imms.append(m_module->m_reader.immS32());
467
            parseStmt();
468
            break;
469
        case SwitchCase::CaseN:
470
            labels.append(label());
471
            imms.append(m_module->m_reader.immS32());
472
            parseStmtList();
473
            break;
474
        case SwitchCase::Default0:
475
            defaultLabel = label();
476
            hasDefault = true;
477
            break;
478
        case SwitchCase::Default1:
479
            defaultLabel = label();
480
            hasDefault = true;
481
            parseStmt();
482
            break;
483
        case SwitchCase::DefaultN:
484
            defaultLabel = label();
485
            hasDefault = true;
486
            parseStmtList();
487
            break;
488
        default:
489
            RELEASE_ASSERT_NOT_REACHED();
490
        }
491
    }
492
493
    Jump end = jump();
494
    table.link(this);
495
496
    for (size_t i = 0; i < labels.size(); ++i) {
497
        Jump jmp = branch32(Equal, GPRInfo::regT0, TrustedImm32(imms[i]));
498
        jmp.linkTo(labels[i], this);
499
    }
500
    if (hasDefault)
501
        jump(defaultLabel);
502
503
    end.link(this);
504
505
    breakJumpList.link(this);
506
    popBreakJumpList();
507
}
508
509
void JITCompiler::parseExpr(ReturnType rType, int dst)
510
{
511
    switch (rType) {
512
    case ReturnType::I32:
513
        parseExprI32(dst);
514
        break;
515
    case ReturnType::F64:
516
        parseExprF64(dst);
517
        break;
518
    default:
519
        RELEASE_ASSERT_NOT_REACHED();
520
    }
521
}
522
523
void JITCompiler::parseExprI32(int dst)
524
{
525
    I32 i32;
526
    I32WithImm i32WithImm;
527
    uint8_t imm;
528
529
    if (m_module->m_reader.code(&i32, &i32WithImm, &imm)) {
530
        switch (i32) {
531
        case I32::LitImm:
532
            store32(TrustedImm32(m_module->m_reader.immU32()), temporaryAddress(dst));
533
            break;
534
        case I32::LitPool:
535
        case I32::GetLoc:
536
            parseGetLocal(dst);
537
            break;
538
        case I32::GetGlo:
539
            RELEASE_ASSERT_NOT_REACHED();
540
        case I32::SetLoc:
541
            parseSetLocal(dst);
542
            break;
543
        case I32::SetGlo:
544
        case I32::SLoad8:
545
        case I32::SLoadOff8:
546
        case I32::ULoad8:
547
        case I32::ULoadOff8:
548
        case I32::SLoad16:
549
        case I32::SLoadOff16:
550
        case I32::ULoad16:
551
        case I32::ULoadOff16:
552
        case I32::Load32:
553
        case I32::LoadOff32:
554
        case I32::Store8:
555
        case I32::StoreOff8:
556
        case I32::Store16:
557
        case I32::StoreOff16:
558
        case I32::Store32:
559
        case I32::StoreOff32:
560
            RELEASE_ASSERT_NOT_REACHED();
561
        case I32::CallInt:
562
            parseCallInternal(ReturnType::I32, dst);
563
            break;
564
        case I32::CallInd:
565
            RELEASE_ASSERT_NOT_REACHED();
566
        case I32::CallImp:
567
            parseCallImport(ReturnType::I32, dst);
568
            break;
569
        case I32::Cond:
570
            parseCond(ReturnType::I32, dst);
571
            break;
572
        case I32::Comma:
573
            parseComma(ReturnType::I32, dst);
574
            break;
575
        case I32::FromF32:
576
            RELEASE_ASSERT_NOT_REACHED();
577
        case I32::FromF64:
578
            parseExprF64(dst);
579
            loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
580
            truncateDoubleToInt32(FPRInfo::fpRegT0, GPRInfo::regT0);
581
            store32(GPRInfo::regT0, temporaryAddress(dst));
582
            break;
583
        case I32::Neg:
584
            parseUnaryOp(static_cast<uint8_t>(i32), ReturnType::I32, dst);
585
            break;
586
        case I32::Add:
587
        case I32::Sub:
588
        case I32::Mul:
589
            parseBinaryOp(static_cast<uint8_t>(i32), ReturnType::I32, dst);
590
            break;
591
        case I32::SDiv:
592
        case I32::UDiv:
593
        case I32::SMod:
594
        case I32::UMod:
595
            RELEASE_ASSERT_NOT_REACHED();
596
        case I32::BitNot:
597
            parseUnaryOp(static_cast<uint8_t>(i32), ReturnType::I32, dst);
598
            break;
599
        case I32::BitOr:
600
        case I32::BitAnd:
601
        case I32::BitXor:
602
            parseBinaryOp(static_cast<uint8_t>(i32), ReturnType::I32, dst);
603
            break;
604
        case I32::Lsh:
605
        case I32::ArithRsh:
606
        case I32::LogicRsh:
607
        case I32::Clz:
608
        case I32::LogicNot:
609
            RELEASE_ASSERT_NOT_REACHED();
610
        case I32::EqI32:
611
            parseRelationalOpI32(Equal, dst);
612
            break;
613
        case I32::EqF32:
614
            RELEASE_ASSERT_NOT_REACHED();
615
        case I32::EqF64:
616
            parseRelationalOpF64(DoubleEqual, dst);
617
            break;
618
        case I32::NEqI32:
619
            parseRelationalOpI32(NotEqual, dst);
620
            break;
621
        case I32::NEqF32:
622
            RELEASE_ASSERT_NOT_REACHED();
623
        case I32::NEqF64:
624
            parseRelationalOpF64(DoubleNotEqual, dst);
625
            break;
626
        case I32::SLeThI32:
627
            parseRelationalOpI32(LessThan, dst);
628
            break;
629
        case I32::ULeThI32:
630
            parseRelationalOpI32(Below, dst);
631
            break;
632
        case I32::LeThF32:
633
            RELEASE_ASSERT_NOT_REACHED();
634
        case I32::LeThF64:
635
            parseRelationalOpF64(DoubleLessThan, dst);
636
            break;
637
        case I32::SLeEqI32:
638
            parseRelationalOpI32(LessThanOrEqual, dst);
639
            break;
640
        case I32::ULeEqI32:
641
            parseRelationalOpI32(BelowOrEqual, dst);
642
            break;
643
        case I32::LeEqF32:
644
            RELEASE_ASSERT_NOT_REACHED();
645
        case I32::LeEqF64:
646
            parseRelationalOpF64(DoubleLessThanOrEqual, dst);
647
            break;
648
        case I32::SGrThI32:
649
            parseRelationalOpI32(GreaterThan, dst);
650
            break;
651
        case I32::UGrThI32:
652
            parseRelationalOpI32(Above, dst);
653
            break;
654
        case I32::GrThF32:
655
            RELEASE_ASSERT_NOT_REACHED();
656
        case I32::GrThF64:
657
            parseRelationalOpF64(DoubleGreaterThan, dst);
658
            break;
659
        case I32::SGrEqI32:
660
            parseRelationalOpI32(GreaterThanOrEqual, dst);
661
            break;
662
        case I32::UGrEqI32:
663
            parseRelationalOpI32(AboveOrEqual, dst);
664
            break;
665
        case I32::GrEqF32:
666
            RELEASE_ASSERT_NOT_REACHED();
667
        case I32::GrEqF64:
668
            parseRelationalOpF64(DoubleGreaterThanOrEqual, dst);
669
            break;
670
        case I32::SMin:
671
        case I32::UMin:
672
        case I32::SMax:
673
        case I32::UMax:
674
        case I32::Abs:
675
        default:
676
            RELEASE_ASSERT_NOT_REACHED();
677
        }
678
    } else {
679
        switch (i32WithImm) {
680
        case I32WithImm::LitImm:
681
            store32(TrustedImm32(imm), temporaryAddress(dst));
682
            break;
683
        case I32WithImm::LitPool:
684
            store32(TrustedImm32(m_module->m_constantI32s[imm]), temporaryAddress(dst));
685
            break;
686
        case I32WithImm::GetLoc:
687
            load32(stackAddress(imm), GPRInfo::regT0);
688
            store32(GPRInfo::regT0, temporaryAddress(dst));
689
            break;
690
        default:
691
            RELEASE_ASSERT_NOT_REACHED();
692
        }
693
    }
694
}
695
696
void JITCompiler::parseExprF64(int dst)
697
{
698
    F64 f64;
699
    F64WithImm f64WithImm;
700
    uint8_t imm;
701
702
    if (m_module->m_reader.code(&f64, &f64WithImm, &imm)) {
703
        switch (f64) {
704
        case F64::LitImm:
705
            store64(TrustedImm64(reinterpretDoubleToInt64(m_module->m_reader.fixedWidth<double>())), temporaryAddress(dst));
706
            break;
707
        case F64::Neg:
708
            parseUnaryOp(static_cast<uint8_t>(f64), ReturnType::F64, dst);
709
            break;
710
        case F64::Add:
711
        case F64::Sub:
712
        case F64::Mul:
713
        case F64::Div:
714
            parseBinaryOp(static_cast<uint8_t>(f64), ReturnType::F64, dst);
715
            break;
716
        case F64::Sqrt:
717
            parseUnaryOp(static_cast<uint8_t>(f64), ReturnType::F64, dst);
718
            break;
719
        case F64::CallInt:
720
            parseCallInternal(ReturnType::F64, dst);
721
            break;
722
        case F64::CallImp:
723
            parseCallImport(ReturnType::F64, dst);
724
            break;
725
        default:
726
            RELEASE_ASSERT_NOT_REACHED();
727
        }
728
    } else {
729
        switch (f64WithImm) {
730
        case F64WithImm::LitPool:
731
            store64(TrustedImm64(reinterpretDoubleToInt64(m_module->m_constantF64s[imm])), temporaryAddress(dst));
732
            break;
733
        case F64WithImm::GetLoc:
734
            // FIXME: loadDouble/storeDouble?
735
            load64(stackAddress(imm), GPRInfo::regT0);
736
            store64(GPRInfo::regT0, temporaryAddress(dst));
737
            break;
738
        default:
739
            RELEASE_ASSERT_NOT_REACHED();
740
        }
741
    }
742
}
743
744
static EncodedJSValue getInternalFunction(ExecState*, Module* module, uint32_t functionIndex)
745
{
746
    // TODO: Use these two lines?
747
    // VM* vm = exec->vm();
748
    // NativeCallFrameTracer tracer(vm, exec);
749
750
    return module->internalFunction(functionIndex);
751
}
752
753
void JITCompiler::parseCallInternal(ReturnType rType, int dst)
754
{
755
    uint32_t functionIndex = m_module->m_reader.immU32();
756
    const Signature& signature = m_module->m_signatures[m_module->m_funcSignatures[functionIndex]];
757
    const Vector<Type>& arguments = signature.arguments;
758
    size_t argumentCount = arguments.size();
759
    // FIXME: rType is redundant with signature.returnType
760
761
    parseCallArguments(arguments, dst);
762
763
    store32(TrustedImm32(argumentCount + 1), Address(stackPointerRegister, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
764
765
    if (maxFrameExtentForSlowPathCall)
766
        addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
767
    setupArgumentsWithExecState(TrustedImmPtr(m_module), TrustedImm32(functionIndex));
768
    move(TrustedImmPtr(bitwise_cast<void*>(getInternalFunction)), GPRInfo::nonArgGPR0);
769
    call(GPRInfo::nonArgGPR0);
770
    if (maxFrameExtentForSlowPathCall)
771
        addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
772
773
    move(GPRInfo::returnValueGPR, GPRInfo::regT0); // regT0 holds callee.
774
    store64(GPRInfo::regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
775
776
    callFunctionSlowCase(rType, dst);
777
}
778
779
static EncodedJSValue getImportedFunction(ExecState* exec, Module* module, uint32_t funcImportIndex)
780
{
781
    // TODO: Use these two lines?
782
    // VM* vm = exec->vm();
783
    // NativeCallFrameTracer tracer(vm, exec);
784
785
    const String& functionImportName = module->functionImportName(funcImportIndex);
786
787
    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
788
    Identifier identifier = Identifier::fromString(&exec->vm(), functionImportName);
789
    PropertySlot slot(globalObject);
790
791
    if (!globalObject->getPropertySlot(exec, identifier, slot)) {
792
        // TODO: do something!
793
        fprintf(stderr, "Can't find a function named \"%s\".\n", functionImportName.utf8().data());
794
        abort();
795
    }
796
797
    JSValue value = slot.getValue(exec, identifier);
798
    if (!value.isFunction()) {
799
        fprintf(stderr, "\"%s\" is not a function.\n", functionImportName.utf8().data());
800
        abort();
801
    }
802
803
    return JSValue::encode(value);
804
}
805
806
void JITCompiler::parseCallImport(ReturnType rType, int dst)
807
{
808
    uint32_t funcImportSignatureIndex = m_module->m_reader.immU32();
809
    const Module::FuncImportSignature& funcImportSignature = m_module->m_funcImportSignatures[funcImportSignatureIndex];
810
    const Signature& signature = m_module->m_signatures[funcImportSignature.signatureIndex];
811
    const Vector<Type>& arguments = signature.arguments;
812
    size_t argumentCount = arguments.size();
813
    // FIXME: rType is redundant with signature.returnType
814
815
    parseCallArguments(arguments, dst);
816
817
    store32(TrustedImm32(argumentCount + 1), Address(stackPointerRegister, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
818
819
    if (maxFrameExtentForSlowPathCall)
820
        addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
821
    setupArgumentsWithExecState(TrustedImmPtr(m_module), TrustedImm32(funcImportSignature.funcImportIndex));
822
    move(TrustedImmPtr(bitwise_cast<void*>(getImportedFunction)), GPRInfo::nonArgGPR0);
823
    call(GPRInfo::nonArgGPR0);
824
    if (maxFrameExtentForSlowPathCall)
825
        addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
826
827
    move(GPRInfo::returnValueGPR, GPRInfo::regT0); // regT0 holds callee.
828
    store64(GPRInfo::regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
829
830
    callFunctionSlowCase(rType, dst);
831
}
832
833
void JITCompiler::callFunctionSlowCase(ReturnType rType, int dst)
834
{
835
    ThunkGenerator generator = linkThunkGeneratorFor(CodeForCall, RegisterPreservationNotRequired);
836
837
    move(TrustedImmPtr(nullptr), GPRInfo::regT2); // TODO: use CallLinkInfo
838
839
    CodePtr ptr = m_vm->getCTIStub(generator).code();
840
841
    move(TrustedImmPtr(ptr.executableAddress()), GPRInfo::nonArgGPR0);
842
843
    call(GPRInfo::nonArgGPR0);
844
845
    addPtr(TrustedImm32(-m_stackHeight), GPRInfo::callFrameRegister, stackPointerRegister); // FIXME: hacky
846
847
    // FIXME: Can we really use returnValueGPR?
848
    switch (rType) {
849
    case ReturnType::I32:
850
        store32(GPRInfo::returnValueGPR, temporaryAddress(dst));
851
        break;
852
    case ReturnType::F64:
853
        unboxDoubleWithoutAssertions(GPRInfo::returnValueGPR, FPRInfo::fpRegT0);
854
        storeDouble(FPRInfo::fpRegT0, temporaryAddress(dst));
855
        break;
856
    case ReturnType::Void:
857
        break; // TODO: sure?
858
    default:
859
        ASSERT_NOT_REACHED();
860
    }
861
}
862
863
void JITCompiler::parseCallArguments(const Vector<Type>& arguments, int dst)
864
{
865
    size_t argumentCount = arguments.size();
866
    size_t offset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), dst + argumentCount + m_currentLocalTypes.size()) - m_currentLocalTypes.size(); // FIXME: better name
867
868
    for (size_t i = 0; i < argumentCount; ++i) {
869
        switch (arguments[i]) {
870
        case Type::I32:
871
            parseExpr(ReturnType::I32, offset);
872
            load32(temporaryAddress(offset), GPRInfo::regT0);
873
            or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);
874
            store64(GPRInfo::regT0, temporaryAddress(offset - i - 1));
875
            break;
876
        case Type::F64:
877
            parseExpr(ReturnType::F64, offset);
878
            loadDouble(temporaryAddress(offset), FPRInfo::fpRegT0);
879
            boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
880
            store64(GPRInfo::regT0, temporaryAddress(offset - i - 1));
881
            break;
882
        default:
883
            ASSERT_NOT_REACHED();
884
        }
885
    }
886
887
    addPtr(TrustedImm32(-(offset + m_currentLocalTypes.size() + 3) * 8 - 8), GPRInfo::callFrameRegister, stackPointerRegister); // FIXME: hacky
888
}
889
890
void JITCompiler::parseBinaryOp(uint8_t op, ReturnType rType, int dst)
891
{
892
    parseExpr(rType, dst);
893
    parseExpr(rType, dst + 1);
894
    switch (rType) {
895
    case ReturnType::I32:
896
        load32(temporaryAddress(dst), GPRInfo::regT0);
897
        load32(temporaryAddress(dst + 1), GPRInfo::regT1);
898
        switch (static_cast<I32>(op)) {
899
        case I32::Add:
900
            add32(GPRInfo::regT1, GPRInfo::regT0);
901
            break;
902
        case I32::Sub:
903
            sub32(GPRInfo::regT1, GPRInfo::regT0);
904
            break;
905
        case I32::Mul:
906
            mul32(GPRInfo::regT1, GPRInfo::regT0);
907
            break;
908
        case I32::BitOr:
909
            or32(GPRInfo::regT1, GPRInfo::regT0);
910
            break;
911
        case I32::BitAnd:
912
            and32(GPRInfo::regT1, GPRInfo::regT0);
913
            break;
914
        case I32::BitXor:
915
            xor32(GPRInfo::regT1, GPRInfo::regT0);
916
            break;
917
        default:
918
            ASSERT_NOT_REACHED();
919
        }
920
        store32(GPRInfo::regT0, temporaryAddress(dst));
921
        break;
922
    case ReturnType::F64:
923
        loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
924
        loadDouble(temporaryAddress(dst + 1), FPRInfo::fpRegT1);
925
        switch (static_cast<F64>(op)) {
926
        case F64::Add:
927
            addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
928
            break;
929
        case F64::Sub:
930
            subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
931
            break;
932
        case F64::Mul:
933
            mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
934
            break;
935
        case F64::Div:
936
            divDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
937
            break;
938
        default:
939
            ASSERT_NOT_REACHED();
940
        }
941
        storeDouble(FPRInfo::fpRegT0, temporaryAddress(dst));
942
        break;
943
    default:
944
        RELEASE_ASSERT_NOT_REACHED();
945
    }
946
}
947
948
void JITCompiler::parseUnaryOp(uint8_t op, ReturnType rType, int dst)
949
{
950
    parseExpr(rType, dst);
951
    switch (rType) {
952
    case ReturnType::I32:
953
        load32(temporaryAddress(dst), GPRInfo::regT0);
954
        switch (static_cast<I32>(op)) {
955
        case I32::Neg:
956
            neg32(GPRInfo::regT0);
957
            break;
958
        case I32::BitNot:
959
            xor32(TrustedImm32(-1), GPRInfo::regT0);
960
            break;
961
        default:
962
            ASSERT_NOT_REACHED();
963
        }
964
        store32(GPRInfo::regT0, temporaryAddress(dst));
965
        break;
966
    case ReturnType::F64:
967
        loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
968
        switch (static_cast<F64>(op)) {
969
        case F64::Neg:
970
            negateDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT1);
971
            break;
972
        case F64::Sqrt:
973
            sqrtDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT1);
974
            break;
975
        default:
976
            ASSERT_NOT_REACHED();
977
        }
978
        storeDouble(FPRInfo::fpRegT1, temporaryAddress(dst));
979
        break;
980
    default:
981
        RELEASE_ASSERT_NOT_REACHED();
982
    }
983
}
984
985
void JITCompiler::parseRelationalOpI32(RelationalCondition condition, int dst)
986
{
987
    parseExpr(ReturnType::I32, dst);
988
    parseExpr(ReturnType::I32, dst + 1);
989
    load32(temporaryAddress(dst), GPRInfo::regT0);
990
    load32(temporaryAddress(dst + 1), GPRInfo::regT1);
991
    compare32(condition, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
992
    store32(GPRInfo::regT0, temporaryAddress(dst));
993
}
994
995
void JITCompiler::parseRelationalOpF64(DoubleCondition condition, int dst)
996
{
997
    parseExpr(ReturnType::F64, dst);
998
    parseExpr(ReturnType::F64, dst + 1);
999
    loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
1000
    loadDouble(temporaryAddress(dst + 1), FPRInfo::fpRegT1);
1001
    Jump trueCase = branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1);
1002
    store32(TrustedImm32(0), temporaryAddress(dst));
1003
    Jump end = jump();
1004
    trueCase.link(this);
1005
    store32(TrustedImm32(1), temporaryAddress(dst));
1006
    end.link(this);
1007
}
1008
1009
void JITCompiler::parseComma(ReturnType rType, int dst)
1010
{
1011
    parseExpr(m_module->m_reader.rtype(), dst);
1012
    parseExpr(rType, dst);
1013
}
1014
1015
void JITCompiler::parseCond(ReturnType rType, int dst)
1016
{
1017
    parseExpr(ReturnType::I32, dst);
1018
    load32(temporaryAddress(dst), GPRInfo::regT0);
1019
    Jump els = branchTest32(Zero, GPRInfo::regT0);
1020
    parseExpr(rType, dst);
1021
    Jump end = jump();
1022
    els.link(this);
1023
    parseExpr(rType, dst);
1024
    end.link(this);
1025
}
1026
1027
} } // namespace JSC::Wasm
- a/Source/JavaScriptCore/wasm/WasmJITCompiler.h +146 lines
Line 0 a/Source/JavaScriptCore/wasm/WasmJITCompiler.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
/*
27
 Licensed under the Apache License, Version 2.0 (the "License");
28
 you may not use this file except in compliance with the License.
29
 You may obtain a copy of the License at
30
31
 http://www.apache.org/licenses/LICENSE-2.0
32
33
 Unless required by applicable law or agreed to in writing, software
34
 distributed under the License is distributed on an "AS IS" BASIS,
35
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
 See the License for the specific language governing permissions and
37
 limitations under the License.
38
*/
39
40
#ifndef WasmJITCompiler_h
41
#define WasmJITCompiler_h
42
43
#include "CCallHelpers.h"
44
#include "WasmModule.h"
45
46
namespace JSC {
47
48
class ExecState;
49
class JITCode;
50
class VM;
51
52
namespace Wasm {
53
54
class JumpScope;
55
56
class JITCompiler : private CCallHelpers {
57
public:
58
    JITCompiler(VM* vm, Module* module)
59
        : CCallHelpers(vm, 0)
60
        , m_module(module)
61
    {
62
    }
63
64
    RefPtr<JITCode> compileFunction(VM&, size_t functionIndex);
65
66
private:
67
    void allocateSpaceOnStack();
68
    void deallocateSpaceOnStack();
69
70
    void parseArguments(const Signature&);
71
    void parseVars();
72
73
    void parseStmt();
74
    void parseGetLocal(int dst);
75
    void parseSetLocal(uint32_t imm, int dst);
76
    void parseSetLocal(int dst);
77
    void parseReturnStmt();
78
    void parseBlockStmt();
79
    void parseStmtList();
80
    void parseIfStmt();
81
    void parseIfElseStmt();
82
    void parseWhileStmt();
83
    void parseDoStmt();
84
    void parseLabelStmt();
85
    void parseBreakStmt();
86
    void parseBreakLabelStmt();
87
    void parseContinueStmt();
88
    void parseContinueLabelStmt();
89
    void parseSwitchStmt();
90
91
    void parseExpr(ReturnType, int dst);
92
    void parseExprI32(int dst);
93
    void parseExprF64(int dst);
94
    void parseCallInternal(ReturnType, int dst);
95
    void parseCallImport(ReturnType, int dst);
96
    void callFunctionSlowCase(ReturnType, int dst);
97
    void parseCallArguments(const Vector<Type>& arguments, int dst);
98
    void parseBinaryOp(uint8_t op, ReturnType, int dst);
99
    void parseUnaryOp(uint8_t op, ReturnType, int dst);
100
    void parseRelationalOpI32(RelationalCondition, int dst);
101
    void parseRelationalOpF64(DoubleCondition, int dst);
102
    void parseComma(ReturnType, int dst);
103
    void parseCond(ReturnType, int dst);
104
105
    Address stackAddress(int i) const // FIXME: Is this correct?
106
    {
107
        return Address(GPRInfo::callFrameRegister, -i * 8 - 8);
108
    }
109
110
    Address temporaryAddress(int i) const // FIXME: Is this correct?
111
    {
112
        return Address(GPRInfo::callFrameRegister, -(i + m_currentLocalTypes.size()) * 8 - 8);
113
    }
114
115
    void pushContinueLabelLabel(Label* label) { m_continueLabelLabels.append(label); }
116
    void popContinueLabelLabel() { m_continueLabelLabels.removeLast(); }
117
    Label* continueLabelLabel(size_t i) const { return m_continueLabelLabels[i]; }
118
    void pushBreakLabelJumpList(JumpList* jumpList) { m_breakLabelJumpLists.append(jumpList); }
119
    void popBreakLabelJumpList() { m_breakLabelJumpLists.removeLast(); }
120
    JumpList* breakLabelJumpList(size_t i) const { return m_breakLabelJumpLists[i]; }
121
122
    void pushContinueJumpScope(JumpScope* jumpScope) { m_continueJumpScopes.append(jumpScope); }
123
    void popContinueJumpScope() { m_continueJumpScopes.removeLast(); }
124
    JumpScope* topContinueJumpScope() const { return m_continueJumpScopes.last(); }
125
126
    void pushBreakJumpList(JumpList* jumpList) { m_breakJumpLists.append(jumpList); }
127
    void popBreakJumpList() { m_breakJumpLists.removeLast(); }
128
    JumpList* topBreakJumpList() const { return m_breakJumpLists.last(); }
129
130
    Module* m_module;
131
132
    uint32_t m_stackHeight; // FIXME: This caused a 'segmentation fault' heisenbug when I added "size_t m_stackHeight". Something must be wrong.
133
134
    ReturnType m_currentReturnType;
135
    Vector<Type> m_currentLocalTypes;
136
137
    Vector<MacroAssembler::Label*> m_continueLabelLabels;
138
    Vector<MacroAssembler::JumpList*> m_breakLabelJumpLists;
139
140
    Vector<JumpScope*> m_continueJumpScopes;
141
    Vector<MacroAssembler::JumpList*> m_breakJumpLists;
142
};
143
144
} } // namespace JSC::Wasm
145
146
#endif // WasmJITCompiler_h
- a/Source/JavaScriptCore/wasm/WasmModule.cpp +274 lines
Line 0 a/Source/JavaScriptCore/wasm/WasmModule.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
/*
27
 Licensed under the Apache License, Version 2.0 (the "License");
28
 you may not use this file except in compliance with the License.
29
 You may obtain a copy of the License at
30
31
 http://www.apache.org/licenses/LICENSE-2.0
32
33
 Unless required by applicable law or agreed to in writing, software
34
 distributed under the License is distributed on an "AS IS" BASIS,
35
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
 See the License for the specific language governing permissions and
37
 limitations under the License.
38
*/
39
40
#include "config.h"
41
#include "WasmModule.h"
42
43
#include "JITCode.h"
44
#include "JSCellInlines.h"
45
#include "ObjectConstructor.h"
46
#include "WasmJITCompiler.h"
47
#include <wtf/text/StringBuilder.h>
48
49
namespace JSC {
50
51
namespace Wasm {
52
53
const ClassInfo Module::s_info = { "Module", &Base::s_info, 0, CREATE_METHOD_TABLE(Module) };
54
55
JSValue Module::compile(ExecState* exec, const Vector<char>& buffer)
56
{
57
    m_reader = Reader(reinterpret_cast<const uint8_t*>(buffer.data()));
58
59
    if (m_reader.fixedWidth<uint32_t>() != MagicNumber)
60
        abort();
61
    m_reader.fixedWidth<uint32_t>(); // output size in asm.js format
62
63
    parseConstantPoolSection();
64
    parseSignatureSection();
65
    parseFunctionImportSection();
66
    parseGlobalSection();
67
    parseFunctionDeclarationSection();
68
    parseFunctionPointerTables();
69
    parseFunctionDefinitionSection(exec);
70
    JSObject* object = parseExportSection(exec);
71
72
    return object;
73
}
74
75
void Module::parseConstantPoolSection()
76
{
77
    uint32_t numberOfI32s = m_reader.immU32();
78
    uint32_t numberOfF32s = m_reader.immU32();
79
    uint32_t numberOfF64s = m_reader.immU32();
80
81
    Vector<uint32_t> constantI32s(numberOfI32s);
82
    for (uint32_t i = 0; i < numberOfI32s; ++i)
83
        constantI32s[i] = m_reader.immU32();
84
85
    Vector<float> constantF32s(numberOfF32s);
86
    for (uint32_t i = 0; i < numberOfF32s; ++i)
87
        constantF32s[i] = m_reader.fixedWidth<float>();
88
89
    Vector<double> constantF64s(numberOfF64s);
90
    for (uint32_t i = 0; i < numberOfF64s; ++i)
91
        constantF64s[i] = m_reader.fixedWidth<double>();
92
93
    m_constantI32s = WTF::move(constantI32s);
94
    m_constantF32s = WTF::move(constantF32s);
95
    m_constantF64s = WTF::move(constantF64s);
96
}
97
98
void Module::parseSignatureSection()
99
{
100
    uint32_t numberOfSignatures = m_reader.immU32();
101
    Vector<Signature> signatures(numberOfSignatures);
102
    for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
103
        ReturnType returnType = m_reader.rtype();
104
        uint32_t argumentCount = m_reader.immU32();
105
        Signature signature(returnType, argumentCount);
106
        for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex)
107
            signature.arguments[argumentIndex] = m_reader.type();
108
        signatures[signatureIndex] = WTF::move(signature);
109
    }
110
111
    m_signatures = WTF::move(signatures);
112
}
113
114
void Module::parseFunctionImportSection()
115
{
116
    uint32_t numberOfFuncImports = m_reader.immU32();
117
    uint32_t numberOfFuncImportSignatures = m_reader.immU32();
118
119
    m_functionImportNames.reserveCapacity(numberOfFuncImports);
120
121
    Vector<FuncImportSignature> funcImportSignatures(numberOfFuncImportSignatures);
122
    FuncImportSignature* funcImportSignature = funcImportSignatures.data();
123
    for (uint32_t funcImportIndex = 0; funcImportIndex < numberOfFuncImports; ++funcImportIndex) {
124
        StringBuilder builder;
125
        while (char c = m_reader.singleChar())
126
            builder.append(c);
127
        m_functionImportNames.append(builder.toString());
128
        // printf("%s\n", builder.toString().utf8().data());
129
130
        uint32_t numberOfSignatures = m_reader.immU32();
131
        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
132
            funcImportSignature->signatureIndex = m_reader.immU32();
133
            funcImportSignature->funcImportIndex = funcImportIndex;
134
            funcImportSignature++;
135
        }
136
    }
137
    assert(funcImportSignature == funcImportSignatures.data() + numberOfFuncImportSignatures);
138
139
    m_funcImportSignatures = WTF::move(funcImportSignatures);
140
}
141
142
void Module::parseGlobalSection()
143
{
144
    uint32_t numberOfI32Zero = m_reader.immU32();
145
    uint32_t numberOfF32Zero = m_reader.immU32();
146
    uint32_t numberOfF64Zero = m_reader.immU32();
147
    uint32_t numberOfI32Import = m_reader.immU32();
148
    uint32_t numberOfF32Import = m_reader.immU32();
149
    uint32_t numberOfF64Import = m_reader.immU32();
150
    uint32_t numberOfGlobalVars = numberOfI32Zero + numberOfF32Zero + numberOfF64Zero + numberOfI32Import + numberOfF32Import + numberOfF64Import;
151
152
    Vector<Type> globalTypes(numberOfGlobalVars);
153
    size_t globalTypeIndex = 0;
154
    for (uint32_t i = 0; i < numberOfI32Zero; ++i)
155
        globalTypes[globalTypeIndex++] = Type::I32;
156
    for (uint32_t i = 0; i < numberOfF32Zero; ++i)
157
        globalTypes[globalTypeIndex++] = Type::F32;
158
    for (uint32_t i = 0; i < numberOfF64Zero; ++i)
159
        globalTypes[globalTypeIndex++] = Type::F64;
160
    for (uint32_t i = 0; i < numberOfI32Import; ++i) {
161
        while (m_reader.singleChar()) { }
162
        globalTypes[globalTypeIndex++] = Type::I32;
163
    }
164
    for (uint32_t i = 0; i < numberOfF32Import; ++i) {
165
        while (m_reader.singleChar()) { }
166
        globalTypes[globalTypeIndex++] = Type::F32;
167
    }
168
    for (uint32_t i = 0; i < numberOfF64Import; ++i) {
169
        while (m_reader.singleChar()) { }
170
        globalTypes[globalTypeIndex++] = Type::F64;
171
    }
172
    m_globalTypes = WTF::move(globalTypes);
173
}
174
175
void Module::parseFunctionDeclarationSection()
176
{
177
    uint32_t numberOfFunctions = m_reader.immU32();
178
    Vector<uint32_t> funcSignatures(numberOfFunctions);
179
    for (uint32_t i = 0; i < numberOfFunctions; ++i)
180
        funcSignatures[i] = m_reader.immU32();
181
182
    m_funcSignatures = WTF::move(funcSignatures);
183
}
184
185
void Module::parseFunctionPointerTables()
186
{
187
    uint32_t numberOfFuncPtrTables = m_reader.immU32();
188
    Vector<FuncPtrTable> funcPtrTables(numberOfFuncPtrTables);
189
    for (uint32_t i = 0; i < numberOfFuncPtrTables; ++i) {
190
        funcPtrTables[i].signatureIndex = m_reader.immU32();
191
        uint32_t numElements = m_reader.immU32();
192
        Vector<uint32_t> elements(numElements);
193
        for (uint32_t j = 0; j < numElements; ++j)
194
            elements[j] = m_reader.immU32();
195
        funcPtrTables[i].elements = WTF::move(elements);
196
    }
197
198
    m_funcPtrTables = WTF::move(funcPtrTables);
199
}
200
201
void Module::parseFunctionDefinitionSection(ExecState* exec)
202
{
203
    for (size_t i = 0; i < m_funcSignatures.size(); ++i)
204
        parseFunctionDefinition(exec, i);
205
}
206
207
JSObject* Module::parseExportSection(ExecState* exec)
208
{
209
    switch (m_reader.exportFormat()) {
210
    case ExportFormat::Default: {
211
        uint32_t functionIndex = m_reader.immU32();
212
        return m_functions[functionIndex].get();
213
    }
214
    case ExportFormat::Record: {
215
        JSObject* object = constructEmptyObject(exec);
216
        uint32_t numberOfExports = m_reader.immU32();
217
        VM& vm = exec->vm();
218
        for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
219
            StringBuilder builder;
220
            while (char c = m_reader.singleChar())
221
                builder.append(c);
222
            uint32_t functionIndex = m_reader.immU32();
223
            Identifier identifier = Identifier::fromString(&vm, builder.toString());
224
            object->putDirect(vm, identifier, m_functions[functionIndex].get());
225
        }
226
        return object;
227
    }
228
    default:
229
        RELEASE_ASSERT_NOT_REACHED();
230
    }
231
    return nullptr;
232
}
233
234
void Module::parseFunctionDefinition(ExecState* exec, size_t functionIndex)
235
{
236
    JITCompiler jitCompiler(&exec->vm(), this);
237
    RefPtr<JITCode> jitCode = jitCompiler.compileFunction(exec->vm(), functionIndex);
238
239
    VM& vm = exec->vm();
240
241
    WebAssemblyExecutable* executable = WebAssemblyExecutable::create(vm, SourceCode());
242
243
    DeferGC deferGC(vm.heap);
244
245
    RefPtr<WebAssemblyCodeBlock> codeBlock = adoptRef(new WebAssemblyCodeBlock(executable, exec->lexicalGlobalObject()));
246
    codeBlock->setJITCode(jitCode);
247
    executable->installCode(codeBlock.get());
248
249
    JSFunction* jsFunction = JSFunction::create(vm, executable, exec->lexicalGlobalObject());
250
    m_functions.append(WriteBarrier<JSFunction>(vm, this, jsFunction));
251
}
252
253
EncodedJSValue Module::internalFunction(size_t functionIndex)
254
{
255
    return JSValue::encode(m_functions[functionIndex].get());
256
}
257
258
void Module::visitChildren(JSCell* cell, SlotVisitor& visitor)
259
{
260
    // FIXME: Why is this never called?
261
    Module* thisObject = static_cast<Module*>(cell);
262
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
263
    Base::visitChildren(thisObject, visitor);
264
    for (auto function : thisObject->m_functions)
265
        visitor.append(&function);
266
}
267
268
JSValue compile(ExecState* exec, const Vector<char>& buffer)
269
{
270
    Module* module = Module::create(exec->vm(), exec->lexicalGlobalObject());
271
    return module->compile(exec, buffer);
272
}
273
274
} } // namespace JSC::Wasm
- a/Source/JavaScriptCore/wasm/WasmModule.h +126 lines
Line 0 a/Source/JavaScriptCore/wasm/WasmModule.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
/*
27
 Licensed under the Apache License, Version 2.0 (the "License");
28
 you may not use this file except in compliance with the License.
29
 You may obtain a copy of the License at
30
31
 http://www.apache.org/licenses/LICENSE-2.0
32
33
 Unless required by applicable law or agreed to in writing, software
34
 distributed under the License is distributed on an "AS IS" BASIS,
35
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
 See the License for the specific language governing permissions and
37
 limitations under the License.
38
*/
39
40
#ifndef WasmModule_h
41
#define WasmModule_h
42
43
#include "JSObject.h"
44
#include "WasmOpcodes.h"
45
46
namespace JSC {
47
48
class JITCode;
49
class JITCompiler;
50
51
namespace Wasm {
52
53
class Module : public JSNonFinalObject {
54
public:
55
    typedef JSNonFinalObject Base;
56
57
    struct FuncImportSignature {
58
        uint32_t signatureIndex;
59
        uint32_t funcImportIndex;
60
    };
61
62
    struct FuncPtrTable {
63
        uint32_t signatureIndex;
64
        Vector<uint32_t> elements;
65
    };
66
67
    Module(VM& vm, Structure* structure)
68
        : Base(vm, structure)
69
    {
70
    }
71
72
    static Module* create(VM& vm, JSGlobalObject* globalObject)
73
    {
74
        Structure* structure = createStructure(vm, globalObject); // FIXME: is this right?
75
        Module* module = new (NotNull, allocateCell<Module>(vm.heap)) Module(vm, structure);
76
        module->finishCreation(vm);
77
        return module;
78
    }
79
80
    DECLARE_INFO;
81
82
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
83
    {
84
        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
85
    }
86
87
    JSValue compile(ExecState*, const Vector<char>& buffer);
88
    EncodedJSValue internalFunction(size_t functionIndex);
89
    const String& functionImportName(size_t functionImportIndex) const { return m_functionImportNames[functionImportIndex]; }
90
91
    static void visitChildren(JSCell*, SlotVisitor&);
92
93
private:
94
    friend class JITCompiler;
95
96
    void parseConstantPoolSection();
97
    void parseSignatureSection();
98
    void parseFunctionImportSection();
99
    void parseGlobalSection();
100
    void parseFunctionDeclarationSection();
101
    void parseFunctionPointerTables();
102
    void parseFunctionDefinitionSection(ExecState*);
103
    JSObject* parseExportSection(ExecState*);
104
105
    void parseFunctionDefinition(ExecState*, size_t functionIndex);
106
107
    Reader m_reader;
108
109
    Vector<Signature> m_signatures;
110
    Vector<uint32_t> m_constantI32s;
111
    Vector<float> m_constantF32s;
112
    Vector<double> m_constantF64s;
113
    Vector<String> m_functionImportNames;
114
    Vector<FuncImportSignature> m_funcImportSignatures;
115
    Vector<Type> m_globalTypes;
116
    Vector<uint32_t> m_funcSignatures;
117
    Vector<FuncPtrTable> m_funcPtrTables;
118
119
    Vector<WriteBarrier<JSFunction>> m_functions;
120
};
121
122
JS_EXPORT_PRIVATE JSValue compile(ExecState*, const Vector<char>& buffer);
123
124
} } // namespace JSC::Wasm
125
126
#endif // WasmModule_h
- a/Source/JavaScriptCore/wasm/WasmOpcodes.h +591 lines
Line 0 a/Source/JavaScriptCore/wasm/WasmOpcodes.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
/*
27
 Licensed under the Apache License, Version 2.0 (the "License");
28
 you may not use this file except in compliance with the License.
29
 You may obtain a copy of the License at
30
31
 http://www.apache.org/licenses/LICENSE-2.0
32
33
 Unless required by applicable law or agreed to in writing, software
34
 distributed under the License is distributed on an "AS IS" BASIS,
35
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36
 See the License for the specific language governing permissions and
37
 limitations under the License.
38
*/
39
40
#ifndef WasmOpcodes_h
41
#define WasmOpcodes_h
42
43
#include <wtf/Vector.h>
44
45
namespace JSC {
46
47
namespace Wasm {
48
49
static const uint32_t MagicNumber = 0x6d736177;
50
51
enum class Stmt : uint8_t {
52
    SetLoc,
53
    SetGlo,
54
    I32Store8,
55
    I32StoreOff8,
56
    I32Store16,
57
    I32StoreOff16,
58
    I32Store32,
59
    I32StoreOff32,
60
    F32Store,
61
    F32StoreOff,
62
    F64Store,
63
    F64StoreOff,
64
    CallInt,
65
    CallInd,
66
    CallImp,
67
    Ret,
68
    Block,
69
    IfThen,
70
    IfElse,
71
    While,
72
    Do,
73
    Label,
74
    Break,
75
    BreakLabel,
76
    Continue,
77
    ContinueLabel,
78
    Switch,
79
80
    Bad
81
};
82
83
enum class StmtWithImm : uint8_t {
84
    SetLoc,
85
    SetGlo,
86
    Reseved1,
87
    Reseved2,
88
89
    Bad
90
};
91
92
enum class SwitchCase : uint8_t {
93
    Case0,
94
    Case1,
95
    CaseN,
96
    Default0,
97
    Default1,
98
    DefaultN
99
};
100
101
enum class I32 : uint8_t {
102
    LitPool,
103
    LitImm,
104
    GetLoc,
105
    GetGlo,
106
    SetLoc,
107
    SetGlo,
108
    SLoad8,
109
    SLoadOff8,
110
    ULoad8,
111
    ULoadOff8,
112
    SLoad16,
113
    SLoadOff16,
114
    ULoad16,
115
    ULoadOff16,
116
    Load32,
117
    LoadOff32,
118
    Store8,
119
    StoreOff8,
120
    Store16,
121
    StoreOff16,
122
    Store32,
123
    StoreOff32,
124
    CallInt,
125
    CallInd,
126
    CallImp,
127
    Cond,
128
    Comma,
129
    FromF32,
130
    FromF64,
131
    Neg,
132
    Add,
133
    Sub,
134
    Mul,
135
    SDiv,
136
    UDiv,
137
    SMod,
138
    UMod,
139
    BitNot,
140
    BitOr,
141
    BitAnd,
142
    BitXor,
143
    Lsh,
144
    ArithRsh,
145
    LogicRsh,
146
    Clz,
147
    LogicNot,
148
    EqI32,
149
    EqF32,
150
    EqF64,
151
    NEqI32,
152
    NEqF32,
153
    NEqF64,
154
    SLeThI32,
155
    ULeThI32,
156
    LeThF32,
157
    LeThF64,
158
    SLeEqI32,
159
    ULeEqI32,
160
    LeEqF32,
161
    LeEqF64,
162
    SGrThI32,
163
    UGrThI32,
164
    GrThF32,
165
    GrThF64,
166
    SGrEqI32,
167
    UGrEqI32,
168
    GrEqF32,
169
    GrEqF64,
170
    SMin,
171
    UMin,
172
    SMax,
173
    UMax,
174
    Abs,
175
176
    Bad
177
};
178
179
enum class I32WithImm : uint8_t {
180
    LitPool,
181
    LitImm,
182
    GetLoc,
183
    Reserved,
184
185
    Bad
186
};
187
188
enum class F32 : uint8_t {
189
    LitPool,
190
    LitImm,
191
    GetLoc,
192
    GetGlo,
193
    SetLoc,
194
    SetGlo,
195
    Load,
196
    LoadOff,
197
    Store,
198
    StoreOff,
199
    CallInt,
200
    CallInd,
201
    Cond,
202
    Comma,
203
    FromS32,
204
    FromU32,
205
    FromF64,
206
    Neg,
207
    Add,
208
    Sub,
209
    Mul,
210
    Div,
211
    Abs,
212
    Ceil,
213
    Floor,
214
    Sqrt,
215
216
    Bad
217
};
218
219
enum class F32WithImm : uint8_t {
220
    LitPool,
221
    GetLoc,
222
    Reserved0,
223
    Reserved1,
224
225
    Bad
226
};
227
228
enum class F64 : uint8_t {
229
    LitPool,
230
    LitImm,
231
    GetLoc,
232
    GetGlo,
233
    SetLoc,
234
    SetGlo,
235
    Load,
236
    LoadOff,
237
    Store,
238
    StoreOff,
239
    CallInt,
240
    CallInd,
241
    CallImp,
242
    Cond,
243
    Comma,
244
    FromS32,
245
    FromU32,
246
    FromF32,
247
    Neg,
248
    Add,
249
    Sub,
250
    Mul,
251
    Div,
252
    Mod,
253
    Min,
254
    Max,
255
    Abs,
256
    Ceil,
257
    Floor,
258
    Sqrt,
259
    Cos,
260
    Sin,
261
    Tan,
262
    ACos,
263
    ASin,
264
    ATan,
265
    ATan2,
266
    Exp,
267
    Ln,
268
    Pow,
269
270
    Bad
271
};
272
273
enum class F64WithImm : uint8_t {
274
    LitPool,
275
    GetLoc,
276
    Reserved0,
277
    Reserved1,
278
279
    Bad
280
};
281
282
enum class Void : uint8_t {
283
    CallInt,
284
    CallInd,
285
    CallImp,
286
287
    Bad
288
};
289
290
enum class Type : uint8_t {
291
    I32,
292
    F32,
293
    F64
294
};
295
296
enum class VarTypes : uint8_t {
297
    I32 = 0x1,
298
    F32 = 0x2,
299
    F64 = 0x4,
300
};
301
302
inline VarTypes operator| (VarTypes lhs, VarTypes rhs) { return VarTypes(uint8_t(lhs) | uint8_t(rhs)); }
303
inline bool operator&(VarTypes lhs, VarTypes rhs) { return bool(uint8_t(lhs) & uint8_t(rhs)); }
304
305
enum class VarTypesWithImm : uint8_t {
306
    OnlyI32,
307
    Reserved0,
308
    Reserved1,
309
    Reserved2
310
};
311
312
enum class ReturnType : uint8_t {
313
    I32 = uint8_t(Type::I32),
314
    F32 = uint8_t(Type::F32),
315
    F64 = uint8_t(Type::F64),
316
    Void
317
};
318
319
class Expr {
320
public:
321
    Expr()
322
    : m_type(ReturnType(-1)), u { }
323
    {
324
    }
325
    Expr(I32 i32) : m_type(ReturnType::I32) { u.i32 = i32; }
326
    Expr(F32 f32) : m_type(ReturnType::F32) { u.f32 = f32; }
327
    Expr(F64 f64) : m_type(ReturnType::F64) { u.f64 = f64; }
328
    Expr(Void v) : m_type(ReturnType::Void) { u.v = v; }
329
330
    ReturnType type() const { return m_type; }
331
    I32 i32() const { return u.i32; }
332
    F32 f32() const { return u.f32; }
333
    F64 f64() const { return u.f64; }
334
335
    bool operator==(Expr rhs) const { return m_type == rhs.m_type && u.raw == rhs.u.raw; }
336
    bool operator!=(Expr rhs) const { return !(*this == rhs); }
337
338
private:
339
    ReturnType m_type;
340
    union U {
341
        I32 i32;
342
        F32 f32;
343
        F64 f64;
344
        Void v;
345
        uint8_t raw;
346
    } u;
347
348
    static_assert(sizeof(U) == sizeof(uint8_t), "Exact overlay of raw_");
349
};
350
351
static const uint8_t HasImmFlag = 0x80;
352
static_assert(uint8_t(I32::Bad) <= HasImmFlag, "MSB reserved to distinguish I32 from I32WithImm");
353
static_assert(uint8_t(F32::Bad) <= HasImmFlag, "MSB reserved to distinguish F32 from F32WithImm");
354
static_assert(uint8_t(F64::Bad) <= HasImmFlag, "MSB reserved to distinguish F64 from F64WithImm");
355
356
static const unsigned OpWithImmBits = 2;
357
static const uint32_t OpWithImmLimit = 1 << OpWithImmBits;
358
static_assert(uint8_t(I32WithImm::Bad) <= OpWithImmLimit, "I32WithImm op fits");
359
static_assert(uint8_t(F32WithImm::Bad) <= OpWithImmLimit, "F32WithImm op fits");
360
static_assert(uint8_t(F64WithImm::Bad) <= OpWithImmLimit, "F64WithImm op fits");
361
362
static const unsigned ImmBits = 5;
363
static const uint32_t ImmLimit = 1 << ImmBits;
364
static_assert((1 + OpWithImmBits + ImmBits) == 8, "Bits of immediate op should add up to a byte");
365
366
static inline uint8_t PackOpWithImm(uint8_t op, uint8_t imm)
367
{
368
    assert(op < OpWithImmLimit);
369
    assert(imm < ImmLimit);
370
    return HasImmFlag | (uint8_t(op) << ImmBits) | imm;
371
}
372
373
template <class TWithImm>
374
static inline void UnpackOpWithImm(uint8_t byte, TWithImm* op, uint8_t *imm)
375
{
376
    assert(byte & HasImmFlag);
377
    *op = TWithImm((byte >> ImmBits) & (OpWithImmLimit - 1));
378
    *imm = byte & (ImmLimit - 1);
379
}
380
381
class ExprWithImm {
382
public:
383
    ExprWithImm()
384
        : m_type(Type(-1))
385
    {
386
    }
387
    ExprWithImm(I32WithImm i32) : m_type(Type::I32) { u.i32 = i32; }
388
    ExprWithImm(F32WithImm f32) : m_type(Type::F32) { u.f32 = f32; }
389
    ExprWithImm(F64WithImm f64) : m_type(Type::F64) { u.f64 = f64; }
390
391
    Type type() const { return m_type; }
392
    I32WithImm i32() const { return u.i32; }
393
    F32WithImm f32() const { return u.f32; }
394
    F64WithImm f64() const { return u.f64; }
395
396
private:
397
    Type m_type;
398
    union U {
399
        I32WithImm i32;
400
        F32WithImm f32;
401
        F64WithImm f64;
402
        uint8_t raw;
403
    } u;
404
405
    static_assert(sizeof(U) == sizeof(uint8_t), "Exact overlay of raw_");
406
};
407
408
enum class ExportFormat : uint8_t {
409
    Default,
410
    Record
411
};
412
413
struct Signature {
414
    ReturnType returnType;
415
    Vector<Type> arguments;
416
417
    Signature() { }
418
    Signature(ReturnType returnType)
419
        : returnType(returnType) { }
420
    Signature(ReturnType returnType, uint32_t argumentCount)
421
        : returnType(returnType)
422
        , arguments(argumentCount) { }
423
    Signature(ReturnType returnType, Vector<Type>&& arguments)
424
        : returnType(returnType)
425
        , arguments(WTF::move(arguments)) { }
426
427
    bool operator==(const Signature& rhs) const { return returnType == rhs.returnType && arguments == rhs.arguments; }
428
    bool operator!=(const Signature& rhs) const { return !(*this == rhs); }
429
430
    struct Hash {
431
        bool operator()(const Signature &signature) const
432
        {
433
            static_assert(sizeof(Type) == 1 && sizeof(ReturnType) == 1, "Shift more");
434
            uint32_t h = uint8_t(signature.returnType);
435
            for (Type t : signature.arguments)
436
                h = ((h << 2) | uint8_t(t)) ^ (h >> 30);
437
            return h;
438
        }
439
    };
440
};
441
442
class Reader {
443
public:
444
    Reader() { }
445
    Reader(const uint8_t* begin)
446
        : m_cursor(begin)
447
    {
448
    }
449
450
    template <class T> T fixedWidth();
451
    Stmt stmt() { return u8<Stmt>(); }
452
    SwitchCase switchCase() { return u8<SwitchCase>(); }
453
    template<class T, class TWithImm> inline bool code(T*, TWithImm*, uint8_t*);
454
    Void voidExpr() { return u8<Void>(); }
455
    ExportFormat exportFormat() { return u8<ExportFormat>(); }
456
    Type type() { return u8<Type>(); }
457
    ReturnType rtype() { return u8<ReturnType>(); }
458
    inline uint32_t immU32();
459
    inline int32_t immS32();
460
    char singleChar() { return *m_cursor++; }
461
462
    inline bool ifI32Lit(const Vector<uint32_t>& i32s, uint32_t*);
463
464
private:
465
    template <class T> T u8() { return T(*m_cursor++); }
466
467
    const uint8_t* m_cursor;
468
};
469
470
template <>
471
inline uint32_t Reader::fixedWidth<uint32_t>()
472
{
473
    uint32_t u32 = m_cursor[0] | m_cursor[1] << 8 | m_cursor[2] << 16 | m_cursor[3] << 24;
474
    m_cursor += 4;
475
    return u32;
476
}
477
478
template <>
479
inline float Reader::fixedWidth<float>()
480
{
481
    union {
482
        uint8_t arr[4];
483
        float f;
484
    } u = { { m_cursor[0], m_cursor[1], m_cursor[2], m_cursor[3] } };
485
    m_cursor += 4;
486
    return u.f;
487
}
488
489
template <>
490
inline double Reader::fixedWidth<double>()
491
{
492
    union {
493
        uint8_t arr[8];
494
        double d;
495
    } u = { { m_cursor[0], m_cursor[1], m_cursor[2], m_cursor[3], m_cursor[4], m_cursor[5], m_cursor[6], m_cursor[7] } };
496
    m_cursor += 8;
497
    return u.d;
498
}
499
500
template <class T, class TWithImm>
501
bool Reader::code(T* t, TWithImm* tWithImm, uint8_t* imm)
502
{
503
    uint8_t byte = *m_cursor++;
504
    if (!(byte & HasImmFlag)) {
505
        *t = T(byte);
506
        return true;
507
    }
508
509
    UnpackOpWithImm(byte, tWithImm, imm);
510
    return false;
511
}
512
513
inline uint32_t Reader::immU32()
514
{
515
    uint32_t u32 = *m_cursor++;
516
    if (u32 < 0x80)
517
        return u32;
518
519
    u32 &= 0x7f;
520
521
    for (unsigned shift = 7; true; shift += 7) {
522
        uint32_t b = *m_cursor++;
523
        if (b < 0x80)
524
            return u32 | (b << shift);
525
        u32 |= (b & 0x7f) << shift;
526
    }
527
}
528
529
inline int32_t Reader::immS32()
530
{
531
    uint32_t u32 = *m_cursor++;
532
    if (u32 < 0x80)
533
        return int32_t(u32) << (32-7) >> (32-7);
534
535
    u32 &= 0x7f;
536
537
    for (unsigned shift = 7; true; shift += 7) {
538
        uint32_t b = *m_cursor++;
539
        if (b < 0x80) {
540
            u32 |= b << shift;
541
            int signExtend = (32-7) - shift;
542
            if (signExtend > 0)
543
                return int32_t(u32) << signExtend >> signExtend;
544
            return int32_t(u32);
545
        }
546
        u32 |= (b & 0x7f) << shift;
547
    }
548
}
549
550
inline bool Reader::ifI32Lit(const Vector<uint32_t>& i32s, uint32_t* u32)
551
{
552
    uint8_t byte = *m_cursor;
553
554
    if (byte & HasImmFlag) {
555
        I32WithImm i32WithImm;
556
        uint8_t imm;
557
        UnpackOpWithImm(byte, &i32WithImm, &imm);
558
559
        if (i32WithImm == I32WithImm::LitImm) {
560
            m_cursor++;
561
            *u32 = imm;
562
            return true;
563
        }
564
565
        if (i32WithImm == I32WithImm::LitPool) {
566
            m_cursor++;
567
            *u32 = i32s[imm];
568
            return true;
569
        }
570
571
        return false;
572
    }
573
574
    if (I32(byte) == I32::LitImm) {
575
        m_cursor++;
576
        *u32 = immU32();
577
        return true;
578
    }
579
580
    if (I32(byte) == I32::LitPool) {
581
        m_cursor++;
582
        *u32 = i32s[immU32()];
583
        return true;
584
    }
585
586
    return false;
587
}
588
589
} } // namespace JSC::Wasm
590
591
#endif // WasmOpcodes_h

Return to Bug 146064