OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef WASM_RUN_UTILS_H | 5 #ifndef WASM_RUN_UTILS_H |
6 #define WASM_RUN_UTILS_H | 6 #define WASM_RUN_UTILS_H |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
11 | 11 |
12 #include "src/base/utils/random-number-generator.h" | 12 #include "src/base/utils/random-number-generator.h" |
13 | 13 |
14 #include "src/compiler/graph-visualizer.h" | 14 #include "src/compiler/graph-visualizer.h" |
15 #include "src/compiler/int64-lowering.h" | 15 #include "src/compiler/int64-lowering.h" |
16 #include "src/compiler/js-graph.h" | 16 #include "src/compiler/js-graph.h" |
17 #include "src/compiler/node.h" | 17 #include "src/compiler/node.h" |
18 #include "src/compiler/pipeline.h" | 18 #include "src/compiler/pipeline.h" |
19 #include "src/compiler/wasm-compiler.h" | 19 #include "src/compiler/wasm-compiler.h" |
20 #include "src/compiler/zone-pool.h" | 20 #include "src/compiler/zone-pool.h" |
21 | 21 |
22 #include "src/wasm/ast-decoder.h" | 22 #include "src/wasm/ast-decoder.h" |
23 #include "src/wasm/wasm-js.h" | 23 #include "src/wasm/wasm-js.h" |
| 24 #include "src/wasm/wasm-macro-gen.h" |
24 #include "src/wasm/wasm-module.h" | 25 #include "src/wasm/wasm-module.h" |
25 #include "src/wasm/wasm-opcodes.h" | 26 #include "src/wasm/wasm-opcodes.h" |
26 | 27 |
27 #include "src/zone.h" | 28 #include "src/zone.h" |
28 | 29 |
29 #include "test/cctest/cctest.h" | 30 #include "test/cctest/cctest.h" |
30 #include "test/cctest/compiler/call-tester.h" | 31 #include "test/cctest/compiler/call-tester.h" |
31 #include "test/cctest/compiler/graph-builder-tester.h" | 32 #include "test/cctest/compiler/graph-builder-tester.h" |
32 | 33 |
33 // TODO(titzer): pull WASM_64 up to a common header. | 34 // TODO(titzer): pull WASM_64 up to a common header. |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 Handle<Code> code = instance->function_code[index]; | 196 Handle<Code> code = instance->function_code[index]; |
196 WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context()); | 197 WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context()); |
197 return compiler::CompileJSToWasmWrapper(isolate, this, name, code, | 198 return compiler::CompileJSToWasmWrapper(isolate, this, name, code, |
198 module_object, index); | 199 module_object, index); |
199 } | 200 } |
200 | 201 |
201 void SetFunctionCode(uint32_t index, Handle<Code> code) { | 202 void SetFunctionCode(uint32_t index, Handle<Code> code) { |
202 instance->function_code[index] = code; | 203 instance->function_code[index] = code; |
203 } | 204 } |
204 | 205 |
| 206 void SetFunctionBytes(uint32_t index, const byte* start, const byte* end) { |
| 207 int length = static_cast<int>(end - start); |
| 208 DCHECK_EQ(end - start, length); |
| 209 uint32_t bytes_offset = AddModuleBytes(Vector<const byte>(start, length)); |
| 210 module_.functions[index].code_start_offset = bytes_offset; |
| 211 module_.functions[index].code_end_offset = bytes_offset + length; |
| 212 } |
| 213 |
| 214 void SetFunctionName(uint32_t index, Vector<const char> name) { |
| 215 uint32_t name_offset = AddModuleBytes(Vector<const byte>( |
| 216 reinterpret_cast<const byte*>(name.start()), name.length())); |
| 217 module_.functions[index].name_offset = name_offset; |
| 218 module_.functions[index].name_length = name.length(); |
| 219 } |
| 220 |
205 void AddIndirectFunctionTable(int* functions, int table_size) { | 221 void AddIndirectFunctionTable(int* functions, int table_size) { |
206 Isolate* isolate = module->shared_isolate; | 222 Isolate* isolate = module->shared_isolate; |
207 Handle<FixedArray> fixed = | 223 Handle<FixedArray> fixed = |
208 isolate->factory()->NewFixedArray(2 * table_size); | 224 isolate->factory()->NewFixedArray(2 * table_size); |
209 instance->function_table = fixed; | 225 instance->function_table = fixed; |
210 DCHECK_EQ(0u, module->function_table.size()); | 226 DCHECK_EQ(0u, module->function_table.size()); |
211 for (int i = 0; i < table_size; i++) { | 227 for (int i = 0; i < table_size; i++) { |
212 module->function_table.push_back(functions[i]); | 228 module->function_table.push_back(functions[i]); |
213 } | 229 } |
214 } | 230 } |
215 | 231 |
216 void PopulateIndirectFunctionTable() { | 232 void PopulateIndirectFunctionTable() { |
217 if (instance->function_table.is_null()) return; | 233 if (instance->function_table.is_null()) return; |
218 int table_size = static_cast<int>(module->function_table.size()); | 234 int table_size = static_cast<int>(module->function_table.size()); |
219 for (int i = 0; i < table_size; i++) { | 235 for (int i = 0; i < table_size; i++) { |
220 int function_index = module->function_table[i]; | 236 int function_index = module->function_table[i]; |
221 WasmFunction* function = &module->functions[function_index]; | 237 WasmFunction* function = &module->functions[function_index]; |
222 instance->function_table->set(i, Smi::FromInt(function->sig_index)); | 238 instance->function_table->set(i, Smi::FromInt(function->sig_index)); |
223 instance->function_table->set(i + table_size, | 239 instance->function_table->set(i + table_size, |
224 *instance->function_code[function_index]); | 240 *instance->function_code[function_index]); |
225 } | 241 } |
226 } | 242 } |
227 | 243 |
| 244 Handle<JSObject> Instantiate() { |
| 245 Isolate* isolate = module->shared_isolate; |
| 246 Handle<JSObject> ffi; // We don't need ffi in tests. |
| 247 Handle<JSArrayBuffer> memory; // We don't need memory in tests. |
| 248 return module->Instantiate(isolate, ffi, memory).ToHandleChecked(); |
| 249 } |
| 250 |
228 private: | 251 private: |
229 WasmModule module_; | 252 WasmModule module_; |
230 WasmModuleInstance instance_; | 253 WasmModuleInstance instance_; |
231 uint32_t global_offset; | 254 uint32_t global_offset; |
232 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data. | 255 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data. |
233 | 256 |
| 257 // This vector contains function names and wasm code, but not in any valid |
| 258 // format. It is references by WasmFunctions (name_offset, code_start_offset). |
| 259 std::vector<byte> module_bytes_; |
| 260 |
234 WasmGlobal* AddGlobal(MachineType mem_type) { | 261 WasmGlobal* AddGlobal(MachineType mem_type) { |
235 byte size = WasmOpcodes::MemSize(mem_type); | 262 byte size = WasmOpcodes::MemSize(mem_type); |
236 global_offset = (global_offset + size - 1) & ~(size - 1); // align | 263 global_offset = (global_offset + size - 1) & ~(size - 1); // align |
237 module->globals.push_back({0, 0, mem_type, global_offset, false}); | 264 module->globals.push_back({0, 0, mem_type, global_offset, false}); |
238 global_offset += size; | 265 global_offset += size; |
239 // limit number of globals. | 266 // limit number of globals. |
240 CHECK_LT(global_offset, kMaxGlobalsSize); | 267 CHECK_LT(global_offset, kMaxGlobalsSize); |
241 return &module->globals.back(); | 268 return &module->globals.back(); |
242 } | 269 } |
| 270 |
| 271 uint32_t AddModuleBytes(Vector<const byte> bytes) { |
| 272 DCHECK(module->module_start == nullptr || |
| 273 module->module_start == module_bytes_.data()); |
| 274 DCHECK_EQ(module->module_start == nullptr, module_bytes_.empty()); |
| 275 module_bytes_.insert(module_bytes_.end(), bytes.start(), |
| 276 bytes.start() + bytes.length()); |
| 277 module->module_start = module_bytes_.data(); |
| 278 module->module_end = module_bytes_.data() + module_bytes_.size(); |
| 279 return static_cast<uint32_t>(module_bytes_.size() - bytes.length()); |
| 280 } |
243 }; | 281 }; |
244 | 282 |
245 inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module, | 283 inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module, |
246 FunctionSig* sig, | 284 FunctionSig* sig, |
247 SourcePositionTable* source_position_table, | 285 SourcePositionTable* source_position_table, |
248 const byte* start, const byte* end) { | 286 const byte* start, const byte* end) { |
249 compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table); | 287 compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table); |
250 TreeResult result = | 288 TreeResult result = |
251 BuildTFGraph(zone->allocator(), &builder, module, sig, start, end); | 289 BuildTFGraph(zone->allocator(), &builder, module, sig, start, end); |
252 if (result.failed()) { | 290 if (result.failed()) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 descriptor_ = testing_module_->GetWasmCallDescriptor(main_zone(), sig); | 498 descriptor_ = testing_module_->GetWasmCallDescriptor(main_zone(), sig); |
461 } | 499 } |
462 } | 500 } |
463 CallDescriptor* descriptor() { return descriptor_; } | 501 CallDescriptor* descriptor() { return descriptor_; } |
464 | 502 |
465 void Build(const byte* start, const byte* end) { | 503 void Build(const byte* start, const byte* end) { |
466 // Build the TurboFan graph. | 504 // Build the TurboFan graph. |
467 local_decls.Prepend(&start, &end); | 505 local_decls.Prepend(&start, &end); |
468 TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig, | 506 TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig, |
469 &source_position_table_, start, end); | 507 &source_position_table_, start, end); |
| 508 if (testing_module_ != nullptr) |
| 509 testing_module_->SetFunctionBytes(function_index_, start, end); |
470 delete[] start; | 510 delete[] start; |
471 } | 511 } |
472 | 512 |
473 byte AllocateLocal(LocalType type) { | 513 byte AllocateLocal(LocalType type) { |
474 uint32_t index = local_decls.AddLocals(1, type, sig); | 514 uint32_t index = local_decls.AddLocals(1, type, sig); |
475 byte result = static_cast<byte>(index); | 515 byte result = static_cast<byte>(index); |
476 DCHECK_EQ(index, result); | 516 DCHECK_EQ(index, result); |
477 return result; | 517 return result; |
478 } | 518 } |
479 | 519 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 #endif | 556 #endif |
517 | 557 |
518 return code; | 558 return code; |
519 } | 559 } |
520 | 560 |
521 uint32_t CompileAndAdd(uint16_t sig_index = 0) { | 561 uint32_t CompileAndAdd(uint16_t sig_index = 0) { |
522 CHECK(testing_module_); | 562 CHECK(testing_module_); |
523 function()->sig_index = sig_index; | 563 function()->sig_index = sig_index; |
524 Handle<Code> code = Compile(); | 564 Handle<Code> code = Compile(); |
525 testing_module_->SetFunctionCode(function_index_, code); | 565 testing_module_->SetFunctionCode(function_index_, code); |
| 566 if (debug_name_.start() != nullptr) |
| 567 testing_module_->SetFunctionName(function_index_, debug_name_); |
526 return static_cast<uint32_t>(function_index_); | 568 return static_cast<uint32_t>(function_index_); |
527 } | 569 } |
528 | 570 |
529 WasmFunction* function() { | 571 WasmFunction* function() { |
530 if (function_) return function_; | 572 if (function_) return function_; |
531 return &testing_module_->module->functions[function_index_]; | 573 return &testing_module_->module->functions[function_index_]; |
532 } | 574 } |
533 | 575 |
534 // Set the context, such that e.g. runtime functions can be called. | 576 // Set the context, such that e.g. runtime functions can be called. |
535 void SetModuleContext() { | 577 void SetModuleContext() { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 if (p1 == MachineType::None()) return 1; | 700 if (p1 == MachineType::None()) return 1; |
659 if (p2 == MachineType::None()) return 2; | 701 if (p2 == MachineType::None()) return 2; |
660 if (p3 == MachineType::None()) return 3; | 702 if (p3 == MachineType::None()) return 3; |
661 return 4; | 703 return 4; |
662 } | 704 } |
663 }; | 705 }; |
664 | 706 |
665 } // namespace | 707 } // namespace |
666 | 708 |
667 #endif | 709 #endif |
OLD | NEW |