|
|
1.1 ! root 1: ! 2: ! 3: ! 4: ! 5: ! 6: ! 7: ! 8: CHAPTER 12 ! 9: ! 10: ! 11: Liszt - the lisp compiler ! 12: ! 13: ! 14: ! 15: ! 16: ! 17: ! 18: 12.1. General strategy of the compiler ! 19: ! 20: The purpose of the lisp compiler, Liszt, is to ! 21: create an object module which when brought into the ! 22: lisp system using _f_a_s_l will have the same effect as ! 23: bringing in the corresponding lisp coded source module ! 24: with _l_o_a_d with one important exception, functions will ! 25: be defined as sequences of machine language instruc- ! 26: tions, instead of lisp S-expressions. Liszt is not a ! 27: function compiler, it is a _f_i_l_e compiler. Such a file ! 28: can contain more than function definitions; it can ! 29: contain other lisp S-expressions which are evaluated ! 30: at load time. These other S-expressions will also be ! 31: stored in the object module produced by Liszt and will ! 32: be evaluated at fasl time. ! 33: ! 34: As is almost universally true of Lisp compilers, ! 35: the main pass of Liszt is written in Lisp. A subse- ! 36: quent pass is the assembler, for which we use the ! 37: standard UNIX assembler. ! 38: ! 39: ! 40: ! 41: 12.2. Running the compiler ! 42: ! 43: The compiler is normally run in this manner: ! 44: % liszt foo ! 45: will compile the file foo.l or foo (the preferred way ! 46: to indicate a lisp source file is to end the file name ! 47: with `.l'). The result of the compilation will be ! 48: placed in the file foo.o if no fatal errors were ! 49: detected. All messages which Liszt generates go to ! 50: the standard output. Normally each function name is ! 51: printed before it is compiled (the -q option ! 52: suppresses this). ! 53: ! 54: ! 55: ! 56: 12.3. Special forms ! 57: ! 58: Liszt makes one pass over the source file. It ! 59: processes each form in this way: ! 60: 9 ! 61: ! 62: 9Liszt - the lisp compiler 12-1 ! 63: ! 64: ! 65: ! 66: ! 67: ! 68: ! 69: ! 70: Liszt - the lisp compiler 12-2 ! 71: ! 72: ! 73: 12.3.1. macro expansion ! 74: ! 75: If the form is a macro invocation (i.e it is a ! 76: list whose car is a symbol whose function binding ! 77: is a macro), then that macro invocation is ! 78: expanded. This is repeated until the top level ! 79: form is not a macro invocation. When Liszt begins, ! 80: there are already some macros defined, in fact some ! 81: functions (such as defun) are actually macros. The ! 82: user may define his own macros as well. For a ! 83: macro to be used it must be defined in the Lisp ! 84: system in which Liszt runs. ! 85: ! 86: ! 87: ! 88: 12.3.2. classification ! 89: ! 90: After all macro expansion is done, the form is ! 91: classified according to its _c_a_r (if the form is not ! 92: a list, then it is classified as an _o_t_h_e_r). ! 93: ! 94: ! 95: ! 96: 12.3.2.1. eval-when ! 97: ! 98: The form of eval-when is (_e_v_a_l- ! 99: _w_h_e_n (_t_i_m_e_1 _t_i_m_e_2 ...) _f_o_r_m_1 _f_o_r_m_2 ...) where ! 100: the time_i are one of _e_v_a_l, _c_o_m_p_i_l_e, or _l_o_a_d. ! 101: The compiler examines the form_i in sequence and ! 102: the action taken depends on what is in the time ! 103: list. If _c_o_m_p_i_l_e is in the list then the com- ! 104: piler will invoke _e_v_a_l on each form_i as it exam- ! 105: ines it. If _l_o_a_d is in the list then the com- ! 106: pile will recursively call itself to compile ! 107: each form_i as it examines it. Note that if _c_o_m_- ! 108: _p_i_l_e and _l_o_a_d are in the time list, then the ! 109: compiler will both evaluate and compile each ! 110: form. This is useful if you need a function to ! 111: be defined in the compiler at both compile time ! 112: (perhaps to aid macro expansion) and at run time ! 113: (after the file is _f_a_s_led in). ! 114: ! 115: ! 116: ! 117: 12.3.2.2. declare ! 118: ! 119: Declare is used to provide information ! 120: about functions and variables to the compiler. ! 121: It is (almost) equivalent to (_e_v_a_l- ! 122: _w_h_e_n (_c_o_m_p_i_l_e) ...). You may declare functions ! 123: to be one of three types: lambda (*expr), ! 124: nlambda (*fexpr), lexpr (*lexpr). The names in ! 125: parenthesis are the Maclisp names and are ! 126: ! 127: ! 128: Printed: August 5, 1983 ! 129: ! 130: ! 131: ! 132: ! 133: ! 134: ! 135: ! 136: Liszt - the lisp compiler 12-3 ! 137: ! 138: ! 139: accepted by the compiler as well (and not just ! 140: when the compiler is in Maclisp mode). Func- ! 141: tions are assumed to be lambdas until they are ! 142: declared otherwise or are defined differently. ! 143: The compiler treats calls to lambdas and lexprs ! 144: equivalently, so you needn't worry about declar- ! 145: ing lexprs either. It is important to declare ! 146: nlambdas or define them before calling them. ! 147: Another attribute you can declare for a function ! 148: is localf which makes the function `local'. A ! 149: local function's name is known only to the func- ! 150: tions defined within the file itself. The ! 151: advantage of a local function is that is can be ! 152: entered and exited very quickly and it can have ! 153: the same name as a function in another file and ! 154: there will be no name conflict. ! 155: ! 156: Variables may be declared special or unspe- ! 157: cial. When a special variable is lambda bound ! 158: (either in a lambda, prog or do expression), its ! 159: old value is stored away on a stack for the ! 160: duration of the lambda, prog or do expression. ! 161: This takes time and is often not necessary. ! 162: Therefore the default classification for vari- ! 163: ables is unspecial. Space for unspecial vari- ! 164: ables is dynamically allocated on a stack. An ! 165: unspecial variable can only be accessed from ! 166: within the function where it is created by its ! 167: presence in a lambda, prog or do expression ! 168: variable list. It is possible to declare that ! 169: all variables are special as will be shown ! 170: below. ! 171: ! 172: You may declare any number of things in ! 173: each declare statement. A sample declaration is ! 174: (_d_e_c_l_a_r_e ! 175: (_l_a_m_b_d_a _f_u_n_c_1 _f_u_n_c_2) ! 176: (*_f_e_x_p_r _f_u_n_c_3) ! 177: (*_l_e_x_p_r _f_u_n_c_4) ! 178: (_l_o_c_a_l_f _f_u_n_c_5) ! 179: (_s_p_e_c_i_a_l _v_a_r_1 _v_a_r_2 _v_a_r_3) ! 180: (_u_n_s_p_e_c_i_a_l _v_a_r_4)) ! 181: ! 182: You may also declare all variables to be ! 183: special with (_d_e_c_l_a_r_e (_s_p_e_c_i_a_l_s _t)). You may ! 184: declare that macro definitions should be com- ! 185: piled as well as evaluated at compile time by ! 186: (_d_e_c_l_a_r_e (_m_a_c_r_o_s _t)). In fact, as was mentioned ! 187: above, declare is much like (_e_v_a_l- ! 188: _w_h_e_n (_c_o_m_p_i_l_e) ...). Thus if the compiler sees ! 189: (_d_e_c_l_a_r_e (_f_o_o _b_a_r)) and foo is defined, then it ! 190: will evaluate (_f_o_o _b_a_r). If foo is not defined ! 191: then an undefined declare attribute warning will ! 192: ! 193: ! 194: Printed: August 5, 1983 ! 195: ! 196: ! 197: ! 198: ! 199: ! 200: ! 201: ! 202: Liszt - the lisp compiler 12-4 ! 203: ! 204: ! 205: be issued. ! 206: ! 207: ! 208: ! 209: 12.3.2.3. (progn 'compile form1 form2 ... formn) ! 210: ! 211: When the compiler sees this it simply com- ! 212: piles form1 through formn as if they too were ! 213: seen at top level. One use for this is to allow ! 214: a macro at top-level to expand into more than ! 215: one function definition for the compiler to com- ! 216: pile. ! 217: ! 218: ! 219: ! 220: 12.3.2.4. include/includef ! 221: ! 222: _I_n_c_l_u_d_e and _i_n_c_l_u_d_e_f cause another file to ! 223: be read and compiled by the compiler. The ! 224: result is the same as if the included file were ! 225: textually inserted into the original file. The ! 226: only difference between _i_n_c_l_u_d_e and _i_n_c_l_u_d_e_f is ! 227: that include doesn't evaluate its argument and ! 228: includef does. Nested includes are allowed. ! 229: ! 230: ! 231: ! 232: 12.3.2.5. def ! 233: ! 234: A def form is used to define a function. ! 235: The macros _d_e_f_u_n and _d_e_f_m_a_c_r_o expand to a def ! 236: form. If the function being defined is a ! 237: lambda, nlambda or lexpr then the compiler con- ! 238: verts the lisp definition to a sequence of ! 239: machine language instructions. If the function ! 240: being defined is a macro, then the compiler will ! 241: evaluate the definition, thus defining the macro ! 242: withing the running Lisp compiler. Furthermore, ! 243: if the variable _m_a_c_r_o_s is set to a non nil ! 244: value, then the macro definition will also be ! 245: translated to machine language and thus will be ! 246: defined when the object file is fasled in. The ! 247: variable _m_a_c_r_o_s is set to t by ! 248: (_d_e_c_l_a_r_e (_m_a_c_r_o_s _t)). ! 249: ! 250: When a function or macro definition is com- ! 251: piled, macro expansion is done whenever possi- ! 252: ble. If the compiler can determine that a form ! 253: would be evaluated if this function were inter- ! 254: preted then it will macro expand it. It will ! 255: not macro expand arguments to a nlambda unless ! 256: the characteristics of the nlambda is known (as ! 257: is the case with _c_o_n_d). The map functions ( ! 258: ! 259: ! 260: Printed: August 5, 1983 ! 261: ! 262: ! 263: ! 264: ! 265: ! 266: ! 267: ! 268: Liszt - the lisp compiler 12-5 ! 269: ! 270: ! 271: _m_a_p, _m_a_p_c, _m_a_p_c_a_r, and so on) are expanded to a ! 272: _d_o statement. This allows the first argument to ! 273: the map function to be a lambda expression which ! 274: references local variables of the function being ! 275: defined. ! 276: ! 277: ! 278: ! 279: 12.3.2.6. other forms ! 280: ! 281: All other forms are simply stored in the ! 282: object file and are evaluated when the file is ! 283: _f_a_s_led in. ! 284: ! 285: ! 286: ! 287: 12.4. Using the compiler ! 288: ! 289: The previous section describes exactly what the ! 290: compiler does with its input. Generally you won't ! 291: have to worry about all that detail as files which ! 292: work interpreted will work compiled. Following is a ! 293: list of steps you should follow to insure that a file ! 294: will compile correctly. ! 295: ! 296: [1] Make sure all macro definitions precede their use ! 297: in functions or other macro definitions. If you ! 298: want the macros to be around when you _f_a_s_l in the ! 299: object file you should include this statement at ! 300: the beginning of the file: (_d_e_c_l_a_r_e (_m_a_c_r_o_s _t)) ! 301: ! 302: [2] Make sure all nlambdas are defined or declared ! 303: before they are used. If the compiler comes ! 304: across a call to a function which has not been ! 305: defined in the current file, which does not ! 306: currently have a function binding, and whose type ! 307: has not been declared then it will assume that ! 308: the function needs its arguments evaluated (i.e. ! 309: it is a lambda or lexpr) and will generate code ! 310: accordingly. This means that you do not have to ! 311: declare nlambda functions like _s_t_a_t_u_s since they ! 312: have an nlambda function binding. ! 313: ! 314: [3] Locate all variables which are used for communi- ! 315: cating values between functions. These variables ! 316: must be declared special at the beginning of a ! 317: file. In most cases there won't be many special ! 318: declarations but if you fail to declare a vari- ! 319: able special that should be, the compiled code ! 320: could fail in mysterious ways. Let's look at a ! 321: common problem, assume that a file contains just ! 322: these three lines: ! 323: 9 ! 324: ! 325: 9 Printed: August 5, 1983 ! 326: ! 327: ! 328: ! 329: ! 330: ! 331: ! 332: ! 333: Liszt - the lisp compiler 12-6 ! 334: ! 335: ! 336: (_d_e_f _a_a_a (_l_a_m_b_d_a (_g_l_o_b _l_o_c) (_b_b_b _l_o_c))) ! 337: (_d_e_f _b_b_b (_l_a_m_b_d_a (_m_y_l_o_c) (_a_d_d _g_l_o_b _m_y_l_o_c))) ! 338: (_d_e_f _c_c_c (_l_a_m_b_d_a (_g_l_o_b _l_o_c) (_b_b_b _l_o_c))) ! 339: ! 340: ! 341: We can see that if we load in these two defini- ! 342: tions then (aaa 3 4) is the same as (add 3 4) and ! 343: will give us 7. Suppose we compile the file con- ! 344: taining these definitions. When Liszt compiles ! 345: aaa, it will assume that both glob and loc are ! 346: local variables and will allocate space on the ! 347: temporary stack for their values when aaa is ! 348: called. Thus the values of the local variables ! 349: glob and loc will not affect the values of the ! 350: symbols glob and loc in the Lisp system. Now ! 351: Liszt moves on to function bbb. Myloc is assumed ! 352: to be local. When it sees the add statement, it ! 353: find a reference to a variable called glob. This ! 354: variable is not a local variable to this function ! 355: and therefore glob must refer to the value of the ! 356: symbol glob. Liszt will automatically declare ! 357: glob to be special and it will print a warning to ! 358: that effect. Thus subsequent uses of glob will ! 359: always refer to the symbol glob. Next Liszt com- ! 360: piles ccc and treats glob as a special and loc as ! 361: a local. When the object file is _f_a_s_l'ed in, and ! 362: (ccc 3 4) is evaluated, the symbol glob will be ! 363: lambda bound to 3 bbb will be called and will ! 364: return 7. However (aaa 3 4) will fail since when ! 365: bbb is called, glob will be unbound. What should ! 366: be done here is to put (_d_e_c_l_a_r_e (_s_p_e_c_i_a_l _g_l_o_b) at ! 367: the beginning of the file. ! 368: ! 369: [4] Make sure that all calls to _a_r_g are within the ! 370: lexpr whose arguments they reference. If _f_o_o is ! 371: a compiled lexpr and it calls _b_a_r then _b_a_r cannot ! 372: use _a_r_g to get at _f_o_o's arguments. If both _f_o_o ! 373: and _b_a_r are interpreted this will work however. ! 374: The macro _l_i_s_t_i_f_y can be used to put all of some ! 375: of a lexprs arguments in a list which then can be ! 376: passed to other functions. ! 377: ! 378: ! 379: ! 380: 12.5. Compiler options ! 381: ! 382: The compiler recognizes a number of options which ! 383: are described below. The options are typed anywhere ! 384: on the command line preceded by a minus sign. The ! 385: entire command line is scanned and all options ! 386: recorded before any action is taken. Thus ! 387: % liszt -mx foo ! 388: % liszt -m -x foo ! 389: ! 390: ! 391: Printed: August 5, 1983 ! 392: ! 393: ! 394: ! 395: ! 396: ! 397: ! 398: ! 399: Liszt - the lisp compiler 12-7 ! 400: ! 401: ! 402: % liszt foo -mx ! 403: are all equivalent. Before scanning the command line ! 404: for options, liszt looks for in the environment for ! 405: the variable LISZT, and if found scans its value as if ! 406: it was a string of options. The meaning of the ! 407: options are: ! 408: ! 409: C The assembler language output of the compiler is ! 410: commented. This is useful when debugging the ! 411: compiler and is not normally done since it slows ! 412: down compilation. ! 413: ! 414: I The next command line argument is taken as a ! 415: filename, and loaded prior to compilation. ! 416: ! 417: e Evaluate the next argument on the command line ! 418: before starting compilation. For example ! 419: % liszt -e '(setq foobar "foo string")' foo ! 420: will evaluate the above s-expression. Note that ! 421: the shell requires that the arguments be sur- ! 422: rounded by single quotes. ! 423: ! 424: i Compile this program in interlisp compatibility ! 425: mode. This is not implemented yet. ! 426: ! 427: m Compile this program in Maclisp mode. The reader ! 428: syntax will be changed to the Maclisp syntax and ! 429: a file of macro definitions will be loaded in ! 430: (usually named /usr/lib/lisp/machacks). This ! 431: switch brings us sufficiently close to Maclisp to ! 432: allow us to compile Macsyma, a large Maclisp pro- ! 433: gram. However Maclisp is a moving target and we ! 434: can't guarantee that this switch will allow you ! 435: to compile any given program. ! 436: ! 437: o Select a different object or assembler language ! 438: file name. For example ! 439: % liszt foo -o xxx.o ! 440: will compile foo and into xxx.o instead of the ! 441: default foo.o, and ! 442: % liszt bar -S -o xxx.s ! 443: will compile to assembler language into xxx.s ! 444: instead of bar.s. ! 445: ! 446: p place profiling code at the beginning of each ! 447: non-local function. If the lisp system is also ! 448: created with profiling in it, this allows func- ! 449: tion calling frequency to be determined (see ! 450: _p_r_o_f(_1)) ! 451: ! 452: q Run in quiet mode. The names of functions being ! 453: compiled and various "Note"'s are not printed. ! 454: 9 ! 455: ! 456: 9 Printed: August 5, 1983 ! 457: ! 458: ! 459: ! 460: ! 461: ! 462: ! 463: ! 464: Liszt - the lisp compiler 12-8 ! 465: ! 466: ! 467: Q print compilation statistics and warn of strange ! 468: constructs. This is the inverse of the q switch ! 469: and is the default. ! 470: ! 471: r place bootstrap code at the beginning of the ! 472: object file, which when the object file is exe- ! 473: cuted will cause a lisp system to be invoked and ! 474: the object file _f_a_s_led in. This is known as ! 475: `autorun' and is described below. ! 476: ! 477: S Create an assembler language file only. ! 478: % liszt -S foo ! 479: will create the file assembler language file ! 480: foo.s and will not attempt to assemble it. If ! 481: this option is not specified, the assembler ! 482: language file will be put in the temporary disk ! 483: area under a automatically generated name based ! 484: on the lisp compiler's process id. Then if there ! 485: are no compilation errors, the assembler will be ! 486: invoked to assemble the file. ! 487: ! 488: T Print the assembler language output on the stan- ! 489: dard output file. This is useful when debugging ! 490: the compiler. ! 491: ! 492: u Run in UCI-Lisp mode. The character syntax is ! 493: changed to that of UCI-Lisp and a UCI-Lisp compa- ! 494: tibility package of macros is read in. ! 495: ! 496: w Suppress warning messages. ! 497: ! 498: x Create an cross reference file. ! 499: % liszt -x foo ! 500: not only compiles foo into foo.o but also gen- ! 501: erates the file foo.x . The file foo.x is lisp ! 502: readable and lists for each function all func- ! 503: tions which that function could call. The pro- ! 504: gram lxref reads one or more of these ".x" files ! 505: and produces a human readable cross reference ! 506: listing. ! 507: ! 508: ! 509: ! 510: 12.6. autorun ! 511: ! 512: The object file which liszt writes does not con- ! 513: tain all the functions necessary to run the lisp pro- ! 514: gram which was compiled. In order to use the object ! 515: file, a lisp system must be started and the object ! 516: file _f_a_s_led in. When the -r switch is given to liszt, ! 517: the object file created will contain a small piece of ! 518: bootstrap code at the beginning, and the object file ! 519: will be made executable. Now, when the name of the ! 520: ! 521: ! 522: Printed: August 5, 1983 ! 523: ! 524: ! 525: ! 526: ! 527: ! 528: ! 529: ! 530: Liszt - the lisp compiler 12-9 ! 531: ! 532: ! 533: object file is given to the UNIX command interpreter ! 534: (shell) to run, the bootstrap code at the beginning of ! 535: the object file will cause a lisp system to be started ! 536: and the first action the lisp system will take is to ! 537: _f_a_s_l in the object file which started it. In effect ! 538: the object file has created an environment in which it ! 539: can run. ! 540: ! 541: Autorun is an alternative to _d_u_m_p_l_i_s_p. The ! 542: advantage of autorun is that the object file which ! 543: starts the whole process is typically small, whereas ! 544: the minimum _d_u_m_p_l_i_s_ped file is very large (one half ! 545: megabyte). The disadvantage of autorun is that the ! 546: file must be _f_a_s_led into a lisp each time it is used ! 547: whereas the file which _d_u_m_p_l_i_s_p creates can be run as ! 548: is. liszt itself is a _d_u_m_p_l_i_s_ped file since it is ! 549: used so often and is large enough that too much time ! 550: would be wasted _f_a_s_ling it in each time it was used. ! 551: The lisp cross reference program, lxref, uses _a_u_t_o_r_u_n ! 552: since it is a small and rarely used program. ! 553: ! 554: In order to have the program _f_a_s_led in begin exe- ! 555: cution (rather than starting a lisp top level), the ! 556: value of the symbol user-top-level should be set to ! 557: the name of the function to get control. An example ! 558: of this is shown next. ! 559: ! 560: ! 561: ! 562: ! 563: ! 564: ! 565: ! 566: ! 567: ! 568: ! 569: ! 570: ! 571: ! 572: ! 573: ! 574: ! 575: ! 576: ! 577: ! 578: ! 579: ! 580: ! 581: ! 582: ! 583: ! 584: ! 585: 9 ! 586: ! 587: 9 Printed: August 5, 1983 ! 588: ! 589: ! 590: ! 591: ! 592: ! 593: ! 594: ! 595: Liszt - the lisp compiler 12-10 ! 596: ! 597: ! 598: ! 599: ____________________________________________________ ! 600: ! 601: _w_e _w_a_n_t _t_o _r_e_p_l_a_c_e _t_h_e _u_n_i_x _d_a_t_e _p_r_o_g_r_a_m _w_i_t_h _o_n_e _w_r_i_t_t_e_n _i_n _l_i_s_p. ! 602: ! 603: % cat lispdate.l ! 604: (defun mydate nil ! 605: (patom "The date is ") ! 606: (patom (status ctime)) ! 607: (terpr) ! 608: (exit 0)) ! 609: (setq user-top-level 'mydate) ! 610: ! 611: % liszt -r lispdate ! 612: Compilation begins with Lisp Compiler 5.2 ! 613: source: lispdate.l, result: lispdate.o ! 614: mydate ! 615: %Note: lispdate.l: Compilation complete ! 616: %Note: lispdate.l: Time: Real: 0:3, CPU: 0:0.28, GC: 0:0.00 for 0 gcs ! 617: %Note: lispdate.l: Assembly begins ! 618: %Note: lispdate.l: Assembly completed successfully ! 619: 3.0u 2.0s 0:17 29% ! 620: ! 621: _W_e _c_h_a_n_g_e _t_h_e _n_a_m_e _t_o _r_e_m_o_v_e _t_h_e "._o", (_t_h_i_s _i_s_n'_t _n_e_c_e_s_s_a_r_y) ! 622: % mv lispdate.o lispdate ! 623: ! 624: _N_o_w _w_e _t_e_s_t _i_t _o_u_t ! 625: % lispdate ! 626: The date is Sat Aug 1 16:58:33 1981 ! 627: % ! 628: ____________________________________________________ ! 629: ! 630: ! 631: ! 632: ! 633: ! 634: ! 635: 12.7. pure literals ! 636: ! 637: Normally the quoted lisp objects (literals) which ! 638: appear in functions are treated as constants. Consider ! 639: this function: ! 640: ! 641: (_d_e_f _f_o_o ! 642: (_l_a_m_b_d_a _n_i_l (_c_o_n_d ((_n_o_t (_e_q '_a (_c_a_r (_s_e_t_q _x '(_a ! 643: _b))))) ! 644: (_p_r_i_n_t '_i_m_p_o_s_s_i_b_l_e!!)) ! 645: (_t (_r_p_l_a_c_a _x '_d))))) ! 646: ! 647: At first glance it seems that the first cond clause ! 648: will never be true, since the _c_a_r of (_a _b) should ! 649: always be _a. However if you run this function twice, ! 650: it will print 'impossible!!' the second time. This is ! 651: ! 652: ! 653: Printed: August 5, 1983 ! 654: ! 655: ! 656: ! 657: ! 658: ! 659: ! 660: ! 661: Liszt - the lisp compiler 12-11 ! 662: ! 663: ! 664: because the following clause modifies the 'constant' ! 665: list (_a _b) with the _r_p_l_a_c_a function. Such modifica- ! 666: tion of literal lisp objects can cause programs to ! 667: behave strangely as the above example shows, but more ! 668: importantly it can cause garbage collection problems ! 669: if done to compiled code. When a file is _f_a_s_led in, ! 670: if the symbol $purcopylits is non nil, the literal ! 671: lisp data is put in 'pure' space, that is it put in ! 672: space which needn't be looked at by the garabage col- ! 673: lector. This reduces the work the garbage collector ! 674: must do but it is dangerous since if the literals are ! 675: modified to point to non pure objects, the marker may ! 676: not mark the non pure objects. If the symbol $pur- ! 677: copylits is nil then the literal lisp data is put in ! 678: impure space and the compiled code will act like the ! 679: interpreted code when literal data is modified. The ! 680: default value for $purcopylits is t. ! 681: ! 682: ! 683: ! 684: 12.8. transfer tables ! 685: ! 686: A transfer table is setup by _f_a_s_l when the object ! 687: file is loaded in. There is one entry in the transfer ! 688: table for each function which is called in that object ! 689: file. The entry for a call to the function _f_o_o has ! 690: two parts whose contents are: ! 691: ! 692: [1] function address - This will initially point to ! 693: the internal function _q_l_i_n_k_e_r. It may some time ! 694: in the future point to the function _f_o_o if cer- ! 695: tain conditions are satisfied (more on this ! 696: below). ! 697: ! 698: [2] function name - This is a pointer to the symbol ! 699: _f_o_o. This will be used by _q_l_i_n_k_e_r. ! 700: ! 701: ! 702: ! 703: When a call is made to the function _f_o_o the call will ! 704: actually be made to the address in the transfer table ! 705: entry and will end up in the _q_l_i_n_k_e_r function. ! 706: _Q_l_i_n_k_e_r will determine that _f_o_o was the function being ! 707: called by locating the function name entry in the ! 708: transfer table[]. If the function being called is not ! 709: compiled then _q_l_i_n_k_e_r just calls _f_u_n_c_a_l_l to perform ! 710: ____________________ ! 711: 9 []_Q_l_i_n_k_e_r does this by tracing back the call stack until ! 712: it finds the _c_a_l_l_s machine instruction which called it. The ! 713: address field of the _c_a_l_l_s contains the address of the ! 714: transfer table entry. ! 715: ! 716: ! 717: ! 718: 9 Printed: August 5, 1983 ! 719: ! 720: ! 721: ! 722: ! 723: ! 724: ! 725: ! 726: Liszt - the lisp compiler 12-12 ! 727: ! 728: ! 729: the function call. If _f_o_o is compiled and if ! 730: (_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k) is non nil, then _q_l_i_n_k_e_r will ! 731: modify the function address part of the transfer table ! 732: to point directly to the function _f_o_o. Finally ! 733: _q_l_i_n_k_e_r will call _f_o_o directly . The next time a call ! 734: is made to _f_o_o the call will go directly to _f_o_o and ! 735: not through _q_l_i_n_k_e_r. This will result in a substan- ! 736: tial speedup in compiled code to compiled code ! 737: transfers. A disadvantage is that no debugging infor- ! 738: mation is left on the stack, so _s_h_o_w_s_t_a_c_k and _b_a_k_t_r_a_c_e ! 739: are useless. Another disadvantage is that if you ! 740: redefine a compiled function either through loading in ! 741: a new version or interactively defining it, then the ! 742: old version may still be called from compiled code if ! 743: the fast linking described above has already been ! 744: done. The solution to these problems is to use ! 745: (_s_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k _v_a_l_u_e). If value is ! 746: ! 747: _n_i_l All transfer tables will be cleared, i.e. all ! 748: function addresses will be set to point to ! 749: _q_l_i_n_k_e_r. This means that the next time a func- ! 750: tion is called _q_l_i_n_k_e_r will be called and will ! 751: look at the current definition. Also, no fast ! 752: links will be set up since (_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k) ! 753: will be nil. The end result is that _s_h_o_w_s_t_a_c_k ! 754: and _b_a_k_t_r_a_c_e will work and the function defini- ! 755: tion at the time of call will always be used. ! 756: ! 757: _o_n This causes the lisp system to go through all ! 758: transfer tables and set up fast links wherever ! 759: possible. This is normally used after you have ! 760: _f_a_s_led in all of your files. Furthermore since ! 761: (_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k) is not nil, _q_l_i_n_k_e_r will make ! 762: new fast links if the situation arises (which ! 763: isn't likely unless you _f_a_s_l in another file). ! 764: ! 765: _t This or any other value not previously mentioned ! 766: will just make (_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k) be non nil, and ! 767: as a result fast links will be made by _q_l_i_n_k_e_r ! 768: if the called function is compiled. ! 769: ! 770: ! 771: ! 772: 12.9. Fixnum functions ! 773: ! 774: The compiler will generate inline arithmetic code ! 775: for fixnum only functions. Such functions include +, ! 776: -, *, /, \, 1+ and 1-. The code generated will be ! 777: much faster than using _a_d_d, _d_i_f_f_e_r_e_n_c_e, etc. However ! 778: it will only work if the arguments to and results of ! 779: the functions are fixnums. No type checking is done. ! 780: ! 781: 9 ! 782: ! 783: 9 Printed: August 5, 1983 ! 784: ! 785: ! 786:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.