[racket] Continuation in embedding Racket

From: Nesterov Kirill (k.v.nesterov at yandex.ru)
Date: Wed Dec 3 16:23:37 EST 2014

>  (call-with-continuation-prompt (lambda () (generate-digit)))
With this I'm getting segfault.

May be my eval handler can clear this situation:

bool idaapi Racket_cli_execute_line(const char *line){
  if(!global_env)
    msg("Racket global_env is null!\n");
  else{
    mz_jmp_buf * volatile save = NULL, fresh;
    Scheme_Config *config = NULL;
    Scheme_Object * r, * curout;
    Scheme_Thread * volatile sct = scheme_get_current_thread();

    MZ_GC_DECL_REG(4);
    MZ_GC_VAR_IN_REG(0, curout);
    MZ_GC_VAR_IN_REG(1, save);
    MZ_GC_VAR_IN_REG(2, config);
    MZ_GC_VAR_IN_REG(3, r);

    MZ_GC_REG();
    
    save = sct->error_buf;
    sct->error_buf = &fresh;

    if (scheme_setjmp(fresh)) {
      msg("Error\n");
      sct->error_buf = save;
    }
    else {
      config = scheme_current_config();
      curout = scheme_get_param(config, MZCONFIG_OUTPUT_PORT);
      r = scheme_eval_string_all(line, global_env, 1);
      if(!SCHEME_VOIDP(r))
	scheme_display(r, curout);
      scheme_display(scheme_make_char('\n'), curout);
    }
    sct->error_buf = save;
    MZ_GC_UNREG();
  }
      
  return true;
}



03.12.2014, 23:55, "Matthew Flatt" <mflatt at cs.utah.edu>:
> I don't think CGC versus 3m is relevant.
>
> My guess is that you need to wrap a prompt around each evaluation of a
> top-level form. You can try this manually at first: Does it work to
> change each `(generate-digit)` at the end below to
>
>  (call-with-continuation-prompt (lambda () (generate-digit)))
>
> ? If so, then building that `call-with-continuation-prompt` wrapper
> into your evaluation function will likely solve the problem.
>
> At Wed, 03 Dec 2014 23:45:28 +0300, Nesterov Kirill wrote:
>>  Hi all,
>>
>>  I'm trying to embed racket 3m version as interpreter into GUI application. For
>>  custom interpreters this application have two required APIs - first one is init
>>  and the second one is eval string. So in init I'm calling
>>  scheme_register_tls_space and scheme_main_setup after. And in eval I'm using
>>  custom version of Racket's read-eval-print-loop without recursion for
>>  evaluation of thrings. And everything is working well until I've tried to
>>  implement generator. Some reading of sources lead we into problem of
>>  continuation. This simple code leads to error "continuation application:
>>  attempt to cross a continuation barrier".
>>
>>  (define (generate-one-element-at-a-time lst)
>>
>>    (define (control-state return)
>>      (for-each
>>       (lambda (element)
>>                 (set! return (call-with-current-continuation
>>                                (lambda (resume-here)
>>                                  ;; Grab the current continuation
>>                                 (set! control-state resume-here)
>>                                 (return element)))))
>>       lst)
>>      (return 'you-fell-off-the-end))
>>
>>    (define (generator)
>>      (call-with-current-continuation control-state))
>>
>>    ;; Return the generator
>>    generator)
>>
>>  (define generate-digit
>>    (generate-one-element-at-a-time '(0 1 2)))
>>
>>  (generate-digit) ;; 0
>>  (generate-digit) ;; 1 ;; error "continuation application: attempt to cross a
>>  continuation barrier"
>>
>>  Attemt to use generators library lead to memory access violation. I suppose the
>>  problem lies in stack frames which are cleared every time eval callback from
>>  the main program is called. For some reasons I can't run racket in another
>>  thread. So may be there is an option how this problem could be solved? May be
>>  my assumption is not right? May be switch to CGC and mapping stack with
>>  scheme_set_stack_base into heap can help? If it help I can show the source of
>>  this plugin.
>>
>>  Thanks,
>>  Kirill
>>  ____________________
>>    Racket Users list:
>>    http://lists.racket-lang.org/users

Posted on the users mailing list.