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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 WasmLinker linker(isolate, functions.size()); | 409 WasmLinker linker(isolate, functions.size()); |
405 ModuleEnv module_env; | 410 ModuleEnv module_env; |
406 module_env.module = this; | 411 module_env.module = this; |
407 module_env.instance = &instance; | 412 module_env.instance = &instance; |
408 module_env.linker = &linker; | 413 module_env.linker = &linker; |
409 module_env.origin = origin; | 414 module_env.origin = origin; |
410 | 415 |
411 if (import_table.size() > 0) { | 416 if (import_table.size() > 0) { |
412 instance.import_code.reserve(import_table.size()); | 417 instance.import_code.reserve(import_table.size()); |
413 for (const WasmImport& import : import_table) { | 418 for (const WasmImport& import : import_table) { |
414 const char* module_cstr = GetNameOrNull(import.module_name_offset); | 419 WasmName module_name = |
415 const char* function_cstr = GetNameOrNull(import.function_name_offset); | 420 GetNameOrNull(import.module_name_offset, import.module_name_length); |
| 421 WasmName function_name = GetNameOrNull(import.function_name_offset, |
| 422 import.function_name_length); |
416 MaybeHandle<JSFunction> function = LookupFunction( | 423 MaybeHandle<JSFunction> function = LookupFunction( |
417 thrower, factory, ffi, index, module_cstr, function_cstr); | 424 thrower, factory, ffi, index, module_name, function_name); |
418 if (function.is_null()) return MaybeHandle<JSObject>(); | 425 if (function.is_null()) return MaybeHandle<JSObject>(); |
419 Handle<Code> code = compiler::CompileWasmToJSWrapper( | 426 Handle<Code> code = compiler::CompileWasmToJSWrapper( |
420 isolate, &module_env, function.ToHandleChecked(), import.sig, | 427 isolate, &module_env, function.ToHandleChecked(), import.sig, |
421 module_cstr, function_cstr); | 428 module_name, function_name); |
422 instance.import_code.push_back(code); | 429 instance.import_code.push_back(code); |
423 index++; | 430 index++; |
424 } | 431 } |
425 } | 432 } |
426 | 433 |
427 //------------------------------------------------------------------------- | 434 //------------------------------------------------------------------------- |
428 // Compile all functions in the module. | 435 // Compile all functions in the module. |
429 //------------------------------------------------------------------------- | 436 //------------------------------------------------------------------------- |
430 | 437 |
431 // First pass: compile each function and initialize the code table. | 438 // First pass: compile each function and initialize the code table. |
432 index = 0; | 439 index = 0; |
433 for (const WasmFunction& func : functions) { | 440 for (const WasmFunction& func : functions) { |
434 if (thrower.error()) break; | 441 if (thrower.error()) break; |
435 DCHECK_EQ(index, func.func_index); | 442 DCHECK_EQ(index, func.func_index); |
436 | 443 |
437 const char* cstr = GetName(func.name_offset); | 444 WasmName str = GetName(func.name_offset, func.name_length); |
438 Handle<String> name = factory->InternalizeUtf8String(cstr); | 445 WasmName str_null = {nullptr, 0}; |
| 446 Handle<String> name = factory->InternalizeUtf8String( |
| 447 Vector<const char>(str.name, str.length)); |
439 Handle<Code> code = Handle<Code>::null(); | 448 Handle<Code> code = Handle<Code>::null(); |
440 Handle<JSFunction> function = Handle<JSFunction>::null(); | 449 Handle<JSFunction> function = Handle<JSFunction>::null(); |
441 if (func.external) { | 450 if (func.external) { |
442 // Lookup external function in FFI object. | 451 // Lookup external function in FFI object. |
443 MaybeHandle<JSFunction> function = | 452 MaybeHandle<JSFunction> function = |
444 LookupFunction(thrower, factory, ffi, index, cstr, nullptr); | 453 LookupFunction(thrower, factory, ffi, index, str, str_null); |
445 if (function.is_null()) return MaybeHandle<JSObject>(); | 454 if (function.is_null()) return MaybeHandle<JSObject>(); |
446 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | 455 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, |
447 function.ToHandleChecked(), | 456 function.ToHandleChecked(), |
448 func.sig, cstr, nullptr); | 457 func.sig, str, str_null); |
449 } else { | 458 } else { |
450 // Compile the function. | 459 // Compile the function. |
451 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 460 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); |
452 if (code.is_null()) { | 461 if (code.is_null()) { |
453 thrower.Error("Compilation of #%d:%s failed.", index, cstr); | 462 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length, |
| 463 str.name); |
454 return MaybeHandle<JSObject>(); | 464 return MaybeHandle<JSObject>(); |
455 } | 465 } |
456 if (func.exported) { | 466 if (func.exported) { |
457 function = compiler::CompileJSToWasmWrapper( | 467 function = compiler::CompileJSToWasmWrapper( |
458 isolate, &module_env, name, code, instance.js_object, index); | 468 isolate, &module_env, name, code, instance.js_object, index); |
459 } | 469 } |
460 } | 470 } |
461 if (!code.is_null()) { | 471 if (!code.is_null()) { |
462 // Install the code into the linker table. | 472 // Install the code into the linker table. |
463 linker.Finish(index, code); | 473 linker.Finish(index, code); |
(...skipping 21 matching lines...) Expand all Loading... |
485 isolate->native_context()->object_function(), isolate); | 495 isolate->native_context()->object_function(), isolate); |
486 Handle<JSObject> exports_object = | 496 Handle<JSObject> exports_object = |
487 factory->NewJSObject(object_function, TENURED); | 497 factory->NewJSObject(object_function, TENURED); |
488 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 498 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
489 JSObject::AddProperty(instance.js_object, exports_name, exports_object, | 499 JSObject::AddProperty(instance.js_object, exports_name, exports_object, |
490 READ_ONLY); | 500 READ_ONLY); |
491 | 501 |
492 // Compile wrappers and add them to the exports object. | 502 // Compile wrappers and add them to the exports object. |
493 for (const WasmExport& exp : export_table) { | 503 for (const WasmExport& exp : export_table) { |
494 if (thrower.error()) break; | 504 if (thrower.error()) break; |
495 const char* cstr = GetName(exp.name_offset); | 505 WasmName str = GetName(exp.name_offset, exp.name_length); |
496 Handle<String> name = factory->InternalizeUtf8String(cstr); | 506 Handle<String> name = factory->InternalizeUtf8String( |
| 507 Vector<const char>(str.name, str.length)); |
497 Handle<Code> code = linker.GetFunctionCode(exp.func_index); | 508 Handle<Code> code = linker.GetFunctionCode(exp.func_index); |
498 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( | 509 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( |
499 isolate, &module_env, name, code, instance.js_object, exp.func_index); | 510 isolate, &module_env, name, code, instance.js_object, exp.func_index); |
500 JSObject::AddProperty(exports_object, name, function, READ_ONLY); | 511 JSObject::AddProperty(exports_object, name, function, READ_ONLY); |
501 } | 512 } |
502 } | 513 } |
503 | 514 |
504 // Run the start function if one was specified. | 515 // Run the start function if one was specified. |
505 if (this->start_function_index >= 0) { | 516 if (this->start_function_index >= 0) { |
506 HandleScope scope(isolate); | 517 HandleScope scope(isolate); |
(...skipping 140 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 |