mirror of
https://gitlab.com/pulsechaincom/go-pulse.git
synced 2024-12-28 14:27:16 +00:00
Fixed MSTORE and added some more commets
This commit is contained in:
parent
f21eb88ad1
commit
c68ff9886b
@ -21,15 +21,17 @@ type ClosureBody interface {
|
||||
type Closure struct {
|
||||
callee Callee
|
||||
object ClosureBody
|
||||
state *State
|
||||
State *State
|
||||
|
||||
gas *big.Int
|
||||
val *big.Int
|
||||
|
||||
args []byte
|
||||
}
|
||||
|
||||
// Create a new closure for the given data items
|
||||
func NewClosure(callee Callee, object ClosureBody, state *State, gas, val *big.Int) *Closure {
|
||||
return &Closure{callee, object, state, gas, val}
|
||||
return &Closure{callee, object, state, gas, val, nil}
|
||||
}
|
||||
|
||||
// Retuns the x element in data slice
|
||||
@ -42,14 +44,20 @@ func (c *Closure) GetMem(x int64) *ethutil.Value {
|
||||
return m
|
||||
}
|
||||
|
||||
func (c *Closure) Call(vm *Vm, args []byte) []byte {
|
||||
c.args = args
|
||||
|
||||
return vm.RunClosure(c)
|
||||
}
|
||||
|
||||
func (c *Closure) Return(ret []byte) []byte {
|
||||
// Return the remaining gas to the callee
|
||||
// If no callee is present return it to
|
||||
// the origin (i.e. contract or tx)
|
||||
if c.callee != nil {
|
||||
c.callee.ReturnGas(c.gas, c.state)
|
||||
c.callee.ReturnGas(c.gas, c.State)
|
||||
} else {
|
||||
c.object.ReturnGas(c.gas, c.state)
|
||||
c.object.ReturnGas(c.gas, c.State)
|
||||
// TODO incase it's a POST contract we gotta serialise the contract again.
|
||||
// But it's not yet defined
|
||||
}
|
||||
|
@ -235,6 +235,7 @@ func (st *ValueStack) Peekn() (*ethutil.Value, *ethutil.Value) {
|
||||
func (st *ValueStack) Push(d *ethutil.Value) {
|
||||
st.data = append(st.data, d)
|
||||
}
|
||||
|
||||
func (st *ValueStack) Print() {
|
||||
fmt.Println("### STACK ###")
|
||||
if len(st.data) > 0 {
|
||||
|
@ -18,6 +18,8 @@ type Vm struct {
|
||||
mem map[string]*big.Int
|
||||
|
||||
vars RuntimeVars
|
||||
|
||||
state *State
|
||||
}
|
||||
|
||||
type RuntimeVars struct {
|
||||
@ -32,7 +34,11 @@ type RuntimeVars struct {
|
||||
txData []string
|
||||
}
|
||||
|
||||
func (vm *Vm) RunClosure(closure *Closure, state *State, vars RuntimeVars) []byte {
|
||||
func NewVm(state *State, vars RuntimeVars) *Vm {
|
||||
return &Vm{vars: vars, state: state}
|
||||
}
|
||||
|
||||
func (vm *Vm) RunClosure(closure *Closure) []byte {
|
||||
// If the amount of gas supplied is less equal to 0
|
||||
if closure.GetGas().Cmp(big.NewInt(0)) <= 0 {
|
||||
// TODO Do something
|
||||
@ -71,17 +77,28 @@ func (vm *Vm) RunClosure(closure *Closure, state *State, vars RuntimeVars) []byt
|
||||
}
|
||||
|
||||
switch op {
|
||||
case oSTOP:
|
||||
case oSTOP: // Stop the closure
|
||||
return closure.Return(nil)
|
||||
case oPUSH:
|
||||
case oPUSH: // Push PC+1 on to the stack
|
||||
pc++
|
||||
val := closure.GetMem(pc).BigInt()
|
||||
stack.Push(val)
|
||||
case oMSTORE:
|
||||
case oMSTORE: // Store the value at stack top-1 in to memory at location stack top
|
||||
// Pop value of the stack
|
||||
val := stack.Pop()
|
||||
// Set the bytes to the memory field
|
||||
mem = append(mem, ethutil.BigToBytes(val, 256)...)
|
||||
val, mStart := stack.Popn()
|
||||
// Ensure that memory is large enough to hold the data
|
||||
// If it isn't resize the memory slice so that it may hold the value
|
||||
bytesLen := big.NewInt(32)
|
||||
totSize := new(big.Int).Add(mStart, bytesLen)
|
||||
lenSize := big.NewInt(int64(len(mem)))
|
||||
if totSize.Cmp(lenSize) > 0 {
|
||||
// Calculate the diff between the sizes
|
||||
diff := new(big.Int).Sub(totSize, lenSize)
|
||||
// Create a new empty slice and append it
|
||||
newSlice := make([]byte, diff.Int64()+1)
|
||||
mem = append(mem, newSlice...)
|
||||
}
|
||||
copy(mem[mStart.Int64():mStart.Int64()+bytesLen.Int64()+1], ethutil.BigToBytes(val, 256))
|
||||
case oCALL:
|
||||
// Pop return size and offset
|
||||
retSize, retOffset := stack.Popn()
|
||||
@ -93,20 +110,25 @@ func (vm *Vm) RunClosure(closure *Closure, state *State, vars RuntimeVars) []byt
|
||||
gas, value := stack.Popn()
|
||||
// Closure addr
|
||||
addr := stack.Pop()
|
||||
|
||||
contract := state.GetContract(addr.Bytes())
|
||||
closure := NewClosure(closure, contract, state, gas, value)
|
||||
ret := vm.RunClosure(closure, state, vars)
|
||||
// Fetch the contract which will serve as the closure body
|
||||
contract := vm.state.GetContract(addr.Bytes())
|
||||
// Create a new callable closure
|
||||
closure := NewClosure(closure, contract, vm.state, gas, value)
|
||||
// Executer the closure and get the return value (if any)
|
||||
ret := closure.Call(vm, nil)
|
||||
|
||||
// Ensure that memory is large enough to hold the returned data
|
||||
// If it isn't resize the memory slice so that it may hold the value
|
||||
totSize := new(big.Int).Add(retOffset, retSize)
|
||||
lenSize := big.NewInt(int64(len(mem)))
|
||||
// Resize the current memory slice so that the return value may fit
|
||||
if totSize.Cmp(lenSize) > 0 {
|
||||
// Calculate the diff between the sizes
|
||||
diff := new(big.Int).Sub(totSize, lenSize)
|
||||
// Create a new empty slice and append it
|
||||
newSlice := make([]byte, diff.Int64()+1)
|
||||
mem = append(mem, newSlice...)
|
||||
}
|
||||
// Copy over the returned values to the memory given the offset and size
|
||||
copy(mem[retOffset.Int64():retOffset.Int64()+retSize.Int64()+1], ret)
|
||||
case oRETURN:
|
||||
size, offset := stack.Popn()
|
||||
|
@ -117,8 +117,10 @@ func TestRun3(t *testing.T) {
|
||||
|
||||
script := Compile([]string{
|
||||
"PUSH", "300",
|
||||
"PUSH", "0",
|
||||
"MSTORE",
|
||||
"PUSH", "300",
|
||||
"PUSH", "31",
|
||||
"MSTORE",
|
||||
"PUSH", "62",
|
||||
"PUSH", "0",
|
||||
@ -147,8 +149,7 @@ func TestRun3(t *testing.T) {
|
||||
executer.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
|
||||
callerClosure := NewClosure(executer, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
|
||||
|
||||
vm := &Vm{}
|
||||
vm.RunClosure(callerClosure, state, RuntimeVars{
|
||||
vm := NewVm(state, RuntimeVars{
|
||||
address: callerAddr,
|
||||
blockNumber: 1,
|
||||
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
|
||||
@ -159,4 +160,5 @@ func TestRun3(t *testing.T) {
|
||||
txValue: big.NewInt(10000),
|
||||
txData: nil,
|
||||
})
|
||||
callerClosure.Call(vm, nil)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user