Add .type directive
This commit is contained in:
89
asm.js
89
asm.js
@@ -97,6 +97,9 @@ const State = Object.freeze({
|
||||
DEF_VALUE: 25,
|
||||
BLOCK_NAME: 26,
|
||||
BLOCK_TYPE: 27,
|
||||
TYPE_NAME: 28,
|
||||
TYPE_PARAM: 29,
|
||||
TYPE_RESULT: 30,
|
||||
});
|
||||
|
||||
const Action = Object.freeze({
|
||||
@@ -118,12 +121,14 @@ const Action = Object.freeze({
|
||||
ENTER: 16,
|
||||
EXIT: 17,
|
||||
ELSE: 18,
|
||||
TYPE: 19,
|
||||
});
|
||||
|
||||
const types = {
|
||||
"void": 0x40,
|
||||
"func": 0x60,
|
||||
"i32": 0x7f,
|
||||
"void": 0x40,
|
||||
"func": 0x60,
|
||||
"funcref": 0x70,
|
||||
"i32": 0x7f,
|
||||
};
|
||||
|
||||
const opcodes = {
|
||||
@@ -208,6 +213,7 @@ class Parser {
|
||||
".utf8": State.UTF8,
|
||||
".align": State.ALIGN,
|
||||
".def": State.DEF_NAME,
|
||||
".type": State.TYPE_NAME,
|
||||
};
|
||||
this.blocks = new Set(["block", "loop", "if"]);
|
||||
this.handlers = {
|
||||
@@ -239,6 +245,9 @@ class Parser {
|
||||
[State.DEF_VALUE]: (token) => this.token_def_value(token),
|
||||
[State.BLOCK_NAME]: (token) => this.token_block_name(token),
|
||||
[State.BLOCK_TYPE]: (token) => this.token_block_type(token),
|
||||
[State.TYPE_NAME]: (token) => this.token_type_name(token),
|
||||
[State.TYPE_PARAM]: (token) => this.token_type_param(token),
|
||||
[State.TYPE_RESULT]: (token) => this.token_type_result(token),
|
||||
};
|
||||
|
||||
this.results = [];
|
||||
@@ -669,6 +678,68 @@ class Parser {
|
||||
return action;
|
||||
}
|
||||
|
||||
token_type_name(token) {
|
||||
if (token == LINE_END) {
|
||||
console.error(
|
||||
"ERROR: Unexpected end of line in .type, expected name");
|
||||
this.state = State.TOP;
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = { name: token, params: [] };
|
||||
this.state = State.TYPE_PARAM;
|
||||
}
|
||||
|
||||
token_type_param(token) {
|
||||
if (token == LINE_END) {
|
||||
console.error(
|
||||
"ERROR: Unexpected end of line in .type, expected "
|
||||
+ "parameter type");
|
||||
this.type = undefined;
|
||||
this.state = State.TOP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (token == "result") {
|
||||
this.type.results = [];
|
||||
this.state = State.TYPE_RESULT;
|
||||
return;
|
||||
}
|
||||
|
||||
const type = types[token];
|
||||
if (type == undefined) {
|
||||
console.error(
|
||||
`ERROR: Unexpected token ${token} in .type, expected `
|
||||
+ "parameter type");
|
||||
this.type = undefined;
|
||||
this.state = State.TOP;
|
||||
return;
|
||||
}
|
||||
|
||||
this.type.params.push(type);
|
||||
}
|
||||
|
||||
token_type_result(token) {
|
||||
if (token == LINE_END) {
|
||||
const action = { type: Action.TYPE, the_type: this.type };
|
||||
this.type = undefined;
|
||||
this.state = State.TOP;
|
||||
return action;
|
||||
}
|
||||
|
||||
const type = types[token];
|
||||
if (type == undefined) {
|
||||
console.error(
|
||||
`ERROR: Unexpected token ${token} in .type, expected `
|
||||
+ "result type");
|
||||
this.type = undefined;
|
||||
this.state = State.TOP;
|
||||
return;
|
||||
}
|
||||
|
||||
this.type.results.push(type);
|
||||
}
|
||||
|
||||
mem_action() {
|
||||
const action = {
|
||||
type: Action.MEM,
|
||||
@@ -730,6 +801,7 @@ export class Assembler {
|
||||
[Action.ENTER]: (action) => this.action_enter(action),
|
||||
[Action.EXIT]: (action) => this.action_exit(action),
|
||||
[Action.ELSE]: (action) => this.action_else(action),
|
||||
[Action.TYPE]: (action) => this.action_type(action),
|
||||
};
|
||||
|
||||
this.exports = [];
|
||||
@@ -742,6 +814,7 @@ export class Assembler {
|
||||
this.defs = {};
|
||||
this.blocks = [];
|
||||
this.types = [];
|
||||
this.type_bindings = {};
|
||||
}
|
||||
|
||||
action_append(action) {
|
||||
@@ -874,6 +947,12 @@ export class Assembler {
|
||||
this.blocks.push(undefined);
|
||||
}
|
||||
|
||||
action_type(action) {
|
||||
const type = this.func_type(action.the_type);
|
||||
const index = this.ensure_type(type);
|
||||
this.type_bindings[action.the_type.name] = index;
|
||||
}
|
||||
|
||||
push(chunk) {
|
||||
const text = this.decoder.decode(chunk, { stream: true });
|
||||
for (const action of this.parser.handle(text))
|
||||
@@ -1066,7 +1145,9 @@ export class Assembler {
|
||||
}
|
||||
|
||||
func_type({ params, results }) {
|
||||
const param_types = Object.values(params);
|
||||
const param_types = params.length == undefined
|
||||
? Object.values(params)
|
||||
: params;
|
||||
return [
|
||||
types["func"],
|
||||
param_types.length,
|
||||
|
||||
Reference in New Issue
Block a user