Emacs::EPL - Protocol implementation and data conversions for Emacs Perl
use Emacs::EPL ':server'; Emacs::EPL::loop;
This module is used internally by epl.el and Emacs::Lisp.
If you use
eval to catch errors in Lisp functions, and
contains a string beginning with
'.Emacs::EPL' (note initial dot),
be sure to
die with the same string before returning control to
This stuff is mainly for the benefit of the author.
NO. CONSTRAINTS INITIAL MSG CLASS FINAL ----- ---------------------- ------------- ------------ -------------- (1) <0> START <1> (2) <1> RAISE <0> (3) <1> RETURN <2,0> (4) <2,0> RETURN <0> (5) <2,n> UNREF <3,0,n> (6) <2,n> CALL <2,n+1> (7) n>0 <2,n> RETURN <2,n-1> (13) <3,0,n> RETURN <2,n> (14) <3,m,n> UNREF <3,m+1,n> (15) m>0 <3,m,n> RETURN <3,m-1,n>
The master is defined to be the process that sends the START message. The other process is the slave. It follows by induction from the table that the master sends in states <0>, <2,n> for even n, and <3,m,n> for odd m+n, and that the slave sends in all other states.
Initiate communication, e.g. by running a subprocess or opening a connection. The slave, if able, sends either a handshake (RETURN) or an exception (RAISE) in response. If an exception is raised, no further communication is permitted.
frame = 1
Request to run code. The calling process may be reentered by a subsequent CALL. Our call ends when we receive a RETURN, RAISE, or POP in the same frame or we send a POP in a next inner frame. If we receive a POP and subsequently use RETURN to exit this frame, the value we return will be ignored.
frame += 1 Lisp: funcall Perl: eval
Deliver the response to a CALL request (7), report successful startup (3), or mark the end of a series of UNREF requests (13, 15). Not permitted in a popped frame.
The three meanings could have been given different names: ``return'', ``handshake'', and ``end_unrefs''.
frame -= 1 Lisp: function return Perl: eval return
Return via exception mechanism, i.e., non-locally. RAISE has the same protocol semantics as RETURN, except that it is permitted in popped frames. It is expected that unless the user has taken specific steps (i.e., a "try" block) in the frame being returned to, the recipient will propagate the exception by sending another RAISE with the same or equivalent argument.
frame -= 1 Lisp: signal Perl: die
Either terminate communication (4), or exit the current frame (11, 12). This also says that we will ignore the argument of a subsequent RETURN from this frame (but will not ignore a RAISE value).
frame -= 1 Lisp: throw, kill-emacs Perl: exit, any nonlocal jump other than die
Send a list of handles that they have given us and that we promise never to use again, so that they may free up some resources. Maybe the resources they free will include references to our stuff, so they may send us some UNREF requests before ending the list with a RETURN. They must not, however, issue any other kinds of requests until they've sent RETURN in this frame.
frame += 1 Lisp: perl-free-ref, whatever garbage-detection means is in effect Perl: DESTROY
Mark-and-sweep garbage collection could be supported by:
(16) <2,n,@s> GC <4,n,@s> (17) <4,n,@s> RETURN(0) <2,n,@s> (18) <4,n,@s> RETURN(1) <5,0,n,@s> (19) <5,0,n,@s> RETURN <3,0,n,@s> (20) <5,m,n,@s> MARK <5,m+1,n,@s> (21) m>=1 <5,m,n,@s> RETURN <5,m-1,n,@s>
Transition (17) gives the receiver a chance to refuse to support mark-and-sweep or simply to indicate that all references are in use. Which of these two is the case could be indicated by another return code.
It might be useful to distinguish between recursive and nonrecursive calls:
(22) <2,n> SIMPLE_CALL <6,n> (23) <6,n> RETURN <2,n>
Further state classes could be introduced to allow UNREF, GC, RAISE, or POP operations during nonrecursive calls. Better yet, add some boolean parameters to the states we've got and to CALL.
Hey, how about CALL/CC and START_THREAD. Then of course you'd need JOIN, YIELD, LOCK, WAIT, ... . Pretty soon you'd have yourself an operating system. Yawn.
The current EPL implementation uses only transitions of types (1) to (15).
Copyright (C) 2001 by John Tobey, firstname.lastname@example.org. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA