VM:Implement THROW opcode (#219)
[VM] - Changed vmstate from HALT to FAULT in Sub opcode - Implemented THROW opcode + tests - Renamed TestSimpleRun test to TestThrowIfNot
This commit is contained in:
parent
9951f04099
commit
24cd21bd8c
4 changed files with 36 additions and 2 deletions
|
@ -12,6 +12,7 @@ var opFunc = map[stack.Instruction]stackInfo{
|
||||||
stack.RET: RET,
|
stack.RET: RET,
|
||||||
stack.EQUAL: EQUAL,
|
stack.EQUAL: EQUAL,
|
||||||
stack.THROWIFNOT: THROWIFNOT,
|
stack.THROWIFNOT: THROWIFNOT,
|
||||||
|
stack.THROW: THROW,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -31,3 +31,9 @@ func THROWIFNOT(op stack.Instruction, ctx *stack.Context, istack *stack.Invocati
|
||||||
}
|
}
|
||||||
return NONE, nil
|
return NONE, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THROW returns a FAULT VM state. This indicate that there is an error in the
|
||||||
|
// current context loaded program.
|
||||||
|
func THROW(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) {
|
||||||
|
return FAULT, errors.New("the execution of the script program end with an error")
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func Sub(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rst
|
||||||
}
|
}
|
||||||
res, err := operandB.Sub(operandA)
|
res, err := operandB.Sub(operandA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return HALT, err
|
return FAULT, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Estack.Push(res)
|
ctx.Estack.Push(res)
|
||||||
|
|
|
@ -61,7 +61,7 @@ func TestPushAdd(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleRun(t *testing.T) {
|
func TestThrowIfNot(t *testing.T) {
|
||||||
|
|
||||||
// Program pushes 20 and 34 to the stack
|
// Program pushes 20 and 34 to the stack
|
||||||
// Adds them together
|
// Adds them together
|
||||||
|
@ -89,6 +89,33 @@ func TestSimpleRun(t *testing.T) {
|
||||||
// ResultStack should be nil
|
// ResultStack should be nil
|
||||||
assert.Equal(t, -1, vm.ResultStack.Len())
|
assert.Equal(t, -1, vm.ResultStack.Len())
|
||||||
|
|
||||||
|
// InvocationStack should be empty
|
||||||
|
assert.Equal(t, 0, vm.InvocationStack.Len())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThrow(t *testing.T) {
|
||||||
|
|
||||||
|
// Program pushes 20 to the stack
|
||||||
|
// exits with an error
|
||||||
|
|
||||||
|
// Push(20)
|
||||||
|
// THROW
|
||||||
|
|
||||||
|
builder := stack.NewBuilder()
|
||||||
|
builder.EmitInt(20).EmitOpcode(stack.THROW)
|
||||||
|
|
||||||
|
// Pass program to VM
|
||||||
|
vm := NewVM(builder.Bytes())
|
||||||
|
|
||||||
|
// Runs vm with program
|
||||||
|
_, err := vm.Run()
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
ctx, err := vm.InvocationStack.CurrentContext()
|
||||||
|
assert.Equal(t, nil, err)
|
||||||
|
assert.Equal(t, 1, ctx.Estack.Len())
|
||||||
|
assert.Equal(t, -1, ctx.Astack.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if the value at the top of the evaluation stack is a integer
|
// returns true if the value at the top of the evaluation stack is a integer
|
||||||
|
|
Loading…
Reference in a new issue