[wasm] Support importing anyref tables
R=clemensh@chromium.org Bug: v8:7581 Change-Id: I6b20698e556ed3808f8b190f88cb700301825b54 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1588432 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#61129}
This commit is contained in:
parent
a30fd9ea92
commit
e24e5710ec
@ -140,6 +140,11 @@ class InstanceBuilder {
|
||||
Handle<String> import_name,
|
||||
Handle<Object> value);
|
||||
|
||||
// Initialize imported tables of type anyfunc.
|
||||
bool InitializeImportedIndirectFunctionTable(
|
||||
Handle<WasmInstanceObject> instance, int import_index,
|
||||
Handle<WasmTableObject> table_object);
|
||||
|
||||
// Process a single imported table.
|
||||
bool ProcessImportedTable(Handle<WasmInstanceObject> instance,
|
||||
int import_index, int table_index,
|
||||
@ -808,6 +813,49 @@ bool InstanceBuilder::ProcessImportedFunction(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstanceBuilder::InitializeImportedIndirectFunctionTable(
|
||||
Handle<WasmInstanceObject> instance, int import_index,
|
||||
Handle<WasmTableObject> table_object) {
|
||||
int imported_table_size = table_object->elements().length();
|
||||
// Allocate a new dispatch table.
|
||||
if (!instance->has_indirect_function_table()) {
|
||||
WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
|
||||
instance, imported_table_size);
|
||||
}
|
||||
// Initialize the dispatch table with the (foreign) JS functions
|
||||
// that are already in the table.
|
||||
for (int i = 0; i < imported_table_size; ++i) {
|
||||
bool is_valid;
|
||||
bool is_null;
|
||||
MaybeHandle<WasmInstanceObject> maybe_target_instance;
|
||||
int function_index;
|
||||
WasmTableObject::GetFunctionTableEntry(isolate_, table_object, i, &is_valid,
|
||||
&is_null, &maybe_target_instance,
|
||||
&function_index);
|
||||
if (!is_valid) {
|
||||
thrower_->LinkError("table import %d[%d] is not a wasm function",
|
||||
import_index, i);
|
||||
return false;
|
||||
}
|
||||
if (is_null) continue;
|
||||
|
||||
Handle<WasmInstanceObject> target_instance =
|
||||
maybe_target_instance.ToHandleChecked();
|
||||
FunctionSig* sig = target_instance->module_object()
|
||||
->module()
|
||||
->functions[function_index]
|
||||
.sig;
|
||||
|
||||
// Look up the signature's canonical id. If there is no canonical
|
||||
// id, then the signature does not appear at all in this module,
|
||||
// so putting {-1} in the table will cause checks to always fail.
|
||||
IndirectFunctionTableEntry(instance, i)
|
||||
.Set(module_->signature_map.Find(*sig), target_instance,
|
||||
function_index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstanceBuilder::ProcessImportedTable(Handle<WasmInstanceObject> instance,
|
||||
int import_index, int table_index,
|
||||
Handle<String> module_name,
|
||||
@ -851,42 +899,17 @@ bool InstanceBuilder::ProcessImportedTable(Handle<WasmInstanceObject> instance,
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate a new dispatch table.
|
||||
if (!instance->has_indirect_function_table()) {
|
||||
WasmInstanceObject::EnsureIndirectFunctionTableWithMinimumSize(
|
||||
instance, imported_table_size);
|
||||
if (table.type != table_object->type()) {
|
||||
ReportLinkError("imported table does not match the expected type",
|
||||
import_index, module_name, import_name);
|
||||
return false;
|
||||
}
|
||||
// Initialize the dispatch table with the (foreign) JS functions
|
||||
// that are already in the table.
|
||||
for (int i = 0; i < imported_table_size; ++i) {
|
||||
bool is_valid;
|
||||
bool is_null;
|
||||
MaybeHandle<WasmInstanceObject> maybe_target_instance;
|
||||
int function_index;
|
||||
WasmTableObject::GetFunctionTableEntry(isolate_, table_object, i, &is_valid,
|
||||
&is_null, &maybe_target_instance,
|
||||
&function_index);
|
||||
if (!is_valid) {
|
||||
thrower_->LinkError("table import %d[%d] is not a wasm function",
|
||||
import_index, i);
|
||||
return false;
|
||||
}
|
||||
if (is_null) continue;
|
||||
|
||||
Handle<WasmInstanceObject> target_instance =
|
||||
maybe_target_instance.ToHandleChecked();
|
||||
FunctionSig* sig = target_instance->module_object()
|
||||
->module()
|
||||
->functions[function_index]
|
||||
.sig;
|
||||
|
||||
// Look up the signature's canonical id. If there is no canonical
|
||||
// id, then the signature does not appear at all in this module,
|
||||
// so putting {-1} in the table will cause checks to always fail.
|
||||
IndirectFunctionTableEntry(instance, i)
|
||||
.Set(module_->signature_map.Find(*sig), target_instance,
|
||||
function_index);
|
||||
if (table.type == kWasmAnyFunc && !InitializeImportedIndirectFunctionTable(
|
||||
instance, import_index, table_object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -29,3 +29,19 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
assertThrows(() => table.set(12), RangeError);
|
||||
})();
|
||||
|
||||
(function TestImportAnyRefTable() {
|
||||
print(arguments.callee.name);
|
||||
|
||||
const builder = new WasmModuleBuilder();
|
||||
const table_index = builder.addImportedTable("imp", "table", 3, 10, kWasmAnyRef);
|
||||
builder.addFunction('get', kSig_r_v)
|
||||
.addBody([kExprI32Const, 0, kExprGetTable, table_index]);
|
||||
|
||||
let table_ref = new WebAssembly.Table({element: "anyref", initial: 3, maximum: 10});
|
||||
builder.instantiate({imp:{table: table_ref}});
|
||||
|
||||
let table_func = new WebAssembly.Table({ element: "anyfunc", initial: 3, maximum: 10 });
|
||||
assertThrows(() => builder.instantiate({ imp: { table: table_func } }),
|
||||
WebAssembly.LinkError, /imported table does not match the expected type/);
|
||||
})();
|
||||
|
@ -843,12 +843,12 @@ class WasmModuleBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
addImportedTable(module, name, initial, maximum) {
|
||||
addImportedTable(module, name, initial, maximum, type) {
|
||||
if (this.tables.length != 0) {
|
||||
throw new Error('Imported tables must be declared before local ones');
|
||||
}
|
||||
let o = {module: module, name: name, kind: kExternalTable, initial: initial,
|
||||
maximum: maximum};
|
||||
maximum: maximum, type: type || kWasmAnyFunctionTypeForm};
|
||||
this.imports.push(o);
|
||||
return this.num_imported_tables++;
|
||||
}
|
||||
@ -999,7 +999,7 @@ class WasmModuleBuilder {
|
||||
section.emit_u32v(imp.initial); // initial
|
||||
if (has_max) section.emit_u32v(imp.maximum); // maximum
|
||||
} else if (imp.kind == kExternalTable) {
|
||||
section.emit_u8(kWasmAnyFunctionTypeForm);
|
||||
section.emit_u8(imp.type);
|
||||
var has_max = (typeof imp.maximum) != "undefined";
|
||||
section.emit_u8(has_max ? 1 : 0); // flags
|
||||
section.emit_u32v(imp.initial); // initial
|
||||
|
Loading…
Reference in New Issue
Block a user