Skip to content

Commit

Permalink
Merge #55
Browse files Browse the repository at this point in the history
55: feat(memory) Add the `Memory.Grow` method r=Hywan a=Hywan

Fix #52.

This method can be used to grow the memory by a number of pages (65kb each).

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
  • Loading branch information
bors[bot] and Hywan committed Jul 8, 2019
2 parents 74c35c0 + 95898f9 commit f819ba8
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
7 changes: 7 additions & 0 deletions wasmer/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ func cWasmerMemoryDataLength(memory *cWasmerMemoryT) cUint32T {
))
}

func cWasmerMemoryGrow(memory *cWasmerMemoryT, numberOfPages cUint32T) cWasmerResultT {
return (cWasmerResultT)(C.wasmer_memory_grow(
(*C.wasmer_memory_t)(memory),
(C.uint32_t)(numberOfPages),
))
}

func cWasmerModuleDeserialize(module **cWasmerModuleT, serializedModule *cWasmerSerializedModuleT) cWasmerResultT {
return (cWasmerResultT)(C.wasmer_module_deserialize(
(**C.wasmer_module_t)(unsafe.Pointer(module)),
Expand Down
39 changes: 39 additions & 0 deletions wasmer/memory.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
package wasmer

import (
"fmt"
"reflect"
"unsafe"
)

// MemoryError represents any kind of errors related to a WebAssembly memory. It
// is returned by `Memory` functions only.
type MemoryError struct {
// Error message.
message string
}

// NewMemoryError constructs a new `MemoryError`.
func NewMemoryError(message string) *MemoryError {
return &MemoryError{message}
}

// `MemoryError` is an actual error. The `Error` function returns
// the error message.
func (error *MemoryError) Error() string {
return error.message
}

// Memory represents an exported memory of a WebAssembly instance. To read
// and write data, please see the `Data` function.
type Memory struct {
Expand Down Expand Up @@ -35,3 +54,23 @@ func (memory *Memory) Data() []byte {

return *(*[]byte)(unsafe.Pointer(&header))
}

// Grow the memory by a number of pages (65kb each).
func (memory *Memory) Grow(numberOfPages uint32) error {
var growResult = cWasmerMemoryGrow(memory.memory, cUint32T(numberOfPages))

if growResult != cWasmerOk {
var lastError, err = GetLastError()
var errorMessage = "Failed to grow the memory:\n %s"

if err != nil {
errorMessage = fmt.Sprintf(errorMessage, "(unknown details)")
} else {
errorMessage = fmt.Sprintf(errorMessage, lastError)
}

return NewMemoryError(errorMessage)
}

return nil
}
28 changes: 28 additions & 0 deletions wasmer/test/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,31 @@ func TestMemoryDataReadWrite(t *testing.T) {

assert.Equal(t, "Aello, World!", string(memory3[pointer:pointer+13]))
}

func TestMemoryGrow(t *testing.T) {
instance, _ := wasm.NewInstance(GetBytes())
defer instance.Close()

memory := instance.Memory
oldMemoryLength := memory.Length()

assert.Equal(t, uint32(1114112), oldMemoryLength)

err := memory.Grow(1)

assert.NoError(t, err)

memoryLength := memory.Length()

assert.Equal(t, uint32(1179648), memoryLength)
assert.Equal(t, uint32(65536), memoryLength-oldMemoryLength)
}

func TestMemoryGrowTooMuch(t *testing.T) {
instance, _ := wasm.NewInstance(GetBytes())
defer instance.Close()

err := instance.Memory.Grow(100000)

assert.EqualError(t, err, "Failed to grow the memory:\n Grow Error: Failed to add pages because would exceed maximum number of pages. Left: 17, Right: 100000, Pages added: 100017")
}

0 comments on commit f819ba8

Please sign in to comment.