[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:
Jakob Kummerow 2021-08-04 22:58:16 +02:00 committed by V8 LUCI CQ
parent fee168ce06
commit d314be6730
4 changed files with 117 additions and 2 deletions

View File

@ -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;

View File

@ -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 {

View 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();

View File

@ -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);