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