Skip to content

Commit

Permalink
feat(global): Implement get and set
Browse files Browse the repository at this point in the history
  • Loading branch information
jubianchi committed Oct 19, 2020
1 parent 270398e commit c088a11
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 1 deletion.
37 changes: 36 additions & 1 deletion wasmer/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package wasmer

// #include <wasmer_wasm.h>
import "C"
import "runtime"
import (
"runtime"
)

type Global struct {
_inner *C.wasm_global_t
Expand Down Expand Up @@ -38,3 +40,36 @@ func (self *Global) IntoExtern() *Extern {

return newExtern(pointer, self.ownedBy())
}

func (self *Global) Type() *GlobalType {
ty := C.wasm_global_type(self.inner())

runtime.KeepAlive(self)

return newGlobalType(ty, self.ownedBy())
}

func (self *Global) Set(value interface{}, kind ValueKind) error {
if self.Type().Mutability() == IMMUTABLE {
return newErrorWith("The global variable is not mutable, cannot set a new value")
}

result, err := fromGoValue(value, kind)

if err != nil {
//TODO: Make this error explicit
panic(err.Error())
}

C.wasm_global_set(self.inner(), &result)

return nil
}

func (self *Global) Get() (interface{}, error) {
var value C.wasm_val_t

C.wasm_global_get(self.inner(), &value)

return toGoValue(&value), nil
}
127 changes: 127 additions & 0 deletions wasmer/global_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package wasmer

import (
"github.com/stretchr/testify/assert"
"testing"
)

var TestBytes = []byte(`
(module
(global $x (export "x") (mut i32) (i32.const 0))
(global $y (export "y") (mut i32) (i32.const 7))
(global $z (export "z") i32 (i32.const 42))
(func (export "get_x") (result i32)
(global.get $x))
(func (export "increment_x")
(global.set $x
(i32.add (global.get $x) (i32.const 1)))))
`)

func instance(t *testing.T) *Instance {
engine := NewEngine()
store := NewStore(engine)
module, err := NewModule(store, TestBytes)

assert.NoError(t, err)

instance, err := NewInstance(module)

assert.NoError(t, err)

return instance
}

func TestExport(t *testing.T) {
x, err := instance(t).Exports.GetGlobal("x")
assert.NoError(t, err)
assert.IsType(t, &Global{}, x)
}

func TestType(t *testing.T) {
x, err := instance(t).Exports.GetGlobal("x")
assert.NoError(t, err)

ty := x.Type()
assert.Equal(t, ty.ValueType().Kind(), I32)
assert.Equal(t, ty.Mutability(), MUTABLE)
}

func TestGlobalMutable(t *testing.T) {
exports := instance(t).Exports

x, err := exports.GetGlobal("x")
assert.NoError(t, err)
assert.Equal(t, x.Type().Mutability(), MUTABLE)

y, err := exports.GetGlobal("y")
assert.NoError(t, err)
assert.Equal(t, y.Type().Mutability(), MUTABLE)

z, err := exports.GetGlobal("z")
assert.NoError(t, err)
assert.Equal(t, z.Type().Mutability(), IMMUTABLE)
}

func TestGlobalReadWrite(t *testing.T) {
y, err := instance(t).Exports.GetGlobal("y")
assert.NoError(t, err)

inititalValue, err := y.Get()
assert.NoError(t, err)
assert.Equal(t, int32(7), inititalValue)

err = y.Set(8, I32)
assert.NoError(t, err)

newValue, err := y.Get()
assert.NoError(t, err)
assert.Equal(t, int32(8), newValue)
}

func TestGlobalReadWriteAndExportedFunctions(t *testing.T) {
instance := instance(t)
x, err := instance.Exports.GetGlobal("x")
assert.NoError(t, err)

value, err := x.Get()
assert.NoError(t, err)
assert.Equal(t, int32(0), value)

err = x.Set(1, I32)
assert.NoError(t, err)

getX, err := instance.Exports.GetFunction("get_x")
assert.NoError(t, err)

result, err := getX()
assert.NoError(t, err)
assert.Equal(t, int32(1), result)

incrX, err := instance.Exports.GetFunction("increment_x")
assert.NoError(t, err)

_, err = incrX()
assert.NoError(t, err)

result, err = getX()
assert.NoError(t, err)
assert.Equal(t, int32(2), result)
}

func TestGlobalReadWriteConstant(t *testing.T) {
z, err := instance(t).Exports.GetGlobal("z")
assert.NoError(t, err)

value, err := z.Get()
assert.NoError(t, err)
assert.Equal(t, int32(42), value)

err = z.Set(153, I32)
assert.Error(t, err)

value, err = z.Get()
assert.NoError(t, err)
assert.Equal(t, int32(42), value)
}

0 comments on commit c088a11

Please sign in to comment.