diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 6c6039f7466b96590b43d51a26883acd0c25d74d..5dcab6e08cafff946fe3f205414bce9e304625ca 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -17,6 +17,7 @@
 package vm
 
 import (
+	"fmt"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -25,16 +26,16 @@ import (
 )
 
 type programInstruction interface {
-	Do(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack)
+	// executes the program instruction and allows the instruction to modify the state of the program
+	do(program *Program, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error)
+	// returns whether the program instruction halts the execution of the JIT
+	halts() bool
+	// Returns the current op code (debugging purposes)
+	Op() OpCode
 }
 
 type instrFn func(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack)
 
-// Do executes the function. This implements programInstruction
-func (fn instrFn) Do(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) {
-	fn(instr, pc, env, contract, memory, stack)
-}
-
 type instruction struct {
 	op   OpCode
 	pc   uint64
@@ -44,6 +45,73 @@ type instruction struct {
 	gas   *big.Int
 	spop  int
 	spush int
+
+	returns bool
+}
+
+func jump(mapping map[uint64]uint64, destinations map[uint64]struct{}, contract *Contract, to *big.Int) (uint64, error) {
+	if !validDest(destinations, to) {
+		nop := contract.GetOp(to.Uint64())
+		return 0, fmt.Errorf("invalid jump destination (%v) %v", nop, to)
+	}
+
+	return mapping[to.Uint64()], nil
+}
+
+func (instr instruction) do(program *Program, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) {
+	// calculate the new memory size and gas price for the current executing opcode
+	newMemSize, cost, err := jitCalculateGasAndSize(env, contract, instr, env.Db(), memory, stack)
+	if err != nil {
+		return nil, err
+	}
+
+	// Use the calculated gas. When insufficient gas is present, use all gas and return an
+	// Out Of Gas error
+	if !contract.UseGas(cost) {
+		return nil, OutOfGasError
+	}
+	// Resize the memory calculated previously
+	memory.Resize(newMemSize.Uint64())
+
+	// These opcodes return an argument and are thefor handled
+	// differently from the rest of the opcodes
+	switch instr.op {
+	case JUMP:
+		if pos, err := jump(program.mapping, program.destinations, contract, stack.pop()); err != nil {
+			return nil, err
+		} else {
+			*pc = pos
+			return nil, nil
+		}
+	case JUMPI:
+		pos, cond := stack.pop(), stack.pop()
+		if cond.Cmp(common.BigTrue) >= 0 {
+			if pos, err := jump(program.mapping, program.destinations, contract, pos); err != nil {
+				return nil, err
+			} else {
+				*pc = pos
+				return nil, nil
+			}
+		}
+	case RETURN:
+		offset, size := stack.pop(), stack.pop()
+		return memory.GetPtr(offset.Int64(), size.Int64()), nil
+	default:
+		if instr.fn == nil {
+			return nil, fmt.Errorf("Invalid opcode 0x%x", instr.op)
+		}
+		instr.fn(instr, pc, env, contract, memory, stack)
+	}
+	*pc++
+	return nil, nil
+}
+
+func (instr instruction) halts() bool {
+	return instr.returns
+}
+
+func (instr instruction) Op() OpCode {
+	return instr.op
 }
 
 func opStaticJump(instr instruction, pc *uint64, ret *big.Int, env Environment, contract *Contract, memory *Memory, stack *stack) {
@@ -536,8 +604,6 @@ func opStop(instr instruction, pc *uint64, env Environment, contract *Contract,
 }
 
 func opSuicide(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) {
-	//receiver := env.Db().GetOrNewStateObject(common.BigToAddress(stack.pop()))
-	//receiver.AddBalance(balance)
 	balance := env.Db().GetBalance(contract.Address())
 	env.Db().AddBalance(common.BigToAddress(stack.pop()), balance)
 
diff --git a/core/vm/jit.go b/core/vm/jit.go
index 6ad57491744109fe1d824e6536a1fb0b9432ba08..8cb95b860b7d194654a46181b5a4b637c8d29b53 100644
--- a/core/vm/jit.go
+++ b/core/vm/jit.go
@@ -86,9 +86,9 @@ type Program struct {
 
 	contract *Contract
 
-	instructions []instruction       // instruction set
-	mapping      map[uint64]int      // real PC mapping to array indices
-	destinations map[uint64]struct{} // cached jump destinations
+	instructions []programInstruction // instruction set
+	mapping      map[uint64]uint64    // real PC mapping to array indices
+	destinations map[uint64]struct{}  // cached jump destinations
 
 	code []byte
 }
@@ -97,7 +97,7 @@ type Program struct {
 func NewProgram(code []byte) *Program {
 	program := &Program{
 		Id:           crypto.Sha3Hash(code),
-		mapping:      make(map[uint64]int),
+		mapping:      make(map[uint64]uint64),
 		destinations: make(map[uint64]struct{}),
 		code:         code,
 	}
@@ -118,10 +118,12 @@ func (p *Program) addInstr(op OpCode, pc uint64, fn instrFn, data *big.Int) {
 		baseOp = DUP1
 	}
 	base := _baseCheck[baseOp]
-	instr := instruction{op, pc, fn, data, base.gas, base.stackPop, base.stackPush}
+
+	returns := op == RETURN || op == SUICIDE || op == STOP
+	instr := instruction{op, pc, fn, data, base.gas, base.stackPop, base.stackPush, returns}
 
 	p.instructions = append(p.instructions, instr)
-	p.mapping[pc] = len(p.instructions) - 1
+	p.mapping[pc] = uint64(len(p.instructions) - 1)
 }
 
 // CompileProgram compiles the given program and return an error when it fails
@@ -301,21 +303,8 @@ func runProgram(program *Program, pcstart uint64, mem *Memory, stack *stack, env
 	contract.Input = input
 
 	var (
-		caller         = contract.caller
-		statedb        = env.Db()
-		pc         int = program.mapping[pcstart]
-		instrCount     = 0
-
-		jump = func(to *big.Int) error {
-			if !validDest(program.destinations, to) {
-				nop := contract.GetOp(to.Uint64())
-				return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
-			}
-
-			pc = program.mapping[to.Uint64()]
-
-			return nil
-		}
+		pc         uint64 = program.mapping[pcstart]
+		instrCount        = 0
 	)
 
 	if glog.V(logger.Debug) {
@@ -326,62 +315,19 @@ func runProgram(program *Program, pcstart uint64, mem *Memory, stack *stack, env
 		}()
 	}
 
-	for pc < len(program.instructions) {
+	for pc < uint64(len(program.instructions)) {
 		instrCount++
 
 		instr := program.instructions[pc]
 
-		// calculate the new memory size and gas price for the current executing opcode
-		newMemSize, cost, err := jitCalculateGasAndSize(env, contract, caller, instr, statedb, mem, stack)
+		ret, err := instr.do(program, &pc, env, contract, mem, stack)
 		if err != nil {
 			return nil, err
 		}
 
-		// Use the calculated gas. When insufficient gas is present, use all gas and return an
-		// Out Of Gas error
-		if !contract.UseGas(cost) {
-			return nil, OutOfGasError
-		}
-		// Resize the memory calculated previously
-		mem.Resize(newMemSize.Uint64())
-
-		// These opcodes return an argument and are thefor handled
-		// differently from the rest of the opcodes
-		switch instr.op {
-		case JUMP:
-			if err := jump(stack.pop()); err != nil {
-				return nil, err
-			}
-			continue
-		case JUMPI:
-			pos, cond := stack.pop(), stack.pop()
-
-			if cond.Cmp(common.BigTrue) >= 0 {
-				if err := jump(pos); err != nil {
-					return nil, err
-				}
-				continue
-			}
-		case RETURN:
-			offset, size := stack.pop(), stack.pop()
-			ret := mem.GetPtr(offset.Int64(), size.Int64())
-
+		if instr.halts() {
 			return contract.Return(ret), nil
-		case SUICIDE:
-			instr.fn(instr, nil, env, contract, mem, stack)
-
-			return contract.Return(nil), nil
-		case STOP:
-			return contract.Return(nil), nil
-		default:
-			if instr.fn == nil {
-				return nil, fmt.Errorf("Invalid opcode %x", instr.op)
-			}
-
-			instr.fn(instr, nil, env, contract, mem, stack)
 		}
-
-		pc++
 	}
 
 	contract.Input = nil
@@ -403,7 +349,7 @@ func validDest(dests map[uint64]struct{}, dest *big.Int) bool {
 
 // jitCalculateGasAndSize calculates the required given the opcode and stack items calculates the new memorysize for
 // the operation. This does not reduce gas or resizes the memory.
-func jitCalculateGasAndSize(env Environment, contract *Contract, caller ContractRef, instr instruction, statedb Database, mem *Memory, stack *stack) (*big.Int, *big.Int, error) {
+func jitCalculateGasAndSize(env Environment, contract *Contract, instr instruction, statedb Database, mem *Memory, stack *stack) (*big.Int, *big.Int, error) {
 	var (
 		gas                 = new(big.Int)
 		newMemSize *big.Int = new(big.Int)