mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Runtime data and storage support callback functions
This commit is contained in:
parent
4aabaa1553
commit
8e9db3e1bc
2 changed files with 108 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -10,3 +10,5 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/**/.DS_Store
|
*/**/.DS_Store
|
||||||
.ethtest
|
.ethtest
|
||||||
|
*.project
|
||||||
|
/.settings/
|
||||||
|
|
|
||||||
108
vm/vm_jit.go
108
vm/vm_jit.go
|
|
@ -16,17 +16,104 @@ import "reflect"
|
||||||
|
|
||||||
type JitVm struct {
|
type JitVm struct {
|
||||||
env Environment
|
env Environment
|
||||||
|
myAddress []byte
|
||||||
backup *DebugVm
|
backup *DebugVm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type i256 [32]byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
Gas = iota
|
||||||
|
address
|
||||||
|
Caller
|
||||||
|
Origin
|
||||||
|
CallValue
|
||||||
|
CallDataSize
|
||||||
|
GasPrice
|
||||||
|
CoinBase
|
||||||
|
TimeStamp
|
||||||
|
Number
|
||||||
|
Difficulty
|
||||||
|
GasLimit
|
||||||
|
CodeSize
|
||||||
|
|
||||||
|
_size
|
||||||
|
|
||||||
|
ReturnDataOffset = CallValue // Reuse 2 fields for return data reference
|
||||||
|
ReturnDataSize = CallDataSize
|
||||||
|
SuicideDestAddress = address ///< Suicide balance destination address
|
||||||
|
)
|
||||||
|
|
||||||
|
type RuntimeData struct {
|
||||||
|
elems [_size]i256
|
||||||
|
callData *byte
|
||||||
|
code *byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash2llvm(h []byte) i256 {
|
||||||
|
var m i256
|
||||||
|
copy(m[len(m) - len(h):], h) // right aligned copy
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func llvm2hash(m *i256) []byte {
|
||||||
|
hdr := reflect.SliceHeader{
|
||||||
|
Data: uintptr(unsafe.Pointer(m)),
|
||||||
|
Len: int(len(m)),
|
||||||
|
Cap: int(len(m)),
|
||||||
|
}
|
||||||
|
return *(*[]byte)(unsafe.Pointer(&hdr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func big2llvm(n *big.Int) i256 {
|
||||||
|
m := hash2llvm(n.Bytes())
|
||||||
|
for i, l := 0, len(m); i < l / 2; i++ {
|
||||||
|
m[i], m[l - i - 1] = m[l - i - 1], m[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func llvm2big(m *i256) *big.Int {
|
||||||
|
n := big.NewInt(0)
|
||||||
|
for i := 0; i < len(m); i++ {
|
||||||
|
b := big.NewInt(int64(m[i]))
|
||||||
|
b.Lsh(b, uint(i) * 8)
|
||||||
|
n.Add(n, b)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
func NewJitVm(env Environment) *JitVm {
|
func NewJitVm(env Environment) *JitVm {
|
||||||
backupVm := NewDebugVm(env)
|
backupVm := NewDebugVm(env)
|
||||||
return &JitVm{env: env, backup: backupVm}
|
return &JitVm{env: env, backup: backupVm}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
||||||
r := C.evmjit_run();
|
self.myAddress = me.Address()
|
||||||
fmt.Printf("JIT result: %d", r);
|
|
||||||
|
var data RuntimeData
|
||||||
|
data.elems[Gas] = big2llvm(gas)
|
||||||
|
data.elems[address] = hash2llvm(self.myAddress)
|
||||||
|
data.elems[Caller] = hash2llvm(caller.Address())
|
||||||
|
data.elems[Origin] = hash2llvm(self.env.Origin())
|
||||||
|
data.elems[CallValue] = big2llvm(value)
|
||||||
|
data.elems[CallDataSize] = big2llvm(big.NewInt(int64(len(callData)))) // TODO: Keep call data size as i64
|
||||||
|
data.elems[CoinBase] = hash2llvm(self.env.Coinbase())
|
||||||
|
data.elems[TimeStamp] = big2llvm(big.NewInt(self.env.Time())) // TODO: Keep timestamp as i64
|
||||||
|
data.elems[Number] = big2llvm(self.env.BlockNumber())
|
||||||
|
data.elems[Difficulty] = big2llvm(self.env.Difficulty())
|
||||||
|
data.elems[GasLimit] = big2llvm(self.env.GasLimit())
|
||||||
|
data.elems[CodeSize] = big2llvm(big.NewInt(int64(len(code)))) // TODO: Keep code size as i64
|
||||||
|
if len(callData) > 0 {
|
||||||
|
data.callData = &callData[0]
|
||||||
|
}
|
||||||
|
if len(code) > 0 {
|
||||||
|
data.code = &code[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
r := C.evmjit_run(unsafe.Pointer(&data), unsafe.Pointer(self));
|
||||||
|
fmt.Printf("JIT result: %d\n", r);
|
||||||
|
|
||||||
return self.backup.Run(me, caller, code, value, gas, price, callData)
|
return self.backup.Run(me, caller, code, value, gas, price, callData)
|
||||||
}
|
}
|
||||||
|
|
@ -70,4 +157,21 @@ func env_sha3(dataPtr unsafe.Pointer, length uint64, hashPtr unsafe.Pointer) {
|
||||||
fmt.Printf("\tout1: %x\n", oHash)
|
fmt.Printf("\tout1: %x\n", oHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export env_sstore
|
||||||
|
func env_sstore(vmPtr unsafe.Pointer, indexPtr unsafe.Pointer, valuePtr unsafe.Pointer) {
|
||||||
|
vm := (*JitVm)(vmPtr)
|
||||||
|
index := llvm2hash((*i256)(indexPtr))
|
||||||
|
value := llvm2hash((*i256)(valuePtr))
|
||||||
|
vm.env.State().SetState(vm.myAddress, index, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export env_sload
|
||||||
|
func env_sload(vmPtr unsafe.Pointer, indexPtr unsafe.Pointer, resultPtr unsafe.Pointer) {
|
||||||
|
vm := (*JitVm)(vmPtr)
|
||||||
|
index := llvm2hash((*i256)(indexPtr))
|
||||||
|
value := vm.env.State().GetState(vm.myAddress, index)
|
||||||
|
result := (*i256)(resultPtr)
|
||||||
|
*result = hash2llvm(value)
|
||||||
|
}
|
||||||
|
|
||||||
//go is nice
|
//go is nice
|
||||||
Loading…
Reference in a new issue