Start hiding members
This commit is contained in:
24
ophandler.go
24
ophandler.go
@@ -80,70 +80,70 @@ func (state *State) DivideSigned(instr *Instruction) {
|
|||||||
func (state *State) IsEqual(instr *Instruction) {
|
func (state *State) IsEqual(instr *Instruction) {
|
||||||
in1 := state.ReadUnsigned(&instr.Operand1)
|
in1 := state.ReadUnsigned(&instr.Operand1)
|
||||||
in2 := state.ReadUnsigned(&instr.Operand2)
|
in2 := state.ReadUnsigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 == in2)
|
state.comparisonResult = (in1 == in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsLessThanUnsigned(instr *Instruction) {
|
func (state *State) IsLessThanUnsigned(instr *Instruction) {
|
||||||
in1 := state.ReadUnsigned(&instr.Operand1)
|
in1 := state.ReadUnsigned(&instr.Operand1)
|
||||||
in2 := state.ReadUnsigned(&instr.Operand2)
|
in2 := state.ReadUnsigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 < in2)
|
state.comparisonResult = (in1 < in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsLessThanSigned(instr *Instruction) {
|
func (state *State) IsLessThanSigned(instr *Instruction) {
|
||||||
in1 := state.ReadSigned(&instr.Operand1)
|
in1 := state.ReadSigned(&instr.Operand1)
|
||||||
in2 := state.ReadSigned(&instr.Operand2)
|
in2 := state.ReadSigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 < in2)
|
state.comparisonResult = (in1 < in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsGreaterThanUnsigned(instr *Instruction) {
|
func (state *State) IsGreaterThanUnsigned(instr *Instruction) {
|
||||||
in1 := state.ReadUnsigned(&instr.Operand1)
|
in1 := state.ReadUnsigned(&instr.Operand1)
|
||||||
in2 := state.ReadUnsigned(&instr.Operand2)
|
in2 := state.ReadUnsigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 > in2)
|
state.comparisonResult = (in1 > in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsGreaterThanSigned(instr *Instruction) {
|
func (state *State) IsGreaterThanSigned(instr *Instruction) {
|
||||||
in1 := state.ReadSigned(&instr.Operand1)
|
in1 := state.ReadSigned(&instr.Operand1)
|
||||||
in2 := state.ReadSigned(&instr.Operand2)
|
in2 := state.ReadSigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 > in2)
|
state.comparisonResult = (in1 > in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsLessThanOrEqualUnsigned(instr *Instruction) {
|
func (state *State) IsLessThanOrEqualUnsigned(instr *Instruction) {
|
||||||
in1 := state.ReadUnsigned(&instr.Operand1)
|
in1 := state.ReadUnsigned(&instr.Operand1)
|
||||||
in2 := state.ReadUnsigned(&instr.Operand2)
|
in2 := state.ReadUnsigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 <= in2)
|
state.comparisonResult = (in1 <= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsLessThanOrEqualSigned(instr *Instruction) {
|
func (state *State) IsLessThanOrEqualSigned(instr *Instruction) {
|
||||||
in1 := state.ReadSigned(&instr.Operand1)
|
in1 := state.ReadSigned(&instr.Operand1)
|
||||||
in2 := state.ReadSigned(&instr.Operand2)
|
in2 := state.ReadSigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 <= in2)
|
state.comparisonResult = (in1 <= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsGreaterThanOrEqualUnsigned(instr *Instruction) {
|
func (state *State) IsGreaterThanOrEqualUnsigned(instr *Instruction) {
|
||||||
in1 := state.ReadUnsigned(&instr.Operand1)
|
in1 := state.ReadUnsigned(&instr.Operand1)
|
||||||
in2 := state.ReadUnsigned(&instr.Operand2)
|
in2 := state.ReadUnsigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 >= in2)
|
state.comparisonResult = (in1 >= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) IsGreaterThanOrEqualSigned(instr *Instruction) {
|
func (state *State) IsGreaterThanOrEqualSigned(instr *Instruction) {
|
||||||
in1 := state.ReadSigned(&instr.Operand1)
|
in1 := state.ReadSigned(&instr.Operand1)
|
||||||
in2 := state.ReadSigned(&instr.Operand2)
|
in2 := state.ReadSigned(&instr.Operand2)
|
||||||
state.ComparisonResult = (in1 >= in2)
|
state.comparisonResult = (in1 >= in2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) Jump(instr *Instruction) {
|
func (state *State) Jump(instr *Instruction) {
|
||||||
in := state.ReadSigned(&instr.Operand1)
|
in := state.ReadSigned(&instr.Operand1)
|
||||||
state.InstructionIndex += in - 1
|
state.instructionIndex += in - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) JumpIfTrue(instr *Instruction) {
|
func (state *State) JumpIfTrue(instr *Instruction) {
|
||||||
if state.ComparisonResult == true {
|
if state.comparisonResult == true {
|
||||||
state.Jump(instr)
|
state.Jump(instr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) JumpIfFalse(instr *Instruction) {
|
func (state *State) JumpIfFalse(instr *Instruction) {
|
||||||
if state.ComparisonResult == false {
|
if state.comparisonResult == false {
|
||||||
state.Jump(instr)
|
state.Jump(instr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
70
state.go
70
state.go
@@ -4,19 +4,19 @@ import "fmt"
|
|||||||
|
|
||||||
import "github.com/pkg/errors"
|
import "github.com/pkg/errors"
|
||||||
|
|
||||||
const GlobalMemoryEntries = 16
|
const globalMemoryEntries = 16
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
Running bool
|
running bool
|
||||||
Error error
|
err error
|
||||||
|
|
||||||
Functions [][]*Instruction
|
functions [][]*Instruction
|
||||||
FunctionIndex int64
|
functionIndex int64
|
||||||
InstructionIndex int64
|
instructionIndex int64
|
||||||
|
|
||||||
ComparisonResult bool
|
comparisonResult bool
|
||||||
GlobalMemory [GlobalMemoryEntries]uint64
|
globalMemory [globalMemoryEntries]uint64
|
||||||
Stack []*StackFrame
|
stack []*StackFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewState(byteCodes [][]byte) (*State, error) {
|
func NewState(byteCodes [][]byte) (*State, error) {
|
||||||
@@ -38,37 +38,37 @@ func NewState(byteCodes [][]byte) (*State, error) {
|
|||||||
OpCode: OpReturn,
|
OpCode: OpReturn,
|
||||||
})
|
})
|
||||||
|
|
||||||
state.Functions = append(state.Functions, instrs)
|
state.functions = append(state.functions, instrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) StackFrame() *StackFrame {
|
func (state *State) StackFrame() *StackFrame {
|
||||||
return state.Stack[len(state.Stack)-1]
|
return state.stack[len(state.stack)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) Function() []*Instruction {
|
func (state *State) Function() []*Instruction {
|
||||||
return state.Functions[state.FunctionIndex]
|
return state.functions[state.functionIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) Execute() {
|
func (state *State) Execute() {
|
||||||
state.setHandlers()
|
state.setHandlers()
|
||||||
state.call(0)
|
state.call(0)
|
||||||
state.Running = true
|
state.running = true
|
||||||
|
|
||||||
for state.Running {
|
for state.running {
|
||||||
state.ProcessInstruction()
|
state.ProcessInstruction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) setError(err error) {
|
func (state *State) setError(err error) {
|
||||||
state.Error = err
|
state.err = err
|
||||||
state.Running = false
|
state.running = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) setHandlers() {
|
func (state *State) setHandlers() {
|
||||||
for _, fnc := range state.Functions {
|
for _, fnc := range state.functions {
|
||||||
for _, instr := range fnc {
|
for _, instr := range fnc {
|
||||||
handler, found := OpHandlers[instr.OpCode]
|
handler, found := OpHandlers[instr.OpCode]
|
||||||
if !found {
|
if !found {
|
||||||
@@ -83,8 +83,8 @@ func (state *State) setHandlers() {
|
|||||||
|
|
||||||
func (state *State) ProcessInstruction() {
|
func (state *State) ProcessInstruction() {
|
||||||
fnc := state.Function()
|
fnc := state.Function()
|
||||||
instr := fnc[state.InstructionIndex]
|
instr := fnc[state.instructionIndex]
|
||||||
state.InstructionIndex += 1
|
state.instructionIndex += 1
|
||||||
instr.opHandler(state, instr)
|
instr.opHandler(state, instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +101,11 @@ func (state *State) ReadUnsigned(op *Operand) uint64 {
|
|||||||
return state.StackFrame().FunctionMemory[op.Value]
|
return state.StackFrame().FunctionMemory[op.Value]
|
||||||
|
|
||||||
case GlobalMemoryIndex:
|
case GlobalMemoryIndex:
|
||||||
if op.Value >= GlobalMemoryEntries {
|
if op.Value >= globalMemoryEntries {
|
||||||
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
|
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return state.GlobalMemory[op.Value]
|
return state.globalMemory[op.Value]
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
|
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
|
||||||
@@ -130,11 +130,11 @@ func (state *State) WriteUnsigned(op *Operand, value uint64) {
|
|||||||
state.StackFrame().FunctionMemory[op.Value] = value
|
state.StackFrame().FunctionMemory[op.Value] = value
|
||||||
|
|
||||||
case GlobalMemoryIndex:
|
case GlobalMemoryIndex:
|
||||||
if op.Value >= GlobalMemoryEntries {
|
if op.Value >= globalMemoryEntries {
|
||||||
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
|
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state.GlobalMemory[op.Value] = value
|
state.globalMemory[op.Value] = value
|
||||||
|
|
||||||
default:
|
default:
|
||||||
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
|
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
|
||||||
@@ -146,25 +146,25 @@ func (state *State) WriteSigned(op *Operand, value int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) call(functionOffset int64) {
|
func (state *State) call(functionOffset int64) {
|
||||||
if state.FunctionIndex+functionOffset >= int64(len(state.Functions)) {
|
if state.functionIndex+functionOffset >= int64(len(state.functions)) {
|
||||||
state.setError(fmt.Errorf("Invalid function call index: %d + %d = %d", state.FunctionIndex, functionOffset, state.FunctionIndex+functionOffset))
|
state.setError(fmt.Errorf("Invalid function call index: %d + %d = %d", state.functionIndex, functionOffset, state.functionIndex+functionOffset))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stackFrame := &StackFrame{
|
stackFrame := &StackFrame{
|
||||||
PreviousFunctionIndex: state.FunctionIndex,
|
PreviousFunctionIndex: state.functionIndex,
|
||||||
PreviousInstructionIndex: state.InstructionIndex,
|
PreviousInstructionIndex: state.instructionIndex,
|
||||||
}
|
}
|
||||||
state.Stack = append(state.Stack, stackFrame)
|
state.stack = append(state.stack, stackFrame)
|
||||||
state.FunctionIndex += functionOffset
|
state.functionIndex += functionOffset
|
||||||
state.InstructionIndex = 0
|
state.instructionIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) ret() {
|
func (state *State) ret() {
|
||||||
state.FunctionIndex = state.StackFrame().PreviousFunctionIndex
|
state.functionIndex = state.StackFrame().PreviousFunctionIndex
|
||||||
state.InstructionIndex = state.StackFrame().PreviousInstructionIndex
|
state.instructionIndex = state.StackFrame().PreviousInstructionIndex
|
||||||
state.Stack = state.Stack[:len(state.Stack)-1]
|
state.stack = state.stack[:len(state.stack)-1]
|
||||||
if len(state.Stack) == 0 {
|
if len(state.stack) == 0 {
|
||||||
state.Running = false
|
state.running = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ func TestFirst(t *testing.T) {
|
|||||||
|
|
||||||
state.Execute()
|
state.Execute()
|
||||||
|
|
||||||
if state.Error != nil {
|
if state.err != nil {
|
||||||
t.Fatal(state)
|
t.Fatal(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.GlobalMemory[0] != 3 {
|
if state.globalMemory[0] != 3 {
|
||||||
t.Fatal(state.GlobalMemory[0])
|
t.Fatal(state.globalMemory[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user