Commit 51ad897d authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][anyref] Implement re-export of mutable anyref globals

R=mstarzinger@chromium.org

Bug: v8:7581
Change-Id: If469467663e632a1dba3bd55ace830e1b2f38f7e
Reviewed-on: https://chromium-review.googlesource.com/c/1409427
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58824}
parent 8436715f
...@@ -1358,17 +1358,28 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) { ...@@ -1358,17 +1358,28 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
if (global.mutability && global.imported) { if (global.mutability && global.imported) {
Handle<FixedArray> buffers_array( Handle<FixedArray> buffers_array(
instance->imported_mutable_globals_buffers(), isolate_); instance->imported_mutable_globals_buffers(), isolate_);
untagged_buffer = buffers_array->GetValueChecked<JSArrayBuffer>( if (global.type == kWasmAnyRef) {
isolate_, global.index); tagged_buffer = buffers_array->GetValueChecked<FixedArray>(
Address global_addr = isolate_, global.index);
instance->imported_mutable_globals()[global.index]; // For anyref globals we store the relative offset in the
// imported_mutable_globals array instead of an absolute address.
size_t buffer_size = untagged_buffer->byte_length(); Address addr = instance->imported_mutable_globals()[global.index];
Address backing_store = DCHECK_LE(addr, static_cast<Address>(
reinterpret_cast<Address>(untagged_buffer->backing_store()); std::numeric_limits<uint32_t>::max()));
CHECK(global_addr >= backing_store && offset = static_cast<uint32_t>(addr);
global_addr < backing_store + buffer_size); } else {
offset = static_cast<uint32_t>(global_addr - backing_store); untagged_buffer = buffers_array->GetValueChecked<JSArrayBuffer>(
isolate_, global.index);
Address global_addr =
instance->imported_mutable_globals()[global.index];
size_t buffer_size = untagged_buffer->byte_length();
Address backing_store =
reinterpret_cast<Address>(untagged_buffer->backing_store());
CHECK(global_addr >= backing_store &&
global_addr < backing_store + buffer_size);
offset = static_cast<uint32_t>(global_addr - backing_store);
}
} else { } else {
if (global.type == kWasmAnyRef) { if (global.type == kWasmAnyRef) {
tagged_buffer = handle(instance->tagged_globals_buffer(), isolate_); tagged_buffer = handle(instance->tagged_globals_buffer(), isolate_);
......
...@@ -255,6 +255,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -255,6 +255,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const i3 = builder2.addImportedGlobal('exports', 'e3', kWasmAnyRef, true); const i3 = builder2.addImportedGlobal('exports', 'e3', kWasmAnyRef, true);
const i4 = builder2.addImportedGlobal('exports', 'e4', kWasmAnyRef, true); const i4 = builder2.addImportedGlobal('exports', 'e4', kWasmAnyRef, true);
builder2.addExportOfKind("reexport1", kExternalGlobal, i1);
builder2.addExportOfKind("reexport2", kExternalGlobal, i2);
builder2.addExportOfKind("reexport3", kExternalGlobal, i3);
builder2.addExportOfKind("reexport4", kExternalGlobal, i4);
builder2.addFunction("set_globals", kSig_v_rr) builder2.addFunction("set_globals", kSig_v_rr)
.addBody([ .addBody([
kExprGetLocal, 0, kExprGetLocal, 0,
...@@ -277,13 +282,32 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -277,13 +282,32 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertSame(obj2, instance2.exports.get_global2()); assertSame(obj2, instance2.exports.get_global2());
assertSame(obj3, instance2.exports.get_global3()); assertSame(obj3, instance2.exports.get_global3());
assertSame(obj2, instance2.exports.reexport2.value);
assertSame(obj3, instance2.exports.reexport3.value);
// Check if instance2 can make changes visible for instance1. // Check if instance2 can make changes visible for instance1.
instance2.exports.set_globals(null, undefined); instance2.exports.set_globals(null, undefined);
assertEquals(null, instance1.exports.get_global2()); assertEquals(null, instance1.exports.get_global2());
assertEquals(undefined, instance1.exports.get_global3()); assertEquals(undefined, instance1.exports.get_global3());
assertEquals(null, instance2.exports.reexport2.value);
assertEquals(undefined, instance2.exports.reexport3.value);
// Check if instance1 can make changes visible for instance2. // Check if instance1 can make changes visible for instance2.
instance1.exports.set_globals("foo", 66343); instance1.exports.set_globals("foo", 66343);
assertEquals("foo", instance2.exports.get_global2()); assertEquals("foo", instance2.exports.get_global2());
assertEquals(66343, instance2.exports.get_global3()); assertEquals(66343, instance2.exports.get_global3());
assertEquals("foo", instance2.exports.reexport2.value);
assertEquals(66343, instance2.exports.reexport3.value);
const bar2 = {f: "oo"};
const bar3 = {b: "ar"};
instance2.exports.reexport2.value = bar2;
instance2.exports.reexport3.value = bar3;
assertSame(bar2, instance1.exports.get_global2());
assertSame(bar3, instance1.exports.get_global3());
assertSame(bar2, instance2.exports.get_global2());
assertSame(bar3, instance2.exports.get_global3());
})(); })();
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