| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 env->local_int32_count = 0; | 53 env->local_int32_count = 0; |
| 54 env->local_int64_count = 0; | 54 env->local_int64_count = 0; |
| 55 env->local_float32_count = 0; | 55 env->local_float32_count = 0; |
| 56 env->local_float64_count = 0; | 56 env->local_float64_count = 0; |
| 57 env->SumLocals(); | 57 env->SumLocals(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 const uint32_t kMaxGlobalsSize = 128; | 60 const uint32_t kMaxGlobalsSize = 128; |
| 61 | 61 |
| 62 // A helper for module environments that adds the ability to allocate memory | 62 // A helper for module environments that adds the ability to allocate memory |
| 63 // and global variables. | 63 // and global variables. Contains a built-in {WasmModuleInstance}. |
| 64 class TestingModule : public ModuleEnv { | 64 class TestingModule : public ModuleEnv { |
| 65 public: | 65 public: |
| 66 TestingModule() : mem_size(0), global_offset(0) { | 66 TestingModule() : instance_(nullptr), global_offset(0) { |
| 67 globals_area = 0; | 67 instance = &instance_; |
| 68 mem_start = 0; | 68 instance->globals_start = global_data; |
| 69 mem_end = 0; | 69 instance->globals_size = kMaxGlobalsSize; |
| 70 instance->mem_start = nullptr; |
| 71 instance->mem_size = 0; |
| 72 instance->function_code = nullptr; |
| 70 module = nullptr; | 73 module = nullptr; |
| 71 linker = nullptr; | 74 linker = nullptr; |
| 72 function_code = nullptr; | |
| 73 asm_js = false; | 75 asm_js = false; |
| 74 memset(global_data, 0, sizeof(global_data)); | 76 memset(global_data, 0, sizeof(global_data)); |
| 75 } | 77 } |
| 76 | 78 |
| 77 ~TestingModule() { | 79 ~TestingModule() { |
| 78 if (mem_start) { | 80 if (instance->mem_start) { |
| 79 free(raw_mem_start<byte>()); | 81 free(instance->mem_start); |
| 80 } | 82 } |
| 81 if (function_code) delete function_code; | 83 if (instance->function_code) delete instance->function_code; |
| 82 if (module) delete module; | 84 if (module) delete module; |
| 83 } | 85 } |
| 84 | 86 |
| 85 byte* AddMemory(size_t size) { | 87 byte* AddMemory(size_t size) { |
| 86 CHECK_EQ(0, mem_start); | 88 CHECK_NULL(instance->mem_start); |
| 87 CHECK_EQ(0, mem_size); | 89 CHECK_EQ(0, instance->mem_size); |
| 88 mem_start = reinterpret_cast<uintptr_t>(malloc(size)); | 90 instance->mem_start = reinterpret_cast<byte*>(malloc(size)); |
| 89 CHECK(mem_start); | 91 CHECK(instance->mem_start); |
| 90 byte* raw = raw_mem_start<byte>(); | 92 memset(instance->mem_start, 0, size); |
| 91 memset(raw, 0, size); | 93 instance->mem_size = size; |
| 92 mem_end = mem_start + size; | |
| 93 mem_size = size; | |
| 94 return raw_mem_start<byte>(); | 94 return raw_mem_start<byte>(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 template <typename T> | 97 template <typename T> |
| 98 T* AddMemoryElems(size_t count) { | 98 T* AddMemoryElems(size_t count) { |
| 99 AddMemory(count * sizeof(T)); | 99 AddMemory(count * sizeof(T)); |
| 100 return raw_mem_start<T>(); | 100 return raw_mem_start<T>(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 template <typename T> | 103 template <typename T> |
| 104 T* AddGlobal(MachineType mem_type) { | 104 T* AddGlobal(MachineType mem_type) { |
| 105 WasmGlobal* global = AddGlobal(mem_type); | 105 WasmGlobal* global = AddGlobal(mem_type); |
| 106 return reinterpret_cast<T*>(globals_area + global->offset); | 106 return reinterpret_cast<T*>(instance->globals_start + global->offset); |
| 107 } | 107 } |
| 108 | 108 |
| 109 byte AddSignature(FunctionSig* sig) { | 109 byte AddSignature(FunctionSig* sig) { |
| 110 AllocModule(); | 110 AllocModule(); |
| 111 if (!module->signatures) { | 111 if (!module->signatures) { |
| 112 module->signatures = new std::vector<FunctionSig*>(); | 112 module->signatures = new std::vector<FunctionSig*>(); |
| 113 } | 113 } |
| 114 module->signatures->push_back(sig); | 114 module->signatures->push_back(sig); |
| 115 size_t size = module->signatures->size(); | 115 size_t size = module->signatures->size(); |
| 116 CHECK(size < 127); | 116 CHECK(size < 127); |
| 117 return static_cast<byte>(size - 1); | 117 return static_cast<byte>(size - 1); |
| 118 } | 118 } |
| 119 | 119 |
| 120 template <typename T> | 120 template <typename T> |
| 121 T* raw_mem_start() { | 121 T* raw_mem_start() { |
| 122 DCHECK(mem_start); | 122 DCHECK(instance->mem_start); |
| 123 return reinterpret_cast<T*>(mem_start); | 123 return reinterpret_cast<T*>(instance->mem_start); |
| 124 } | 124 } |
| 125 | 125 |
| 126 template <typename T> | 126 template <typename T> |
| 127 T* raw_mem_end() { | 127 T* raw_mem_end() { |
| 128 DCHECK(mem_end); | 128 DCHECK(instance->mem_start); |
| 129 return reinterpret_cast<T*>(mem_end); | 129 return reinterpret_cast<T*>(instance->mem_start + instance->mem_size); |
| 130 } | 130 } |
| 131 | 131 |
| 132 template <typename T> | 132 template <typename T> |
| 133 T raw_mem_at(int i) { | 133 T raw_mem_at(int i) { |
| 134 DCHECK(mem_start); | 134 DCHECK(instance->mem_start); |
| 135 return reinterpret_cast<T*>(mem_start)[i]; | 135 return reinterpret_cast<T*>(instance->mem_start)[i]; |
| 136 } | 136 } |
| 137 | 137 |
| 138 template <typename T> | 138 template <typename T> |
| 139 T raw_val_at(int i) { | 139 T raw_val_at(int i) { |
| 140 T val; | 140 T val; |
| 141 memcpy(&val, reinterpret_cast<void*>(mem_start + i), sizeof(T)); | 141 memcpy(&val, reinterpret_cast<void*>(instance->mem_start + i), sizeof(T)); |
| 142 return val; | 142 return val; |
| 143 } | 143 } |
| 144 | 144 |
| 145 // Zero-initialize the memory. | 145 // Zero-initialize the memory. |
| 146 void BlankMemory() { | 146 void BlankMemory() { |
| 147 byte* raw = raw_mem_start<byte>(); | 147 byte* raw = raw_mem_start<byte>(); |
| 148 memset(raw, 0, mem_size); | 148 memset(raw, 0, instance->mem_size); |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Pseudo-randomly intialize the memory. | 151 // Pseudo-randomly intialize the memory. |
| 152 void RandomizeMemory(unsigned int seed = 88) { | 152 void RandomizeMemory(unsigned int seed = 88) { |
| 153 byte* raw = raw_mem_start<byte>(); | 153 byte* raw = raw_mem_start<byte>(); |
| 154 byte* end = raw_mem_end<byte>(); | 154 byte* end = raw_mem_end<byte>(); |
| 155 v8::base::RandomNumberGenerator rng; | 155 v8::base::RandomNumberGenerator rng; |
| 156 rng.SetSeed(seed); | 156 rng.SetSeed(seed); |
| 157 rng.NextBytes(raw, end - raw); | 157 rng.NextBytes(raw, end - raw); |
| 158 } | 158 } |
| 159 | 159 |
| 160 WasmFunction* AddFunction(FunctionSig* sig, Handle<Code> code) { | 160 WasmFunction* AddFunction(FunctionSig* sig, Handle<Code> code) { |
| 161 AllocModule(); | 161 AllocModule(); |
| 162 if (module->functions == nullptr) { | 162 if (module->functions == nullptr) { |
| 163 module->functions = new std::vector<WasmFunction>(); | 163 module->functions = new std::vector<WasmFunction>(); |
| 164 function_code = new std::vector<Handle<Code>>(); | 164 instance->function_code = new std::vector<Handle<Code>>(); |
| 165 } | 165 } |
| 166 module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false}); | 166 module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false}); |
| 167 function_code->push_back(code); | 167 instance->function_code->push_back(code); |
| 168 return &module->functions->back(); | 168 return &module->functions->back(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 void AddIndirectFunctionTable(int* functions, int table_size) { | 171 void AddIndirectFunctionTable(int* functions, int table_size) { |
| 172 AllocModule(); | 172 AllocModule(); |
| 173 Isolate* isolate = module->shared_isolate; | 173 Isolate* isolate = module->shared_isolate; |
| 174 Handle<FixedArray> fixed = | 174 Handle<FixedArray> fixed = |
| 175 isolate->factory()->NewFixedArray(2 * table_size); | 175 isolate->factory()->NewFixedArray(2 * table_size); |
| 176 function_table = fixed; | 176 instance->function_table = fixed; |
| 177 module->function_table = new std::vector<uint16_t>(); | 177 module->function_table = new std::vector<uint16_t>(); |
| 178 for (int i = 0; i < table_size; i++) { | 178 for (int i = 0; i < table_size; i++) { |
| 179 module->function_table->push_back(functions[i]); | 179 module->function_table->push_back(functions[i]); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 void PopulateIndirectFunctionTable() { | 183 void PopulateIndirectFunctionTable() { |
| 184 if (function_table.is_null()) return; | 184 if (instance->function_table.is_null()) return; |
| 185 int table_size = static_cast<int>(module->function_table->size()); | 185 int table_size = static_cast<int>(module->function_table->size()); |
| 186 for (int i = 0; i < table_size; i++) { | 186 for (int i = 0; i < table_size; i++) { |
| 187 int function_index = module->function_table->at(i); | 187 int function_index = module->function_table->at(i); |
| 188 WasmFunction* function = &module->functions->at(function_index); | 188 WasmFunction* function = &module->functions->at(function_index); |
| 189 function_table->set(i, Smi::FromInt(function->sig_index)); | 189 instance->function_table->set(i, Smi::FromInt(function->sig_index)); |
| 190 function_table->set(i + table_size, *function_code->at(function_index)); | 190 instance->function_table->set( |
| 191 i + table_size, *instance->function_code->at(function_index)); |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 | 194 |
| 194 | 195 |
| 195 private: | 196 private: |
| 196 size_t mem_size; | 197 WasmModuleInstance instance_; |
| 197 uint32_t global_offset; | 198 uint32_t global_offset; |
| 198 byte global_data[kMaxGlobalsSize]; | 199 byte global_data[kMaxGlobalsSize]; // preallocated global data. |
| 199 | 200 |
| 200 WasmGlobal* AddGlobal(MachineType mem_type) { | 201 WasmGlobal* AddGlobal(MachineType mem_type) { |
| 201 AllocModule(); | 202 AllocModule(); |
| 202 if (globals_area == 0) { | 203 if (!module->globals) { |
| 203 globals_area = reinterpret_cast<uintptr_t>(global_data); | |
| 204 module->globals = new std::vector<WasmGlobal>(); | 204 module->globals = new std::vector<WasmGlobal>(); |
| 205 } | 205 } |
| 206 byte size = WasmOpcodes::MemSize(mem_type); | 206 byte size = WasmOpcodes::MemSize(mem_type); |
| 207 global_offset = (global_offset + size - 1) & ~(size - 1); // align | 207 global_offset = (global_offset + size - 1) & ~(size - 1); // align |
| 208 module->globals->push_back({0, mem_type, global_offset, false}); | 208 module->globals->push_back({0, mem_type, global_offset, false}); |
| 209 global_offset += size; | 209 global_offset += size; |
| 210 // limit number of globals. | 210 // limit number of globals. |
| 211 CHECK_LT(global_offset, kMaxGlobalsSize); | 211 CHECK_LT(global_offset, kMaxGlobalsSize); |
| 212 return &module->globals->back(); | 212 return &module->globals->back(); |
| 213 } | 213 } |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 if (p1 == MachineType::None()) return 1; | 407 if (p1 == MachineType::None()) return 1; |
| 408 if (p2 == MachineType::None()) return 2; | 408 if (p2 == MachineType::None()) return 2; |
| 409 if (p3 == MachineType::None()) return 3; | 409 if (p3 == MachineType::None()) return 3; |
| 410 return 4; | 410 return 4; |
| 411 } | 411 } |
| 412 }; | 412 }; |
| 413 | 413 |
| 414 } // namespace | 414 } // namespace |
| 415 | 415 |
| 416 #endif | 416 #endif |
| OLD | NEW |