|
|
1.1 ! root 1: .\" Copyright (c) 1980 Regents of the University of California. ! 2: .\" All rights reserved. The Berkeley software License Agreement ! 3: .\" specifies the terms and conditions for redistribution. ! 4: .\" ! 5: .\" @(#)ch12.n 6.1 (Berkeley) 4/29/86 ! 6: .\" ! 7: ." $Header: ch12.n 1.2 83/07/23 12:41:32 layer Exp $ ! 8: .Lc Liszt\ -\ the\ lisp\ compiler 12 ! 9: .sh 2 "General strategy of the compiler" \n(ch 1 ! 10: .pp ! 11: The purpose of the lisp compiler, Liszt, is to create an object module which ! 12: when brought into the lisp system using ! 13: .i fasl ! 14: will have the same effect as bringing in the corresponding lisp coded source ! 15: module with ! 16: .i load ! 17: with one important exception, ! 18: functions will be defined as sequences of machine language instructions, instead ! 19: of lisp S-expressions. ! 20: Liszt is not a function compiler, it is a ! 21: .i file ! 22: compiler. ! 23: Such a file can contain more than function definitions; it can ! 24: contain other lisp S-expressions which are evaluated ! 25: at load time. ! 26: These other S-expressions will also be stored in the object ! 27: module produced by Liszt and will be evaluated at fasl time. ! 28: .pp ! 29: As is almost universally true of Lisp compilers, the main pass of Liszt ! 30: is written in Lisp. ! 31: A subsequent pass is the assembler, for which we use the ! 32: standard UNIX assembler. ! 33: .sh 2 "Running the compiler" ! 34: .pp ! 35: The compiler is normally run in this manner: ! 36: .br ! 37: % \fBliszt foo\fP ! 38: .br ! 39: will compile the file foo.l or foo (the preferred way to indicate a lisp ! 40: source file is to end the file name with `.l'). ! 41: The result of the compilation will be placed in the file foo.o if no ! 42: fatal errors were detected. ! 43: All messages which Liszt generates go to the standard output. ! 44: Normally each function name is printed before it is compiled (the \-q ! 45: option suppresses this). ! 46: .sh 2 "Special forms" ! 47: .pp ! 48: Liszt makes one pass over the source file. ! 49: It processes each form in this way: ! 50: .sh 3 macro\ expansion ! 51: .pp ! 52: If the form is a macro invocation (i.e it is a list whose car is a symbol ! 53: whose function binding is a macro), then that macro invocation is expanded. ! 54: This is repeated until the top level form is not a macro invocation. ! 55: When Liszt begins, there are already some macros defined, in fact some ! 56: functions (such as defun) are actually macros. ! 57: The user may define his own macros as well. ! 58: For a macro to be used it must be defined in the Lisp system ! 59: in which Liszt runs. ! 60: .sh +0 classification ! 61: .pp ! 62: After all macro expansion is done, the form is classified according to its ! 63: .i car ! 64: (if the form is not a list, then it is classified as an ! 65: .i other ). ! 66: .sh +1 "eval-when" ! 67: .pp ! 68: The form of eval-when is ! 69: \fI(eval-when\ (time1\ time2\ ...)\ form1\ form2\ ...)\fP ! 70: where the time\fIi\fP are one of ! 71: .i eval , ! 72: .i compile , ! 73: or ! 74: .i load . ! 75: The compiler examines the form\fIi\fP in sequence and the action taken ! 76: depends on what is in the time list. ! 77: If ! 78: .i compile ! 79: is in the list then the compiler will invoke ! 80: .i eval ! 81: on each form\fIi\fP as it examines it. ! 82: If ! 83: .i load ! 84: is in the list then the compile will recursively call itself to compile ! 85: each form\fIi\fP as it examines it. ! 86: Note that if ! 87: .i compile ! 88: and ! 89: .i load ! 90: are in the time list, then the compiler will both evaluate and compile ! 91: each form. ! 92: This is useful if you need a function to be defined in the compiler ! 93: at both compile time (perhaps to aid macro expansion) and at run time ! 94: (after the file is ! 95: .i fasl ed ! 96: in). ! 97: .sh +0 "declare" ! 98: .pp ! 99: Declare is used to provide information about functions and variables to ! 100: the compiler. ! 101: It is (almost) equivalent to \fI(eval-when\ (compile)\ ...)\fP. ! 102: You may declare functions to be one of three types: lambda (*expr), ! 103: nlambda (*fexpr), lexpr (*lexpr). ! 104: The names in parenthesis are the Maclisp names and are accepted by the ! 105: compiler as well (and not just when the compiler is in Maclisp mode). ! 106: Functions are assumed to be lambdas until they are declared otherwise ! 107: or are defined differently. ! 108: The compiler treats calls to lambdas and lexprs equivalently, so you needn't ! 109: worry about declaring lexprs either. ! 110: It is important to declare nlambdas or define them before calling them. ! 111: Another attribute you can declare for a function is localf which ! 112: makes the function `local'. ! 113: A local function's name is ! 114: known only to the functions defined ! 115: within the file itself. The ! 116: advantage of a local function is that is can be entered ! 117: and exited very quickly and it can have the same name as a function in ! 118: another file and there will be no name conflict. ! 119: .pp ! 120: Variables may be declared special or unspecial. ! 121: When a special variable is lambda bound (either in a lambda, ! 122: prog or do expression), its old value is stored away on a stack for the ! 123: duration of the lambda, prog or do expression. ! 124: This takes time and is often not necessary. ! 125: Therefore the default classification for variables is unspecial. ! 126: Space for unspecial variables is dynamically allocated on a stack. ! 127: An unspecial variable can only be accessed from within the function ! 128: where it is created by its presence in a lambda, prog or do ! 129: expression variable list. ! 130: It is possible to declare that all variables are special as will be ! 131: shown below. ! 132: .pp ! 133: You may declare any number of things in each declare statement. ! 134: A sample declaration is ! 135: .ft I ! 136: .nf ! 137: (declare ! 138: \ \ \ \ \ (lambda func1 func2) ! 139: \ \ \ \ \ (*fexpr func3) ! 140: \ \ \ \ \ (*lexpr func4) ! 141: \ \ \ \ \ (localf func5) ! 142: \ \ \ \ \ (special var1 var2 var3) ! 143: \ \ \ \ \ (unspecial var4)) ! 144: .fi ! 145: .ft R ! 146: .pp ! 147: You may also declare all variables to be special with ! 148: \fI(declare\ (specials\ t))\fP. ! 149: You may declare that macro definitions should be compiled as well as ! 150: evaluated at compile time by \fI(declare\ (macros\ t))\fP. ! 151: In fact, as was mentioned above, declare is much like ! 152: \fI(eval-when\ (compile)\ ...)\fP. ! 153: Thus if the compiler sees \fI(declare\ (foo\ bar))\fP ! 154: and foo is defined, then it will evaluate \fI(foo\ bar)\fP. ! 155: If foo is not defined then an undefined declare attribute warning will ! 156: be issued. ! 157: .sh +0 "(progn 'compile \fRform1 form2 ... formn\fB)\fP" ! 158: .pp ! 159: When the compiler sees this it simply compiles form1 through formn as if ! 160: they too were seen at top level. ! 161: One use for this is to allow a macro at top-level to ! 162: expand into more than one function definition for the compiler to compile. ! 163: .sh +0 "include/includef" ! 164: .pp ! 165: .i Include ! 166: and ! 167: .i includef ! 168: cause another file to be read and compiled by ! 169: the compiler. The result is the same as if the included file were ! 170: textually inserted into the original file. The only difference ! 171: between ! 172: .i include ! 173: and ! 174: .i includef ! 175: is that include doesn't evaluate its ! 176: argument and includef does. Nested includes are allowed. ! 177: .sh +0 "def" ! 178: .pp ! 179: A def form is used to define a function. The macros ! 180: .i defun ! 181: and ! 182: .i defmacro ! 183: expand to a def form. ! 184: If the function being defined is a lambda, nlambda or lexpr then ! 185: the compiler converts the lisp definition to a sequence of machine ! 186: language instructions. ! 187: If the function being defined is a macro, then the compiler will evaluate ! 188: the definition, thus defining the macro withing the running Lisp compiler. ! 189: Furthermore, if the variable ! 190: .i macros ! 191: is set to a non nil value, then the macro definition will also be translated ! 192: to machine language and thus will be defined when the object file is ! 193: fasled in. ! 194: The variable ! 195: .i macros ! 196: is set to t by ! 197: \fI(declare\ (macros\ t))\fP. ! 198: .pp ! 199: When a function or macro definition is compiled, macro expansion is ! 200: done whenever possible. ! 201: If the compiler can determine that a form would be evaluated if this ! 202: function were interpreted then it will macro expand it. ! 203: It will not macro expand arguments to a nlambda unless the characteristics ! 204: of the nlambda is known (as is the case with ! 205: .i cond). ! 206: The map functions ( ! 207: .i map , ! 208: .i mapc , ! 209: .i mapcar , ! 210: and so on) ! 211: are expanded to a ! 212: .i do ! 213: statement. ! 214: This allows the first argument to the map function to be a lambda ! 215: expression which references local variables of the function being ! 216: defined. ! 217: .sh +0 "other forms" ! 218: .pp ! 219: All other forms are simply stored in the object file and are evaluated ! 220: when the file is ! 221: .i fasl ed ! 222: in. ! 223: .sh 2 "Using the compiler" ! 224: .pp ! 225: The previous section describes exactly what the compiler does with its ! 226: input. ! 227: Generally you won't have to worry about all that detail as files which ! 228: work interpreted will work compiled. ! 229: Following is a list of steps you should follow to insure that a file ! 230: will compile correctly. ! 231: .ip [1] ! 232: Make sure all macro definitions precede their use in functions or other ! 233: macro definitions. ! 234: If you want the macros to be around when you ! 235: .i fasl ! 236: in the object file you should include this statement at the beginning ! 237: of the file: \fI(declare\ (macros\ t))\fP ! 238: .ip [2] ! 239: Make sure all nlambdas are defined or declared before they are used. ! 240: If the compiler comes across a call to a ! 241: function which has not been defined in the current file, ! 242: which does not currently have a function binding, ! 243: and whose type has not been declared then it will assume that the function ! 244: needs its arguments evaluated ! 245: (i.e. it is a lambda or lexpr) and will generate code ! 246: accordingly. ! 247: This means that you do not have to declare nlambda functions like ! 248: .i status ! 249: since they have an nlambda function binding. ! 250: .ip [3] ! 251: Locate all variables which are used for communicating values between ! 252: functions. ! 253: These variables must be declared special at the beginning of a file. ! 254: In most cases there won't be many special declarations but if you ! 255: fail to declare a variable special that should be, the compiled code ! 256: could fail in mysterious ways. ! 257: Let's look at a common problem, assume that a file contains just ! 258: these three lines: ! 259: .sp 2v ! 260: .ft I ! 261: (def aaa (lambda (glob loc) (bbb loc))) ! 262: .br ! 263: (def bbb (lambda (myloc) (add glob myloc))) ! 264: .br ! 265: (def ccc (lambda (glob loc) (bbb loc))) ! 266: .sp 2v ! 267: .ft R ! 268: We can see that if we load in these two definitions then (aaa 3 4) is ! 269: the same as (add 3 4) and will give us 7. ! 270: Suppose we compile the file containing these definitions. ! 271: When Liszt compiles aaa, it will assume that both glob and loc are local ! 272: variables and will allocate space on the temporary stack for their values ! 273: when aaa is called. ! 274: Thus the values of the local variables glob and loc ! 275: will not affect the values of the symbols glob and loc in the Lisp system. ! 276: Now Liszt moves on to function bbb. ! 277: Myloc is assumed to be local. ! 278: When it sees the add statement, it find a reference to a variable called ! 279: glob. ! 280: This variable is not a local variable to this function and therefore ! 281: glob must refer to the value of the symbol glob. ! 282: Liszt will automatically declare glob to be special and it will print ! 283: a warning to that effect. ! 284: Thus subsequent uses of glob will always refer to the symbol glob. ! 285: Next Liszt compiles ccc and treats glob as a special and loc ! 286: as a local. ! 287: When the object file is ! 288: .i fasl 'ed ! 289: in, and (ccc 3 4) is evaluated, ! 290: the symbol glob will be lambda bound to 3 ! 291: bbb will be called and will return 7. ! 292: However (aaa 3 4) will fail since when bbb is called, glob will be unbound. ! 293: What should be done here is to put ! 294: \fI(declare\ (special\ glob)\fP ! 295: at the beginning of the file. ! 296: .ip [4] ! 297: Make sure that all calls to ! 298: .i arg ! 299: are within the lexpr whose arguments they reference. ! 300: If \fIfoo\fP is a compiled lexpr and it calls \fIbar\fP then \fIbar\fP cannot ! 301: use \fIarg\fP to get at \fIfoo\fP's arguments. ! 302: If both ! 303: .i foo ! 304: and ! 305: .i bar ! 306: are interpreted this will work however. ! 307: The macro ! 308: .i listify ! 309: can be used to put all of some of a lexprs arguments in a list which ! 310: then can be passed to other functions. ! 311: .sh 2 "Compiler options" ! 312: .pp ! 313: The compiler recognizes a number of options which are described below. ! 314: The options are typed anywhere on the command line preceded by a minus sign. ! 315: The entire command line is scanned and all options recorded before any action ! 316: is taken. Thus ! 317: .br ! 318: % liszt -mx foo ! 319: .br ! 320: % liszt -m -x foo ! 321: .br ! 322: % liszt foo -mx ! 323: .br ! 324: are all equivalent. ! 325: Before scanning the command line for options, liszt looks for in the ! 326: environment for the variable LISZT, and if found scans its value ! 327: as if it was a string of options. ! 328: The meaning of the options are: ! 329: .ip \fBC\fP ! 330: The assembler language output of the compiler is commented. ! 331: This is useful when debugging the compiler and is not normally done since ! 332: it slows down compilation. ! 333: .ip \fBI\fP ! 334: The next command line argument is taken as a filename, and loaded prior ! 335: to compilation. ! 336: .ip \fBe\fP ! 337: Evaluate the next argument on the command line before starting compilation. ! 338: For example ! 339: .br ! 340: % liszt -e '(setq foobar "foo string")' foo ! 341: .br ! 342: will evaluate the above s-expression. Note that the shell requires ! 343: that the arguments be surrounded by single quotes. ! 344: .ip \fBi\fP ! 345: Compile this program in interlisp compatibility mode. ! 346: This is not implemented yet. ! 347: .ip \fBm\fP ! 348: Compile this program in Maclisp mode. ! 349: The reader syntax will be changed to the Maclisp syntax and a file of ! 350: macro definitions will be loaded in (usually named /usr/lib/lisp/machacks). ! 351: This switch brings us sufficiently close to Maclisp to allow us to compile ! 352: Macsyma, a large Maclisp program. ! 353: However Maclisp is a moving target and we can't guarantee that this switch ! 354: will allow you to compile any given program. ! 355: .ip \fBo\fP ! 356: Select a different object or assembler language file name. ! 357: For example ! 358: .br ! 359: % liszt foo -o xxx.o ! 360: .br ! 361: will compile foo and into xxx.o instead of the default foo.o, and ! 362: .br ! 363: % liszt bar -S -o xxx.s ! 364: .br ! 365: will compile to assembler language into xxx.s instead of bar.s. ! 366: .ip \fBp\fP ! 367: place profiling code at the beginning of each non-local function. ! 368: If the lisp system is also created with profiling in it, this allows ! 369: function calling frequency to be determined (see \fIprof(1)\fP) ! 370: .ip \fBq\fP ! 371: Run in quiet mode. ! 372: The names of functions being compiled and various ! 373: "Note"'s are not printed. ! 374: .ip \fBQ\fP ! 375: print compilation statistics and warn of strange constructs. ! 376: This is the inverse of the \fBq\fP switch and is the default. ! 377: .ip \fBr\fP ! 378: place bootstrap code at the beginning of the object file, which when ! 379: the object file is executed will cause a lisp system to be invoked ! 380: and the object file \fIfasl\fPed in. ! 381: This is known as `autorun' and is described below. ! 382: .ip \fBS\fP ! 383: Create an assembler language file only. ! 384: .br ! 385: % liszt -S foo ! 386: .br ! 387: will create the file assembler language file foo.s and will not attempt ! 388: to assemble it. ! 389: If this option is not specified, the assembler language file will be put ! 390: in the temporary disk area under a automatically generated name based on ! 391: the lisp compiler's process id. ! 392: Then if there are no compilation errors, the assembler will be invoked to ! 393: assemble the file. ! 394: .ip \fBT\fP ! 395: Print the assembler language output on the standard output file. ! 396: This is useful when debugging the compiler. ! 397: .ip \fBu\fP ! 398: Run in UCI-Lisp mode. ! 399: The character syntax is changed to that of UCI-Lisp and a UCI-Lisp compatibility ! 400: package of macros is read in. ! 401: .ip \fBw\fP ! 402: Suppress warning messages. ! 403: .ip \fBx\fP ! 404: Create an cross reference file. ! 405: .br ! 406: % liszt -x foo ! 407: .br ! 408: not only compiles foo into foo.o but also generates the file foo.x\ . ! 409: The file foo.x is lisp readable and lists for each function all functions ! 410: which that function could call. ! 411: The program lxref reads one or more of these ".x" files and produces a ! 412: human readable cross reference listing. ! 413: .sh 2 autorun ! 414: .pp ! 415: The object file ! 416: which liszt writes does not contain all the functions necessary ! 417: to run the lisp program which was compiled. ! 418: In order to use the object file, a lisp system must be started and ! 419: the object file ! 420: .i fasl ed ! 421: in. ! 422: When the -r switch is given to liszt, the object file created will ! 423: contain a small piece of bootstrap code at the beginning, and the ! 424: object file will be made executable. ! 425: Now, when the name of the object file is given to the UNIX command ! 426: interpreter (shell) to run, the bootstrap code at the beginning ! 427: of the object file will cause a lisp system to be started and ! 428: the first action the lisp system will take is to ! 429: .i fasl ! 430: in the object file which started it. ! 431: In effect the object file has created an environment in which it can run. ! 432: .pp ! 433: Autorun is an alternative to ! 434: .i dumplisp . ! 435: The advantage of autorun is that the object file which starts the whole ! 436: process is typically small, whereas the minimum ! 437: .i dumplisp ed ! 438: file is very large (one half megabyte). ! 439: The disadvantage of autorun is that the file must be ! 440: .i fasl ed ! 441: into a lisp each time it is used whereas the file which ! 442: .i dumplisp ! 443: creates can be run as is. ! 444: liszt itself is a ! 445: .i dumplisp ed ! 446: file since it is used so often and is large enough that ! 447: too much time would be wasted ! 448: .i fasl ing ! 449: it in each time it was used. ! 450: The lisp cross reference program, lxref, uses ! 451: .i autorun ! 452: since it is a small and rarely used program. ! 453: .pp ! 454: In order to have the program ! 455: .i fasl ed ! 456: in begin execution ! 457: (rather than starting a lisp top level), ! 458: the value of the symbol user-top-level should be set to the name of the ! 459: function to get control. An example of this is shown next. ! 460: .Eb ! 461: \fIwe want to replace the unix date program with one written in lisp.\fP ! 462: ! 463: % \fBcat lispdate.l\fP ! 464: (de\kBfun mydate nil ! 465: \h'|\nBu'\kA(patom "The date is ") ! 466: \h'|\nAu'\kB(patom (status ctime)) ! 467: \h'|\nBu'\kA(terpr) ! 468: \h'|\nAu'(exit 0)) ! 469: (se\kAtq user-top-level 'mydate) ! 470: ! 471: % \fBliszt -r lispdate\fP ! 472: Compilation begins with Lisp Compiler 5.2 ! 473: source: lispdate.l, result: lispdate.o ! 474: mydate ! 475: %Note: lispdate.l: Compilation complete ! 476: %Note: lispdate.l: Time: Real: 0:3, CPU: 0:0.28, GC: 0:0.00 for 0 gcs ! 477: %Note: lispdate.l: Assembly begins ! 478: %Note: lispdate.l: Assembly completed successfully ! 479: 3.0u 2.0s 0:17 29% ! 480: ! 481: \fI We change the name to remove the ".o", (this isn't necessary) \fP ! 482: % \fBmv lispdate.o lispdate\fP ! 483: ! 484: \fI Now we test it out \fP ! 485: % \fBlispdate\fP ! 486: The date is Sat Aug 1 16:58:33 1981 ! 487: % ! 488: .Ee ! 489: .sh 2 "pure literals" ! 490: .pp ! 491: Normally the quoted lisp objects (literals) which appear in functions are ! 492: treated as constants. ! 493: Consider this function: ! 494: .br ! 495: .ft I ! 496: ! 497: (de\kCf foo ! 498: \h'|\nCu'(lambda nil (cond \kA(\kB(not (eq 'a (car (setq x '(a b))))) ! 499: \h'|\nBu'(print 'impossible!!)) ! 500: \h'|\nAu'(t (rplaca x 'd))))) ! 501: ! 502: .ft P ! 503: .br ! 504: At first glance it seems that the first cond clause will never be ! 505: true, since the \fIcar\fP of \fI(a\ b)\fP should always be ! 506: .i a . ! 507: However if you run this function twice, it will print 'impossible!!' the ! 508: second time. ! 509: This is because the following clause modifies the 'constant' list \fI(a\ b)\fP ! 510: with the \fIrplaca\fP function. ! 511: Such modification of literal lisp objects can cause programs to behave ! 512: strangely as the above example shows, but more importantly it can cause ! 513: garbage collection problems if done to compiled code. ! 514: When a file is \fIfasl\fPed in, if the ! 515: symbol $purcopylits is non nil, the literal lisp data is put ! 516: in 'pure' space, that is it put in space which needn't be looked at ! 517: by the garabage collector. This reduces the work the garbage collector ! 518: must do but it is dangerous since if the literals are modified to point ! 519: to non pure objects, the marker may not mark the non pure objects. ! 520: If the symbol $purcopylits is nil then the literal lisp data is put in ! 521: impure space and the compiled code will act like the interpreted ! 522: code when literal data is modified. ! 523: The default value for $purcopylits is t. ! 524: .sh 2 "transfer tables" ! 525: .pp ! 526: A transfer table is setup by ! 527: .i fasl ! 528: when the object file is loaded in. ! 529: There is one entry in the transfer table for each function which is ! 530: called in that object file. ! 531: The entry for a call to the function ! 532: .i foo ! 533: has two parts whose contents are: ! 534: .ip [1] ! 535: function address \- ! 536: This will initially point to the internal function ! 537: .i qlinker . ! 538: It may some time in the future point to the function ! 539: .i foo ! 540: if certain conditions are satisfied (more on this below). ! 541: .ip [2] ! 542: function name \- ! 543: This is a pointer to the symbol ! 544: .i foo . ! 545: This will be used by ! 546: .i qlinker. ! 547: .sp 2v ! 548: .lp ! 549: When a call is made to the function ! 550: .i foo ! 551: the call will actually be made to the address in the ! 552: transfer table entry and will end up in the ! 553: .i qlinker ! 554: function. ! 555: .i Qlinker ! 556: will determine that ! 557: .i foo ! 558: was the function being called by locating the function name ! 559: entry in the transfer table\*[\(dg\*]. ! 560: .(f ! 561: \*[\(dg\*]\fIQlinker\fP does this by tracing back the call stack until it ! 562: finds the \fIcalls\fP machine instruction which called it. The address ! 563: field of the \fIcalls\fP contains the address of the transfer table entry. ! 564: .)f ! 565: If the function being called is not compiled then ! 566: .i qlinker ! 567: just calls ! 568: .i funcall ! 569: to perform the function call. ! 570: If ! 571: .i foo ! 572: is compiled and if \fI(status\ translink)\fP is non nil, then ! 573: .i qlinker ! 574: will modify the function address part of the transfer table to point directly ! 575: to the function ! 576: .i foo . ! 577: Finally ! 578: .i qlinker ! 579: will call ! 580: .i foo ! 581: directly . ! 582: The next time a call is made to ! 583: .i foo ! 584: the call will go directly to ! 585: .i foo ! 586: and not through ! 587: .i qlinker . ! 588: This will result in a substantial speedup in compiled code to compiled code ! 589: transfers. ! 590: A disadvantage is that no debugging information is left on the stack, ! 591: so ! 592: .i showstack ! 593: and ! 594: .i baktrace ! 595: are useless. ! 596: Another disadvantage is that if you redefine a compiled function either ! 597: through loading in a new version or interactively defining it, then ! 598: the old version may still be called from compiled code if the fast linking ! 599: described above has already been done. ! 600: The solution to these problems is to use \fI(sstatus\ translink\ value)\fP. ! 601: If value is ! 602: .ip \fInil\fP ! 603: All transfer tables will be cleared, i.e. all function ! 604: addresses will be set to point to ! 605: .i qlinker . ! 606: This means that the next time a function is called ! 607: .i qlinker ! 608: will be called and will look at the current definition. ! 609: Also, no fast links will be set up since \fI(status\ translink)\fP ! 610: will be nil. ! 611: The end result is that ! 612: .i showstack ! 613: and ! 614: .i baktrace ! 615: will work and the function definition at the time of call will always be used. ! 616: .ip \fIon\fP ! 617: This causes the lisp system to go through all transfer tables and set up ! 618: fast links wherever possible. ! 619: This is normally used after you have ! 620: .i fasl ed ! 621: in all of your files. ! 622: Furthermore since \fI(status\ translink)\fP is not nil, ! 623: .i qlinker ! 624: will make new fast links if the situation arises (which isn't likely unless ! 625: you ! 626: .i fasl ! 627: in another file). ! 628: .ip \fIt\fP ! 629: This or any other value not previously mentioned will just make ! 630: \fI(status\ translink)\fP be non nil, and as a result fast links will ! 631: be made by ! 632: .i qlinker ! 633: if the called function is compiled. ! 634: .sh +0 "Fixnum functions" ! 635: .pp ! 636: The compiler will generate inline arithmetic code for fixnum only functions. ! 637: Such functions include \(pl, \(mi, *, /, \\, 1\(pl and 1\-. ! 638: The code generated will be much faster than using \fIadd\fP, \fIdifference\fP, ! 639: etc. ! 640: However it will only work if the arguments to and results of the functions ! 641: are fixnums. ! 642: No type checking is done.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.