# Path: src/som/interpreter/ast/nodes/dispatch.py
# class SuperDispatchNode(_AbstractDispatchNode):
# 
#     _immutable_fields_ = ['_cached_method']
# 
#     def __init__(self, selector, lookup_class, universe):
#         _AbstractDispatchNode.__init__(self, universe)
#         self._cached_method = lookup_class.lookup_invokable(selector)
#         if self._cached_method is None:
#             raise RuntimeError("#dnu support for super missing")
# 
#     def execute_dispatch(self, rcvr, args):
#         return self._cached_method.invoke(rcvr, args)
# 
# class UninitializedDispatchNode(_AbstractDispatchWithLookupNode):
# 
#     def _specialize(self, rcvr):
#         assert rcvr is not None
# 
#         # Determine position in dispatch node chain, i.e., size of inline cache
#         i_node = self
#         chain_depth = 0
# 
#         while isinstance(i_node.get_parent(), _AbstractDispatchNode):
#             i_node = i_node.get_parent()
#             chain_depth += 1
# 
#         send_node = i_node.get_parent()
# 
#         if chain_depth < _AbstractDispatchNode.INLINE_CACHE_SIZE:
#             rcvr_class = rcvr.get_class(self._universe)
#             method = rcvr_class.lookup_invokable(self._selector)
# 
#             new_chain_end = UninitializedDispatchNode(self._selector,
#                                                       self._universe)
# 
#             if method is not None:
#                 node = _CachedDispatchObjectCheckNode(rcvr_class, method,
#                                                       new_chain_end,
#                                                       self._universe)
#             else:
#                 node = _CachedDnuObjectCheckNode(self._selector, rcvr_class,
#                                                  new_chain_end, self._universe)
# 
#             return self.replace(node)
#         else:
#             # the chain is longer than the maximum defined by INLINE_CACHE_SIZE
#             # and thus, this callsite is considered to be megaprophic, and we
#             # generalize it.
# 
#             generic_replacement = GenericDispatchNode(self._selector,
#                                                       self._universe)
#             send_node.replace_dispatch_list_head(generic_replacement)
#             return generic_replacement
# 
#     def execute_dispatch(self, rcvr, args):
#         return self._specialize(rcvr).execute_dispatch(rcvr, args)
# 
# def send_does_not_understand(receiver, selector, arguments, universe):
#     args = _prepare_dnu_arguments(arguments, selector, universe)
#     return lookup_and_send(receiver, "doesNotUnderstand:arguments:", args, universe)
# 
# Path: src/som/interpreter/ast/nodes/message/abstract_node.py
# class AbstractMessageNode(ExpressionNode):
# 
#     _immutable_fields_ = ['_selector', '_universe',
#                           '_rcvr_expr?', '_arg_exprs?[*]']
#     _child_nodes_      = ['_rcvr_expr',  '_arg_exprs[*]']
# 
#     def __init__(self, selector, universe, rcvr_expr, arg_exprs,
#                  source_section = None):
#         ExpressionNode.__init__(self, source_section)
#         self._selector = selector
#         self._universe = universe
#         assert arg_exprs is not None
#         make_sure_not_resized(arg_exprs)
#         self._rcvr_expr = self.adopt_child(rcvr_expr)
#         self._arg_exprs = self.adopt_children(arg_exprs)
# 
#     @unroll_safe
#     def _evaluate_rcvr_and_args(self, frame):
#         rcvr = self._rcvr_expr.execute(frame)
#         assert isinstance(rcvr, AbstractObject)
#         if len(self._arg_exprs) == 0:
#             args = []
#         else:
#             args = [arg_exp.execute(frame) for arg_exp in self._arg_exprs]
#         return rcvr, args


from rlib.debug import make_sure_not_resized
from rlib.jit import we_are_jitted
from ..dispatch import SuperDispatchNode, UninitializedDispatchNode, send_does_not_understand
from .abstract_node import AbstractMessageNode
                                     arg_exprs, source_section)
        if rcvr_expr.is_super_node():
            dispatch = SuperDispatchNode(selector, rcvr_expr.get_super_class(),
                                         universe)
        else:
            dispatch = UninitializedDispatchNode(selector, universe)
        self._dispatch = self.adopt_child(dispatch)

    def replace_dispatch_list_head(self, node):
        self._dispatch.replace(node)

    def execute(self, frame):
        rcvr, args = self._evaluate_rcvr_and_args(frame)
        return self.execute_evaluated(frame, rcvr, args)

    def execute_evaluated(self, frame, rcvr, args):
        assert frame is not None
        assert rcvr is not None
        assert args is not None
        make_sure_not_resized(args)
        if we_are_jitted():
            return self._direct_dispatch(rcvr, args)
        else:
            return self._dispatch.execute_dispatch(rcvr, args)

    def _direct_dispatch(self, rcvr, args):
        method = self._lookup_method(rcvr)
        if method:
            return method.invoke(rcvr, args)
        else:

# Path: src/som/interpreter/ast/nodes/dispatch.py
# class SuperDispatchNode(_AbstractDispatchNode):
# 
#     _immutable_fields_ = ['_cached_method']
# 
#     def __init__(self, selector, lookup_class, universe):
#         _AbstractDispatchNode.__init__(self, universe)
#         self._cached_method = lookup_class.lookup_invokable(selector)
#         if self._cached_method is None:
#             raise RuntimeError("#dnu support for super missing")
# 
#     def execute_dispatch(self, rcvr, args):
#         return self._cached_method.invoke(rcvr, args)
# 
# class UninitializedDispatchNode(_AbstractDispatchWithLookupNode):
# 
#     def _specialize(self, rcvr):
#         assert rcvr is not None
# 
#         # Determine position in dispatch node chain, i.e., size of inline cache
#         i_node = self
#         chain_depth = 0
# 
#         while isinstance(i_node.get_parent(), _AbstractDispatchNode):
#             i_node = i_node.get_parent()
#             chain_depth += 1
# 
#         send_node = i_node.get_parent()
# 
#         if chain_depth < _AbstractDispatchNode.INLINE_CACHE_SIZE:
#             rcvr_class = rcvr.get_class(self._universe)
#             method = rcvr_class.lookup_invokable(self._selector)
# 
#             new_chain_end = UninitializedDispatchNode(self._selector,
#                                                       self._universe)
# 
#             if method is not None:
#                 node = _CachedDispatchObjectCheckNode(rcvr_class, method,
#                                                       new_chain_end,
#                                                       self._universe)
#             else:
#                 node = _CachedDnuObjectCheckNode(self._selector, rcvr_class,
#                                                  new_chain_end, self._universe)
# 
#             return self.replace(node)
#         else:
#             # the chain is longer than the maximum defined by INLINE_CACHE_SIZE
#             # and thus, this callsite is considered to be megaprophic, and we
#             # generalize it.
# 
#             generic_replacement = GenericDispatchNode(self._selector,
#                                                       self._universe)
#             send_node.replace_dispatch_list_head(generic_replacement)
#             return generic_replacement
# 
#     def execute_dispatch(self, rcvr, args):
#         return self._specialize(rcvr).execute_dispatch(rcvr, args)
# 
# def send_does_not_understand(receiver, selector, arguments, universe):
#     args = _prepare_dnu_arguments(arguments, selector, universe)
#     return lookup_and_send(receiver, "doesNotUnderstand:arguments:", args, universe)
# 
# Path: src/som/interpreter/ast/nodes/message/abstract_node.py
# class AbstractMessageNode(ExpressionNode):
# 
#     _immutable_fields_ = ['_selector', '_universe',
#                           '_rcvr_expr?', '_arg_exprs?[*]']
#     _child_nodes_      = ['_rcvr_expr',  '_arg_exprs[*]']
# 
#     def __init__(self, selector, universe, rcvr_expr, arg_exprs,
#                  source_section = None):
#         ExpressionNode.__init__(self, source_section)
#         self._selector = selector
#         self._universe = universe
#         assert arg_exprs is not None
#         make_sure_not_resized(arg_exprs)
#         self._rcvr_expr = self.adopt_child(rcvr_expr)
#         self._arg_exprs = self.adopt_children(arg_exprs)
# 
#     @unroll_safe
#     def _evaluate_rcvr_and_args(self, frame):
#         rcvr = self._rcvr_expr.execute(frame)
#         assert isinstance(rcvr, AbstractObject)
#         if len(self._arg_exprs) == 0:
#             args = []
#         else:
#             args = [arg_exp.execute(frame) for arg_exp in self._arg_exprs]
#         return rcvr, args


# Path: src/som/interpreter/ast/nodes/message/generic_node.py
from rlib.debug import make_sure_not_resized
from rlib.jit import we_are_jitted
from ..dispatch import SuperDispatchNode, UninitializedDispatchNode, send_does_not_understand
from .abstract_node import AbstractMessageNode

                                     arg_exprs, source_section)
        if rcvr_expr.is_super_node():
            dispatch = SuperDispatchNode(selector, rcvr_expr.get_super_class(),
                                         universe)
        else:
            dispatch = UninitializedDispatchNode(selector, universe)
        self._dispatch = self.adopt_child(dispatch)

    def replace_dispatch_list_head(self, node):
        self._dispatch.replace(node)

    def execute(self, frame):
        rcvr, args = self._evaluate_rcvr_and_args(frame)
        return self.execute_evaluated(frame, rcvr, args)

    def execute_evaluated(self, frame, rcvr, args):
        assert frame is not None
        assert rcvr is not None
        assert args is not None
        make_sure_not_resized(args)
        if we_are_jitted():
            return self._direct_dispatch(rcvr, args)
        else:
            return self._dispatch.execute_dispatch(rcvr, args)

    def _direct_dispatch(self, rcvr, args):
        method = self._lookup_method(rcvr)
        if method:
            return method.invoke(rcvr, args)
        else:

            return send_does_not_understand(rcvr, self._selector, args, self._universe)