Assemble kernel on the client #1
54
asm.js
54
asm.js
@@ -47,10 +47,12 @@ class Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const State = Object.freeze({
|
const State = Object.freeze({
|
||||||
TOP: 0,
|
TOP: 0,
|
||||||
EXPORT: 1,
|
EXPORT: 1,
|
||||||
FUNC: 2,
|
FUNC: 2,
|
||||||
RESULT: 3,
|
RESULT: 3,
|
||||||
|
PARAM_NAME: 4,
|
||||||
|
PARAM_TYPE: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
const Action = Object.freeze({
|
const Action = Object.freeze({
|
||||||
@@ -58,6 +60,7 @@ const Action = Object.freeze({
|
|||||||
EXPORT: 1,
|
EXPORT: 1,
|
||||||
FUNC: 2,
|
FUNC: 2,
|
||||||
RESULT: 3,
|
RESULT: 3,
|
||||||
|
PARAM: 4,
|
||||||
});
|
});
|
||||||
|
|
||||||
const types = {
|
const types = {
|
||||||
@@ -67,6 +70,7 @@ const types = {
|
|||||||
|
|
||||||
const opcodes = {
|
const opcodes = {
|
||||||
"end": 0x0b,
|
"end": 0x0b,
|
||||||
|
"local.get": 0x20,
|
||||||
"i32.const": 0x41,
|
"i32.const": 0x41,
|
||||||
"i32.mul": 0x6c,
|
"i32.mul": 0x6c,
|
||||||
};
|
};
|
||||||
@@ -80,15 +84,19 @@ class Parser {
|
|||||||
".export": State.EXPORT,
|
".export": State.EXPORT,
|
||||||
".func": State.FUNC,
|
".func": State.FUNC,
|
||||||
".result": State.RESULT,
|
".result": State.RESULT,
|
||||||
|
".param": State.PARAM_NAME,
|
||||||
};
|
};
|
||||||
this.handlers = {
|
this.handlers = {
|
||||||
[State.TOP]: (token) => this.token_top(token),
|
[State.TOP]: (token) => this.token_top(token),
|
||||||
[State.EXPORT]: (token) => this.token_export(token),
|
[State.EXPORT]: (token) => this.token_export(token),
|
||||||
[State.FUNC]: (token) => this.token_func(token),
|
[State.FUNC]: (token) => this.token_func(token),
|
||||||
[State.RESULT]: (token) => this.token_result(token),
|
[State.RESULT]: (token) => this.token_result(token),
|
||||||
|
[State.PARAM_NAME]: (token) => this.token_param_name(token),
|
||||||
|
[State.PARAM_TYPE]: (token) => this.token_param_type(token),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.results = [];
|
this.results = [];
|
||||||
|
this.params = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
translate_code(token) {
|
translate_code(token) {
|
||||||
@@ -132,6 +140,31 @@ class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token_param_name(token) {
|
||||||
|
if (token == LINE_END) {
|
||||||
|
const action = { type: Action.PARAM, params: this.params };
|
||||||
|
this.state = State.TOP;
|
||||||
|
this.params = {};
|
||||||
|
return action;
|
||||||
|
} else {
|
||||||
|
this.current_param = token;
|
||||||
|
this.state = State.PARAM_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
token_param_type(token) {
|
||||||
|
if (token == LINE_END) {
|
||||||
|
console.error(
|
||||||
|
"ERROR: Unexpected newline in .params: expected type");
|
||||||
|
this.state = State.TOP;
|
||||||
|
this.params = {};
|
||||||
|
} else {
|
||||||
|
this.params[this.current_param] = types[token];
|
||||||
|
this.current_param = undefined;
|
||||||
|
this.state = State.PARAM_NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*handle(src) {
|
*handle(src) {
|
||||||
let action;
|
let action;
|
||||||
for (const token of this.tokenizer.handle(src)) {
|
for (const token of this.tokenizer.handle(src)) {
|
||||||
@@ -158,6 +191,7 @@ export class Assembler {
|
|||||||
[Action.EXPORT]: (action) => this.action_export(action),
|
[Action.EXPORT]: (action) => this.action_export(action),
|
||||||
[Action.FUNC]: (action) => this.action_func(action),
|
[Action.FUNC]: (action) => this.action_func(action),
|
||||||
[Action.RESULT]: (action) => this.action_result(action),
|
[Action.RESULT]: (action) => this.action_result(action),
|
||||||
|
[Action.PARAM]: (action) => this.action_param(action),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.exports = [];
|
this.exports = [];
|
||||||
@@ -187,6 +221,10 @@ export class Assembler {
|
|||||||
this.funcs[this.current_func].results.push(...action.results);
|
this.funcs[this.current_func].results.push(...action.results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_param(action) {
|
||||||
|
Object.assign(this.funcs[this.current_func].params, action.params);
|
||||||
|
}
|
||||||
|
|
||||||
push(chunk) {
|
push(chunk) {
|
||||||
const text = this.decoder.decode(chunk, { stream: true });
|
const text = this.decoder.decode(chunk, { stream: true });
|
||||||
for (const action of this.parser.handle(text))
|
for (const action of this.parser.handle(text))
|
||||||
|
|||||||
Reference in New Issue
Block a user