wasm-chisel
wasm-chisel copied to clipboard
feature for adding wat functions to a wasm file
Suppose you have a wasm file like this:
(module $chiselExample
(type $t2 (func (param i32 i32) (result i32)))
(import "ewasm" "addmod" (func $addmod256 (type $t2)))
(export "main" (func $main))
(func $main (result i32)
(local $pointx i32) (local $pointy i32)
(i64.store (i32.const 0) (i64.const 7771015739068247266)) ;; point.x
(i64.store (i32.const 8) (i64.const 15978182637586970136))
(i64.store (i32.const 16) (i64.const 1690519934368996064))
(i64.store (i32.const 24) (i64.const 630815934106406715))
(local.set $pointx (i32.const 0))
(i64.store (i32.const 32) (i64.const 13209253545858841660)) ;; point.y
(i64.store (i32.const 40) (i64.const 1023134550666483074))
(i64.store (i32.const 48) (i64.const 13677454995611397236))
(i64.store (i32.const 56) (i64.const 249532354227923480))
(local.set $pointy (i32.const 32))
(call $addmod256
(local.get $pointx) (local.get $pointy))
(return)
)
(memory $memory (export "memory") 50)
)
Above, the $addmod256 function is an imported host function. But suppose you also have a wasm implementation of that function:
(module $addmodForChisel
(type $t2 (func (param i32 i32) (result i32)))
(func $addmod256 (type $t2)
(param $pointx i32) (param $pointy i32)
(result $resultx i32)
;; bunch of hand-written wast code...
(return)
)
)
If you'd like to use the wasm function instead of the host function, it would be useful if chisel could paste the code for $addmod256 from the second file into the first file, producing a wasm module like this:
(module $chiselExample
(type $t2 (func (param i32 i32) (result i32)))
(export "main" (func $main))
(func $main (result i32)
(local $pointx i32) (local $pointy i32)
(i64.store (i32.const 0) (i64.const 7771015739068247266)) ;; point.x
(i64.store (i32.const 8) (i64.const 15978182637586970136))
(i64.store (i32.const 16) (i64.const 1690519934368996064))
(i64.store (i32.const 24) (i64.const 630815934106406715))
(local.set $pointx (i32.const 0))
(i64.store (i32.const 32) (i64.const 13209253545858841660)) ;; point.y
(i64.store (i32.const 40) (i64.const 1023134550666483074))
(i64.store (i32.const 48) (i64.const 13677454995611397236))
(i64.store (i32.const 56) (i64.const 249532354227923480))
(local.set $pointy (i32.const 32))
(call $addmod256
(local.get $pointx) (local.get $pointy))
(return)
)
(func $addmod256 (type $t2)
(param $pointx i32) (param $pointy i32)
(result $resultx i32)
;; bunch of hand-written wast code...
(return)
)
(memory $memory (export "memory") 50)
)
Practically this is a form of module linking.
Some thoughts about merging a function into a module:
- Obviously, the type section, function section, and code section must all include everything needed.
- Validation has some checks related to
globals,tables,calls, andcall_indirects. - Conventions may be used by the code. For example, LLVM can generate code which uses a shadow stack, so it may be difficult to merge with other wasm which does not follow the shadow-stack conventions.
Edit: I can prototype this in PyWebAssembly if it must be automated.