Created
May 1, 2018 12:51
-
-
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.
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
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