Skip to content

Instantly share code, notes, and snippets.

@gballet
Created May 1, 2018 12:51
Show Gist options
  • Save gballet/ff599598aaf13f252ed7de2f5c08439f to your computer and use it in GitHub Desktop.
Save gballet/ff599598aaf13f252ed7de2f5c08439f to your computer and use it in GitHub Desktop.
A golang test related to some hacks in go-interpreter/wagon that would let WASM code execute native code.
package exec
import (
"reflect"
"testing"
"github.com/go-interpreter/wagon/wasm"
)
const secretValue = 0xdeadbeef
var secretVariable int = 0
// a native function that can be called by WASM code.
func testNativeFunction() {
secretVariable = secretValue
}
func TestNativeCall(t *testing.T) {
// validate.VerifyModule
testNativeModule := &wasm.Module{
Types: &wasm.SectionTypes{},
Import: &wasm.SectionImports{},
Table: &wasm.SectionTables{},
Memory: &wasm.SectionMemories{},
Global: &wasm.SectionGlobals{},
Export: &wasm.SectionExports{},
Start: &wasm.SectionStartFunction{Index: 0},
Elements: &wasm.SectionElements{},
Data: &wasm.SectionData{},
NativeFunctions: []reflect.Value{reflect.ValueOf(testNativeFunction)},
}
// A function signature. Both the native and WASM function
// have the same signature.
fsig := wasm.FunctionSig{
Form: 0,
ParamTypes: []wasm.ValueType{},
ReturnTypes: []wasm.ValueType{},
}
// List of all function types available in this module.
// There is only one: (func [] -> [])
testNativeModule.Types = &wasm.SectionTypes{
Entries: []wasm.FunctionSig{fsig, fsig},
}
testNativeModule.Function = &wasm.SectionFunctions{
Types: []uint32{0, 0},
}
// The body of the start function, that should only
// call the native function
fb := wasm.FunctionBody{
Module: testNativeModule,
Locals: []wasm.LocalEntry{},
// code should disassemble to:
// call 1 (which is native)
// end
Code: []byte{0x02, 0x00, 0x10, 0x01, 0x0b},
}
// There was no call to `ReadModule` so this part emulates
// how the module object would look like if the function
// had been called.
testNativeModule.FunctionIndexSpace = []wasm.Function{
wasm.Function{
Sig: &fsig,
Body: &fb,
},
wasm.Function{
Sig: &fsig,
Native: true,
},
}
testNativeModule.Code = &wasm.SectionCode{
Bodies: []wasm.FunctionBody{fb},
}
// Once called, NewVM will execute the module's main
// function.
vm, err := NewVM(testNativeModule)
if err != nil {
t.Fatalf("Error creating VM: %v", vm)
}
if len(vm.compiledFuncs) < 1 {
t.Fatalf("Need at least a start function!")
}
// Only one entry, which should be a function
if secretVariable != secretValue {
t.Fatalf("x is %d instead of %d", secretVariable, secretValue)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment