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 |