To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 6f08fccc authored by Stefan Marr's avatar Stefan Marr
Browse files

Replace dispatch table with simple if:elif:



Changing to a tuple didn't did not solve the issue that RPython could not find a unique name for those function pointers. Now the traditional approach.
This also allows us to get rid of the exception for the HALT bytecode.
Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent dcee23b6
from som.interpreter.bytecodes import bytecode_length
class InterpreterHalt(Exception):
"""This exception is used to exit from the interpreter loop using the
HALT bytecode."""
pass
from som.interpreter.bytecodes import bytecode_length, Bytecodes
class Interpreter(object):
def __init__(self, universe):
self._universe = universe
self._frame = None
self._dispatch_table = (self._do_halt,
self._do_dup,
self._do_push_local,
self._do_push_argument,
self._do_push_field,
self._do_push_block,
self._do_push_constant,
self._do_push_global,
self._do_pop,
self._do_pop_local,
self._do_pop_argument,
self._do_pop_field,
self._do_send,
self._do_super_send,
self._do_return_local,
self._do_return_non_local)
def _do_halt(self, bytecode_index):
raise InterpreterHalt()
def _do_dup(self, bytecode_index):
def _do_dup(self):
# Handle the dup bytecode
self.get_frame().push(self.get_frame().get_stack_element(0))
......@@ -81,7 +57,7 @@ class Interpreter(object):
# Send 'unknownGlobal:' to self
self.get_self().send_unknown_global(global_name, self._universe, self)
def _do_pop(self, bytecode_index):
def _do_pop(self):
# Handle the pop bytecode
self.get_frame().pop()
......@@ -124,14 +100,14 @@ class Interpreter(object):
receiver.send_does_not_understand(signature, self._universe, self)
def _do_return_local(self, bytecode_index):
def _do_return_local(self):
# Handle the return local bytecode
result = self.get_frame().pop()
# Pop the top frame and push the result
self._pop_frame_and_push_result(result)
def _do_return_non_local(self, bytecode_index):
def _do_return_non_local(self):
# Handle the return non local bytecode
result = self.get_frame().pop()
......@@ -176,30 +152,57 @@ class Interpreter(object):
def start(self):
try:
# Iterate through the bytecodes
while True:
# Get the current bytecode index
bytecode_index = self.get_frame().get_bytecode_index()
# Get the current bytecode
bytecode = self.get_method().get_bytecode(bytecode_index)
# Get the length of the current bytecode
bc_length = bytecode_length(bytecode)
# Compute the next bytecode index
next_bytecode_index = bytecode_index + bc_length
# Update the bytecode index of the frame
self.get_frame().set_bytecode_index(next_bytecode_index)
# Handle the current bytecode
self._dispatch_table[bytecode](bytecode_index)
except InterpreterHalt:
return self.get_frame().get_stack_element(0)
# Iterate through the bytecodes
while True:
# Get the current bytecode index
bytecode_index = self.get_frame().get_bytecode_index()
# Get the current bytecode
bytecode = self.get_method().get_bytecode(bytecode_index)
# Get the length of the current bytecode
bc_length = bytecode_length(bytecode)
# Compute the next bytecode index
next_bytecode_index = bytecode_index + bc_length
# Update the bytecode index of the frame
self.get_frame().set_bytecode_index(next_bytecode_index)
# Handle the current bytecode
if bytecode == Bytecodes.halt:
return self.get_frame().get_stack_element(0)
elif bytecode == Bytecodes.dup:
self._do_dup()
elif bytecode == Bytecodes.push_local:
self._do_push_local(bytecode_index)
elif bytecode == Bytecodes.push_argument:
self._do_push_argument(bytecode_index)
elif bytecode == Bytecodes.push_field:
self._do_push_field(bytecode_index)
elif bytecode == Bytecodes.push_block:
self._do_push_block(bytecode_index)
elif bytecode == Bytecodes.push_constant:
self._do_push_constant(bytecode_index)
elif bytecode == Bytecodes.push_global:
self._do_push_global(bytecode_index)
elif bytecode == Bytecodes.pop:
self._do_pop()
elif bytecode == Bytecodes.pop_local:
self._do_pop_local(bytecode_index)
elif bytecode == Bytecodes.pop_argument:
self._do_pop_argument(bytecode_index)
elif bytecode == Bytecodes.pop_field:
self._do_pop_field(bytecode_index)
elif bytecode == Bytecodes.send:
self._do_send(bytecode_index)
elif bytecode == Bytecodes.super_send:
self._do_super_send(bytecode_index)
elif bytecode == Bytecodes.return_local:
self._do_return_local()
elif bytecode == Bytecodes.return_non_local:
self._do_return_non_local()
def push_new_frame(self, method):
# Allocate a new frame and make it the current one
self._frame = self._universe.new_frame(self._frame, method)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment