Make the handle_* methods user-visible
This commit is contained in:
parent
edd237f0be
commit
4ac9de366b
1 changed files with 38 additions and 38 deletions
|
@ -181,23 +181,23 @@ class Interpreter(BaseInterpreter):
|
|||
def step(self, state: InterpreterState, opcode: isa.Opcode) -> InterpreterState:
|
||||
"""Execute an instruction, producing the next state of the VM."""
|
||||
|
||||
return self._handle_opcode(state, opcode)
|
||||
return self.handle_opcode(state, opcode)
|
||||
|
||||
####################################################################################################################
|
||||
# BEGIN INSTRUCTION IMPLEMENTATIONS AT LENGTH
|
||||
####################################################################################################################
|
||||
|
||||
@opcode_dispatch
|
||||
def _handle_opcode(self, state: InterpreterState, opcode: isa.Opcode) -> InterpreterState:
|
||||
def handle_opcode(self, state: InterpreterState, opcode: isa.Opcode) -> InterpreterState:
|
||||
"""Generic entrypoint. Exists to establish a type signature and provide singledispatch handling."""
|
||||
return self.handle_unknown(state, opcode)
|
||||
|
||||
@_handle_opcode.register(object)
|
||||
def _handle_unknown(self, state: InterpreterState, opcode: isa.Opcode) -> InterpreterState:
|
||||
@handle_opcode.register(object)
|
||||
def handle_unknown(self, state: InterpreterState, opcode: isa.Opcode) -> InterpreterState:
|
||||
return self.handle_unknown(state, opcode)
|
||||
|
||||
@_handle_opcode.register(isa.IDENTIFIERC)
|
||||
def _handle_identifierc(self, state: InterpreterState, opcode: isa.IDENTIFIERC) -> InterpreterState:
|
||||
@handle_opcode.register(isa.IDENTIFIERC)
|
||||
def handle_identifierc(self, state: InterpreterState, opcode: isa.IDENTIFIERC) -> InterpreterState:
|
||||
name = opcode.val
|
||||
if not (name in state.module.functions
|
||||
or name in state.module.types
|
||||
|
@ -208,8 +208,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.TYPEREF)
|
||||
def _handle_typeref(self, state, opcode) -> InterpreterState:
|
||||
@handle_opcode.register(isa.TYPEREF)
|
||||
def handle_typeref(self, state, opcode) -> InterpreterState:
|
||||
id = state.stackframe.pop()
|
||||
if not isinstance(id, Identifier):
|
||||
return self.handle_fault(state, opcode, "TYPEREF consumes an identifier")
|
||||
|
@ -221,8 +221,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.ARMREF)
|
||||
def _handle_armref(self, state, opcode) -> InterpreterState:
|
||||
@handle_opcode.register(isa.ARMREF)
|
||||
def handle_armref(self, state, opcode) -> InterpreterState:
|
||||
id: Identifier = state.stackframe.pop()
|
||||
if not isinstance(id, Identifier):
|
||||
return self.handle_fault(state, opcode, "VARIANTREF consumes an identifier and a typeref")
|
||||
|
@ -239,8 +239,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.ARM)
|
||||
def _handle_arm(self, state: InterpreterState, opcode: isa.ARM) -> InterpreterState:
|
||||
@handle_opcode.register(isa.ARM)
|
||||
def handle_arm(self, state: InterpreterState, opcode: isa.ARM) -> InterpreterState:
|
||||
armref: VariantRef = state.stackframe.pop()
|
||||
if not isinstance(armref, VariantRef):
|
||||
return self.handle_fault(state, opcode, "VARIANT must be given a valid constructor reference")
|
||||
|
@ -260,8 +260,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.ATEST)
|
||||
def _handle_atest(self, state: InterpreterState, opcode: isa.ATEST) -> InterpreterState:
|
||||
@handle_opcode.register(isa.ATEST)
|
||||
def handle_atest(self, state: InterpreterState, opcode: isa.ATEST) -> InterpreterState:
|
||||
armref: VariantRef = state.stackframe.pop()
|
||||
if not isinstance(armref, VariantRef):
|
||||
return self.handle_fault(state, opcode, "VTEST must be given a variant reference")
|
||||
|
@ -277,15 +277,15 @@ class Interpreter(BaseInterpreter):
|
|||
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.GOTO)
|
||||
def _handle_goto(self, state, opcode: isa.GOTO) -> InterpreterState:
|
||||
@handle_opcode.register(isa.GOTO)
|
||||
def handle_goto(self, state, opcode: isa.GOTO) -> InterpreterState:
|
||||
if (opcode.target < 0):
|
||||
return self.handle_fault(state, opcode, "Illegal branch target")
|
||||
state.stackframe.goto(opcode.target)
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.DUP)
|
||||
def _handle_dupe(self, state, opcode: isa.DUP) -> InterpreterState:
|
||||
@handle_opcode.register(isa.DUP)
|
||||
def handle_dupe(self, state, opcode: isa.DUP) -> InterpreterState:
|
||||
if (opcode.nargs > len(state.stackframe)):
|
||||
return self.handle_fault(state, opcode, "Stack size violation")
|
||||
|
||||
|
@ -293,8 +293,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.ROT)
|
||||
def _handle_rot(self, state, opcode: isa.DUP) -> InterpreterState:
|
||||
@handle_opcode.register(isa.ROT)
|
||||
def handle_rot(self, state, opcode: isa.DUP) -> InterpreterState:
|
||||
if (opcode.nargs > len(state.stackframe)):
|
||||
return self.handle_fault(state, opcode, "Stack size violation")
|
||||
|
||||
|
@ -302,8 +302,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.DROP)
|
||||
def _handle_drop(self, state, opcode: isa.DROP) -> InterpreterState:
|
||||
@handle_opcode.register(isa.DROP)
|
||||
def handle_drop(self, state, opcode: isa.DROP) -> InterpreterState:
|
||||
if (opcode.nargs > len(state.stackframe)):
|
||||
return self.handle_fault(state, opcode, "Stack size violation")
|
||||
|
||||
|
@ -311,8 +311,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.SLOT)
|
||||
def _handle_slot(self, state, opcode: isa.SLOT) -> InterpreterState:
|
||||
@handle_opcode.register(isa.SLOT)
|
||||
def handle_slot(self, state, opcode: isa.SLOT) -> InterpreterState:
|
||||
if (opcode.target < 0):
|
||||
return self.handle_fault(state, opcode, "SLOT must have a positive reference")
|
||||
|
||||
|
@ -323,8 +323,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.FUNREF)
|
||||
def _handle_funref(self, state, opcode) -> InterpreterState:
|
||||
@handle_opcode.register(isa.FUNREF)
|
||||
def handle_funref(self, state, opcode) -> InterpreterState:
|
||||
id = state.stackframe.pop()
|
||||
if not isinstance(id, Identifier):
|
||||
return self.handle_fault(state, opcode, "FUNREF consumes an IDENTIFIER")
|
||||
|
@ -337,8 +337,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.CALLF)
|
||||
def _handle_callf(self, state, opcode: isa.CALLF) -> InterpreterState:
|
||||
@handle_opcode.register(isa.CALLF)
|
||||
def handle_callf(self, state, opcode: isa.CALLF) -> InterpreterState:
|
||||
sig = state.stackframe.pop()
|
||||
if not isinstance(sig, FunctionRef):
|
||||
return self.handle_fault(state, opcode, "CALLF requires a funref at top of stack")
|
||||
|
@ -358,8 +358,8 @@ class Interpreter(BaseInterpreter):
|
|||
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.RETURN)
|
||||
def _handle_return(self, state, opcode: isa.RETURN) -> InterpreterState:
|
||||
@handle_opcode.register(isa.RETURN)
|
||||
def handle_return(self, state, opcode: isa.RETURN) -> InterpreterState:
|
||||
n = 1 # FIXME: clean this up
|
||||
if (n > len(state.stackframe)):
|
||||
return self.handle_fault(state, opcode, "Stack size violation")
|
||||
|
@ -373,8 +373,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe = state.stackframe.ret(n)
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.CLOSUREF)
|
||||
def _handle_closuref(self, state: InterpreterState, opcode: isa.CLOSUREF) -> InterpreterState:
|
||||
@handle_opcode.register(isa.CLOSUREF)
|
||||
def handle_closuref(self, state: InterpreterState, opcode: isa.CLOSUREF) -> InterpreterState:
|
||||
n = opcode.nargs
|
||||
|
||||
sig = state.stackframe.pop()
|
||||
|
@ -397,8 +397,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.CLOSUREC)
|
||||
def _handle_closurec(self, state, opcode: isa.CLOSUREC) -> InterpreterState:
|
||||
@handle_opcode.register(isa.CLOSUREC)
|
||||
def handle_closurec(self, state, opcode: isa.CLOSUREC) -> InterpreterState:
|
||||
n = opcode.nargs
|
||||
|
||||
c = state.stackframe.pop()
|
||||
|
@ -421,8 +421,8 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe._ip += 1
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.CALLC)
|
||||
def _handle_callc(self, state, opcode: isa.CALLC) -> InterpreterState:
|
||||
@handle_opcode.register(isa.CALLC)
|
||||
def handle_callc(self, state, opcode: isa.CALLC) -> InterpreterState:
|
||||
n = opcode.nargs
|
||||
c = state.stackframe.pop()
|
||||
if not isinstance(c, Closure):
|
||||
|
@ -445,6 +445,6 @@ class Interpreter(BaseInterpreter):
|
|||
state.stackframe = state.stackframe.call(fun, ip)
|
||||
return state
|
||||
|
||||
@_handle_opcode.register(isa.BREAK)
|
||||
def _handle_break(self, state, _) -> InterpreterState:
|
||||
@handle_opcode.register(isa.BREAK)
|
||||
def handle_break(self, state, _) -> InterpreterState:
|
||||
raise InterpreterReturn(state.stackframe._stack)
|
||||
|
|
Loading…
Reference in a new issue