Bug 1310949: Render table and elem sections; r=luke

MozReview-Commit-ID: Lm2YKBz9wsz

--HG--
extra : rebase_source : e07503aaab7943fb1242d0f1492c76a3e77f187c
This commit is contained in:
Benjamin Bouvier 2016-10-20 18:12:27 +02:00
Родитель d61d3482c4
Коммит b87511701c
4 изменённых файлов: 108 добавлений и 49 удалений

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

@ -697,10 +697,7 @@ class AstExport : public AstNode
{}
AstName name() const { return name_; }
DefinitionKind kind() const { return kind_; }
AstRef& ref() {
MOZ_ASSERT(kind_ == DefinitionKind::Function || kind_ == DefinitionKind::Global);
return ref_;
}
AstRef& ref() { return ref_; }
};
class AstDataSegment : public AstNode

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

@ -1838,7 +1838,7 @@ AstDecodeGlobalSection(AstDecodeContext& c)
}
static bool
AstDecodeFunctionExport(AstDecodeContext& c, AstExport** export_)
AstDecodeExport(AstDecodeContext& c, AstExport** export_)
{
AstName fieldName;
if (!AstDecodeName(c, &fieldName))
@ -1878,7 +1878,7 @@ AstDecodeExportSection(AstDecodeContext& c)
for (uint32_t i = 0; i < numExports; i++) {
AstExport* export_ = nullptr;
if (!AstDecodeFunctionExport(c, &export_))
if (!AstDecodeExport(c, &export_))
return false;
if (!c.module().append(export_))
return false;

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

@ -1193,38 +1193,45 @@ RenderTypeSection(WasmRenderContext& c, const AstModule::SigVector& sigs)
}
static bool
RenderTableSection(WasmRenderContext& c, const AstModule& module)
RenderLimits(WasmRenderContext& c, const Limits& limits)
{
if (module.elemSegments().empty())
return true;
const AstElemSegment& segment = *module.elemSegments()[0];
if (!RenderIndent(c))
if (!RenderInt32(c, limits.initial))
return false;
if (!c.buffer.append("(table anyfunc (elem "))
return false;
for (const AstRef& elem : segment.elems()) {
if (limits.maximum) {
if (!c.buffer.append(" "))
return false;
uint32_t index = elem.index();
AstName name = index < module.funcImportNames().length()
? module.funcImportNames()[index]
: module.funcs()[index - module.funcImportNames().length()]->name();
if (name.empty()) {
if (!RenderInt32(c, index))
return false;
} else {
if (!RenderName(c, name))
return false;
}
if (!RenderInt32(c, *limits.maximum))
return false;
}
return true;
}
return c.buffer.append("))\n");
static bool
RenderResizableTable(WasmRenderContext& c, const Limits& table)
{
if (!c.buffer.append("(table "))
return false;
if (!RenderLimits(c, table))
return false;
return c.buffer.append(" anyfunc)");
}
static bool
RenderTableSection(WasmRenderContext& c, const AstModule& module)
{
if (!module.hasTable())
return true;
for (const AstResizable& table : module.tables()) {
if (table.imported)
continue;
if (!RenderIndent(c))
return false;
if (!RenderResizableTable(c, table.limits))
return false;
if (!c.buffer.append("\n"))
return false;
}
return true;
}
static bool
@ -1242,6 +1249,42 @@ RenderInlineExpr(WasmRenderContext& c, AstExpr& expr)
return c.buffer.append(")");
}
static bool
RenderElemSection(WasmRenderContext& c, const AstModule& module)
{
for (const AstElemSegment* segment : module.elemSegments()) {
if (!RenderIndent(c))
return false;
if (!c.buffer.append("(elem "))
return false;
if (!RenderInlineExpr(c, *segment->offset()))
return false;
for (const AstRef& elem : segment->elems()) {
if (!c.buffer.append(" "))
return false;
uint32_t index = elem.index();
AstName name = index < module.funcImportNames().length()
? module.funcImportNames()[index]
: module.funcs()[index - module.funcImportNames().length()]->name();
if (name.empty()) {
if (!RenderInt32(c, index))
return false;
} else {
if (!RenderName(c, name))
return false;
}
}
if (!c.buffer.append(")\n"))
return false;
}
return true;
}
static bool
RenderGlobal(WasmRenderContext& c, const AstGlobal& glob, bool inImport = false)
{
@ -1296,22 +1339,6 @@ RenderGlobalSection(WasmRenderContext& c, const AstModule& module)
return true;
}
static bool
RenderLimits(WasmRenderContext& c, const Limits& limits)
{
if (!RenderInt32(c, limits.initial))
return false;
if (limits.maximum) {
if (!c.buffer.append(" "))
return false;
if (!RenderInt32(c, *limits.maximum))
return false;
}
return true;
}
static bool
RenderResizableMemory(WasmRenderContext& c, Limits memory)
{
@ -1366,7 +1393,8 @@ RenderImport(WasmRenderContext& c, AstImport& import, const AstModule& module)
break;
}
case DefinitionKind::Table: {
// TODO next patch
if (!RenderResizableTable(c, import.limits()))
return false;
break;
}
case DefinitionKind::Memory: {
@ -1610,6 +1638,9 @@ RenderModule(WasmRenderContext& c, AstModule& module)
if (!RenderTableSection(c, module))
return false;
if (!RenderElemSection(c, module))
return false;
if (!RenderGlobalSection(c, module))
return false;

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

@ -63,3 +63,34 @@ wasmFullPass(`(module
)
(export "mem" memory)
)`, 0x050403, {"": {memory}});
// Tables.
wasmFullPass(`(module
(table (export "table") 3 anyfunc)
(type $t (func (result i32)))
(func $foo (result i32) (i32.const 1))
(func $bar (result i32) (i32.const 2))
(func $baz (result i32) (i32.const 3))
(elem (i32.const 0) $baz $bar)
(elem (i32.const 2) $foo)
(func (export "run") (param i32) (result i32)
get_local 0
call_indirect $t
)
)`, 3, {}, 0);
let table = new WebAssembly.Table({ element: 'anyfunc', initial: 3, maximum: 3 });
wasmFullPass(`(module
(table (import "" "table") 3 4 anyfunc)
(type $t (func (result i32)))
(func $foo (result i32) (i32.const 1))
(func $bar (result i32) (i32.const 2))
(func $baz (result i32) (i32.const 3))
(elem (i32.const 0) $baz $bar)
(elem (i32.const 2) $foo)
(func (export "run") (param i32) (result i32)
get_local 0
call_indirect $t
)
)`, 3, {"":{table}}, 0);