aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/vm.go
diff options
context:
space:
mode:
authorJM <jm@dexon.org>2019-01-31 15:12:57 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:03 +0800
commit9b8cd76237318e173147a7c32763b6b9d9759951 (patch)
tree44f860e1ed7e63354f48096ee5df0fa475719cc9 /core/vm/vm.go
parentd3b485a5af768db59bd648175849f961e25bc630 (diff)
downloaddexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar.gz
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar.bz2
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar.lz
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar.xz
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.tar.zst
dexon-9b8cd76237318e173147a7c32763b6b9d9759951.zip
core: vm: vm interface (#164)
Diffstat (limited to 'core/vm/vm.go')
-rw-r--r--core/vm/vm.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/core/vm/vm.go b/core/vm/vm.go
new file mode 100644
index 000000000..8d4dffd0b
--- /dev/null
+++ b/core/vm/vm.go
@@ -0,0 +1,105 @@
+package vm
+
+import (
+ "fmt"
+ "math/big"
+
+ "github.com/dexon-foundation/dexon/common"
+)
+
+const (
+ EVM = byte(iota)
+ SQLVM
+)
+
+var (
+ MULTIVM = true
+)
+
+type VM interface {
+ Create(ContractRef, []byte, uint64, *big.Int,
+ Interpreter) ([]byte, common.Address, uint64, error)
+ Create2(ContractRef, []byte, uint64, *big.Int, *big.Int,
+ Interpreter) ([]byte, common.Address, uint64, error)
+ Call(ContractRef, common.Address, []byte, uint64, *big.Int,
+ Interpreter) ([]byte, uint64, error)
+ CallCode(ContractRef, common.Address, []byte, uint64,
+ *big.Int, Interpreter) ([]byte, uint64, error)
+ DelegateCall(ContractRef, common.Address, []byte, uint64,
+ Interpreter) ([]byte, uint64, error)
+ StaticCall(ContractRef, common.Address, []byte, uint64,
+ Interpreter) ([]byte, uint64, error)
+}
+
+type Interpreter interface {
+ StateDB() StateDB
+}
+
+var vmList map[byte]VM
+
+func init() {
+ vmList = make(map[byte]VM)
+}
+func Register(vmType byte, vm VM) {
+ vmList[vmType] = vm
+}
+func Create(caller ContractRef, code []byte, gas uint64, value *big.Int,
+ interpreter Interpreter) (ret []byte, contractAddr common.Address,
+ leftOverGas uint64, err error) {
+
+ name, code := getVMAndCode(code)
+ return vmList[name].Create(caller, code, gas, value, interpreter)
+}
+
+func Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int,
+ salt *big.Int, interpreter Interpreter) (ret []byte,
+ contractAddr common.Address, leftOverGas uint64, err error) {
+
+ name, code := getVMAndCode(code)
+ return vmList[name].Create2(caller, code, gas, endowment, salt, interpreter)
+}
+
+func Call(caller ContractRef, addr common.Address, input []byte, gas uint64,
+ value *big.Int, interpreter Interpreter) (ret []byte, leftOverGas uint64, err error) {
+
+ code := interpreter.StateDB().GetCode(addr)
+ name, _ := getVMAndCode(code)
+ return vmList[name].Call(caller, addr, input, gas, value, interpreter)
+}
+
+func CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64,
+ value *big.Int, interpreter Interpreter) (ret []byte, leftOverGas uint64, err error) {
+
+ code := interpreter.StateDB().GetCode(addr)
+ name, _ := getVMAndCode(code)
+ return vmList[name].CallCode(caller, addr, input, gas, value, interpreter)
+}
+
+func DelegateCall(caller ContractRef, addr common.Address, input []byte,
+ gas uint64, interpreter Interpreter) (ret []byte, leftOverGas uint64, err error) {
+
+ code := interpreter.StateDB().GetCode(addr)
+ name, _ := getVMAndCode(code)
+ return vmList[name].DelegateCall(caller, addr, input, gas, interpreter)
+}
+
+func StaticCall(caller ContractRef, addr common.Address, input []byte,
+ gas uint64, interpreter Interpreter) (ret []byte, leftOverGas uint64, err error) {
+
+ code := interpreter.StateDB().GetCode(addr)
+ name, _ := getVMAndCode(code)
+ return vmList[name].StaticCall(caller, addr, input, gas, interpreter)
+}
+
+func getVMAndCode(code []byte) (byte, []byte) {
+ if MULTIVM && len(code) > 0 {
+ switch code[0] {
+ case EVM, SQLVM:
+ return code[0], code[1:]
+ default:
+ fmt.Printf("Unknow code prefix %x\n", code[0])
+ return EVM, code[1:]
+ }
+ }
+ return EVM, code
+}