Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1113)

Side by Side Diff: src/wasm/wasm-module.h

Issue 2540133002: [wasm] Remove raw byte pointers from WasmModule (Closed)
Patch Set: Address comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-interpreter.cc ('k') | src/wasm/wasm-module.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 V8_WASM_MODULE_H_ 5 #ifndef V8_WASM_MODULE_H_
6 #define V8_WASM_MODULE_H_ 6 #define V8_WASM_MODULE_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/api.h" 10 #include "src/api.h"
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 170
171 // Static representation of a WASM export. 171 // Static representation of a WASM export.
172 struct WasmExport { 172 struct WasmExport {
173 uint32_t name_length; // length in bytes of the exported name. 173 uint32_t name_length; // length in bytes of the exported name.
174 uint32_t name_offset; // offset in module bytes of the name to export. 174 uint32_t name_offset; // offset in module bytes of the name to export.
175 WasmExternalKind kind; // kind of the export. 175 WasmExternalKind kind; // kind of the export.
176 uint32_t index; // index into the respective space. 176 uint32_t index; // index into the respective space.
177 }; 177 };
178 178
179 enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin }; 179 enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin };
180 struct ModuleWireBytes;
180 181
181 // Static representation of a module. 182 // Static representation of a module.
182 struct V8_EXPORT_PRIVATE WasmModule { 183 struct V8_EXPORT_PRIVATE WasmModule {
183 static const uint32_t kPageSize = 0x10000; // Page size, 64kb. 184 static const uint32_t kPageSize = 0x10000; // Page size, 64kb.
184 static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb 185 static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb
185 static const size_t kV8MaxPages = 16384; // Maximum memory size = 1gb 186 static const size_t kV8MaxPages = 16384; // Maximum memory size = 1gb
186 static const size_t kSpecMaxPages = 65536; // Maximum according to the spec 187 static const size_t kSpecMaxPages = 65536; // Maximum according to the spec
187 static const size_t kV8MaxTableSize = 16 * 1024 * 1024; 188 static const size_t kV8MaxTableSize = 16 * 1024 * 1024;
188 189
189 Zone* owned_zone; 190 Zone* owned_zone;
190 const byte* module_start = nullptr; // starting address for the module bytes
191 const byte* module_end = nullptr; // end address for the module bytes
192 uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages 191 uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages
193 uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages 192 uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages
194 bool has_memory = false; // true if the memory was defined or imported 193 bool has_memory = false; // true if the memory was defined or imported
195 bool mem_export = false; // true if the memory is exported 194 bool mem_export = false; // true if the memory is exported
196 // TODO(wasm): reconcile start function index being an int with 195 // TODO(wasm): reconcile start function index being an int with
197 // the fact that we index on uint32_t, so we may technically not be 196 // the fact that we index on uint32_t, so we may technically not be
198 // able to represent some start_function_index -es. 197 // able to represent some start_function_index -es.
199 int start_function_index = -1; // start function, if any 198 int start_function_index = -1; // start function, if any
200 ModuleOrigin origin = kWasmOrigin; // origin of the module 199 ModuleOrigin origin = kWasmOrigin; // origin of the module
201 200
(...skipping 11 matching lines...) Expand all
213 std::vector<WasmTableInit> table_inits; // initializations of tables 212 std::vector<WasmTableInit> table_inits; // initializations of tables
214 // We store the semaphore here to extend its lifetime. In <libc-2.21, which we 213 // We store the semaphore here to extend its lifetime. In <libc-2.21, which we
215 // use on the try bots, semaphore::Wait() can return while some compilation 214 // use on the try bots, semaphore::Wait() can return while some compilation
216 // tasks are still executing semaphore::Signal(). If the semaphore is cleaned 215 // tasks are still executing semaphore::Signal(). If the semaphore is cleaned
217 // up right after semaphore::Wait() returns, then this can cause an 216 // up right after semaphore::Wait() returns, then this can cause an
218 // invalid-semaphore error in the compilation tasks. 217 // invalid-semaphore error in the compilation tasks.
219 // TODO(wasm): Move this semaphore back to CompileInParallel when the try bots 218 // TODO(wasm): Move this semaphore back to CompileInParallel when the try bots
220 // switch to libc-2.21 or higher. 219 // switch to libc-2.21 or higher.
221 std::unique_ptr<base::Semaphore> pending_tasks; 220 std::unique_ptr<base::Semaphore> pending_tasks;
222 221
223 WasmModule() : WasmModule(nullptr, nullptr) {} 222 WasmModule() : WasmModule(nullptr) {}
224 WasmModule(Zone* owned_zone, const byte* module_start); 223 WasmModule(Zone* owned_zone);
225 ~WasmModule() { 224 ~WasmModule() {
226 if (owned_zone) delete owned_zone; 225 if (owned_zone) delete owned_zone;
227 } 226 }
228 227
229 // Get a string stored in the module bytes representing a name.
230 WasmName GetName(uint32_t offset, uint32_t length) const {
231 if (length == 0) return {"<?>", 3}; // no name.
232 CHECK(BoundsCheck(offset, offset + length));
233 DCHECK_GE(static_cast<int>(length), 0);
234 return {reinterpret_cast<const char*>(module_start + offset),
235 static_cast<int>(length)};
236 }
237
238 // Get a string stored in the module bytes representing a function name.
239 WasmName GetName(WasmFunction* function) const {
240 return GetName(function->name_offset, function->name_length);
241 }
242
243 // Get a string stored in the module bytes representing a name.
244 WasmName GetNameOrNull(uint32_t offset, uint32_t length) const {
245 if (offset == 0 && length == 0) return {NULL, 0}; // no name.
246 CHECK(BoundsCheck(offset, offset + length));
247 DCHECK_GE(static_cast<int>(length), 0);
248 return {reinterpret_cast<const char*>(module_start + offset),
249 static_cast<int>(length)};
250 }
251
252 // Get a string stored in the module bytes representing a function name.
253 WasmName GetNameOrNull(const WasmFunction* function) const {
254 return GetNameOrNull(function->name_offset, function->name_length);
255 }
256
257 // Checks the given offset range is contained within the module bytes.
258 bool BoundsCheck(uint32_t start, uint32_t end) const {
259 size_t size = module_end - module_start;
260 return start <= size && end <= size;
261 }
262
263 // Creates a new instantiation of the module in the given isolate. 228 // Creates a new instantiation of the module in the given isolate.
264 static MaybeHandle<WasmInstanceObject> Instantiate( 229 static MaybeHandle<WasmInstanceObject> Instantiate(
265 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, 230 Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module,
266 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory); 231 Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory);
267 232
268 MaybeHandle<WasmCompiledModule> CompileFunctions( 233 MaybeHandle<WasmCompiledModule> CompileFunctions(
269 Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper, 234 Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper,
270 ErrorThrower* thrower) const; 235 ErrorThrower* thrower, const ModuleWireBytes& wire_bytes) const;
271 }; 236 };
272 237
273 typedef Managed<WasmModule> WasmModuleWrapper; 238 typedef Managed<WasmModule> WasmModuleWrapper;
274 239
275 // An instantiated WASM module, including memory, function table, etc. 240 // An instantiated WASM module, including memory, function table, etc.
276 struct WasmInstance { 241 struct WasmInstance {
277 const WasmModule* module; // static representation of the module. 242 const WasmModule* module; // static representation of the module.
278 // -- Heap allocated -------------------------------------------------------- 243 // -- Heap allocated --------------------------------------------------------
279 Handle<JSObject> js_object; // JavaScript module object. 244 Handle<JSObject> js_object; // JavaScript module object.
280 Handle<Context> context; // JavaScript native context. 245 Handle<Context> context; // JavaScript native context.
281 Handle<JSArrayBuffer> mem_buffer; // Handle to array buffer of memory. 246 Handle<JSArrayBuffer> mem_buffer; // Handle to array buffer of memory.
282 Handle<JSArrayBuffer> globals_buffer; // Handle to array buffer of globals. 247 Handle<JSArrayBuffer> globals_buffer; // Handle to array buffer of globals.
283 std::vector<Handle<FixedArray>> function_tables; // indirect function tables. 248 std::vector<Handle<FixedArray>> function_tables; // indirect function tables.
284 std::vector<Handle<Code>> function_code; // code objects for each function. 249 std::vector<Handle<Code>> function_code; // code objects for each function.
285 // -- raw memory ------------------------------------------------------------ 250 // -- raw memory ------------------------------------------------------------
286 byte* mem_start = nullptr; // start of linear memory. 251 byte* mem_start = nullptr; // start of linear memory.
287 uint32_t mem_size = 0; // size of the linear memory. 252 uint32_t mem_size = 0; // size of the linear memory.
288 // -- raw globals ----------------------------------------------------------- 253 // -- raw globals -----------------------------------------------------------
289 byte* globals_start = nullptr; // start of the globals area. 254 byte* globals_start = nullptr; // start of the globals area.
290 255
291 explicit WasmInstance(const WasmModule* m) 256 explicit WasmInstance(const WasmModule* m)
292 : module(m), 257 : module(m),
293 function_tables(m->function_tables.size()), 258 function_tables(m->function_tables.size()),
294 function_code(m->functions.size()) {} 259 function_code(m->functions.size()) {}
295 }; 260 };
296 261
262 // Interface to the storage (wire bytes) of a wasm module.
263 // It is illegal for anyone receiving a ModuleWireBytes to store pointers based
264 // on module_bytes, as this storage is only guaranteed to be alive as long as
265 // this struct is alive.
266 struct V8_EXPORT_PRIVATE ModuleWireBytes {
267 ModuleWireBytes(Vector<const byte> module_bytes)
268 : module_bytes(module_bytes) {}
269 ModuleWireBytes(const byte* start, const byte* end)
270 : module_bytes(start, static_cast<int>(end - start)) {
271 DCHECK_GE(kMaxInt, end - start);
272 }
273
274 const Vector<const byte> module_bytes;
275
276 // Get a string stored in the module bytes representing a name.
277 WasmName GetName(uint32_t offset, uint32_t length) const {
278 if (length == 0) return {"<?>", 3}; // no name.
279 CHECK(BoundsCheck(offset, length));
280 DCHECK_GE(static_cast<int>(length), 0);
281 return Vector<const char>::cast(
282 module_bytes.SubVector(offset, offset + length));
283 }
284
285 // Get a string stored in the module bytes representing a function name.
286 WasmName GetName(const WasmFunction* function) const {
287 return GetName(function->name_offset, function->name_length);
288 }
289
290 // Get a string stored in the module bytes representing a name.
291 WasmName GetNameOrNull(uint32_t offset, uint32_t length) const {
292 if (offset == 0 && length == 0) return {NULL, 0}; // no name.
293 CHECK(BoundsCheck(offset, length));
294 DCHECK_GE(static_cast<int>(length), 0);
295 return Vector<const char>::cast(
296 module_bytes.SubVector(offset, offset + length));
297 }
298
299 // Get a string stored in the module bytes representing a function name.
300 WasmName GetNameOrNull(const WasmFunction* function) const {
301 return GetNameOrNull(function->name_offset, function->name_length);
302 }
303
304 // Checks the given offset range is contained within the module bytes.
305 bool BoundsCheck(uint32_t offset, uint32_t length) const {
306 uint32_t size = static_cast<uint32_t>(module_bytes.length());
307 return offset <= size && length <= size - offset;
308 }
309 };
310
297 // Interface provided to the decoder/graph builder which contains only 311 // Interface provided to the decoder/graph builder which contains only
298 // minimal information about the globals, functions, and function tables. 312 // minimal information about the globals, functions, and function tables.
299 struct V8_EXPORT_PRIVATE ModuleEnv { 313 struct V8_EXPORT_PRIVATE ModuleEnv {
314 ModuleEnv(const WasmModule* module, WasmInstance* instance)
315 : module(module), instance(instance) {}
316
300 const WasmModule* module; 317 const WasmModule* module;
301 WasmInstance* instance; 318 WasmInstance* instance;
302 ModuleOrigin origin;
303 319
304 bool IsValidGlobal(uint32_t index) const { 320 bool IsValidGlobal(uint32_t index) const {
305 return module && index < module->globals.size(); 321 return module && index < module->globals.size();
306 } 322 }
307 bool IsValidFunction(uint32_t index) const { 323 bool IsValidFunction(uint32_t index) const {
308 return module && index < module->functions.size(); 324 return module && index < module->functions.size();
309 } 325 }
310 bool IsValidSignature(uint32_t index) const { 326 bool IsValidSignature(uint32_t index) const {
311 return module && index < module->signatures.size(); 327 return module && index < module->signatures.size();
312 } 328 }
(...skipping 10 matching lines...) Expand all
323 } 339 }
324 FunctionSig* GetSignature(uint32_t index) { 340 FunctionSig* GetSignature(uint32_t index) {
325 DCHECK(IsValidSignature(index)); 341 DCHECK(IsValidSignature(index));
326 return module->signatures[index]; 342 return module->signatures[index];
327 } 343 }
328 const WasmIndirectFunctionTable* GetTable(uint32_t index) const { 344 const WasmIndirectFunctionTable* GetTable(uint32_t index) const {
329 DCHECK(IsValidTable(index)); 345 DCHECK(IsValidTable(index));
330 return &module->function_tables[index]; 346 return &module->function_tables[index];
331 } 347 }
332 348
333 bool asm_js() { return origin == kAsmJsOrigin; } 349 bool asm_js() { return module->origin == kAsmJsOrigin; }
334 350
335 Handle<Code> GetFunctionCode(uint32_t index) { 351 Handle<Code> GetFunctionCode(uint32_t index) {
336 DCHECK_NOT_NULL(instance); 352 DCHECK_NOT_NULL(instance);
337 return instance->function_code[index]; 353 return instance->function_code[index];
338 } 354 }
339 355
340 static compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone, 356 static compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone,
341 FunctionSig* sig); 357 FunctionSig* sig);
342 static compiler::CallDescriptor* GetI32WasmCallDescriptor( 358 static compiler::CallDescriptor* GetI32WasmCallDescriptor(
343 Zone* zone, compiler::CallDescriptor* descriptor); 359 Zone* zone, compiler::CallDescriptor* descriptor);
344 static compiler::CallDescriptor* GetI32WasmCallDescriptorForSimd( 360 static compiler::CallDescriptor* GetI32WasmCallDescriptorForSimd(
345 Zone* zone, compiler::CallDescriptor* descriptor); 361 Zone* zone, compiler::CallDescriptor* descriptor);
346 }; 362 };
347 363
364 // A ModuleEnv together with ModuleWireBytes.
365 struct ModuleBytesEnv : public ModuleEnv, public ModuleWireBytes {
366 ModuleBytesEnv(const WasmModule* module, WasmInstance* instance,
367 Vector<const byte> module_bytes)
368 : ModuleEnv(module, instance), ModuleWireBytes(module_bytes) {}
369 ModuleBytesEnv(const WasmModule* module, WasmInstance* instance,
370 const ModuleWireBytes& wire_bytes)
371 : ModuleEnv(module, instance), ModuleWireBytes(wire_bytes) {}
372 };
373
348 // A helper for printing out the names of functions. 374 // A helper for printing out the names of functions.
349 struct WasmFunctionName { 375 struct WasmFunctionName {
376 WasmFunctionName(const WasmFunction* function, ModuleBytesEnv* module_env)
377 : function_(function), name_(module_env->GetNameOrNull(function)) {}
378
350 const WasmFunction* function_; 379 const WasmFunction* function_;
351 const WasmModule* module_; 380 WasmName name_;
352 WasmFunctionName(const WasmFunction* function, const ModuleEnv* menv)
353 : function_(function), module_(menv ? menv->module : nullptr) {}
354 }; 381 };
355 382
356 std::ostream& operator<<(std::ostream& os, const WasmModule& module); 383 std::ostream& operator<<(std::ostream& os, const WasmModule& module);
357 std::ostream& operator<<(std::ostream& os, const WasmFunction& function); 384 std::ostream& operator<<(std::ostream& os, const WasmFunction& function);
358 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name); 385 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
359 386
360 // Extract a function name from the given wasm instance. 387 // Extract a function name from the given wasm instance.
361 // Returns "<WASM UNNAMED>" if no instance is passed, the function is unnamed or 388 // Returns "<WASM UNNAMED>" if no instance is passed, the function is unnamed or
362 // the name is not a valid UTF-8 string. 389 // the name is not a valid UTF-8 string.
363 // TODO(5620): Refactor once we always get a wasm instance. 390 // TODO(5620): Refactor once we always get a wasm instance.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 void ValidateModuleState(Isolate* isolate, Handle<WasmModuleObject> module_obj); 466 void ValidateModuleState(Isolate* isolate, Handle<WasmModuleObject> module_obj);
440 void ValidateOrphanedInstance(Isolate* isolate, 467 void ValidateOrphanedInstance(Isolate* isolate,
441 Handle<WasmInstanceObject> instance); 468 Handle<WasmInstanceObject> instance);
442 469
443 } // namespace testing 470 } // namespace testing
444 } // namespace wasm 471 } // namespace wasm
445 } // namespace internal 472 } // namespace internal
446 } // namespace v8 473 } // namespace v8
447 474
448 #endif // V8_WASM_MODULE_H_ 475 #endif // V8_WASM_MODULE_H_
OLDNEW
« no previous file with comments | « src/wasm/wasm-interpreter.cc ('k') | src/wasm/wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698