797324cb04
Implement 3 new instructions: TRY,ENDTRY,ENDFINALLY. 1. TRY marks the start of the block where exceptions are catched. It has 2 arguments which are relative offsets of exception handler and the end of the whole try/catch construction. 2. ENDTRY denotes either end of try or catch block. 3. ENDFINALLY denotes end of finally block which is executed irregardless of whether an exception has occured.
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
package vm
|
|
|
|
import (
|
|
"errors"
|
|
"math/big"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
)
|
|
|
|
// exceptionHandlingState represents state of the exception handling process.
|
|
type exceptionHandlingState byte
|
|
|
|
const (
|
|
eTry exceptionHandlingState = iota
|
|
eCatch
|
|
eFinally
|
|
)
|
|
|
|
// exceptionHandlingContext represents context of the exception handling process.
|
|
type exceptionHandlingContext struct {
|
|
CatchOffset int
|
|
FinallyOffset int
|
|
EndOffset int
|
|
State exceptionHandlingState
|
|
}
|
|
|
|
func newExceptionHandlingContext(cOffset, fOffset int) *exceptionHandlingContext {
|
|
return &exceptionHandlingContext{
|
|
CatchOffset: cOffset,
|
|
FinallyOffset: fOffset,
|
|
EndOffset: -1,
|
|
State: eTry,
|
|
}
|
|
}
|
|
|
|
// HasCatch returns true iff context has `catch` block.
|
|
func (c *exceptionHandlingContext) HasCatch() bool { return c.CatchOffset >= 0 }
|
|
|
|
// HasFinally returns true iff context has `finally` block.
|
|
func (c *exceptionHandlingContext) HasFinally() bool { return c.FinallyOffset >= 0 }
|
|
|
|
// String implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) String() string {
|
|
return "exception handling context"
|
|
}
|
|
|
|
// Value implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Value() interface{} {
|
|
return c
|
|
}
|
|
|
|
// Dup implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Dup() stackitem.Item {
|
|
return c
|
|
}
|
|
|
|
// Bool implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Bool() bool {
|
|
panic("can't convert exceptionHandlingContext to Bool")
|
|
}
|
|
|
|
// TryBytes implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) TryBytes() ([]byte, error) {
|
|
return nil, errors.New("can't convert exceptionHandlingContext to ByteArray")
|
|
}
|
|
|
|
// TryInteger implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) TryInteger() (*big.Int, error) {
|
|
return nil, errors.New("can't convert exceptionHandlingContext to Integer")
|
|
}
|
|
|
|
// Type implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Type() stackitem.Type {
|
|
panic("exceptionHandlingContext cannot appear on evaluation stack")
|
|
}
|
|
|
|
// Convert implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Convert(_ stackitem.Type) (stackitem.Item, error) {
|
|
panic("exceptionHandlingContext cannot be converted to anything")
|
|
}
|
|
|
|
// Equals implements stackitem.Item interface.
|
|
func (c *exceptionHandlingContext) Equals(s stackitem.Item) bool {
|
|
return c == s
|
|
}
|