[wasm-gc] Merge anyref and externref
According to the latest changes in wasm-gc, externref will be renamed to anyref, and will be assigned as the top of the reference type hierarchy. Since in the current wasm type system funcref is not a subtype of anyref, subtyping is now dependent on whether wasm-gc is enabled. Bug: v8:7748 Change-Id: I0c0ae3dd5523e624d4490ca33d1fba4c2ae59393 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3468345 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#79322}
This commit is contained in:
parent
8d55cd6c0e
commit
6a6c116843
@ -48,10 +48,10 @@ extern macro AllocateWasmArray(
|
||||
}
|
||||
|
||||
namespace wasm {
|
||||
const kExternTableType: constexpr int31
|
||||
generates 'wasm::kWasmExternRef.raw_bit_field()';
|
||||
const kExternNonNullTableType: constexpr int31
|
||||
generates 'wasm::kWasmExternNonNullableRef.raw_bit_field()';
|
||||
const kAnyTableType: constexpr int31
|
||||
generates 'wasm::kWasmAnyRef.raw_bit_field()';
|
||||
const kAnyNonNullTableType: constexpr int31
|
||||
generates 'wasm::kWasmAnyNonNullableRef.raw_bit_field()';
|
||||
|
||||
extern macro WasmBuiltinsAssembler::LoadInstanceFromFrame(): WasmInstanceObject;
|
||||
|
||||
@ -213,8 +213,8 @@ builtin WasmTableSet(tableIndex: intptr, index: int32, value: Object): Object {
|
||||
// function dispatch tables.
|
||||
// TODO(7748): Update this if further table types are supported.
|
||||
const tableType: Smi = table.raw_type;
|
||||
if (tableType != SmiConstant(kExternTableType) &&
|
||||
tableType != SmiConstant(kExternNonNullTableType)) {
|
||||
if (tableType != SmiConstant(kAnyTableType) &&
|
||||
tableType != SmiConstant(kAnyNonNullTableType)) {
|
||||
goto CallRuntime;
|
||||
}
|
||||
|
||||
|
@ -6407,8 +6407,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
case wasm::kRef:
|
||||
case wasm::kOptRef:
|
||||
switch (type.heap_representation()) {
|
||||
case wasm::HeapType::kExtern:
|
||||
return node;
|
||||
case wasm::HeapType::kFunc: {
|
||||
if (type.kind() == wasm::kOptRef) {
|
||||
auto done =
|
||||
@ -6446,6 +6444,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
return BuildAllocateObjectWrapper(node, context);
|
||||
}
|
||||
case wasm::HeapType::kAny: {
|
||||
if (!enabled_features_.has_gc()) return node;
|
||||
// Wrap {node} in object wrapper if it is an array/struct.
|
||||
// Extract external function if this is a WasmInternalFunction.
|
||||
// Otherwise (i.e. null and external refs), return input.
|
||||
@ -6618,9 +6617,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
case wasm::kRef:
|
||||
case wasm::kOptRef: {
|
||||
switch (type.heap_representation()) {
|
||||
case wasm::HeapType::kExtern:
|
||||
return input;
|
||||
case wasm::HeapType::kAny:
|
||||
if (!enabled_features_.has_gc()) return input;
|
||||
// If this is a wrapper for arrays/structs/i31s, unpack it.
|
||||
// TODO(7748): Update this when JS interop has settled.
|
||||
return BuildUnpackObjectWrapper(input, js_context);
|
||||
|
@ -980,7 +980,7 @@ Handle<WasmValueObject> WasmValueObject::New(
|
||||
v = handle(Handle<WasmInternalFunction>::cast(ref)->external(),
|
||||
isolate);
|
||||
} else if (ref->IsJSFunction() || ref->IsSmi() || ref->IsNull() ||
|
||||
value.type().is_reference_to(wasm::HeapType::kExtern)) {
|
||||
value.type().is_reference_to(wasm::HeapType::kAny)) {
|
||||
v = ref;
|
||||
} else {
|
||||
// Fail gracefully.
|
||||
|
@ -3280,7 +3280,7 @@ class LiftoffCompiler {
|
||||
ValueType type =
|
||||
index < static_cast<int>(__ num_locals())
|
||||
? decoder->local_type(index)
|
||||
: exception ? ValueType::Ref(HeapType::kExtern, kNonNullable)
|
||||
: exception ? ValueType::Ref(HeapType::kAny, kNonNullable)
|
||||
: decoder->stack_value(decoder_stack_index--)->type;
|
||||
DCHECK(CheckCompatibleStackSlotTypes(slot.kind(), type.kind()));
|
||||
value.type = type;
|
||||
|
@ -84,9 +84,7 @@ ValKind V8ValueTypeToWasm(i::wasm::ValueType v8_valtype) {
|
||||
switch (v8_valtype.heap_representation()) {
|
||||
case i::wasm::HeapType::kFunc:
|
||||
return FUNCREF;
|
||||
case i::wasm::HeapType::kExtern:
|
||||
// TODO(7748): Rename this to EXTERNREF if/when third-party API
|
||||
// changes.
|
||||
case i::wasm::HeapType::kAny:
|
||||
return ANYREF;
|
||||
default:
|
||||
// TODO(wasm+): support new value types
|
||||
@ -111,7 +109,7 @@ i::wasm::ValueType WasmValKindToV8(ValKind kind) {
|
||||
case FUNCREF:
|
||||
return i::wasm::kWasmFuncRef;
|
||||
case ANYREF:
|
||||
return i::wasm::kWasmExternRef;
|
||||
return i::wasm::kWasmAnyRef;
|
||||
default:
|
||||
// TODO(wasm+): support new value types
|
||||
UNREACHABLE();
|
||||
@ -1928,7 +1926,7 @@ auto Table::make(Store* store_abs, const TableType* type, const Ref* ref)
|
||||
break;
|
||||
case ANYREF:
|
||||
// See Engine::make().
|
||||
i_type = i::wasm::kWasmExternRef;
|
||||
i_type = i::wasm::kWasmAnyRef;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -1974,7 +1972,7 @@ auto Table::type() const -> own<TableType> {
|
||||
case i::wasm::HeapType::kFunc:
|
||||
kind = FUNCREF;
|
||||
break;
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kAny:
|
||||
kind = ANYREF;
|
||||
break;
|
||||
default:
|
||||
|
@ -204,7 +204,7 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc,
|
||||
case kI31RefCode:
|
||||
case kDataRefCode:
|
||||
case kArrayRefCode:
|
||||
case kAnyRefCode:
|
||||
case kAnyRefCodeAlias:
|
||||
if (!VALIDATE(enabled.has_gc())) {
|
||||
DecodeError<validate>(
|
||||
decoder, pc,
|
||||
@ -213,7 +213,7 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc,
|
||||
return HeapType(HeapType::kBottom);
|
||||
}
|
||||
V8_FALLTHROUGH;
|
||||
case kExternRefCode:
|
||||
case kAnyRefCode:
|
||||
case kFuncRefCode:
|
||||
return HeapType::from_code(code);
|
||||
default:
|
||||
@ -271,7 +271,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
|
||||
case kI31RefCode:
|
||||
case kDataRefCode:
|
||||
case kArrayRefCode:
|
||||
case kAnyRefCode:
|
||||
case kAnyRefCodeAlias:
|
||||
if (!VALIDATE(enabled.has_gc())) {
|
||||
DecodeError<validate>(
|
||||
decoder, pc,
|
||||
@ -280,7 +280,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
|
||||
return kWasmBottom;
|
||||
}
|
||||
V8_FALLTHROUGH;
|
||||
case kExternRefCode:
|
||||
case kAnyRefCode:
|
||||
case kFuncRefCode: {
|
||||
HeapType heap_type = HeapType::from_code(code);
|
||||
Nullability nullability =
|
||||
|
@ -179,7 +179,7 @@ bool UseGenericWrapper(const FunctionSig* sig) {
|
||||
ValueType ret = sig->GetReturn(0);
|
||||
if (ret.kind() == kS128) return false;
|
||||
if (ret.is_reference()) {
|
||||
if (ret.heap_representation() != wasm::HeapType::kExtern &&
|
||||
if (ret.heap_representation() != wasm::HeapType::kAny &&
|
||||
ret.heap_representation() != wasm::HeapType::kFunc) {
|
||||
return false;
|
||||
}
|
||||
@ -189,7 +189,7 @@ bool UseGenericWrapper(const FunctionSig* sig) {
|
||||
if (type.kind() != kI32 && type.kind() != kI64 && type.kind() != kF32 &&
|
||||
type.kind() != kF64 &&
|
||||
!(type.is_reference() &&
|
||||
type.heap_representation() == wasm::HeapType::kExtern)) {
|
||||
type.heap_representation() == wasm::HeapType::kAny)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -803,9 +803,7 @@ class ModuleDecoderImpl : public Decoder {
|
||||
const byte* type_position = pc();
|
||||
ValueType type = consume_reference_type();
|
||||
if (!WasmTable::IsValidTableType(type, module_.get())) {
|
||||
error(type_position,
|
||||
"Currently, only externref and function references are "
|
||||
"allowed as table types");
|
||||
errorf(type_position, "Invalid table type %s", type.name().c_str());
|
||||
break;
|
||||
}
|
||||
table->type = type;
|
||||
|
@ -61,12 +61,11 @@ class HeapType {
|
||||
public:
|
||||
enum Representation : uint32_t {
|
||||
kFunc = kV8MaxWasmTypes, // shorthand: c
|
||||
kExtern, // shorthand: e
|
||||
kEq, // shorthand: q
|
||||
kI31, // shorthand: j
|
||||
kData, // shorthand: o
|
||||
kArray, // shorthand: g
|
||||
kAny, // shorthand: a
|
||||
kAny, // shorthand: a. Aka kExtern.
|
||||
// This value is used to represent failures in the parsing of heap types and
|
||||
// does not correspond to a wasm heap type. It has to be last in this list.
|
||||
kBottom
|
||||
@ -76,13 +75,12 @@ class HeapType {
|
||||
switch (code) {
|
||||
case ValueTypeCode::kFuncRefCode:
|
||||
return HeapType(kFunc);
|
||||
case ValueTypeCode::kExternRefCode:
|
||||
return HeapType(kExtern);
|
||||
case ValueTypeCode::kEqRefCode:
|
||||
return HeapType(kEq);
|
||||
case ValueTypeCode::kI31RefCode:
|
||||
return HeapType(kI31);
|
||||
case ValueTypeCode::kAnyRefCode:
|
||||
case ValueTypeCode::kAnyRefCodeAlias:
|
||||
return HeapType(kAny);
|
||||
case ValueTypeCode::kDataRefCode:
|
||||
return HeapType(kData);
|
||||
@ -132,8 +130,6 @@ class HeapType {
|
||||
switch (representation_) {
|
||||
case kFunc:
|
||||
return std::string("func");
|
||||
case kExtern:
|
||||
return std::string("extern");
|
||||
case kEq:
|
||||
return std::string("eq");
|
||||
case kI31:
|
||||
@ -143,7 +139,7 @@ class HeapType {
|
||||
case kArray:
|
||||
return std::string("array");
|
||||
case kAny:
|
||||
return std::string("any");
|
||||
return std::string(FLAG_experimental_wasm_gc ? "any" : "extern");
|
||||
default:
|
||||
return std::to_string(representation_);
|
||||
}
|
||||
@ -157,8 +153,6 @@ class HeapType {
|
||||
switch (representation_) {
|
||||
case kFunc:
|
||||
return mask | kFuncRefCode;
|
||||
case kExtern:
|
||||
return mask | kExternRefCode;
|
||||
case kEq:
|
||||
return mask | kEqRefCode;
|
||||
case kI31:
|
||||
@ -424,7 +418,7 @@ class ValueType {
|
||||
case MachineRepresentation::kFloat64:
|
||||
return Primitive(kF64);
|
||||
case MachineRepresentation::kTaggedPointer:
|
||||
return Ref(HeapType::kExtern, kNullable);
|
||||
return Ref(HeapType::kAny, kNullable);
|
||||
case MachineRepresentation::kSimd128:
|
||||
return Primitive(kS128);
|
||||
default:
|
||||
@ -447,8 +441,6 @@ class ValueType {
|
||||
switch (heap_representation()) {
|
||||
case HeapType::kFunc:
|
||||
return kFuncRefCode;
|
||||
case HeapType::kExtern:
|
||||
return kExternRefCode;
|
||||
case HeapType::kEq:
|
||||
return kEqRefCode;
|
||||
case HeapType::kAny:
|
||||
@ -492,7 +484,6 @@ class ValueType {
|
||||
heap_representation() != HeapType::kData;
|
||||
case kOptRef:
|
||||
return heap_representation() != HeapType::kFunc &&
|
||||
heap_representation() != HeapType::kExtern &&
|
||||
heap_representation() != HeapType::kEq &&
|
||||
heap_representation() != HeapType::kAny;
|
||||
default:
|
||||
@ -576,24 +567,22 @@ constexpr ValueType kWasmI8 = ValueType::Primitive(kI8);
|
||||
constexpr ValueType kWasmI16 = ValueType::Primitive(kI16);
|
||||
constexpr ValueType kWasmVoid = ValueType::Primitive(kVoid);
|
||||
constexpr ValueType kWasmBottom = ValueType::Primitive(kBottom);
|
||||
// Established reference-type proposal shorthands.
|
||||
// Established reference-type and wasm-gc proposal shorthands.
|
||||
constexpr ValueType kWasmFuncRef = ValueType::Ref(HeapType::kFunc, kNullable);
|
||||
constexpr ValueType kWasmExternRef =
|
||||
ValueType::Ref(HeapType::kExtern, kNullable);
|
||||
constexpr ValueType kWasmAnyRef = ValueType::Ref(HeapType::kAny, kNullable);
|
||||
constexpr ValueType kWasmEqRef = ValueType::Ref(HeapType::kEq, kNullable);
|
||||
constexpr ValueType kWasmI31Ref = ValueType::Ref(HeapType::kI31, kNonNullable);
|
||||
constexpr ValueType kWasmDataRef =
|
||||
ValueType::Ref(HeapType::kData, kNonNullable);
|
||||
constexpr ValueType kWasmArrayRef =
|
||||
ValueType::Ref(HeapType::kArray, kNonNullable);
|
||||
constexpr ValueType kWasmAnyRef = ValueType::Ref(HeapType::kAny, kNullable);
|
||||
|
||||
// Constants used by the generic js-to-wasm wrapper.
|
||||
constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1;
|
||||
|
||||
// This is used in wasm.tq.
|
||||
constexpr ValueType kWasmExternNonNullableRef =
|
||||
ValueType::Ref(HeapType::kExtern, kNonNullable);
|
||||
constexpr ValueType kWasmAnyNonNullableRef =
|
||||
ValueType::Ref(HeapType::kAny, kNonNullable);
|
||||
|
||||
#define FOREACH_WASMVALUE_CTYPES(V) \
|
||||
V(kI32, int32_t) \
|
||||
|
@ -37,9 +37,10 @@ enum ValueTypeCode : uint8_t {
|
||||
kI16Code = 0x79,
|
||||
// Current reference types
|
||||
kFuncRefCode = 0x70,
|
||||
kExternRefCode = 0x6f,
|
||||
kAnyRefCode = 0x6f, // aka externref
|
||||
// typed-funcref and GC proposal types
|
||||
kAnyRefCode = 0x6e,
|
||||
// TODO(7748): For backwards compatibility only, remove when able.
|
||||
kAnyRefCodeAlias = 0x6e,
|
||||
kEqRefCode = 0x6d,
|
||||
kOptRefCode = 0x6c,
|
||||
kRefCode = 0x6b,
|
||||
|
@ -1161,7 +1161,8 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
// and anyfunc just becomes an alias for "funcref".
|
||||
type = i::wasm::kWasmFuncRef;
|
||||
} else if (string->StringEquals(v8_str(isolate, "externref"))) {
|
||||
type = i::wasm::kWasmExternRef;
|
||||
// externref is known as anyref as of wasm-gc.
|
||||
type = i::wasm::kWasmAnyRef;
|
||||
} else {
|
||||
thrower.TypeError(
|
||||
"Descriptor property 'element' must be a WebAssembly reference type");
|
||||
@ -1333,7 +1334,7 @@ bool GetValueType(Isolate* isolate, MaybeLocal<Value> maybe,
|
||||
} else if (string->StringEquals(v8_str(isolate, "f64"))) {
|
||||
*type = i::wasm::kWasmF64;
|
||||
} else if (string->StringEquals(v8_str(isolate, "externref"))) {
|
||||
*type = i::wasm::kWasmExternRef;
|
||||
*type = i::wasm::kWasmAnyRef;
|
||||
} else if (enabled_features.has_type_reflection() &&
|
||||
string->StringEquals(v8_str(isolate, "funcref"))) {
|
||||
// The type reflection proposal renames "anyfunc" to "funcref", and makes
|
||||
@ -1496,7 +1497,6 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef: {
|
||||
switch (type.heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kAny: {
|
||||
if (args.Length() < 2) {
|
||||
// When no initial value is provided, we have to use the WebAssembly
|
||||
@ -1713,7 +1713,6 @@ void EncodeExceptionValues(v8::Isolate* isolate,
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (type.heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
case i::wasm::HeapType::kEq:
|
||||
@ -1928,7 +1927,7 @@ void WebAssemblyFunctionType(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
for (size_t i = 0; i < param_count; ++i) {
|
||||
builder.AddParam(sig->GetParam(0));
|
||||
}
|
||||
builder.AddReturn(i::wasm::kWasmExternRef);
|
||||
builder.AddReturn(i::wasm::kWasmAnyRef);
|
||||
sig = builder.Build();
|
||||
}
|
||||
} else if (i::WasmJSFunction::IsWasmJSFunction(*arg0)) {
|
||||
@ -2028,7 +2027,7 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
return_value.Set(old_size);
|
||||
}
|
||||
|
||||
// WebAssembly.Table.get(num) -> JSFunction
|
||||
// WebAssembly.Table.get(num) -> any
|
||||
void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
@ -2058,7 +2057,7 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
return_value.Set(Utils::ToLocal(result));
|
||||
}
|
||||
|
||||
// WebAssembly.Table.set(num, JSFunction)
|
||||
// WebAssembly.Table.set(num, any)
|
||||
void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
@ -2077,28 +2076,23 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
return;
|
||||
}
|
||||
|
||||
i::Handle<i::Object> element;
|
||||
if (args.Length() >= 2) {
|
||||
element = Utils::OpenHandle(*args[1]);
|
||||
} else {
|
||||
element = DefaultReferenceValue(i_isolate, table_object->type());
|
||||
}
|
||||
i::Handle<i::Object> element =
|
||||
args.Length() >= 2
|
||||
? Utils::OpenHandle(*args[1])
|
||||
: DefaultReferenceValue(i_isolate, table_object->type());
|
||||
|
||||
if (!i::WasmTableObject::IsValidElement(i_isolate, table_object, element)) {
|
||||
thrower.TypeError(
|
||||
"Argument 1 must be null or a WebAssembly function of type compatible "
|
||||
"to 'this'");
|
||||
thrower.TypeError("Argument 1 is invalid for table of type %s",
|
||||
table_object->type().name().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(7748): Generalize this if other table types are allowed.
|
||||
bool has_function_type = table_object->type() == i::wasm::kWasmFuncRef ||
|
||||
table_object->type().has_index();
|
||||
if (has_function_type && !element->IsNull()) {
|
||||
element = i::WasmInternalFunction::FromExternal(element, i_isolate)
|
||||
.ToHandleChecked();
|
||||
}
|
||||
i::Handle<i::Object> external_element;
|
||||
bool is_external = i::WasmInternalFunction::FromExternal(element, i_isolate)
|
||||
.ToHandle(&external_element);
|
||||
|
||||
i::WasmTableObject::Set(i_isolate, table_object, index, element);
|
||||
i::WasmTableObject::Set(i_isolate, table_object, index,
|
||||
is_external ? external_element : element);
|
||||
}
|
||||
|
||||
// WebAssembly.Table.type() -> TableType
|
||||
@ -2282,7 +2276,6 @@ void WebAssemblyExceptionGetArg(
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (signature.get(i).heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
case i::wasm::HeapType::kEq:
|
||||
@ -2341,7 +2334,6 @@ void WebAssemblyExceptionGetArg(
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (signature.get(index).heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kFunc:
|
||||
case i::wasm::HeapType::kAny:
|
||||
case i::wasm::HeapType::kEq:
|
||||
@ -2425,7 +2417,6 @@ void WebAssemblyGlobalGetValueCommon(
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (receiver->type().heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kAny:
|
||||
return_value.Set(Utils::ToLocal(receiver->GetRef()));
|
||||
break;
|
||||
@ -2521,7 +2512,6 @@ void WebAssemblyGlobalSetValue(
|
||||
case i::wasm::kRef:
|
||||
case i::wasm::kOptRef:
|
||||
switch (receiver->type().heap_representation()) {
|
||||
case i::wasm::HeapType::kExtern:
|
||||
case i::wasm::HeapType::kAny:
|
||||
receiver->SetExternRef(Utils::OpenHandle(*args[0]));
|
||||
break;
|
||||
@ -2634,10 +2624,9 @@ void WebAssemblySuspenderSuspendOnReturnedPromise(
|
||||
return;
|
||||
}
|
||||
sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
|
||||
if (sig->return_count() != 1 ||
|
||||
sig->GetReturn(0) != i::wasm::kWasmExternRef) {
|
||||
thrower.TypeError(
|
||||
"Expected a WebAssembly.Function with return type externref");
|
||||
if (sig->return_count() != 1 || sig->GetReturn(0) != i::wasm::kWasmAnyRef) {
|
||||
thrower.TypeError("Expected a WebAssembly.Function with return type %s",
|
||||
i::wasm::kWasmAnyRef.name().c_str());
|
||||
}
|
||||
|
||||
auto callable = handle(
|
||||
|
@ -520,7 +520,7 @@ struct WasmTable {
|
||||
static bool IsValidTableType(ValueType type, const WasmModule* module) {
|
||||
if (!type.is_object_reference()) return false;
|
||||
HeapType heap_type = type.heap_type();
|
||||
return heap_type == HeapType::kFunc || heap_type == HeapType::kExtern ||
|
||||
return heap_type == HeapType::kFunc || heap_type == HeapType::kAny ||
|
||||
(module != nullptr && heap_type.is_index() &&
|
||||
module->has_signature(heap_type.ref_index()));
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ void WasmGlobalObject::set_type(wasm::ValueType value) {
|
||||
int WasmGlobalObject::type_size() const { return type().element_size_bytes(); }
|
||||
|
||||
Address WasmGlobalObject::address() const {
|
||||
DCHECK_NE(type(), wasm::kWasmExternRef);
|
||||
DCHECK_NE(type(), wasm::kWasmAnyRef);
|
||||
DCHECK_LE(offset() + type_size(), untagged_buffer().byte_length());
|
||||
return Address(untagged_buffer().backing_store()) + offset();
|
||||
}
|
||||
@ -167,8 +167,7 @@ void WasmGlobalObject::SetF64(double value) {
|
||||
}
|
||||
|
||||
void WasmGlobalObject::SetExternRef(Handle<Object> value) {
|
||||
DCHECK(type().is_reference_to(wasm::HeapType::kExtern) ||
|
||||
type().is_reference_to(wasm::HeapType::kAny));
|
||||
DCHECK(type().is_reference_to(wasm::HeapType::kAny));
|
||||
tagged_buffer().set(offset(), *value);
|
||||
}
|
||||
|
||||
|
@ -380,7 +380,6 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
|
||||
int entry_index = static_cast<int>(index);
|
||||
|
||||
switch (table->type().heap_representation()) {
|
||||
case wasm::HeapType::kExtern:
|
||||
case wasm::HeapType::kAny:
|
||||
entries->set(entry_index, *entry);
|
||||
return;
|
||||
@ -423,7 +422,7 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
}
|
||||
|
||||
switch (table->type().heap_representation()) {
|
||||
case wasm::HeapType::kExtern:
|
||||
case wasm::HeapType::kAny:
|
||||
return entry;
|
||||
case wasm::HeapType::kFunc:
|
||||
if (entry->IsWasmInternalFunction()) return entry;
|
||||
@ -432,7 +431,6 @@ Handle<Object> WasmTableObject::Get(Isolate* isolate,
|
||||
case wasm::HeapType::kI31:
|
||||
case wasm::HeapType::kData:
|
||||
case wasm::HeapType::kArray:
|
||||
case wasm::HeapType::kAny:
|
||||
// TODO(7748): Implement once we have a story for struct/arrays/i31ref in
|
||||
// JS.
|
||||
UNIMPLEMENTED();
|
||||
@ -2170,7 +2168,7 @@ bool WasmJSFunction::MatchesSignatureForSuspend(const wasm::FunctionSig* sig) {
|
||||
// This function is only called for functions wrapped by a
|
||||
// WebAssembly.Suspender object, so the return type has to be externref.
|
||||
CHECK_EQ(function_data.serialized_return_count(), 1);
|
||||
CHECK_EQ(function_data.serialized_signature().get(0), wasm::kWasmExternRef);
|
||||
CHECK_EQ(function_data.serialized_signature().get(0), wasm::kWasmAnyRef);
|
||||
const wasm::ValueType* expected = sig->all().begin();
|
||||
return function_data.serialized_signature().matches(
|
||||
1, expected + return_count, parameter_count);
|
||||
@ -2205,9 +2203,6 @@ bool WasmExternalFunction::IsWasmExternalFunction(Object object) {
|
||||
// static
|
||||
MaybeHandle<WasmInternalFunction> WasmInternalFunction::FromExternal(
|
||||
Handle<Object> external, Isolate* isolate) {
|
||||
if (external->IsNull(isolate)) {
|
||||
return MaybeHandle<WasmInternalFunction>();
|
||||
}
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(*external) ||
|
||||
WasmJSFunction::IsWasmJSFunction(*external) ||
|
||||
WasmCapiFunction::IsWasmCapiFunction(*external)) {
|
||||
@ -2216,7 +2211,6 @@ MaybeHandle<WasmInternalFunction> WasmInternalFunction::FromExternal(
|
||||
kAcquireLoad));
|
||||
return handle(data.internal(), isolate);
|
||||
}
|
||||
// {external} is not null or a wasm external function.
|
||||
return MaybeHandle<WasmInternalFunction>();
|
||||
}
|
||||
|
||||
@ -2271,7 +2265,6 @@ bool TypecheckJSObject(Isolate* isolate, const WasmModule* module,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case HeapType::kExtern:
|
||||
case HeapType::kAny:
|
||||
return true;
|
||||
case HeapType::kData:
|
||||
|
@ -774,7 +774,7 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
|
||||
V(l_ill, kWasmI64, kWasmI32, kWasmI64, kWasmI64) \
|
||||
V(i_iil, kWasmI32, kWasmI32, kWasmI32, kWasmI64) \
|
||||
V(i_ill, kWasmI32, kWasmI32, kWasmI64, kWasmI64) \
|
||||
V(i_e, kWasmI32, kWasmExternRef) \
|
||||
V(i_a, kWasmI32, kWasmAnyRef) \
|
||||
V(i_ci, kWasmI32, kWasmFuncRef, kWasmI32) \
|
||||
V(i_qq, kWasmI32, kWasmEqRef, kWasmEqRef)
|
||||
|
||||
|
@ -170,7 +170,9 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
|
||||
|
||||
switch (sub_heap.representation()) {
|
||||
case HeapType::kFunc:
|
||||
case HeapType::kExtern:
|
||||
// funcref is a subtype of anyref (aka externref) under wasm-gc.
|
||||
return sub_heap == super_heap ||
|
||||
(FLAG_experimental_wasm_gc && super_heap == HeapType::kAny);
|
||||
case HeapType::kEq:
|
||||
return sub_heap == super_heap || super_heap == HeapType::kAny;
|
||||
case HeapType::kAny:
|
||||
@ -200,7 +202,6 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
|
||||
return !sub_module->has_signature(sub_index);
|
||||
case HeapType::kArray:
|
||||
return sub_module->has_array(sub_index);
|
||||
case HeapType::kExtern:
|
||||
case HeapType::kI31:
|
||||
return false;
|
||||
case HeapType::kAny:
|
||||
|
@ -431,7 +431,7 @@ TEST(Liftoff_debug_side_table_catch_all) {
|
||||
LiftoffCompileEnvironment env;
|
||||
TestSignatures sigs;
|
||||
int ex = env.builder()->AddException(sigs.v_v());
|
||||
ValueType exception_type = ValueType::Ref(HeapType::kExtern, kNonNullable);
|
||||
ValueType exception_type = ValueType::Ref(HeapType::kAny, kNonNullable);
|
||||
auto debug_side_table = env.GenerateDebugSideTable(
|
||||
{}, {kWasmI32},
|
||||
{WASM_TRY_CATCH_ALL_T(kWasmI32, WASM_STMTS(WASM_I32V(0), WASM_THROW(ex)),
|
||||
@ -456,7 +456,7 @@ TEST(Liftoff_debug_side_table_catch_all) {
|
||||
TEST(Regress1199526) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(eh);
|
||||
LiftoffCompileEnvironment env;
|
||||
ValueType exception_type = ValueType::Ref(HeapType::kExtern, kNonNullable);
|
||||
ValueType exception_type = ValueType::Ref(HeapType::kAny, kNonNullable);
|
||||
auto debug_side_table = env.GenerateDebugSideTable(
|
||||
{}, {},
|
||||
{kExprTry, kVoidCode, kExprCallFunction, 0, kExprCatchAll, kExprLoop,
|
||||
|
@ -348,20 +348,19 @@ TEST(MemoryGrowInvalidSize) {
|
||||
TEST(ReferenceTypeLocals) {
|
||||
{
|
||||
WasmRunner<int32_t> r(TestExecutionTier::kInterpreter);
|
||||
BUILD(r, WASM_REF_IS_NULL(WASM_REF_NULL(kExternRefCode)));
|
||||
BUILD(r, WASM_REF_IS_NULL(WASM_REF_NULL(kAnyRefCode)));
|
||||
CHECK_EQ(1, r.Call());
|
||||
}
|
||||
{
|
||||
WasmRunner<int32_t> r(TestExecutionTier::kInterpreter);
|
||||
r.AllocateLocal(kWasmExternRef);
|
||||
r.AllocateLocal(kWasmAnyRef);
|
||||
BUILD(r, WASM_REF_IS_NULL(WASM_LOCAL_GET(0)));
|
||||
CHECK_EQ(1, r.Call());
|
||||
}
|
||||
{
|
||||
WasmRunner<int32_t> r(TestExecutionTier::kInterpreter);
|
||||
r.AllocateLocal(kWasmExternRef);
|
||||
BUILD(r,
|
||||
WASM_REF_IS_NULL(WASM_LOCAL_TEE(0, WASM_REF_NULL(kExternRefCode))));
|
||||
r.AllocateLocal(kWasmAnyRef);
|
||||
BUILD(r, WASM_REF_IS_NULL(WASM_LOCAL_TEE(0, WASM_REF_NULL(kAnyRefCode))));
|
||||
CHECK_EQ(1, r.Call());
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ class TestSignatures {
|
||||
sig_i_ff(1, 2, kIntFloatTypes4),
|
||||
sig_i_d(1, 1, kIntDoubleTypes4),
|
||||
sig_i_dd(1, 2, kIntDoubleTypes4),
|
||||
sig_i_e(1, 1, kIntExternRefTypes4),
|
||||
sig_i_ee(1, 2, kIntExternRefTypes4),
|
||||
sig_i_a(1, 1, kIntAnyRefTypes4),
|
||||
sig_i_aa(1, 2, kIntAnyRefTypes4),
|
||||
sig_i_c(1, 1, kIntFuncRefTypes4),
|
||||
sig_i_s(1, 1, kIntSimd128Types4),
|
||||
sig_l_v(1, 0, kLongTypes4),
|
||||
@ -37,15 +37,15 @@ class TestSignatures {
|
||||
sig_f_ff(1, 2, kFloatTypes4),
|
||||
sig_d_d(1, 1, kDoubleTypes4),
|
||||
sig_d_dd(1, 2, kDoubleTypes4),
|
||||
sig_e_v(1, 0, kExternRefTypes4),
|
||||
sig_a_v(1, 0, kAnyRefTypes4),
|
||||
sig_c_v(1, 0, kFuncTypes4),
|
||||
sig_e_e(1, 1, kExternRefTypes4),
|
||||
sig_a_a(1, 1, kAnyRefTypes4),
|
||||
sig_c_c(1, 1, kFuncTypes4),
|
||||
sig_v_v(0, 0, kIntTypes4),
|
||||
sig_v_i(0, 1, kIntTypes4),
|
||||
sig_v_ii(0, 2, kIntTypes4),
|
||||
sig_v_iii(0, 3, kIntTypes4),
|
||||
sig_v_e(0, 1, kExternRefTypes4),
|
||||
sig_v_a(0, 1, kAnyRefTypes4),
|
||||
sig_v_c(0, 1, kFuncTypes4),
|
||||
sig_v_d(0, 1, kDoubleTypes4),
|
||||
sig_s_i(1, 1, kSimd128IntTypes4),
|
||||
@ -58,12 +58,12 @@ class TestSignatures {
|
||||
for (int i = 0; i < 4; i++) kLongTypes4[i] = kWasmI64;
|
||||
for (int i = 0; i < 4; i++) kFloatTypes4[i] = kWasmF32;
|
||||
for (int i = 0; i < 4; i++) kDoubleTypes4[i] = kWasmF64;
|
||||
for (int i = 0; i < 4; i++) kExternRefTypes4[i] = kWasmExternRef;
|
||||
for (int i = 0; i < 4; i++) kAnyRefTypes4[i] = kWasmAnyRef;
|
||||
for (int i = 0; i < 4; i++) kFuncTypes4[i] = kWasmFuncRef;
|
||||
for (int i = 1; i < 4; i++) kIntLongTypes4[i] = kWasmI64;
|
||||
for (int i = 1; i < 4; i++) kIntFloatTypes4[i] = kWasmF32;
|
||||
for (int i = 1; i < 4; i++) kIntDoubleTypes4[i] = kWasmF64;
|
||||
for (int i = 1; i < 4; i++) kIntExternRefTypes4[i] = kWasmExternRef;
|
||||
for (int i = 1; i < 4; i++) kIntAnyRefTypes4[i] = kWasmAnyRef;
|
||||
for (int i = 1; i < 4; i++) kIntFuncRefTypes4[i] = kWasmFuncRef;
|
||||
for (int i = 0; i < 4; i++) kSimd128Types4[i] = kWasmS128;
|
||||
for (int i = 1; i < 4; i++) kIntSimd128Types4[i] = kWasmS128;
|
||||
@ -71,7 +71,7 @@ class TestSignatures {
|
||||
kIntLongTypes4[0] = kWasmI32;
|
||||
kIntFloatTypes4[0] = kWasmI32;
|
||||
kIntDoubleTypes4[0] = kWasmI32;
|
||||
kIntExternRefTypes4[0] = kWasmI32;
|
||||
kIntAnyRefTypes4[0] = kWasmI32;
|
||||
kIntFuncRefTypes4[0] = kWasmI32;
|
||||
kIntSimd128Types4[0] = kWasmI32;
|
||||
kSimd128IntTypes4[1] = kWasmI32;
|
||||
@ -91,8 +91,8 @@ class TestSignatures {
|
||||
FunctionSig* l_l() { return &sig_l_l; }
|
||||
FunctionSig* l_ll() { return &sig_l_ll; }
|
||||
FunctionSig* i_ll() { return &sig_i_ll; }
|
||||
FunctionSig* i_e() { return &sig_i_e; }
|
||||
FunctionSig* i_ee() { return &sig_i_ee; }
|
||||
FunctionSig* i_a() { return &sig_i_a; }
|
||||
FunctionSig* i_aa() { return &sig_i_aa; }
|
||||
FunctionSig* i_c() { return &sig_i_c; }
|
||||
FunctionSig* i_s() { return &sig_i_s; }
|
||||
|
||||
@ -101,16 +101,16 @@ class TestSignatures {
|
||||
FunctionSig* d_d() { return &sig_d_d; }
|
||||
FunctionSig* d_dd() { return &sig_d_dd; }
|
||||
|
||||
FunctionSig* e_v() { return &sig_e_v; }
|
||||
FunctionSig* a_v() { return &sig_a_v; }
|
||||
FunctionSig* c_v() { return &sig_c_v; }
|
||||
FunctionSig* e_e() { return &sig_e_e; }
|
||||
FunctionSig* a_a() { return &sig_a_a; }
|
||||
FunctionSig* c_c() { return &sig_c_c; }
|
||||
|
||||
FunctionSig* v_v() { return &sig_v_v; }
|
||||
FunctionSig* v_i() { return &sig_v_i; }
|
||||
FunctionSig* v_ii() { return &sig_v_ii; }
|
||||
FunctionSig* v_iii() { return &sig_v_iii; }
|
||||
FunctionSig* v_e() { return &sig_v_e; }
|
||||
FunctionSig* v_a() { return &sig_v_a; }
|
||||
FunctionSig* v_c() { return &sig_v_c; }
|
||||
FunctionSig* v_d() { return &sig_v_d; }
|
||||
FunctionSig* s_i() { return &sig_s_i; }
|
||||
@ -134,12 +134,12 @@ class TestSignatures {
|
||||
ValueType kLongTypes4[4];
|
||||
ValueType kFloatTypes4[4];
|
||||
ValueType kDoubleTypes4[4];
|
||||
ValueType kExternRefTypes4[4];
|
||||
ValueType kAnyRefTypes4[4];
|
||||
ValueType kFuncTypes4[4];
|
||||
ValueType kIntLongTypes4[4];
|
||||
ValueType kIntFloatTypes4[4];
|
||||
ValueType kIntDoubleTypes4[4];
|
||||
ValueType kIntExternRefTypes4[4];
|
||||
ValueType kIntAnyRefTypes4[4];
|
||||
ValueType kIntFuncRefTypes4[4];
|
||||
ValueType kSimd128Types4[4];
|
||||
ValueType kIntSimd128Types4[4];
|
||||
@ -154,8 +154,8 @@ class TestSignatures {
|
||||
FunctionSig sig_i_ff;
|
||||
FunctionSig sig_i_d;
|
||||
FunctionSig sig_i_dd;
|
||||
FunctionSig sig_i_e;
|
||||
FunctionSig sig_i_ee;
|
||||
FunctionSig sig_i_a;
|
||||
FunctionSig sig_i_aa;
|
||||
FunctionSig sig_i_c;
|
||||
FunctionSig sig_i_s;
|
||||
|
||||
@ -169,16 +169,16 @@ class TestSignatures {
|
||||
FunctionSig sig_d_d;
|
||||
FunctionSig sig_d_dd;
|
||||
|
||||
FunctionSig sig_e_v;
|
||||
FunctionSig sig_a_v;
|
||||
FunctionSig sig_c_v;
|
||||
FunctionSig sig_e_e;
|
||||
FunctionSig sig_a_a;
|
||||
FunctionSig sig_c_c;
|
||||
|
||||
FunctionSig sig_v_v;
|
||||
FunctionSig sig_v_i;
|
||||
FunctionSig sig_v_ii;
|
||||
FunctionSig sig_v_iii;
|
||||
FunctionSig sig_v_e;
|
||||
FunctionSig sig_v_a;
|
||||
FunctionSig sig_v_c;
|
||||
FunctionSig sig_v_d;
|
||||
FunctionSig sig_s_i;
|
||||
|
@ -210,7 +210,7 @@
|
||||
#define WASM_SELECT_D(tval, fval, cond) \
|
||||
tval, fval, cond, kExprSelectWithType, U32V_1(1), kF64Code
|
||||
#define WASM_SELECT_R(tval, fval, cond) \
|
||||
tval, fval, cond, kExprSelectWithType, U32V_1(1), kExternRefCode
|
||||
tval, fval, cond, kExprSelectWithType, U32V_1(1), kAnyRefCode
|
||||
#define WASM_SELECT_A(tval, fval, cond) \
|
||||
tval, fval, cond, kExprSelectWithType, U32V_1(1), kFuncRefCode
|
||||
|
||||
|
@ -130,7 +130,7 @@ ValueType GetValueTypeHelper(DataRange* data, bool liftoff_as_reference,
|
||||
const bool nullable =
|
||||
(allow_non_nullable == kAllowNonNullables) ? data->get<bool>() : true;
|
||||
if (nullable) {
|
||||
types.insert(types.end(), {kWasmI31Ref, kWasmExternRef, kWasmFuncRef});
|
||||
types.insert(types.end(), {kWasmI31Ref, kWasmFuncRef});
|
||||
}
|
||||
if (include_generics == kIncludeGenerics) {
|
||||
types.insert(types.end(), {kWasmDataRef, kWasmAnyRef, kWasmEqRef});
|
||||
@ -974,10 +974,7 @@ class WasmGenerator {
|
||||
table_op<kVoid>({kWasmI32, kWasmFuncRef, kWasmI32}, data, kExprTableFill);
|
||||
}
|
||||
void table_copy(DataRange* data) {
|
||||
ValueType needed_type =
|
||||
data->get<bool>()
|
||||
? ValueType::Ref(HeapType(HeapType::kFunc), kNullable)
|
||||
: ValueType::Ref(HeapType(HeapType::kExtern), kNullable);
|
||||
ValueType needed_type = data->get<bool>() ? kWasmFuncRef : kWasmAnyRef;
|
||||
int table_count = builder_->builder()->NumTables();
|
||||
ZoneVector<uint32_t> table(builder_->builder()->zone());
|
||||
for (int i = 0; i < table_count; i++) {
|
||||
@ -2083,7 +2080,7 @@ void WasmGenerator::GenerateRef(HeapType type, DataRange* data,
|
||||
&WasmGenerator::new_object, &WasmGenerator::get_local_ref,
|
||||
&WasmGenerator::array_get_ref, &WasmGenerator::struct_get_ref};
|
||||
|
||||
constexpr GenerateFnWithHeap alternatives_func_extern[] = {
|
||||
constexpr GenerateFnWithHeap alternatives_func_any[] = {
|
||||
&WasmGenerator::table_get, &WasmGenerator::get_local_ref,
|
||||
&WasmGenerator::array_get_ref, &WasmGenerator::struct_get_ref};
|
||||
|
||||
@ -2094,46 +2091,43 @@ void WasmGenerator::GenerateRef(HeapType type, DataRange* data,
|
||||
switch (type.representation()) {
|
||||
// For abstract types, sometimes generate one of their subtypes.
|
||||
case HeapType::kAny: {
|
||||
// Note: It is possible we land here even without {liftoff_as_reference_},
|
||||
// because we use anyref as a supertype of all reference types. Therefore,
|
||||
// we have to generate the correct subtypes based on the value of
|
||||
// {liftoff_as_reference_}.
|
||||
// Weighed according to the types in the module. If there are D data types
|
||||
// and F function types, the relative frequencies for dataref is D, for
|
||||
// funcref F, for externref 1, for i31ref 2 if {liftoff_as_reference_}
|
||||
// otherwise 0, and for falling back to anyref 2 or 0.
|
||||
// Note: It is possible we land here even without {liftoff_as_reference_}.
|
||||
// In this case, we do not support any subtyping, and just fall back to
|
||||
// directly generating anyref.
|
||||
if (!liftoff_as_reference_) {
|
||||
DCHECK(nullability);
|
||||
GenerateOneOf(alternatives_func_any, type, data, nullability);
|
||||
return;
|
||||
}
|
||||
// Weighed according to the types in the module:
|
||||
// If there are D data types and F function types, the relative
|
||||
// frequencies for dataref is D, for funcref F, and for i31ref and falling
|
||||
// back to anyref 2.
|
||||
const uint8_t num_data_types = num_structs_ + num_arrays_;
|
||||
const uint8_t num_function_types = functions_.size();
|
||||
const uint8_t emit_externref = (nullability == kNullable) ? 1 : 0;
|
||||
const uint8_t emit_i31ref = liftoff_as_reference_ ? 2 : 0;
|
||||
const uint8_t fallback_to_anyref = liftoff_as_reference_ ? 2 : 0;
|
||||
uint8_t random = data->get<uint8_t>() %
|
||||
(num_data_types + num_function_types + emit_externref +
|
||||
emit_i31ref + fallback_to_anyref);
|
||||
const uint8_t emit_i31ref = 2;
|
||||
const uint8_t fallback_to_anyref = 2;
|
||||
uint8_t random =
|
||||
data->get<uint8_t>() % (num_data_types + num_function_types +
|
||||
emit_i31ref + fallback_to_anyref);
|
||||
// We have to compute this first so in case GenerateOneOf fails
|
||||
// we will continue to fall back on an alternative that is guaranteed
|
||||
// to generate a value of the wanted type.
|
||||
// In order to know which alternative to fall back to in case
|
||||
// GenerateOneOf failed, the random variable is recomputed.
|
||||
if (random >=
|
||||
num_data_types + num_function_types + emit_externref + emit_i31ref) {
|
||||
if (random >= num_data_types + num_function_types + emit_i31ref) {
|
||||
DCHECK(liftoff_as_reference_);
|
||||
if (GenerateOneOf(alternatives_other, type, data, nullability)) {
|
||||
if (GenerateOneOf(alternatives_func_any, type, data, nullability)) {
|
||||
return;
|
||||
}
|
||||
random = data->get<uint8_t>() % (num_data_types + num_function_types +
|
||||
emit_externref + emit_i31ref);
|
||||
random = data->get<uint8_t>() %
|
||||
(num_data_types + num_function_types + emit_i31ref);
|
||||
}
|
||||
if (random < num_data_types) {
|
||||
DCHECK(liftoff_as_reference_);
|
||||
GenerateRef(HeapType(HeapType::kData), data, nullability);
|
||||
} else if (random < num_data_types + num_function_types) {
|
||||
GenerateRef(HeapType(HeapType::kFunc), data, nullability);
|
||||
} else if (random <
|
||||
num_data_types + num_function_types + emit_externref) {
|
||||
GenerateRef(HeapType(HeapType::kExtern), data, nullability);
|
||||
} else {
|
||||
DCHECK(liftoff_as_reference_);
|
||||
GenerateRef(HeapType(HeapType::kI31), data, nullability);
|
||||
}
|
||||
return;
|
||||
@ -2190,17 +2184,12 @@ void WasmGenerator::GenerateRef(HeapType type, DataRange* data,
|
||||
}
|
||||
return;
|
||||
}
|
||||
case HeapType::kExtern: {
|
||||
DCHECK(nullability);
|
||||
GenerateOneOf(alternatives_func_extern, type, data, nullability);
|
||||
return;
|
||||
}
|
||||
case HeapType::kFunc: {
|
||||
uint32_t random = data->get<uint32_t>() % (functions_.size() + 1);
|
||||
/// Try generating one of the alternatives
|
||||
// and continue to the rest of the methods in case it fails.
|
||||
if (random >= functions_.size()) {
|
||||
if (GenerateOneOf(alternatives_func_extern, type, data, nullability)) {
|
||||
if (GenerateOneOf(alternatives_func_any, type, data, nullability)) {
|
||||
return;
|
||||
}
|
||||
random = data->get<uint32_t>() % functions_.size();
|
||||
@ -2587,7 +2576,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
// other table indices.
|
||||
// TODO(11954): Support typed function tables.
|
||||
bool use_funcref = i == 0 || range.get<bool>();
|
||||
ValueType type = use_funcref ? kWasmFuncRef : kWasmExternRef;
|
||||
ValueType type = use_funcref ? kWasmFuncRef : kWasmAnyRef;
|
||||
uint32_t table_index = builder.AddTable(type, min_size, max_size);
|
||||
if (type == kWasmFuncRef) {
|
||||
// For function tables, initialize them with functions from the program.
|
||||
|
@ -211,8 +211,6 @@ std::string HeapTypeToConstantName(HeapType heap_type) {
|
||||
switch (heap_type.representation()) {
|
||||
case HeapType::kFunc:
|
||||
return "kWasmFuncRef";
|
||||
case HeapType::kExtern:
|
||||
return "kWasmExternRef";
|
||||
case HeapType::kEq:
|
||||
return "kWasmEqRef";
|
||||
case HeapType::kI31:
|
||||
@ -248,8 +246,6 @@ std::string ValueTypeToConstantName(ValueType type) {
|
||||
return "kWasmS128";
|
||||
case kOptRef:
|
||||
switch (type.heap_representation()) {
|
||||
case HeapType::kExtern:
|
||||
return "kWasmExternRef";
|
||||
case HeapType::kFunc:
|
||||
return "kWasmFuncRef";
|
||||
case HeapType::kEq:
|
||||
|
@ -715,18 +715,18 @@ assertThrows(
|
||||
/must be convertible to a valid number/);
|
||||
assertThrows(
|
||||
() => set.call(tbl1, 0, undefined), TypeError,
|
||||
/must be null or a WebAssembly function/);
|
||||
/Argument 1 is invalid for table of type funcref/);
|
||||
assertThrows(
|
||||
() => set.call(tbl1, undefined, undefined), TypeError,
|
||||
/must be convertible to a valid number/);
|
||||
assertThrows(
|
||||
() => set.call(tbl1, 0, {}), TypeError,
|
||||
/must be null or a WebAssembly function/);
|
||||
assertThrows(() => set.call(tbl1, 0, function() {
|
||||
}), TypeError, /must be null or a WebAssembly function/);
|
||||
/Argument 1 is invalid for table of type funcref/);
|
||||
assertThrows(() => set.call(tbl1, 0, function() {}),
|
||||
TypeError, /Argument 1 is invalid for table of type funcref/);
|
||||
assertThrows(
|
||||
() => set.call(tbl1, 0, Math.sin), TypeError,
|
||||
/must be null or a WebAssembly function/);
|
||||
/Argument 1 is invalid for table of type funcref/);
|
||||
assertThrows(
|
||||
() => set.call(tbl1, {valueOf() { throw Error('hai') }}, null), Error,
|
||||
'hai');
|
||||
|
@ -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: --experimental-wasm-typed-funcref
|
||||
// Flags: --experimental-wasm-gc
|
||||
|
||||
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
/* TODO(7748): Implement cross-module subtyping.
|
||||
@ -144,3 +144,67 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
assertEquals(44, instance.exports.table_test(0, 33, 11));
|
||||
assertEquals(22, instance.exports.table_test(1, 33, 11));
|
||||
})();
|
||||
|
||||
(function TestAnyRefTable() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
||||
let unary_type = builder.addType(kSig_i_i);
|
||||
let binary_type = builder.addType(kSig_i_ii);
|
||||
let struct_type = builder.addStruct([makeField(kWasmI32, false)]);
|
||||
|
||||
let successor = builder.addFunction('addition', unary_type)
|
||||
.addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add]);
|
||||
|
||||
let subtraction = builder.addFunction('subtraction', binary_type)
|
||||
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Sub])
|
||||
|
||||
let table = builder.addTable(kWasmAnyRef, 4, 4);
|
||||
builder.addActiveElementSegment(
|
||||
table, WasmInitExpr.I32Const(0),
|
||||
[WasmInitExpr.RefFunc(successor.index),
|
||||
WasmInitExpr.RefFunc(subtraction.index),
|
||||
WasmInitExpr.StructNew(struct_type, [WasmInitExpr.I32Const(10)]),
|
||||
WasmInitExpr.RefNull(kWasmEqRef)],
|
||||
kWasmAnyRef);
|
||||
|
||||
// return static_cast<i->i>(table[0])(local_0)
|
||||
builder.addFunction("f0_getter", kSig_i_i)
|
||||
.addBody([
|
||||
kExprLocalGet, 0,
|
||||
kExprI32Const, 0, kExprTableGet, 0,
|
||||
kGCPrefix, kExprRefAsFunc, kGCPrefix, kExprRefCastStatic, unary_type,
|
||||
kExprCallRef])
|
||||
.exportFunc();
|
||||
|
||||
// return static_cast<(i,i)->i>(table[1])(local_0, local_1)
|
||||
builder.addFunction("f1_getter", kSig_i_ii)
|
||||
.addBody([
|
||||
kExprLocalGet, 0, kExprLocalGet, 1,
|
||||
kExprI32Const, 1, kExprTableGet, 0,
|
||||
kGCPrefix, kExprRefAsFunc, kGCPrefix, kExprRefCastStatic, binary_type,
|
||||
kExprCallRef])
|
||||
.exportFunc();
|
||||
|
||||
// return static_cast<struct_type>(table[2]).field_0
|
||||
builder.addFunction("struct_getter", kSig_i_v)
|
||||
.addBody([
|
||||
kExprI32Const, 2, kExprTableGet, 0,
|
||||
kGCPrefix, kExprRefAsData, kGCPrefix, kExprRefCastStatic, struct_type,
|
||||
kGCPrefix, kExprStructGet, struct_type, 0])
|
||||
.exportFunc();
|
||||
|
||||
// return table[3] == null
|
||||
builder.addFunction("null_getter", kSig_i_v)
|
||||
.addBody([kExprI32Const, 3, kExprTableGet, 0, kExprRefIsNull])
|
||||
.exportFunc();
|
||||
|
||||
let instance = builder.instantiate({});
|
||||
|
||||
assertTrue(!!instance);
|
||||
|
||||
assertEquals(43, instance.exports.f0_getter(42));
|
||||
assertEquals(-7, instance.exports.f1_getter(12, 19));
|
||||
assertEquals(10, instance.exports.struct_getter());
|
||||
assertEquals(1, instance.exports.null_getter());
|
||||
})();
|
||||
|
@ -120,8 +120,8 @@ let kWasmI16 = 0x79;
|
||||
// indices.
|
||||
let kWasmFuncRef = -0x10;
|
||||
let kWasmAnyFunc = kWasmFuncRef; // Alias named as in the JS API spec
|
||||
let kWasmExternRef = -0x11;
|
||||
let kWasmAnyRef = -0x12;
|
||||
let kWasmAnyRef = -0x11;
|
||||
let kWasmExternRef = kWasmAnyRef; // Alias for test backwards compatibility.
|
||||
let kWasmEqRef = -0x13;
|
||||
let kWasmI31Ref = -0x16;
|
||||
let kWasmDataRef = -0x19;
|
||||
|
@ -48,7 +48,7 @@ static const byte kCodeSetLocal0[] = {WASM_LOCAL_SET(0, WASM_ZERO)};
|
||||
static const byte kCodeTeeLocal0[] = {WASM_LOCAL_TEE(0, WASM_ZERO)};
|
||||
|
||||
static const ValueType kValueTypes[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
|
||||
kWasmExternRef};
|
||||
kWasmAnyRef};
|
||||
static const MachineType machineTypes[] = {
|
||||
MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
|
||||
MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
|
||||
@ -1723,8 +1723,8 @@ TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) {
|
||||
TEST_F(FunctionBodyDecoderTest, ReturnCallWithSubtype) {
|
||||
WASM_FEATURE_SCOPE(return_call);
|
||||
|
||||
auto sig = MakeSig::Returns(kWasmExternRef);
|
||||
auto callee_sig = MakeSig::Returns(kWasmExternNonNullableRef);
|
||||
auto sig = MakeSig::Returns(kWasmAnyRef);
|
||||
auto callee_sig = MakeSig::Returns(kWasmAnyNonNullableRef);
|
||||
builder.AddFunction(&callee_sig);
|
||||
|
||||
ExpectValidates(&sig, {WASM_RETURN_CALL_FUNCTION0(0)});
|
||||
@ -1946,7 +1946,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs2) {
|
||||
"call_indirect: Immediate signature #1 is not a subtype of "
|
||||
"immediate table #0");
|
||||
|
||||
byte non_function_table_index = builder.InitializeTable(kWasmExternRef);
|
||||
byte non_function_table_index = builder.InitializeTable(kWasmAnyRef);
|
||||
ExpectFailure(
|
||||
sigs.i_v(),
|
||||
{WASM_CALL_INDIRECT_TABLE(non_function_table_index, table_type_index,
|
||||
@ -2180,14 +2180,14 @@ TEST_F(FunctionBodyDecoderTest, TableSet) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
|
||||
byte tab_type = builder.AddSignature(sigs.i_i());
|
||||
byte tab_ref1 = builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
byte tab_ref1 = builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
byte tab_func1 = builder.AddTable(kWasmFuncRef, 20, true, 30);
|
||||
byte tab_func2 = builder.AddTable(kWasmFuncRef, 10, false, 20);
|
||||
byte tab_ref2 = builder.AddTable(kWasmExternRef, 10, false, 20);
|
||||
byte tab_ref2 = builder.AddTable(kWasmAnyRef, 10, false, 20);
|
||||
byte tab_typed_func =
|
||||
builder.AddTable(ValueType::Ref(tab_type, kNullable), 10, false, 20);
|
||||
|
||||
ValueType sig_types[]{kWasmExternRef, kWasmFuncRef, kWasmI32,
|
||||
ValueType sig_types[]{kWasmAnyRef, kWasmFuncRef, kWasmI32,
|
||||
ValueType::Ref(tab_type, kNonNullable)};
|
||||
FunctionSig sig(0, 4, sig_types);
|
||||
byte local_ref = 0;
|
||||
@ -2236,14 +2236,14 @@ TEST_F(FunctionBodyDecoderTest, TableGet) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
|
||||
byte tab_type = builder.AddSignature(sigs.i_i());
|
||||
byte tab_ref1 = builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
byte tab_ref1 = builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
byte tab_func1 = builder.AddTable(kWasmFuncRef, 20, true, 30);
|
||||
byte tab_func2 = builder.AddTable(kWasmFuncRef, 10, false, 20);
|
||||
byte tab_ref2 = builder.AddTable(kWasmExternRef, 10, false, 20);
|
||||
byte tab_ref2 = builder.AddTable(kWasmAnyRef, 10, false, 20);
|
||||
byte tab_typed_func =
|
||||
builder.AddTable(ValueType::Ref(tab_type, kNullable), 10, false, 20);
|
||||
|
||||
ValueType sig_types[]{kWasmExternRef, kWasmFuncRef, kWasmI32,
|
||||
ValueType sig_types[]{kWasmAnyRef, kWasmFuncRef, kWasmI32,
|
||||
ValueType::Ref(tab_type, kNullable)};
|
||||
FunctionSig sig(0, 4, sig_types);
|
||||
byte local_ref = 0;
|
||||
@ -2300,10 +2300,10 @@ TEST_F(FunctionBodyDecoderTest, TableGet) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MultiTableCallIndirect) {
|
||||
byte tab_ref = builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
byte tab_ref = builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
byte tab_func = builder.AddTable(kWasmFuncRef, 20, true, 30);
|
||||
|
||||
ValueType sig_types[]{kWasmExternRef, kWasmFuncRef, kWasmI32};
|
||||
ValueType sig_types[]{kWasmAnyRef, kWasmFuncRef, kWasmI32};
|
||||
FunctionSig sig(0, 3, sig_types);
|
||||
byte sig_index = builder.AddSignature(sigs.i_v());
|
||||
|
||||
@ -2849,7 +2849,7 @@ TEST_F(FunctionBodyDecoderTest, Select) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, Select_needs_value_type) {
|
||||
ExpectFailure(sigs.e_e(),
|
||||
ExpectFailure(sigs.a_a(),
|
||||
{WASM_SELECT(WASM_LOCAL_GET(0), WASM_LOCAL_GET(0), WASM_ZERO)});
|
||||
ExpectFailure(sigs.c_c(),
|
||||
{WASM_SELECT(WASM_LOCAL_GET(0), WASM_LOCAL_GET(0), WASM_ZERO)});
|
||||
@ -2869,7 +2869,7 @@ TEST_F(FunctionBodyDecoderTest, Select_fail2) {
|
||||
ValueType type = kValueTypes[i];
|
||||
if (type == kWasmI32) continue;
|
||||
// Select without specified type is only allowed for number types.
|
||||
if (type == kWasmExternRef) continue;
|
||||
if (type == kWasmAnyRef) continue;
|
||||
|
||||
ValueType types[] = {type, kWasmI32, type};
|
||||
FunctionSig sig(1, 2, types);
|
||||
@ -2908,9 +2908,9 @@ TEST_F(FunctionBodyDecoderTest, SelectWithType) {
|
||||
{WASM_SELECT_D(WASM_F64(0.0), WASM_F64(0.0), WASM_ZERO)});
|
||||
ExpectValidates(sigs.l_l(),
|
||||
{WASM_SELECT_L(WASM_I64V_1(0), WASM_I64V_1(0), WASM_ZERO)});
|
||||
ExpectValidates(sigs.e_e(),
|
||||
{WASM_SELECT_R(WASM_REF_NULL(kExternRefCode),
|
||||
WASM_REF_NULL(kExternRefCode), WASM_ZERO)});
|
||||
ExpectValidates(sigs.a_a(),
|
||||
{WASM_SELECT_R(WASM_REF_NULL(kAnyRefCode),
|
||||
WASM_REF_NULL(kAnyRefCode), WASM_ZERO)});
|
||||
ExpectValidates(sigs.c_c(),
|
||||
{WASM_SELECT_A(WASM_REF_NULL(kFuncRefCode),
|
||||
WASM_REF_NULL(kFuncRefCode), WASM_ZERO)});
|
||||
@ -3349,8 +3349,7 @@ TEST_F(FunctionBodyDecoderTest, TableInit) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableInitWrongType) {
|
||||
uint32_t table_index = builder.InitializeTable(wasm::kWasmFuncRef);
|
||||
uint32_t element_index =
|
||||
builder.AddPassiveElementSegment(wasm::kWasmExternRef);
|
||||
uint32_t element_index = builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
|
||||
ExpectFailure(sigs.v_v(), {WASM_TABLE_INIT(table_index, element_index,
|
||||
WASM_ZERO, WASM_ZERO, WASM_ZERO)});
|
||||
}
|
||||
@ -3425,31 +3424,31 @@ TEST_F(FunctionBodyDecoderTest, TableCopy) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableCopyWrongType) {
|
||||
uint32_t dst_table_index = builder.InitializeTable(wasm::kWasmFuncRef);
|
||||
uint32_t src_table_index = builder.InitializeTable(wasm::kWasmExternRef);
|
||||
uint32_t src_table_index = builder.InitializeTable(wasm::kWasmAnyRef);
|
||||
ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(dst_table_index, src_table_index,
|
||||
WASM_ZERO, WASM_ZERO, WASM_ZERO)});
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableGrow) {
|
||||
byte tab_func = builder.AddTable(kWasmFuncRef, 10, true, 20);
|
||||
byte tab_ref = builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
byte tab_ref = builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
|
||||
ExpectValidates(
|
||||
sigs.i_c(),
|
||||
{WASM_TABLE_GROW(tab_func, WASM_REF_NULL(kFuncRefCode), WASM_ONE)});
|
||||
ExpectValidates(
|
||||
sigs.i_e(),
|
||||
{WASM_TABLE_GROW(tab_ref, WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
sigs.i_a(),
|
||||
{WASM_TABLE_GROW(tab_ref, WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
// FuncRef table cannot be initialized with an ExternRef value.
|
||||
ExpectFailure(sigs.i_e(),
|
||||
ExpectFailure(sigs.i_a(),
|
||||
{WASM_TABLE_GROW(tab_func, WASM_LOCAL_GET(0), WASM_ONE)});
|
||||
// ExternRef table cannot be initialized with a FuncRef value.
|
||||
ExpectFailure(sigs.i_c(),
|
||||
{WASM_TABLE_GROW(tab_ref, WASM_LOCAL_GET(0), WASM_ONE)});
|
||||
// Check that the table index gets verified.
|
||||
ExpectFailure(
|
||||
sigs.i_e(),
|
||||
{WASM_TABLE_GROW(tab_ref + 2, WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
sigs.i_a(),
|
||||
{WASM_TABLE_GROW(tab_ref + 2, WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableSize) {
|
||||
@ -3460,32 +3459,32 @@ TEST_F(FunctionBodyDecoderTest, TableSize) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableFill) {
|
||||
byte tab_func = builder.AddTable(kWasmFuncRef, 10, true, 20);
|
||||
byte tab_ref = builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
byte tab_ref = builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
ExpectValidates(sigs.v_c(),
|
||||
{WASM_TABLE_FILL(tab_func, WASM_ONE,
|
||||
WASM_REF_NULL(kFuncRefCode), WASM_ONE)});
|
||||
ExpectValidates(sigs.v_e(),
|
||||
ExpectValidates(sigs.v_a(),
|
||||
{WASM_TABLE_FILL(tab_ref, WASM_ONE,
|
||||
WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
// FuncRef table cannot be initialized with an ExternRef value.
|
||||
ExpectFailure(sigs.v_e(), {WASM_TABLE_FILL(tab_func, WASM_ONE,
|
||||
ExpectFailure(sigs.v_a(), {WASM_TABLE_FILL(tab_func, WASM_ONE,
|
||||
WASM_LOCAL_GET(0), WASM_ONE)});
|
||||
// ExternRef table cannot be initialized with a FuncRef value.
|
||||
ExpectFailure(sigs.v_c(), {WASM_TABLE_FILL(tab_ref, WASM_ONE,
|
||||
WASM_LOCAL_GET(0), WASM_ONE)});
|
||||
// Check that the table index gets verified.
|
||||
ExpectFailure(sigs.v_e(),
|
||||
ExpectFailure(sigs.v_a(),
|
||||
{WASM_TABLE_FILL(tab_ref + 2, WASM_ONE,
|
||||
WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, TableOpsWithoutTable) {
|
||||
ExpectFailure(sigs.i_v(),
|
||||
{WASM_TABLE_GROW(0, WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
{WASM_TABLE_GROW(0, WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
ExpectFailure(sigs.i_v(), {WASM_TABLE_SIZE(0)});
|
||||
ExpectFailure(
|
||||
sigs.i_e(),
|
||||
{WASM_TABLE_FILL(0, WASM_ONE, WASM_REF_NULL(kExternRefCode), WASM_ONE)});
|
||||
sigs.i_a(),
|
||||
{WASM_TABLE_FILL(0, WASM_ONE, WASM_REF_NULL(kAnyRefCode), WASM_ONE)});
|
||||
builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_TABLE_INIT(0, 0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
|
||||
@ -3496,7 +3495,7 @@ TEST_F(FunctionBodyDecoderTest, TableOpsWithoutTable) {
|
||||
TEST_F(FunctionBodyDecoderTest, TableCopyMultiTable) {
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
|
||||
module = builder.module();
|
||||
// We added one table, therefore table.copy on table 0 should work.
|
||||
@ -3517,8 +3516,8 @@ TEST_F(FunctionBodyDecoderTest, TableCopyMultiTable) {
|
||||
}
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
|
||||
module = builder.module();
|
||||
// We added two tables, therefore table.copy on table 0 should work.
|
||||
@ -3544,8 +3543,8 @@ TEST_F(FunctionBodyDecoderTest, TableCopyMultiTable) {
|
||||
TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmExternRef);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
|
||||
module = builder.module();
|
||||
// We added one table, therefore table.init on table 0 should work.
|
||||
int table_index = 0;
|
||||
@ -3558,9 +3557,9 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
|
||||
}
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddTable(kWasmExternRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmExternRef);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddTable(kWasmAnyRef, 10, true, 20);
|
||||
builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
|
||||
module = builder.module();
|
||||
// We added two tables, therefore table.init on table 0 should work.
|
||||
int table_index = 0;
|
||||
@ -3668,13 +3667,13 @@ TEST_F(FunctionBodyDecoderTest, NominalStructSubtyping) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, DefaultableLocal) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
AddLocals(kWasmExternRef, 1);
|
||||
AddLocals(kWasmAnyRef, 1);
|
||||
ExpectValidates(sigs.v_v(), {});
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, NonDefaultableLocal) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
AddLocals(ValueType::Ref(HeapType::kExtern, kNonNullable), 1);
|
||||
AddLocals(ValueType::Ref(HeapType::kAny, kNonNullable), 1);
|
||||
ExpectFailure(sigs.v_v(), {}, kAppendEnd,
|
||||
"Cannot define function-level local of non-defaultable type");
|
||||
}
|
||||
@ -3763,10 +3762,9 @@ TEST_F(FunctionBodyDecoderTest, RefEq) {
|
||||
kWasmF32,
|
||||
kWasmF64,
|
||||
kWasmS128,
|
||||
kWasmExternRef,
|
||||
kWasmFuncRef,
|
||||
kWasmAnyRef,
|
||||
ValueType::Ref(HeapType::kExtern, kNonNullable),
|
||||
ValueType::Ref(HeapType::kAny, kNonNullable),
|
||||
ValueType::Ref(HeapType::kFunc, kNonNullable)};
|
||||
|
||||
for (ValueType type1 : eqref_subtypes) {
|
||||
@ -3798,9 +3796,8 @@ TEST_F(FunctionBodyDecoderTest, RefAsNonNull) {
|
||||
|
||||
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
|
||||
byte array_type_index = builder.AddArray(kWasmI32, true);
|
||||
uint32_t heap_types[] = {
|
||||
struct_type_index, array_type_index, HeapType::kFunc, HeapType::kEq,
|
||||
HeapType::kExtern, HeapType::kI31, HeapType::kAny};
|
||||
uint32_t heap_types[] = {struct_type_index, array_type_index, HeapType::kFunc,
|
||||
HeapType::kEq, HeapType::kAny, HeapType::kI31};
|
||||
|
||||
ValueType non_compatible_types[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
|
||||
kWasmS128};
|
||||
@ -3837,9 +3834,8 @@ TEST_F(FunctionBodyDecoderTest, RefNull) {
|
||||
|
||||
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
|
||||
byte array_type_index = builder.AddArray(kWasmI32, true);
|
||||
uint32_t type_reprs[] = {
|
||||
struct_type_index, array_type_index, HeapType::kFunc, HeapType::kEq,
|
||||
HeapType::kExtern, HeapType::kI31, HeapType::kAny};
|
||||
uint32_t type_reprs[] = {struct_type_index, array_type_index, HeapType::kFunc,
|
||||
HeapType::kEq, HeapType::kAny, HeapType::kI31};
|
||||
// It works with heap types.
|
||||
for (uint32_t type_repr : type_reprs) {
|
||||
const ValueType type = ValueType::Ref(type_repr, kNullable);
|
||||
@ -3856,17 +3852,15 @@ TEST_F(FunctionBodyDecoderTest, RefIsNull) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
|
||||
ExpectValidates(sigs.i_i(),
|
||||
{WASM_REF_IS_NULL(WASM_REF_NULL(kExternRefCode))});
|
||||
ExpectValidates(sigs.i_i(), {WASM_REF_IS_NULL(WASM_REF_NULL(kAnyRefCode))});
|
||||
ExpectFailure(
|
||||
sigs.i_i(), {WASM_REF_IS_NULL(WASM_LOCAL_GET(0))}, kAppendEnd,
|
||||
"ref.is_null[0] expected reference type, found local.get of type i32");
|
||||
|
||||
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
|
||||
byte array_type_index = builder.AddArray(kWasmI32, true);
|
||||
uint32_t heap_types[] = {
|
||||
struct_type_index, array_type_index, HeapType::kFunc, HeapType::kEq,
|
||||
HeapType::kExtern, HeapType::kI31, HeapType::kAny};
|
||||
uint32_t heap_types[] = {struct_type_index, array_type_index, HeapType::kFunc,
|
||||
HeapType::kEq, HeapType::kAny, HeapType::kI31};
|
||||
|
||||
for (uint32_t heap_type : heap_types) {
|
||||
const ValueType types[] = {kWasmI32, ValueType::Ref(heap_type, kNullable)};
|
||||
@ -3908,6 +3902,7 @@ TEST_F(FunctionBodyDecoderTest, BrOnNull) {
|
||||
TEST_F(FunctionBodyDecoderTest, BrOnNonNull) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
FLAG_SCOPE(experimental_wasm_gc);
|
||||
|
||||
const ValueType reps[] = {ValueType::Ref(HeapType::kFunc, kNonNullable),
|
||||
ValueType::Ref(HeapType::kFunc, kNullable)};
|
||||
@ -4103,8 +4098,8 @@ TEST_F(FunctionBodyDecoderTest, GCArray) {
|
||||
// Mistyped initializer.
|
||||
ExpectFailure(&sig_r_v,
|
||||
{WASM_ARRAY_NEW_WITH_RTT(
|
||||
array_type_index, WASM_REF_NULL(kExternRefCode),
|
||||
WASM_I32V(10), WASM_RTT_CANON(array_type_index))},
|
||||
array_type_index, WASM_REF_NULL(kAnyRefCode), WASM_I32V(10),
|
||||
WASM_RTT_CANON(array_type_index))},
|
||||
kAppendEnd,
|
||||
"array.new_with_rtt[0] expected type funcref, found ref.null "
|
||||
"of type externref");
|
||||
@ -4424,6 +4419,7 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) {
|
||||
TEST_F(FunctionBodyDecoderTest, BrOnCastOrCastFail) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
FLAG_SCOPE(experimental_wasm_gc);
|
||||
|
||||
byte super_struct = builder.AddStruct({F(kWasmI16, true)});
|
||||
byte sub_struct =
|
||||
@ -4492,6 +4488,7 @@ TEST_F(FunctionBodyDecoderTest, BrOnCastOrCastFail) {
|
||||
TEST_F(FunctionBodyDecoderTest, BrOnAbstractType) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
FLAG_SCOPE(experimental_wasm_gc);
|
||||
|
||||
ValueType kNonNullableFunc = ValueType::Ref(HeapType::kFunc, kNonNullable);
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace module_decoder_unittest {
|
||||
#define WASM_INIT_EXPR_F32(val) WASM_F32(val), kExprEnd
|
||||
#define WASM_INIT_EXPR_I64(val) WASM_I64(val), kExprEnd
|
||||
#define WASM_INIT_EXPR_F64(val) WASM_F64(val), kExprEnd
|
||||
#define WASM_INIT_EXPR_EXTERN_REF_NULL WASM_REF_NULL(kExternRefCode), kExprEnd
|
||||
#define WASM_INIT_EXPR_EXTERN_REF_NULL WASM_REF_NULL(kAnyRefCode), kExprEnd
|
||||
#define WASM_INIT_EXPR_FUNC_REF_NULL WASM_REF_NULL(kFuncRefCode), kExprEnd
|
||||
#define WASM_INIT_EXPR_REF_FUNC(val) WASM_REF_FUNC(val), kExprEnd
|
||||
#define WASM_INIT_EXPR_GLOBAL(index) WASM_GLOBAL_GET(index), kExprEnd
|
||||
@ -185,12 +185,12 @@ struct ValueTypePair {
|
||||
uint8_t code;
|
||||
ValueType type;
|
||||
} kValueTypes[] = {
|
||||
{kI32Code, kWasmI32}, // --
|
||||
{kI64Code, kWasmI64}, // --
|
||||
{kF32Code, kWasmF32}, // --
|
||||
{kF64Code, kWasmF64}, // --
|
||||
{kFuncRefCode, kWasmFuncRef}, // --
|
||||
{kExternRefCode, kWasmExternRef}, // --
|
||||
{kI32Code, kWasmI32}, // --
|
||||
{kI64Code, kWasmI64}, // --
|
||||
{kF32Code, kWasmF32}, // --
|
||||
{kF64Code, kWasmF64}, // --
|
||||
{kFuncRefCode, kWasmFuncRef}, // --
|
||||
{kAnyRefCode, kWasmAnyRef}, // --
|
||||
};
|
||||
|
||||
class WasmModuleVerifyTest : public TestWithIsolateAndZone {
|
||||
@ -309,7 +309,7 @@ TEST_F(WasmModuleVerifyTest, ExternRefGlobal) {
|
||||
TWO_EMPTY_FUNCTIONS(SIG_INDEX(0)),
|
||||
SECTION(Global, // --
|
||||
ENTRY_COUNT(2), // --
|
||||
kExternRefCode, // local type
|
||||
kAnyRefCode, // local type
|
||||
0, // immutable
|
||||
WASM_INIT_EXPR_EXTERN_REF_NULL, // init
|
||||
kFuncRefCode, // local type
|
||||
@ -336,7 +336,7 @@ TEST_F(WasmModuleVerifyTest, ExternRefGlobal) {
|
||||
EXPECT_EQ(0u, result.value()->data_segments.size());
|
||||
|
||||
const WasmGlobal* global = &result.value()->globals[0];
|
||||
EXPECT_EQ(kWasmExternRef, global->type);
|
||||
EXPECT_EQ(kWasmAnyRef, global->type);
|
||||
EXPECT_FALSE(global->mutability);
|
||||
|
||||
global = &result.value()->globals[1];
|
||||
@ -410,12 +410,12 @@ TEST_F(WasmModuleVerifyTest, ExternRefGlobalWithGlobalInit) {
|
||||
ADD_COUNT('m'), // module name
|
||||
ADD_COUNT('f'), // global name
|
||||
kExternalGlobal, // import kind
|
||||
kExternRefCode, // type
|
||||
kAnyRefCode, // type
|
||||
0), // mutability
|
||||
SECTION(Global, // --
|
||||
ENTRY_COUNT(1),
|
||||
kExternRefCode, // local type
|
||||
0, // immutable
|
||||
kAnyRefCode, // local type
|
||||
0, // immutable
|
||||
WASM_INIT_EXPR_GLOBAL(0)),
|
||||
};
|
||||
|
||||
@ -429,7 +429,7 @@ TEST_F(WasmModuleVerifyTest, ExternRefGlobalWithGlobalInit) {
|
||||
|
||||
const WasmGlobal* global = &result.value()->globals.back();
|
||||
|
||||
EXPECT_EQ(kWasmExternRef, global->type);
|
||||
EXPECT_EQ(kWasmAnyRef, global->type);
|
||||
EXPECT_FALSE(global->mutability);
|
||||
}
|
||||
}
|
||||
@ -441,12 +441,12 @@ TEST_F(WasmModuleVerifyTest, NullGlobalWithGlobalInit) {
|
||||
ADD_COUNT('m'), // module name
|
||||
ADD_COUNT('n'), // global name
|
||||
kExternalGlobal, // import kind
|
||||
kExternRefCode, // type
|
||||
kAnyRefCode, // type
|
||||
0), // mutability
|
||||
SECTION(Global, // --
|
||||
ENTRY_COUNT(1),
|
||||
kExternRefCode, // local type
|
||||
0, // immutable
|
||||
kAnyRefCode, // local type
|
||||
0, // immutable
|
||||
WASM_INIT_EXPR_GLOBAL(0)),
|
||||
};
|
||||
|
||||
@ -461,7 +461,7 @@ TEST_F(WasmModuleVerifyTest, NullGlobalWithGlobalInit) {
|
||||
|
||||
const WasmGlobal* global = &result.value()->globals.back();
|
||||
|
||||
EXPECT_EQ(kWasmExternRef, global->type);
|
||||
EXPECT_EQ(kWasmAnyRef, global->type);
|
||||
EXPECT_FALSE(global->mutability);
|
||||
}
|
||||
}
|
||||
@ -1931,7 +1931,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionInitExternRefTableWithFuncRef) {
|
||||
ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
|
||||
// table declaration ---------------------------------------------------
|
||||
SECTION(Table, ENTRY_COUNT(2), // section header
|
||||
kExternRefCode, 0, 5, // table 0
|
||||
kAnyRefCode, 0, 5, // table 0
|
||||
kFuncRefCode, 0, 9), // table 1
|
||||
// elements ------------------------------------------------------------
|
||||
SECTION(Element,
|
||||
@ -2011,7 +2011,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionDontInitExternRefImportedTable) {
|
||||
ADD_COUNT('m'), // module name
|
||||
ADD_COUNT('s'), // table name
|
||||
kExternalTable, // import kind
|
||||
kExternRefCode, // elem_type
|
||||
kAnyRefCode, // elem_type
|
||||
0, // no maximum field
|
||||
10), // initial size
|
||||
// funcs ---------------------------------------------------------------
|
||||
@ -2077,7 +2077,7 @@ TEST_F(WasmModuleVerifyTest, MultipleTables) {
|
||||
kFuncRefCode, // table 1: type
|
||||
0, // table 1: no maximum
|
||||
10, // table 1: minimum size
|
||||
kExternRefCode, // table 2: type
|
||||
kAnyRefCode, // table 2: type
|
||||
0, // table 2: no maximum
|
||||
11), // table 2: minimum size
|
||||
};
|
||||
@ -2091,7 +2091,7 @@ TEST_F(WasmModuleVerifyTest, MultipleTables) {
|
||||
EXPECT_EQ(kWasmFuncRef, result.value()->tables[0].type);
|
||||
|
||||
EXPECT_EQ(11u, result.value()->tables[1].initial_size);
|
||||
EXPECT_EQ(kWasmExternRef, result.value()->tables[1].type);
|
||||
EXPECT_EQ(kWasmAnyRef, result.value()->tables[1].type);
|
||||
}
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, TypedFunctionTable) {
|
||||
@ -3189,7 +3189,7 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegmentExternRef) {
|
||||
// table declaration -----------------------------------------------------
|
||||
SECTION(Table, ENTRY_COUNT(1), kFuncRefCode, 0, 1),
|
||||
// element segments -----------------------------------------------------
|
||||
SECTION(Element, ENTRY_COUNT(1), PASSIVE_WITH_ELEMENTS, kExternRefCode,
|
||||
SECTION(Element, ENTRY_COUNT(1), PASSIVE_WITH_ELEMENTS, kAnyRefCode,
|
||||
U32V_1(0)),
|
||||
// code ------------------------------------------------------------------
|
||||
ONE_EMPTY_BODY};
|
||||
|
@ -51,6 +51,7 @@ void DefineSignature(WasmModule* module,
|
||||
}
|
||||
|
||||
TEST_F(WasmSubtypingTest, Subtyping) {
|
||||
FLAG_SCOPE(experimental_wasm_gc);
|
||||
v8::internal::AccountingAllocator allocator;
|
||||
WasmModule module1_(std::make_unique<Zone>(&allocator, ZONE_NAME));
|
||||
WasmModule module2_(std::make_unique<Zone>(&allocator, ZONE_NAME));
|
||||
@ -82,10 +83,10 @@ TEST_F(WasmSubtypingTest, Subtyping) {
|
||||
|
||||
constexpr ValueType numeric_types[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
|
||||
kWasmS128};
|
||||
constexpr ValueType ref_types[] = {
|
||||
kWasmExternRef, kWasmFuncRef, kWasmEqRef, kWasmI31Ref, kWasmDataRef,
|
||||
kWasmArrayRef, kWasmAnyRef, optRef(0), ref(0), optRef(2),
|
||||
ref(2), optRef(11), ref(11)};
|
||||
constexpr ValueType ref_types[] = {kWasmFuncRef, kWasmEqRef, kWasmI31Ref,
|
||||
kWasmDataRef, kWasmArrayRef, kWasmAnyRef,
|
||||
optRef(0), ref(0), optRef(2),
|
||||
ref(2), optRef(11), ref(11)};
|
||||
|
||||
#define SUBTYPE(type1, type2) \
|
||||
EXPECT_TRUE(IsSubtypeOf(type1, type2, module1, module))
|
||||
@ -124,9 +125,8 @@ TEST_F(WasmSubtypingTest, Subtyping) {
|
||||
// Concrete reference types, i31ref and dataref are subtypes of eqref,
|
||||
// externref/funcref/anyref/functions are not.
|
||||
SUBTYPE_IFF(ref_type, kWasmEqRef,
|
||||
ref_type != kWasmFuncRef && ref_type != kWasmExternRef &&
|
||||
ref_type != kWasmAnyRef && ref_type != optRef(11) &&
|
||||
ref_type != ref(11));
|
||||
ref_type != kWasmFuncRef && ref_type != kWasmAnyRef &&
|
||||
ref_type != optRef(11) && ref_type != ref(11));
|
||||
// Non-nullable struct/array types are subtypes of dataref.
|
||||
SUBTYPE_IFF(ref_type, kWasmDataRef,
|
||||
ref_type == kWasmDataRef || ref_type == kWasmArrayRef ||
|
||||
@ -147,10 +147,8 @@ TEST_F(WasmSubtypingTest, Subtyping) {
|
||||
}
|
||||
|
||||
// The rest of ref. types are unrelated.
|
||||
for (ValueType type_1 :
|
||||
{kWasmExternRef, kWasmFuncRef, kWasmI31Ref, kWasmArrayRef}) {
|
||||
for (ValueType type_2 :
|
||||
{kWasmExternRef, kWasmFuncRef, kWasmI31Ref, kWasmArrayRef}) {
|
||||
for (ValueType type_1 : {kWasmFuncRef, kWasmI31Ref, kWasmArrayRef}) {
|
||||
for (ValueType type_2 : {kWasmFuncRef, kWasmI31Ref, kWasmArrayRef}) {
|
||||
SUBTYPE_IFF(type_1, type_2, type_1 == type_2);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ TEST_F(WasmCallDescriptorTest, TestExternRefIsGrouped) {
|
||||
ValueType params[kMaxCount];
|
||||
|
||||
for (size_t i = 0; i < kMaxCount; i += 2) {
|
||||
params[i] = kWasmExternRef;
|
||||
params[i] = kWasmAnyRef;
|
||||
EXPECT_TRUE(i + 1 < kMaxCount);
|
||||
params[i + 1] = kWasmI32;
|
||||
}
|
||||
|
@ -188,9 +188,9 @@ TEST_F(WasmCapiTest, DirectCallCapiFunction) {
|
||||
ValType::make(::wasm::ANYREF)));
|
||||
own<Func> func = Func::make(store(), cpp_sig.get(), PlusOne);
|
||||
Extern* imports[] = {func.get()};
|
||||
ValueType wasm_types[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
|
||||
kWasmExternRef, kWasmI32, kWasmI64, kWasmF32,
|
||||
kWasmF64, kWasmExternRef};
|
||||
ValueType wasm_types[] = {kWasmI32, kWasmI64, kWasmF32, kWasmF64,
|
||||
kWasmAnyRef, kWasmI32, kWasmI64, kWasmF32,
|
||||
kWasmF64, kWasmAnyRef};
|
||||
FunctionSig wasm_sig(5, 5, wasm_types);
|
||||
int func_index = builder()->AddImport(base::CStrVector("func"), &wasm_sig);
|
||||
builder()->ExportImportedFunction(base::CStrVector("func"), func_index);
|
||||
|
@ -23,9 +23,9 @@ own<Trap> IdentityCallback(const Val args[], Val results[]) {
|
||||
} // namespace
|
||||
|
||||
TEST_F(WasmCapiTest, HostRef) {
|
||||
ValueType rr_reps[] = {kWasmExternRef, kWasmExternRef};
|
||||
ValueType ri_reps[] = {kWasmExternRef, kWasmI32};
|
||||
ValueType ir_reps[] = {kWasmI32, kWasmExternRef};
|
||||
ValueType rr_reps[] = {kWasmAnyRef, kWasmAnyRef};
|
||||
ValueType ri_reps[] = {kWasmAnyRef, kWasmI32};
|
||||
ValueType ir_reps[] = {kWasmI32, kWasmAnyRef};
|
||||
// Naming convention: result_params_sig.
|
||||
FunctionSig r_r_sig(1, 1, rr_reps);
|
||||
FunctionSig v_r_sig(0, 1, rr_reps);
|
||||
@ -35,9 +35,9 @@ TEST_F(WasmCapiTest, HostRef) {
|
||||
uint32_t func_index = builder()->AddImport(base::CStrVector("f"), &r_r_sig);
|
||||
const bool kMutable = true;
|
||||
uint32_t global_index = builder()->AddExportedGlobal(
|
||||
kWasmExternRef, kMutable, WasmInitExpr::RefNullConst(HeapType::kExtern),
|
||||
kWasmAnyRef, kMutable, WasmInitExpr::RefNullConst(HeapType::kAny),
|
||||
base::CStrVector("global"));
|
||||
uint32_t table_index = builder()->AddTable(kWasmExternRef, 10);
|
||||
uint32_t table_index = builder()->AddTable(kWasmAnyRef, 10);
|
||||
builder()->AddExport(base::CStrVector("table"), kExternalTable, table_index);
|
||||
byte global_set_code[] = {WASM_GLOBAL_SET(global_index, WASM_LOCAL_GET(0))};
|
||||
AddExportedFunction(base::CStrVector("global.set"), global_set_code,
|
||||
|
@ -35,8 +35,8 @@ void ExpectName(const char* expected, const ::wasm::Name& name) {
|
||||
TEST_F(WasmCapiTest, Reflect) {
|
||||
// Create a module exporting a function, a global, a table, and a memory.
|
||||
byte code[] = {WASM_UNREACHABLE};
|
||||
ValueType types[] = {kWasmI32, kWasmExternRef, kWasmI32,
|
||||
kWasmI64, kWasmF32, kWasmF64};
|
||||
ValueType types[] = {kWasmI32, kWasmAnyRef, kWasmI32,
|
||||
kWasmI64, kWasmF32, kWasmF64};
|
||||
FunctionSig sig(2, 4, types);
|
||||
AddExportedFunction(base::CStrVector(kFuncName), code, sizeof(code), &sig);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user