github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/wasm/wasm.go (about) 1 package wasm 2 3 import ( 4 "github.com/hyperledger/burrow/acm" 5 "github.com/hyperledger/burrow/acm/acmstate" 6 "github.com/hyperledger/burrow/execution/defaults" 7 "github.com/hyperledger/burrow/execution/engine" 8 "github.com/hyperledger/burrow/execution/errors" 9 "github.com/hyperledger/burrow/execution/exec" 10 "github.com/hyperledger/burrow/execution/native" 11 lifeExec "github.com/perlin-network/life/exec" 12 ) 13 14 // Implements ewasm, see https://github.com/ewasm/design 15 // WASM 16 var DefaultVMConfig = lifeExec.VMConfig{ 17 DisableFloatingPoint: true, 18 MaxMemoryPages: 16, 19 DefaultMemoryPages: 16, 20 } 21 22 type WVM struct { 23 engine.Externals 24 options engine.Options 25 vmConfig lifeExec.VMConfig 26 externalDispatcher engine.Dispatcher 27 } 28 29 func New(options engine.Options) *WVM { 30 vm := &WVM{ 31 options: defaults.CompleteOptions(options), 32 vmConfig: DefaultVMConfig, 33 } 34 vm.externalDispatcher = engine.Dispatchers{&vm.Externals, options.Natives, vm} 35 return vm 36 } 37 38 func Default() *WVM { 39 return New(engine.Options{}) 40 } 41 42 // RunWASM creates a WASM VM, and executes the given WASM contract code 43 func (vm *WVM) Execute(st acmstate.ReaderWriter, blockchain engine.Blockchain, eventSink exec.EventSink, 44 params engine.CallParams, code []byte) (output []byte, cerr error) { 45 defer func() { 46 if r := recover(); r != nil { 47 cerr = errors.Codes.ExecutionAborted 48 } 49 }() 50 51 st = native.NewState(vm.options.Natives, st) 52 53 state := engine.State{ 54 CallFrame: engine.NewCallFrame(st).WithMaxCallStackDepth(vm.options.CallStackMaxDepth), 55 Blockchain: blockchain, 56 EventSink: eventSink, 57 } 58 59 output, err := vm.Contract(code).Call(state, params) 60 61 if err == nil { 62 // Only sync back when there was no exception 63 err = state.CallFrame.Sync() 64 } 65 // Always return output - we may have a reverted exception for which the return is meaningful 66 return output, err 67 } 68 69 func (vm *WVM) Dispatch(acc *acm.Account) engine.Callable { 70 if len(acc.WASMCode) == 0 { 71 return nil 72 } 73 return vm.Contract(acc.WASMCode) 74 } 75 76 func (vm *WVM) Contract(code []byte) *Contract { 77 return &Contract{ 78 vm: vm, 79 code: code, 80 } 81 }