Commit ce8812ac authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm-gc][test] Add builtin ref type handling in wasm-module-builder

We currently print reference type indices as unsigned LEB. This will not
work properly for large indices (>=64), as they will be interpreted as
negative indices when read back. They may also alias with builtin types.
In this CL, we fix this by defining builtin types as negative numbers.
We add positive byte constants that can be used in function bodies.
We adapt wasm-module-builder and tests to the above changes.

Bug: v8:7748
Change-Id: I4dfaa65d4cbf77a6731ca2283148bd842ea5c56b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3080569
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76176}
parent e7053d46
......@@ -2949,7 +2949,7 @@ uint8_t CompilationStateImpl::AddCompilationUnitInternal(
ExecutionTier reached_tier =
CompilationStateImpl::ReachedTierField::decode(function_progress);
if (FLAG_experimental_wasm_gc) {
/*if (FLAG_experimental_wasm_gc) {
// The Turbofan optimizations we enable for WasmGC code can (for now)
// take a very long time, so skip Turbofan compilation for super-large
// functions.
......@@ -2968,7 +2968,7 @@ uint8_t CompilationStateImpl::AddCompilationUnitInternal(
outstanding_top_tier_functions_--;
}
}
}
}*/
if (reached_tier < required_baseline_tier) {
builder->AddBaselineUnit(function_index, required_baseline_tier);
......
......@@ -11,7 +11,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
(function testExternRefNull() {
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_r_v)
.addBody([kExprRefNull, kWasmExternRef])
.addBody([kExprRefNull, kExternRefCode])
.exportFunc();
var wire_bytes = builder.toBuffer();
......
......@@ -152,7 +152,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_a_a);
builder.addFunction('main', sig_index)
.addBody([kExprRefNull, kWasmAnyFunc, kExprLocalSet, 0, kExprLocalGet, 0])
.addBody([kExprRefNull, kAnyFuncCode, kExprLocalSet, 0, kExprLocalGet, 0])
.exportFunc();
const main = builder.instantiate().exports.main;
......@@ -164,7 +164,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_a_v);
builder.addFunction('main', sig_index)
.addBody([kExprRefNull, kWasmAnyFunc])
.addBody([kExprRefNull, kAnyFuncCode])
.exportFunc();
const main = builder.instantiate().exports.main;
......@@ -176,7 +176,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_a_v);
builder.addFunction('main', sig_index)
.addBody([kExprRefNull, kWasmAnyFunc, kExprReturn])
.addBody([kExprRefNull, kAnyFuncCode, kExprReturn])
.exportFunc();
const main = builder.instantiate().exports.main;
......
......@@ -14,7 +14,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
let except = builder.addTag(kSig_v_r);
builder.addFunction("throw_null", kSig_v_v)
.addBody([
kExprRefNull, kWasmExternRef,
kExprRefNull, kExternRefCode,
kExprThrow, except,
]).exportFunc();
let instance = builder.instantiate();
......@@ -33,7 +33,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
kExprLocalGet, 0,
kExprI32Eqz,
kExprIf, kWasmI32,
kExprRefNull, kWasmExternRef,
kExprRefNull, kExternRefCode,
kExprThrow, except,
kExprElse,
kExprI32Const, 42,
......@@ -79,7 +79,7 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
let except = builder.addTag(kSig_v_r);
builder.addFunction("throw_catch_param", kSig_r_r)
.addBody([
kExprTry, kWasmExternRef,
kExprTry, kExternRefCode,
kExprLocalGet, 0,
kExprThrow, except,
kExprCatch, except,
......
......@@ -165,7 +165,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_r_v)
.addBody([kExprRefNull, kWasmExternRef])
.addBody([kExprRefNull, kExternRefCode])
.exportFunc();
const instance = builder.instantiate();
......@@ -196,7 +196,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v)
.addBody([kExprRefNull, kWasmExternRef, kExprRefIsNull])
.addBody([kExprRefNull, kExternRefCode, kExprRefIsNull])
.exportFunc();
const instance = builder.instantiate();
......@@ -225,7 +225,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_r_v);
builder.addFunction('main', sig_index)
.addBody([kExprRefNull, kWasmExternRef])
.addBody([kExprRefNull, kExternRefCode])
.exportFunc();
const main = builder.instantiate().exports.main;
......@@ -237,7 +237,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_r_v);
builder.addFunction('main', sig_index)
.addBody([kExprRefNull, kWasmExternRef, kExprReturn])
.addBody([kExprRefNull, kExternRefCode, kExprReturn])
.exportFunc();
const main = builder.instantiate().exports.main;
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm
// Flags: --expose-wasm --experimental-wasm-typed-funcref
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
......@@ -183,3 +183,24 @@ function instantiate(buffer, ffi) {
assertEquals(i, instance.exports.main());
}
})();
(function TestBigTypeIndices() {
print(arguments.callee.name);
// These are all positive type indices (e.g. kI31RefCode and not kWasmI31Ref)
// and should be treated as such.
let indices = [kI31RefCode, kDataRefCode, 200, 400];
let kMaxIndex = 400;
let builder = new WasmModuleBuilder();
for (let i = 0; i <= kMaxIndex; i++) {
builder.addType(kSig_i_i);
builder.addFunction(undefined, i)
.addBody([kExprLocalGet, 0]);
builder.addGlobal(wasmRefType(i), false, WasmInitExpr.RefFunc(i));
}
for (let i of indices) {
builder.addFunction('f_' + i, makeSig([], [wasmRefType(i)]))
.addBody([kExprRefFunc, ...wasmSignedLeb(i, 5)])
.exportFunc();
}
builder.instantiate();
})();
......@@ -57,7 +57,7 @@ let instance = (() => {
.addBody([kExprLocalGet, 0])
.exportFunc();
builder.addFunction(key + '_null', makeSig([], [type]))
.addBody([kExprRefNull, test_types[key]])
.addBody([kExprRefNull, ...wasmSignedLeb(test_types[key])])
.exportFunc();
}
......
......@@ -111,29 +111,46 @@ let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b;
let kWasmI8 = 0x7a;
let kWasmI16 = 0x79;
let kWasmFuncRef = 0x70;
// These are defined as negative integers to distinguish them from positive type
// indices.
let kWasmFuncRef = -0x10;
let kWasmAnyFunc = kWasmFuncRef; // Alias named as in the JS API spec
let kWasmExternRef = 0x6f;
let kWasmAnyRef = 0x6e;
let kWasmEqRef = 0x6d;
let kWasmExternRef = -0x11;
let kWasmAnyRef = -0x12;
let kWasmEqRef = -0x13;
let kWasmI31Ref = -0x16;
let kWasmDataRef = -0x19;
// Use the positive-byte versions inside function bodies.
let kLeb128Mask = 0x7f;
let kFuncRefCode = kWasmFuncRef & kLeb128Mask;
let kAnyFuncCode = kFuncRefCode; // Alias named as in the JS API spec
let kExternRefCode = kWasmExternRef & kLeb128Mask;
let kAnyRefCode = kWasmAnyRef & kLeb128Mask;
let kEqRefCode = kWasmEqRef & kLeb128Mask;
let kI31RefCode = kWasmI31Ref & kLeb128Mask;
let kDataRefCode = kWasmDataRef & kLeb128Mask;
let kWasmOptRef = 0x6c;
let kWasmRef = 0x6b;
function wasmOptRefType(index) {
return {opcode: kWasmOptRef, index: index};
function wasmOptRefType(heap_type) {
return {opcode: kWasmOptRef, heap_type: heap_type};
}
function wasmRefType(index) {
return {opcode: kWasmRef, index: index};
function wasmRefType(heap_type) {
return {opcode: kWasmRef, heap_type: heap_type};
}
let kWasmI31Ref = 0x6a;
let kWasmRttWithDepth = 0x69;
function wasmRtt(index, depth) {
if (index < 0) throw new Error("Expecting non-negative type index");
return {opcode: kWasmRttWithDepth, index: index, depth: depth};
}
let kWasmRtt = 0x68;
function wasmRttNoDepth(index) {
if (index < 0) throw new Error("Expecting non-negative type index");
return {opcode: kWasmRtt, index: index};
}
let kWasmDataRef = 0x67;
let kExternalFunction = 0;
let kExternalTable = 1;
......@@ -943,16 +960,21 @@ class Binary {
}
}
emit_heap_type(heap_type) {
this.emit_bytes(wasmSignedLeb(heap_type, kMaxVarInt32Size));
}
emit_type(type) {
if ((typeof type) == 'number') {
this.emit_u8(type);
this.emit_u8(type >= 0 ? type : type & kLeb128Mask);
} else {
this.emit_u8(type.opcode);
if ('depth' in type) this.emit_u8(type.depth);
this.emit_u32v(type.index);
this.emit_heap_type(type.heap_type);
}
}
emit_init_expr_recursive(expr) {
switch (expr.kind) {
case kExprGlobalGet:
......@@ -980,7 +1002,7 @@ class Binary {
break;
case kExprRefNull:
this.emit_u8(kExprRefNull);
this.emit_u32v(expr.value);
this.emit_heap_type(expr.value);
break;
case kExprStructNewWithRtt:
for (let operand of expr.operands) {
......@@ -1177,14 +1199,14 @@ class WasmInitExpr {
if ((typeof type) != 'number' && type.opcode != kWasmOptRef) {
throw new Error("Non-defaultable type");
}
let heap_type = (typeof type) == 'number' ? type : type.index;
let heap_type = (typeof type) == 'number' ? type : type.heap_type;
return this.RefNull(heap_type);
}
}
}
class WasmGlobalBuilder {
// {init} a pair {type, immediate}. Construct it with WasmInitExpr.
// {init} should be constructed with WasmInitExpr.
constructor(module, type, mutable, init) {
this.module = module;
this.type = type;
......
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