Commit d5a0860e authored by titzer's avatar titzer Committed by Commit bot

[wasm] Implement the WebAssembly.Module.imports function.

R=rossberg@chromium.org
BUG=v8:5813,chromium:575167

Review-Url: https://codereview.chromium.org/2620203005
Cr-Commit-Position: refs/heads/master@{#42231}
parent b16febbc
......@@ -232,6 +232,36 @@ MaybeLocal<Value> InstantiateModuleImpl(
return Utils::ToLocal(instance.ToHandleChecked());
}
void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
if (args.Length() < 1) {
thrower.TypeError("Argument 0 must be a WebAssembly.Module");
return;
}
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]),
i::Handle<i::Symbol>(i_context->wasm_module_sym()),
"Argument 0 must be a WebAssembly.Module")) {
return;
}
Local<Object> module_obj = Local<Object>::Cast(args[0]);
i::Handle<i::WasmModuleObject> i_module_obj =
i::Handle<i::WasmModuleObject>::cast(v8::Utils::OpenHandle(*module_obj));
i::Handle<i::JSArray> imports = i::wasm::GetImports(i_isolate, i_module_obj);
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(Utils::ToLocal(imports));
}
void WebAssemblyInstanceCtor(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate();
......@@ -721,6 +751,8 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
JSFunction::SetInitialMap(module_constructor, map, module_proto);
JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(),
module_constructor, DONT_ENUM);
InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports,
1);
// Setup Instance
Handle<JSFunction> instance_constructor =
......
......@@ -2330,3 +2330,75 @@ void testing::ValidateOrphanedInstance(Isolate* isolate,
CHECK(compiled_module->has_weak_wasm_module());
CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
}
Handle<JSArray> wasm::GetImports(Isolate* isolate,
Handle<WasmModuleObject> module_object) {
Handle<WasmCompiledModule> compiled_module(module_object->compiled_module(),
isolate);
Factory* factory = isolate->factory();
Handle<String> module_string = factory->InternalizeUtf8String("module");
Handle<String> name_string = factory->InternalizeUtf8String("name");
Handle<String> kind_string = factory->InternalizeUtf8String("kind");
Handle<String> function_string = factory->InternalizeUtf8String("function");
Handle<String> table_string = factory->InternalizeUtf8String("table");
Handle<String> memory_string = factory->InternalizeUtf8String("memory");
Handle<String> global_string = factory->InternalizeUtf8String("global");
// Create the result array.
WasmModule* module = compiled_module->module();
int num_imports = static_cast<int>(module->import_table.size());
Handle<JSArray> array_object = factory->NewJSArray(FAST_ELEMENTS, 0, 0);
Handle<FixedArray> storage = factory->NewFixedArray(num_imports);
JSArray::SetContent(array_object, storage);
array_object->set_length(Smi::FromInt(num_imports));
Handle<JSFunction> object_function =
Handle<JSFunction>(isolate->native_context()->object_function(), isolate);
// Populate the result array.
for (int index = 0; index < num_imports; ++index) {
WasmImport& import = module->import_table[index];
Handle<JSObject> entry = factory->NewJSObject(object_function, TENURED);
Handle<String> import_kind;
switch (import.kind) {
case kExternalFunction:
import_kind = function_string;
break;
case kExternalTable:
import_kind = table_string;
break;
case kExternalMemory:
import_kind = memory_string;
break;
case kExternalGlobal:
import_kind = global_string;
break;
default:
UNREACHABLE();
}
MaybeHandle<String> import_module =
WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
isolate, compiled_module, import.module_name_offset,
import.module_name_length);
MaybeHandle<String> import_name =
WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
isolate, compiled_module, import.field_name_offset,
import.field_name_length);
JSObject::AddProperty(entry, module_string, import_module.ToHandleChecked(),
NONE);
JSObject::AddProperty(entry, name_string, import_name.ToHandleChecked(),
NONE);
JSObject::AddProperty(entry, kind_string, import_kind, NONE);
storage->set(index, *entry);
}
return array_object;
}
......@@ -396,6 +396,9 @@ V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes(
ModuleOrigin origin, Handle<Script> asm_js_script,
Vector<const byte> asm_offset_table);
V8_EXPORT_PRIVATE Handle<JSArray> GetImports(Isolate* isolate,
Handle<WasmModuleObject> module);
V8_EXPORT_PRIVATE bool ValidateModuleBytes(Isolate* isolate, const byte* start,
const byte* end,
ErrorThrower* thrower,
......
......@@ -153,7 +153,6 @@ assertEq(typeof emptyModule, "object");
//TODO assertEq(String(emptyModule), "[object WebAssembly.Module]");
assertEq(Object.getPrototypeOf(emptyModule), moduleProto);
if (false) { // TODO: Module.imports support
// 'WebAssembly.Module.imports' data property
let moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports');
assertEq(typeof moduleImportsDesc.value, "function");
......@@ -167,10 +166,19 @@ assertEq(moduleImports.length, 1);
assertErrorMessage(() => moduleImports(), TypeError, /requires more than 0 arguments/);
assertErrorMessage(() => moduleImports(undefined), TypeError, /first argument must be a WebAssembly.Module/);
assertErrorMessage(() => moduleImports({}), TypeError, /first argument must be a WebAssembly.Module/);
var arr = moduleImports(new Module(wasmTextToBinary('(module)')));
var arr = moduleImports(new Module(emptyModuleBinary));
assertEq(arr instanceof Array, true);
assertEq(arr.length, 0);
var arr = moduleImports(new Module(wasmTextToBinary('(module (func (import "a" "b")) (memory (import "c" "d") 1) (table (import "e" "f") 1 anyfunc) (global (import "g" "⚡") i32))')));
let importingModuleBinary2 = (() => {
var text = '(module (func (import "a" "b")) (memory (import "c" "d") 1) (table (import "e" "f") 1 anyfunc) (global (import "g" "⚡") i32))'
let builder = new WasmModuleBuilder();
builder.addImport("a", "b", kSig_i_i);
builder.addImportedMemory("c", "d");
builder.addImportedTable("e", "f");
builder.addImportedGlobal("g", "x", kWasmI32);
return new Int8Array(builder.toBuffer());
})();
var arr = moduleImports(new Module(importingModuleBinary2));
assertEq(arr instanceof Array, true);
assertEq(arr.length, 4);
assertEq(arr[0].kind, "function");
......@@ -184,8 +192,7 @@ assertEq(arr[2].module, "e");
assertEq(arr[2].name, "f");
assertEq(arr[3].kind, "global");
assertEq(arr[3].module, "g");
assertEq(arr[3].name, "⚡");
}
assertEq(arr[3].name, "x");
if (false) { // TODO: Module.exports property
// 'WebAssembly.Module.exports' data property
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment