jsp@glia.biostr.washington.edu (Jeff Prothero) (11/20/90)
Why are the xlftab.c:funtab[] entries so carefully numbered? What is going to break if the numbering is changed? Primarily the image save/restore stuff? Why can't/shouldn't those things which will break key off the function names instead of the table offsets? Why are extra slots reserved at the end of funtab[]? What's the point of image save/restore? Should saved images be portable between machines or versions? Would it be hard/pointless to write code to convert the xlisp state into initialized C header files, so that the xlisp state could be portably compiled into an application? {...YOYOYOY...:-} -- jsp@glia.biostr.washington.edu (Jeff Prothero) jsp@u.washington.edu (If above bounces.) Biological Structure Graphics Lab, U Washington
toma@tekgvs.LABS.TEK.COM (Tom Almy) (11/21/90)
In article <JSP.90Nov19154628@glia.biostr.washington.edu> jsp@glia.biostr.washington.edu (Jeff Prothero) writes: >Why are the xlftab.c:funtab[] entries so carefully numbered? Beats me. I was careful to maintain the numbering until I ran out of slots. Now I just append to the end! The table is only actually scanned once (during initialization), and the scan is terminated by the null entry at the end. >What is going to break if the numbering is changed? Primarily the >image save/restore stuff? >Why can't/shouldn't those things which will break key off the function >names instead of the table offsets? The first entries, for the read macros and the intrinsic message selectors, are referenced by offset for initialization (probably due to laziness, but I am not sure). As long as you leave these alone, nothing else breaks. (but see below) >Why are extra slots reserved at the end of funtab[]? You can delete them. >What's the point of image save/restore? Should saved images be >portable between machines or versions? You can save your workspace, and go back to it at a later time, like in Smalltalk or APL. You can use it as a snapshot, and later go back in time. It is the only way to do a vector/string memory defragmentation (except for people who use my files dldmem and dlimage, in which case the defragmentation is automatic). Saved images are not portable between machines because these are binary files and the representations can change (big vs little endian, wordsize, etc). They are also not portable if funtab changes. >Would it be hard/pointless to write code to convert the xlisp >state into initialized C header files, so that the xlisp state >could be portably compiled into an application? The state is mainly a large initialized linked list which can not be statically declared in C (you need to execute code to set the links). IMHO it would also be pointless since applications should be distributed as xlisp source rather than C files (what if the user doesn't have a C compiler?). Tom Almy toma@tekgvs.labs.tek.com Standard Disclaimers Apply
jsp@glia.biostr.washington.edu. (Jeff Prothero) (11/21/90)
In article <8457@tekgvs.LABS.TEK.COM> toma@tekgvs.LABS.TEK.COM (Tom Almy) writes: In article <JSP.90Nov19154628@glia.biostr.washington.edu> jsp@glia.biostr.washington.edu (Jeff Prothero) writes: >>What's the point of image save/restore? Should saved images be >>portable between machines or versions? >Saved images are not portable between machines because these are binary >files and the representations can change (big vs little endian, wordsize, etc). >They are also not portable if funtab changes. Yeah... notice, my question was *should* saved images be portable. Do people save images only for an afternoon, or do they habitually archive them and come back a year later...? >>Would it be hard/pointless to write code to convert the xlisp >>state into initialized C header files, so that the xlisp state >>could be portably compiled into an application? >The state is mainly a large initialized linked list which can not be >statically declared in C (you need to execute code to set the links). Is this obviously true? You can initialize an array of pointers to functions in C. (Remember funtab[]? :-) As far as I know, you can initialize pointers to anything in C. Is it nonportable in practice to initialize an array of pointers with the pointers pointing various places into the array...? I don't think my compiler would have any problems with this... >IMHO it would also be pointless since applications should be distributed >as xlisp source rather than C files (what if the user doesn't have a C >compiler?). I'm sensitive to this. But loading a lot of source text in can slow things down. Loading an imagefile is one way to speed things up. Having the lisp image precompiled in would be another... >Tom Almy >toma@tekgvs.labs.tek.com >Standard Disclaimers Apply -- jsp@glia.biostr.washington.edu (Jeff Prothero) jsp@u.washington.edu (If above bounces.) Biological Structure Graphics Lab, U Washington
mayer@hplabsz.HPL.HP.COM (Niels Mayer) (11/21/90)
In article <JSP.90Nov19154628@glia.biostr.washington.edu> jsp@glia.biostr.washington.edu (Jeff Prothero) writes: >Why are the xlftab.c:funtab[] entries so carefully numbered? For function calls, the funtab index is necessary, but there are other ways of doing it -- xlisp/xlinit.c:initwks() just calls: | /* install the built-in functions and special forms */ | for (i = 0, p = funtab; p->fd_subr != NULL; ++i, ++p) | if (p->fd_name) | xlsubr(p->fd_name,p->fd_type,p->fd_subr,i); | which sets up a subr node, with a name, FSUBR/SUBR kind, function pointer, and offset (index into funtab) for each entry in funtab. A brief peruse of the code shows that xlisp/xlprin.c:putsubr() and xlisp/xlimage.c:xlirestore() are the only things that access the index into funtab. The former is used to get the name of the function, and the latter is used to retrieve the C function pointer assocd w/ a subr node from funtab... #ifdef ADVERTIZING_MODE_ON FYI, for perusing XLISP/WINTERP/MOTIF sources, I strongly encourage the use of powerful static analysis tools. AT&T's software toolchest has something called CSCOPE, and HP has a whizzy X11/Motif-Look-And-Feel programming environment (for C C++, Common Lisp, etc) called SOFTBENCH with a very nice static analysis tool... Much more useful than grep for answering questions like "list every use of this identifier", "show me the definition of this identifier", etc. Ask your friendly HP Sales rep for details. #endif Getting back to the point... Methods are added via xladdmsg(), which requires the index into the function table rather than a function pointer or somesuch. Example: in xlisp/xlobj.c: | xladdmsg(class,":NEW",FT_CLNEW); | xladdmsg(class,":ISNEW",FT_CLISNEW); | xladdmsg(class,":ANSWER",FT_CLANSWER); | xladdmsg(object,":ISNEW",FT_OBISNEW); | xladdmsg(object,":CLASS",FT_OBCLASS); | xladdmsg(object,":SHOW",FT_OBSHOW); Where FT_* are defined in xlisp/xlisp.h: | /* function table offsets for the initialization functions */ | #define FT_RMHASH 0 | #define FT_RMQUOTE 1 | #define FT_RMDQUOTE 2 | #define FT_RMBQUOTE 3 | #define FT_RMCOMMA 4 | #define FT_RMLPAR 5 | #define FT_RMRPAR 6 | #define FT_RMSEMI 7 | /* #define xxxxxx 8 */ | /* #define yyyyyy 9 */ | #define FT_CLNEW 10 | #define FT_CLISNEW 11 | #define FT_CLANSWER 12 | #define FT_OBISNEW 13 | #define FT_OBCLASS 14 | #define FT_OBSHOW 15 And xlisp/xlftab.c contains corresponding: | xladdmsg(class,":NEW",FT_CLNEW); | xladdmsg(class,":ISNEW",FT_CLISNEW); | xladdmsg(class,":ANSWER",FT_CLANSWER); | | /* finish initializing 'object' */ | setivar(object,SUPERCLASS,NIL); | xladdmsg(object,":ISNEW",FT_OBISNEW); | xladdmsg(object,":CLASS",FT_OBCLASS); | xladdmsg(object,":SHOW",FT_OBSHOW); >What is going to break if the numbering is changed? Primarily the >image save/restore stuff? The main reason is because you have to make sure that the number of an entry into funtab[] corresponds to the number in the #define FT_* in xlisp.h. If these get out of sync, then you end up calling the wrong method associated with a message, which isn't Good. If you restore into a system in which funtab[]'s entries are differently numbered, you'll pick up the wrong C function call... Since I added HUNDREDS of methods to implement WINTERP, I had to worry about funtab numbering alot. I didn't want to change XLISP extensively, because then it wouldn't be the same old standard xlisp that we're all used to (and patching it for updates would become harder). To avoid explicitly renumbering things, I did the ugly hack visible in src-server/w_funtab.c src-server/w_funtab.h (do not look at these after eating lest you want to lose your lunch). This hack/technique is also known as "C preprocessor abuse".... > >Why can't/shouldn't those things which will break key off the function >names instead of the table offsets? > Note that 'union ninfo' is a 2 element union. If you wanted to put the name, C fn ptr, SUBR/FSUBR info into the union, all value nodes would take up an extra 4 bytes. By keeping the static information in a table to be looked up when needed, and only keeping the C fn ptr and index in the value node, value nodes are kept small, and yet function calls don't require extra indirection. Your solution of keying off the function names sounds like it would require extra indirection, even with hashing. Other solutions and tradeoffs are obviously possible. The one we're discussing happens to be the way David Betz decided to do it. >Why are extra slots reserved at the end of funtab[]? > So you can add more functions easily. >What's the point of image save/restore? Faster startup times. >Should saved images be >portable between machines or versions? I don't think that's possible if different machines/versions have different primitives. You could define indexes 0 thru N to be common/shared functions, and have restore retrieve xnotdef() for all others. > >Would it be hard/pointless to write code to convert the xlisp >state into initialized C header files, so that the xlisp state >could be portably compiled into an application? ??? Perhaps you'd be better off looking at what gnuemacs and (I think) KCL do w/r/t dumping (akin to core dumping) an executable image and then "undumping" it to restore the executable and memory image created by loading and initializing files. Undumping is very nice when it works, but can create massive headaches when it doesn't. In the case of gnuemacs, these undumped images cannot be debugged with the manufacturer's supplied debugging tools. You could compile with gcc and debug with gdb. However, for HPUX HP's product compilers supposedly produce better/faster code. >{...YOYOYOY...:-} Indeed! ------------------------------------------------------------------------------- Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com Human-Computer Interaction Department Hewlett-Packard Laboratories Palo Alto, CA. *