[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);
|
module_->add_signature(s);
|
||||||
break;
|
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: {
|
case kWasmStructTypeCode: {
|
||||||
if (!enabled_features_.has_gc()) {
|
if (!enabled_features_.has_gc()) {
|
||||||
errorf(pc(),
|
errorf(pc(),
|
||||||
@ -575,6 +590,21 @@ class ModuleDecoderImpl : public Decoder {
|
|||||||
// {signature_map} does for function signatures?
|
// {signature_map} does for function signatures?
|
||||||
break;
|
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: {
|
case kWasmArrayTypeCode: {
|
||||||
if (!enabled_features_.has_gc()) {
|
if (!enabled_features_.has_gc()) {
|
||||||
errorf(pc(),
|
errorf(pc(),
|
||||||
@ -586,6 +616,21 @@ class ModuleDecoderImpl : public Decoder {
|
|||||||
module_->add_array_type(type);
|
module_->add_array_type(type);
|
||||||
break;
|
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:
|
default:
|
||||||
errorf(pc(), "unknown type form: %d", kind);
|
errorf(pc(), "unknown type form: %d", kind);
|
||||||
break;
|
break;
|
||||||
|
@ -50,6 +50,9 @@ enum ValueTypeCode : uint8_t {
|
|||||||
constexpr uint8_t kWasmFunctionTypeCode = 0x60;
|
constexpr uint8_t kWasmFunctionTypeCode = 0x60;
|
||||||
constexpr uint8_t kWasmStructTypeCode = 0x5f;
|
constexpr uint8_t kWasmStructTypeCode = 0x5f;
|
||||||
constexpr uint8_t kWasmArrayTypeCode = 0x5e;
|
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.
|
// Binary encoding of import/export kinds.
|
||||||
enum ImportExportKindCode : uint8_t {
|
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 kWasmFunctionTypeForm = 0x60;
|
||||||
let kWasmStructTypeForm = 0x5f;
|
let kWasmStructTypeForm = 0x5f;
|
||||||
let kWasmArrayTypeForm = 0x5e;
|
let kWasmArrayTypeForm = 0x5e;
|
||||||
|
let kWasmFunctionExtendingTypeForm = 0x5d;
|
||||||
|
let kWasmStructExtendingTypeForm = 0x5c;
|
||||||
|
let kWasmArrayExtendingTypeForm = 0x5b;
|
||||||
|
|
||||||
let kLimitsNoMaximum = 0x00;
|
let kLimitsNoMaximum = 0x00;
|
||||||
let kLimitsWithMaximum = 0x01;
|
let kLimitsWithMaximum = 0x01;
|
||||||
@ -1223,6 +1226,15 @@ class WasmStruct {
|
|||||||
throw new Error('struct fields must be an array');
|
throw new Error('struct fields must be an array');
|
||||||
}
|
}
|
||||||
this.fields = fields;
|
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;
|
this.type = type;
|
||||||
if (!mutability) throw new Error("Immutable arrays are not supported yet");
|
if (!mutability) throw new Error("Immutable arrays are not supported yet");
|
||||||
this.mutability = mutability;
|
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 {
|
class WasmElemSegment {
|
||||||
constructor(table, offset, type, elements, is_decl) {
|
constructor(table, offset, type, elements, is_decl) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
@ -1356,11 +1376,21 @@ class WasmModuleBuilder {
|
|||||||
return this.types.length - 1;
|
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) {
|
addArray(type, mutability) {
|
||||||
this.types.push(new WasmArray(type, mutability));
|
this.types.push(new WasmArray(type, mutability));
|
||||||
return this.types.length - 1;
|
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) {
|
addGlobal(type, mutable, init) {
|
||||||
if (init === undefined) init = WasmInitExpr.defaultFor(type);
|
if (init === undefined) init = WasmInitExpr.defaultFor(type);
|
||||||
let glob = new WasmGlobalBuilder(this, type, mutable, init);
|
let glob = new WasmGlobalBuilder(this, type, mutable, init);
|
||||||
@ -1589,16 +1619,22 @@ class WasmModuleBuilder {
|
|||||||
section.emit_u32v(wasm.types.length);
|
section.emit_u32v(wasm.types.length);
|
||||||
for (let type of wasm.types) {
|
for (let type of wasm.types) {
|
||||||
if (type instanceof WasmStruct) {
|
if (type instanceof WasmStruct) {
|
||||||
section.emit_u8(kWasmStructTypeForm);
|
section.emit_u8(type.type_form);
|
||||||
section.emit_u32v(type.fields.length);
|
section.emit_u32v(type.fields.length);
|
||||||
for (let field of type.fields) {
|
for (let field of type.fields) {
|
||||||
section.emit_type(field.type);
|
section.emit_type(field.type);
|
||||||
section.emit_u8(field.mutability ? 1 : 0);
|
section.emit_u8(field.mutability ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
if (type instanceof WasmStructExtending) {
|
||||||
|
section.emit_u32v(type.supertype);
|
||||||
|
}
|
||||||
} else if (type instanceof WasmArray) {
|
} else if (type instanceof WasmArray) {
|
||||||
section.emit_u8(kWasmArrayTypeForm);
|
section.emit_u8(type.type_form);
|
||||||
section.emit_type(type.type);
|
section.emit_type(type.type);
|
||||||
section.emit_u8(type.mutability ? 1 : 0);
|
section.emit_u8(type.mutability ? 1 : 0);
|
||||||
|
if (type instanceof WasmArrayExtending) {
|
||||||
|
section.emit_u32v(type.supertype);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
section.emit_u8(kWasmFunctionTypeForm);
|
section.emit_u8(kWasmFunctionTypeForm);
|
||||||
section.emit_u32v(type.params.length);
|
section.emit_u32v(type.params.length);
|
||||||
|
Loading…
Reference in New Issue
Block a user