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> |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 | 71 |
72 const uint32_t kMaxGlobalsSize = 128; | 72 const uint32_t kMaxGlobalsSize = 128; |
73 | 73 |
74 // A helper for module environments that adds the ability to allocate memory | 74 // A helper for module environments that adds the ability to allocate memory |
75 // and global variables. Contains a built-in {WasmModule} and | 75 // and global variables. Contains a built-in {WasmModule} and |
76 // {WasmModuleInstance}. | 76 // {WasmModuleInstance}. |
77 class TestingModule : public ModuleEnv { | 77 class TestingModule : public ModuleEnv { |
78 public: | 78 public: |
79 explicit TestingModule(WasmExecutionMode mode = kExecuteCompiled) | 79 explicit TestingModule(WasmExecutionMode mode = kExecuteCompiled) |
80 : execution_mode_(mode), | 80 : execution_mode_(mode), |
| 81 linked_(false), |
81 instance_(&module_), | 82 instance_(&module_), |
82 isolate_(CcTest::InitIsolateOnce()), | 83 isolate_(CcTest::InitIsolateOnce()), |
83 global_offset(0), | 84 global_offset(0), |
84 interpreter_(mode == kExecuteInterpreted | 85 interpreter_(mode == kExecuteInterpreted |
85 ? new WasmInterpreter(&instance_, &allocator_) | 86 ? new WasmInterpreter(&instance_, &allocator_) |
86 : nullptr) { | 87 : nullptr) { |
87 module = &module_; | 88 module = &module_; |
88 instance = &instance_; | 89 instance = &instance_; |
89 instance->module = &module_; | 90 instance->module = &module_; |
90 instance->globals_start = global_data; | 91 instance->globals_start = global_data; |
91 module_.globals_size = kMaxGlobalsSize; | 92 module_.globals_size = kMaxGlobalsSize; |
92 instance->mem_start = nullptr; | 93 instance->mem_start = nullptr; |
93 instance->mem_size = 0; | 94 instance->mem_size = 0; |
94 linker = nullptr; | |
95 origin = kWasmOrigin; | 95 origin = kWasmOrigin; |
96 memset(global_data, 0, sizeof(global_data)); | 96 memset(global_data, 0, sizeof(global_data)); |
97 } | 97 } |
98 | 98 |
99 ~TestingModule() { | 99 ~TestingModule() { |
100 if (instance->mem_start) { | 100 if (instance->mem_start) { |
101 free(instance->mem_start); | 101 free(instance->mem_start); |
102 } | 102 } |
103 if (interpreter_) delete interpreter_; | 103 if (interpreter_) delete interpreter_; |
104 } | 104 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 instance->function_code[index] = code; | 201 instance->function_code[index] = code; |
202 return index; | 202 return index; |
203 } | 203 } |
204 | 204 |
205 Handle<JSFunction> WrapCode(uint32_t index) { | 205 Handle<JSFunction> WrapCode(uint32_t index) { |
206 // Wrap the code so it can be called as a JS function. | 206 // Wrap the code so it can be called as a JS function. |
207 Handle<String> name = isolate_->factory()->NewStringFromStaticChars("main"); | 207 Handle<String> name = isolate_->factory()->NewStringFromStaticChars("main"); |
208 Handle<JSObject> module_object = Handle<JSObject>(0, isolate_); | 208 Handle<JSObject> module_object = Handle<JSObject>(0, isolate_); |
209 Handle<Code> code = instance->function_code[index]; | 209 Handle<Code> code = instance->function_code[index]; |
210 WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context()); | 210 WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context()); |
211 return compiler::CompileJSToWasmWrapper(isolate_, this, name, code, | 211 Handle<JSFunction> ret = compiler::CompileJSToWasmWrapper( |
212 module_object, index); | 212 isolate_, this, name, code, module_object, index); |
| 213 Link(); |
| 214 return ret; |
213 } | 215 } |
214 | 216 |
215 void SetFunctionCode(uint32_t index, Handle<Code> code) { | 217 void SetFunctionCode(uint32_t index, Handle<Code> code) { |
216 instance->function_code[index] = code; | 218 instance->function_code[index] = code; |
217 } | 219 } |
218 | 220 |
219 void AddIndirectFunctionTable(int* functions, int table_size) { | 221 void AddIndirectFunctionTable(int* functions, int table_size) { |
220 Handle<FixedArray> fixed = | 222 Handle<FixedArray> fixed = |
221 isolate_->factory()->NewFixedArray(2 * table_size); | 223 isolate_->factory()->NewFixedArray(2 * table_size); |
222 instance->function_table = fixed; | 224 instance->function_table = fixed; |
(...skipping 12 matching lines...) Expand all Loading... |
235 instance->function_table->set(i, Smi::FromInt(function->sig_index)); | 237 instance->function_table->set(i, Smi::FromInt(function->sig_index)); |
236 instance->function_table->set(i + table_size, | 238 instance->function_table->set(i + table_size, |
237 *instance->function_code[function_index]); | 239 *instance->function_code[function_index]); |
238 } | 240 } |
239 } | 241 } |
240 WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; } | 242 WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; } |
241 | 243 |
242 WasmInterpreter* interpreter() { return interpreter_; } | 244 WasmInterpreter* interpreter() { return interpreter_; } |
243 WasmExecutionMode execution_mode() { return execution_mode_; } | 245 WasmExecutionMode execution_mode() { return execution_mode_; } |
244 | 246 |
| 247 void Link() { |
| 248 if (linked_) return; |
| 249 compiler::Link(CcTest::i_isolate(), instance->function_code, |
| 250 instance->function_code, RelocInfo::kWasmDirectCallMask); |
| 251 compiler::Link(CcTest::i_isolate(), instance->function_code, |
| 252 instance->import_code, RelocInfo::kWasmImportCallMask); |
| 253 |
| 254 linked_ = true; |
| 255 } |
| 256 |
245 private: | 257 private: |
246 WasmExecutionMode execution_mode_; | 258 WasmExecutionMode execution_mode_; |
247 WasmModule module_; | 259 WasmModule module_; |
| 260 bool linked_; |
248 WasmModuleInstance instance_; | 261 WasmModuleInstance instance_; |
249 Isolate* isolate_; | 262 Isolate* isolate_; |
250 v8::base::AccountingAllocator allocator_; | 263 v8::base::AccountingAllocator allocator_; |
251 uint32_t global_offset; | 264 uint32_t global_offset; |
252 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data. | 265 V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data. |
253 WasmInterpreter* interpreter_; | 266 WasmInterpreter* interpreter_; |
254 | 267 |
255 const WasmGlobal* AddGlobal(MachineType mem_type) { | 268 const WasmGlobal* AddGlobal(MachineType mem_type) { |
256 byte size = WasmOpcodes::MemSize(mem_type); | 269 byte size = WasmOpcodes::MemSize(mem_type); |
257 global_offset = (global_offset + size - 1) & ~(size - 1); // align | 270 global_offset = (global_offset + size - 1) & ~(size - 1); // align |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 return Call(p0, p1, p2, 0); | 705 return Call(p0, p1, p2, 0); |
693 } | 706 } |
694 } | 707 } |
695 | 708 |
696 template <typename P0, typename P1, typename P2, typename P3> | 709 template <typename P0, typename P1, typename P2, typename P3> |
697 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { | 710 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { |
698 if (interpret()) { | 711 if (interpret()) { |
699 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)}; | 712 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)}; |
700 return CallInterpreter(ArrayVector(args)); | 713 return CallInterpreter(ArrayVector(args)); |
701 } else { | 714 } else { |
| 715 if (compiler_.testing_module_ != nullptr) { |
| 716 compiler_.testing_module_->Link(); |
| 717 } |
702 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(), | 718 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(), |
703 wrapper_.GetWrapperCode(), | 719 wrapper_.GetWrapperCode(), |
704 wrapper_.signature()); | 720 wrapper_.signature()); |
705 ReturnType return_value; | 721 ReturnType return_value; |
706 int32_t result = runner.Call<void*, void*, void*, void*, void*>( | 722 int32_t result = runner.Call<void*, void*, void*, void*, void*>( |
707 &p0, &p1, &p2, &p3, &return_value); | 723 &p0, &p1, &p2, &p3, &return_value); |
708 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result); | 724 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result); |
709 return return_value; | 725 return return_value; |
710 } | 726 } |
711 } | 727 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 // interpreter. | 778 // interpreter. |
763 #define WASM_EXEC_TEST(name) \ | 779 #define WASM_EXEC_TEST(name) \ |
764 void RunWasm_##name(WasmExecutionMode execution_mode); \ | 780 void RunWasm_##name(WasmExecutionMode execution_mode); \ |
765 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ | 781 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ |
766 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ | 782 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ |
767 void RunWasm_##name(WasmExecutionMode execution_mode) | 783 void RunWasm_##name(WasmExecutionMode execution_mode) |
768 | 784 |
769 } // namespace | 785 } // namespace |
770 | 786 |
771 #endif | 787 #endif |
OLD | NEW |