Previous: Program Self-Knowledge, Up: The Implementation [Contents][Index]
malloc()
storage.
lgcd()
needs to generate at most one bignum, but currently
generates more.
divide()
could use shifts instead of multiply and divide when
scaling.
dump
ing an executable does not preserve ports. When
loading a dump
ed executable, disk files could be reopened to the
same file and position as they had when the executable was dumped.
Provided there is still type code space available in SCM, if we devote some of the IMCAR codes to "inlined" operations, we should get a significant performance boost. What is eliminated is the having to look up a
GLOC
orILOC
and then dispatch on the subr type. The IMCAR operation would be dispatched to directly. Another way to view this is that we make available special form versions ofCAR
,CDR
, etc. Since the actual operation code is localized in the interpreter, it is much easier than uncompilation and then recompilation to handle(trace car)
; For instance a switch gets set which tells the interpreter to instead always look up the values of the associated symbols.
Previous: Improvements To Make, Up: Improvements To Make [Contents][Index]
George Carrette (gjc@mitech.com) outlines how to dynamically link on VMS. There is already some code in dynl.c to do this, but someone with a VMS system needs to finish and debug it.
main() {init_lisp(); lisp_repl();}
eval.c
and there are some toplevel non-static variables in use
called the_heap
, the_environment
, and some read-only
toplevel structures, such as the_subr_table
.
$ LINK/SHARE=LISPRTL.EXE/DEBUG REPL.OBJ,GC.OBJ,EVAL.OBJ,LISPRTL.OPT/OPT
SYS$LIBRARY:VAXCRTL/SHARE UNIVERSAL=init_lisp UNIVERSAL=lisp_repl PSECT_ATTR=the_subr_table,SHR,NOWRT,LCL PSECT_ATTR=the_heap,NOSHR,LCL PSECT_ATTR=the_environment,NOSHR,LCL
Notice The psect (Program Section) attributes.
LCL
means to keep the name local to the shared library. You almost always want to do that for a good clean library.
SHR,NOWRT
means shared-read-only. Which is the default for code, and is also good for efficiency of some data structures.
NOSHR,LCL
is what you want for everything else.
Note: If you do not have a handy list of all these toplevel variables, do not dispair. Just do your link with the /MAP=LISPRTL.MAP/FULL and then search the map file,
$SEARCH/OUT=LISPRTL.LOSERS LISPRTL.MAP ", SHR,NOEXE, RD, WRT"
And use an emacs keyboard macro to muck the result into the proper form. Of course only the programmer can tell if things can be made read-only. I have a DCL command procedure to do this if you want it.
$ DEFINE LISPRTL USER$DISK:[JAFFER]LISPRTL.EXE $LINK MAIN.OBJ,SYS$INPUT:/OPT SYS$LIBRARY:VAXCRTL/SHARE LISPRTL/SHARE
Note the definition of the LISPRTL
logical name. Without such a
definition you will need to copy LISPRTL.EXE over to
SYS$SHARE (aka SYS$LIBRARY) in order to invoke the main
program once it is linked.
INIT_MYSUBRS
that must be called before using it.
$ CC MYSUBRS.C $ LINK/SHARE=MYSUBRS.EXE MYSUBRS.OBJ,SYS$INPUT:/OPT SYS$LIBRARY:VAXCRTL/SHARE LISPRTL/SHARE UNIVERSAL=INIT_MYSUBRS
Ok. Another hint is that you can avoid having to add the PSECT
declaration of NOSHR,LCL
by declaring variables status
in
the C language source. That works great for most things.
{void (*init_fcn)(); long retval; retval = lib$find_image_symbol("MYSUBRS","INIT_MYSUBRS",&init_fcn, "SYS$DISK:[].EXE"); if (retval != SS$_NORMAL) error(…); (*init_fcn)();}
But of course all string arguments must be (struct dsc$descriptor
*)
and the last argument is optional if MYSUBRS
is defined as a
logical name or if MYSUBRS.EXE has been copied over to
SYS$SHARE. The other consideration is that you will want to turn
off C-c or other interrupt handling while you are inside most
lib$
calls.
As far as the generation of all the UNIVERSAL=…
declarations. Well, you could do well to have that automatically
generated from the public LISPRTL.H file, of course.
VMS has a good manual called the Guide to Writing Modular
Procedures or something like that, which covers this whole area rather
well, and also talks about advanced techniques, such as a way to declare
a program section with a pointer to a procedure that will be
automatically invoked whenever any shared image is dynamically
activated. Also, how to set up a handler for normal or abnormal program
exit so that you can clean up side effects (such as opening a database).
But for use with LISPRTL
you probably don’t need that hair.
One fancier option that is useful under VMS for LISPLIB.EXE is to
define all your exported procedures through an call vector instead
of having them just be pointers into random places in the image, which
is what you get by using UNIVERSAL
.
If you set up the call vector thing correctly it will allow you to modify and relink LISPLIB.EXE without having to relink programs that have been linked against it.
Previous: Program Self-Knowledge, Up: The Implementation [Contents][Index]