From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Marius Vollmer Newsgroups: gmane.lisp.guile.user Subject: Refactoring dynamic roots Date: Mon, 24 Jan 2005 21:55:24 +0100 Message-ID: NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1106602237 22116 80.91.229.6 (24 Jan 2005 21:30:37 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Mon, 24 Jan 2005 21:30:37 +0000 (UTC) Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Mon Jan 24 22:30:17 2005 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CtBmq-0005x3-00 for ; Mon, 24 Jan 2005 22:30:16 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CtBz3-0006PV-Ta for guile-user@m.gmane.org; Mon, 24 Jan 2005 16:42:54 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1CtBxh-0005bK-TM for guile-user@gnu.org; Mon, 24 Jan 2005 16:41:29 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1CtBxg-0005ac-QF for guile-user@gnu.org; Mon, 24 Jan 2005 16:41:29 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CtBnU-0002iv-S9 for guile-user@gnu.org; Mon, 24 Jan 2005 16:30:56 -0500 Original-Received: from [129.217.163.1] (helo=mail.dt.e-technik.uni-dortmund.de) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CtBF9-0002u0-Ek for guile-user@gnu.org; Mon, 24 Jan 2005 15:55:27 -0500 Original-Received: from localhost (localhost [127.0.0.1]) by mail.dt.e-technik.uni-dortmund.de (Postfix) with ESMTP id DADF944234 for ; Mon, 24 Jan 2005 21:55:26 +0100 (CET) Original-Received: from mail.dt.e-technik.uni-dortmund.de ([127.0.0.1]) by localhost (krusty [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 12385-05-2 for ; Mon, 24 Jan 2005 21:55:26 +0100 (CET) Original-Received: from troy.dt.e-technik.uni-dortmund.de (troy.dt.e-technik.uni-dortmund.de [129.217.163.17]) by mail.dt.e-technik.uni-dortmund.de (Postfix) with ESMTP id 41F5644232 for ; Mon, 24 Jan 2005 21:55:25 +0100 (CET) Original-Received: by troy.dt.e-technik.uni-dortmund.de (Postfix, from userid 520) id C033BB9A4; Mon, 24 Jan 2005 21:55:24 +0100 (CET) Original-To: guile-user@gnu.org User-Agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3 (gnu/linux) X-Virus-Scanned: by amavisd-new at dt.e-technik.uni-dortmund.de X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: main.gmane.org gmane.lisp.guile.user:4155 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.user:4155 Hi, I have a dim plan for redoing dynamic roots in a more useful way and I like to test the ideas out on you. Right now, dynamic roots are useful mainly for two things: controlling continuations so that they don't jump past you, and isolating changes to the 'dynamic state' (the values of all fluids and the current ports) of Guile. I want to separate these two functionalities since you might want one without the other. Also, entering a dynamic root now unwinds the active dynamic-winds to the root and winds them back when leaving the root. This might not be wanted and is potentially expensive. Also, the roles of dynamic roots in Guile is not as clear now as it could be, in my view, and cleaning them up will make the internals a lot simpler, I hope. ** Controlling continuations Controlling continuations is useful when invoking Scheme callbacks from C code in a situation where the C code must guarantee that the callback returns exactly once. There is a proposal for this in workbook/extensions/dynamic-root.text, but I want to simplify this even more by not caring about an exception handler. Error handling needs to be taken care of anyway, and I think it is more flexible to not include it in these functions. For example, I hope that we have a way in the future to directly specify an error handler that is called in the dynamic context of the error and not in the dynamic context from where it was installed. That might mean that we have two ways to handle errors and I think it will be easier to offer them when not too many functions deal with the business of setting up error handlers. - void *scm_c_with_continuation_barrier (void *(func)(void *), void *data) Call FUNC on DATA and do not allow the invocation of continuations that would cross the invocation to scm_with_continuation_barrier. Such an attempt causes an error to be signaled. Throws (such as errors) that are not caught from within FUNC are caught by scm_with_continuation_barrier. In that case, a short message is printed to the current error port and NULL is returned. Thus, scm_with_continuation_barrier returns exactly once. [ The docs for scm_with_guile would state that it includes an implicit call to scm_c_with_continuation_barrier. ] - with-continuation-barrier proc Like scm_c_with_continuation_barrier but return '#f' for uncaught throws. ** Controlling the dynamic state The other thing that dynamic roots do is to isolate changes to the dynamic state. For example, calls to set-current-output-port or fluid-set! have no effects outside of a dynamic root. This might be useful when running arbitrary code since the caller can protect itself from unexpected changes to the dynamic state. (This is not _that_ useful for sandboxing code since the code can of course change the global state of Guile arbitrarily unless other measures are taken.) Of course, when running arbitrary code, it is nice to give it its own dynamic state and to use that dynamic state from one run to the next. This can not be done with dynamic roots right now since each call to call-with-dynamic-root creates a new root. Therefore, the functions below allow one to create a 'dynamic state' object that can be reused. I think it would be nice to have 'eval' take such an object as its second arg. The dynamic state contains the current module, and in that way the dynamic state might be a better representation of an execution environment than just a module. The implementation would be like this: each thread has a pointer to a 'current dynamic state object'. The list of active dynamic-winds is separate from this. References to fluids and current ports, etc are made to this current dynamic state object. Evaluating code with a different dynamic state object swaps this object in and out via dynamic-wind. It wont probably be the case i the beginning, but it might be good to let a dynamic state object be just the values of the fluids, nothing more, and do all dynamic state stuff such as the ports with fluids. - make-dynamic-state [parent] Make a new dynamic state object and initialize it from PARENT. When PARENT is omitted, the current dynamic state object is used. - current-dynamic-state Return the current dynamic state object. - set-current-dynamic-state state Make STATE the current dynamic state object. Using with-dynamic-state is usually more appropriate. [But since it is harmless to provide this function, we do anyway.] - with-dynamic-state state proc Call PROC while STATE is the current dynamic state object. This behaves like dynamic-wind, swapping the current dynamic states when control flow crosses. - with-new-dynamic-state proc The same as (with-dynamic-state (make-dynamic-state) proc). - eval FORM [STATE] When the second argument to eval is a dynamic state object, evaluate FORM from within a suitable call to with-dynamic-state. - void scm_frame_dynamic_state (SCM state) Set the current dynamic state to STATE while the current frame is active. _______________________________________________ Guile-user mailing list Guile-user@gnu.org http://lists.gnu.org/mailman/listinfo/guile-user