Skip to content

Commit

Permalink
Flatten id, deref
Browse files Browse the repository at this point in the history
  • Loading branch information
dy committed Dec 16, 2024
1 parent fc4c0c3 commit b023877
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 22 deletions.
28 changes: 9 additions & 19 deletions src/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default (nodes) => {
if (typeof nodes === 'string') nodes = parse(nodes); else nodes = [...nodes]

// module abbr https://webassembly.github.io/spec/core/text/modules.html#id10
if (nodes[0] === 'module') nodes.shift(), id(nodes)
if (nodes[0] === 'module') nodes.shift(), typeof nodes[0] === 'string' && nodes.shift()
// single node, not module
else if (typeof nodes[0] === 'string') nodes = [nodes]

Expand Down Expand Up @@ -50,7 +50,7 @@ export default (nodes) => {

for (let [kind, ...node] of nodes) {
// index, alias
let name = id(node), idx = nodeGroups[kind].length;
let name = node[0]?.[0] === '$' ? node.shift() : null, idx = nodeGroups[kind].length;
if (name) sections[kind][name] = idx; // save alias

// export abbr
Expand Down Expand Up @@ -81,8 +81,7 @@ export default (nodes) => {
// FIXME: can be turned into shallow node
if (kind === 'import') {
let [mod, field, [kind, ...dfn]] = node
let name = id(dfn)
if (name) sections[kind][name] = nodeGroups[kind].length
if (dfn[0]?.[0] === '$') sections[kind][dfn.shift()] = nodeGroups[kind].length
nodeGroups[kind].length++
node[2] = [kind, ...dfn]
}
Expand Down Expand Up @@ -117,12 +116,6 @@ export default (nodes) => {
return new Uint8Array(binary)
}

// consume $id
const id = nodes => nodes[0]?.[0] === '$' && nodes.shift()

// inject $id
const deref = (nodes, dict) => nodes[0][0] === '$' ? dict[nodes.shift()] : +nodes.shift()

// abbr for blocks, loops, ifs
// https://webassembly.github.io/spec/core/text/instructions.html#folded-instructions
const unfold = nodes => {
Expand All @@ -148,8 +141,7 @@ const unfold = nodes => {
if (node[node.length - 1]?.[0] === 'then') thenelse.unshift(...node.pop())

// label?
let name = id(node)
if (name) blocktype.push(name)
if (node[0]?.[0] === '$') blocktype.push(node.shift())
// blocktype?
while (['type', 'param', 'result'].includes(node[0]?.[0])) blocktype.push(node.shift());

Expand Down Expand Up @@ -397,8 +389,7 @@ const instr = (nodes, ctx) => {
ctx.block.push(opCode)

// (block $x) (loop $y)
let name = id(nodes)
if (name) ctx.block[name] = ctx.block.length
if (nodes[0]?.[0] === '$') ctx.block[nodes.shift()] = ctx.block.length

// get type - can be either typeidx or valtype (numtype | reftype)
// (result i32) - doesn't require registering type
Expand Down Expand Up @@ -488,7 +479,7 @@ const instr = (nodes, ctx) => {

// ref.func $id
else if (opCode == 0xd2) {
immed = uleb(deref(nodes, ctx.func))
immed = uleb(nodes[0][0] === '$' ? ctx.func[nodes.shift()] : +nodes.shift())
}

// ref.null
Expand All @@ -513,18 +504,17 @@ const instr = (nodes, ctx) => {

// (local.get $id), (local.tee $id x)
else if (opCode >= 0x20 && opCode <= 0x22) {
immed = uleb(deref(nodes, ctx.local))
immed = uleb(nodes[0][0] === '$' ? ctx.local[nodes.shift()] : +nodes.shift())
}

// (global.get $id), (global.set $id)
else if (opCode == 0x23 || opCode == 0x24) {
immed = uleb(deref(nodes, ctx.global))
immed = uleb(nodes[0][0] === '$' ? ctx.global[nodes.shift()] : +nodes.shift())
}

// (call id ...nodes)
else if (opCode == 0x10) {
let name = id(nodes)
immed = uleb(name ? ctx.func[name] : +nodes.shift());
immed = uleb(nodes[0]?.[0] === '$' ? ctx.func[nodes.shift()] : +nodes.shift());
// FIXME: how to get signature of imported function
}

Expand Down
6 changes: 3 additions & 3 deletions todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
* [x] split generic precompile into section builders as was in v1
* [x] ~~introduce more complete ref/deref use~~ -> we can't really solve full hoisting issue (types, code refs)
* [x] make IR: types indexing, code deferring
* [ ] make generic consuming ops for instructions instead of condition checks
* [ ] flatten (deabbr) ops
* [x] ~~make generic consuming ops for instructions instead of condition checks~~ -> it's too metaphysical & unclear how to handle generic cases
* [ ] flatten (deabbr) ops (if makes sense)
* [x] make func init code immediately instead of duplicating code
* [ ] make use of expr inside of code section, !mb instr groups?
* [ ] make use of expr inside of code section, !mb instr groups? Or better use instr instead of expr for wider support (extrapolate standard)
* [ ] streamline sections parsing/build (no intermediary array)
* [x] elem all use-cases
* [ ] Print: make it as nice as AI
Expand Down

0 comments on commit b023877

Please sign in to comment.