OLD | NEW |
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 #include "src/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
6 #include "src/objects.h" | 6 #include "src/objects.h" |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/simulator.h" | 9 #include "src/simulator.h" |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 os << " code bytes: " | 42 os << " code bytes: " |
43 << (function.code_end_offset - function.code_start_offset); | 43 << (function.code_end_offset - function.code_start_offset); |
44 return os; | 44 return os; |
45 } | 45 } |
46 | 46 |
47 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) { | 47 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) { |
48 os << "#" << pair.function_->func_index << ":"; | 48 os << "#" << pair.function_->func_index << ":"; |
49 if (pair.function_->name_offset > 0) { | 49 if (pair.function_->name_offset > 0) { |
50 if (pair.module_) { | 50 if (pair.module_) { |
51 os << pair.module_->GetName(pair.function_->name_offset); | 51 WasmName name = pair.module_->GetName(pair.function_->name_offset, |
| 52 pair.function_->name_length); |
| 53 os.write(name.name, name.length); |
52 } else { | 54 } else { |
53 os << "+" << pair.function_->func_index; | 55 os << "+" << pair.function_->func_index; |
54 } | 56 } |
55 } else { | 57 } else { |
56 os << "?"; | 58 os << "?"; |
57 } | 59 } |
58 return os; | 60 return os; |
59 } | 61 } |
60 | 62 |
61 // A helper class for compiling multiple wasm functions that offers | 63 // A helper class for compiling multiple wasm functions that offers |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 module_end(nullptr), | 275 module_end(nullptr), |
274 min_mem_pages(0), | 276 min_mem_pages(0), |
275 max_mem_pages(0), | 277 max_mem_pages(0), |
276 mem_export(false), | 278 mem_export(false), |
277 mem_external(false), | 279 mem_external(false), |
278 start_function_index(-1), | 280 start_function_index(-1), |
279 origin(kWasmOrigin) {} | 281 origin(kWasmOrigin) {} |
280 | 282 |
281 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, | 283 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, |
282 const char* error, uint32_t index, | 284 const char* error, uint32_t index, |
283 const char* module_cstr, | 285 wasm::WasmName module_name, |
284 const char* function_cstr) { | 286 wasm::WasmName function_name) { |
285 if (function_cstr) { | 287 if (function_name.name) { |
286 thrower.Error("Import #%d module=\"%s\" function=\"%s\" error: %s", index, | 288 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", |
287 module_cstr, function_cstr, error); | 289 index, module_name.length, module_name.name, |
| 290 function_name.length, function_name.name, error); |
288 } else { | 291 } else { |
289 thrower.Error("Import #%d module=\"%s\" error: %s", index, module_cstr, | 292 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, |
290 error); | 293 module_name.length, module_name.name, error); |
291 } | 294 } |
292 thrower.Error("Import "); | 295 thrower.Error("Import "); |
293 return MaybeHandle<JSFunction>(); | 296 return MaybeHandle<JSFunction>(); |
294 } | 297 } |
295 | 298 |
296 static MaybeHandle<JSFunction> LookupFunction( | 299 static MaybeHandle<JSFunction> LookupFunction( |
297 ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi, | 300 ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi, |
298 uint32_t index, const char* module_cstr, const char* function_cstr) { | 301 uint32_t index, wasm::WasmName module_name, wasm::WasmName function_name) { |
299 if (ffi.is_null()) { | 302 if (ffi.is_null()) { |
300 return ReportFFIError(thrower, "FFI is not an object", index, module_cstr, | 303 return ReportFFIError(thrower, "FFI is not an object", index, module_name, |
301 function_cstr); | 304 function_name); |
302 } | 305 } |
303 | 306 |
304 // Look up the module first. | 307 // Look up the module first. |
305 Handle<String> name = factory->InternalizeUtf8String(module_cstr); | 308 Handle<String> name = factory->InternalizeUtf8String( |
| 309 Vector<const char>(module_name.name, module_name.length)); |
306 MaybeHandle<Object> result = Object::GetProperty(ffi, name); | 310 MaybeHandle<Object> result = Object::GetProperty(ffi, name); |
307 if (result.is_null()) { | 311 if (result.is_null()) { |
308 return ReportFFIError(thrower, "module not found", index, module_cstr, | 312 return ReportFFIError(thrower, "module not found", index, module_name, |
309 function_cstr); | 313 function_name); |
310 } | 314 } |
311 | 315 |
312 Handle<Object> module = result.ToHandleChecked(); | 316 Handle<Object> module = result.ToHandleChecked(); |
313 | 317 |
314 if (!module->IsJSReceiver()) { | 318 if (!module->IsJSReceiver()) { |
315 return ReportFFIError(thrower, "module is not an object or function", index, | 319 return ReportFFIError(thrower, "module is not an object or function", index, |
316 module_cstr, function_cstr); | 320 module_name, function_name); |
317 } | 321 } |
318 | 322 |
319 Handle<Object> function; | 323 Handle<Object> function; |
320 if (function_cstr) { | 324 if (function_name.name) { |
321 // Look up the function in the module. | 325 // Look up the function in the module. |
322 Handle<String> name = factory->InternalizeUtf8String(function_cstr); | 326 Handle<String> name = factory->InternalizeUtf8String( |
| 327 Vector<const char>(function_name.name, function_name.length)); |
323 MaybeHandle<Object> result = Object::GetProperty(module, name); | 328 MaybeHandle<Object> result = Object::GetProperty(module, name); |
324 if (result.is_null()) { | 329 if (result.is_null()) { |
325 return ReportFFIError(thrower, "function not found", index, module_cstr, | 330 return ReportFFIError(thrower, "function not found", index, module_name, |
326 function_cstr); | 331 function_name); |
327 } | 332 } |
328 function = result.ToHandleChecked(); | 333 function = result.ToHandleChecked(); |
329 } else { | 334 } else { |
330 // No function specified. Use the "default export". | 335 // No function specified. Use the "default export". |
331 function = module; | 336 function = module; |
332 } | 337 } |
333 | 338 |
334 if (!function->IsJSFunction()) { | 339 if (!function->IsJSFunction()) { |
335 return ReportFFIError(thrower, "not a function", index, module_cstr, | 340 return ReportFFIError(thrower, "not a function", index, module_name, |
336 function_cstr); | 341 function_name); |
337 } | 342 } |
338 | 343 |
339 return Handle<JSFunction>::cast(function); | 344 return Handle<JSFunction>::cast(function); |
340 } | 345 } |
341 | 346 |
342 // Instantiates a wasm module as a JSObject. | 347 // Instantiates a wasm module as a JSObject. |
343 // * allocates a backing store of {mem_size} bytes. | 348 // * allocates a backing store of {mem_size} bytes. |
344 // * installs a named property "memory" for that buffer if exported | 349 // * installs a named property "memory" for that buffer if exported |
345 // * installs named properties on the object for exported functions | 350 // * installs named properties on the object for exported functions |
346 // * compiles wasm code to machine code | 351 // * compiles wasm code to machine code |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 WasmLinker linker(isolate, functions.size()); | 402 WasmLinker linker(isolate, functions.size()); |
398 ModuleEnv module_env; | 403 ModuleEnv module_env; |
399 module_env.module = this; | 404 module_env.module = this; |
400 module_env.instance = &instance; | 405 module_env.instance = &instance; |
401 module_env.linker = &linker; | 406 module_env.linker = &linker; |
402 module_env.origin = origin; | 407 module_env.origin = origin; |
403 | 408 |
404 if (import_table.size() > 0) { | 409 if (import_table.size() > 0) { |
405 instance.import_code.reserve(import_table.size()); | 410 instance.import_code.reserve(import_table.size()); |
406 for (const WasmImport& import : import_table) { | 411 for (const WasmImport& import : import_table) { |
407 const char* module_cstr = GetNameOrNull(import.module_name_offset); | 412 WasmName module_name = |
408 const char* function_cstr = GetNameOrNull(import.function_name_offset); | 413 GetNameOrNull(import.module_name_offset, import.module_name_length); |
| 414 WasmName function_name = GetNameOrNull(import.function_name_offset, |
| 415 import.function_name_length); |
409 MaybeHandle<JSFunction> function = LookupFunction( | 416 MaybeHandle<JSFunction> function = LookupFunction( |
410 thrower, factory, ffi, index, module_cstr, function_cstr); | 417 thrower, factory, ffi, index, module_name, function_name); |
411 if (function.is_null()) return MaybeHandle<JSObject>(); | 418 if (function.is_null()) return MaybeHandle<JSObject>(); |
412 Handle<Code> code = compiler::CompileWasmToJSWrapper( | 419 Handle<Code> code = compiler::CompileWasmToJSWrapper( |
413 isolate, &module_env, function.ToHandleChecked(), import.sig, | 420 isolate, &module_env, function.ToHandleChecked(), import.sig, |
414 module_cstr, function_cstr); | 421 module_name, function_name); |
415 instance.import_code.push_back(code); | 422 instance.import_code.push_back(code); |
416 index++; | 423 index++; |
417 } | 424 } |
418 } | 425 } |
419 | 426 |
420 //------------------------------------------------------------------------- | 427 //------------------------------------------------------------------------- |
421 // Compile all functions in the module. | 428 // Compile all functions in the module. |
422 //------------------------------------------------------------------------- | 429 //------------------------------------------------------------------------- |
423 | 430 |
424 // First pass: compile each function and initialize the code table. | 431 // First pass: compile each function and initialize the code table. |
425 index = 0; | 432 index = 0; |
426 for (const WasmFunction& func : functions) { | 433 for (const WasmFunction& func : functions) { |
427 if (thrower.error()) break; | 434 if (thrower.error()) break; |
428 DCHECK_EQ(index, func.func_index); | 435 DCHECK_EQ(index, func.func_index); |
429 | 436 |
430 const char* cstr = GetName(func.name_offset); | 437 WasmName str = GetName(func.name_offset, func.name_length); |
431 Handle<String> name = factory->InternalizeUtf8String(cstr); | 438 WasmName str_null = {nullptr, 0}; |
| 439 Handle<String> name = factory->InternalizeUtf8String( |
| 440 Vector<const char>(str.name, str.length)); |
432 Handle<Code> code = Handle<Code>::null(); | 441 Handle<Code> code = Handle<Code>::null(); |
433 Handle<JSFunction> function = Handle<JSFunction>::null(); | 442 Handle<JSFunction> function = Handle<JSFunction>::null(); |
434 if (func.external) { | 443 if (func.external) { |
435 // Lookup external function in FFI object. | 444 // Lookup external function in FFI object. |
436 MaybeHandle<JSFunction> function = | 445 MaybeHandle<JSFunction> function = |
437 LookupFunction(thrower, factory, ffi, index, cstr, nullptr); | 446 LookupFunction(thrower, factory, ffi, index, str, str_null); |
438 if (function.is_null()) return MaybeHandle<JSObject>(); | 447 if (function.is_null()) return MaybeHandle<JSObject>(); |
439 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | 448 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, |
440 function.ToHandleChecked(), | 449 function.ToHandleChecked(), |
441 func.sig, cstr, nullptr); | 450 func.sig, str, str_null); |
442 } else { | 451 } else { |
443 // Compile the function. | 452 // Compile the function. |
444 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 453 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); |
445 if (code.is_null()) { | 454 if (code.is_null()) { |
446 thrower.Error("Compilation of #%d:%s failed.", index, cstr); | 455 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length, |
| 456 str.name); |
447 return MaybeHandle<JSObject>(); | 457 return MaybeHandle<JSObject>(); |
448 } | 458 } |
449 if (func.exported) { | 459 if (func.exported) { |
450 function = compiler::CompileJSToWasmWrapper( | 460 function = compiler::CompileJSToWasmWrapper( |
451 isolate, &module_env, name, code, instance.js_object, index); | 461 isolate, &module_env, name, code, instance.js_object, index); |
452 } | 462 } |
453 } | 463 } |
454 if (!code.is_null()) { | 464 if (!code.is_null()) { |
455 // Install the code into the linker table. | 465 // Install the code into the linker table. |
456 linker.Finish(index, code); | 466 linker.Finish(index, code); |
(...skipping 21 matching lines...) Expand all Loading... |
478 isolate->native_context()->object_function(), isolate); | 488 isolate->native_context()->object_function(), isolate); |
479 Handle<JSObject> exports_object = | 489 Handle<JSObject> exports_object = |
480 factory->NewJSObject(object_function, TENURED); | 490 factory->NewJSObject(object_function, TENURED); |
481 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 491 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
482 JSObject::AddProperty(instance.js_object, exports_name, exports_object, | 492 JSObject::AddProperty(instance.js_object, exports_name, exports_object, |
483 READ_ONLY); | 493 READ_ONLY); |
484 | 494 |
485 // Compile wrappers and add them to the exports object. | 495 // Compile wrappers and add them to the exports object. |
486 for (const WasmExport& exp : export_table) { | 496 for (const WasmExport& exp : export_table) { |
487 if (thrower.error()) break; | 497 if (thrower.error()) break; |
488 const char* cstr = GetName(exp.name_offset); | 498 WasmName str = GetName(exp.name_offset, exp.name_length); |
489 Handle<String> name = factory->InternalizeUtf8String(cstr); | 499 Handle<String> name = factory->InternalizeUtf8String( |
| 500 Vector<const char>(str.name, str.length)); |
490 Handle<Code> code = linker.GetFunctionCode(exp.func_index); | 501 Handle<Code> code = linker.GetFunctionCode(exp.func_index); |
491 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( | 502 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( |
492 isolate, &module_env, name, code, instance.js_object, exp.func_index); | 503 isolate, &module_env, name, code, instance.js_object, exp.func_index); |
493 JSObject::AddProperty(exports_object, name, function, READ_ONLY); | 504 JSObject::AddProperty(exports_object, name, function, READ_ONLY); |
494 } | 505 } |
495 | 506 |
496 if (mem_export) { | 507 if (mem_export) { |
497 // Export the memory as a named property. | 508 // Export the memory as a named property. |
498 Handle<String> name = factory->InternalizeUtf8String("memory"); | 509 Handle<String> name = factory->InternalizeUtf8String("memory"); |
499 JSObject::AddProperty(exports_object, name, instance.mem_buffer, | 510 JSObject::AddProperty(exports_object, name, instance.mem_buffer, |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 658 } |
648 if (result->IsHeapNumber()) { | 659 if (result->IsHeapNumber()) { |
649 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 660 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
650 } | 661 } |
651 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 662 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
652 return -1; | 663 return -1; |
653 } | 664 } |
654 } // namespace wasm | 665 } // namespace wasm |
655 } // namespace internal | 666 } // namespace internal |
656 } // namespace v8 | 667 } // namespace v8 |
OLD | NEW |