<div dir="ltr">Thanks Bill, that seems to be all working so far. Thanks for the explanation. I am having a weird occasional issue though, which has me worried that I could have a nasty bug in how I've set things up. In max, I've got it so that multiple s7 interpreters can be running, one in each s4m.scm object. So far no issues on this approach. I've pasted my eval helper below, adapted from the grepl.c example.<div><br></div><div>So yesterday, I had this weird thing happen where one instance of the interpreter started logging a bizarre error message from this function, that didn't seem to have any relevance to what it was doing, and it was also still managing to execute code at the same time. It looked from the outside like s7_eval_string was getting called twice, once with something totally unexpected, and once with what I expect. I just wondered if there are ever cases you've seen where s7_get_output_string and s7_current_error_port could be returning the wrong errors, or stale data of some kind. I know this is all rather vague, but the behaviour has me completely flumoxed. No worries if it's too vague to even comment on.</div><div><br></div><div>thanks</div><div>iain<br><div><br></div><div>// eval string with error logging<br>void scm4max_s7_eval_string(t_scm4max *x, char *string_to_eval){<br> //post("scm4max_s7_eval_string() %s", string_to_eval);<br> int gc_loc;<br> s7_pointer old_port, result;<br> const char *errmsg = NULL;<br> char *msg = NULL;<br> old_port = s7_set_current_error_port(x->s7, s7_open_output_string(x->s7));<br> gc_loc = s7_gc_protect(x->s7, old_port);<br> s7_pointer res = s7_eval_c_string(x->s7, string_to_eval);<br> errmsg = s7_get_output_string(x->s7, s7_current_error_port(x->s7));<br> if ((errmsg) && (*errmsg)){<br> msg = (char *)calloc(strlen(errmsg) + 1, sizeof(char));<br> strcpy(msg, errmsg);<br> }<br> s7_close_output_port(x->s7, s7_current_error_port(x->s7));<br> s7_set_current_error_port(x->s7, old_port);<br> s7_gc_unprotect_at(x->s7, gc_loc);<br> if (msg){<br> object_error(x, "s4m Error: %s", msg);<br> free(msg);<br> }else{<br> scm4max_post_s7_res(x, res);<br> }<br>}<br><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 11, 2020 at 5:35 AM <<a href="mailto:bil@ccrma.stanford.edu">bil@ccrma.stanford.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">> What is the reason we need to do the gc_protect and later unprotect of <br>
> the old port?<br>
<br>
It looks like I never addressed that in s7.html. There is a short<br>
explanation in s7.h under s7_gc_protect. In s7, the GC can run<br>
at any time. If you have stored a reference to an s7 object,<br>
and the GC might run during its lifetime, and its lifetime<br>
is not really short (there's a lag between the making of an object<br>
and its first possible GC), you need to protect it. It will remain<br>
protected until you unprotect it, so to avoid an ever-growing heap,<br>
you need to unprotect it.<br>
<br>
<br>
</blockquote></div>