[wasm] Re-exported globals preserve their identity
V8 fails a recently added spec test that when an imported global get re-exported, it should preserve its identity. This CL fixes the behavior in V8. Drive-by change: fix the object printer of globals: a global which stores a reference type only has a tagged buffer, a global which stores a value type only has an untagged buffer. R=clemensb@chromium.org Bug: v8:10556 Change-Id: I949d147fe4395610cfec6cf60082e1faecb23036 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2235702 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68513}
This commit is contained in:
parent
3f9119d586
commit
f7a1932ef9
@ -1815,8 +1815,11 @@ void WasmTableObject::WasmTableObjectPrint(std::ostream& os) { // NOLINT
|
||||
|
||||
void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) { // NOLINT
|
||||
PrintHeader(os, "WasmGlobalObject");
|
||||
os << "\n - untagged_buffer: " << Brief(untagged_buffer());
|
||||
os << "\n - tagged_buffer: " << Brief(tagged_buffer());
|
||||
if (type().is_reference_type()) {
|
||||
os << "\n - tagged_buffer: " << Brief(tagged_buffer());
|
||||
} else {
|
||||
os << "\n - untagged_buffer: " << Brief(untagged_buffer());
|
||||
}
|
||||
os << "\n - offset: " << offset();
|
||||
os << "\n - raw_type: " << raw_type();
|
||||
os << "\n - is_mutable: " << is_mutable();
|
||||
|
@ -259,9 +259,6 @@ class InstanceBuilder {
|
||||
// Process initialization of globals.
|
||||
void InitGlobals(Handle<WasmInstanceObject> instance);
|
||||
|
||||
|
||||
bool NeedsWrappers() const;
|
||||
|
||||
// Process the exports, creating wrappers for functions, tables, memories,
|
||||
// and globals.
|
||||
void ProcessExports(Handle<WasmInstanceObject> instance);
|
||||
@ -1479,31 +1476,29 @@ bool InstanceBuilder::AllocateMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstanceBuilder::NeedsWrappers() const {
|
||||
if (module_->num_exported_functions > 0) return true;
|
||||
for (auto& table : module_->tables) {
|
||||
if (table.type.heap_type() == kHeapFunc) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Process the exports, creating wrappers for functions, tables, memories,
|
||||
// globals, and exceptions.
|
||||
void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
|
||||
if (NeedsWrappers()) {
|
||||
// If an imported WebAssembly function gets exported, the exported function
|
||||
// has to be identical to to imported function. Therefore we cache all
|
||||
// imported WebAssembly functions in the instance.
|
||||
for (int index = 0, end = static_cast<int>(module_->import_table.size());
|
||||
index < end; ++index) {
|
||||
const WasmImport& import = module_->import_table[index];
|
||||
if (import.kind == kExternalFunction) {
|
||||
Handle<Object> value = sanitized_imports_[index].value;
|
||||
if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
|
||||
WasmInstanceObject::SetWasmExternalFunction(
|
||||
isolate_, instance, import.index,
|
||||
Handle<WasmExternalFunction>::cast(value));
|
||||
}
|
||||
std::unordered_map<int, Handle<Object>> imported_globals;
|
||||
|
||||
// If an imported WebAssembly function or global gets exported, the export
|
||||
// has to be identical to to import. Therefore we cache all imported
|
||||
// WebAssembly functions in the instance, and all imported globals in a map
|
||||
// here.
|
||||
for (int index = 0, end = static_cast<int>(module_->import_table.size());
|
||||
index < end; ++index) {
|
||||
const WasmImport& import = module_->import_table[index];
|
||||
if (import.kind == kExternalFunction) {
|
||||
Handle<Object> value = sanitized_imports_[index].value;
|
||||
if (WasmExternalFunction::IsWasmExternalFunction(*value)) {
|
||||
WasmInstanceObject::SetWasmExternalFunction(
|
||||
isolate_, instance, import.index,
|
||||
Handle<WasmExternalFunction>::cast(value));
|
||||
}
|
||||
} else if (import.kind == kExternalGlobal) {
|
||||
Handle<Object> value = sanitized_imports_[index].value;
|
||||
if (value->IsWasmGlobalObject()) {
|
||||
imported_globals[import.index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1563,6 +1558,13 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
|
||||
}
|
||||
case kExternalGlobal: {
|
||||
const WasmGlobal& global = module_->globals[exp.index];
|
||||
if (global.imported) {
|
||||
auto cached_global = imported_globals.find(exp.index);
|
||||
if (cached_global != imported_globals.end()) {
|
||||
desc.set_value(cached_global->second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Handle<JSArrayBuffer> untagged_buffer;
|
||||
Handle<FixedArray> tagged_buffer;
|
||||
uint32_t offset;
|
||||
|
31
test/mjsunit/wasm/globals-import-export-identity.js
Normal file
31
test/mjsunit/wasm/globals-import-export-identity.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
const global1 = new WebAssembly.Global({value: 'i32', mutable: true}, 14);
|
||||
const global2 = new WebAssembly.Global({value: 'i32', mutable: true}, 15);
|
||||
const global3 = new WebAssembly.Global({value: 'i32', mutable: true}, 32);
|
||||
|
||||
const builder = new WasmModuleBuilder();
|
||||
|
||||
// Two additional globals, so that global-index != export-index.
|
||||
builder.addImportedGlobal('module', 'global1', kWasmI32, true);
|
||||
builder.addImportedGlobal('module', 'global2', kWasmI32, true);
|
||||
const globalIndex =
|
||||
builder.addImportedGlobal('module', 'global3', kWasmI32, true);
|
||||
builder.addExportOfKind('exportedGlobal', kExternalGlobal, globalIndex);
|
||||
|
||||
const buffer = builder.toBuffer();
|
||||
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
const instance = new WebAssembly.Instance(module, {
|
||||
'module': {
|
||||
'global1': global1,
|
||||
'global2': global2,
|
||||
'global3': global3,
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(global3, instance.exports.exportedGlobal);
|
7219
test/wasm-js/third_party/testharness.js
vendored
7219
test/wasm-js/third_party/testharness.js
vendored
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,6 @@
|
||||
[ALWAYS, {
|
||||
# TODO(v8:10556): Remove sub-typing in the reference-types implementation
|
||||
'constructor/instantiate': [FAIL],
|
||||
'instance/constructor-caching': [FAIL],
|
||||
'instance/constructor': [FAIL],
|
||||
'proposals/js-types/constructor/instantiate': [FAIL],
|
||||
'proposals/js-types/global/constructor': [FAIL],
|
||||
|
Loading…
Reference in New Issue
Block a user