| 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 |