diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 5554ad5e31..de121ec608 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -817,6 +817,26 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) return ret, nil } +func opYield(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + // Save current Environment as coroutine + coroutine := NewCoroutine(*pc + 1, *scope.Stack) + + // Push coroutine to the stack + scope.PushCoroutine(coroutine) + + log.Printf("Coroutine %d yielded with %v", coroutine.PC, coroutine.Stack) + + // Call the next coroutine + nextCoroutine, err := scope.PopCoroutine() + if err != nil { + return nil, err + } + ret, err := nextCoroutine.ExecuteCoroutine(interpreter, scope) + log.Printf("Coroutine %d returned with %v", nextCoroutine.PC, ret) + + return nil, errStopToken +} + func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { offset, size := scope.Stack.pop(), scope.Stack.pop() ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 2d4e2a7efd..83ac58db6a 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -275,7 +275,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( err = nil // clear stop token error } - log2.Println("returning from run with", res, err) // Res is array of bytes located in scope.Memory return res, err } diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index ce7bea33af..b417b7186e 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -1044,6 +1044,12 @@ func newFrontierInstructionSet() JumpTable { maxStack: maxStack(7, 1), memorySize: memoryCall, }, + YIELD: { + execute: opYield, + constantGas: 1, //TODO: set this to something reasonable + minStack: minStack(0, 0), + maxStack: maxStack(0, 0), + }, RETURN: { execute: opReturn, dynamicGas: gasReturn, diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 1af864054a..8851a65011 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -219,6 +219,7 @@ const ( STATICCALL OpCode = 0xfa SPAWN OpCode = 0xfb + YIELD OpCode = 0xfc REVERT OpCode = 0xfd INVALID OpCode = 0xfe SELFDESTRUCT OpCode = 0xff @@ -393,6 +394,7 @@ var opCodeToString = map[OpCode]string{ DELEGATECALL: "DELEGATECALL", CREATE2: "CREATE2", STATICCALL: "STATICCALL", + YIELD: "YIELD", REVERT: "REVERT", INVALID: "INVALID", SELFDESTRUCT: "SELFDESTRUCT", @@ -448,6 +450,7 @@ var stringToOp = map[string]OpCode{ "BLOBHASH": BLOBHASH, "DELEGATECALL": DELEGATECALL, "STATICCALL": STATICCALL, + "YIELD": YIELD, "CODESIZE": CODESIZE, "CODECOPY": CODECOPY, "GASPRICE": GASPRICE,