Last active
June 13, 2024 12:02
-
-
Save onliniak/bed0a28ebbca2d3403a8163fe87dba44 to your computer and use it in GitHub Desktop.
WAMR C Bindings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@[Link("iwasm")] | |
lib LibWasm | |
struct WASMModuleCommon | |
buffer : UInt8* | |
binary_file : UInt32 | |
io_error : LibC::Char* | |
io_error_bytesize : UInt32 | |
end | |
struct WASMModuleInstanceCommon | |
mymodule : WASMModuleCommon* | |
stack_size : UInt32 | |
heap_size : UInt32 | |
io_error : LibC::Char* | |
io_error_bytesize : UInt32 | |
end | |
struct WASMExecEnv | |
module_inst : WASMModuleInstanceCommon* | |
stack_size : UInt32 | |
end | |
struct WASMFunctionInstanceCommon | |
module_inst : WASMModuleInstanceCommon* | |
func_name : LibC::Char* | |
func_signature : LibC::Char* | |
end | |
fun wasm_runtime_init : Bool | |
# fun read_wasm_binary_to_buffer(LibC::Char*, Int32) : LibC::Char* | |
fun wasm_runtime_load(UInt8*, UInt32, LibC::Char*, UInt32) : WASMModuleCommon* | |
fun wasm_runtime_instantiate(WASMModuleCommon*, UInt32, UInt32, LibC::Char*, UInt32) : WASMModuleInstanceCommon* | |
fun wasm_runtime_lookup_function(WASMModuleInstanceCommon*, LibC::Char*, LibC::Char*) : WASMFunctionInstanceCommon* | |
fun wasm_runtime_create_exec_env(WASMModuleInstanceCommon*, UInt32) : WASMExecEnv* | |
fun wasm_runtime_call_wasm(WASMExecEnv*, WASMFunctionInstanceCommon*, UInt32, Int32*) : Bool | |
fun wasm_runtime_get_exception(WASMModuleInstanceCommon*) : LibC::Char* | |
fun wasm_runtime_destroy_exec_env(WASMExecEnv*) | |
fun wasm_runtime_deinstantiate(WASMModuleInstanceCommon*) | |
fun wasm_runtime_unload(WASMModuleCommon*) | |
fun wasm_runtime_destroy : Nil | |
end | |
def exec(wasm_file : String, argv : Array(Int32), io_error = IO::Memory.new, stack_size = 8092, heap_size = 8092) | |
# initialize the wasm runtime by default configurations | |
LibWasm.wasm_runtime_init | |
# read WASM file into a memory buffer | |
# buffer = LibWasm.read_wasm_binary_to_buffer(wasm_file, wasm_file.bytesize); | |
# parse the WASM file from buffer and create a WASM module | |
mymodule = LibWasm.wasm_runtime_load(wasm_file, wasm_file.size, io_error.to_s, io_error.bytesize) | |
# create an instance of the WASM module (WASM linear memory is ready) | |
module_inst = LibWasm.wasm_runtime_instantiate(mymodule, stack_size, heap_size, io_error.to_s, io_error.bytesize) | |
# lookup a WASM function by its name | |
# The function signature can NULL here | |
func = LibWasm.wasm_runtime_lookup_function(module_inst, "fib", "(i32i32)") | |
# creat an execution environment to execute the WASM functions | |
exec_env = LibWasm.wasm_runtime_create_exec_env(module_inst, stack_size) | |
# call the WASM function | |
if LibWasm.wasm_runtime_call_wasm(exec_env, func, argv.size, argv) | |
# the return value is stored in argv[0] | |
# 1 = Number of arguments | |
# argv = array of arguments | |
p "fib function return: #{argv[0]}" | |
else | |
LibWasm.wasm_runtime_get_exception(module_inst) | |
# exception is thrown if call fails | |
end | |
LibWasm.wasm_runtime_destroy_exec_env(exec_env) | |
LibWasm.wasm_runtime_deinstantiate(module_inst) | |
LibWasm.wasm_runtime_unload(mymodule) | |
LibWasm.wasm_runtime_destroy | |
end | |
# usage | |
argv = Array(Int32).new | |
argv << 8 | |
exec(File.read("fib.wasm"), argv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(module | |
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) | |
(type $i32_=>_i32 (func (param i32) (result i32))) | |
(memory $0 0) | |
(export "add" (func $src/index/add)) | |
(export "add2" (func $src/index/add2)) | |
(export "sub" (func $src/index/sub)) | |
(export "mul" (func $src/index/mul)) | |
(export "div" (func $src/index/div)) | |
(export "pow" (func $src/index/pow)) | |
(export "memory" (memory $0)) | |
(func $src/index/add (param $0 i32) (param $1 i32) (result i32) | |
local.get $0 | |
local.get $1 | |
i32.add | |
) | |
(func $src/index/add2 (param $0 i32) (result i32) | |
local.get $0 | |
i32.const 2 | |
i32.add | |
) | |
(func $src/index/sub (param $0 i32) (param $1 i32) (result i32) | |
local.get $0 | |
local.get $1 | |
i32.sub | |
) | |
(func $src/index/mul (param $0 i32) (param $1 i32) (result i32) | |
local.get $0 | |
local.get $1 | |
i32.mul | |
) | |
(func $src/index/div (param $0 i32) (param $1 i32) (result i32) | |
local.get $0 | |
local.get $1 | |
i32.div_s | |
) | |
(func $src/index/pow (param $0 i32) (param $1 i32) (result i32) | |
(local $2 i32) | |
block $__inlined_func$~lib/math/ipow32 (result i32) | |
i32.const 1 | |
local.set $2 | |
i32.const 1 | |
local.get $1 | |
i32.shl | |
i32.const 0 | |
local.get $1 | |
i32.const 32 | |
i32.lt_u | |
select | |
local.get $0 | |
i32.const 2 | |
i32.eq | |
br_if $__inlined_func$~lib/math/ipow32 | |
drop | |
local.get $1 | |
i32.const 0 | |
i32.le_s | |
if | |
i32.const -1 | |
i32.const 1 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.get $0 | |
i32.const -1 | |
i32.eq | |
br_if $__inlined_func$~lib/math/ipow32 | |
drop | |
local.get $1 | |
i32.eqz | |
local.get $0 | |
i32.const 1 | |
i32.eq | |
i32.or | |
br $__inlined_func$~lib/math/ipow32 | |
else | |
local.get $1 | |
i32.const 1 | |
i32.eq | |
if | |
local.get $0 | |
br $__inlined_func$~lib/math/ipow32 | |
else | |
local.get $1 | |
i32.const 2 | |
i32.eq | |
if | |
local.get $0 | |
local.get $0 | |
i32.mul | |
br $__inlined_func$~lib/math/ipow32 | |
else | |
local.get $1 | |
i32.const 32 | |
i32.lt_s | |
if | |
block $break|0 | |
block $case4|0 | |
block $case3|0 | |
block $case2|0 | |
block $case1|0 | |
block $case0|0 | |
i32.const 31 | |
local.get $1 | |
i32.clz | |
i32.sub | |
br_table $case4|0 $case3|0 $case2|0 $case1|0 $case0|0 $break|0 | |
end | |
local.get $0 | |
i32.const 1 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
local.get $1 | |
i32.const 1 | |
i32.shr_u | |
local.set $1 | |
local.get $0 | |
local.get $0 | |
i32.mul | |
local.set $0 | |
end | |
local.get $0 | |
local.get $2 | |
i32.mul | |
local.get $2 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
local.get $1 | |
i32.const 1 | |
i32.shr_u | |
local.set $1 | |
local.get $0 | |
local.get $0 | |
i32.mul | |
local.set $0 | |
end | |
local.get $0 | |
local.get $2 | |
i32.mul | |
local.get $2 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
local.get $1 | |
i32.const 1 | |
i32.shr_u | |
local.set $1 | |
local.get $0 | |
local.get $0 | |
i32.mul | |
local.set $0 | |
end | |
local.get $0 | |
local.get $2 | |
i32.mul | |
local.get $2 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
local.get $1 | |
i32.const 1 | |
i32.shr_u | |
local.set $1 | |
local.get $0 | |
local.get $0 | |
i32.mul | |
local.set $0 | |
end | |
local.get $0 | |
local.get $2 | |
i32.mul | |
local.get $2 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
end | |
local.get $2 | |
br $__inlined_func$~lib/math/ipow32 | |
end | |
end | |
end | |
end | |
loop $while-continue|1 | |
local.get $1 | |
if | |
local.get $0 | |
local.get $2 | |
i32.mul | |
local.get $2 | |
local.get $1 | |
i32.const 1 | |
i32.and | |
select | |
local.set $2 | |
local.get $1 | |
i32.const 1 | |
i32.shr_u | |
local.set $1 | |
local.get $0 | |
local.get $0 | |
i32.mul | |
local.set $0 | |
br $while-continue|1 | |
end | |
end | |
local.get $2 | |
end | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(module | |
(type (;0;) (func (param i32) (result i32))) | |
(func (;0;) (type 0) (param i32) (result i32) | |
local.get 0 | |
i32.const 1 | |
i32.eq | |
if ;; label = @1 | |
i32.const 1 | |
return | |
end | |
local.get 0 | |
i32.const 2 | |
i32.eq | |
if ;; label = @1 | |
i32.const 1 | |
return | |
end | |
local.get 0 | |
i32.const 1 | |
i32.sub | |
local.get 0 | |
i32.const 2 | |
i32.sub | |
call 0 | |
i32.add) | |
(func (;1;) (type 0) (param i32) (result i32) | |
(local i32 i32 i32 i32) | |
i32.const 1 | |
local.set 1 | |
i32.const 1 | |
local.set 2 | |
i32.const 2 | |
local.set 4 | |
local.get 0 | |
i32.const 0 | |
i32.le_s | |
if ;; label = @1 | |
i32.const 0 | |
return | |
end | |
local.get 0 | |
i32.const 1 | |
i32.eq | |
if ;; label = @1 | |
i32.const 1 | |
return | |
end | |
loop ;; label = @1 | |
local.get 4 | |
local.get 0 | |
i32.lt_s | |
if ;; label = @2 | |
local.get 1 | |
local.get 2 | |
i32.add | |
local.set 3 | |
local.get 2 | |
local.set 1 | |
local.get 3 | |
local.set 2 | |
local.get 4 | |
i32.const 1 | |
i32.add | |
local.set 4 | |
br 1 (;@1;) | |
end | |
end | |
local.get 2) | |
(export "fib" (func 1)) | |
(export "fib_iterative" (func 1)) | |
(export "fib_recursive" (func 1))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To coś pokazuje jak mając zerową wiedzę z C użyłem biblioteki w tym języku. Możliwe, że wcześniejsze wersje pomogą Ci zrozumieć błędy jakie popełniasz.