Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: module imports should not use type index as their function identifier #411

Merged
merged 2 commits into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions packages/wasm-edit/test/ast-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ function removeNodesOfType(t) {
};
}

function makeTypeNode() {
return t.typeInstruction(undefined, t.signature([], []));
}

function makeFuncNodes(i, params = [], results = [], body = []) {
body.push(t.instruction("nop"));

const id = t.identifier(getUniqueName("func"));
const id = t.identifier(`func_${i}`);
const func = t.func(id, t.signature(params, results), body);

const functype = t.typeInstruction(undefined, t.signature(params, results));

const funcindex = t.indexInFuncSection(i);

return [func, functype, funcindex];
return [func, funcindex];
}

function makeFuncExportNode(i) {
Expand Down Expand Up @@ -127,16 +129,17 @@ describe("AST synchronization", () => {
b => addWithAST(ast, b, [makeGlobalNode(10)]),
b => editWithAST(ast, b, removeNodesOfType("TypeInstruction")),

b => addWithAST(ast, b, makeFuncNodes(0)),
b => addWithAST(ast, b, [makeTypeNode()]),

b => addWithAST(ast, b, [makeFuncImportNode()]),
b => editWithAST(ast, b, renameImports("c")),

b => addWithAST(ast, b, makeFuncNodes(1)),
b => addWithAST(ast, b, [makeFuncExportNode(0)]),

b => addWithAST(ast, b, [makeGlobalImportNode()]),
b => editWithAST(ast, b, renameImports("a")),
b => editWithAST(ast, b, renameImports("b")),

b => addWithAST(ast, b, [makeFuncImportNode()]),

b => editWithAST(ast, b, renameImports("c"))
b => editWithAST(ast, b, renameImports("b"))
];

it("should run steps", function() {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-parser/src/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ export function decode(ab: ArrayBuffer, opts: DecoderOpts): Program {
throw new CompileError(`function signature not found (${typeindex})`);
}

const id = t.numberLiteralFromRaw(typeindex);
const id = getUniqueName("func");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should try to eliminate the unique name generator (because statefull), and rather use the typeindex here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should try to eliminate the unique name generator (because statefull)

I agree, that maybe the type name generator should be removed. I'm not sure what it's used for!

and rather use the typeindex here

No ... that's the bug that this PR is fixing. Module imports are functions which are referenced by index, i.e. if you have the following:

(type (func (result i32)))
(type (func (param i32) (result i32)))
(import "a" "c" (func $foo (type 1)))
(func $bar)

The function foo has index 0, and bar has index 1. The index does not relate to the type reference.


importDescr = t.funcImportDescr(
id,
Expand Down
4 changes: 2 additions & 2 deletions packages/wasm-parser/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ function restoreFunctionNames(ast) {
ModuleImport({ node }: NodePath<ModuleImport>) {
if (node.descr.type === "FuncImportDescr") {
// $FlowIgnore
const nodeName: NumberLiteral = node.descr.id;
const index = nodeName.value;
const indexBasedFunctionName: string = node.descr.id;
const index = Number(indexBasedFunctionName.replace("func_", ""));
const functionName = functionNames.find(f => f.index === index);

if (functionName) {
Expand Down
5 changes: 5 additions & 0 deletions packages/wasm-parser/test/fixtures/import/complex/actual.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(module
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this simple test, which adds a couple of type definitions, was enough to repro the issues from #406

(type (func (result i32)))
(type (func (param i32) (result i32)))
(import "a" "c" (func $fff (param i32) (result i32)))
)
4 changes: 2 additions & 2 deletions packages/wast-parser/src/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,6 @@ export function parse(tokensList: Array<Object>, source: string): Program {
}

const name = token.value;

let fnName = t.identifier(`${moduleName}.${name}`);
eatToken();

eatTokenOfType(tokens.openParen);
Expand All @@ -419,6 +417,8 @@ export function parse(tokensList: Array<Object>, source: string): Program {
const fnParams = [];
const fnResult = [];

let fnName = t.identifier(getUniqueName("func"));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change was not necessarily needed to make tests pass, but this does mean we have the same generated names when parsing wat

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following https://github.com/xtuc/webassemblyjs/pull/411/files#r202406723 we could add our own func increment, or maybe we already have this information?


if (token.type === tokens.identifier) {
fnName = identifierFromToken(token);
eatToken();
Expand Down