def do_rewind_frames(frames, index, env, final_cont): from pycket.interpreter import return_void if index < 0: return return_void(env, final_cont) frame = frames[index] ctxt = rewind_next_frame_cont(frames, index, final_cont, env, frame.prev) return frame.rewind(env, ctxt)
def default_error_display_handler(msg, exn_object, env, cont): from pycket.prims.input_output import current_error_param, return_void port = current_error_param.get(cont) assert isinstance(port, values.W_OutputPort) port.write("%s : %s\n" % (exn_object.struct_type().name.tostring(), msg.tostring())) # FIXME : FIX the continuation-mark-set->context and extract a stack trace using it return return_void(env, cont)
def install_continuation_fast_path(current_cont, args, has_handlers, env, cont): from pycket.interpreter import return_multi_vals, return_void if not has_handlers: args = values.Values.make(args) return return_multi_vals(args, env, cont) unwind = find_handlers(current_cont, cont) cont = return_args_cont(args, env, cont) unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def default_error_display_handler(msg, exn_object, env, cont): from pycket.prims.input_output import current_error_param, return_void port = current_error_param.get(cont) assert isinstance(port, values.W_OutputPort) if is_exn(exn_object): port.write("%s : %s\n" % (exn_object.struct_type().name.tostring(), msg.tostring())) else: port.write("exception : %s\n" % (msg.tostring())) if not is_user_exn(exn_object): display_stack_trace(port, cont) return return_void(env, cont)
def install_continuation(cont, prompt_tag, args, env, current_cont, extend=False, escape=False): from pycket.interpreter import return_multi_vals, return_void # Find the common merge point for two continuations # The extend option controls whether or not we remove frames from the # existing continuation, or simply stack the new continuation on top. # This is what differentiates call-with-current-continuation from # call-with-composable-continuation. if extend: _, rewind = find_continuation_prompt(prompt_tag, cont, direction='rewind') base, unwind = current_cont, None stop = None else: head1, handlers = scan_continuation(current_cont, prompt_tag, look_for=cont, escape=escape) if head1 is None: return install_continuation_fast_path(current_cont, args, handlers, env, cont) head2, _ = scan_continuation(cont, prompt_tag) base, stop, unwind, rewind = find_merge_point(head1, head2) # Append the continuations at the appropriate prompt if base is not None: cont = cont.append(base, stop=stop, upto=prompt_tag) # Fast path if no unwinding is required (avoids continuation allocation) if not unwind and not rewind: args = values.Values.make(args) return return_multi_vals(args, env, cont) # NOTE: All the continuations pushed here expect no arguments # They simply wrap functions which we could call directly, but using # continuations to perform the desired sequencing is easier. cont = return_args_cont(args, env, cont) if rewind: cont = do_rewind_cont(rewind, env, cont) if unwind: unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def install_continuation(cont, prompt_tag, args, env, current_cont, extend=False, escape=False): from pycket.interpreter import return_multi_vals, return_void # Find the common merge point for two continuations # The extend option controls whether or not we remove frames from the # existing continuation, or simply stack the new continuation on top. # This is what differentiates call-with-current-continuation from # call-with-composable-continuation. if extend: _ , rewind = find_continuation_prompt(prompt_tag, cont, direction='rewind') base, unwind = current_cont, None stop = None else: head1, handlers = scan_continuation( current_cont, prompt_tag, look_for=cont, escape=escape) if head1 is None: return install_continuation_fast_path(current_cont, args, handlers, env, cont) head2, _ = scan_continuation(cont, prompt_tag) base, stop, unwind, rewind = find_merge_point(head1, head2) # Append the continuations at the appropriate prompt if base is not None: cont = cont.append(base, stop=stop, upto=prompt_tag) # Fast path if no unwinding is required (avoids continuation allocation) if not unwind and not rewind: args = values.Values.make(args) return return_multi_vals(args, env, cont) # NOTE: All the continuations pushed here expect no arguments # They simply wrap functions which we could call directly, but using # continuations to perform the desired sequencing is easier. cont = return_args_cont(args, env, cont) if rewind: cont = do_rewind_cont(rewind, env, cont) if unwind: unwind = [x for x in reversed(unwind)] cont = do_unwind_cont(unwind, env, cont) return return_void(env, cont)
def rewind(self, env, cont): from pycket.interpreter import return_void return return_void(env, cont)