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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 : shared_isolate(nullptr), | 271 : shared_isolate(nullptr), |
272 module_start(nullptr), | 272 module_start(nullptr), |
273 module_end(nullptr), | 273 module_end(nullptr), |
274 min_mem_pages(0), | 274 min_mem_pages(0), |
275 max_mem_pages(0), | 275 max_mem_pages(0), |
276 mem_export(false), | 276 mem_export(false), |
277 mem_external(false), | 277 mem_external(false), |
278 start_function_index(-1), | 278 start_function_index(-1), |
279 origin(kWasmOrigin) {} | 279 origin(kWasmOrigin) {} |
280 | 280 |
281 static MaybeHandle<JSFunction> LookupFunction(ErrorThrower& thrower, | 281 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, |
282 Handle<JSObject> ffi, | 282 const char* error, uint32_t index, |
283 uint32_t index, | 283 const char* module_cstr, |
284 Handle<String> name, | 284 const char* function_cstr) { |
285 const char* cstr) { | 285 if (function_cstr) { |
286 if (!ffi.is_null()) { | 286 thrower.Error("Import #%d module=\"%s\" function=\"%s\" error: %s", index, |
287 MaybeHandle<Object> result = Object::GetProperty(ffi, name); | 287 module_cstr, function_cstr, error); |
288 if (!result.is_null()) { | 288 } else { |
289 Handle<Object> obj = result.ToHandleChecked(); | 289 thrower.Error("Import #%d module=\"%s\" error: %s", index, module_cstr, |
290 if (obj->IsJSFunction()) { | 290 error); |
291 return Handle<JSFunction>::cast(obj); | 291 } |
292 } else { | 292 thrower.Error("Import "); |
293 thrower.Error("FFI function #%d:%s is not a JSFunction.", index, cstr); | 293 return MaybeHandle<JSFunction>(); |
294 return MaybeHandle<JSFunction>(); | 294 } |
295 } | 295 |
296 } else { | 296 static MaybeHandle<JSFunction> LookupFunction( |
297 thrower.Error("FFI function #%d:%s not found.", index, cstr); | 297 ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi, |
298 return MaybeHandle<JSFunction>(); | 298 uint32_t index, const char* module_cstr, const char* function_cstr) { |
| 299 if (ffi.is_null()) { |
| 300 return ReportFFIError(thrower, "FFI is not an object", index, module_cstr, |
| 301 function_cstr); |
| 302 } |
| 303 |
| 304 // Look up the module first. |
| 305 Handle<String> name = factory->InternalizeUtf8String(module_cstr); |
| 306 MaybeHandle<Object> result = Object::GetProperty(ffi, name); |
| 307 if (result.is_null()) { |
| 308 return ReportFFIError(thrower, "module not found", index, module_cstr, |
| 309 function_cstr); |
| 310 } |
| 311 |
| 312 Handle<Object> module = result.ToHandleChecked(); |
| 313 |
| 314 if (!module->IsJSReceiver()) { |
| 315 return ReportFFIError(thrower, "module is not an object or function", index, |
| 316 module_cstr, function_cstr); |
| 317 } |
| 318 |
| 319 Handle<Object> function; |
| 320 if (function_cstr) { |
| 321 // Look up the function in the module. |
| 322 Handle<String> name = factory->InternalizeUtf8String(function_cstr); |
| 323 MaybeHandle<Object> result = Object::GetProperty(module, name); |
| 324 if (result.is_null()) { |
| 325 return ReportFFIError(thrower, "function not found", index, module_cstr, |
| 326 function_cstr); |
299 } | 327 } |
| 328 function = result.ToHandleChecked(); |
300 } else { | 329 } else { |
301 thrower.Error("FFI table is not an object."); | 330 // No function specified. Use the "default export". |
302 return MaybeHandle<JSFunction>(); | 331 function = module; |
303 } | 332 } |
| 333 |
| 334 if (!function->IsJSFunction()) { |
| 335 return ReportFFIError(thrower, "not a function", index, module_cstr, |
| 336 function_cstr); |
| 337 } |
| 338 |
| 339 return Handle<JSFunction>::cast(function); |
304 } | 340 } |
305 | 341 |
306 // Instantiates a wasm module as a JSObject. | 342 // Instantiates a wasm module as a JSObject. |
307 // * allocates a backing store of {mem_size} bytes. | 343 // * allocates a backing store of {mem_size} bytes. |
308 // * installs a named property "memory" for that buffer if exported | 344 // * installs a named property "memory" for that buffer if exported |
309 // * installs named properties on the object for exported functions | 345 // * installs named properties on the object for exported functions |
310 // * compiles wasm code to machine code | 346 // * compiles wasm code to machine code |
311 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 347 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
312 Handle<JSObject> ffi, | 348 Handle<JSObject> ffi, |
313 Handle<JSArrayBuffer> memory) { | 349 Handle<JSArrayBuffer> memory) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 WasmLinker linker(isolate, functions.size()); | 404 WasmLinker linker(isolate, functions.size()); |
369 ModuleEnv module_env; | 405 ModuleEnv module_env; |
370 module_env.module = this; | 406 module_env.module = this; |
371 module_env.instance = &instance; | 407 module_env.instance = &instance; |
372 module_env.linker = &linker; | 408 module_env.linker = &linker; |
373 module_env.origin = origin; | 409 module_env.origin = origin; |
374 | 410 |
375 if (import_table.size() > 0) { | 411 if (import_table.size() > 0) { |
376 instance.import_code.reserve(import_table.size()); | 412 instance.import_code.reserve(import_table.size()); |
377 for (const WasmImport& import : import_table) { | 413 for (const WasmImport& import : import_table) { |
378 const char* cstr = GetName(import.function_name_offset); | 414 const char* module_cstr = GetNameOrNull(import.module_name_offset); |
379 Handle<String> name = factory->InternalizeUtf8String(cstr); | 415 const char* function_cstr = GetNameOrNull(import.function_name_offset); |
380 MaybeHandle<JSFunction> function = | 416 MaybeHandle<JSFunction> function = LookupFunction( |
381 LookupFunction(thrower, ffi, index, name, cstr); | 417 thrower, factory, ffi, index, module_cstr, function_cstr); |
382 if (function.is_null()) return MaybeHandle<JSObject>(); | 418 if (function.is_null()) return MaybeHandle<JSObject>(); |
383 Handle<Code> code = compiler::CompileWasmToJSWrapper( | 419 Handle<Code> code = compiler::CompileWasmToJSWrapper( |
384 isolate, &module_env, function.ToHandleChecked(), import.sig, cstr); | 420 isolate, &module_env, function.ToHandleChecked(), import.sig, |
| 421 module_cstr, function_cstr); |
385 instance.import_code.push_back(code); | 422 instance.import_code.push_back(code); |
386 index++; | 423 index++; |
387 } | 424 } |
388 } | 425 } |
389 | 426 |
390 //------------------------------------------------------------------------- | 427 //------------------------------------------------------------------------- |
391 // Compile all functions in the module. | 428 // Compile all functions in the module. |
392 //------------------------------------------------------------------------- | 429 //------------------------------------------------------------------------- |
393 | 430 |
394 // First pass: compile each function and initialize the code table. | 431 // First pass: compile each function and initialize the code table. |
395 index = 0; | 432 index = 0; |
396 for (const WasmFunction& func : functions) { | 433 for (const WasmFunction& func : functions) { |
397 if (thrower.error()) break; | 434 if (thrower.error()) break; |
398 DCHECK_EQ(index, func.func_index); | 435 DCHECK_EQ(index, func.func_index); |
399 | 436 |
400 const char* cstr = GetName(func.name_offset); | 437 const char* cstr = GetName(func.name_offset); |
401 Handle<String> name = factory->InternalizeUtf8String(cstr); | 438 Handle<String> name = factory->InternalizeUtf8String(cstr); |
402 Handle<Code> code = Handle<Code>::null(); | 439 Handle<Code> code = Handle<Code>::null(); |
403 Handle<JSFunction> function = Handle<JSFunction>::null(); | 440 Handle<JSFunction> function = Handle<JSFunction>::null(); |
404 if (func.external) { | 441 if (func.external) { |
405 // Lookup external function in FFI object. | 442 // Lookup external function in FFI object. |
406 MaybeHandle<JSFunction> function = | 443 MaybeHandle<JSFunction> function = |
407 LookupFunction(thrower, ffi, index, name, cstr); | 444 LookupFunction(thrower, factory, ffi, index, cstr, nullptr); |
408 if (function.is_null()) return MaybeHandle<JSObject>(); | 445 if (function.is_null()) return MaybeHandle<JSObject>(); |
409 code = compiler::CompileWasmToJSWrapper( | 446 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, |
410 isolate, &module_env, function.ToHandleChecked(), func.sig, cstr); | 447 function.ToHandleChecked(), |
| 448 func.sig, cstr, nullptr); |
411 } else { | 449 } else { |
412 // Compile the function. | 450 // Compile the function. |
413 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 451 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); |
414 if (code.is_null()) { | 452 if (code.is_null()) { |
415 thrower.Error("Compilation of #%d:%s failed.", index, cstr); | 453 thrower.Error("Compilation of #%d:%s failed.", index, cstr); |
416 return MaybeHandle<JSObject>(); | 454 return MaybeHandle<JSObject>(); |
417 } | 455 } |
418 if (func.exported) { | 456 if (func.exported) { |
419 function = compiler::CompileJSToWasmWrapper( | 457 function = compiler::CompileJSToWasmWrapper( |
420 isolate, &module_env, name, code, instance.js_object, index); | 458 isolate, &module_env, name, code, instance.js_object, index); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 } | 647 } |
610 if (result->IsHeapNumber()) { | 648 if (result->IsHeapNumber()) { |
611 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 649 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
612 } | 650 } |
613 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 651 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
614 return -1; | 652 return -1; |
615 } | 653 } |
616 } // namespace wasm | 654 } // namespace wasm |
617 } // namespace internal | 655 } // namespace internal |
618 } // namespace v8 | 656 } // namespace v8 |
OLD | NEW |