Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 1709653002: [wasm] Add support for import section. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: delete the import_code vector Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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);
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.
305 ErrorThrower thrower(isolate, "WasmModule::Instantiate()"); 331 ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
306 Factory* factory = isolate->factory(); 332 Factory* factory = isolate->factory();
307 333
308 //------------------------------------------------------------------------- 334 //-------------------------------------------------------------------------
309 // Allocate the instance and its JS counterpart. 335 // Allocate the instance and its JS counterpart.
310 //------------------------------------------------------------------------- 336 //-------------------------------------------------------------------------
311 Handle<Map> map = factory->NewMap( 337 Handle<Map> map = factory->NewMap(
312 JS_OBJECT_TYPE, 338 JS_OBJECT_TYPE,
313 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 339 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
314 WasmModuleInstance instance(this); 340 WasmModuleInstance instance(this);
341 std::vector<Handle<Code>> import_code;
315 instance.context = isolate->native_context(); 342 instance.context = isolate->native_context();
316 instance.js_object = factory->NewJSObjectFromMap(map, TENURED); 343 instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
317 Handle<FixedArray> code_table = 344 Handle<FixedArray> code_table =
318 factory->NewFixedArray(static_cast<int>(functions->size()), TENURED); 345 factory->NewFixedArray(static_cast<int>(functions->size()), TENURED);
319 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table); 346 instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
320 347
321 //------------------------------------------------------------------------- 348 //-------------------------------------------------------------------------
322 // Allocate and initialize the linear memory. 349 // Allocate and initialize the linear memory.
323 //------------------------------------------------------------------------- 350 //-------------------------------------------------------------------------
324 if (memory.is_null()) { 351 if (memory.is_null()) {
(...skipping 19 matching lines...) Expand all
344 //------------------------------------------------------------------------- 371 //-------------------------------------------------------------------------
345 if (!AllocateGlobals(&thrower, isolate, &instance)) { 372 if (!AllocateGlobals(&thrower, isolate, &instance)) {
346 return MaybeHandle<JSObject>(); 373 return MaybeHandle<JSObject>();
347 } 374 }
348 if (!instance.globals_buffer.is_null()) { 375 if (!instance.globals_buffer.is_null()) {
349 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer, 376 instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer,
350 *instance.globals_buffer); 377 *instance.globals_buffer);
351 } 378 }
352 379
353 //------------------------------------------------------------------------- 380 //-------------------------------------------------------------------------
354 // Compile all functions in the module. 381 // Compile wrappers to imported functions.
355 //------------------------------------------------------------------------- 382 //-------------------------------------------------------------------------
383 uint32_t index = 0;
356 instance.function_table = BuildFunctionTable(isolate, this); 384 instance.function_table = BuildFunctionTable(isolate, this);
357 uint32_t index = 0;
358 WasmLinker linker(isolate, functions->size()); 385 WasmLinker linker(isolate, functions->size());
359 ModuleEnv module_env; 386 ModuleEnv module_env;
360 module_env.module = this; 387 module_env.module = this;
361 module_env.instance = &instance; 388 module_env.instance = &instance;
362 module_env.linker = &linker; 389 module_env.linker = &linker;
363 module_env.asm_js = false; 390 module_env.asm_js = false;
364 391
392 if (import_table->size() > 0) {
393 instance.import_code = &import_code;
394 instance.import_code->reserve(import_table->size());
395 for (const WasmImport& import : *import_table) {
396 const char* cstr = GetName(import.function_name_offset);
397 Handle<String> name = factory->InternalizeUtf8String(cstr);
398 MaybeHandle<JSFunction> function =
399 LookupFunction(thrower, ffi, index, name, cstr);
400 if (function.is_null()) return MaybeHandle<JSObject>();
401 Handle<Code> code = compiler::CompileWasmToJSWrapper(
402 isolate, &module_env, function.ToHandleChecked(), import.sig, cstr);
403 instance.import_code->push_back(code);
404 index++;
405 }
406 }
407
408 //-------------------------------------------------------------------------
409 // Compile all functions in the module.
410 //-------------------------------------------------------------------------
411
365 // First pass: compile each function and initialize the code table. 412 // First pass: compile each function and initialize the code table.
413 index = 0;
366 for (const WasmFunction& func : *functions) { 414 for (const WasmFunction& func : *functions) {
367 if (thrower.error()) break; 415 if (thrower.error()) break;
368 DCHECK_EQ(index, func.func_index); 416 DCHECK_EQ(index, func.func_index);
369 417
370 const char* cstr = GetName(func.name_offset); 418 const char* cstr = GetName(func.name_offset);
371 Handle<String> name = factory->InternalizeUtf8String(cstr); 419 Handle<String> name = factory->InternalizeUtf8String(cstr);
372 Handle<Code> code = Handle<Code>::null(); 420 Handle<Code> code = Handle<Code>::null();
373 Handle<JSFunction> function = Handle<JSFunction>::null(); 421 Handle<JSFunction> function = Handle<JSFunction>::null();
374 if (func.external) { 422 if (func.external) {
375 // Lookup external function in FFI object. 423 // Lookup external function in FFI object.
376 if (!ffi.is_null()) { 424 MaybeHandle<JSFunction> function =
377 MaybeHandle<Object> result = Object::GetProperty(ffi, name); 425 LookupFunction(thrower, ffi, index, name, cstr);
378 if (!result.is_null()) { 426 if (function.is_null()) return MaybeHandle<JSObject>();
379 Handle<Object> obj = result.ToHandleChecked(); 427 code = compiler::CompileWasmToJSWrapper(
380 if (obj->IsJSFunction()) { 428 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 { 429 } else {
398 // Compile the function. 430 // Compile the function.
399 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func); 431 code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
400 if (code.is_null()) { 432 if (code.is_null()) {
401 thrower.Error("Compilation of #%d:%s failed.", index, cstr); 433 thrower.Error("Compilation of #%d:%s failed.", index, cstr);
402 return MaybeHandle<JSObject>(); 434 return MaybeHandle<JSObject>();
403 } 435 }
404 if (func.exported) { 436 if (func.exported) {
405 function = compiler::CompileJSToWasmWrapper( 437 function = compiler::CompileJSToWasmWrapper(
406 isolate, &module_env, name, code, instance.js_object, index); 438 isolate, &module_env, name, code, instance.js_object, index);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 479
448 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) { 480 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) {
449 DCHECK(IsValidFunction(index)); 481 DCHECK(IsValidFunction(index));
450 if (linker) return linker->GetFunctionCode(index); 482 if (linker) return linker->GetFunctionCode(index);
451 if (instance && instance->function_code) { 483 if (instance && instance->function_code) {
452 return instance->function_code->at(index); 484 return instance->function_code->at(index);
453 } 485 }
454 return Handle<Code>::null(); 486 return Handle<Code>::null();
455 } 487 }
456 488
489 Handle<Code> ModuleEnv::GetImportCode(uint32_t index) {
490 DCHECK(IsValidImport(index));
491 if (instance && instance->import_code) {
492 return instance->import_code->at(index);
493 }
494 return Handle<Code>::null();
495 }
457 496
458 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, 497 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone,
459 uint32_t index) { 498 uint32_t index) {
460 DCHECK(IsValidFunction(index)); 499 DCHECK(IsValidFunction(index));
461 // Always make a direct call to whatever is in the table at that location. 500 // Always make a direct call to whatever is in the table at that location.
462 // A wrapper will be generated for FFI calls. 501 // A wrapper will be generated for FFI calls.
463 WasmFunction* function = &module->functions->at(index); 502 WasmFunction* function = &module->functions->at(index);
464 return GetWasmCallDescriptor(zone, function->sig); 503 return GetWasmCallDescriptor(zone, function->sig);
465 } 504 }
466 505
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 604 }
566 if (result->IsHeapNumber()) { 605 if (result->IsHeapNumber()) {
567 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); 606 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
568 } 607 }
569 thrower.Error("WASM.compileRun() failed: Return value should be number"); 608 thrower.Error("WASM.compileRun() failed: Return value should be number");
570 return -1; 609 return -1;
571 } 610 }
572 } // namespace wasm 611 } // namespace wasm
573 } // namespace internal 612 } // namespace internal
574 } // namespace v8 613 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698