Chromium Code Reviews| 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 module_end(nullptr), | 275 module_end(nullptr), |
| 276 min_mem_size_log2(0), | 276 min_mem_size_log2(0), |
| 277 max_mem_size_log2(0), | 277 max_mem_size_log2(0), |
| 278 mem_export(false), | 278 mem_export(false), |
| 279 mem_external(false), | 279 mem_external(false), |
| 280 start_function_index(-1), | 280 start_function_index(-1), |
| 281 globals(nullptr), | 281 globals(nullptr), |
| 282 signatures(nullptr), | 282 signatures(nullptr), |
| 283 functions(nullptr), | 283 functions(nullptr), |
| 284 data_segments(nullptr), | 284 data_segments(nullptr), |
| 285 function_table(nullptr) {} | 285 function_table(nullptr), |
| 286 import_table(nullptr) {} | |
| 286 | 287 |
| 287 WasmModule::~WasmModule() { | 288 WasmModule::~WasmModule() { |
| 288 if (globals) delete globals; | 289 if (globals) delete globals; |
| 289 if (signatures) delete signatures; | 290 if (signatures) delete signatures; |
| 290 if (functions) delete functions; | 291 if (functions) delete functions; |
| 291 if (data_segments) delete data_segments; | 292 if (data_segments) delete data_segments; |
| 292 if (function_table) delete function_table; | 293 if (function_table) delete function_table; |
| 294 if (import_table) delete import_table; | |
| 293 } | 295 } |
| 294 | 296 |
| 297 static MaybeHandle<JSFunction> LookupFunction(ErrorThrower& thrower, | |
| 298 Handle<JSObject> ffi, | |
| 299 uint32_t index, | |
| 300 Handle<String> name, | |
| 301 const char* cstr) { | |
| 302 if (!ffi.is_null()) { | |
| 303 MaybeHandle<Object> result = Object::GetProperty(ffi, name); | |
| 304 if (!result.is_null()) { | |
| 305 Handle<Object> obj = result.ToHandleChecked(); | |
| 306 if (obj->IsJSFunction()) { | |
| 307 return Handle<JSFunction>::cast(obj); | |
| 308 } else { | |
| 309 thrower.Error("FFI function #%d:%s is not a JSFunction.", index, cstr); | |
|
bradnelson
2016/02/19 06:43:57
This will fix things crashing if a proxy object is
titzer
2016/02/19 11:53:47
It's the same as the code before, just factored in
| |
| 310 return MaybeHandle<JSFunction>(); | |
| 311 } | |
| 312 } else { | |
| 313 thrower.Error("FFI function #%d:%s not found.", index, cstr); | |
| 314 return MaybeHandle<JSFunction>(); | |
| 315 } | |
| 316 } else { | |
| 317 thrower.Error("FFI table is not an object."); | |
| 318 return MaybeHandle<JSFunction>(); | |
| 319 } | |
| 320 } | |
| 295 | 321 |
| 296 // Instantiates a wasm module as a JSObject. | 322 // Instantiates a wasm module as a JSObject. |
| 297 // * allocates a backing store of {mem_size} bytes. | 323 // * allocates a backing store of {mem_size} bytes. |
| 298 // * installs a named property "memory" for that buffer if exported | 324 // * installs a named property "memory" for that buffer if exported |
| 299 // * installs named properties on the object for exported functions | 325 // * installs named properties on the object for exported functions |
| 300 // * compiles wasm code to machine code | 326 // * compiles wasm code to machine code |
| 301 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 327 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
| 302 Handle<JSObject> ffi, | 328 Handle<JSObject> ffi, |
| 303 Handle<JSArrayBuffer> memory) { | 329 Handle<JSArrayBuffer> memory) { |
| 304 this->shared_isolate = isolate; // TODO(titzer): have a real shared isolate. | 330 this->shared_isolate = isolate; // TODO(titzer): have a real shared isolate. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 //------------------------------------------------------------------------- | 370 //------------------------------------------------------------------------- |
| 345 if (!AllocateGlobals(&thrower, isolate, &instance)) { | 371 if (!AllocateGlobals(&thrower, isolate, &instance)) { |
| 346 return MaybeHandle<JSObject>(); | 372 return MaybeHandle<JSObject>(); |
| 347 } | 373 } |
| 348 if (!instance.globals_buffer.is_null()) { | 374 if (!instance.globals_buffer.is_null()) { |
| 349 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer, | 375 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer, |
| 350 *instance.globals_buffer); | 376 *instance.globals_buffer); |
| 351 } | 377 } |
| 352 | 378 |
| 353 //------------------------------------------------------------------------- | 379 //------------------------------------------------------------------------- |
| 354 // Compile all functions in the module. | 380 // Compile wrappers to imported functions. |
| 355 //------------------------------------------------------------------------- | 381 //------------------------------------------------------------------------- |
| 382 uint32_t index = 0; | |
| 356 instance.function_table = BuildFunctionTable(isolate, this); | 383 instance.function_table = BuildFunctionTable(isolate, this); |
| 357 uint32_t index = 0; | |
| 358 WasmLinker linker(isolate, functions->size()); | 384 WasmLinker linker(isolate, functions->size()); |
| 359 ModuleEnv module_env; | 385 ModuleEnv module_env; |
| 360 module_env.module = this; | 386 module_env.module = this; |
| 361 module_env.instance = &instance; | 387 module_env.instance = &instance; |
| 362 module_env.linker = &linker; | 388 module_env.linker = &linker; |
| 363 module_env.asm_js = false; | 389 module_env.asm_js = false; |
| 364 | 390 |
| 391 if (import_table->size() > 0) { | |
| 392 instance.import_code = new std::vector<Handle<Code>>(); | |
| 393 instance.import_code->reserve(import_table->size()); | |
| 394 for (const WasmImport& import : *import_table) { | |
| 395 const char* cstr = GetName(import.function_name_offset); | |
| 396 Handle<String> name = factory->InternalizeUtf8String(cstr); | |
| 397 MaybeHandle<JSFunction> function = | |
| 398 LookupFunction(thrower, ffi, index, name, cstr); | |
| 399 if (function.is_null()) return MaybeHandle<JSObject>(); | |
| 400 Handle<Code> code = compiler::CompileWasmToJSWrapper( | |
| 401 isolate, &module_env, function.ToHandleChecked(), import.sig, cstr); | |
| 402 instance.import_code->push_back(code); | |
| 403 index++; | |
| 404 } | |
| 405 } | |
| 406 | |
| 407 //------------------------------------------------------------------------- | |
| 408 // Compile all functions in the module. | |
| 409 //------------------------------------------------------------------------- | |
| 410 | |
| 365 // First pass: compile each function and initialize the code table. | 411 // First pass: compile each function and initialize the code table. |
| 412 index = 0; | |
| 366 for (const WasmFunction& func : *functions) { | 413 for (const WasmFunction& func : *functions) { |
| 367 if (thrower.error()) break; | 414 if (thrower.error()) break; |
| 368 DCHECK_EQ(index, func.func_index); | 415 DCHECK_EQ(index, func.func_index); |
| 369 | 416 |
| 370 const char* cstr = GetName(func.name_offset); | 417 const char* cstr = GetName(func.name_offset); |
| 371 Handle<String> name = factory->InternalizeUtf8String(cstr); | 418 Handle<String> name = factory->InternalizeUtf8String(cstr); |
| 372 Handle<Code> code = Handle<Code>::null(); | 419 Handle<Code> code = Handle<Code>::null(); |
| 373 Handle<JSFunction> function = Handle<JSFunction>::null(); | 420 Handle<JSFunction> function = Handle<JSFunction>::null(); |
| 374 if (func.external) { | 421 if (func.external) { |
| 375 // Lookup external function in FFI object. | 422 // Lookup external function in FFI object. |
| 376 if (!ffi.is_null()) { | 423 MaybeHandle<JSFunction> function = |
| 377 MaybeHandle<Object> result = Object::GetProperty(ffi, name); | 424 LookupFunction(thrower, ffi, index, name, cstr); |
| 378 if (!result.is_null()) { | 425 if (function.is_null()) return MaybeHandle<JSObject>(); |
| 379 Handle<Object> obj = result.ToHandleChecked(); | 426 code = compiler::CompileWasmToJSWrapper( |
| 380 if (obj->IsJSFunction()) { | 427 isolate, &module_env, function.ToHandleChecked(), func.sig, cstr); |
| 381 function = Handle<JSFunction>::cast(obj); | |
| 382 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | |
| 383 function, index); | |
| 384 } else { | |
| 385 thrower.Error("FFI function #%d:%s is not a JSFunction.", index, | |
| 386 cstr); | |
| 387 return MaybeHandle<JSObject>(); | |
| 388 } | |
| 389 } else { | |
| 390 thrower.Error("FFI function #%d:%s not found.", index, cstr); | |
| 391 return MaybeHandle<JSObject>(); | |
| 392 } | |
| 393 } else { | |
| 394 thrower.Error("FFI table is not an object."); | |
| 395 return MaybeHandle<JSObject>(); | |
| 396 } | |
| 397 } else { | 428 } else { |
| 398 // Compile the function. | 429 // Compile the function. |
| 399 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 430 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); |
| 400 if (code.is_null()) { | 431 if (code.is_null()) { |
| 401 thrower.Error("Compilation of #%d:%s failed.", index, cstr); | 432 thrower.Error("Compilation of #%d:%s failed.", index, cstr); |
| 402 return MaybeHandle<JSObject>(); | 433 return MaybeHandle<JSObject>(); |
| 403 } | 434 } |
| 404 if (func.exported) { | 435 if (func.exported) { |
| 405 function = compiler::CompileJSToWasmWrapper( | 436 function = compiler::CompileJSToWasmWrapper( |
| 406 isolate, &module_env, name, code, instance.js_object, index); | 437 isolate, &module_env, name, code, instance.js_object, index); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 | 478 |
| 448 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) { | 479 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) { |
| 449 DCHECK(IsValidFunction(index)); | 480 DCHECK(IsValidFunction(index)); |
| 450 if (linker) return linker->GetFunctionCode(index); | 481 if (linker) return linker->GetFunctionCode(index); |
| 451 if (instance && instance->function_code) { | 482 if (instance && instance->function_code) { |
| 452 return instance->function_code->at(index); | 483 return instance->function_code->at(index); |
| 453 } | 484 } |
| 454 return Handle<Code>::null(); | 485 return Handle<Code>::null(); |
| 455 } | 486 } |
| 456 | 487 |
| 488 Handle<Code> ModuleEnv::GetImportCode(uint32_t index) { | |
| 489 DCHECK(IsValidImport(index)); | |
| 490 if (instance && instance->import_code) { | |
| 491 return instance->import_code->at(index); | |
| 492 } | |
| 493 return Handle<Code>::null(); | |
| 494 } | |
| 457 | 495 |
| 458 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, | 496 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, |
| 459 uint32_t index) { | 497 uint32_t index) { |
| 460 DCHECK(IsValidFunction(index)); | 498 DCHECK(IsValidFunction(index)); |
| 461 // Always make a direct call to whatever is in the table at that location. | 499 // Always make a direct call to whatever is in the table at that location. |
| 462 // A wrapper will be generated for FFI calls. | 500 // A wrapper will be generated for FFI calls. |
| 463 WasmFunction* function = &module->functions->at(index); | 501 WasmFunction* function = &module->functions->at(index); |
| 464 return GetWasmCallDescriptor(zone, function->sig); | 502 return GetWasmCallDescriptor(zone, function->sig); |
| 465 } | 503 } |
| 466 | 504 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 } | 603 } |
| 566 if (result->IsHeapNumber()) { | 604 if (result->IsHeapNumber()) { |
| 567 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 605 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| 568 } | 606 } |
| 569 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 607 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
| 570 return -1; | 608 return -1; |
| 571 } | 609 } |
| 572 } // namespace wasm | 610 } // namespace wasm |
| 573 } // namespace internal | 611 } // namespace internal |
| 574 } // namespace v8 | 612 } // namespace v8 |
| OLD | NEW |