[wasm-gc] Experiment: accept types with explicit inheritance
This patch makes V8 accept the binary format produced by Binaryen after https://github.com/WebAssembly/binaryen/pull/3933 when the --experimental-wasm-gc-experiments flag is present. The explicit inheritance information is not used for anything. Validation is performed only insofar as explicit supertypes must be valid types. Bug: v8:7748 Change-Id: Id5b5050aa03591281632e3a2a161aa93422e10bd Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3071406 Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#76135}
This commit is contained in:
parent
fee168ce06
commit
d314be6730
@ -562,6 +562,21 @@ class ModuleDecoderImpl : public Decoder {
|
||||
module_->add_signature(s);
|
||||
break;
|
||||
}
|
||||
case kWasmFunctionExtendingTypeCode: {
|
||||
if (!enabled_features_.has_gc_experiments()) {
|
||||
errorf(pc(),
|
||||
"nominal types need --experimental-wasm-gc-experiments");
|
||||
break;
|
||||
}
|
||||
const FunctionSig* s = consume_sig(module_->signature_zone.get());
|
||||
module_->add_signature(s);
|
||||
uint32_t super_index = consume_u32v("supertype");
|
||||
if (!module_->has_signature(super_index)) {
|
||||
errorf(pc(), "invalid function supertype index: %d", super_index);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kWasmStructTypeCode: {
|
||||
if (!enabled_features_.has_gc()) {
|
||||
errorf(pc(),
|
||||
@ -575,6 +590,21 @@ class ModuleDecoderImpl : public Decoder {
|
||||
// {signature_map} does for function signatures?
|
||||
break;
|
||||
}
|
||||
case kWasmStructExtendingTypeCode: {
|
||||
if (!enabled_features_.has_gc_experiments()) {
|
||||
errorf(pc(),
|
||||
"nominal types need --experimental-wasm-gc-experiments");
|
||||
break;
|
||||
}
|
||||
const StructType* s = consume_struct(module_->signature_zone.get());
|
||||
module_->add_struct_type(s);
|
||||
uint32_t super_index = consume_u32v("supertype");
|
||||
if (!module_->has_struct(super_index)) {
|
||||
errorf(pc(), "invalid struct supertype: %d", super_index);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kWasmArrayTypeCode: {
|
||||
if (!enabled_features_.has_gc()) {
|
||||
errorf(pc(),
|
||||
@ -586,6 +616,21 @@ class ModuleDecoderImpl : public Decoder {
|
||||
module_->add_array_type(type);
|
||||
break;
|
||||
}
|
||||
case kWasmArrayExtendingTypeCode: {
|
||||
if (!enabled_features_.has_gc_experiments()) {
|
||||
errorf(pc(),
|
||||
"nominal types need --experimental-wasm-gc-experiments");
|
||||
break;
|
||||
}
|
||||
const ArrayType* type = consume_array(module_->signature_zone.get());
|
||||
module_->add_array_type(type);
|
||||
uint32_t super_index = consume_u32v("supertype");
|
||||
if (!module_->has_array(super_index)) {
|
||||
errorf(pc(), "invalid array supertype: %d", super_index);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errorf(pc(), "unknown type form: %d", kind);
|
||||
break;
|
||||
|
@ -50,6 +50,9 @@ enum ValueTypeCode : uint8_t {
|
||||
constexpr uint8_t kWasmFunctionTypeCode = 0x60;
|
||||
constexpr uint8_t kWasmStructTypeCode = 0x5f;
|
||||
constexpr uint8_t kWasmArrayTypeCode = 0x5e;
|
||||
constexpr uint8_t kWasmFunctionExtendingTypeCode = 0x5d;
|
||||
constexpr uint8_t kWasmStructExtendingTypeCode = 0x5c;
|
||||
constexpr uint8_t kWasmArrayExtendingTypeCode = 0x5b;
|
||||
|
||||
// Binary encoding of import/export kinds.
|
||||
enum ImportExportKindCode : uint8_t {
|
||||
|
31
test/mjsunit/wasm/gc-nominal.js
Normal file
31
test/mjsunit/wasm/gc-nominal.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Flags: --experimental-wasm-gc-experiments
|
||||
|
||||
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
var builder = new WasmModuleBuilder();
|
||||
let struct1 = builder.addStruct([makeField(kWasmI32, true)]);
|
||||
let struct2 = builder.addStructExtending(
|
||||
[makeField(kWasmI32, true), makeField(kWasmI32, true)], struct1);
|
||||
|
||||
let array1 = builder.addArray(kWasmI32, true);
|
||||
let array2 = builder.addArrayExtending(kWasmI32, true, array1);
|
||||
|
||||
builder.addFunction("main", kSig_v_v)
|
||||
.addLocals(wasmOptRefType(struct1), 1)
|
||||
.addLocals(wasmOptRefType(array1), 1)
|
||||
.addBody([
|
||||
kGCPrefix, kExprRttCanon, struct2,
|
||||
kGCPrefix, kExprStructNewDefault, struct2,
|
||||
kExprLocalSet, 0,
|
||||
kExprI32Const, 10, // length
|
||||
kGCPrefix, kExprRttCanon, array2,
|
||||
kGCPrefix, kExprArrayNewDefault, array2,
|
||||
kExprLocalSet, 1
|
||||
]);
|
||||
|
||||
// This test is only interested in type checking.
|
||||
builder.instantiate();
|
@ -77,6 +77,9 @@ let kLocalNamesCode = 2;
|
||||
let kWasmFunctionTypeForm = 0x60;
|
||||
let kWasmStructTypeForm = 0x5f;
|
||||
let kWasmArrayTypeForm = 0x5e;
|
||||
let kWasmFunctionExtendingTypeForm = 0x5d;
|
||||
let kWasmStructExtendingTypeForm = 0x5c;
|
||||
let kWasmArrayExtendingTypeForm = 0x5b;
|
||||
|
||||
let kLimitsNoMaximum = 0x00;
|
||||
let kLimitsWithMaximum = 0x01;
|
||||
@ -1223,6 +1226,15 @@ class WasmStruct {
|
||||
throw new Error('struct fields must be an array');
|
||||
}
|
||||
this.fields = fields;
|
||||
this.type_form = kWasmStructTypeForm;
|
||||
}
|
||||
}
|
||||
|
||||
class WasmStructExtending extends WasmStruct {
|
||||
constructor(fields, supertype_idx) {
|
||||
super(fields);
|
||||
this.supertype = supertype_idx;
|
||||
this.type_form = kWasmStructExtendingTypeForm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1231,9 +1243,17 @@ class WasmArray {
|
||||
this.type = type;
|
||||
if (!mutability) throw new Error("Immutable arrays are not supported yet");
|
||||
this.mutability = mutability;
|
||||
this.type_form = kWasmArrayTypeForm;
|
||||
}
|
||||
}
|
||||
|
||||
class WasmArrayExtending extends WasmArray {
|
||||
constructor(type, mutability, supertype_idx) {
|
||||
super(type, mutability);
|
||||
this.supertype = supertype_idx;
|
||||
this.type_form = kWasmArrayExtendingTypeForm;
|
||||
}
|
||||
}
|
||||
class WasmElemSegment {
|
||||
constructor(table, offset, type, elements, is_decl) {
|
||||
this.table = table;
|
||||
@ -1356,11 +1376,21 @@ class WasmModuleBuilder {
|
||||
return this.types.length - 1;
|
||||
}
|
||||
|
||||
addStructExtending(fields, supertype_idx) {
|
||||
this.types.push(new WasmStructExtending(fields, supertype_idx));
|
||||
return this.types.length - 1;
|
||||
}
|
||||
|
||||
addArray(type, mutability) {
|
||||
this.types.push(new WasmArray(type, mutability));
|
||||
return this.types.length - 1;
|
||||
}
|
||||
|
||||
addArrayExtending(type, mutability, supertype_idx) {
|
||||
this.types.push(new WasmArrayExtending(type, mutability, supertype_idx));
|
||||
return this.types.length - 1;
|
||||
}
|
||||
|
||||
addGlobal(type, mutable, init) {
|
||||
if (init === undefined) init = WasmInitExpr.defaultFor(type);
|
||||
let glob = new WasmGlobalBuilder(this, type, mutable, init);
|
||||
@ -1589,16 +1619,22 @@ class WasmModuleBuilder {
|
||||
section.emit_u32v(wasm.types.length);
|
||||
for (let type of wasm.types) {
|
||||
if (type instanceof WasmStruct) {
|
||||
section.emit_u8(kWasmStructTypeForm);
|
||||
section.emit_u8(type.type_form);
|
||||
section.emit_u32v(type.fields.length);
|
||||
for (let field of type.fields) {
|
||||
section.emit_type(field.type);
|
||||
section.emit_u8(field.mutability ? 1 : 0);
|
||||
}
|
||||
if (type instanceof WasmStructExtending) {
|
||||
section.emit_u32v(type.supertype);
|
||||
}
|
||||
} else if (type instanceof WasmArray) {
|
||||
section.emit_u8(kWasmArrayTypeForm);
|
||||
section.emit_u8(type.type_form);
|
||||
section.emit_type(type.type);
|
||||
section.emit_u8(type.mutability ? 1 : 0);
|
||||
if (type instanceof WasmArrayExtending) {
|
||||
section.emit_u32v(type.supertype);
|
||||
}
|
||||
} else {
|
||||
section.emit_u8(kWasmFunctionTypeForm);
|
||||
section.emit_u32v(type.params.length);
|
||||
|
Loading…
Reference in New Issue
Block a user