diff --git a/cmd/wasm-run/main.go b/cmd/wasm-run/main.go index 578113c4..607d1f97 100644 --- a/cmd/wasm-run/main.go +++ b/cmd/wasm-run/main.go @@ -11,6 +11,8 @@ import ( "log" "os" + "github.com/go-interpreter/wagon/internal/emlibc" + "github.com/go-interpreter/wagon/exec" "github.com/go-interpreter/wagon/validate" "github.com/go-interpreter/wagon/wasm" @@ -95,6 +97,9 @@ func run(w io.Writer, fname string, verify bool) { } func importer(name string) (*wasm.Module, error) { + if name == "env" { + return emlibc.ResolveEnv(name) + } f, err := os.Open(name + ".wasm") if err != nil { return nil, err diff --git a/internal/emlibc/resolver.go b/internal/emlibc/resolver.go new file mode 100644 index 00000000..00ed719d --- /dev/null +++ b/internal/emlibc/resolver.go @@ -0,0 +1,114 @@ +package emlibc + +import ( + "errors" + "fmt" + "reflect" + + "github.com/go-interpreter/wagon/exec" + + "github.com/go-interpreter/wagon/wasm" +) + +func ResolveEnv(name string) (*wasm.Module, error) { + if name == "env" { + return GetEnv(), nil + } + fmt.Println("tried resolve", name) + return nil, errors.New("Not Found") +} +func clen(n []byte) int { + for i := 0; i < len(n); i++ { + if n[i] == 0 { + return i + } + } + return len(n) +} +func GetEnv() *wasm.Module { + + m := wasm.NewModule() + print := func(proc *exec.Process, v int32) int32 { + fmt.Printf("result = %v\n", v) + return 0 + } + puts := func(proc *exec.Process, v int32) int32 { + + buf := []byte{} + temp := make([]byte, 1) + for i := int(v); i < proc.MemSize(); i++ { + _, err := proc.ReadAt(temp, int64(i)) + if err != nil { + fmt.Println(err) + } + if temp[0] == 0 { + break + } + buf = append(buf, temp[0]) + } + fmt.Println(string(buf)) + return 0 + } + m.Types = &wasm.SectionTypes{ + Entries: []wasm.FunctionSig{ + { + Form: 0, // value for the 'func' type constructor + ParamTypes: []wasm.ValueType{wasm.ValueTypeI32}, + ReturnTypes: []wasm.ValueType{wasm.ValueTypeI32}, + }, + }, + } + m.GlobalIndexSpace = []wasm.GlobalEntry{ + { + Type: wasm.GlobalVar{ + Type: wasm.ValueTypeI32, + }, + Init: []byte{65, 0, 11}, + }, + } + // m.LinearMemoryIndexSpace = [][]byte{make([]byte, 256)} + m.Memory = &wasm.SectionMemories{ + Entries: []wasm.Memory{ + { + Limits: wasm.ResizableLimits{Initial: 1}, + }, + }, + } + m.FunctionIndexSpace = []wasm.Function{ + { + Sig: &m.Types.Entries[0], + Host: reflect.ValueOf(print), + Body: &wasm.FunctionBody{}, // create a dummy wasm body (the actual value will be taken from Host.) + }, + { + Sig: &m.Types.Entries[0], + Host: reflect.ValueOf(puts), + Body: &wasm.FunctionBody{}, // create a dummy wasm body (the actual value will be taken from Host.) + }, + } + m.Export = &wasm.SectionExports{ + Entries: map[string]wasm.ExportEntry{ + "print": { + FieldStr: "print", + Kind: wasm.ExternalFunction, + Index: 0, + }, + "_puts": { + FieldStr: "_puts", + Kind: wasm.ExternalFunction, + Index: 1, + }, + "__memory_base": { + FieldStr: "__memory_base", + Kind: wasm.ExternalGlobal, + Index: 0, + }, + "memory": { + FieldStr: "memory", + Kind: wasm.ExternalMemory, + Index: 0, + }, + }, + } + return m +} diff --git a/internal/emlibc/test/puts.go b/internal/emlibc/test/puts.go new file mode 100644 index 00000000..6dc8acf1 --- /dev/null +++ b/internal/emlibc/test/puts.go @@ -0,0 +1,3 @@ +//go:generate emcc -Os src/puts.c -s SIDE_MODULE=1 -o puts.wasm -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 + +package test diff --git a/internal/emlibc/test/puts.wasm b/internal/emlibc/test/puts.wasm new file mode 100644 index 00000000..915f303b Binary files /dev/null and b/internal/emlibc/test/puts.wasm differ diff --git a/internal/emlibc/test/puts.wasm.map b/internal/emlibc/test/puts.wasm.map new file mode 100644 index 00000000..6c5cabbf --- /dev/null +++ b/internal/emlibc/test/puts.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/puts.c"],"names":[],"mappings":"iIAIA,KACA"} \ No newline at end of file diff --git a/internal/emlibc/test/puts.wast b/internal/emlibc/test/puts.wast new file mode 100644 index 00000000..b7e81b16 --- /dev/null +++ b/internal/emlibc/test/puts.wast @@ -0,0 +1,35 @@ +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (data (global.get $__memory_base) "Hello") + (import "env" "__memory_base" (global $__memory_base i32)) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (memory $memory 1) + (global $STACKTOP (mut i32) (i32.const 0)) + (global $STACK_MAX (mut i32) (i32.const 0)) + (export "__post_instantiate" (func $__post_instantiate)) + (export "_main" (func $_main)) + (func $_main (; 1 ;) (; has Stack IR ;) (result i32) + ;;@ src/puts.c:5:0 + (drop + (call $_puts + (global.get $__memory_base) + ) + ) + ;;@ src/puts.c:6:0 + (i32.const 0) + ) + (func $__post_instantiate (; 2 ;) (; has Stack IR ;) + (global.set $STACKTOP + (i32.add + (global.get $__memory_base) + (i32.const 16) + ) + ) + (global.set $STACK_MAX + (i32.add + (global.get $STACKTOP) + (i32.const 5242880) + ) + ) + ) +) diff --git a/internal/emlibc/test/src/puts.c b/internal/emlibc/test/src/puts.c new file mode 100644 index 00000000..4a1744c4 --- /dev/null +++ b/internal/emlibc/test/src/puts.c @@ -0,0 +1,6 @@ +#include + + +int main(){ + puts("Hello"); +} \ No newline at end of file diff --git a/wasm/init_expr.go b/wasm/init_expr.go index 3a59fb3a..e05b37d0 100644 --- a/wasm/init_expr.go +++ b/wasm/init_expr.go @@ -144,7 +144,8 @@ func (m *Module) ExecInitExpr(expr []byte) (interface{}, error) { if globalVar == nil { return nil, InvalidGlobalIndexError(index) } - lastVal = globalVar.Type.Type + return m.ExecInitExpr(globalVar.Init) + // lastVal = globalVar.Type.Type case end: break default: @@ -155,7 +156,6 @@ func (m *Module) ExecInitExpr(expr []byte) (interface{}, error) { if len(stack) == 0 { return nil, nil } - v := stack[len(stack)-1] switch lastVal { case ValueTypeI32: