Compare commits

..

6 Commits

54
asm.js
View File

@@ -106,6 +106,7 @@ const State = Object.freeze({
ELEM_TABLE: 33,
ELEM_ELEM: 34,
ELEM_LABEL: 35,
ZERO: 36,
});
const Action = Object.freeze({
@@ -161,6 +162,7 @@ const opcodes = {
"i32.store": 0x36,
"i32.store8": 0x3a,
"i32.const": 0x41,
"i64.const": 0x42,
"i32.eqz": 0x45,
"i32.eq": 0x46,
"i32.ne": 0x47,
@@ -175,6 +177,8 @@ const opcodes = {
"i32.add": 0x6a,
"i32.sub": 0x6b,
"i32.mul": 0x6c,
"i32.div_s": 0x6d,
"i32.rem_s": 0x6f,
"i32.and": 0x71,
"i32.or": 0x72,
"i32.xor": 0x73,
@@ -185,10 +189,10 @@ const opcodes = {
// Threads instructions
"memory.atomic.notify": [ 0xfe, 0x00 ],
"memory.atomic.wait32": [ 0xfe, 0x01 ],
"memory.atomic.load": [ 0xfe, 0x10 ],
"memory.atomic.load8_u": [ 0xfe, 0x12 ],
"memory.atomic.store": [ 0xfe, 0x17 ],
"memory.atomic.store8": [ 0xfe, 0x19 ],
"i32.atomic.load": [ 0xfe, 0x10 ],
"i32.atomic.load8_u": [ 0xfe, 0x12 ],
"i32.atomic.store": [ 0xfe, 0x17 ],
"i32.atomic.store8": [ 0xfe, 0x19 ],
};
const mem_flags = {
@@ -225,6 +229,7 @@ class Parser {
".type": State.TYPE_NAME,
".table": State.TABLE_NAME,
".elem": State.ELEM_TABLE,
".zero": State.ZERO,
};
this.blocks = new Set(["block", "loop", "if"]);
this.handlers = {
@@ -264,6 +269,7 @@ class Parser {
[State.ELEM_TABLE]: (token) => this.token_elem_table(token),
[State.ELEM_ELEM]: (token) => this.token_elem_elem(token),
[State.ELEM_LABEL]: (token) => this.token_elem_label(token),
[State.ZERO]: (token) => this.token_zero(token),
};
this.results = [];
@@ -547,15 +553,10 @@ class Parser {
token_at_addr(token) {
const value = this.integer(token);
if (value == null) {
console.error(
`ERROR: Unexpected token ${token} in .mem: `
+ "expected address");
this.at = undefined;
return;
}
if (value != null)
this.at.addr = value;
else
this.at.addr_symbol = token;
const action = { type: Action.AT, at: this.at };
this.at = undefined;
this.state = State.TOP;
@@ -823,6 +824,26 @@ class Parser {
return action;
}
token_zero(token) {
if (token == LINE_END) {
console.error(
"ERROR: Unexpected newline in .zero, expected count")
this.state = State.TOP;
return;
}
const count = this.integer(token);
if (count == null) {
console.error(
`ERROR: Unexpected token ${token} in .zero, expected count`);
this.state = State.TOP;
return;
}
this.state = State.TOP;
return { type: Action.DATA, size: count, value: 0 }
}
mem_action() {
const action = {
type: Action.MEM,
@@ -963,7 +984,7 @@ export class Assembler {
}
func.body.push(...this.leb128(def_value));
} else {
func.body.push(...this.leb128(value));
func.body.push(...this.uleb128(value));
}
}
@@ -995,7 +1016,8 @@ export class Assembler {
return;
}
this.pos.mem = mem;
this.pos.addr = action.at.addr;
this.pos.addr = action.at.addr
?? this.lookup_def(action.at.addr_symbol);
this.data.push({ loc: { ...this.pos }, data: [] })
}
@@ -1327,7 +1349,9 @@ export class Assembler {
];
const sections = template.map(([ code, generator ]) => {
const body = generator();
return body == null ? [] : [ code, body.length, body ];
if (body == null)
return [];
return [ code, this.uleb128(body.length), body ];
});
return new Uint8Array([ HEADER, sections ].flat(Infinity));