wasm-chisel icon indicating copy to clipboard operation
wasm-chisel copied to clipboard

feature for adding wat functions to a wasm file

Open cdetrio opened this issue 6 years ago • 2 comments

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)
)

cdetrio avatar May 28 '19 14:05 cdetrio

Practically this is a form of module linking.

axic avatar Jun 02 '19 20:06 axic

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, and call_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.

poemm avatar Jul 17 '19 12:07 poemm