| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +152 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2015-07-09  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
        * jsc.cpp:
16
        (GlobalObject::finishCreation):
17
        (functionLoadWebAssembly):
18
        * llint/LLIntSlowPaths.cpp:
19
        (JSC::LLInt::setUpCall):
20
        * runtime/Executable.cpp:
21
        (JSC::ScriptExecutable::installCode):
22
        (JSC::ScriptExecutable::newCodeBlockFor):
23
        (JSC::ScriptExecutable::prepareForExecutionImpl):
24
        (JSC::WebAssemblyExecutable::WebAssemblyExecutable):
25
        (JSC::WebAssemblyExecutable::finishCreation):
26
        (JSC::WebAssemblyExecutable::destroy):
27
        (JSC::WebAssemblyExecutable::baselineCodeBlockFor):
28
        (JSC::WebAssemblyExecutable::visitChildren):
29
        (JSC::WebAssemblyExecutable::symbolTable):
30
        (JSC::WebAssemblyExecutable::clearCode):
31
        (JSC::WebAssemblyExecutable::unlinkCalls):
32
        * runtime/Executable.h:
33
        (JSC::ExecutableBase::isWebAssemblyExecutable):
34
        * runtime/JSFunction.cpp:
35
        (JSC::JSFunction::create):
36
        * runtime/JSFunction.h:
37
        (JSC::JSFunction::createImpl):
38
        * runtime/JSFunctionInlines.h:
39
        (JSC::JSFunction::JSFunction):
40
        (JSC::JSFunction::isHostFunction):
41
        * runtime/JSType.h:
42
        * runtime/VM.cpp:
43
        (JSC::VM::VM):
44
        * runtime/VM.h:
45
        * wasm/WasmJITCompiler.cpp: Added.
46
        (JSC::Wasm::JumpScope::JumpScope):
47
        (JSC::Wasm::JumpScope::jump):
48
        (JSC::Wasm::JumpScope::link):
49
        (JSC::Wasm::JITCompiler::compileFunction):
50
        (JSC::Wasm::JITCompiler::allocateSpaceOnStack):
51
        (JSC::Wasm::JITCompiler::deallocateSpaceOnStack):
52
        (JSC::Wasm::JITCompiler::parseArguments):
53
        (JSC::Wasm::JITCompiler::parseVars):
54
        (JSC::Wasm::JITCompiler::parseStmt):
55
        (JSC::Wasm::JITCompiler::parseGetLocal):
56
        (JSC::Wasm::JITCompiler::parseSetLocal):
57
        (JSC::Wasm::JITCompiler::parseReturnStmt):
58
        (JSC::Wasm::JITCompiler::parseStmtList):
59
        (JSC::Wasm::JITCompiler::parseBlockStmt):
60
        (JSC::Wasm::JITCompiler::parseIfStmt):
61
        (JSC::Wasm::JITCompiler::parseIfElseStmt):
62
        (JSC::Wasm::JITCompiler::parseWhileStmt):
63
        (JSC::Wasm::JITCompiler::parseDoStmt):
64
        (JSC::Wasm::JITCompiler::parseLabelStmt):
65
        (JSC::Wasm::JITCompiler::parseBreakStmt):
66
        (JSC::Wasm::JITCompiler::parseBreakLabelStmt):
67
        (JSC::Wasm::JITCompiler::parseContinueStmt):
68
        (JSC::Wasm::JITCompiler::parseContinueLabelStmt):
69
        (JSC::Wasm::JITCompiler::parseSwitchStmt):
70
        (JSC::Wasm::JITCompiler::parseExpr):
71
        (JSC::Wasm::JITCompiler::parseExprI32):
72
        (JSC::Wasm::JITCompiler::parseExprF64):
73
        (JSC::Wasm::callInternalFunction):
74
        (JSC::Wasm::JITCompiler::parseCallInternal):
75
        (JSC::Wasm::JITCompiler::parseBinaryOp):
76
        (JSC::Wasm::JITCompiler::parseUnaryOp):
77
        (JSC::Wasm::JITCompiler::parseRelationalOpI32):
78
        (JSC::Wasm::JITCompiler::parseRelationalOpF64):
79
        (JSC::Wasm::JITCompiler::parseComma):
80
        (JSC::Wasm::JITCompiler::parseCond):
81
        * wasm/WasmJITCompiler.h: Added.
82
        (JSC::Wasm::JITCompiler::JITCompiler):
83
        (JSC::Wasm::JITCompiler::appendCall):
84
        (JSC::Wasm::JITCompiler::stackAddress):
85
        (JSC::Wasm::JITCompiler::temporaryAddress):
86
        (JSC::Wasm::JITCompiler::pushContinueLabelLabel):
87
        (JSC::Wasm::JITCompiler::popContinueLabelLabel):
88
        (JSC::Wasm::JITCompiler::continueLabelLabel):
89
        (JSC::Wasm::JITCompiler::pushBreakLabelJumpList):
90
        (JSC::Wasm::JITCompiler::popBreakLabelJumpList):
91
        (JSC::Wasm::JITCompiler::breakLabelJumpList):
92
        (JSC::Wasm::JITCompiler::pushContinueJumpScope):
93
        (JSC::Wasm::JITCompiler::popContinueJumpScope):
94
        (JSC::Wasm::JITCompiler::topContinueJumpScope):
95
        (JSC::Wasm::JITCompiler::pushBreakJumpList):
96
        (JSC::Wasm::JITCompiler::popBreakJumpList):
97
        (JSC::Wasm::JITCompiler::topBreakJumpList):
98
        * wasm/WasmModule.cpp: Added.
99
        (JSC::Wasm::Module::compile):
100
        (JSC::Wasm::Module::parseConstantPoolSection):
101
        (JSC::Wasm::Module::parseSignatureSection):
102
        (JSC::Wasm::Module::parseFunctionImportSection):
103
        (JSC::Wasm::Module::parseGlobalSection):
104
        (JSC::Wasm::Module::parseFunctionDeclarationSection):
105
        (JSC::Wasm::Module::parseFunctionPointerTables):
106
        (JSC::Wasm::Module::parseFunctionDefinitionSection):
107
        (JSC::Wasm::Module::parseExportSection):
108
        (JSC::Wasm::Module::parseFunctionDefinition):
109
        (JSC::Wasm::Module::callInternalFunction):
110
        (JSC::Wasm::compile):
111
        * wasm/WasmModule.h: Added.
112
        (JSC::Wasm::Module::Module):
113
        (JSC::Wasm::Module::create):
114
        (JSC::Wasm::Module::createStructure):
115
        * wasm/WasmOpcodes.h: Added.
116
        (JSC::Wasm::operator| ):
117
        (JSC::Wasm::operator&):
118
        (JSC::Wasm::Expr::Expr):
119
        (JSC::Wasm::Expr::type):
120
        (JSC::Wasm::Expr::i32):
121
        (JSC::Wasm::Expr::f32):
122
        (JSC::Wasm::Expr::f64):
123
        (JSC::Wasm::Expr::operator==):
124
        (JSC::Wasm::Expr::operator!=):
125
        (JSC::Wasm::PackOpWithImm):
126
        (JSC::Wasm::UnpackOpWithImm):
127
        (JSC::Wasm::ExprWithImm::ExprWithImm):
128
        (JSC::Wasm::ExprWithImm::type):
129
        (JSC::Wasm::ExprWithImm::i32):
130
        (JSC::Wasm::ExprWithImm::f32):
131
        (JSC::Wasm::ExprWithImm::f64):
132
        (JSC::Wasm::Signature::Signature):
133
        (JSC::Wasm::Signature::operator==):
134
        (JSC::Wasm::Signature::operator!=):
135
        (JSC::Wasm::Signature::Hash::operator()):
136
        (JSC::Wasm::Reader::Reader):
137
        (JSC::Wasm::Reader::stmt):
138
        (JSC::Wasm::Reader::switchCase):
139
        (JSC::Wasm::Reader::voidExpr):
140
        (JSC::Wasm::Reader::exportFormat):
141
        (JSC::Wasm::Reader::type):
142
        (JSC::Wasm::Reader::rtype):
143
        (JSC::Wasm::Reader::singleChar):
144
        (JSC::Wasm::Reader::u8):
145
        (JSC::Wasm::Reader::fixedWidth<uint32_t>):
146
        (JSC::Wasm::Reader::fixedWidth<float>):
147
        (JSC::Wasm::Reader::fixedWidth<double>):
148
        (JSC::Wasm::Reader::code):
149
        (JSC::Wasm::Reader::immU32):
150
        (JSC::Wasm::Reader::immS32):
151
        (JSC::Wasm::Reader::ifI32Lit):
152
1
2015-06-20  Yusuke Suzuki  <utatane.tea@gmail.com>
153
2015-06-20  Yusuke Suzuki  <utatane.tea@gmail.com>
2
154
3
        [ES6] Destructuring assignment need to accept iterables
155
        [ES6] Destructuring assignment need to accept iterables
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +28 lines
Lines 1016-1021 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
1016
		70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
1016
		70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */; };
1017
		70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
1017
		70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6031AFDBEA200449739 /* TemplateRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
1018
		70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
1018
		70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
1019
		7B2076361B4DC05900F7BB93 /* WasmModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2076351B4DC05600F7BB93 /* WasmModule.h */; settings = {ATTRIBUTES = (Private, ); }; };
1020
		7B2076371B4DC05E00F7BB93 /* WasmModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B2076341B4DC05600F7BB93 /* WasmModule.cpp */; };
1021
		7B545E501B4605C70029390E /* WasmJITCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B545E4D1B4605C30029390E /* WasmJITCompiler.cpp */; };
1022
		7B545E511B4605D30029390E /* WasmJITCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B545E4E1B4605C30029390E /* WasmJITCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
1023
		7B545E521B4605D80029390E /* WasmOpcodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B545E4F1B4605C30029390E /* WasmOpcodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
1019
		7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */; };
1024
		7C008CD2186F8A9300955C24 /* JSPromiseFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */; };
1020
		7C008CD3186F8A9300955C24 /* JSPromiseFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
1025
		7C008CD3186F8A9300955C24 /* JSPromiseFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
1021
		7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
1026
		7C008CDA187124BB00955C24 /* JSPromiseDeferred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */; };
Lines 2758-2763 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
2758
		70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
2763
		70ECA6021AFDBEA200449739 /* TemplateRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistry.cpp; sourceTree = "<group>"; };
2759
		70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
2764
		70ECA6031AFDBEA200449739 /* TemplateRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistry.h; sourceTree = "<group>"; };
2760
		70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
2765
		70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
2766
		7B2076341B4DC05600F7BB93 /* WasmModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModule.cpp; sourceTree = "<group>"; };
2767
		7B2076351B4DC05600F7BB93 /* WasmModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmModule.h; sourceTree = "<group>"; };
2768
		7B545E4D1B4605C30029390E /* WasmJITCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmJITCompiler.cpp; sourceTree = "<group>"; };
2769
		7B545E4E1B4605C30029390E /* WasmJITCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmJITCompiler.h; sourceTree = "<group>"; };
2770
		7B545E4F1B4605C30029390E /* WasmOpcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOpcodes.h; sourceTree = "<group>"; };
2761
		7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JSPromiseFunctions.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
2771
		7C008CD0186F8A9300955C24 /* JSPromiseFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = JSPromiseFunctions.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
2762
		7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseFunctions.h; sourceTree = "<group>"; };
2772
		7C008CD1186F8A9300955C24 /* JSPromiseFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseFunctions.h; sourceTree = "<group>"; };
2763
		7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; sourceTree = "<group>"; };
2773
		7C008CD8187124BB00955C24 /* JSPromiseDeferred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseDeferred.cpp; 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
				7B545E4C1B4605A30029390E /* wasm */,
3620
				86EAC48C0F93E8B9008EC948 /* yarr */,
3631
				86EAC48C0F93E8B9008EC948 /* yarr */,
3621
			);
3632
			);
3622
			name = JavaScriptCore;
3633
			name = JavaScriptCore;
Lines 4280-4285 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
4280
			path = disassembler/ARMv7;
4291
			path = disassembler/ARMv7;
4281
			sourceTree = "<group>";
4292
			sourceTree = "<group>";
4282
		};
4293
		};
4294
		7B545E4C1B4605A30029390E /* wasm */ = {
4295
			isa = PBXGroup;
4296
			children = (
4297
				7B2076341B4DC05600F7BB93 /* WasmModule.cpp */,
4298
				7B2076351B4DC05600F7BB93 /* WasmModule.h */,
4299
				7B545E4D1B4605C30029390E /* WasmJITCompiler.cpp */,
4300
				7B545E4E1B4605C30029390E /* WasmJITCompiler.h */,
4301
				7B545E4F1B4605C30029390E /* WasmOpcodes.h */,
4302
			);
4303
			path = wasm;
4304
			sourceTree = "<group>";
4305
		};
4283
		7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
4306
		7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
4284
			isa = PBXGroup;
4307
			isa = PBXGroup;
4285
			children = (
4308
			children = (
Lines 5636-5641 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
5636
				A5EF9B161A1D440000702E90 /* generate_cpp_frontend_dispatcher_header.py in Headers */,
5659
				A5EF9B161A1D440000702E90 /* generate_cpp_frontend_dispatcher_header.py in Headers */,
5637
				2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
5660
				2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */,
5638
				A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */,
5661
				A5EF9B181A1D440600702E90 /* generate_cpp_protocol_types_header.py in Headers */,
5662
				7B2076361B4DC05900F7BB93 /* WasmModule.h in Headers */,
5639
				A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */,
5663
				A5EF9B191A1D440700702E90 /* generate_cpp_protocol_types_implementation.py in Headers */,
5640
				C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */,
5664
				C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */,
5641
				70DC3E0A1B2DF2C700054299 /* IteratorPrototype.h in Headers */,
5665
				70DC3E0A1B2DF2C700054299 /* IteratorPrototype.h in Headers */,
Lines 6043-6048 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec6
6043
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
6067
				BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
6044
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
6068
				A5FD0076189B038C00633231 /* IdentifiersFactory.h in Headers */,
6045
				996231E918D1804200C03FDA /* InspectorBackendCommands.js in Headers */,
6069
				996231E918D1804200C03FDA /* InspectorBackendCommands.js in Headers */,
6070
				7B545E521B4605D80029390E /* WasmOpcodes.h in Headers */,
6046
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
6071
				C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
6047
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
6072
				0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
6048
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
6073
				0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
Lines 6145-6150 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec7
6145
				86E3C613167BABD7006D760A /* JSContext.h in Headers */,
6170
				86E3C613167BABD7006D760A /* JSContext.h in Headers */,
6146
				86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */,
6171
				86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */,
6147
				BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
6172
				BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
6173
				7B545E511B4605D30029390E /* WasmJITCompiler.h in Headers */,
6148
				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
6174
				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
6149
				A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
6175
				A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
6150
				0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */,
6176
				0F7576D318E1FEE9002EF4CD /* AccessorCallJITStubRoutine.h in Headers */,
Lines 7167-7172 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec8
7167
				0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */,
7193
				0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */,
7168
				0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
7194
				0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
7169
				86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
7195
				86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
7196
				7B545E501B4605C70029390E /* WasmJITCompiler.cpp in Sources */,
7170
				A7D89CFD17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp in Sources */,
7197
				A7D89CFD17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.cpp in Sources */,
7171
				0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
7198
				0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
7172
				0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
7199
				0FD8A32517D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.cpp in Sources */,
Lines 7203-7208 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec9
7203
				0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
7230
				0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
7204
				0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
7231
				0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */,
7205
				709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
7232
				709FB8671AE335C60039D069 /* JSWeakSet.cpp in Sources */,
7233
				7B2076371B4DC05E00F7BB93 /* WasmModule.cpp in Sources */,
7206
				0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
7234
				0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
7207
				0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
7235
				0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
7208
				0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
7236
				0FB17662196B8F9E0091052A /* DFGPureValue.cpp in Sources */,
- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +72 lines
Lines 2182-2187 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin a/Source/JavaScriptCore/bytecode/CodeBlock.cpp_sec1
2182
    m_heap->m_codeBlocks.add(this);
2182
    m_heap->m_codeBlocks.add(this);
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
    
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
}
2185
2247
2186
CodeBlock::~CodeBlock()
2248
CodeBlock::~CodeBlock()
2187
{
2249
{
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 +21 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
#if ENABLE(JIT)
1160
protected:
1161
    virtual CodeBlock* replacement() override;
1162
    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
1163
#endif
1164
};
1165
1145
inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
1166
inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
1146
{
1167
{
1147
    RELEASE_ASSERT(inlineCallFrame);
1168
    RELEASE_ASSERT(inlineCallFrame);
- 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 490-495 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*); a/Source/JavaScriptCore/jsc.cpp_sec2
490
static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
491
static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);
491
static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
492
static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);
492
static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
493
static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);
494
static EncodedJSValue JSC_HOST_CALL functionLoadWebAssembly(ExecState*);
493
495
494
#if ENABLE(SAMPLING_FLAGS)
496
#if ENABLE(SAMPLING_FLAGS)
495
static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
497
static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
Lines 651-656 protected: a/Source/JavaScriptCore/jsc.cpp_sec3
651
        addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
653
        addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
652
654
653
        addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
655
        addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
656
657
        addFunction(vm, "loadWebAssembly", functionLoadWebAssembly, 1);
654
        
658
        
655
        JSArray* array = constructEmptyArray(globalExec(), 0);
659
        JSArray* array = constructEmptyArray(globalExec(), 0);
656
        for (size_t i = 0; i < arguments.size(); ++i)
660
        for (size_t i = 0; i < arguments.size(); ++i)
Lines 1165-1170 EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*) a/Source/JavaScriptCore/jsc.cpp_sec4
1165
    return JSValue::encode(jsUndefined());
1169
    return JSValue::encode(jsUndefined());
1166
}
1170
}
1167
1171
1172
EncodedJSValue JSC_HOST_CALL functionLoadWebAssembly(ExecState* exec)
1173
{
1174
    String fileName = exec->argument(0).toString(exec)->value(exec);
1175
    Vector<char> buffer;
1176
    if (!fillBufferWithContentsOfFile(fileName, buffer))
1177
        return JSValue::encode(exec->vm().throwException(exec, createError(exec, ASCIILiteral("Could not open file."))));
1178
    JSValue result = Wasm::compile(exec, buffer);
1179
    return JSValue::encode(result);
1180
}
1181
1168
// Use SEH for Release builds only to get rid of the crash report dialog
1182
// Use SEH for Release builds only to get rid of the crash report dialog
1169
// (luckily the same tests fail in Release and Debug builds so far). Need to
1183
// (luckily the same tests fail in Release and Debug builds so far). Need to
1170
// be in a separate main function because the jscmain function requires object
1184
// 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 +98 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
    
153
    if (isWebAssemblyExecutable()) {
154
        WebAssemblyExecutable* executable = jsCast<WebAssemblyExecutable*>(this);
155
        WebAssemblyCodeBlock* codeBlock = static_cast<WebAssemblyCodeBlock*>(genericCodeBlock);
156
        switch (kind) {
157
        case CodeForCall:
158
            executable->m_codeBlockForCall = codeBlock;
159
            break;
160
        case CodeForConstruct:
161
            ASSERT_NOT_REACHED();
162
            executable->m_codeBlockForConstruct = codeBlock;
163
            break;
164
        }
165
        
166
        // FIXME: this is just to make isHostFunction() happy.
167
        // But this will make isHostFunction() return true.
168
        m_numParametersForCall = 0;
169
        m_numParametersForConstruct = 0;
170
    } else {
171
    
172
        // FIXME: need to deal with codeType()
152
    switch (genericCodeBlock->codeType()) {
173
    switch (genericCodeBlock->codeType()) {
153
    case GlobalCode: {
174
    case GlobalCode: {
154
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
175
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
Lines 192-197 void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) a/Source/JavaScriptCore/runtime/Executable.cpp_sec2
192
    if (oldCodeBlock)
213
    if (oldCodeBlock)
193
        oldCodeBlock->unlinkIncomingCalls();
214
        oldCodeBlock->unlinkIncomingCalls();
194
215
216
    }
217
    
195
    Debugger* debugger = genericCodeBlock->globalObject()->debugger();
218
    Debugger* debugger = genericCodeBlock->globalObject()->debugger();
196
    if (debugger)
219
    if (debugger)
197
        debugger->registerCodeBlock(genericCodeBlock);
220
        debugger->registerCodeBlock(genericCodeBlock);
Lines 228-233 RefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor( a/Source/JavaScriptCore/runtime/Executable.cpp_sec3
228
            executable->source().provider(), executable->source().startColumn()));
251
            executable->source().provider(), executable->source().startColumn()));
229
    }
252
    }
230
    
253
    
254
    ASSERT(!isWebAssemblyExecutable());
255
    
231
    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
256
    RELEASE_ASSERT(classInfo() == FunctionExecutable::info());
232
    RELEASE_ASSERT(function);
257
    RELEASE_ASSERT(function);
233
    FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
258
    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(
348
JSObject* ScriptExecutable::prepareForExecutionImpl(
324
    ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
349
    ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
325
{
350
{
351
    ASSERT(!isWebAssemblyExecutable());
352
    
326
    VM& vm = exec->vm();
353
    VM& vm = exec->vm();
327
    DeferGC deferGC(vm.heap);
354
    DeferGC deferGC(vm.heap);
328
    
355
    
Lines 425-430 void FunctionExecutable::destroy(JSCell* cell) a/Source/JavaScriptCore/runtime/Executable.cpp_sec5
425
    static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
452
    static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable();
426
}
453
}
427
454
455
const ClassInfo WebAssemblyExecutable::s_info = { "WebAssemblyExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(WebAssemblyExecutable) };
456
457
WebAssemblyExecutable::WebAssemblyExecutable(VM& vm, const SourceCode& source)
458
    : ScriptExecutable(vm.webAssemblyExecutableStructure.get(), vm, source, /*isInStrictContext*/ false )
459
{
460
    /*
461
    RELEASE_ASSERT(!source.isNull());
462
    ASSERT(source.length());
463
    m_firstLine = firstLine;
464
    m_lastLine = lastLine;
465
    m_startColumn = startColumn;
466
    m_endColumn = endColumn;
467
    m_parametersStartOffset = unlinkedExecutable->parametersStartOffset();
468
    m_typeProfilingStartOffset = unlinkedExecutable->typeProfilingStartOffset();
469
    m_typeProfilingEndOffset = unlinkedExecutable->typeProfilingEndOffset();
470
    */
471
}
472
473
void WebAssemblyExecutable::finishCreation(VM& vm)
474
{
475
    Base::finishCreation(vm);
476
    m_singletonFunction.set(vm, this, InferredValue::create(vm));
477
}
478
479
void WebAssemblyExecutable::destroy(JSCell* cell)
480
{
481
    static_cast<WebAssemblyExecutable*>(cell)->WebAssemblyExecutable::~WebAssemblyExecutable();
482
}
483
428
inline const char* samplingDescription(JITCode::JITType jitType)
484
inline const char* samplingDescription(JITCode::JITType jitType)
429
{
485
{
430
    switch (jitType) {
486
    switch (jitType) {
Lines 619-624 FunctionExecutable* FunctionExecutable::fromGlobalCode( a/Source/JavaScriptCore/runtime/Executable.cpp_sec6
619
    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
675
    return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
620
}
676
}
621
677
678
WebAssemblyCodeBlock* WebAssemblyExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)
679
{
680
    WebAssemblyCodeBlock* result;
681
    if (kind == CodeForCall)
682
        result = m_codeBlockForCall.get();
683
    else {
684
        RELEASE_ASSERT(kind == CodeForConstruct);
685
        result = m_codeBlockForConstruct.get();
686
    }
687
    if (!result)
688
        return 0;
689
    return static_cast<WebAssemblyCodeBlock*>(result->baselineAlternative());
690
}
691
692
void WebAssemblyExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
693
{
694
    WebAssemblyExecutable* thisObject = jsCast<WebAssemblyExecutable*>(cell);
695
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
696
    ScriptExecutable::visitChildren(thisObject, visitor);
697
    if (thisObject->m_codeBlockForCall)
698
        thisObject->m_codeBlockForCall->visitAggregate(visitor);
699
    if (thisObject->m_codeBlockForConstruct)
700
        thisObject->m_codeBlockForConstruct->visitAggregate(visitor);
701
    visitor.append(&thisObject->m_singletonFunction);
702
}
703
704
SymbolTable* WebAssemblyExecutable::symbolTable(CodeSpecializationKind kind)
705
{
706
    return codeBlockFor(kind)->symbolTable();
707
}
708
709
void WebAssemblyExecutable::clearCode()
710
{
711
    m_codeBlockForCall.clear();
712
    m_codeBlockForConstruct.clear();
713
    Base::clearCode();
714
}
715
716
void WebAssemblyExecutable::unlinkCalls()
717
{
718
}
719
622
void ExecutableBase::dump(PrintStream& out) const
720
void ExecutableBase::dump(PrintStream& out) const
623
{
721
{
624
    ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
722
    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 221-226 VM::VM(VMType vmType, HeapType heapType) a/Source/JavaScriptCore/runtime/VM.cpp_sec1
221
    evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
221
    evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull()));
222
    programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
222
    programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull()));
223
    functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
223
    functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
224
    webAssemblyExecutableStructure.set(*this, WebAssemblyExecutable::createStructure(*this, 0, jsNull()));
224
    regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
225
    regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
225
    symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
226
    symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull()));
226
    symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull()));
227
    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 +915 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
48
namespace JSC {
49
50
namespace Wasm {
51
52
class JumpScope {
53
public:
54
    JumpScope(MacroAssembler* macroAssembler)
55
        : m_macroAssembler(macroAssembler)
56
        , m_linked(false)
57
    {
58
    }
59
60
    JumpScope(MacroAssembler* macroAssembler, const MacroAssembler::Label& label)
61
        : m_macroAssembler(macroAssembler)
62
        , m_linked(true)
63
        , m_label(label)
64
    {
65
    }
66
67
    void jump()
68
    {
69
        if (m_linked)
70
            m_macroAssembler->jump(m_label);
71
        else
72
            m_jumpList.append(m_macroAssembler->jump());
73
    }
74
75
    void link()
76
    {
77
        ASSERT(!m_linked);
78
        m_jumpList.link(m_macroAssembler);
79
    }
80
81
private:
82
    MacroAssembler* m_macroAssembler;
83
    bool m_linked;
84
    MacroAssembler::Label m_label;
85
    MacroAssembler::JumpList m_jumpList;
86
};
87
88
RefPtr<JITCode> JITCompiler::compileFunction(VM& vm, size_t functionIndex)
89
{
90
    emitFunctionPrologue();
91
    allocateSpaceOnStack();
92
93
    const Signature& signature = m_module->m_signatures[m_module->m_funcSignatures[functionIndex]];
94
    m_currentReturnType = signature.ret;
95
    m_currentLocalTypes.clear();
96
    parseArguments(signature);
97
    parseVars();
98
    parseStmtList();
99
100
    LinkBuffer patchBuffer(vm, *this, 0, JITCompilationMustSucceed);
101
102
    for (auto iter = m_calls.begin(); iter != m_calls.end(); ++iter)
103
        patchBuffer.link(iter->first, FunctionPtr(iter->second));
104
105
    MacroAssemblerCodePtr withArityCheck;
106
    CodeRef result = FINALIZE_CODE(patchBuffer, ("Baseline JIT code for WebAssembly"));
107
    return adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT));
108
}
109
110
void JITCompiler::allocateSpaceOnStack()
111
{
112
    m_stackHeight = 32; // FIXME: calculate the actual height
113
    addPtr(TrustedImm32(-m_stackHeight), stackPointerRegister);
114
}
115
116
void JITCompiler::deallocateSpaceOnStack()
117
{
118
    addPtr(TrustedImm32(m_stackHeight), stackPointerRegister);
119
}
120
121
void JITCompiler::parseArguments(const Signature& signature)
122
{
123
    size_t argumentCount = signature.arguments.size();
124
    for (uint32_t argIndex = 0; argIndex < argumentCount; ++argIndex) {
125
        Type type = signature.arguments[argIndex];
126
        m_currentLocalTypes.append(type);
127
        switch (type) {
128
        case Type::I32:
129
        case Type::F32:
130
        case Type::F64:
131
            break;
132
        default:
133
            RELEASE_ASSERT_NOT_REACHED();
134
        }
135
    }
136
}
137
138
void JITCompiler::parseVars()
139
{
140
    uint32_t numberOfI32Vars = 0;
141
    uint32_t numberOfF32Vars = 0;
142
    uint32_t numberOfF64Vars = 0;
143
144
    VarTypes varTypes;
145
    VarTypesWithImm varTypesWithImm;
146
    uint8_t imm;
147
    if (m_module->m_read.code(&varTypes, &varTypesWithImm, &imm)) {
148
        if (varTypes & VarTypes::I32)
149
            numberOfI32Vars = m_module->m_read.immU32();
150
        if (varTypes & VarTypes::F32)
151
            numberOfF32Vars = m_module->m_read.immU32();
152
        if (varTypes & VarTypes::F64)
153
            numberOfF64Vars = m_module->m_read.immU32();
154
    } else
155
        numberOfI32Vars = imm;
156
157
    uint32_t numberOfVars = numberOfI32Vars + numberOfF32Vars + numberOfF64Vars;
158
    if (numberOfVars > 0) {
159
        uint32_t localIndex = m_currentLocalTypes.size();
160
        for (uint32_t i = 0; i < numberOfI32Vars; ++i) {
161
            m_currentLocalTypes.append(Type::I32);
162
            store32(TrustedImm32(0), stackAddress(localIndex++));
163
        }
164
        for (uint32_t i = 0; i < numberOfF32Vars; ++i) {
165
            m_currentLocalTypes.append(Type::F32);
166
            store32(TrustedImm32(0), stackAddress(localIndex++));
167
        }
168
        for (uint32_t i = 0; i < numberOfF64Vars; ++i) {
169
            m_currentLocalTypes.append(Type::F64);
170
            store64(TrustedImm64(0), stackAddress(localIndex++));
171
        }
172
    }
173
}
174
175
void JITCompiler::parseStmt()
176
{
177
    Stmt stmt;
178
    StmtWithImm stmtWithImm;
179
    uint8_t imm;
180
    if (m_module->m_read.code(&stmt, &stmtWithImm, &imm)) {
181
        switch (stmt) {
182
        case Stmt::SetLoc:
183
            parseSetLocal(0);
184
            break;
185
        case Stmt::SetGlo:
186
        case Stmt::I32Store8:
187
        case Stmt::I32StoreOff8:
188
        case Stmt::I32Store16:
189
        case Stmt::I32StoreOff16:
190
        case Stmt::I32Store32:
191
        case Stmt::I32StoreOff32:
192
        case Stmt::F32Store:
193
        case Stmt::F32StoreOff:
194
        case Stmt::F64Store:
195
        case Stmt::F64StoreOff:
196
        case Stmt::CallInt:
197
        case Stmt::CallInd:
198
        case Stmt::CallImp:
199
            RELEASE_ASSERT_NOT_REACHED();
200
        case Stmt::Ret:
201
            parseReturnStmt();
202
            return;
203
        case Stmt::Block:
204
            parseBlockStmt();
205
            return;
206
        case Stmt::IfThen:
207
            parseIfStmt();
208
            return;
209
        case Stmt::IfElse:
210
            parseIfElseStmt();
211
            return;
212
        case Stmt::While:
213
            parseWhileStmt();
214
            return;
215
        case Stmt::Do:
216
            parseDoStmt();
217
            return;
218
        case Stmt::Label:
219
            parseLabelStmt();
220
            return;
221
        case Stmt::Break:
222
            parseBreakStmt();
223
            return;
224
        case Stmt::BreakLabel:
225
            parseBreakLabelStmt();
226
            return;
227
        case Stmt::Continue:
228
            parseContinueStmt();
229
            break;
230
        case Stmt::ContinueLabel:
231
            parseContinueLabelStmt();
232
            return;
233
        case Stmt::Switch:
234
            parseSwitchStmt();
235
            break;
236
        default:
237
            RELEASE_ASSERT_NOT_REACHED();
238
        }
239
    } else {
240
        switch (stmtWithImm) {
241
        case StmtWithImm::SetLoc:
242
            parseSetLocal(imm, 0);
243
            break;
244
        case StmtWithImm::SetGlo:
245
        default:
246
            RELEASE_ASSERT_NOT_REACHED();
247
        }
248
    }
249
}
250
251
void JITCompiler::parseGetLocal(int dst)
252
{
253
    uint32_t imm = m_module->m_read.immU32();
254
    switch (m_currentLocalTypes[imm]) {
255
    case Type::I32:
256
    case Type::F32: // FIXME: loadFloat/storeFloat?
257
        load32(stackAddress(imm), GPRInfo::regT0);
258
        store32(GPRInfo::regT0, temporaryAddress(dst));
259
        break;
260
    case Type::F64: // FIXME: loadDouble/storeDouble?
261
        load64(stackAddress(imm), GPRInfo::regT0);
262
        store64(GPRInfo::regT0, temporaryAddress(dst));
263
        break;
264
    default:
265
        RELEASE_ASSERT_NOT_REACHED();
266
    }
267
}
268
269
void JITCompiler::parseSetLocal(uint32_t imm, int dst)
270
{
271
    Type type = m_currentLocalTypes[imm];
272
    parseExpr(RType(type), dst);
273
    switch (type) {
274
    case Type::I32:
275
    case Type::F32:
276
        load32(temporaryAddress(dst), GPRInfo::regT0);
277
        store32(GPRInfo::regT0, stackAddress(imm));
278
        break;
279
    case Type::F64:
280
        load64(temporaryAddress(dst), GPRInfo::regT0);
281
        store64(GPRInfo::regT0, stackAddress(imm));
282
        break;
283
    default:
284
        RELEASE_ASSERT_NOT_REACHED();
285
    }
286
}
287
288
void JITCompiler::parseSetLocal(int dst)
289
{
290
    parseSetLocal(m_module->m_read.immU32(), dst);
291
}
292
293
void JITCompiler::parseReturnStmt()
294
{
295
    switch (m_currentReturnType) {
296
    case RType::I32:
297
        parseExpr(RType::I32, 0);
298
        load32(temporaryAddress(0), GPRInfo::returnValueGPR);
299
        boxInt52(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR, GPRInfo::regT0, FPRInfo::fpRegT0);
300
        break;
301
    case RType::F32:
302
        parseExpr(RType::F32, 0);
303
        loadDouble(temporaryAddress(0), FPRInfo::fpRegT0); // FIXME: hacky! This loads 64 bits!
304
        convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
305
        boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
306
        break;
307
    case RType::F64:
308
        parseExpr(RType::F64, 0);
309
        loadDouble(temporaryAddress(0), FPRInfo::fpRegT0);
310
        boxDouble(FPRInfo::fpRegT0, GPRInfo::returnValueGPR);
311
        break;
312
    case RType::Void:
313
        break;
314
    }
315
316
    deallocateSpaceOnStack();
317
    emitFunctionEpilogue();
318
    ret();
319
}
320
321
void JITCompiler::parseStmtList()
322
{
323
    uint32_t numberOfStmts = m_module->m_read.immU32();
324
    for (uint32_t i = 0; i < numberOfStmts; ++i)
325
        parseStmt();
326
}
327
328
void JITCompiler::parseBlockStmt()
329
{
330
    parseStmtList();
331
}
332
333
void JITCompiler::parseIfStmt()
334
{
335
    parseExpr(RType::I32, 0);
336
    load32(temporaryAddress(0), GPRInfo::regT0);
337
    Jump end = branchTest32(Zero, GPRInfo::regT0);
338
    parseStmt();
339
    end.link(this);
340
}
341
342
void JITCompiler::parseIfElseStmt()
343
{
344
    parseExpr(RType::I32, 0);
345
    load32(temporaryAddress(0), GPRInfo::regT0);
346
    Jump els = branchTest32(Zero, GPRInfo::regT0);
347
    parseStmt();
348
    Jump end = jump();
349
    els.link(this);
350
    parseStmt();
351
    end.link(this);
352
}
353
354
void JITCompiler::parseWhileStmt()
355
{
356
    JumpScope continueJumpScope(this, label());
357
    pushContinueJumpScope(&continueJumpScope);
358
359
    JumpList breakJumpList;
360
    pushBreakJumpList(&breakJumpList);
361
362
    parseExpr(RType::I32, 0);
363
    load32(temporaryAddress(0), GPRInfo::regT0);
364
    Jump end = branchTest32(Zero, GPRInfo::regT0);
365
    parseStmt();
366
    continueJumpScope.jump();
367
    end.link(this);
368
    breakJumpList.link(this);
369
370
    popBreakJumpList();
371
372
    popContinueJumpScope();
373
}
374
375
void JITCompiler::parseDoStmt()
376
{
377
    JumpScope continueJumpScope(this);
378
    pushContinueJumpScope(&continueJumpScope);
379
380
    JumpList breakJumpList;
381
    pushBreakJumpList(&breakJumpList);
382
383
    Label start = label();
384
    parseStmt();
385
    continueJumpScope.link();
386
    parseExpr(RType::I32, 0);
387
    load32(temporaryAddress(0), GPRInfo::regT0);
388
    Jump jumpToStart = branchTest32(NonZero, GPRInfo::regT0);
389
    jumpToStart.linkTo(start, this);
390
    breakJumpList.link(this);
391
392
    popBreakJumpList();
393
394
    popContinueJumpScope();
395
}
396
397
void JITCompiler::parseLabelStmt()
398
{
399
    Label continueLabel = label();
400
    JumpList breakJumpList;
401
    pushContinueLabelLabel(&continueLabel);
402
    pushBreakLabelJumpList(&breakJumpList);
403
    parseStmt();
404
    breakJumpList.link(this);
405
    popBreakLabelJumpList();
406
    popContinueLabelLabel();
407
}
408
409
void JITCompiler::parseBreakStmt()
410
{
411
    topBreakJumpList()->append(jump());
412
}
413
414
void JITCompiler::parseBreakLabelStmt()
415
{
416
    uint32_t index = m_module->m_read.immU32();
417
    breakLabelJumpList(index)->append(jump());
418
}
419
420
void JITCompiler::parseContinueStmt()
421
{
422
    topContinueJumpScope()->jump();
423
}
424
425
void JITCompiler::parseContinueLabelStmt()
426
{
427
    uint32_t index = m_module->m_read.immU32();
428
    jump(*continueLabelLabel(index));
429
}
430
431
void JITCompiler::parseSwitchStmt()
432
{
433
    JumpList breakJumpList;
434
    pushBreakJumpList(&breakJumpList);
435
436
    uint32_t numberOfCases = m_module->m_read.immU32();
437
    parseExpr(RType::I32, 0);
438
    load32(temporaryAddress(0), GPRInfo::regT0);
439
440
    Jump table = jump();
441
442
    Vector<Label> labels;
443
    Vector<int32_t> imms;
444
    Label defaultLabel;
445
    bool hasDefault = false;
446
447
    for (uint32_t i = 0; i < numberOfCases; ++i) {
448
        switch (m_module->m_read.switchCase()) {
449
        case SwitchCase::Case0:
450
            labels.append(label());
451
            imms.append(m_module->m_read.immS32());
452
            break;
453
        case SwitchCase::Case1:
454
            labels.append(label());
455
            imms.append(m_module->m_read.immS32());
456
            parseStmt();
457
            break;
458
        case SwitchCase::CaseN:
459
            labels.append(label());
460
            imms.append(m_module->m_read.immS32());
461
            parseStmtList();
462
            break;
463
        case SwitchCase::Default0:
464
            defaultLabel = label();
465
            hasDefault = true;
466
            break;
467
        case SwitchCase::Default1:
468
            defaultLabel = label();
469
            hasDefault = true;
470
            parseStmt();
471
            break;
472
        case SwitchCase::DefaultN:
473
            defaultLabel = label();
474
            hasDefault = true;
475
            parseStmtList();
476
            break;
477
        default:
478
            RELEASE_ASSERT_NOT_REACHED();
479
        }
480
    }
481
482
    Jump end = jump();
483
    table.link(this);
484
485
    for (size_t i = 0; i < labels.size(); ++i) {
486
        Jump jmp = branch32(Equal, GPRInfo::regT0, TrustedImm32(imms[i]));
487
        jmp.linkTo(labels[i], this);
488
    }
489
    if (hasDefault)
490
        jump(defaultLabel);
491
492
    end.link(this);
493
494
    breakJumpList.link(this);
495
    popBreakJumpList();
496
}
497
498
void JITCompiler::parseExpr(RType rType, int dst)
499
{
500
    switch (rType) {
501
    case RType::I32:
502
        parseExprI32(dst);
503
        break;
504
    case RType::F64:
505
        parseExprF64(dst);
506
        break;
507
    default:
508
        RELEASE_ASSERT_NOT_REACHED();
509
    }
510
}
511
512
void JITCompiler::parseExprI32(int dst)
513
{
514
    I32 i32;
515
    I32WithImm i32WithImm;
516
    uint8_t imm;
517
518
    if (m_module->m_read.code(&i32, &i32WithImm, &imm)) {
519
        switch (i32) {
520
        case I32::LitImm:
521
            store32(TrustedImm32(m_module->m_read.immU32()), temporaryAddress(dst));
522
            break;
523
        case I32::LitPool:
524
        case I32::GetLoc:
525
            parseGetLocal(dst);
526
            break;
527
        case I32::GetGlo:
528
            RELEASE_ASSERT_NOT_REACHED();
529
        case I32::SetLoc:
530
            parseSetLocal(dst);
531
            break;
532
        case I32::SetGlo:
533
        case I32::SLoad8:
534
        case I32::SLoadOff8:
535
        case I32::ULoad8:
536
        case I32::ULoadOff8:
537
        case I32::SLoad16:
538
        case I32::SLoadOff16:
539
        case I32::ULoad16:
540
        case I32::ULoadOff16:
541
        case I32::Load32:
542
        case I32::LoadOff32:
543
        case I32::Store8:
544
        case I32::StoreOff8:
545
        case I32::Store16:
546
        case I32::StoreOff16:
547
        case I32::Store32:
548
        case I32::StoreOff32:
549
            RELEASE_ASSERT_NOT_REACHED();
550
        case I32::CallInt:
551
            parseCallInternal(RType::I32, dst);
552
            break;
553
        case I32::CallInd:
554
        case I32::CallImp:
555
            RELEASE_ASSERT_NOT_REACHED();
556
        case I32::Cond:
557
            parseCond(RType::I32, dst);
558
            break;
559
        case I32::Comma:
560
            parseComma(RType::I32, dst);
561
            break;
562
        case I32::FromF32:
563
            RELEASE_ASSERT_NOT_REACHED();
564
        case I32::FromF64:
565
            parseExprF64(dst);
566
            loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
567
            truncateDoubleToInt32(FPRInfo::fpRegT0, GPRInfo::regT0);
568
            store32(GPRInfo::regT0, temporaryAddress(dst));
569
            break;
570
        case I32::Neg:
571
            parseUnaryOp(static_cast<uint8_t>(i32), RType::I32, dst);
572
            break;
573
        case I32::Add:
574
        case I32::Sub:
575
        case I32::Mul:
576
            parseBinaryOp(static_cast<uint8_t>(i32), RType::I32, dst);
577
            break;
578
        case I32::SDiv:
579
        case I32::UDiv:
580
        case I32::SMod:
581
        case I32::UMod:
582
            RELEASE_ASSERT_NOT_REACHED();
583
        case I32::BitNot:
584
            parseUnaryOp(static_cast<uint8_t>(i32), RType::I32, dst);
585
            break;
586
        case I32::BitOr:
587
        case I32::BitAnd:
588
        case I32::BitXor:
589
            parseBinaryOp(static_cast<uint8_t>(i32), RType::I32, dst);
590
            break;
591
        case I32::Lsh:
592
        case I32::ArithRsh:
593
        case I32::LogicRsh:
594
        case I32::Clz:
595
        case I32::LogicNot:
596
            RELEASE_ASSERT_NOT_REACHED();
597
        case I32::EqI32:
598
            parseRelationalOpI32(Equal, RType::I32, dst);
599
            break;
600
        case I32::EqF32:
601
            RELEASE_ASSERT_NOT_REACHED();
602
        case I32::EqF64:
603
            parseRelationalOpF64(DoubleEqual, RType::F64, dst);
604
            break;
605
        case I32::NEqI32:
606
            parseRelationalOpI32(NotEqual, RType::I32, dst);
607
            break;
608
        case I32::NEqF32:
609
            RELEASE_ASSERT_NOT_REACHED();
610
        case I32::NEqF64:
611
            parseRelationalOpF64(DoubleNotEqual, RType::F64, dst);
612
            break;
613
        case I32::SLeThI32:
614
            parseRelationalOpI32(LessThan, RType::I32, dst);
615
            break;
616
        case I32::ULeThI32:
617
            parseRelationalOpI32(Below, RType::I32, dst);
618
            break;
619
        case I32::LeThF32:
620
            RELEASE_ASSERT_NOT_REACHED();
621
        case I32::LeThF64:
622
            parseRelationalOpF64(DoubleLessThan, RType::F64, dst);
623
            break;
624
        case I32::SLeEqI32:
625
            parseRelationalOpI32(LessThanOrEqual, RType::I32, dst);
626
            break;
627
        case I32::ULeEqI32:
628
            parseRelationalOpI32(BelowOrEqual, RType::I32, dst);
629
            break;
630
        case I32::LeEqF32:
631
            RELEASE_ASSERT_NOT_REACHED();
632
        case I32::LeEqF64:
633
            parseRelationalOpF64(DoubleLessThanOrEqual, RType::F64, dst);
634
            break;
635
        case I32::SGrThI32:
636
            parseRelationalOpI32(GreaterThan, RType::I32, dst);
637
            break;
638
        case I32::UGrThI32:
639
            parseRelationalOpI32(Above, RType::I32, dst);
640
            break;
641
        case I32::GrThF32:
642
            RELEASE_ASSERT_NOT_REACHED();
643
        case I32::GrThF64:
644
            parseRelationalOpF64(DoubleGreaterThan, RType::F64, dst);
645
            break;
646
        case I32::SGrEqI32:
647
            parseRelationalOpI32(GreaterThanOrEqual, RType::I32, dst);
648
            break;
649
        case I32::UGrEqI32:
650
            parseRelationalOpI32(AboveOrEqual, RType::I32, dst);
651
            break;
652
        case I32::GrEqF32:
653
            RELEASE_ASSERT_NOT_REACHED();
654
        case I32::GrEqF64:
655
            parseRelationalOpF64(DoubleGreaterThanOrEqual, RType::F64, dst);
656
            break;
657
        case I32::SMin:
658
        case I32::UMin:
659
        case I32::SMax:
660
        case I32::UMax:
661
        case I32::Abs:
662
        default:
663
            RELEASE_ASSERT_NOT_REACHED();
664
        }
665
    } else {
666
        switch (i32WithImm) {
667
        case I32WithImm::LitImm:
668
            store32(TrustedImm32(imm), temporaryAddress(dst));
669
            break;
670
        case I32WithImm::LitPool:
671
            store32(TrustedImm32(m_module->m_constantI32s[imm]), temporaryAddress(dst));
672
            break;
673
        case I32WithImm::GetLoc:
674
            load32(stackAddress(imm), GPRInfo::regT0);
675
            store32(GPRInfo::regT0, temporaryAddress(dst));
676
            break;
677
        default:
678
            RELEASE_ASSERT_NOT_REACHED();
679
        }
680
    }
681
}
682
683
void JITCompiler::parseExprF64(int dst)
684
{
685
    F64 f64;
686
    F64WithImm f64WithImm;
687
    uint8_t imm;
688
689
    if (m_module->m_read.code(&f64, &f64WithImm, &imm)) {
690
        switch (f64) {
691
        case F64::LitImm:
692
            store64(TrustedImm64(reinterpretDoubleToInt64(m_module->m_read.fixedWidth<double>())), temporaryAddress(dst));
693
            break;
694
        case F64::Neg:
695
            parseUnaryOp(static_cast<uint8_t>(f64), RType::F64, dst);
696
            break;
697
        case F64::Add:
698
        case F64::Sub:
699
        case F64::Mul:
700
        case F64::Div:
701
            parseBinaryOp(static_cast<uint8_t>(f64), RType::F64, dst);
702
            break;
703
        case F64::Sqrt:
704
            parseUnaryOp(static_cast<uint8_t>(f64), RType::F64, dst);
705
            break;
706
        default:
707
            RELEASE_ASSERT_NOT_REACHED();
708
        }
709
    } else {
710
        switch (f64WithImm) {
711
        case F64WithImm::LitPool:
712
            store64(TrustedImm64(reinterpretDoubleToInt64(m_module->m_constantF64s[imm])), temporaryAddress(dst));
713
            break;
714
        case F64WithImm::GetLoc:
715
            // FIXME: loadDouble/storeDouble?
716
            load64(stackAddress(imm), GPRInfo::regT0);
717
            store64(GPRInfo::regT0, temporaryAddress(dst));
718
            break;
719
        default:
720
            RELEASE_ASSERT_NOT_REACHED();
721
        }
722
    }
723
}
724
725
static int32_t callInternalFunction(ExecState* exec, Module* module, uint32_t functionIndex)
726
{
727
    // FIXME: Do we have to use these two lines?
728
    // VM* vm = exec->vm();
729
    // NativeCallFrameTracer tracer(vm, exec);
730
731
    // FIXME: We shouldn't unbox the value here!
732
    return module->callInternalFunction(exec, functionIndex).asInt32();
733
}
734
735
void JITCompiler::parseCallInternal(RType rType, int dst)
736
{
737
    ASSERT(rType == RType::I32);
738
    uint32_t functionIndex = m_module->m_read.immU32();
739
    const Vector<Type>& arguments = m_module->m_signatures[m_module->m_funcSignatures[functionIndex]].arguments;
740
741
    // TODO: actually pass arguments
742
    for (size_t i = 0; i < arguments.size(); ++i) {
743
        switch (arguments[i]) {
744
        case Type::I32:
745
            parseExpr(RType::I32, dst);
746
            break;
747
        case Type::F64:
748
            parseExpr(RType::F64, dst);
749
            break;
750
        default:
751
            ASSERT_NOT_REACHED();
752
        }
753
    }
754
    if (maxFrameExtentForSlowPathCall)
755
        addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
756
    setupArgumentsWithExecState(TrustedImmPtr(m_module), TrustedImm32(functionIndex));
757
    appendCall(callInternalFunction);
758
    if (maxFrameExtentForSlowPathCall)
759
        addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
760
761
    // FIXME: Can we really use returnValueGPR?
762
    store32(GPRInfo::returnValueGPR, temporaryAddress(dst));
763
}
764
765
void JITCompiler::parseBinaryOp(uint8_t op, RType rType, int dst)
766
{
767
    parseExpr(rType, dst);
768
    parseExpr(rType, dst + 1);
769
    switch (rType) {
770
    case RType::I32:
771
        load32(temporaryAddress(dst), GPRInfo::regT0);
772
        load32(temporaryAddress(dst + 1), GPRInfo::regT1);
773
        switch (static_cast<I32>(op)) {
774
        case I32::Add:
775
            add32(GPRInfo::regT1, GPRInfo::regT0);
776
            break;
777
        case I32::Sub:
778
            sub32(GPRInfo::regT1, GPRInfo::regT0);
779
            break;
780
        case I32::Mul:
781
            mul32(GPRInfo::regT1, GPRInfo::regT0);
782
            break;
783
        case I32::BitOr:
784
            or32(GPRInfo::regT1, GPRInfo::regT0);
785
            break;
786
        case I32::BitAnd:
787
            and32(GPRInfo::regT1, GPRInfo::regT0);
788
            break;
789
        case I32::BitXor:
790
            xor32(GPRInfo::regT1, GPRInfo::regT0);
791
            break;
792
        default:
793
            ASSERT_NOT_REACHED();
794
        }
795
        store32(GPRInfo::regT0, temporaryAddress(dst));
796
        break;
797
    case RType::F64:
798
        loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
799
        loadDouble(temporaryAddress(dst + 1), FPRInfo::fpRegT1);
800
        switch (static_cast<F64>(op)) {
801
        case F64::Add:
802
            addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
803
            break;
804
        case F64::Sub:
805
            subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
806
            break;
807
        case F64::Mul:
808
            mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
809
            break;
810
        case F64::Div:
811
            divDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
812
            break;
813
        default:
814
            ASSERT_NOT_REACHED();
815
        }
816
        storeDouble(FPRInfo::fpRegT0, temporaryAddress(dst));
817
        break;
818
    default:
819
        RELEASE_ASSERT_NOT_REACHED();
820
    }
821
}
822
823
void JITCompiler::parseUnaryOp(uint8_t op, RType rType, int dst)
824
{
825
    parseExpr(rType, dst);
826
    switch (rType) {
827
    case RType::I32:
828
        load32(temporaryAddress(dst), GPRInfo::regT0);
829
        switch (static_cast<I32>(op)) {
830
        case I32::Neg:
831
            neg32(GPRInfo::regT0);
832
            break;
833
        case I32::BitNot:
834
            xor32(TrustedImm32(-1), GPRInfo::regT0);
835
            break;
836
        default:
837
            ASSERT_NOT_REACHED();
838
        }
839
        store32(GPRInfo::regT0, temporaryAddress(dst));
840
        break;
841
    case RType::F64:
842
        loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
843
        switch (static_cast<F64>(op)) {
844
        case F64::Neg:
845
            negateDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT1);
846
            break;
847
        case F64::Sqrt:
848
            sqrtDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT1);
849
            break;
850
        default:
851
            ASSERT_NOT_REACHED();
852
        }
853
        storeDouble(FPRInfo::fpRegT1, temporaryAddress(dst));
854
        break;
855
    default:
856
        RELEASE_ASSERT_NOT_REACHED();
857
    }
858
}
859
860
void JITCompiler::parseRelationalOpI32(RelationalCondition condition, RType operandType, int dst)
861
{
862
    parseExpr(operandType, dst);
863
    parseExpr(operandType, dst + 1);
864
    switch (operandType) {
865
    case RType::I32:
866
        load32(temporaryAddress(dst), GPRInfo::regT0);
867
        load32(temporaryAddress(dst + 1), GPRInfo::regT1);
868
        compare32(condition, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
869
        break;
870
    default:
871
        RELEASE_ASSERT_NOT_REACHED();
872
    }
873
    store32(GPRInfo::regT0, temporaryAddress(dst));
874
}
875
876
void JITCompiler::parseRelationalOpF64(DoubleCondition condition, RType operandType, int dst)
877
{
878
    parseExpr(operandType, dst);
879
    parseExpr(operandType, dst + 1);
880
    switch (operandType) {
881
    case RType::F64: {
882
        loadDouble(temporaryAddress(dst), FPRInfo::fpRegT0);
883
        loadDouble(temporaryAddress(dst + 1), FPRInfo::fpRegT1);
884
        Jump trueCase = branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1);
885
        store32(TrustedImm32(0), temporaryAddress(dst));
886
        Jump end = jump();
887
        trueCase.link(this);
888
        store32(TrustedImm32(1), temporaryAddress(dst));
889
        end.link(this);
890
        break;
891
    }
892
    default:
893
        RELEASE_ASSERT_NOT_REACHED();
894
    }
895
}
896
897
void JITCompiler::parseComma(RType rType, int dst)
898
{
899
    parseExpr(m_module->m_read.rtype(), dst);
900
    parseExpr(rType, dst);
901
}
902
903
void JITCompiler::parseCond(RType rType, int dst)
904
{
905
    parseExpr(RType::I32, dst);
906
    load32(temporaryAddress(dst), GPRInfo::regT0);
907
    Jump els = branchTest32(Zero, GPRInfo::regT0);
908
    parseExpr(rType, dst);
909
    Jump end = jump();
910
    els.link(this);
911
    parseExpr(rType, dst);
912
    end.link(this);
913
}
914
915
} } // namespace JSC::Wasm
- a/Source/JavaScriptCore/wasm/WasmJITCompiler.h +151 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 appendCall(const FunctionPtr& function)
68
    {
69
        Call functionCall = call();
70
        m_calls.append(std::make_pair(functionCall, function.value()));
71
    }
72
73
    void allocateSpaceOnStack();
74
    void deallocateSpaceOnStack();
75
76
    void parseArguments(const Signature&);
77
    void parseVars();
78
79
    void parseStmt();
80
    void parseGetLocal(int dst);
81
    void parseSetLocal(uint32_t imm, int dst);
82
    void parseSetLocal(int dst);
83
    void parseReturnStmt();
84
    void parseBlockStmt();
85
    void parseStmtList();
86
    void parseIfStmt();
87
    void parseIfElseStmt();
88
    void parseWhileStmt();
89
    void parseDoStmt();
90
    void parseLabelStmt();
91
    void parseBreakStmt();
92
    void parseBreakLabelStmt();
93
    void parseContinueStmt();
94
    void parseContinueLabelStmt();
95
    void parseSwitchStmt();
96
97
    void parseExpr(RType, int dst);
98
    void parseExprI32(int dst);
99
    void parseExprF64(int dst);
100
    void parseCallInternal(RType, int dst);
101
    void parseBinaryOp(uint8_t op, RType, int dst);
102
    void parseUnaryOp(uint8_t op, RType, int dst);
103
    void parseRelationalOpI32(RelationalCondition, RType operandType, int dst);
104
    void parseRelationalOpF64(DoubleCondition, RType operandType, int dst);
105
    void parseComma(RType, int dst);
106
    void parseCond(RType, int dst);
107
108
    Address stackAddress(int i) const // FIXME: Is this correct?
109
    {
110
        return Address(GPRInfo::callFrameRegister, -i * 8 - 8);
111
    }
112
113
    Address temporaryAddress(int i) const // FIXME: Is this correct?
114
    {
115
        return Address(GPRInfo::callFrameRegister, -(i + m_currentLocalTypes.size()) * 8 - 8);
116
    }
117
118
    void pushContinueLabelLabel(Label* label) { m_continueLabelLabels.append(label); }
119
    void popContinueLabelLabel() { m_continueLabelLabels.removeLast(); }
120
    Label* continueLabelLabel(size_t i) const { return m_continueLabelLabels[i]; }
121
    void pushBreakLabelJumpList(JumpList* jumpList) { m_breakLabelJumpLists.append(jumpList); }
122
    void popBreakLabelJumpList() { m_breakLabelJumpLists.removeLast(); }
123
    JumpList* breakLabelJumpList(size_t i) const { return m_breakLabelJumpLists[i]; }
124
125
    void pushContinueJumpScope(JumpScope* jumpScope) { m_continueJumpScopes.append(jumpScope); }
126
    void popContinueJumpScope() { m_continueJumpScopes.removeLast(); }
127
    JumpScope* topContinueJumpScope() const { return m_continueJumpScopes.last(); }
128
129
    void pushBreakJumpList(JumpList* jumpList) { m_breakJumpLists.append(jumpList); }
130
    void popBreakJumpList() { m_breakJumpLists.removeLast(); }
131
    JumpList* topBreakJumpList() const { return m_breakJumpLists.last(); }
132
133
    Module* m_module;
134
135
    uint32_t m_stackHeight; // FIXME: This caused a 'segmentation fault' heisenbug when I added "size_t m_stackHeight". Something must be wrong.
136
137
    Vector<std::pair<Call, void*>> m_calls;
138
139
    RType m_currentReturnType;
140
    Vector<Type> m_currentLocalTypes;
141
142
    Vector<MacroAssembler::Label*> m_continueLabelLabels;
143
    Vector<MacroAssembler::JumpList*> m_breakLabelJumpLists;
144
145
    Vector<JumpScope*> m_continueJumpScopes;
146
    Vector<MacroAssembler::JumpList*> m_breakJumpLists;
147
};
148
149
} } // namespace JSC::Wasm
150
151
#endif // WasmJITCompiler_h
- a/Source/JavaScriptCore/wasm/WasmModule.cpp +267 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 "ProtoCallFrame.h"
47
#include "WasmJITCompiler.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_read = Reader(reinterpret_cast<const uint8_t*>(buffer.data()));
58
59
    if (m_read.fixedWidth<uint32_t>() != MagicNumber)
60
        abort();
61
    m_read.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
    parseExportSection();
71
72
    VM& vm = exec->vm();
73
74
    JSObject* object = constructEmptyObject(exec);
75
76
    for (size_t i = 0; i < m_jitCodes.size(); ++i) {
77
        RefPtr<JITCode> jitCode = m_jitCodes[i];
78
79
        WebAssemblyExecutable* executable = WebAssemblyExecutable::create(vm, SourceCode());
80
81
        DeferGC deferGC(vm.heap);
82
83
        RefPtr<WebAssemblyCodeBlock> codeBlock = adoptRef(new WebAssemblyCodeBlock(executable, exec->lexicalGlobalObject()));
84
        codeBlock->setJITCode(jitCode);
85
        executable->installCode(codeBlock.get());
86
87
        JSFunction* jsFunction = JSFunction::create(exec->vm(), executable, exec->lexicalGlobalObject());
88
89
        Identifier identifier = Identifier::fromString(&vm, String::format("f%lu", i));
90
        object->putDirect(vm, identifier, jsFunction);
91
    }
92
93
    return object;
94
}
95
96
void Module::parseConstantPoolSection()
97
{
98
    uint32_t numberOfI32s = m_read.immU32();
99
    uint32_t numberOfF32s = m_read.immU32();
100
    uint32_t numberOfF64s = m_read.immU32();
101
102
    Vector<uint32_t> constantI32s(numberOfI32s);
103
    for (uint32_t i = 0; i < numberOfI32s; ++i)
104
        constantI32s[i] = m_read.immU32();
105
106
    Vector<float> constantF32s(numberOfF32s);
107
    for (uint32_t i = 0; i < numberOfF32s; ++i)
108
        constantF32s[i] = m_read.fixedWidth<float>();
109
110
    Vector<double> constantF64s(numberOfF64s);
111
    for (uint32_t i = 0; i < numberOfF64s; ++i)
112
        constantF64s[i] = m_read.fixedWidth<double>();
113
114
    m_constantI32s = WTF::move(constantI32s);
115
    m_constantF32s = WTF::move(constantF32s);
116
    m_constantF64s = WTF::move(constantF64s);
117
}
118
119
void Module::parseSignatureSection()
120
{
121
    uint32_t numberOfSignatures = m_read.immU32();
122
    Vector<Signature> signatures(numberOfSignatures);
123
    for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
124
        RType ret = m_read.rtype();
125
        uint32_t argumentCount = m_read.immU32();
126
        Signature signature(ret, argumentCount);
127
        for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex)
128
            signature.arguments[argumentIndex] = m_read.type();
129
        signatures[signatureIndex] = WTF::move(signature);
130
    }
131
132
    m_signatures = WTF::move(signatures);
133
}
134
135
void Module::parseFunctionImportSection()
136
{
137
    uint32_t numberOfFuncImports = m_read.immU32();
138
    uint32_t numberOfFuncImportSignatures = m_read.immU32();
139
140
    Vector<FuncImportSignature> funcImportSignatures(numberOfFuncImportSignatures);
141
    FuncImportSignature* funcImportSignature = funcImportSignatures.data();
142
    for (uint32_t funcImportIndex = 0; funcImportIndex < numberOfFuncImports; ++funcImportIndex) {
143
        while (m_read.singleChar()) { }
144
145
        uint32_t numberOfSignatures = m_read.immU32();
146
        for (uint32_t i = 0; i < numberOfSignatures; ++i) {
147
            funcImportSignature->signatureIndex = m_read.immU32();
148
            funcImportSignature->funcImportIndex = funcImportIndex;
149
            funcImportSignature++;
150
        }
151
    }
152
    assert(funcImportSignature == funcImportSignatures.data() + numberOfFuncImportSignatures);
153
154
    m_funcImportSignatures = WTF::move(funcImportSignatures);
155
}
156
157
void Module::parseGlobalSection()
158
{
159
    uint32_t numberOfI32Zero = m_read.immU32();
160
    uint32_t numberOfF32Zero = m_read.immU32();
161
    uint32_t numberOfF64Zero = m_read.immU32();
162
    uint32_t numberOfI32Import = m_read.immU32();
163
    uint32_t numberOfF32Import = m_read.immU32();
164
    uint32_t numberOfF64Import = m_read.immU32();
165
    uint32_t numberOfGlobalVars = numberOfI32Zero + numberOfF32Zero + numberOfF64Zero + numberOfI32Import + numberOfF32Import + numberOfF64Import;
166
167
    Vector<Type> globalTypes(numberOfGlobalVars);
168
    size_t globalTypeIndex = 0;
169
    for (uint32_t i = 0; i < numberOfI32Zero; ++i)
170
        globalTypes[globalTypeIndex++] = Type::I32;
171
    for (uint32_t i = 0; i < numberOfF32Zero; ++i)
172
        globalTypes[globalTypeIndex++] = Type::F32;
173
    for (uint32_t i = 0; i < numberOfF64Zero; ++i)
174
        globalTypes[globalTypeIndex++] = Type::F64;
175
    for (uint32_t i = 0; i < numberOfI32Import; ++i) {
176
        while (m_read.singleChar()) { }
177
        globalTypes[globalTypeIndex++] = Type::I32;
178
    }
179
    for (uint32_t i = 0; i < numberOfF32Import; ++i) {
180
        while (m_read.singleChar()) { }
181
        globalTypes[globalTypeIndex++] = Type::F32;
182
    }
183
    for (uint32_t i = 0; i < numberOfF64Import; ++i) {
184
        while (m_read.singleChar()) { }
185
        globalTypes[globalTypeIndex++] = Type::F64;
186
    }
187
    m_globalTypes = WTF::move(globalTypes);
188
}
189
190
void Module::parseFunctionDeclarationSection()
191
{
192
    uint32_t numberOfFunctions = m_read.immU32();
193
    Vector<uint32_t> funcSignatures(numberOfFunctions);
194
    for (uint32_t i = 0; i < numberOfFunctions; ++i)
195
        funcSignatures[i] = m_read.immU32();
196
197
    m_funcSignatures = WTF::move(funcSignatures);
198
}
199
200
void Module::parseFunctionPointerTables()
201
{
202
    uint32_t numberOfFuncPtrTables = m_read.immU32();
203
    Vector<FuncPtrTable> funcPtrTables(numberOfFuncPtrTables);
204
    for (uint32_t i = 0; i < numberOfFuncPtrTables; ++i) {
205
        funcPtrTables[i].signatureIndex = m_read.immU32();
206
        uint32_t numElements = m_read.immU32();
207
        Vector<uint32_t> elements(numElements);
208
        for (uint32_t j = 0; j < numElements; ++j)
209
            elements[j] = m_read.immU32();
210
        funcPtrTables[i].elements = WTF::move(elements);
211
    }
212
213
    m_funcPtrTables = WTF::move(funcPtrTables);
214
}
215
216
void Module::parseFunctionDefinitionSection(ExecState* exec)
217
{
218
    for (size_t i = 0; i < m_funcSignatures.size(); ++i)
219
        parseFunctionDefinition(exec, i);
220
}
221
222
void Module::parseExportSection()
223
{
224
    switch (m_read.exportFormat()) {
225
    case ExportFormat::Default:
226
        m_read.immU32();
227
        break;
228
    case ExportFormat::Record:
229
        if (uint32_t numExports = m_read.immU32()) {
230
            for (uint32_t exportIndex = 0; exportIndex < numExports; ++exportIndex) {
231
                while (m_read.singleChar()) { }
232
                m_read.immU32();
233
            }
234
        }
235
        break;
236
    default:
237
        RELEASE_ASSERT_NOT_REACHED();
238
    }
239
}
240
241
void Module::parseFunctionDefinition(ExecState* exec, size_t functionIndex)
242
{
243
    JITCompiler jitCompiler(&exec->vm(), this);
244
    RefPtr<JITCode> jitCode = jitCompiler.compileFunction(exec->vm(), functionIndex);
245
    m_jitCodes.append(jitCode);
246
}
247
248
JSValue Module::callInternalFunction(ExecState* exec, size_t functionIndex)
249
{
250
    // FIXME: hacky!
251
    VM& vm = exec->vm();
252
    ProtoCallFrame protoCallFrame;
253
    protoCallFrame.init(0, JSCallee::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()), jsUndefined(), 1);
254
255
    return m_jitCodes[functionIndex]->execute(&vm, &protoCallFrame);
256
}
257
258
JSValue compile(ExecState* exec, const Vector<char>& buffer)
259
{
260
    Module* module = Module::create(exec->vm(), exec->lexicalGlobalObject());
261
262
    // FIXME: If the GC happens to run at this time, will we fail?
263
264
    return module->compile(exec, buffer);
265
}
266
267
} } // namespace JSC::Wasm
- a/Source/JavaScriptCore/wasm/WasmModule.h +122 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
    Module(VM& vm, Structure* structure)
58
        : Base(vm, structure)
59
    {
60
    }
61
62
    static Module* create(VM& vm, JSGlobalObject* globalObject)
63
    {
64
        Structure* structure = createStructure(vm, globalObject); // FIXME: is this right?
65
        Module* module = new (NotNull, allocateCell<Module>(vm.heap)) Module(vm, structure);
66
        module->finishCreation(vm);
67
        return module;
68
    }
69
70
    DECLARE_INFO;
71
72
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
73
    {
74
        return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
75
    }
76
77
    JSValue compile(ExecState*, const Vector<char>& buffer);
78
    JSValue callInternalFunction(ExecState*, size_t functionIndex);
79
80
private:
81
    friend class JITCompiler;
82
83
    struct FuncImportSignature {
84
        uint32_t signatureIndex;
85
        uint32_t funcImportIndex;
86
    };
87
88
    struct FuncPtrTable {
89
        uint32_t signatureIndex;
90
        Vector<uint32_t> elements;
91
    };
92
93
    void parseConstantPoolSection();
94
    void parseSignatureSection();
95
    void parseFunctionImportSection();
96
    void parseGlobalSection();
97
    void parseFunctionDeclarationSection();
98
    void parseFunctionPointerTables();
99
    void parseFunctionDefinitionSection(ExecState*);
100
    void parseExportSection();
101
102
    void parseFunctionDefinition(ExecState*, size_t functionIndex);
103
104
    Reader m_read;
105
106
    Vector<Signature> m_signatures;
107
    Vector<uint32_t> m_constantI32s;
108
    Vector<float> m_constantF32s;
109
    Vector<double> m_constantF64s;
110
    Vector<FuncImportSignature> m_funcImportSignatures;
111
    Vector<Type> m_globalTypes;
112
    Vector<uint32_t> m_funcSignatures;
113
    Vector<FuncPtrTable> m_funcPtrTables;
114
115
    Vector<RefPtr<JITCode>> m_jitCodes; // TODO: keep JSFunctions instead and make sure to keep them alive
116
};
117
118
JS_EXPORT_PRIVATE JSValue compile(ExecState*, const Vector<char>& buffer);
119
120
} } // namespace JSC::Wasm
121
122
#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 RType : 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(RType(-1)), u { }
323
    {
324
    }
325
    Expr(I32 i32) : m_type(RType::I32) { u.i32 = i32; }
326
    Expr(F32 f32) : m_type(RType::F32) { u.f32 = f32; }
327
    Expr(F64 f64) : m_type(RType::F64) { u.f64 = f64; }
328
    Expr(Void v) : m_type(RType::Void) { u.v = v; }
329
330
    RType 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
    RType 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
    RType ret;
415
    Vector<Type> arguments;
416
417
    Signature() { }
418
    Signature(RType ret)
419
        : ret(ret) { }
420
    Signature(RType ret, uint32_t argumentCount)
421
        : ret(ret)
422
        , arguments(argumentCount) { }
423
    Signature(RType ret, Vector<Type>&& arguments)
424
        : ret(ret)
425
        , arguments(WTF::move(arguments)) { }
426
427
    bool operator==(const Signature& rhs) const { return ret == rhs.ret && 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(RType) == 1, "Shift more");
434
            uint32_t h = uint8_t(signature.ret);
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
    RType rtype() { return u8<RType>(); }
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