зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1284155 - Baldr: add element type to Tables (r=bbouvier)
MozReview-Commit-ID: 236qwoLkmH8 --HG-- extra : rebase_source : d37a161e91e6f9626ab8be1c0086919835078a16
This commit is contained in:
Родитель
c2137a4bda
Коммит
7bae287798
|
@ -64,6 +64,7 @@ enum class ValType
|
|||
|
||||
enum class TypeConstructor
|
||||
{
|
||||
AnyFunc = 0x20,
|
||||
Function = 0x40
|
||||
};
|
||||
|
||||
|
|
|
@ -727,6 +727,13 @@ DecodeResizableMemory(Decoder& d, ModuleGeneratorData* init)
|
|||
static bool
|
||||
DecodeResizableTable(Decoder& d, ModuleGeneratorData* init)
|
||||
{
|
||||
uint32_t elementType;
|
||||
if (!d.readVarU32(&elementType))
|
||||
return Fail(d, "expected table element type");
|
||||
|
||||
if (elementType != uint32_t(TypeConstructor::AnyFunc))
|
||||
return Fail(d, "expected 'anyfunc' element type");
|
||||
|
||||
Resizable resizable;
|
||||
if (!DecodeResizable(d, &resizable))
|
||||
return false;
|
||||
|
|
|
@ -900,18 +900,40 @@ WasmTableObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
RootedObject obj(cx, &args[0].toObject());
|
||||
RootedId id(cx);
|
||||
RootedValue val(cx);
|
||||
|
||||
JSAtom* elementAtom = Atomize(cx, "element", strlen("element"));
|
||||
if (!elementAtom)
|
||||
return false;
|
||||
id = AtomToId(elementAtom);
|
||||
if (!GetProperty(cx, obj, obj, id, &val))
|
||||
return false;
|
||||
|
||||
if (!val.isString()) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_ELEMENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSLinearString* str = val.toString()->ensureLinear(cx);
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
if (!StringEqualsAscii(str, "anyfunc")) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_ELEMENT);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSAtom* initialAtom = Atomize(cx, "initial", strlen("initial"));
|
||||
if (!initialAtom)
|
||||
return false;
|
||||
|
||||
RootedObject obj(cx, &args[0].toObject());
|
||||
RootedId id(cx, AtomToId(initialAtom));
|
||||
RootedValue initialVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, id, &initialVal))
|
||||
id = AtomToId(initialAtom);
|
||||
if (!GetProperty(cx, obj, obj, id, &val))
|
||||
return false;
|
||||
|
||||
double initialDbl;
|
||||
if (!ToInteger(cx, initialVal, &initialDbl))
|
||||
if (!ToInteger(cx, val, &initialDbl))
|
||||
return false;
|
||||
|
||||
if (initialDbl < 0 || initialDbl > INT32_MAX) {
|
||||
|
|
|
@ -3717,6 +3717,15 @@ EncodeResizable(Encoder& e, const AstResizable& resizable)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EncodeResizableTable(Encoder& e, const AstResizable& resizable)
|
||||
{
|
||||
if (!e.writeVarU32(uint32_t(TypeConstructor::AnyFunc)))
|
||||
return false;
|
||||
|
||||
return EncodeResizable(e, resizable);
|
||||
}
|
||||
|
||||
static bool
|
||||
EncodeImport(Encoder& e, bool newFormat, AstImport& imp)
|
||||
{
|
||||
|
@ -3755,6 +3764,9 @@ EncodeImport(Encoder& e, bool newFormat, AstImport& imp)
|
|||
return false;
|
||||
break;
|
||||
case DefinitionKind::Table:
|
||||
if (!EncodeResizableTable(e, imp.resizable()))
|
||||
return false;
|
||||
break;
|
||||
case DefinitionKind::Memory:
|
||||
if (!EncodeResizable(e, imp.resizable()))
|
||||
return false;
|
||||
|
@ -3936,7 +3948,7 @@ EncodeTableSection(Encoder& e, bool newFormat, AstModule& module)
|
|||
const AstResizable& table = module.table();
|
||||
|
||||
if (newFormat) {
|
||||
if (!EncodeResizable(e, table))
|
||||
if (!EncodeResizableTable(e, table))
|
||||
return false;
|
||||
} else {
|
||||
if (module.elemSegments().length() != 1)
|
||||
|
|
|
@ -10,10 +10,10 @@ const mem1Page = new Memory({initial:1});
|
|||
const mem2Page = new Memory({initial:2});
|
||||
const mem3Page = new Memory({initial:3});
|
||||
const mem4Page = new Memory({initial:4});
|
||||
const tab1Elem = new Table({initial:1});
|
||||
const tab2Elem = new Table({initial:2});
|
||||
const tab3Elem = new Table({initial:3});
|
||||
const tab4Elem = new Table({initial:4});
|
||||
const tab1Elem = new Table({initial:1, element:"anyfunc"});
|
||||
const tab2Elem = new Table({initial:2, element:"anyfunc"});
|
||||
const tab3Elem = new Table({initial:3, element:"anyfunc"});
|
||||
const tab4Elem = new Table({initial:4, element:"anyfunc"});
|
||||
|
||||
// Explicitly opt into the new binary format for imports and exports until it
|
||||
// is used by default everywhere.
|
||||
|
@ -259,7 +259,7 @@ assertEq(mem, e.foo);
|
|||
assertEq(mem, e.bar);
|
||||
|
||||
var code = textToBinary('(module (import "a" "b" (table 1 1)) (export "foo" table) (export "bar" table))');
|
||||
var tbl = new Table({initial:1});
|
||||
var tbl = new Table({initial:1, element:"anyfunc"});
|
||||
var e = new Instance(new Module(code), {a:{b:tbl}}).exports;
|
||||
assertEq(tbl, e.foo);
|
||||
assertEq(tbl, e.bar);
|
||||
|
@ -317,7 +317,7 @@ var m = new Module(textToBinary(`
|
|||
(func $three (result i32) (i32.const 3))
|
||||
(func $four (result i32) (i32.const 4)))
|
||||
`));
|
||||
var tbl = new Table({initial:10});
|
||||
var tbl = new Table({initial:10, element:"anyfunc"});
|
||||
new Instance(m, {a:{b:tbl}});
|
||||
assertEq(tbl.get(0)(), 1);
|
||||
assertEq(tbl.get(1)(), 2);
|
||||
|
|
|
@ -171,11 +171,14 @@ assertEq(Table.length, 1);
|
|||
assertEq(Table.name, "Table");
|
||||
assertErrorMessage(() => Table(), TypeError, /constructor without new is forbidden/);
|
||||
assertErrorMessage(() => new Table(1), TypeError, "first argument must be a table descriptor");
|
||||
assertErrorMessage(() => new Table({initial:{valueOf() { throw new Error("here")}}}), Error, "here");
|
||||
assertErrorMessage(() => new Table({initial:-1}), TypeError, /bad Table initial size/);
|
||||
assertErrorMessage(() => new Table({initial:Math.pow(2,32)}), TypeError, /bad Table initial size/);
|
||||
assertEq(new Table({initial:1}) instanceof Table, true);
|
||||
assertEq(new Table({initial:1.5}) instanceof Table, true);
|
||||
assertErrorMessage(() => new Table({initial:1, element:1}), TypeError, /must be "anyfunc"/);
|
||||
assertErrorMessage(() => new Table({initial:1, element:"any"}), TypeError, /must be "anyfunc"/);
|
||||
assertErrorMessage(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError, /must be "anyfunc"/);
|
||||
assertErrorMessage(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error, "here");
|
||||
assertErrorMessage(() => new Table({initial:-1, element:"anyfunc"}), TypeError, /bad Table initial size/);
|
||||
assertErrorMessage(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), TypeError, /bad Table initial size/);
|
||||
assertEq(new Table({initial:1, element:"anyfunc"}) instanceof Table, true);
|
||||
assertEq(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true);
|
||||
|
||||
// 'WebAssembly.Table.prototype' property
|
||||
const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype');
|
||||
|
@ -191,7 +194,7 @@ assertEq(String(tableProto), "[object Object]");
|
|||
assertEq(Object.getPrototypeOf(tableProto), Object.prototype);
|
||||
|
||||
// 'WebAssembly.Table' instance objects
|
||||
const tbl1 = new Table({initial:2});
|
||||
const tbl1 = new Table({initial:2, element:"anyfunc"});
|
||||
assertEq(typeof tbl1, "object");
|
||||
assertEq(String(tbl1), "[object WebAssembly.Table]");
|
||||
assertEq(Object.getPrototypeOf(tbl1), tableProto);
|
||||
|
|
|
@ -108,7 +108,7 @@ assertEq(finalizeCount(), 3);
|
|||
// Before initialization, a table is not bound to any instance.
|
||||
resetFinalizeCount();
|
||||
var i = evalText(`(module (func $f0 (result i32) (i32.const 0)) (export "f0" $f0))`);
|
||||
var t = new Table({initial:4});
|
||||
var t = new Table({initial:4, element:"anyfunc"});
|
||||
i.edge = makeFinalizeObserver();
|
||||
t.edge = makeFinalizeObserver();
|
||||
gc();
|
||||
|
@ -125,7 +125,7 @@ assertEq(finalizeCount(), 2);
|
|||
resetFinalizeCount();
|
||||
var i = evalText(`(module (func $f (result i32) (i32.const 42)) (export "f" $f))`);
|
||||
var f = i.exports.f;
|
||||
var t = new Table({initial:1});
|
||||
var t = new Table({initial:1, element:"anyfunc"});
|
||||
i.edge = makeFinalizeObserver();
|
||||
f.edge = makeFinalizeObserver();
|
||||
t.edge = makeFinalizeObserver();
|
||||
|
|
|
@ -29,7 +29,7 @@ assertErrorMessage(() => evalText(`(module (table (resizable 10)) (import "globa
|
|||
assertErrorMessage(() => evalText(`(module (table (resizable 10)) (import "globals" "a" (global i32 immutable)) (elem (i32.const 1) $f0 $f0) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:0}}), TypeError, /must be.*ordered/);
|
||||
assertErrorMessage(() => evalText(`(module (table (resizable 10)) (import "globals" "a" (global i32 immutable)) (elem (get_global 0) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`, {globals:{a:1}}), TypeError, /must be.*disjoint/);
|
||||
|
||||
var tbl = new Table({initial:50});
|
||||
var tbl = new Table({initial:50, element:"anyfunc"});
|
||||
assertErrorMessage(() => evalText(`(module
|
||||
(import "globals" "table" (table 10 100))
|
||||
(import "globals" "a" (global i32 immutable))
|
||||
|
@ -64,7 +64,7 @@ assertEq(call(5), 2);
|
|||
assertErrorMessage(() => call(6), Error, /bad wasm indirect call/);
|
||||
assertErrorMessage(() => call(10), Error, /out-of-range/);
|
||||
|
||||
var tbl = new Table({initial:3});
|
||||
var tbl = new Table({initial:3, element:"anyfunc"});
|
||||
var call = evalText(`(module (import "a" "b" (table 2)) (export "tbl" table) (elem (i32.const 0) $f0 $f1) ${callee(0)} ${callee(1)} ${caller})`, {a:{b:tbl}}).exports.call;
|
||||
assertEq(call(0), 0);
|
||||
assertEq(call(1), 1);
|
||||
|
|
|
@ -350,6 +350,7 @@ MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument mus
|
|||
MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMP_SIZE, 1, JSEXN_TYPEERR, "imported {0} with incompatible size")
|
||||
MSG_DEF(JSMSG_WASM_BAD_SIZE, 2, JSEXN_TYPEERR, "bad {0} {1} size")
|
||||
MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\"")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument, if present, must be an object")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 1, JSEXN_TYPEERR, "import object field is not {0}")
|
||||
MSG_DEF(JSMSG_WASM_BAD_SET_VALUE, 0, JSEXN_TYPEERR, "second argument must be null or an exported WebAssembly Function object")
|
||||
|
|
Загрузка…
Ссылка в новой задаче