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 |