Pre-resolve handlers
This commit is contained in:
33
main.go
33
main.go
@@ -20,6 +20,8 @@ const InstructionBytes = 32
|
||||
const GlobalMemoryEntries = 16
|
||||
const FunctionMemoryEntries = 16
|
||||
|
||||
type OpHandler func(*State, *Instruction)
|
||||
|
||||
type Operand struct {
|
||||
Type OperandType
|
||||
Reserved [3]byte
|
||||
@@ -31,6 +33,8 @@ type Instruction struct {
|
||||
Reserved [4]byte
|
||||
Operand1 Operand
|
||||
Operand2 Operand
|
||||
|
||||
opHandler OpHandler `struc:"skip"`
|
||||
}
|
||||
|
||||
type State struct {
|
||||
@@ -51,8 +55,6 @@ type StackFrame struct {
|
||||
FunctionMemory [FunctionMemoryEntries]uint64
|
||||
}
|
||||
|
||||
type OpHandler func(*State, *Instruction)
|
||||
|
||||
var OpHandlers = map[uint32]OpHandler{
|
||||
0x00000000: (*State).NoOp,
|
||||
0x00000001: (*State).Call,
|
||||
@@ -124,17 +126,24 @@ func (state *State) Function() []*Instruction {
|
||||
}
|
||||
|
||||
func (state *State) Execute() {
|
||||
state.prepare()
|
||||
state.call(0)
|
||||
|
||||
for len(state.Stack) > 0 {
|
||||
for len(state.Stack) > 0 && state.Error == nil{
|
||||
state.ProcessInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
if state.Error != nil {
|
||||
break
|
||||
func (state *State) prepare() {
|
||||
for _, fnc := range state.Functions {
|
||||
for _, instr := range fnc {
|
||||
handler, found := OpHandlers[instr.OpCode]
|
||||
if !found {
|
||||
state.Error = fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode)
|
||||
return
|
||||
}
|
||||
|
||||
if state.InstructionIndex >= int64(len(state.Function())) {
|
||||
state.ret()
|
||||
instr.opHandler = handler
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,16 +157,8 @@ func (state *State) ProcessInstruction() {
|
||||
}
|
||||
|
||||
instr := fnc[state.InstructionIndex]
|
||||
|
||||
handler, found := OpHandlers[instr.OpCode]
|
||||
if !found {
|
||||
state.Error = fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode)
|
||||
return
|
||||
}
|
||||
|
||||
state.InstructionIndex += 1
|
||||
|
||||
handler(state, instr)
|
||||
instr.opHandler(state, instr)
|
||||
}
|
||||
|
||||
func (state *State) ReadUnsigned(op *Operand) uint64 {
|
||||
|
||||
Reference in New Issue
Block a user