Bug 1796315 - wasm: Remove 'private reftypes' and allow non-nullable globals. r=yury

This commit remove WASM_PRIVATE_REFTYPES which is from the original prototype
that Lars wrote. It's not been needed since we added 'isExposable' to prevent
certain wasm values such as V128 from going to JS, and used that for GC
values.

This commit also removes the restriction on non-nullable globals. The
globals JS-API supports non-nullable globals, and the internal
wasm type system should ensure all globals are initialized to
non-null.

As a drive-by, the table.get() JS-API was updated to not work when the
table has a non-exposable value type.

Differential Revision: https://phabricator.services.mozilla.com/D159796
This commit is contained in:
Ryan Hunt 2022-11-14 17:09:12 +00:00
Родитель cb1d8e16fe
Коммит dec5434b19
14 изменённых файлов: 123 добавлений и 518 удалений

Просмотреть файл

@ -669,33 +669,6 @@ set_config("ENABLE_WASM_GC", wasm_gc)
set_define("ENABLE_WASM_GC", wasm_gc)
# Support for WebAssembly private ref types.
# Prevent (ref T) types from being exposed to JS content so that wasm need do
# no typechecking at the JS/wasm boundary
# ===========================================================================
@depends(milestone.is_nightly, "--enable-wasm-gc")
def default_wasm_private_reftypes(is_nightly, gc):
if gc and is_nightly:
return True
option(
"--enable-wasm-private-reftypes",
default=default_wasm_private_reftypes,
help="{Enable|Disable} WebAssembly private reference types",
)
set_config(
"WASM_PRIVATE_REFTYPES",
depends_if("--enable-wasm-private-reftypes")(lambda x: True),
)
set_define(
"WASM_PRIVATE_REFTYPES",
depends_if("--enable-wasm-private-reftypes")(lambda x: True),
)
# Support for WebAssembly shared memory and atomics.
#
# This affects the JS shell only.

Просмотреть файл

@ -150,11 +150,14 @@ assertErrorMessage(() => runNull(), TypeError, /cannot pass null to non-nullable
assertErrorMessage(() => runMultiNullReg(), TypeError, /cannot pass null to non-nullable/);
assertErrorMessage(() => runMultiNullStack(), TypeError, /cannot pass null to non-nullable/);
// cannot have non-nullable globals
wasmFailValidateText(`(module
(global $a (import "" "") (ref extern))
(global (ref extern) global.get $a)
)`, /non-nullable references not supported in globals/);
{
// can have non-nullable globals
wasmEvalText(`(module
(func $f)
(elem declare $f)
(global (ref func) ref.func $f)
)`);
}
// cannot have non-nullable tables
wasmFailValidateText(`(module

Просмотреть файл

@ -0,0 +1,72 @@
// |jit-test| skip-if: !wasmGcEnabled()
function linkGlobals(typeSection, exportInit, linkType) {
let {global} = wasmEvalText(`(module
${typeSection}
(global (export "global") ${linkType} ${exportInit})
)`).exports;
wasmEvalText(`(module
${typeSection}
(import "" "global"
(global ${linkType})
)
)`, {"": {global}});
}
function linkTables(typeSection, exportInit, linkType) {
let {table} = wasmEvalText(`(module
${typeSection}
(table (export "table") ${linkType} (elem (${exportInit})))
)`).exports;
wasmEvalText(`(module
${typeSection}
(import "" "table"
(table 0 1 ${linkType})
)
)`, {"": {table}});
}
function linkFuncs(typeSection, exportInit, linkType) {
let {func} = wasmEvalText(`(module
${typeSection}
(func
(export "func")
(param ${linkType})
(result ${linkType})
unreachable
)
)`).exports;
wasmEvalText(`(module
${typeSection}
(import "" "func"
(func (param ${linkType}) (result ${linkType}))
)
)`, {"": {func}});
}
const TESTS = [
[
"(type (struct (field i32)))",
"ref.null 0",
"(ref null 0)",
],
[
"(type (array i32))",
"ref.null 0",
"(ref null 0)",
],
[
"(type (struct (field i32))) (type (struct (field (ref 0))))",
"ref.null 1",
"(ref null 1)",
]
];
for (let test of TESTS) {
linkGlobals(...test);
linkTables(...test);
linkFuncs(...test);
}

Просмотреть файл

@ -94,29 +94,3 @@
let ins = new WebAssembly.Instance(mod, {"":{g}}).exports;
assertEq(ins.get(), obj);
}
// We can't import a global of a reference type because we don't have a good
// notion of structural type compatibility yet.
{
let bin = wasmTextToBinary(
`(module
(type $box (struct (field $val i32)))
(import "m" "g" (global (mut (ref null $box)))))`);
assertErrorMessage(() => new WebAssembly.Module(bin), WebAssembly.CompileError,
/cannot expose indexed reference type/);
}
// We can't export a global of a reference type because we can't later import
// it. (Once we can export it, the value setter must also perform the necessary
// subtype check, which implies we have some notion of exporting types, and we
// don't have that yet.)
{
let bin = wasmTextToBinary(
`(module
(type $box (struct (field $val i32)))
(global $boxg (export "box") (mut (ref null $box)) (ref.null $box)))`);
assertErrorMessage(() => new WebAssembly.Module(bin), WebAssembly.CompileError,
/cannot expose indexed reference type/);
}

Просмотреть файл

@ -1,316 +0,0 @@
// |jit-test| skip-if: !wasmGcEnabled()
// For the time being, we do not want to expose struct types outside of the
// module where they are defined, and so there are restrictions on how functions
// and global variables that traffic in struct types can be used.
//
// At the same time, intra-module uses of functions and globals that use struct
// types must be allowed to the greatest extent possible.
//
// Terminology: A function that takes a Ref parameter or returns a Ref result is
// "exposed for Ref", as is a global of Ref type. EqRef is OK though, in all
// cases.
//
// To keep it simple we have the following restrictions that can all be checked
// statically.
//
// - Exported and imported functions cannot be exposed for Ref.
//
// - If the module has an exported or imported table then no function stored in
// that table by the module (by means of an element segment) can be exposed
// for Ref.
//
// - If the module has an exported or imported table then no call_indirect via
// that table may reference a type that is exposed for Ref.
//
// - An exported or imported global cannot be exposed for Ref.
//
// Conversely,
//
// - If a module has a private table then it can contain private functions that
// are exposed for Ref and it is possible to call those functions via that
// table.
//
// - If a module has a private global then it can be exposed for ref.
//
// Note that
//
// - code generators can work around the restrictions by instead using
// functions and globals that use eqref, and by using downcasts to check
// that the types are indeed correct. (Though the meaning of downcast will
// change as the GC feature evolves.)
//
// - we could probably make the restrictions slightly softer but there's really
// no advantage to doing so.
function wasmCompile(text) {
return new WebAssembly.Module(wasmTextToBinary(text));
}
// Exported function can't take ref type parameter, but eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $x i32)))
(func (export "f") (param (ref null $box)) (unreachable)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(func (export "f") (param eqref) (unreachable)))`),
"object");
// Exported function can't return ref result, but eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $x i32)))
(func (export "f") (result (ref null $box)) (ref.null $box)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(func (export "f") (result eqref) (ref.null eq)))`),
"object");
// Imported function can't take ref parameter, but eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $x i32)))
(import "m" "f" (func (param (ref null $box)))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(import "m" "f" (func (param eqref))))`),
"object");
// Imported function can't return ref type, but eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $x i32)))
(import "m" "f" (func (param i32) (result (ref null $box)))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(import "m" "f" (func (param i32) (result eqref))))`),
"object");
// Imported global can't be of Ref type (irrespective of mutability), though eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(import "m" "g" (global (mut (ref null $box)))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(import "m" "g" (global (ref null $box))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(import "m" "g" (global (mut eqref))))`),
"object");
assertEq(typeof wasmCompile(
`(module
(import "m" "g" (global eqref)))`),
"object");
// Exported global can't be of Ref type (irrespective of mutability), though eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(global $boxg (export "box") (mut (ref null $box)) (ref.null $box)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(global $boxg (export "box") (ref null $box) (ref.null $box)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(global $boxg (export "box") (mut eqref) (ref.null eq)))`),
"object");
assertEq(typeof wasmCompile(
`(module
(global $boxg (export "box") eqref (ref.null eq)))`),
"object");
// Exported table cannot reference functions that are exposed for Ref, but eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(table (export "tbl") 1 funcref)
(elem (i32.const 0) $f1)
(func $f1 (param (ref null $box)) (unreachable)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(table (export "tbl") 1 funcref)
(elem (i32.const 0) $f1)
(func $f1 (result (ref null $box)) (ref.null $box)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(table (export "tbl") 1 funcref)
(elem (i32.const 0) $f1)
(func $f1 (param eqref) (unreachable)))`),
"object");
assertEq(typeof wasmCompile(
`(module
(table (export "tbl") 1 funcref)
(elem (i32.const 0) $f1)
(func $f1 (result eqref) (ref.null eq)))`),
"object");
// Imported table cannot reference functions that are exposed for Ref, though eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(import "m" "tbl" (table 1 funcref))
(elem (i32.const 0) $f1)
(func $f1 (param (ref null $box)) (unreachable)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(import "m" "tbl" (table 1 funcref))
(elem (i32.const 0) $f1)
(func $f1 (result (ref null $box)) (ref.null $box)))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(import "m" "tbl" (table 1 funcref))
(elem (i32.const 0) $f1)
(func $f1 (param eqref) (unreachable)))`),
"object");
assertEq(typeof wasmCompile(
`(module
(import "m" "tbl" (table 1 funcref))
(elem (i32.const 0) $f1)
(func $f1 (result eqref) (ref.null eq)))`),
"object");
// Can't call via exported table with type that is exposed for Ref, though eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(type $fn (func (param (ref null $box))))
(table (export "tbl") 1 funcref)
(func (param i32)
(call_indirect (type $fn) (ref.null $box) (local.get 0))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(type $fn (func (result (ref null $box))))
(table (export "tbl") 1 funcref)
(func (param i32) (result (ref null $box))
(call_indirect (type $fn) (local.get 0))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(type $fn (func (param eqref)))
(table (export "tbl") 1 funcref)
(func (param i32)
(call_indirect (type $fn) (ref.null eq) (local.get 0))))`),
"object");
assertEq(typeof wasmCompile(
`(module
(type $fn (func (result eqref)))
(table (export "tbl") 1 funcref)
(func (param i32) (result eqref)
(call_indirect (type $fn) (local.get 0))))`),
"object");
// Can't call via imported table with type that is exposed for Ref, though eqref is OK.
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(type $fn (func (param (ref null $box))))
(import "m" "tbl" (table 1 funcref))
(func (param i32)
(call_indirect (type $fn) (ref.null $box) (local.get 0))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertErrorMessage(() => wasmCompile(
`(module
(type $box (struct (field $val i32)))
(type $fn (func (result (ref null $box))))
(import "m" "tbl" (table 1 funcref))
(func (param i32) (result (ref null $box))
(call_indirect (type $fn) (local.get 0))))`),
WebAssembly.CompileError,
/cannot expose indexed reference type/);
assertEq(typeof wasmCompile(
`(module
(type $fn (func (param eqref)))
(import "m" "tbl" (table 1 funcref))
(func (param i32)
(call_indirect (type $fn) (ref.null eq) (local.get 0))))`),
"object");
assertEq(typeof wasmCompile(
`(module
(type $fn (func (result eqref)))
(import "m" "tbl" (table 1 funcref))
(func (param i32) (result eqref)
(call_indirect (type $fn) (local.get 0))))`),
"object");
// We can call via a private table with a type that is exposed for Ref.
{
let m = wasmCompile(
`(module
(type $box (struct (field $val i32)))
(type $fn (func (param (ref null $box)) (result i32)))
(table 1 funcref)
(elem (i32.const 0) $f1)
(func $f1 (param (ref null $box)) (result i32) (i32.const 37))
(func (export "f") (param i32) (result i32)
(call_indirect (type $fn) (ref.null $box) (local.get 0))))`);
let i = new WebAssembly.Instance(m).exports;
assertEq(i.f(0), 37);
}

Просмотреть файл

@ -3167,22 +3167,7 @@ bool WasmTableObject::getImpl(JSContext* cx, const CallArgs& args) {
return false;
}
switch (table.repr()) {
case TableRepr::Func: {
MOZ_RELEASE_ASSERT(!table.isAsmJS());
RootedFunction fun(cx);
if (!table.getFuncRef(cx, index, &fun)) {
return false;
}
args.rval().setObjectOrNull(fun);
break;
}
case TableRepr::Ref: {
args.rval().set(UnboxAnyRef(table.getAnyRef(index)));
break;
}
}
return true;
return table.getValue(cx, index, args.rval());
}
/* static */

Просмотреть файл

@ -2443,13 +2443,6 @@ inline bool OpIter<Policy>::readCallIndirect(uint32_t* funcTypeIndex,
}
const FuncType& funcType = typeDef.funcType();
#ifdef WASM_PRIVATE_REFTYPES
if (env_.tables[*tableIndex].isImportedOrExported &&
funcType.exposesTypeIndex()) {
return fail("cannot expose indexed reference type");
}
#endif
if (!popCallArgs(funcType.args(), argValues)) {
return false;
}

Просмотреть файл

@ -235,6 +235,31 @@ void Table::fillAnyRef(uint32_t index, uint32_t fillCount, AnyRef ref) {
}
}
bool Table::getValue(JSContext* cx, uint32_t index,
MutableHandleValue result) const {
switch (repr()) {
case TableRepr::Func: {
MOZ_RELEASE_ASSERT(!isAsmJS());
RootedFunction fun(cx);
if (!getFuncRef(cx, index, &fun)) {
return false;
}
result.setObjectOrNull(fun);
return true;
}
case TableRepr::Ref: {
if (!ValType(elemType_).isExposable()) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_BAD_VAL_TYPE);
return false;
}
return ToJSValue(cx, &objects_[index], ValType(elemType_), result);
}
default:
MOZ_CRASH();
}
}
void Table::setNull(uint32_t index) {
switch (repr()) {
case TableRepr::Func: {
@ -304,6 +329,8 @@ bool Table::copy(JSContext* cx, const Table& srcTable, uint32_t dstIndex,
}
uint32_t Table::grow(uint32_t delta) {
MOZ_RELEASE_ASSERT(elemType_.isNullable());
// This isn't just an optimization: movingGrowable() assumes that
// onMovingGrowTable does not fire when length == maximum.
if (!delta) {

Просмотреть файл

@ -99,6 +99,10 @@ class Table : public ShareableBase<Table> {
AnyRef getAnyRef(uint32_t index) const;
void fillAnyRef(uint32_t index, uint32_t fillCount, AnyRef ref);
// Get the element at index and convert it to a JS value.
[[nodiscard]] bool getValue(JSContext* cx, uint32_t index,
MutableHandleValue result) const;
void setNull(uint32_t index);
// Copy entry from |srcTable| at |srcIndex| to this table at |dstIndex|. Used

Просмотреть файл

@ -216,22 +216,6 @@ class FuncType {
return false;
}
#ifdef WASM_PRIVATE_REFTYPES
bool exposesTypeIndex() const {
for (const ValType& arg : args()) {
if (arg.isTypeRef()) {
return true;
}
}
for (const ValType& result : results()) {
if (result.isTypeRef()) {
return true;
}
}
return false;
}
#endif
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
WASM_DECLARE_FRIEND_SERIALIZE(FuncType);
};

Просмотреть файл

@ -387,9 +387,8 @@ class RefType {
case RefType::Eq:
case RefType::Struct:
case RefType::Array:
return TableRepr::Ref;
case RefType::TypeRef:
MOZ_CRASH("NYI");
return TableRepr::Ref;
}
MOZ_CRASH("switch is exhaustive");
}

Просмотреть файл

@ -1478,15 +1478,6 @@ static bool DecodePreamble(Decoder& d) {
return true;
}
#ifdef WASM_PRIVATE_REFTYPES
static bool FuncTypeIsJSCompatible(Decoder& d, const FuncType& ft) {
if (ft.exposesTypeIndex()) {
return d.fail("cannot expose indexed reference type");
}
return true;
}
#endif
static bool DecodeValTypeVector(Decoder& d, ModuleEnvironment* env,
uint32_t count, ValTypeVector* valTypes) {
if (!valTypes->resize(count)) {
@ -1904,26 +1895,6 @@ static bool DecodeTableTypeAndLimits(Decoder& d, const FeatureArgs& features,
/* isAsmJS */ false);
}
static bool GlobalIsJSCompatible(Decoder& d, ValType type) {
switch (type.kind()) {
case ValType::I32:
case ValType::F32:
case ValType::F64:
case ValType::I64:
case ValType::V128:
break;
case ValType::Ref:
if (type.refType().isTypeRef()) {
return d.fail("cannot expose indexed reference type");
}
break;
default:
return d.fail("unexpected variable type in global import/export");
}
return true;
}
static bool DecodeGlobalType(Decoder& d, const SharedTypeContext& types,
const FeatureArgs& features, ValType* type,
bool* isMutable) {
@ -1931,10 +1902,6 @@ static bool DecodeGlobalType(Decoder& d, const SharedTypeContext& types,
return d.fail("expected global type");
}
if (type->isRefType() && !type->isNullable()) {
return d.fail("non-nullable references not supported in globals");
}
uint8_t flags;
if (!d.readFixedU8(&flags)) {
return d.fail("expected global flags");
@ -1981,18 +1948,6 @@ static bool DecodeMemoryTypeAndLimits(Decoder& d, ModuleEnvironment* env) {
return true;
}
#ifdef WASM_PRIVATE_REFTYPES
static bool TagIsJSCompatible(Decoder& d, const ValTypeVector& type) {
for (auto t : type) {
if (t.isTypeRef()) {
return d.fail("cannot expose indexed reference type");
}
}
return true;
}
#endif // WASM_PRIVATE_REFTYPES
static bool DecodeTag(Decoder& d, ModuleEnvironment* env, TagKind* tagKind,
uint32_t* funcTypeIndex) {
uint32_t tagCode;
@ -2044,12 +1999,6 @@ static bool DecodeImport(Decoder& d, ModuleEnvironment* env) {
if (!DecodeFuncTypeIndex(d, env->types, &funcTypeIndex)) {
return false;
}
#ifdef WASM_PRIVATE_REFTYPES
if (!FuncTypeIsJSCompatible(d,
env->types->type(funcTypeIndex).funcType())) {
return false;
}
#endif
if (!env->funcs.append(FuncDesc(
&env->types->type(funcTypeIndex).funcType(), funcTypeIndex))) {
return false;
@ -2079,9 +2028,6 @@ static bool DecodeImport(Decoder& d, ModuleEnvironment* env) {
if (!DecodeGlobalType(d, env->types, env->features, &type, &isMutable)) {
return false;
}
if (!GlobalIsJSCompatible(d, type)) {
return false;
}
if (!env->globals.append(
GlobalDesc(type, isMutable, env->globals.length()))) {
return false;
@ -2101,11 +2047,6 @@ static bool DecodeImport(Decoder& d, ModuleEnvironment* env) {
if (!args.appendAll((*env->types)[funcTypeIndex].funcType().args())) {
return false;
}
#ifdef WASM_PRIVATE_REFTYPES
if (!TagIsJSCompatible(d, args)) {
return false;
}
#endif
MutableTagType tagType = js_new<TagType>();
if (!tagType || !tagType->initialize(std::move(args))) {
return false;
@ -2374,11 +2315,6 @@ static bool DecodeExport(Decoder& d, ModuleEnvironment* env, NameSet* dupSet) {
if (funcIndex >= env->numFuncs()) {
return d.fail("exported function index out of bounds");
}
#ifdef WASM_PRIVATE_REFTYPES
if (!FuncTypeIsJSCompatible(d, *env->funcs[funcIndex].type)) {
return false;
}
#endif
env->declareFuncExported(funcIndex, /* eager */ true,
/* canRefFunc */ true);
@ -2423,9 +2359,6 @@ static bool DecodeExport(Decoder& d, ModuleEnvironment* env, NameSet* dupSet) {
GlobalDesc* global = &env->globals[globalIndex];
global->setIsExport();
if (!GlobalIsJSCompatible(d, global->type())) {
return false;
}
return env->exports.emplaceBack(std::move(fieldName), globalIndex,
DefinitionKind::Global);
@ -2439,12 +2372,6 @@ static bool DecodeExport(Decoder& d, ModuleEnvironment* env, NameSet* dupSet) {
return d.fail("exported tag index out of bounds");
}
#ifdef WASM_PRIVATE_REFTYPES
if (!TagIsJSCompatible(d, env->tags[tagIndex].type->argTypes_)) {
return false;
}
#endif
env->tags[tagIndex].isExport = true;
return env->exports.emplaceBack(std::move(fieldName), tagIndex,
DefinitionKind::Tag);
@ -2673,15 +2600,6 @@ static bool DecodeElemSection(Decoder& d, ModuleEnvironment* env) {
return false;
}
#ifdef WASM_PRIVATE_REFTYPES
// We assume that passive or declared segments may be applied to external
// tables. We can do slightly better: if there are no external tables in
// the module then we don't need to worry about passive or declared
// segments either. But this is a temporary restriction.
bool exportedTable = kind == ElemSegmentKind::Passive ||
kind == ElemSegmentKind::Declared ||
env->tables[seg->tableIndex].isImportedOrExported;
#endif
bool isAsmJS = seg->active() && env->tables[seg->tableIndex].isAsmJS;
// For passive segments we should use InitExpr but we don't really want to
@ -2726,12 +2644,6 @@ static bool DecodeElemSection(Decoder& d, ModuleEnvironment* env) {
if (funcIndex >= env->numFuncs()) {
return d.fail("table element out of range");
}
#ifdef WASM_PRIVATE_REFTYPES
if (exportedTable &&
!FuncTypeIsJSCompatible(d, *env->funcs[funcIndex].type)) {
return false;
}
#endif
}
if (payload == ElemSegmentPayload::ElemExpression) {

Просмотреть файл

@ -130,29 +130,25 @@ bool wasm::CheckRefType(JSContext* cx, RefType targetType, HandleValue v,
JSMSG_WASM_BAD_REF_NONNULLABLE_VALUE);
return false;
}
switch (targetType.kind()) {
case RefType::Func:
if (!CheckFuncRefValue(cx, v, fnval)) {
return false;
}
break;
return CheckFuncRefValue(cx, v, fnval);
case RefType::Extern:
if (!BoxAnyRef(cx, v, refval)) {
return false;
}
break;
return BoxAnyRef(cx, v, refval);
case RefType::Eq:
if (!CheckEqRefValue(cx, v, refval)) {
return false;
}
break;
return CheckEqRefValue(cx, v, refval);
case RefType::Any:
case RefType::Struct:
case RefType::Array:
case RefType::TypeRef:
MOZ_CRASH("temporarily unsupported Ref type");
break;
}
return true;
MOZ_ASSERT(!ValType(targetType).isExposable());
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_BAD_VAL_TYPE);
return false;
}
bool wasm::CheckFuncRefValue(JSContext* cx, HandleValue v,

Просмотреть файл

@ -292,7 +292,6 @@ class LitVal {
LitVal() : type_(ValType()), cell_{} {}
explicit LitVal(ValType type) : type_(type) {
MOZ_ASSERT(type.isDefaultable());
switch (type.kind()) {
case ValType::Kind::I32: {
cell_.i32_ = 0;