Esempio n. 1
0
    def switch_to_smalltalk(self, interp, s_frame, first_call=False):
        self.post_resume()
        log('Switching to Smalltalk...')

        if self.is_done():
            return self._create_return_frame(interp.space)

        # import pdb; pdb.set_trace()
        if first_call:  # attach s_frame with resume method for the first time
            s_resume_frame = self._build_resume_method(interp.space,
                                                       is_eval=True)
            s_resume_frame.store_s_sender(s_frame)
        elif s_frame.w_method() is self.resume_method.get():
            s_resume_frame = self._build_resume_method(interp.space)
            eval_frame = s_frame.s_sender()
            # Ensure #resume: method with closure = nil
            if (eval_frame.w_method() is self.eval_method.get()
                    and eval_frame.closure is not None):
                # instead of chaining resume frames, store original sender
                s_resume_frame.store_s_sender(eval_frame)
            else:
                print('Unexpected eval_frame found:\n%s' %
                      s_frame.print_stack())
                s_resume_frame.store_s_sender(s_frame)
        else:
            print 'Unexpected s_frame found:\n%s' % s_frame.print_stack()
            s_resume_frame = s_frame
        interp.quick_check_for_interrupt(s_resume_frame,
                                         dec=interp.interrupt_counter_size)
        # this will raise a ProcessSwitch if there are interrupts or timers ...
        return s_resume_frame
Esempio n. 2
0
 def _create_return_frame(self, space):
     from rsqueakvm.storage_contexts import ContextPartShadow
     log('Language has finished and returned a result.')
     # we want evalInThread and resumePython to return new frames,
     # so we don't build up stack, but we also don't raise to the
     # top-level loop all the time.
     # For resuming, we obviously need a new frame, because that's
     # how the Smalltalk scheduler knows how to continue back to Python.
     # Unfortunately, a primitive can only EITHER always return a new
     # frame OR a result. So when we get a result, we cannot simply
     # return it. Instead, we need to build a frame that simply returns
     # the result
     if space.is_spur.is_set():
         w_cm = objectmodel.instantiate(W_SpurCompiledMethod)
     else:
         w_cm = objectmodel.instantiate(W_PreSpurCompiledMethod)
     w_resume_class = self.foreign_process_class()
     w_cm.header = 0
     w_cm._primitive = 0
     w_cm.literalsize = 3
     w_cm.islarge = False
     w_cm._tempsize = 0
     w_cm.argsize = 0
     w_cm.compiledin_class = w_resume_class.getclass(space)
     w_cm.lookup_selector = 'fakeReturnResult'
     w_cm.bytes = [
         chr(b) for b in [
             0x20,  # push constant
             0x7C,  # return stack top
         ]
     ]
     w_cm.literals = [self.get_result(), space.w_nil, w_cm.compiledin_class]
     return ContextPartShadow.build_method_context(space, w_cm,
                                                   w_resume_class)
Esempio n. 3
0
    def switch_to_smalltalk(self, interp, s_frame, first_call=False):
        self.post_resume()
        log('Switching to Smalltalk...')

        if self.is_done():
            return self._create_return_frame(interp.space)

        # import pdb; pdb.set_trace()
        if first_call:  # attach s_frame with resume method for the first time
            s_resume_frame = self._build_resume_method(
                interp.space, is_eval=True)
            s_resume_frame.store_s_sender(s_frame)
        elif s_frame.w_method() is self.resume_method.get():
            s_resume_frame = self._build_resume_method(interp.space)
            eval_frame = s_frame.s_sender()
            # Ensure #resume: method with closure = nil
            if (eval_frame.w_method() is self.eval_method.get() and
                    eval_frame.closure is not None):
                # instead of chaining resume frames, store original sender
                s_resume_frame.store_s_sender(eval_frame)
            else:
                print ('Unexpected eval_frame found:\n%s' %
                       s_frame.print_stack())
                s_resume_frame.store_s_sender(s_frame)
        else:
            print 'Unexpected s_frame found:\n%s' % s_frame.print_stack()
            s_resume_frame = s_frame
        interp.quick_check_for_interrupt(s_resume_frame,
                                         dec=interp.interrupt_counter_size)
        # this will raise a ProcessSwitch if there are interrupts or timers ...
        return s_resume_frame
Esempio n. 4
0
 def _create_return_frame(self, space):
     from rsqueakvm.storage_contexts import ContextPartShadow
     log('Language has finished and returned a result.')
     # we want evalInThread and resumePython to return new frames,
     # so we don't build up stack, but we also don't raise to the
     # top-level loop all the time.
     # For resuming, we obviously need a new frame, because that's
     # how the Smalltalk scheduler knows how to continue back to Python.
     # Unfortunately, a primitive can only EITHER always return a new
     # frame OR a result. So when we get a result, we cannot simply
     # return it. Instead, we need to build a frame that simply returns
     # the result
     if space.is_spur.is_set():
         w_cm = objectmodel.instantiate(W_SpurCompiledMethod)
     else:
         w_cm = objectmodel.instantiate(W_PreSpurCompiledMethod)
     w_resume_class = self.foreign_process_class()
     w_cm.header = 0
     w_cm._primitive = 0
     w_cm.literalsize = 3
     w_cm.islarge = False
     w_cm._tempsize = 0
     w_cm.argsize = 0
     w_cm.compiledin_class = w_resume_class.getclass(space)
     w_cm.lookup_selector = 'fakeReturnResult'
     w_cm.bytes = [chr(b) for b in [
         0x20,  # push constant
         0x7C,  # return stack top
     ]]
     w_cm.literals = [self.get_result(), space.w_nil, w_cm.compiledin_class]
     return ContextPartShadow.build_method_context(
         space, w_cm, w_resume_class)
Esempio n. 5
0
 def _switch_to_handle(self):
     if not self._has_valid_handle():
         print 'handle not valid: %s' % self.handle
         return
     self.handle = self.sthread.switch(self.handle)
     if self.handle is self.sthread.get_null_handle():
         log('language_process thread has finished (handle is null)')
     if self.sthread.is_empty_handle(self.handle):
         log('language_process thread has finished (handle is empty)')
Esempio n. 6
0
 def setup(self):
     try:
         self.counter_size.set(
             int(os.environ.get('TOPAZ_CHECK_INTERVAL') or '10000'))
         self.interrupts_disabled.set(
             bool(os.environ.get('TOPAZ_DISABLE_INTERRUPTS')))
     except:
         pass
     if self.interrupts_disabled.get():
         log('TOPAZ_DISABLE_INTERRUPTS set.')
     else:
         log('TOPAZ_CHECK_INTERVAL set to %s.' % self.counter_size.get())
Esempio n. 7
0
 def setup(self):
     try:
         self.counter_size.set(int(
             os.environ.get('TOPAZ_CHECK_INTERVAL') or '10000'))
         self.interrupts_disabled.set(bool(
             os.environ.get('TOPAZ_DISABLE_INTERRUPTS')))
     except:
         pass
     if self.interrupts_disabled.get():
         log('TOPAZ_DISABLE_INTERRUPTS set.')
     else:
         log('TOPAZ_CHECK_INTERVAL set to %s.' % self.counter_size.get())
Esempio n. 8
0
 def new_stacklet_callback(h, arg):
     log('new_stacklet_callback: %s' % h)
     self = global_execution_state.origin
     self.handle = h
     global_execution_state.clear()
     # stacklets start immediate, so yield back before executing any code,
     # code is only executed when the resume primitive is used,
     # eval primitive only creates a new language process
     self.return_to_smalltalk()
     self.language_process().safe_run()
     global_execution_state.origin = self
     return self.handle  # return to Smalltalk when done
Esempio n. 9
0
def get_restart_pycode(source, filename='<string>', cmd='exec'):
    log('Trying to patch:\n%s' % source)
    try:
        py_code = py_compiling.compile(py_space, py_space.newtext(source),
                                       filename, cmd)
        if not isinstance(py_code, PyCode):
            print 'py_code not an instance of PyCode'
            return
        if cmd == 'eval':
            return py_code
        co_consts_w_len = len(py_code.co_consts_w)
        if co_consts_w_len >= 1:
            if co_consts_w_len > 1:
                log('More than 1 const produced: %s' % co_consts_w_len)
            first_consts_w = py_code.co_consts_w[0]
            if not isinstance(first_consts_w, PyCode):
                log('First const is not a PyCode')
                return py_code
            return first_consts_w
    except OperationError as e:
        # import pdb; pdb.set_trace()
        print 'Failed to compile new frame: %s' % e.errorstr(py_space)
Esempio n. 10
0
def get_restart_pycode(source, filename='<string>', cmd='exec'):
    log('Trying to patch:\n%s' % source)
    try:
        py_code = py_compiling.compile(py_space, py_space.newtext(source),
                                       filename, cmd)
        if not isinstance(py_code, PyCode):
            print 'py_code not an instance of PyCode'
            return
        if cmd == 'eval':
            return py_code
        co_consts_w_len = len(py_code.co_consts_w)
        if co_consts_w_len >= 1:
            if co_consts_w_len > 1:
                log('More than 1 const produced: %s' % co_consts_w_len)
            first_consts_w = py_code.co_consts_w[0]
            if not isinstance(first_consts_w, PyCode):
                log('First const is not a PyCode')
                return py_code
            return first_consts_w
    except OperationError as e:
        # import pdb; pdb.set_trace()
        print 'Failed to compile new frame: %s' % e.errorstr(py_space)
Esempio n. 11
0
 def __init__(self, language_process):
     log('Starting %s...' % language_process)
     self._language_process = language_process
Esempio n. 12
0
 def resume(self):
     log('Resuming %s...' % self.language_process())
     self.language_process().pre_resume()
     self._resume_thread()