[wasm] Support tables with exnref type entries.
This extends existing table support to be able to store 'exnref' in addition to 'anyref' types. Tools can use this to maintain data structures for exception packages. R=ahaas@chromium.org TEST=mjsunit/wasm/exceptions-anyref BUG=v8:8091 Change-Id: Iccbcfdc328db81a366921bcdd98c2256f66e7fc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781046 Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#64323}
This commit is contained in:
parent
c2e95a362a
commit
5fbeb5c5bd
@ -3489,7 +3489,8 @@ void WasmGraphBuilder::GetTableBaseAndOffset(uint32_t table_index,
|
||||
|
||||
Node* WasmGraphBuilder::TableGet(uint32_t table_index, Node* index,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef) {
|
||||
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef ||
|
||||
env_->module->tables[table_index].type == wasm::kWasmExnRef) {
|
||||
Node* base = nullptr;
|
||||
Node* offset = nullptr;
|
||||
GetTableBaseAndOffset(table_index, index, position, &base, &offset);
|
||||
@ -3518,7 +3519,8 @@ Node* WasmGraphBuilder::TableGet(uint32_t table_index, Node* index,
|
||||
|
||||
Node* WasmGraphBuilder::TableSet(uint32_t table_index, Node* index, Node* val,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef) {
|
||||
if (env_->module->tables[table_index].type == wasm::kWasmAnyRef ||
|
||||
env_->module->tables[table_index].type == wasm::kWasmExnRef) {
|
||||
Node* base = nullptr;
|
||||
Node* offset = nullptr;
|
||||
GetTableBaseAndOffset(table_index, index, position, &base, &offset);
|
||||
|
@ -1635,6 +1635,12 @@ class ModuleDecoderImpl : public Decoder {
|
||||
"Invalid type. Set --experimental-wasm-anyref to use 'AnyRef'");
|
||||
}
|
||||
return kWasmAnyRef;
|
||||
case kLocalExnRef:
|
||||
if (!enabled_features_.eh) {
|
||||
error(pc_ - 1,
|
||||
"Invalid type. Set --experimental-wasm-eh to use 'ExnRef'");
|
||||
}
|
||||
return kWasmExnRef;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -529,8 +529,11 @@ bool WasmTableObject::IsInBounds(Isolate* isolate,
|
||||
bool WasmTableObject::IsValidElement(Isolate* isolate,
|
||||
Handle<WasmTableObject> table,
|
||||
Handle<Object> entry) {
|
||||
// Anyref tables take everything.
|
||||
if (table->type() == wasm::kWasmAnyRef) return true;
|
||||
// Anyref and exnref tables take everything.
|
||||
if (table->type() == wasm::kWasmAnyRef ||
|
||||
table->type() == wasm::kWasmExnRef) {
|
||||
return true;
|
||||
}
|
||||
// FuncRef tables can store {null}, {WasmExportedFunction}, {WasmJSFunction},
|
||||
// or {WasmCapiFunction} objects.
|
||||
if (entry->IsNull(isolate)) return true;
|
||||
@ -548,7 +551,8 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
|
||||
Handle<FixedArray> entries(table->entries(), isolate);
|
||||
// The FixedArray is addressed with int's.
|
||||
int entry_index = static_cast<int>(index);
|
||||
if (table->type() == wasm::kWasmAnyRef) {
|
||||
if (table->type() == wasm::kWasmAnyRef ||
|
||||
table->type() == wasm::kWasmExnRef) {
|
||||
entries->set(entry_index, *entry);
|
||||
return;
|
||||
}
|
||||
@ -592,8 +596,11 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
|
||||
Handle<Object> entry(entries->get(entry_index), isolate);
|
||||
|
||||
// First we handle the easy anyref table case.
|
||||
if (table->type() == wasm::kWasmAnyRef) return entry;
|
||||
// First we handle the easy anyref and exnref table case.
|
||||
if (table->type() == wasm::kWasmAnyRef ||
|
||||
table->type() == wasm::kWasmExnRef) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
// Now we handle the funcref case.
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*entry) ||
|
||||
|
@ -143,3 +143,42 @@ load("test/mjsunit/wasm/exceptions-utils.js");
|
||||
assertEquals(2.3, instance.exports.throw_catch_param(2.3));
|
||||
assertEquals("str", instance.exports.throw_catch_param("str"));
|
||||
})();
|
||||
|
||||
// Test storing and loading to/from an exception type table.
|
||||
(function TestTableExnRef() {
|
||||
let kSig_e_i = makeSig([kWasmI32], [kWasmExnRef]);
|
||||
let kSig_v_ie = makeSig([kWasmI32, kWasmExnRef], []);
|
||||
let builder = new WasmModuleBuilder();
|
||||
let table = builder.addTable(kWasmExnRef, 2).exportAs("table");
|
||||
builder.addFunction("table_load", kSig_e_i)
|
||||
.addBody([
|
||||
kExprLocalGet, 0,
|
||||
kExprTableGet, table.index
|
||||
]).exportFunc();
|
||||
builder.addFunction("table_store", kSig_v_ie)
|
||||
.addBody([
|
||||
kExprLocalGet, 0,
|
||||
kExprLocalGet, 1,
|
||||
kExprTableSet, table.index
|
||||
]).exportFunc();
|
||||
let instance = builder.instantiate();
|
||||
let e0 = new Error("my encapsulated error");
|
||||
let e1 = new Error("my other encapsulated error");
|
||||
|
||||
assertNull(instance.exports.table_load(0));
|
||||
assertNull(instance.exports.table_load(1));
|
||||
assertNull(instance.exports.table.get(0));
|
||||
assertNull(instance.exports.table.get(1));
|
||||
|
||||
instance.exports.table_store(0, e0);
|
||||
assertSame(e0, instance.exports.table_load(0));
|
||||
assertNull(instance.exports.table_load(1));
|
||||
assertSame(e0, instance.exports.table.get(0));
|
||||
assertNull(instance.exports.table.get(1));
|
||||
|
||||
instance.exports.table.set(1, e1);
|
||||
assertSame(e0, instance.exports.table_load(0));
|
||||
assertSame(e1, instance.exports.table_load(1));
|
||||
assertSame(e0, instance.exports.table.get(0));
|
||||
assertSame(e1, instance.exports.table.get(1));
|
||||
})();
|
||||
|
@ -799,8 +799,9 @@ class WasmModuleBuilder {
|
||||
}
|
||||
|
||||
addTable(type, initial_size, max_size = undefined) {
|
||||
if (type != kWasmAnyRef && type != kWasmAnyFunc) {
|
||||
throw new Error('Tables must be of type kWasmAnyRef or kWasmAnyFunc');
|
||||
if (type != kWasmAnyRef && type != kWasmAnyFunc && type != kWasmExnRef) {
|
||||
throw new Error(
|
||||
'Tables must be of type kWasmAnyRef, kWasmAnyFunc, or kWasmExnRef');
|
||||
}
|
||||
let table = new WasmTableBuilder(this, type, initial_size, max_size);
|
||||
table.index = this.tables.length + this.num_imported_tables;
|
||||
|
Loading…
Reference in New Issue
Block a user