@@ -0,0 +1,2539 @@
+from rsqueakvm.util import system%0Aif %22TailcallPlugin%22 not in system.optional_plugins:%0A    raise LookupError%0A%0Afrom rsqueakvm.error import PrimitiveFailedError%0Afrom rsqueakvm.plugins.plugin import Plugin, PluginPatchScripts%0A%0Afrom rpython.rlib import jit%0A%0ATailcallPlugin = Plugin()%0A%0A%0Adef _patch_contexts():%0A    from rsqueakvm.storage_contexts import ContextPartShadow, ExtraContextAttributes%0A    from rsqueakvm.model.compiled_methods import W_CompiledMethod%0A%0A    def is_tailcall_context(self):%0A        return jit.promote(self.get_extra_data()._is_tailcall_context)%0A    def set_is_tailcall_context(self):%0A        self.get_extra_data()._is_tailcall_context = True%0A    ContextPartShadow.is_tailcall_context = is_tailcall_context%0A    ContextPartShadow.set_is_tailcall_context = set_is_tailcall_context%0A%0A    ExtraContextAttributes._attrs_ += %5B'_is_tailcall_context'%5D%0A    original_init = ExtraContextAttributes.__init__%0A    def init_with_tailcallmarker(self):%0A        original_init(self)%0A        self._is_tailcall_context = False%0A    ExtraContextAttributes.__init__ = init_with_tailcallmarker%0A%0A_patch_contexts()%0A%0Adef _patch_interpreter():%0A    from rsqueakvm.interpreter import Interpreter%0A    original_stack_frame = Interpreter.stack_frame%0A    @jit.unroll_safe%0A    def stack_frame(self, s_frame, old_s_frame):%0A        if old_s_frame.is_tailcall_context() %5C%0A           and s_frame.w_method() is old_s_frame.w_method() %5C%0A           and old_s_frame.pc() == s_frame.w_method.end_pc():%0A            old_s_frame.store_pc(0)%0A            for i in range(0, len(old_s_frame._temps_and_stack)):%0A                old_s_frame._temps_and_stack%5Bi%5D = s_frame._temps_and_stack%5Bi%5D%0A            old_s_frame._stack_ptr =old_s_frame.tempsize()%0A            old_s_frame.initialize_temps(self.space, w_arguments)%0A        else:%0A            return original_stack_frame(self, s_frame, old_s_frame)    %0A    Interpreter.stack_frame = stack_frame%0A%0APluginPatchScripts.append(_patch_interpreter)%0A%0A@TailcallPlugin.expose_primitive(unwrap_spec=%5Bobject%5D)%0Adef primitiveMarkTailcallContext(interp, s_frame, w_recv):%0A    s_frame.set_is_tailcall_context()%0A    return w_recv%0A%0A@TailcallPlugin.expose_primitive(unwrap_spec=%5Bobject%5D)%0Adef primitiveIsTailcallContext(interp, s_frame, w_recv):%0A    return s_frame.is_tailcall_context()%0A%0A%22%22%22%0A'From Squeak6.0alpha of 5 December 2016 %5Blatest update: #16859%5D on 21 December 2016 at 1:53:02 pm'!%0A%0A!Object methodsFor: '*tailcall' stamp: 'topa 12/21/2016 13:52'!%0Atailrecursive%0A%09%3Cprimitive: 'primitiveMarkTailcallContext' module: 'TailcallPlugin'%3E! !%0A%0A%22%22%22%0A

Add tailcall plugin.