fns2.c 113 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500
  1. /* fns2.c Copyright (C) 1989-96 Codemist Ltd */
  2. /*
  3. * Basic functions part 2.
  4. */
  5. /* Signature: 31f63691 12-Mar-2000 */
  6. #include <stdarg.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "machine.h"
  10. #include "tags.h"
  11. #include "cslerror.h"
  12. #include "externs.h"
  13. #include "read.h"
  14. #include "entries.h"
  15. #include "arith.h"
  16. #ifdef COMMON
  17. #include "clsyms.h"
  18. #endif
  19. #ifdef TIMEOUT
  20. #include "timeout.h"
  21. #endif
  22. #ifdef SOCKETS
  23. #include "sockhdr.h"
  24. #endif
  25. Lisp_Object getcodevector(int32 type, int32 size)
  26. {
  27. /*
  28. * type is the code (e.g. TYPE_BPS) that gets packed, together with
  29. * the size, into a header word.
  30. * size is measured in bytes and must allow space for the header word.
  31. * This obtains space in the BPS area
  32. */
  33. Lisp_Object nil = C_nil;
  34. #ifdef CHECK_FOR_CORRUPT_HEAP
  35. validate_all();
  36. #endif
  37. for (;;)
  38. { int32 alloc_size = (int32)doubleword_align_up(size);
  39. char *cf = (char *)codefringe, *cl = (char *)codelimit;
  40. unsigned int free = cf - cl;
  41. char *r;
  42. if (alloc_size > (int32)free)
  43. { char msg[40];
  44. sprintf(msg, "codevector %ld", (long)size);
  45. reclaim(nil, msg, GC_BPS, alloc_size);
  46. errexit();
  47. continue;
  48. }
  49. r = cf - alloc_size;
  50. codefringe = (Lisp_Object)r;
  51. *((Header *)r) = type + (size << 10) + TAG_ODDS;
  52. return TAG_BPS +
  53. (((int32)(r - cl + 12) & (PAGE_POWER_OF_TWO-4)) << 6) +
  54. (((int32)(bps_pages_count-1))<<(PAGE_BITS+6)); /* Wow! Obscure!! */
  55. }
  56. }
  57. Lisp_Object Lget_bps(Lisp_Object nil, Lisp_Object n)
  58. {
  59. int32 n1;
  60. if (!is_fixnum(n) || (int32)n<0) return aerror1("get-bps", n);
  61. n1 = int_of_fixnum(n);
  62. n = getcodevector(TYPE_BPS, n1+4);
  63. errexit();
  64. return onevalue(n);
  65. }
  66. Lisp_Object get_native_code_vector(int32 size)
  67. {
  68. /*
  69. * Create some space for native code and return a handle that identifies
  70. * its start point. size is measured in bytes.
  71. */
  72. Lisp_Object nil = C_nil;
  73. if (size <= 0) size = 8;
  74. for (;;)
  75. { int32 alloc_size = (int32)doubleword_align_up(size);
  76. int32 cf = native_fringe;
  77. int32 free = CSL_PAGE_SIZE - cf - 0x100; /* 256 bytes to be safe */
  78. /*
  79. * When I start up a cold CSL I will have native_fringe set to zero and
  80. * native_pages_count also zero, indicating that there is none of this stuff
  81. * active.
  82. */
  83. if (native_fringe == 0 || alloc_size > free)
  84. { char msg[40];
  85. sprintf(msg, "native code %ld", (long)size);
  86. reclaim(nil, msg, GC_NATIVE, alloc_size);
  87. errexit();
  88. continue;
  89. }
  90. free = (int32)native_pages[native_pages_count-1];
  91. free = doubleword_align_up(free);
  92. /*
  93. * I put the number of bytes in this block as the first word of the chunk
  94. * of memory, and arrange that there is a zero in what would be the first
  95. * word of unused space. Provided the user does not clobber bytes 0 to 4
  96. * or the block this is enough to allow restart code to scan through all
  97. * native code segments.
  98. */
  99. *(int32 *)(free+native_fringe) = alloc_size;
  100. *(int32 *)(free+native_fringe+alloc_size) = 0;
  101. native_fringe += alloc_size;
  102. native_pages_changed = 1;
  103. return Lcons(nil,
  104. fixnum_of_int(native_pages_count-1),
  105. fixnum_of_int(cf));
  106. }
  107. }
  108. Lisp_Object Lget_native(Lisp_Object nil, Lisp_Object n)
  109. {
  110. int32 n1;
  111. if (!is_fixnum(n) || (int32)n<0) return aerror1("get-native", n);
  112. n1 = int_of_fixnum(n);
  113. n = get_native_code_vector(n1);
  114. errexit();
  115. return onevalue(n);
  116. }
  117. int do_not_kill_native_code = 0;
  118. void set_fns(Lisp_Object a, one_args *f1, two_args *f2, n_args *fn)
  119. {
  120. Lisp_Object nil = C_nil;
  121. Lisp_Object w1, w2, w3 = nil;
  122. /*
  123. * If I redefine a function for any reason (except to set trace options
  124. * on a bytecoded definition) I will discard any native-coded definitions
  125. * by splicing them out of the record. I provide a global variable to
  126. * defeat this behaviour (ugh).
  127. */
  128. if (!do_not_kill_native_code)
  129. { for (w1 = native_code; w1!=nil; w1=qcdr(w1))
  130. { w2 = qcar(w1);
  131. if (qcar(w2) == a) break;
  132. w3 = w1;
  133. }
  134. if (w1 != nil)
  135. { w1 = qcdr(w1);
  136. if (w3 == nil) native_code = w1;
  137. else qcdr(w3) = w1;
  138. }
  139. }
  140. if ((qheader(a) & (SYM_C_DEF | SYM_CODEPTR)) ==
  141. (SYM_C_DEF | SYM_CODEPTR))
  142. {
  143. #ifdef NOISY_RE_PROTECTED_FNS
  144. trace_printf("+++ protected function ");
  145. prin_to_trace(a);
  146. trace_printf(" not redefined\n");
  147. #endif
  148. return;
  149. }
  150. ifn1(a) = (int32)f1;
  151. ifn2(a) = (int32)f2;
  152. ifnn(a) = (int32)fn;
  153. }
  154. #ifdef HIDE_USELESS_SYMBOL_ENVIRONMENTS
  155. static CSLbool interpreter_entry(Lisp_Object a)
  156. /*
  157. * If a function will be handled by the interpreter, including the case
  158. * of it being undefined, then the fn1() cell will tell me so.
  159. */
  160. {
  161. return (
  162. qfn1(a) == interpreted1 ||
  163. qfn1(a) == traceinterpreted1 ||
  164. qfn1(a) == double_interpreted1 ||
  165. qfn1(a) == funarged1 ||
  166. qfn1(a) == tracefunarged1 ||
  167. qfn1(a) == double_funarged1 ||
  168. qfn1(a) == undefined1);
  169. }
  170. #endif
  171. static char *show_fn(void *p)
  172. {
  173. int i;
  174. for (i=0; i<entry_table_size; i++)
  175. if (entries_table[i].p == p) return 1+entries_table[i].s;
  176. return "unknown";
  177. }
  178. Lisp_Object Lsymbol_fn_cell(Lisp_Object nil, Lisp_Object a)
  179. /*
  180. * For debugging...
  181. */
  182. {
  183. char *s1, *s2, *sn;
  184. if (!symbolp(a)) return onevalue(nil);
  185. s1 = show_fn((void *)qfn1(a));
  186. s2 = show_fn((void *)qfn2(a));
  187. sn = show_fn((void *)qfnn(a));
  188. trace_printf("%s %s %s\n", s1, s2, sn);
  189. return onevalue(nil);
  190. }
  191. Lisp_Object Lsymbol_argcount(Lisp_Object nil, Lisp_Object a)
  192. /*
  193. * For debugging and JIT compiler use. Only valid if the function involved
  194. * is byte-coded. For simple functions taking a fixed number of args the
  195. * result is an integer. Otherwise it is a list of 3 items
  196. * (fewest-legal-args most-args-before-&rest flags)
  197. * where the flags has a 1 bit if missing &optional args are to be left
  198. * for the bytecoded stuff to unpick, otherwise they should be mapped to nil
  199. * somewhere. The 2 bit is present if a &rest argument is present.
  200. */
  201. {
  202. one_args *f1;
  203. two_args *f2;
  204. n_args *fn;
  205. int low, high, hardrest;
  206. Lisp_Object r;
  207. unsigned char *b;
  208. if (!symbolp(a)) return onevalue(nil);
  209. f1 = qfn1(a);
  210. f2 = qfn2(a);
  211. fn = qfnn(a);
  212. r = qenv(a);
  213. if (!consp(r)) return onevalue(nil);
  214. r = qcar(r);
  215. if (!is_bps(r)) return onevalue(nil);
  216. b = (unsigned char *)data_of_bps(r);
  217. if (f1 == bytecoded1 ||
  218. f1 == tracebytecoded1 ||
  219. f1 == double_bytecoded1) return onevalue(fixnum_of_int(1));
  220. if (f2 == bytecoded2 ||
  221. f2 == tracebytecoded2 ||
  222. f2 == double_bytecoded2) return onevalue(fixnum_of_int(2));
  223. if (fn == bytecoded0 ||
  224. fn == tracebytecoded0 ||
  225. fn == double_bytecoded0) return onevalue(fixnum_of_int(0));
  226. if (fn == bytecoded3 ||
  227. fn == tracebytecoded3 ||
  228. fn == double_bytecoded3) return onevalue(fixnum_of_int(3));
  229. if (fn == bytecodedn ||
  230. fn == tracebytecodedn ||
  231. fn == double_bytecodedn) return onevalue(fixnum_of_int(b[0]));
  232. low = b[0]; /* smallest number of valid args */
  233. high = low + b[1]; /* largest number before &rest is accounted for */
  234. hardrest = 0;
  235. /*
  236. * byteopt - optional arguments, with default of NIL
  237. */
  238. if (f1 == byteopt1 ||
  239. f1 == tracebyteopt1) hardrest = 0;
  240. /*
  241. * hardopt - optional arguments but default is passed as a SPID so that
  242. * the user can follow up and apply cleverer default processing
  243. */
  244. else if (f1 == hardopt1 ||
  245. f1 == tracehardopt1) hardrest = 1;
  246. /*
  247. * byteoptrest - anything with a &rest argument on the end.
  248. */
  249. else if (f1 == byteoptrest1 ||
  250. f1 == tracebyteoptrest1) hardrest = 1;
  251. /*
  252. * hardoptrest - some &optional args with non-nil default value, plus &rest
  253. */
  254. else if (f1 == hardoptrest1 ||
  255. f1 == tracehardoptrest1) hardrest = 3;
  256. else return onevalue(nil);
  257. r = list3(fixnum_of_int(low),
  258. fixnum_of_int(high), fixnum_of_int(hardrest));
  259. errexit();
  260. return onevalue(r);
  261. }
  262. Lisp_Object Lsymbol_env(Lisp_Object nil, Lisp_Object a)
  263. /*
  264. * Not Common Lisp - read the 'environment' cell associated with a
  265. * symbol. This cell is deemed empty unless the symbol-function is
  266. * compiled code. For use mainly for debugging.
  267. */
  268. {
  269. if (!symbolp(a)) return onevalue(nil);
  270. #ifdef HIDE_USELESS_SYMBOL_ENVIRONMENTS
  271. else if ((qheader(a) & (SYM_SPECIAL_FORM | SYM_MACRO)) != 0 ||
  272. interpreter_entry(a)) return onevalue(nil);
  273. #endif
  274. return onevalue(qenv(a));
  275. }
  276. Lisp_Object Lsymbol_set_env(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  277. {
  278. CSL_IGNORE(nil);
  279. if (!is_symbol(a)) return aerror1("symbol-set-env", a);
  280. if ((qheader(a) & (SYM_C_DEF | SYM_CODEPTR)) ==
  281. (SYM_C_DEF | SYM_CODEPTR)) return onevalue(nil);
  282. qenv(a) = b;
  283. return onevalue(b);
  284. }
  285. Lisp_Object Lsymbol_fastgets(Lisp_Object nil, Lisp_Object a)
  286. {
  287. if (!symbolp(a)) return onevalue(nil);
  288. return onevalue(qfastgets(a));
  289. }
  290. /*
  291. * (protect 'name t) arranges that the function indicated (which is
  292. * expected to have been defined in the C kernel) can not be redefined.
  293. * (protect 'name nil) restores the usual state of affairs.
  294. */
  295. Lisp_Object Lsymbol_protect(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  296. {
  297. Header h;
  298. if (!is_symbol(a)) return onevalue(nil);
  299. h = qheader(a);
  300. if (b == nil) qheader(a) = h & ~(SYM_CODEPTR | SYM_C_DEF);
  301. else qheader(a) = h | SYM_CODEPTR | SYM_C_DEF;
  302. h &= (SYM_CODEPTR | SYM_C_DEF);
  303. return onevalue(Lispify_predicate(h == (SYM_CODEPTR | SYM_C_DEF)));
  304. }
  305. /*
  306. * (symbol-make-fastget 'xxx nil) returns current information, nil if no
  307. * fastget usage set.
  308. * (symbol-make-fastget 'xxx n) sets it to n (0 <= n < 63)
  309. * (symbol-make-fastget 'xxx -1) sets the option off
  310. * (symbol-make-fastget n) specify fast-get range (n <= 63)
  311. */
  312. Lisp_Object Lsymbol_make_fastget1(Lisp_Object nil, Lisp_Object a)
  313. {
  314. int32 n, n1 = fastget_size;
  315. CSL_IGNORE(nil);
  316. if (!is_fixnum(a) ||
  317. (n = int_of_fixnum(a)) < 0 ||
  318. (n > MAX_FASTGET_SIZE)) return aerror1("symbol-make-fastget", a);
  319. term_printf("+++ Fastget size was %d, now %d\n", n1, n);
  320. fastget_size = n;
  321. return onevalue(fixnum_of_int(n1));
  322. }
  323. Lisp_Object Lsymbol_make_fastget(Lisp_Object nil, Lisp_Object a, Lisp_Object n)
  324. {
  325. int32 n1, p, q;
  326. Header h;
  327. if (!symbolp(a)) return onevalue(nil);
  328. h = qheader(a);
  329. p = header_fastget(h);
  330. if (is_fixnum(n))
  331. { n1 = int_of_fixnum(n);
  332. if (n1 < -1 || n1 >= fastget_size)
  333. return aerror1("symbol-make-fastget", n);
  334. trace_printf("+++ Use fastget slot %d for ", n1);
  335. loop_print_trace(a);
  336. errexit();
  337. trace_printf("\n");
  338. if (p != 0) elt(fastget_names, p-1) = SPID_NOPROP;
  339. q = (n1 + 1) & 0x3f;
  340. h = (h & ~SYM_FASTGET_MASK) | (q << SYM_FASTGET_SHIFT);
  341. qheader(a) = h;
  342. if (q != 0) elt(fastget_names, q-1) = a;
  343. }
  344. if (p == 0) return onevalue(nil);
  345. else return onevalue(fixnum_of_int(p - 1));
  346. }
  347. static Lisp_Object deleqip(Lisp_Object a, Lisp_Object l)
  348. /*
  349. * This deletes the item a (tested for using EQ) from the list l,
  350. * assuming that the list is nil-terminated and that the item a
  351. * occurs at most once. It overwrites the list l in the process.
  352. */
  353. {
  354. Lisp_Object nil = C_nil, w, r;
  355. if (l == nil) return nil;
  356. if (qcar(l) == a) return qcdr(l);
  357. r = l;
  358. while (w = l, (l = qcdr(l)) != nil)
  359. { if (qcar(l) == a)
  360. { qcdr(w) = qcdr(l);
  361. return r;
  362. }
  363. }
  364. return r;
  365. }
  366. void lose_C_def(Lisp_Object a)
  367. {
  368. /*
  369. * None of the code here can cause garbage collection.
  370. */
  371. #ifdef COMMON
  372. Lisp_Object nil = C_nil;
  373. Lisp_Object b = get(a, unset_var, nil), c;
  374. #else
  375. nil_as_base
  376. Lisp_Object b = get(a, unset_var), c;
  377. #endif
  378. Lremprop(C_nil, a, unset_var);
  379. qheader(a) &= ~SYM_C_DEF;
  380. #ifdef COMMON
  381. c = get(b, work_symbol, nil);
  382. #else
  383. c = get(b, work_symbol);
  384. #endif
  385. c = deleqip(a, c);
  386. if (c == C_nil) Lremprop(C_nil, b, work_symbol);
  387. else putprop(b, work_symbol, c);
  388. }
  389. /*
  390. * (symbol-set-native fn args bpsbase offset env)
  391. * where bpsbase is as handed back by (make-native nnn) and offset is
  392. * the offset in this block to enter at.
  393. * If args has the actual arg count in its bottom byte. Usually the
  394. * rest of it will be zero, and then one function cell is set to point to the
  395. * given entrypoint and the other two are set to point at error handlers.
  396. * If any bits in args beyond that are set then this call only changes the
  397. * directly specified function cell, and the others are left in whatever state
  398. * they were. If several of the fuction cells are to be filled in (eg to cope
  399. * with &optional or &rest arguments) then a simple call with args<256 must
  400. * be made first, followed by the calls (args>=256) that fill in the other
  401. * two cells.
  402. * The first time that symbol-set-native is called on a function that
  403. * function MUST have a byte coded definition, and this definition is
  404. * picked up and stored away, so that if (preserve) is called the bytecoded
  405. * definition will be available for use on systems with different
  406. * architectures. To make things tolerably consistent with that any operation
  407. * that installs a new bytecoded (or for that matter other) definition
  408. * will clear away any native-compiled versions of the function.
  409. *
  410. * The native code that is installed will be expected to have relocation
  411. * records starting at the start of bpsbase, and these will be activated,
  412. * filling in references from the bps to other executable parts of Lisp.
  413. * Passing bad arguments to this function provide a quick and easy way to
  414. * cayse UTTER havoc. Therefore I disable its use in server applications.
  415. */
  416. Lisp_Object MS_CDECL Lsymbol_set_native(Lisp_Object nil, int nargs, ...)
  417. {
  418. va_list a;
  419. Lisp_Object fn, args, bpsbase, offset, env, w1, w2, w3;
  420. int32 pagenumber, page, bps, address, t_p, arginfo;
  421. #ifdef SOCKETS
  422. /*
  423. * Security measure - deny symbol-set-native to remote users
  424. */
  425. if (socket_server != 0) return aerror("symbol-set-native");
  426. #endif
  427. argcheck(nargs, 5, "symbol-set-native");
  428. va_start(a, nargs);
  429. fn = va_arg(a, Lisp_Object);
  430. args = va_arg(a, Lisp_Object);
  431. bpsbase = va_arg(a, Lisp_Object);
  432. offset = va_arg(a, Lisp_Object);
  433. env = va_arg(a, Lisp_Object);
  434. va_end(a);
  435. if (!is_symbol(fn) ||
  436. (qheader(fn) & (SYM_SPECIAL_FORM | SYM_CODEPTR)) != 0)
  437. return aerror1("symbol-set-native", fn);
  438. if (!is_fixnum(args)) return aerror1("symbol-set-native", args);
  439. if (!consp(bpsbase) ||
  440. !is_fixnum(qcar(bpsbase)) ||
  441. !is_fixnum(qcdr(bpsbase)))
  442. return aerror1("symbol-set-native", bpsbase);
  443. if (!is_fixnum(offset)) return aerror1("symbol-set-native", offset);
  444. nargs = int_of_fixnum(args);
  445. pagenumber = int_of_fixnum(qcar(bpsbase));
  446. if (pagenumber<0 || pagenumber>=native_pages_count)
  447. return aerror1("symbol-set-native", bpsbase);
  448. bps = int_of_fixnum(qcdr(bpsbase));
  449. address = bps+int_of_fixnum(offset);
  450. if (address<8 || address>=CSL_PAGE_SIZE)
  451. return aerror1("symbol-set-native", offset);
  452. page = (int32)native_pages[pagenumber];
  453. page = doubleword_align_up(page);
  454. bps = page + bps;
  455. relocate_native_function((unsigned char *)bps);
  456. /*
  457. * Here I need to push the info I have just collected onto
  458. * the native_code list since otherwise things will not be re-loaded in
  459. * from a checkpoint image. Also if the function is at present byte-coded
  460. * I need to record that info about it in native_code.
  461. */
  462. w1 = native_code;
  463. while (w1!=nil)
  464. { w2 = qcar(w1);
  465. if (qcar(w2) == fn) break;
  466. w1 = qcdr(w1);
  467. }
  468. if (w1 == nil)
  469. {
  470. /*
  471. * Here the function has not been seen as native code ever before, so it has
  472. * not been entered into the list. Do something about that...
  473. */
  474. push2(env, fn);
  475. args = Lsymbol_argcount(nil, fn);
  476. errexitn(2);
  477. if (args == nil)
  478. return aerror1("No bytecode definition found for", fn);
  479. /*
  480. * Now I have to reverse the information that symbol_argcount gave me
  481. * to get the single numeric code as wanted by symbol_set_definition.
  482. * Oh what a mess.
  483. */
  484. if (is_fixnum(args)) arginfo = int_of_fixnum(args);
  485. else
  486. { arginfo = int_of_fixnum(qcar(args));
  487. args = qcdr(args);
  488. arginfo |= ((int_of_fixnum(qcar(args)) - arginfo) << 8);
  489. args = qcdr(args);
  490. arginfo |= int_of_fixnum(qcar(args)) << 16;
  491. }
  492. fn = stack[0];
  493. w2 = list2(fn, fixnum_of_int(arginfo));
  494. errexitn(2);
  495. w2 = cons(w2, native_code);
  496. errexitn(2);
  497. native_code = w2;
  498. w2 = qcar(w2);
  499. pop2(fn, env);
  500. }
  501. w2 = qcdr(w2); /* {nargs,(type . offset . env),...} */
  502. /*
  503. * If I was defining this function in the simple way I should clear any
  504. * previous version (for this machine architecture) from the record.
  505. * Just at present this does not release the memory, but at some stage
  506. * in the future I may arrange to compact away old code when I do a
  507. * preserve operation (say).
  508. */
  509. if (nargs <= 0xff)
  510. { w1 = w3 = w2;
  511. for (w1=qcdr(w2); w1!=nil; w1=qcdr(w1))
  512. { w3 = qcar(w1);
  513. if (qcar(w3) == fixnum_of_int(native_code_tag)) break;
  514. w3 = w1;
  515. }
  516. if (w1 != nil) qcdr(w3) = qcdr(w1);
  517. }
  518. /*
  519. * w2 is still the entry for this function in the native code list. It
  520. * needs to have an entry of type 0 (ie for bytecoded) and so the next
  521. * thing to do is to check that such an entry exists and if not to create
  522. * it.
  523. */
  524. w1 = w2;
  525. while ((w1 = qcdr(w1)) != nil)
  526. { w3 = qcar(w1);
  527. if (qcar(w3) == fixnum_of_int(0)) break;
  528. w1 = qcdr(w1);
  529. }
  530. if (w1 == nil)
  531. {
  532. /*
  533. * This is where there was no bytecode entry on the native code list
  534. * for this function, so I had better create one for it. Note that only
  535. * one such entry will ever be stored so it does not matter much where on
  536. * the list it goes. I suspect that the list ought always to be empty
  537. * in this case anyway.
  538. */
  539. push3(fn, env, w2);
  540. w1 = list2star(fixnum_of_int(0), fixnum_of_int(0), qenv(fn));
  541. errexitn(3);
  542. w2 = stack[0];
  543. w1 = cons(w1, qcdr(w2));
  544. errexitn(3);
  545. pop3(w2, env, fn);
  546. qcdr(w2) = w1;
  547. }
  548. /*
  549. * Now the list of native code associated with this function certainly holds
  550. * a byte-coded definition (and for sanity that had better be consistent
  551. * with the native code I am installing now, but that is not something
  552. * that can be checked at this level). Put in an entry referring to the
  553. * current gubbins.
  554. */
  555. push3(w2, fn, env);
  556. /*
  557. * now I pack the code type, arg category and offset into the
  558. * single fixnum that that information has to end up in.
  559. */
  560. t_p = (native_code_tag << 20);
  561. if ((nargs & 0xffffff00) != 0)
  562. {
  563. switch (nargs & 0xff)
  564. {
  565. case 1: t_p |= (1<<18); break;
  566. case 2: t_p |= (2<<18); break;
  567. default:t_p |= (3<<18); break;
  568. }
  569. }
  570. t_p |= (pagenumber & 0x3ffff);
  571. w1 = list2star(fixnum_of_int(t_p), fixnum_of_int(address), env);
  572. errexitn(3);
  573. w1 = ncons(w1);
  574. pop3(env, fn, w2);
  575. errexit();
  576. while ((w3 = qcdr(w2)) != nil) w2 = w3; /* Tag onto the END */
  577. qcdr(w2) = w1;
  578. qheader(fn) &= ~SYM_TRACED;
  579. address = page + address;
  580. /*
  581. * The code here must do just about the equivalent to that in restart.c
  582. */
  583. switch (nargs & 0xff)
  584. {
  585. case 0: ifnn(fn) = address;
  586. if (nargs<=0xff)
  587. ifn1(fn) = (int32)wrong_no_0a, ifn2(fn) = (int32)wrong_no_0b;
  588. break;
  589. case 1: ifn1(fn) = address;
  590. if (nargs<=0xff)
  591. ifn2(fn) = (int32)too_many_1, ifnn(fn) = (int32)wrong_no_1;
  592. break;
  593. case 2: ifn2(fn) = address;
  594. if (nargs<=0xff)
  595. ifn1(fn) = (int32)too_few_2, ifnn(fn) = (int32)wrong_no_2;
  596. break;
  597. case 3: ifnn(fn) = address;
  598. if (nargs<=0xff)
  599. ifn1(fn) = (int32)wrong_no_3a, ifn2(fn) = (int32)wrong_no_3b;
  600. break;
  601. default: ifnn(fn) = address;
  602. if (nargs<=0xff)
  603. ifn1(fn) = (int32)wrong_no_na, ifn2(fn) = (int32)wrong_no_nb;
  604. break;
  605. }
  606. qenv(fn) = env;
  607. return onevalue(fn);
  608. }
  609. static CSLbool restore_fn_cell(Lisp_Object a, char *name,
  610. int32 len, setup_type const s[])
  611. {
  612. int i;
  613. for (i=0; s[i].name != NULL; i++)
  614. { if (strlen(s[i].name) == len &&
  615. memcmp(name, s[i].name, len) == 0) break;
  616. }
  617. if (s[i].name == NULL) return NO;
  618. set_fns(a, s[i].one, s[i].two, s[i].n);
  619. return YES;
  620. }
  621. static Lisp_Object Lrestore_c_code(Lisp_Object nil, Lisp_Object a)
  622. {
  623. char *name;
  624. int32 len;
  625. Lisp_Object pn;
  626. if (!symbolp(a)) return aerror1("restore-c-code", a);
  627. push(a);
  628. pn = get_pname(a);
  629. pop(a);
  630. errexit();
  631. name = (char *)&celt(pn, 0);
  632. len = length_of_header(vechdr(pn)) - 4;
  633. if (restore_fn_cell(a, name, len, u01_setup) ||
  634. restore_fn_cell(a, name, len, u02_setup) ||
  635. restore_fn_cell(a, name, len, u03_setup) ||
  636. restore_fn_cell(a, name, len, u04_setup) ||
  637. restore_fn_cell(a, name, len, u05_setup) ||
  638. restore_fn_cell(a, name, len, u06_setup) ||
  639. restore_fn_cell(a, name, len, u07_setup) ||
  640. restore_fn_cell(a, name, len, u08_setup) ||
  641. restore_fn_cell(a, name, len, u09_setup) ||
  642. restore_fn_cell(a, name, len, u10_setup) ||
  643. restore_fn_cell(a, name, len, u11_setup) ||
  644. restore_fn_cell(a, name, len, u12_setup))
  645. { Lisp_Object env;
  646. push(a);
  647. #ifdef COMMON
  648. env = get(a, funarg, nil);
  649. #else
  650. env = get(a, funarg);
  651. #endif
  652. pop(a);
  653. errexit();
  654. qenv(a) = env;
  655. return onevalue(a);
  656. }
  657. else return onevalue(nil);
  658. }
  659. Lisp_Object Lsymbol_set_definition(Lisp_Object nil,
  660. Lisp_Object a, Lisp_Object b)
  661. /*
  662. * The odd case here is where the second argument represents a freshly
  663. * created bit of compiled code. In which case the structure is
  664. * (nargs . codevec . envvec)
  665. * where nargs is an integer indicating the number of arguments, codevec
  666. * is a vector of bytecodes, and envvec is something to go in the
  667. * environment cell of the symbol.
  668. * Here the low 8 bits of nargs indicate the number of required arguments.
  669. * The next 8 bits give the number of optional arguments, and the next
  670. * two bits are flags. Of these, the first is set if any of the optional
  671. * arguments has an initform or supplied-p associate, and the other
  672. * indicates that a "&rest" argument is required.
  673. * Bits beyond that (if non-zero) indicate that the function definition
  674. * is of the form (defun f1 (a b c) (f2 a b)) and the number coded is the
  675. * length of the function body.
  676. * Standard Lisp does not need &optional or &rest arguments, but it turned
  677. * out to be pretty easy to make the bytecode compiler support them.
  678. */
  679. {
  680. if (!is_symbol(a) ||
  681. /*
  682. * Something flagged with the CODEPTR bit is a gensym manufactured to
  683. * stand for a compiled-code object. It should NOT be reset!
  684. */
  685. (qheader(a) & (SYM_SPECIAL_FORM | SYM_CODEPTR)) != 0)
  686. { if (qheader(a) & SYM_C_DEF) return onevalue(nil);
  687. return aerror1("symbol-set-definition", a);
  688. }
  689. qheader(a) &= ~SYM_TRACED;
  690. set_fns(a, undefined1, undefined2, undefinedn); /* Tidy up first */
  691. qenv(a) = a;
  692. if ((qheader(a) & SYM_C_DEF) != 0) lose_C_def(a);
  693. if (b == nil) return onevalue(b); /* set defn to nil to undefine */
  694. else if (symbolp(b))
  695. {
  696. /*
  697. * One could imagine a view that the second arg to symbol-set-definition
  698. * had to be a codepointer object. I will be kind (?) and permit the NAME
  699. * of a function too. However for the second arg to be a macro or a
  700. * special form would still be a calamity.
  701. * if ((qheader(b) & SYM_CODEPTR) == 0)
  702. * return aerror1("symbol-set-definition", b);
  703. */
  704. if ((qheader(b) & (SYM_SPECIAL_FORM | SYM_MACRO)) != 0)
  705. return aerror1("symbol-set-definition", b);
  706. qheader(a) = qheader(a) & ~SYM_MACRO;
  707. { set_fns(a, qfn1(b), qfn2(b), qfnn(b));
  708. qenv(a) = qenv(b);
  709. /*
  710. * In order that checkpoint files can be made there is some very
  711. * ugly fooling around here for functions that are defined in the C coded
  712. * kernel. Sorry.
  713. */
  714. if ((qheader(b) & SYM_C_DEF) != 0)
  715. {
  716. #ifdef COMMON
  717. Lisp_Object c = get(b, unset_var, nil);
  718. #else
  719. Lisp_Object c = get(b, unset_var);
  720. #endif
  721. if (c == nil) c = b;
  722. push2(c, a);
  723. putprop(a, unset_var, c);
  724. errexitn(2);
  725. pop(a);
  726. #ifdef COMMON
  727. a = cons(a, get(stack[0], work_symbol, nil));
  728. #else
  729. a = cons(a, get(stack[0], work_symbol));
  730. #endif
  731. errexitn(1);
  732. putprop(stack[0], work_symbol, a);
  733. pop(b);
  734. errexit();
  735. }
  736. }
  737. }
  738. else if (!consp(b)) return aerror1("symbol-set-definition", b);
  739. else if (is_fixnum(qcar(b)))
  740. { int32 nargs = (int)int_of_fixnum(qcar(b)), nopts, flagbits, ntail;
  741. nopts = nargs >> 8;
  742. flagbits = nopts >> 8;
  743. ntail = flagbits >> 2;
  744. nargs &= 0xff;
  745. nopts &= 0xff;
  746. flagbits &= 3;
  747. if (ntail != 0)
  748. { switch (100*nargs + ntail-1)
  749. {
  750. case 300: set_fns(a, wrong_no_na, wrong_no_nb, f3_as_0); break;
  751. case 301: set_fns(a, wrong_no_na, wrong_no_nb, f3_as_1); break;
  752. case 302: set_fns(a, wrong_no_na, wrong_no_nb, f3_as_2); break;
  753. case 303: set_fns(a, wrong_no_na, wrong_no_nb, f3_as_3); break;
  754. case 200: set_fns(a, too_few_2, f2_as_0, wrong_no_2); break;
  755. case 201: set_fns(a, too_few_2, f2_as_1, wrong_no_2); break;
  756. case 202: set_fns(a, too_few_2, f2_as_2, wrong_no_2); break;
  757. case 100: set_fns(a, f1_as_0, too_many_1, wrong_no_1); break;
  758. case 101: set_fns(a, f1_as_1, too_many_1, wrong_no_1); break;
  759. case 000: set_fns(a, wrong_no_na, wrong_no_nb, f0_as_0); break;
  760. }
  761. b = qcdr(b);
  762. }
  763. else if (flagbits != 0 || nopts != 0)
  764. { if ((qheader(a) & SYM_TRACED) == 0) switch(flagbits)
  765. {
  766. default:
  767. case 0: /* easy case optional arguments */
  768. set_fns(a, byteopt1, byteopt2, byteoptn); break;
  769. case 1: /* optional args, but non-nil default, or supplied-p extra */
  770. set_fns(a, hardopt1, hardopt2, hardoptn); break;
  771. case 2: /* easy opt args, but also a &rest arg */
  772. set_fns(a, byteoptrest1, byteoptrest2, byteoptrestn); break;
  773. case 3: /* complicated &options and &rest */
  774. set_fns(a, hardoptrest1, hardoptrest2, hardoptrestn); break;
  775. }
  776. else switch (flagbits)
  777. {
  778. default:
  779. case 0: /* easy case optional arguments */
  780. set_fns(a, tracebyteopt1, tracebyteopt2, tracebyteoptn); break;
  781. case 1: /* optional args, but non-nil default, or supplied-p extra */
  782. set_fns(a, tracehardopt1, tracehardopt2, tracehardoptn); break;
  783. case 2: /* easy opt args, but also a &rest arg */
  784. set_fns(a, tracebyteoptrest1, tracebyteoptrest2, tracebyteoptrestn); break;
  785. case 3: /* complicated &options and &rest */
  786. set_fns(a, tracehardoptrest1, tracehardoptrest2, tracehardoptrestn); break;
  787. }
  788. }
  789. else
  790. { if (nargs > 4) nargs = 4;
  791. if ((qheader(a) & SYM_TRACED) != 0) nargs += 5;
  792. qheader(a) = qheader(a) & ~SYM_MACRO;
  793. switch (nargs)
  794. {
  795. case 0: set_fns(a, wrong_no_0a, wrong_no_0b, bytecoded0);
  796. break;
  797. case 1: set_fns(a, bytecoded1, too_many_1, wrong_no_1);
  798. break;
  799. case 2: set_fns(a, too_few_2, bytecoded2, wrong_no_2);
  800. break;
  801. case 3: set_fns(a, wrong_no_3a, wrong_no_3b, bytecoded3);
  802. break;
  803. default:
  804. case 4: set_fns(a, wrong_no_na, wrong_no_nb, bytecodedn);
  805. break;
  806. case 5+0: set_fns(a, wrong_no_0a, wrong_no_0b, tracebytecoded0);
  807. break;
  808. case 5+1: set_fns(a, tracebytecoded1, too_many_1, wrong_no_1);
  809. break;
  810. case 5+2: set_fns(a, too_few_2, tracebytecoded2, wrong_no_2);
  811. break;
  812. case 5+3: set_fns(a, wrong_no_3a, wrong_no_3b, tracebytecoded3);
  813. break;
  814. case 5+4: set_fns(a, wrong_no_na, wrong_no_nb, tracebytecodedn);
  815. break;
  816. }
  817. }
  818. qenv(a) = qcdr(b);
  819. }
  820. else if (qcar(b) == lambda)
  821. { Lisp_Object bvl = qcar(qcdr(b));
  822. int nargs = 0;
  823. while (consp(bvl)) nargs++, bvl = qcdr(bvl);
  824. qheader(a) = qheader(a) & ~SYM_MACRO;
  825. if ((qheader(a) & SYM_TRACED) != 0)
  826. set_fns(a, traceinterpreted1, traceinterpreted2, traceinterpretedn);
  827. else set_fns(a, interpreted1, interpreted2, interpretedn);
  828. qenv(a) = qcdr(b);
  829. if (qvalue(comp_symbol) != nil &&
  830. qfn1(compiler_symbol) != undefined1)
  831. { push(a);
  832. a = ncons(a);
  833. errexitn(1);
  834. (qfn1(compiler_symbol))(qenv(compiler_symbol), a);
  835. pop(a);
  836. errexit();
  837. }
  838. }
  839. else if (qcar(b) == funarg)
  840. { Lisp_Object bvl = qcar(qcdr(b));
  841. int nargs = 0;
  842. while (consp(bvl)) nargs++, bvl = qcdr(bvl);
  843. qheader(a) = qheader(a) & ~SYM_MACRO;
  844. if ((qheader(a) & SYM_TRACED) != 0)
  845. set_fns(a, tracefunarged1, tracefunarged2, tracefunargedn);
  846. else set_fns(a, funarged1, funarged2, funargedn);
  847. qenv(a) = qcdr(b);
  848. }
  849. else return aerror1("symbol-set-definition", b);
  850. return onevalue(b);
  851. }
  852. Lisp_Object Lgetd(Lisp_Object nil, Lisp_Object a)
  853. {
  854. Header h;
  855. Lisp_Object type;
  856. CSL_IGNORE(nil);
  857. if (a == nil) return onevalue(nil);
  858. else if (!is_symbol(a)) return onevalue(nil);
  859. h = qheader(a);
  860. if ((h & SYM_SPECIAL_FORM) != 0) type = fexpr_symbol;
  861. else if ((h & SYM_MACRO) != 0)
  862. { a = cons(lambda, qenv(a));
  863. errexit();
  864. type = macro_symbol;
  865. }
  866. else
  867. { a = Lsymbol_function(nil, a);
  868. errexit();
  869. if (a == nil) return onevalue(nil);
  870. type = expr_symbol;
  871. }
  872. a = cons(type, a);
  873. errexit();
  874. return onevalue(a);
  875. }
  876. Lisp_Object Lremd(Lisp_Object nil, Lisp_Object a)
  877. {
  878. Lisp_Object res;
  879. CSL_IGNORE(nil);
  880. if (!is_symbol(a) ||
  881. (qheader(a) & SYM_SPECIAL_FORM) != 0)
  882. return aerror1("remd", a);
  883. if ((qheader(a) & (SYM_C_DEF | SYM_CODEPTR)) ==
  884. (SYM_C_DEF | SYM_CODEPTR)) return onevalue(nil);
  885. res = Lgetd(nil, a);
  886. errexit();
  887. if (res == nil) return onevalue(nil); /* no definition to remove */
  888. /*
  889. * I treat an explicit use of remd as a redefinition, and ensure that
  890. * restarting a preserved image will not put the definition back.
  891. */
  892. qheader(a) = qheader(a) & ~SYM_MACRO;
  893. if ((qheader(a) & SYM_C_DEF) != 0) lose_C_def(a);
  894. set_fns(a, undefined1, undefined2, undefinedn);
  895. qenv(a) = a;
  896. return onevalue(res);
  897. }
  898. /*
  899. * For set-autoload the first argument must be a symbol that will name
  900. * a function, the second arg is either an atom or a list of atoms, each
  901. * of which specified a module to be loaded if the names function is
  902. * called. Loading the modules is expected to instate a definition for the
  903. * function involved. This function is arranged so it does NOT do anything
  904. * if the function being set for autoloading is already defined. This is
  905. * on the supposition that the existing definition is in fact the desired
  906. * one, say because the relevant module happens to have been loaded already.
  907. * An explicit use of remd first can be used to ensure that no previous
  908. * definition is present and thus that a real autoload stub will be instated,
  909. * if that is what you really want.
  910. */
  911. Lisp_Object Lset_autoload(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  912. {
  913. Lisp_Object res;
  914. CSL_IGNORE(nil);
  915. if (!is_symbol(a) ||
  916. (qheader(a) & SYM_SPECIAL_FORM) != 0)
  917. return aerror1("set-autoload", a);
  918. if (!(qfn1(a) == undefined1 && qfn2(a) == undefined2 &&
  919. qfnn(a) == undefinedn)) return onevalue(nil);
  920. if ((qheader(a) & (SYM_C_DEF | SYM_CODEPTR)) ==
  921. (SYM_C_DEF | SYM_CODEPTR)) return onevalue(nil);
  922. push2(a, b);
  923. if (consp(b)) res = cons(a, b);
  924. else res = list2(a, b);
  925. pop2(b, a);
  926. errexit();
  927. /*
  928. * I treat an explicit use of set-autoload as a redefinition, and ensure that
  929. * restarting a preserved image will not put the definition back. Note that
  930. * I will not allow autoloadable macros...
  931. */
  932. qheader(a) = qheader(a) & ~SYM_MACRO;
  933. if ((qheader(a) & SYM_C_DEF) != 0) lose_C_def(a);
  934. set_fns(a, autoload1, autoload2, autoloadn);
  935. qenv(a) = res;
  936. return onevalue(res);
  937. }
  938. #define pack_funtable(a, n) ((((int32)(a)) << 16) | (n))
  939. #define funtable_nargs(u) ((u) >> 16)
  940. #define funtable_index(u) ((u) & 0xffffU)
  941. static one_args *displaced1 = NULL;
  942. static two_args *displaced2;
  943. static n_args *displacedn;
  944. static unsigned32 table_entry;
  945. static void trace_entering(char *s)
  946. {
  947. int i;
  948. for (i=0; i<trace_depth; i++) trace_printf(" ");
  949. trace_printf(s);
  950. trace_depth++;
  951. }
  952. static void trace_exiting(char *s)
  953. {
  954. int i;
  955. trace_depth--;
  956. trace_printf(s);
  957. }
  958. static Lisp_Object traced1_function(Lisp_Object env, Lisp_Object a)
  959. {
  960. Lisp_Object name, nil = C_nil;
  961. Lisp_Object r = nil;
  962. /*
  963. * Worry about errors & garbage collection in following calls to print fns
  964. * This MUST be fixed sometime fairly soon... but then it could only bite
  965. * people using the trace facility, and their code is already dead!
  966. */
  967. freshline_trace();
  968. trace_entering("");
  969. loop_print_trace(tracedfn);
  970. push(tracedfn);
  971. trace_printf(" called (1 arg)\narg1: ");
  972. loop_print_trace(a);
  973. trace_printf("\n");
  974. r = (*displaced1)(env, a);
  975. pop(name);
  976. errexit();
  977. push(r);
  978. freshline_trace();
  979. loop_print_trace(name);
  980. trace_printf(" = ");
  981. loop_print_trace(r);
  982. trace_exiting("\n");
  983. pop(r);
  984. return onevalue(r);
  985. }
  986. static Lisp_Object traced2_function(Lisp_Object env,
  987. Lisp_Object a, Lisp_Object b)
  988. {
  989. Lisp_Object name, nil = C_nil;
  990. Lisp_Object r = nil;
  991. freshline_trace();
  992. trace_entering("");
  993. loop_print_trace(tracedfn);
  994. push(tracedfn);
  995. trace_printf(" called (2 args)\narg1:");
  996. loop_print_trace(a);
  997. trace_printf("\narg2: ");
  998. loop_print_trace(b);
  999. trace_printf("\n");
  1000. r = (*displaced2)(env, a, b);
  1001. pop(name);
  1002. errexit();
  1003. push(r);
  1004. freshline_trace();
  1005. loop_print_trace(name);
  1006. trace_printf(" = ");
  1007. loop_print_trace(r);
  1008. trace_exiting("\n");
  1009. pop(r);
  1010. return onevalue(r);
  1011. }
  1012. static Lisp_Object MS_CDECL tracedn_function(Lisp_Object env, int nargs, ...)
  1013. {
  1014. Lisp_Object name, nil = C_nil;
  1015. Lisp_Object r = nil;
  1016. int i;
  1017. va_list a;
  1018. push(tracedfn);
  1019. va_start(a, nargs);
  1020. push_args(a, nargs);
  1021. freshline_trace();
  1022. trace_entering("");
  1023. loop_print_trace(tracedfn);
  1024. trace_printf(" called (%d args)\n", nargs);
  1025. for (i=1; i<=nargs; i++)
  1026. { trace_printf("arg%d: ", i);
  1027. loop_print_trace(stack[i-nargs]);
  1028. trace_printf("\n");
  1029. }
  1030. if (nargs <= 15) switch (nargs)
  1031. {
  1032. default:
  1033. /*
  1034. * Calls with 1 or 2 args can never arise, since those cases have been
  1035. * split off for separate treatment.
  1036. */
  1037. popv(nargs+1);
  1038. return aerror("system error in trace mechanism");
  1039. case 0:
  1040. r = (*displacedn)(env, 0);
  1041. break;
  1042. case 3:
  1043. r = (*displacedn)(env, 3, stack[-2], stack[-1], stack[0]);
  1044. break;
  1045. case 4:
  1046. r = (*displacedn)(env, 4, stack[-3], stack[-2], stack[-1],
  1047. stack[0]);
  1048. break;
  1049. case 5:
  1050. r = (*displacedn)(env, 5, stack[-4], stack[-3], stack[-2],
  1051. stack[-1], stack[0]);
  1052. break;
  1053. case 6:
  1054. r = (*displacedn)(env, 6, stack[-5], stack[-4], stack[-3],
  1055. stack[-2], stack[-1], stack[0]);
  1056. break;
  1057. case 7:
  1058. r = (*displacedn)(env, 7, stack[-6], stack[-5], stack[-4],
  1059. stack[-3], stack[-2], stack[-1], stack[0]);
  1060. break;
  1061. case 8:
  1062. r = (*displacedn)(env, 8, stack[-7], stack[-6], stack[-5],
  1063. stack[-4], stack[-3], stack[-2], stack[-1],
  1064. stack[0]);
  1065. break;
  1066. case 9:
  1067. r = (*displacedn)(env, 9, stack[-8], stack[-7], stack[-6],
  1068. stack[-5], stack[-4], stack[-3], stack[-2],
  1069. stack[-1], stack[0]);
  1070. break;
  1071. case 10:
  1072. r = (*displacedn)(env, 10, stack[-9], stack[-8], stack[-7],
  1073. stack[-6], stack[-5], stack[-4], stack[-3],
  1074. stack[-2], stack[-1], stack[0]);
  1075. break;
  1076. case 11:
  1077. r = (*displacedn)(env, 11, stack[-10], stack[-9],
  1078. stack[-8], stack[-7], stack[-6], stack[-5],
  1079. stack[-4], stack[-3], stack[-2], stack[-1],
  1080. stack[0]);
  1081. break;
  1082. case 12:
  1083. r = (*displacedn)(env, 12, stack[-11], stack[-10],
  1084. stack[-9], stack[-8], stack[-7], stack[-6],
  1085. stack[-5], stack[-4], stack[-3], stack[-2],
  1086. stack[-1], stack[0]);
  1087. break;
  1088. case 13:
  1089. r = (*displacedn)(env, 13, stack[-12], stack[-11],
  1090. stack[-10], stack[-9], stack[-8], stack[-7],
  1091. stack[-6], stack[-5], stack[-4], stack[-3],
  1092. stack[-2], stack[-1], stack[0]);
  1093. break;
  1094. case 14:
  1095. r = (*displacedn)(env, 14, stack[-13], stack[-12],
  1096. stack[-11], stack[-10], stack[-9], stack[-8],
  1097. stack[-7], stack[-6], stack[-5], stack[-4],
  1098. stack[-3], stack[-2], stack[-1], stack[0]);
  1099. break;
  1100. case 15:
  1101. r = (*displacedn)(env, 15, stack[-14], stack[-13],
  1102. stack[-12], stack[-11], stack[-10], stack[-9],
  1103. stack[-8], stack[-7], stack[-6], stack[-5],
  1104. stack[-4], stack[-3], stack[-2], stack[-1],
  1105. stack[0]);
  1106. break;
  1107. }
  1108. else
  1109. { trace_printf("Too many arguments to trace a function\n");
  1110. /*
  1111. * Because the above is a horrid mess I will only support traced
  1112. * calls with at most 15 args (more than I expect most people to
  1113. * try). And this only applies to thigs that are NOT bytecoded -
  1114. * I can trace bytecoded things with more args I believe, so users are not
  1115. * utterly lost I hope.
  1116. */
  1117. return aerror("traced function with > 15 args: not supported");
  1118. }
  1119. popv(nargs);
  1120. pop(name);
  1121. errexit();
  1122. push(r);
  1123. freshline_trace();
  1124. loop_print_trace(name);
  1125. trace_printf(" = ");
  1126. loop_print_trace(r);
  1127. trace_exiting("\n");
  1128. pop(r);
  1129. return onevalue(r);
  1130. }
  1131. #define NOT_FOUND 100
  1132. static unsigned32 find_built_in_function(one_args *f1,
  1133. two_args *f2,
  1134. n_args *fn)
  1135. /*
  1136. * This take the entrypoint of a function and tries to identify it
  1137. * by scanning the tables used by the bytecode interpreter. If the
  1138. * function is found a record is returned indicating how many args
  1139. * it takes, and what its index is in the relevant table. The code
  1140. * <NOT_FOUND,NOT_FOUND> is returned to indicate failure if the function
  1141. * is not found.
  1142. */
  1143. {
  1144. int32 index;
  1145. for (index=0; zero_arg_functions[index]!=NULL; index++)
  1146. if (fn == zero_arg_functions[index]) return pack_funtable(0, index);
  1147. for (index=0; one_arg_functions[index]!=NULL; index++)
  1148. if (f1 == one_arg_functions[index]) return pack_funtable(1, index);
  1149. for (index=0; two_arg_functions[index]!=NULL; index++)
  1150. if (f2 == two_arg_functions[index]) return pack_funtable(2, index);
  1151. for (index=0; three_arg_functions[index]!=NULL; index++)
  1152. if (fn == three_arg_functions[index]) return pack_funtable(3, index);
  1153. return pack_funtable(NOT_FOUND, NOT_FOUND);
  1154. }
  1155. Lisp_Object Ltrace_all(Lisp_Object nil, Lisp_Object a)
  1156. {
  1157. #ifdef DEBUG
  1158. if (a == nil) trace_all = 0;
  1159. else trace_all = 1;
  1160. return onevalue(nil);
  1161. #else
  1162. return aerror("trace-all only supported in DEBUG version");
  1163. #endif
  1164. }
  1165. Lisp_Object Ltrace(Lisp_Object nil, Lisp_Object a)
  1166. {
  1167. Lisp_Object w = a;
  1168. if (symbolp(a))
  1169. { a = ncons(a);
  1170. errexit();
  1171. w = a;
  1172. }
  1173. while (consp(w))
  1174. { Lisp_Object s = qcar(w);
  1175. w = qcdr(w);
  1176. if (symbolp(s))
  1177. { one_args *f1 = qfn1(s);
  1178. two_args *f2 = qfn2(s);
  1179. n_args *fn = qfnn(s);
  1180. int fixenv = 0, done = 0;
  1181. if (f1 == undefined1)
  1182. { freshline_debug();
  1183. debug_printf("+++ ");
  1184. loop_print_debug(s);
  1185. debug_printf(" not yet defined\n");
  1186. continue;
  1187. }
  1188. qheader(s) |= SYM_TRACED;
  1189. if (f1 == interpreted1)
  1190. { set_fns(s, traceinterpreted1, traceinterpreted2, traceinterpretedn);
  1191. fixenv = done = 1;
  1192. }
  1193. if (f1 == funarged1)
  1194. { set_fns(s, tracefunarged1, tracefunarged2, tracefunargedn);
  1195. fixenv = done = 1;
  1196. }
  1197. if (fn == bytecoded0) ifnn(s) = (int32)tracebytecoded0, done = 1;
  1198. if (f1 == bytecoded1) ifn1(s) = (int32)tracebytecoded1, done = 1;
  1199. if (f2 == bytecoded2) ifn2(s) = (int32)tracebytecoded2, done = 1;
  1200. if (fn == bytecoded3) ifnn(s) = (int32)tracebytecoded3, done = 1;
  1201. if (fn == bytecodedn) ifnn(s) = (int32)tracebytecodedn, done = 1;
  1202. if (f1 == byteopt1) ifn1(s) = (int32)tracebyteopt1, done = 1;
  1203. if (f2 == byteopt2) ifn2(s) = (int32)tracebyteopt2, done = 1;
  1204. if (fn == byteoptn) ifnn(s) = (int32)tracebyteoptn, done = 1;
  1205. if (f1 == hardopt1) ifn1(s) = (int32)tracehardopt1, done = 1;
  1206. if (f2 == hardopt2) ifn2(s) = (int32)tracehardopt2, done = 1;
  1207. if (fn == hardoptn) ifnn(s) = (int32)tracehardoptn, done = 1;
  1208. if (f1 == byteoptrest1) ifn1(s) = (int32)tracebyteoptrest1, done = 1;
  1209. if (f2 == byteoptrest2) ifn2(s) = (int32)tracebyteoptrest2, done = 1;
  1210. if (fn == byteoptrestn) ifnn(s) = (int32)tracebyteoptrestn, done = 1;
  1211. if (f1 == hardoptrest1) ifn1(s) = (int32)tracehardoptrest1, done = 1;
  1212. if (f2 == hardoptrest2) ifn2(s) = (int32)tracehardoptrest2, done = 1;
  1213. if (fn == hardoptrestn) ifnn(s) = (int32)tracehardoptrestn, done = 1;
  1214. if (fixenv)
  1215. { push2(a, s);
  1216. a = cons(s, qenv(s));
  1217. errexitn(2);
  1218. pop(s);
  1219. qenv(s) = a;
  1220. pop(a);
  1221. }
  1222. if (done) continue;
  1223. /*
  1224. * I permit the tracing of just one function from the kernel, and achieve
  1225. * this by installing a wrapper function in place of the real definition.
  1226. * Indeed this is just like Lisp-level embedding, except that I can get at the
  1227. * entrypoint table used by the bytecode interpreter and so trap calls made
  1228. * via there, and I can use that table to tell me how many arguments the
  1229. * traced function needed.
  1230. */
  1231. if (displaced1 == NULL)
  1232. { int nargs = funtable_nargs(table_entry);
  1233. /*
  1234. * Remember what function was being traced, so that it can eventually be
  1235. * invoked, and its name printed.
  1236. */
  1237. displaced1 = f1;
  1238. displaced2 = f2;
  1239. displacedn = fn;
  1240. tracedfn = s;
  1241. /*
  1242. * This makes calls via the regular interpreter see the traced version...
  1243. */
  1244. set_fns(s, traced1_function, traced2_function,
  1245. tracedn_function);
  1246. table_entry = find_built_in_function(f1, f2, fn);
  1247. nargs = funtable_nargs(table_entry);
  1248. table_entry = funtable_index(table_entry);
  1249. if (nargs != NOT_FOUND)
  1250. {
  1251. /*
  1252. * .. and now I make calls via short-form bytecodes do likewise.
  1253. */
  1254. switch (nargs)
  1255. {
  1256. default:
  1257. case 0: zero_arg_functions[funtable_index(table_entry)] =
  1258. tracedn_function;
  1259. break;
  1260. case 1: one_arg_functions[funtable_index(table_entry)] =
  1261. traced1_function;
  1262. break;
  1263. case 2: two_arg_functions[funtable_index(table_entry)] =
  1264. traced2_function;
  1265. break;
  1266. case 3: three_arg_functions[funtable_index(table_entry)] =
  1267. tracedn_function;
  1268. break;
  1269. }
  1270. }
  1271. }
  1272. continue;
  1273. }
  1274. }
  1275. return onevalue(a);
  1276. }
  1277. Lisp_Object Luntrace(Lisp_Object nil, Lisp_Object a)
  1278. {
  1279. Lisp_Object w = a;
  1280. CSL_IGNORE(nil);
  1281. if (symbolp(a))
  1282. { a = ncons(a);
  1283. errexit();
  1284. w = a;
  1285. }
  1286. while (consp(w))
  1287. { Lisp_Object s = qcar(w);
  1288. w = qcdr(w);
  1289. if (symbolp(s))
  1290. { one_args *f1 = qfn1(s);
  1291. two_args *f2 = qfn2(s);
  1292. n_args *fn = qfnn(s);
  1293. if (f1 == traceinterpreted1)
  1294. { set_fns(a, interpreted1, interpreted2, interpretedn);
  1295. qenv(s) = qcdr(qenv(s));
  1296. }
  1297. else if (f1 == tracefunarged1)
  1298. { set_fns(s, funarged1, funarged2, funargedn);
  1299. qenv(s) = qcdr(qenv(s));
  1300. }
  1301. if (f1 == tracebytecoded1) ifn1(s) = (int32)bytecoded1;
  1302. if (f2 == tracebytecoded2) ifn2(s) = (int32)bytecoded2;
  1303. if (fn == tracebytecoded0) ifnn(s) = (int32)bytecoded0;
  1304. if (fn == tracebytecoded3) ifnn(s) = (int32)bytecoded3;
  1305. if (fn == tracebytecodedn) ifnn(s) = (int32)bytecodedn;
  1306. if (f1 == tracebyteopt1) ifn1(s) = (int32)byteopt1;
  1307. if (f2 == tracebyteopt2) ifn2(s) = (int32)byteopt2;
  1308. if (fn == tracebyteoptn) ifnn(s) = (int32)byteoptn;
  1309. if (f1 == tracebyteoptrest1) ifn1(s) = (int32)byteoptrest1;
  1310. if (f2 == tracebyteoptrest2) ifn2(s) = (int32)byteoptrest2;
  1311. if (fn == tracebyteoptrestn) ifnn(s) = (int32)byteoptrestn;
  1312. if (f1 == tracehardopt1) ifn1(s) = (int32)hardopt1;
  1313. if (f2 == tracehardopt2) ifn2(s) = (int32)hardopt2;
  1314. if (fn == tracehardoptn) ifnn(s) = (int32)hardoptn;
  1315. if (f1 == tracehardoptrest1) ifn1(s) = (int32)hardoptrest1;
  1316. if (f2 == tracehardoptrest2) ifn2(s) = (int32)hardoptrest2;
  1317. if (fn == tracehardoptrestn) ifnn(s) = (int32)hardoptrestn;
  1318. if (f1 == traced1_function)
  1319. { int nargs = funtable_nargs(table_entry);
  1320. set_fns(s, displaced1, displaced2, displacedn);
  1321. if (nargs != NOT_FOUND)
  1322. switch (nargs)
  1323. {
  1324. default:
  1325. case 0: zero_arg_functions[funtable_index(table_entry)] =
  1326. displacedn;
  1327. break;
  1328. case 1: one_arg_functions[funtable_index(table_entry)] =
  1329. displaced1;
  1330. break;
  1331. case 2: two_arg_functions[funtable_index(table_entry)] =
  1332. displaced2;
  1333. break;
  1334. case 3: three_arg_functions[funtable_index(table_entry)] =
  1335. displacedn;
  1336. break;
  1337. }
  1338. displaced1 = NULL;
  1339. displaced2 = NULL;
  1340. displacedn = NULL;
  1341. }
  1342. qheader(s) &= ~SYM_TRACED;
  1343. }
  1344. }
  1345. return onevalue(a);
  1346. }
  1347. Lisp_Object Ldouble(Lisp_Object nil, Lisp_Object a)
  1348. {
  1349. Lisp_Object w = a;
  1350. if (symbolp(a))
  1351. { a = ncons(a);
  1352. errexit();
  1353. w = a;
  1354. }
  1355. while (consp(w))
  1356. { Lisp_Object s = qcar(w);
  1357. w = qcdr(w);
  1358. if (symbolp(s))
  1359. { one_args *f1 = qfn1(s);
  1360. two_args *f2 = qfn2(s);
  1361. n_args *fn = qfnn(s);
  1362. int fixenv = 0, done = 0;
  1363. if (f1 == undefined1) continue;
  1364. if (f1 == interpreted1)
  1365. { set_fns(s, double_interpreted1, double_interpreted2, double_interpretedn);
  1366. fixenv = done = 1;
  1367. }
  1368. if (f1 == funarged1)
  1369. { set_fns(s, double_funarged1, double_funarged2, double_funargedn);
  1370. fixenv = done = 1;
  1371. }
  1372. if (fn == bytecoded0) ifnn(s) = (int32)double_bytecoded0, done = 1;
  1373. if (f1 == bytecoded1) ifn1(s) = (int32)double_bytecoded1, done = 1;
  1374. if (f2 == bytecoded2) ifn2(s) = (int32)double_bytecoded2, done = 1;
  1375. if (fn == bytecoded3) ifnn(s) = (int32)double_bytecoded3, done = 1;
  1376. if (fn == bytecodedn) ifnn(s) = (int32)double_bytecodedn, done = 1;
  1377. if (f1 == byteopt1) ifn1(s) = (int32)double_byteopt1, done = 1;
  1378. if (f2 == byteopt2) ifn2(s) = (int32)double_byteopt2, done = 1;
  1379. if (fn == byteoptn) ifnn(s) = (int32)double_byteoptn, done = 1;
  1380. if (f1 == hardopt1) ifn1(s) = (int32)double_hardopt1, done = 1;
  1381. if (f2 == hardopt2) ifn2(s) = (int32)double_hardopt2, done = 1;
  1382. if (fn == hardoptn) ifnn(s) = (int32)double_hardoptn, done = 1;
  1383. if (f1 == byteoptrest1) ifn1(s) = (int32)double_byteoptrest1, done = 1;
  1384. if (f2 == byteoptrest2) ifn2(s) = (int32)double_byteoptrest2, done = 1;
  1385. if (fn == byteoptrestn) ifnn(s) = (int32)double_byteoptrestn, done = 1;
  1386. if (f1 == hardoptrest1) ifn1(s) = (int32)double_hardoptrest1, done = 1;
  1387. if (f2 == hardoptrest2) ifn2(s) = (int32)double_hardoptrest2, done = 1;
  1388. if (fn == hardoptrestn) ifnn(s) = (int32)double_hardoptrestn, done = 1;
  1389. if (fixenv)
  1390. { push2(a, s);
  1391. a = cons(s, qenv(s));
  1392. errexitn(2);
  1393. pop(s);
  1394. qenv(s) = a;
  1395. pop(a);
  1396. }
  1397. if (done) continue;
  1398. debug_printf("Unable to execution-double: "); loop_print_debug(s);
  1399. trace_printf("\n");
  1400. continue;
  1401. }
  1402. }
  1403. return onevalue(a);
  1404. }
  1405. Lisp_Object Lundouble(Lisp_Object nil, Lisp_Object a)
  1406. {
  1407. Lisp_Object w = a;
  1408. CSL_IGNORE(nil);
  1409. if (symbolp(a))
  1410. { a = ncons(a);
  1411. errexit();
  1412. w = a;
  1413. }
  1414. while (consp(w))
  1415. { Lisp_Object s = qcar(w);
  1416. w = qcdr(w);
  1417. if (symbolp(s))
  1418. { one_args *f1 = qfn1(s);
  1419. two_args *f2 = qfn2(s);
  1420. n_args *fn = qfnn(s);
  1421. if (f1 == double_interpreted1)
  1422. { set_fns(a, interpreted1, interpreted2, interpretedn);
  1423. qenv(s) = qcdr(qenv(s));
  1424. }
  1425. else if (f1 == double_funarged1)
  1426. { set_fns(s, funarged1, funarged2, funargedn);
  1427. qenv(s) = qcdr(qenv(s));
  1428. }
  1429. else if (f1 == double_bytecoded1) ifn1(s) = (int32)bytecoded1;
  1430. else if (f2 == double_bytecoded2) ifn2(s) = (int32)bytecoded2;
  1431. else if (fn == double_bytecoded0) ifnn(s) = (int32)bytecoded0;
  1432. else if (fn == double_bytecoded3) ifnn(s) = (int32)bytecoded3;
  1433. else if (fn == double_bytecodedn) ifnn(s) = (int32)bytecodedn;
  1434. else if (f1 == double_byteopt1) ifn1(s) = (int32)byteopt1;
  1435. else if (f2 == double_byteopt2) ifn2(s) = (int32)byteopt2;
  1436. else if (fn == double_byteoptn) ifnn(s) = (int32)byteoptn;
  1437. else if (f1 == double_byteoptrest1) ifn1(s) = (int32)byteoptrest1;
  1438. else if (f2 == double_byteoptrest2) ifn2(s) = (int32)byteoptrest2;
  1439. else if (fn == double_byteoptrestn) ifnn(s) = (int32)byteoptrestn;
  1440. else if (f1 == double_hardopt1) ifn1(s) = (int32)hardopt1;
  1441. else if (f2 == double_hardopt2) ifn2(s) = (int32)hardopt2;
  1442. else if (fn == double_hardoptn) ifnn(s) = (int32)hardoptn;
  1443. else if (f1 == double_hardoptrest1) ifn1(s) = (int32)hardoptrest1;
  1444. else if (f2 == double_hardoptrest2) ifn2(s) = (int32)hardoptrest2;
  1445. else if (fn == double_hardoptrestn) ifnn(s) = (int32)hardoptrestn;
  1446. }
  1447. }
  1448. return onevalue(a);
  1449. }
  1450. Lisp_Object Lmacro_function(Lisp_Object nil, Lisp_Object a)
  1451. {
  1452. if (!symbolp(a)) return onevalue(nil);
  1453. else if ((qheader(a) & SYM_MACRO) == 0) return onevalue(nil);
  1454. /* If the MACRO bit is set in the header I know there is a definition */
  1455. else return onevalue(cons(lambda, qenv(a)));
  1456. }
  1457. Lisp_Object get_pname(Lisp_Object a)
  1458. {
  1459. Lisp_Object name = qpname(a);
  1460. #ifndef COMMON
  1461. /*
  1462. * When a gensym is first created its pname field points at a string that
  1463. * will form the base of its name, and a magic bit is set in its header.
  1464. * If at some stage it is necessary to inspect the print name (mainly in
  1465. * order to print the symbol) it becomes necessary to create a new string
  1466. * and insert a serial number. Doing things this way means that the serial
  1467. * numbers that users see will tend to be smaller, and space for per-gensym
  1468. * strings does not get allocated unless really needed. The down side is
  1469. * that every time I want to grab the pname of anything I have to check for
  1470. * this case and admit the possibility of garbage collection or even
  1471. * failure.
  1472. */
  1473. if (qheader(a) & SYM_UNPRINTED_GENSYM)
  1474. { unsigned32 len;
  1475. Lisp_Object nil = C_nil;
  1476. char genname[64];
  1477. len = length_of_header(vechdr(name)) - 4;
  1478. if (len > 60) len = 60; /* Unpublished truncation of the string */
  1479. sprintf(genname, "%.*s%lu", (int)len,
  1480. (char *)name + (4 - TAG_VECTOR), (long)gensym_ser++);
  1481. push(a);
  1482. name = make_string(genname);
  1483. pop(a);
  1484. errexit();
  1485. qpname(a) = name;
  1486. qheader(a) &= ~SYM_UNPRINTED_GENSYM;
  1487. }
  1488. #endif
  1489. return name;
  1490. }
  1491. Lisp_Object Lsymbol_name(Lisp_Object nil, Lisp_Object a)
  1492. {
  1493. if (!symbolp(a)) return aerror1("symbol-name", a);
  1494. a = get_pname(a);
  1495. errexit();
  1496. return onevalue(a);
  1497. }
  1498. #ifdef COMMON
  1499. Lisp_Object Lsymbol_package(Lisp_Object nil, Lisp_Object a)
  1500. {
  1501. if (!symbolp(a)) return aerror1("symbol-package", a);
  1502. a = qpackage(a);
  1503. return onevalue(a);
  1504. }
  1505. #endif
  1506. static Lisp_Object Lrestart_csl2(Lisp_Object nil,
  1507. Lisp_Object a, Lisp_Object b)
  1508. /*
  1509. * If the argument is given as nil then this is a cold-start, and when
  1510. * I begin again it would be a VERY good idea to do a (load!-module 'compat)
  1511. * rather promptly (otherwise some Lisp functions will not work at all).
  1512. * I do not automate that because this function is intended for use in
  1513. * delicate system rebuilding contexts and I want the user to have ultimate
  1514. * control. (restart!-csl t) reloads a heap-image in the normal way.
  1515. * (restart!-csl 'xx) where xx is neither nil nor t starts by reloading a
  1516. * heap image, but then it looks for a function with the same name as xx
  1517. * (since a heap image is reloaded it is NOT easy (possible?) to keep the
  1518. * symbol) and calls it as a function. Finally the case
  1519. * (restart!-csl '(module fn)) restart the system, then calls load-module
  1520. * on the named module and finally calls the given restart function.
  1521. * This last option can be useful since otherwise the function to be called
  1522. * in (restart!-csl 'xx) would need to be in the base image as re-loaded.
  1523. */
  1524. {
  1525. int n;
  1526. char *v;
  1527. #ifdef SOCKETS
  1528. /*
  1529. * Security measure - deny restart-csl to remote users
  1530. */
  1531. if (socket_server != 0) return aerror("restart-csl");
  1532. #endif
  1533. n = 0;
  1534. v = NULL;
  1535. /*
  1536. * A comment seems in order here. The case b==SPID_NOARG should only
  1537. * arise if I came from Lrestart_csl: it indicates that there was
  1538. * no second argument provided.
  1539. */
  1540. if (b != SPID_NOARG)
  1541. { Lisp_Object b1 = b = Lexploden(nil, b);
  1542. errexit();
  1543. while (b1 != nil)
  1544. { n++; /* number of chars of arg */
  1545. b1 = qcdr(b1);
  1546. }
  1547. v = (char *)malloc(n+1);
  1548. if (v == NULL) return aerror("space exhausted in restart-csl");
  1549. n = 0;
  1550. while (b != nil)
  1551. { v[n++] = int_of_fixnum(qcar(b));
  1552. b = qcdr(b);
  1553. }
  1554. v[n] = 0;
  1555. }
  1556. term_printf("\nThe system is about to do a restart...\n");
  1557. /* Almost all unpicking of the argument is done back in csl.c */
  1558. exit_value = a;
  1559. exit_tag = fixnum_of_int(2); /* Flag to say "restart" */
  1560. exit_reason = UNWIND_RESTART;
  1561. exit_charvec = v;
  1562. flip_exception();
  1563. return nil;
  1564. }
  1565. static Lisp_Object Lrestart_csl(Lisp_Object nil, Lisp_Object a)
  1566. {
  1567. return Lrestart_csl2(nil, a, SPID_NOARG);
  1568. }
  1569. static Lisp_Object Lpreserve(Lisp_Object nil,
  1570. Lisp_Object startup, Lisp_Object banner)
  1571. /*
  1572. * (preserve <startup-fn>) saves a Lisp image in a standard place
  1573. * and arranges that when restarted the saved image will call the specified
  1574. * startup function. In the process of doing all this it unwinds down to
  1575. * the top level of Lisp. If a startup function is not given then the
  1576. * previously active one is used. If nil is specified then the previously
  1577. * active startup function is retained. If banner is non-nil (well really
  1578. * I want a string) is is a message of up to 40 characters to display
  1579. * when the system restart.
  1580. */
  1581. {
  1582. char filename[LONGEST_LEGAL_FILENAME];
  1583. CSLbool failed;
  1584. #ifdef SOCKETS
  1585. /*
  1586. * Security measure - deny preserve to remote users
  1587. */
  1588. if (socket_server != 0) return aerror("preserve");
  1589. #endif
  1590. if (startup != nil) supervisor = startup;
  1591. failed = Iwriterootp(filename); /* Can I open image file for writing? */
  1592. term_printf("\nThe system will be preserved on file \"%s\"\n", filename);
  1593. if (failed) return aerror("preserve");
  1594. exit_count = 0;
  1595. nil = C_nil;
  1596. exit_value = banner;
  1597. exit_tag = fixnum_of_int(1); /* Flag to say "preserve" */
  1598. exit_reason = UNWIND_RESTART;
  1599. flip_exception();
  1600. return nil;
  1601. }
  1602. static Lisp_Object MS_CDECL Lpreserve_0(Lisp_Object nil, int nargs, ...)
  1603. {
  1604. argcheck(nargs, 0, "preserve");
  1605. return Lpreserve(nil, nil, nil);
  1606. }
  1607. static Lisp_Object Lpreserve_1(Lisp_Object nil, Lisp_Object startup)
  1608. {
  1609. return Lpreserve(nil, startup, nil);
  1610. }
  1611. /*
  1612. * This is an experimental addition - a version of PRESERVE that allows
  1613. * CSL to continue executing after it has written out an image file.
  1614. */
  1615. static Lisp_Object Lcheckpoint(Lisp_Object nil,
  1616. Lisp_Object startup, Lisp_Object banner)
  1617. {
  1618. char filename[LONGEST_LEGAL_FILENAME];
  1619. CSLbool failed = 0;
  1620. char *msg = "";
  1621. #ifdef SOCKETS
  1622. /*
  1623. * Security measure - deny checkpoint to remote users
  1624. */
  1625. if (socket_server != 0) return aerror("checkpoint");
  1626. #endif
  1627. if (startup != nil) supervisor = startup;
  1628. failed = Iwriterootp(filename); /* Can I open image file for writing? */
  1629. term_printf("\nThe system will be preserved on file \"%s\"\n", filename);
  1630. if (failed) return aerror("checkpoint");
  1631. if (is_vector(banner) &&
  1632. type_of_header(vechdr(banner)) == TYPE_STRING)
  1633. msg = &celt(banner, 0);
  1634. /*
  1635. * Note, with some degree of nervousness, that things on the C stack will
  1636. * be updated by the garbage collection that happens during the processing
  1637. * of the call to preserve(), but they will be neither adjusted into
  1638. * relative addresses nor unadjusted (and hence restored) by in the
  1639. * image-writing. But the image writing will not actually move any data
  1640. * around so all is still OK, I hope!
  1641. */
  1642. push5(codevec, litvec, catch_tags, faslvec, faslgensyms);
  1643. preserve(msg);
  1644. nil = C_nil;
  1645. if (exception_pending()) failed = 1, flip_exception();
  1646. adjust_all();
  1647. pop5(faslgensyms, faslvec, catch_tags, litvec, codevec);
  1648. eq_hash_tables = eq_hash_table_list;
  1649. equal_hash_tables = equal_hash_table_list;
  1650. eq_hash_table_list = equal_hash_table_list = nil;
  1651. { Lisp_Object qq;
  1652. for (qq = eq_hash_tables; qq!=nil; qq=qcdr(qq))
  1653. rehash_this_table(qcar(qq));
  1654. for (qq = equal_hash_tables; qq!=nil; qq=qcdr(qq))
  1655. rehash_this_table(qcar(qq));
  1656. }
  1657. set_up_functions(YES);
  1658. if (failed) return aerror("checkpoint");
  1659. return onevalue(nil);
  1660. }
  1661. static Lisp_Object MS_CDECL Lcheckpoint_0(Lisp_Object nil, int nargs, ...)
  1662. {
  1663. argcheck(nargs, 0, "checkpoint");
  1664. return Lcheckpoint(nil, nil, nil);
  1665. }
  1666. static Lisp_Object Lcheckpoint_1(Lisp_Object nil, Lisp_Object startup)
  1667. {
  1668. return Lcheckpoint(nil, startup, nil);
  1669. }
  1670. #ifdef COMMON
  1671. static CSLbool eql_numbers(Lisp_Object a, Lisp_Object b)
  1672. /*
  1673. * This is only called from eql, and then only when a and b are both tagged
  1674. * as ratios or complex numbers.
  1675. */
  1676. {
  1677. Lisp_Object p, q;
  1678. p = *(Lisp_Object *)(a + (4 - TAG_NUMBERS));
  1679. q = *(Lisp_Object *)(b + (4 - TAG_NUMBERS));
  1680. if (!eql(p, q)) return NO;
  1681. p = *(Lisp_Object *)(a + (8 - TAG_NUMBERS));
  1682. q = *(Lisp_Object *)(b + (8 - TAG_NUMBERS));
  1683. return eql(p, q);
  1684. }
  1685. #endif
  1686. CSLbool eql_fn(Lisp_Object a, Lisp_Object b)
  1687. /*
  1688. * This seems incredible - all the messing about that is needed to
  1689. * check that numeric values compare properly. Ugh.
  1690. */
  1691. {
  1692. /*
  1693. * (these tests done before eql_fn is called).
  1694. * if (a == b) return YES;
  1695. * if ((((int32)a ^ (int32)b) & TAG_BITS) != 0) return NO;
  1696. *
  1697. * Actually in Common Lisp mode where I have short floats as immediate data
  1698. * I have further pain here with (eql 0.0 -0.0).
  1699. */
  1700. #ifdef COMMON
  1701. if ((a == TAG_SFLOAT && b == (TAG_SFLOAT|0x80000000)) ||
  1702. (a == (TAG_SFLOAT|0x80000000) && b == TAG_SFLOAT) return YES;
  1703. #endif
  1704. if (!is_number(a) || is_immed_or_cons(a)) return NO;
  1705. if (is_bfloat(a))
  1706. { Header h = flthdr(a);
  1707. if (h != flthdr(b)) return NO;
  1708. h = length_of_header(h);
  1709. #ifdef COMMON
  1710. if (h == 8) /* Single float */
  1711. {
  1712. #ifdef OLD_CODE
  1713. if (*(int32 *)(a + (4 - TAG_BOXFLOAT)) !=
  1714. *(int32 *)(b + (4 - TAG_BOXFLOAT))) return NO;
  1715. else return YES;
  1716. #else
  1717. return (single_float_val(a) == single_float_val(b));
  1718. #endif
  1719. }
  1720. else
  1721. #endif
  1722. /*
  1723. * For the moment I view all non-single floats as double floats. Extra
  1724. * stuff will be needed here if I ever implement long floats as 3-word
  1725. * objects.
  1726. */
  1727. {
  1728. #ifdef OLD_CODE
  1729. if ((*(int32 *)((char *)a + (8 - TAG_BOXFLOAT)) !=
  1730. *(int32 *)((char *)b + (8 - TAG_BOXFLOAT))) ||
  1731. (*(int32 *)((char *)a + (12 - TAG_BOXFLOAT)) !=
  1732. *(int32 *)((char *)b + (12 - TAG_BOXFLOAT)))) return NO;
  1733. else return YES;
  1734. #else
  1735. return (double_float_val(a) == double_float_val(b));
  1736. #endif
  1737. }
  1738. }
  1739. else /* ratio, complex or bignum */
  1740. { Header h = numhdr(a);
  1741. if (h != numhdr(b)) return NO;
  1742. if (type_of_header(h) == TYPE_BIGNUM)
  1743. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  1744. while (hh > (4 - TAG_NUMBERS))
  1745. { hh -= 4;
  1746. if (*(Lisp_Object *)((char *)a + hh) !=
  1747. *(Lisp_Object *)((char *)b + hh))
  1748. return NO;
  1749. }
  1750. return YES;
  1751. }
  1752. #ifdef COMMON
  1753. else return eql_numbers(a, b);
  1754. #else
  1755. else return NO;
  1756. #endif
  1757. }
  1758. }
  1759. static CSLbool cl_vec_equal(Lisp_Object a, Lisp_Object b)
  1760. /*
  1761. * here a and b are known to be vectors or arrays. This should compare
  1762. * them following the Common Lisp recipe, where strings or bitvectors
  1763. * (simple or complex) have their contents compared, while all other types of
  1764. * vector or array are tested using EQ.
  1765. */
  1766. {
  1767. Header ha = vechdr(a), hb = vechdr(b);
  1768. int32 offa = 0, offb = 0;
  1769. int ta = type_of_header(ha), tb = type_of_header(hb);
  1770. int32 la = length_of_header(ha), lb = length_of_header(hb);
  1771. #ifdef COMMON
  1772. if (header_of_bitvector(ha)) ta = TYPE_BITVEC1;
  1773. if (header_of_bitvector(hb)) tb = TYPE_BITVEC1;
  1774. #endif
  1775. switch (ta)
  1776. {
  1777. /*
  1778. case TYPE_ARRAY:
  1779. /* My moan here is that, as noted above, I ought to process even
  1780. * non-simple strings and bit-vectors by comparing contents, but as a
  1781. * matter of idleness I have not yet got around to that. In fact if I get
  1782. * arrays to compare here I will pretend that they are not strings or
  1783. * bit-vectors and compare using EQ...
  1784. */
  1785. case TYPE_STRING:
  1786. switch (tb)
  1787. {
  1788. /* /*
  1789. case TYPE_ARRAY:
  1790. */
  1791. case TYPE_STRING:
  1792. goto compare_strings;
  1793. default:return NO;
  1794. }
  1795. #ifdef COMMON
  1796. case TYPE_BITVEC1:
  1797. switch (tb)
  1798. {
  1799. /* /*
  1800. case TYPE_ARRAY:
  1801. */
  1802. case TYPE_BITVEC1:
  1803. goto compare_bits;
  1804. default:return NO;
  1805. }
  1806. #endif
  1807. default: return (a == b);
  1808. }
  1809. compare_strings:
  1810. if (la != lb) return NO;
  1811. while (la > 0)
  1812. { la--;
  1813. if (*((char *)a + la + offa - TAG_VECTOR) !=
  1814. *((char *)b + la + offb - TAG_VECTOR)) return NO;
  1815. }
  1816. return YES;
  1817. #ifdef COMMON
  1818. compare_bits:
  1819. if (la != lb) return NO;
  1820. while (la > 0)
  1821. { la--;
  1822. if (*((char *)a + la + offa - TAG_VECTOR) !=
  1823. *((char *)b + la + offb - TAG_VECTOR)) return NO;
  1824. }
  1825. return YES;
  1826. #endif
  1827. }
  1828. CSLbool cl_equal_fn(Lisp_Object a, Lisp_Object b)
  1829. /*
  1830. * a and b are not EQ at this stage.. I guarantee to have checked that
  1831. * before entering this general purpose code.
  1832. */
  1833. {
  1834. Lisp_Object nil = C_nil;
  1835. CSL_IGNORE(nil);
  1836. /*
  1837. * The for loop at the top here is so that cl_equal can iterate along the
  1838. * length of linear lists.
  1839. */
  1840. #ifdef CHECK_STACK
  1841. if (check_stack(__FILE__,__LINE__))
  1842. { err_printf("Stack too deep in cl_equal\n");
  1843. my_exit(EXIT_FAILURE);
  1844. }
  1845. #endif
  1846. for (;;)
  1847. {
  1848. int32 ta = (int32)a & TAG_BITS;
  1849. if (ta == TAG_CONS
  1850. #ifdef COMMON
  1851. && a != nil
  1852. #endif
  1853. )
  1854. { if (!consp(b)
  1855. #ifdef COMMON
  1856. || b == nil
  1857. #endif
  1858. ) return NO;
  1859. else
  1860. { Lisp_Object ca = qcar(a), cb = qcar(b);
  1861. if (ca == cb)
  1862. { a = qcdr(a);
  1863. b = qcdr(b);
  1864. if (a == b) return YES;
  1865. continue;
  1866. }
  1867. /*
  1868. * And here, because cl_equal() seems to be a very important low-level
  1869. * primitive, I unwind one level of the recursion that would arise
  1870. * with nested lists.
  1871. */
  1872. for (;;)
  1873. {
  1874. int32 tca = (int32)ca & TAG_BITS;
  1875. if (tca == TAG_CONS
  1876. #ifdef COMMON
  1877. && ca != nil
  1878. #endif
  1879. )
  1880. { if (!consp(cb)
  1881. #ifdef COMMON
  1882. || cb == nil
  1883. #endif
  1884. ) return NO;
  1885. else
  1886. { Lisp_Object cca = qcar(ca), ccb = qcar(cb);
  1887. if (cca == ccb)
  1888. { ca = qcdr(ca);
  1889. cb = qcdr(cb);
  1890. if (ca == cb) break;
  1891. continue;
  1892. }
  1893. /*
  1894. * Do a real recursion when I get down to args like
  1895. * ((x ...) ...) ((y ...) ...)
  1896. */
  1897. if (!cl_equal(cca, ccb)) return NO;
  1898. ca = qcdr(ca);
  1899. cb = qcdr(cb);
  1900. if (ca == cb) break;
  1901. continue;
  1902. }
  1903. }
  1904. else if (tca <= TAG_SYMBOL ||
  1905. ((int32)cb & TAG_BITS) != tca) return NO;
  1906. else switch (tca)
  1907. {
  1908. case TAG_NUMBERS:
  1909. { Header h = numhdr(ca);
  1910. if (h != numhdr(cb)) return NO;
  1911. if (type_of_header(h) == TYPE_BIGNUM)
  1912. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  1913. while (hh > (4 - TAG_NUMBERS))
  1914. { hh -= 4;
  1915. if (*(Lisp_Object *)((char *)ca + hh) !=
  1916. *(Lisp_Object *)((char *)cb + hh))
  1917. return NO;
  1918. }
  1919. break;
  1920. }
  1921. #ifdef COMMON
  1922. else if (!eql_numbers(ca, cb)) return NO;
  1923. else break;
  1924. #else
  1925. else return NO;
  1926. #endif
  1927. }
  1928. case TAG_VECTOR:
  1929. if (!cl_vec_equal(ca, cb)) return NO;
  1930. break;
  1931. default:
  1932. case TAG_BOXFLOAT:
  1933. { Header h = flthdr(ca);
  1934. if (h != flthdr(cb)) return NO;
  1935. h = length_of_header(h);
  1936. #ifdef COMMON
  1937. if (h == 8) /* Single float */
  1938. {
  1939. #ifdef OLD_CODE
  1940. if (*(int32 *)(ca + (4 - TAG_BOXFLOAT)) !=
  1941. *(int32 *)(cb + (4 - TAG_BOXFLOAT)))
  1942. return NO;
  1943. #else
  1944. if (single_float_val(ca) !=
  1945. single_float_val(cb)) return NO;
  1946. #endif
  1947. else break;
  1948. }
  1949. else
  1950. #endif
  1951. {
  1952. #ifdef OLD_CODE
  1953. if ((*(int32 *)((char *)ca +
  1954. (8 - TAG_BOXFLOAT)) !=
  1955. *(int32 *)((char *)cb +
  1956. (8 - TAG_BOXFLOAT))) ||
  1957. (*(int32 *)((char *)ca +
  1958. (12 - TAG_BOXFLOAT)) !=
  1959. *(int32 *)((char *)cb +
  1960. (12 - TAG_BOXFLOAT)))) return NO;
  1961. #else
  1962. if (double_float_val(ca) !=
  1963. double_float_val(cb)) return NO;
  1964. #endif
  1965. else break;
  1966. }
  1967. }
  1968. }
  1969. break; /* out of the for (;;) loop */
  1970. }
  1971. a = qcdr(a);
  1972. b = qcdr(b);
  1973. if (a == b) return YES;
  1974. continue;
  1975. }
  1976. }
  1977. else if (ta <= TAG_SYMBOL ||
  1978. ((int32)b & TAG_BITS) != ta) return NO;
  1979. else switch (ta)
  1980. {
  1981. case TAG_NUMBERS:
  1982. { Header h = numhdr(a);
  1983. if (h != numhdr(b)) return NO;
  1984. if (type_of_header(h) == TYPE_BIGNUM)
  1985. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  1986. while (hh > (4 - TAG_NUMBERS))
  1987. { hh -= 4;
  1988. if (*(Lisp_Object *)((char *)a + hh) !=
  1989. *(Lisp_Object *)((char *)b + hh))
  1990. return NO;
  1991. }
  1992. return YES;
  1993. }
  1994. #ifdef COMMON
  1995. else return eql_numbers(a, b);
  1996. #else
  1997. else return NO;
  1998. #endif
  1999. }
  2000. case TAG_VECTOR:
  2001. return cl_vec_equal(a, b);
  2002. default:
  2003. case TAG_BOXFLOAT:
  2004. { Header h = flthdr(a);
  2005. if (h != flthdr(b)) return NO;
  2006. h = length_of_header(h);
  2007. #ifdef COMMON
  2008. if (h == 8) /* Single float */
  2009. {
  2010. #ifdef OLD_CODE
  2011. if (*(int32 *)(a + (4 - TAG_BOXFLOAT)) !=
  2012. *(int32 *)(b + (4 - TAG_BOXFLOAT))) return NO;
  2013. #else
  2014. if (single_float_val(a) != single_float_val(b))
  2015. return NO;
  2016. #endif
  2017. else return YES;
  2018. }
  2019. else
  2020. #endif
  2021. /*
  2022. * For the moment I view all non-single floats as double floats. Extra
  2023. * stuff will be needed here if I ever implement long floats as 3-word
  2024. * objects.
  2025. */
  2026. {
  2027. #ifdef OLD_CODE
  2028. if ((*(int32 *)((char *)a + (8 - TAG_BOXFLOAT)) !=
  2029. *(int32 *)((char *)b + (8 - TAG_BOXFLOAT))) ||
  2030. (*(int32 *)((char *)a + (12 - TAG_BOXFLOAT)) !=
  2031. *(int32 *)((char *)b + (12 - TAG_BOXFLOAT))))
  2032. return NO;
  2033. #else
  2034. if (double_float_val(a) != double_float_val(b))
  2035. return NO;
  2036. #endif
  2037. else return YES;
  2038. }
  2039. }
  2040. }
  2041. }
  2042. }
  2043. static CSLbool vec_equal(Lisp_Object a, Lisp_Object b);
  2044. #ifdef TRACED_EQUAL
  2045. #define LOG_SIZE 10000
  2046. typedef struct equal_record
  2047. {
  2048. char file[24];
  2049. int line;
  2050. int depth;
  2051. int count;
  2052. } equal_record;
  2053. static equal_record equal_counts[LOG_SIZE];
  2054. static void record_equal(char *file, int line, int depth)
  2055. {
  2056. int hash = 169*line + depth;
  2057. char *p = file;
  2058. while (*p != 0) hash = 168*hash + (*p++ & 0xff);
  2059. hash = ((169*hash) & 0x7fffffff) % LOG_SIZE;
  2060. while (equal_counts[hash].count != 0)
  2061. { if (equal_counts[hash].line == line &&
  2062. equal_counts[hash].depth == depth &&
  2063. strncmp(equal_counts[hash].file, file, 24) == 0)
  2064. { equal_counts[hash].count++;
  2065. return;
  2066. }
  2067. hash = (hash + 1) % LOG_SIZE;
  2068. }
  2069. strncpy(equal_counts[hash].file, file, 24);
  2070. equal_counts[hash].line = line;
  2071. equal_counts[hash].depth = depth;
  2072. equal_counts[hash].count = 1;
  2073. return;
  2074. }
  2075. void dump_equals()
  2076. {
  2077. int i;
  2078. FILE *log = fopen("equal.log", "w");
  2079. if (log == NULL) log = stdout;
  2080. fprintf(log, "\nCalls to equal...\n");
  2081. for (i=0; i<LOG_SIZE; i++)
  2082. if (equal_counts[i].count != 0)
  2083. fprintf(log, "%24.24s %5d %5d %10d\n",
  2084. equal_counts[i].file, equal_counts[i].line,
  2085. equal_counts[i].depth, equal_counts[i].count);
  2086. fprintf(log, "end of counts\n");
  2087. if (log != stdout) fclose(log);
  2088. }
  2089. CSLbool traced_equal_fn(Lisp_Object a, Lisp_Object b,
  2090. char *file, int line, int depth)
  2091. /*
  2092. * a and b are not EQ at this stage.. I guarantee to have checked that
  2093. * before entering this general purpose code.
  2094. */
  2095. {
  2096. Lisp_Object nil = C_nil;
  2097. record_equal(file, line, depth);
  2098. #undef equal_fn
  2099. #define equal_fn(a, b) traced_equal_fn(a, b, file, line, depth+1)
  2100. #else
  2101. CSLbool equal_fn(Lisp_Object a, Lisp_Object b)
  2102. /*
  2103. * a and b are not EQ at this stage.. I guarantee to have checked that
  2104. * before entering this general purpose code. I will also have checked that
  2105. * the types of the two args agree, and that they are not both immediate
  2106. * date.
  2107. */
  2108. {
  2109. Lisp_Object nil = C_nil;
  2110. CSL_IGNORE(nil);
  2111. #endif
  2112. /*
  2113. * The for loop at the top here is so that equal can iterate along the
  2114. * length of linear lists.
  2115. */
  2116. #ifdef CHECK_STACK
  2117. if (check_stack(__FILE__,__LINE__))
  2118. { err_printf("Stack too deep in equal\n");
  2119. my_exit(EXIT_FAILURE);
  2120. }
  2121. #endif
  2122. for (;;)
  2123. {
  2124. int32 ta = (int32)a & TAG_BITS;
  2125. if (ta == TAG_CONS
  2126. #ifdef COMMON
  2127. && a != nil
  2128. #endif
  2129. )
  2130. { if (!consp(b)
  2131. #ifdef COMMON
  2132. || b == nil
  2133. #endif
  2134. ) return NO;
  2135. else
  2136. { Lisp_Object ca = qcar(a), cb = qcar(b);
  2137. if (ca == cb)
  2138. { a = qcdr(a);
  2139. b = qcdr(b);
  2140. if (a == b) return YES;
  2141. continue;
  2142. }
  2143. /*
  2144. * And here, because equal() seems to be a very important low-level
  2145. * primitive, I unwind one level of the recursion that would arise
  2146. * with nested lists.
  2147. */
  2148. for (;;)
  2149. {
  2150. int32 tca = (int32)ca & TAG_BITS;
  2151. if (tca == TAG_CONS
  2152. #ifdef COMMON
  2153. && ca != nil
  2154. #endif
  2155. )
  2156. { if (!consp(cb)
  2157. #ifdef COMMON
  2158. || cb == nil
  2159. #endif
  2160. ) return NO;
  2161. else
  2162. { Lisp_Object cca = qcar(ca), ccb = qcar(cb);
  2163. if (cca == ccb)
  2164. { ca = qcdr(ca);
  2165. cb = qcdr(cb);
  2166. if (ca == cb) break;
  2167. continue;
  2168. }
  2169. /*
  2170. * Do a real recursion when I get down to args like
  2171. * ((x ...) ...) ((y ...) ...)
  2172. */
  2173. if (!equal(cca, ccb)) return NO;
  2174. ca = qcdr(ca);
  2175. cb = qcdr(cb);
  2176. if (ca == cb) break;
  2177. continue;
  2178. }
  2179. }
  2180. else if (tca <= TAG_SYMBOL ||
  2181. ((int32)cb & TAG_BITS) != tca) return NO;
  2182. else switch (tca)
  2183. {
  2184. case TAG_NUMBERS:
  2185. { Header h = numhdr(ca);
  2186. if (h != numhdr(cb)) return NO;
  2187. if (type_of_header(h) == TYPE_BIGNUM)
  2188. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  2189. while (hh > (4 - TAG_NUMBERS))
  2190. { hh -= 4;
  2191. if (*(Lisp_Object *)((char *)ca + hh) !=
  2192. *(Lisp_Object *)((char *)cb + hh))
  2193. return NO;
  2194. }
  2195. break;
  2196. }
  2197. #ifdef COMMON
  2198. else if (!eql_numbers(ca, cb)) return NO;
  2199. else break;
  2200. #else
  2201. else return NO;
  2202. #endif
  2203. }
  2204. case TAG_VECTOR:
  2205. if (!vec_equal(ca, cb)) return NO;
  2206. break;
  2207. default:
  2208. case TAG_BOXFLOAT:
  2209. { Header h = flthdr(ca);
  2210. if (h != flthdr(cb)) return NO;
  2211. h = length_of_header(h);
  2212. #ifdef COMMON
  2213. if (h == 8) /* Single float */
  2214. {
  2215. #ifdef OLD_CODE
  2216. if (*(int32 *)(ca + (4 - TAG_BOXFLOAT)) !=
  2217. *(int32 *)(cb + (4 - TAG_BOXFLOAT)))
  2218. return NO;
  2219. #else
  2220. if (single_float_val(ca) !=
  2221. single_float_val(cb)) return NO;
  2222. #endif
  2223. else break;
  2224. }
  2225. else
  2226. #endif
  2227. {
  2228. #ifdef OLD_CODE
  2229. if ((*(int32 *)((char *)ca +
  2230. (8 - TAG_BOXFLOAT)) !=
  2231. *(int32 *)((char *)cb +
  2232. (8 - TAG_BOXFLOAT))) ||
  2233. (*(int32 *)((char *)ca +
  2234. (12 - TAG_BOXFLOAT)) !=
  2235. *(int32 *)((char *)cb +
  2236. (12 - TAG_BOXFLOAT)))) return NO;
  2237. #else
  2238. if (double_float_val(ca) !=
  2239. double_float_val(cb)) return NO;
  2240. #endif
  2241. else break;
  2242. }
  2243. }
  2244. }
  2245. break; /* out of the for (;;) loop */
  2246. }
  2247. a = qcdr(a);
  2248. b = qcdr(b);
  2249. if (a == b) return YES;
  2250. continue;
  2251. }
  2252. }
  2253. else if (ta <= TAG_SYMBOL ||
  2254. ((int32)b & TAG_BITS) != ta) return NO;
  2255. else switch (ta)
  2256. {
  2257. case TAG_NUMBERS:
  2258. { Header h = numhdr(a);
  2259. if (h != numhdr(b)) return NO;
  2260. if (type_of_header(h) == TYPE_BIGNUM)
  2261. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  2262. while (hh > (4 - TAG_NUMBERS))
  2263. { hh -= 4;
  2264. if (*(Lisp_Object *)((char *)a + hh) !=
  2265. *(Lisp_Object *)((char *)b + hh))
  2266. return NO;
  2267. }
  2268. return YES;
  2269. }
  2270. #ifdef COMMON
  2271. else return eql_numbers(a, b);
  2272. #else
  2273. else return NO;
  2274. #endif
  2275. }
  2276. case TAG_VECTOR:
  2277. return vec_equal(a, b);
  2278. default:
  2279. case TAG_BOXFLOAT:
  2280. { Header h = flthdr(a);
  2281. if (h != flthdr(b)) return NO;
  2282. h = length_of_header(h);
  2283. #ifdef COMMON
  2284. if (h == 8) /* Single float */
  2285. {
  2286. #ifdef OLD_CODE
  2287. if (*(int32 *)(a + (4 - TAG_BOXFLOAT)) !=
  2288. *(int32 *)(b + (4 - TAG_BOXFLOAT))) return NO;
  2289. #else
  2290. if (single_float_val(a) != single_float_val(b))
  2291. return NO;
  2292. #endif
  2293. else return YES;
  2294. }
  2295. else
  2296. #endif
  2297. /*
  2298. * For the moment I view all non-single floats as double floats. Extra
  2299. * stuff will be needed here if I ever implement long floats as 3-word
  2300. * objects.
  2301. */
  2302. {
  2303. #ifdef OLD_CODE
  2304. if ((*(int32 *)((char *)a + (8 - TAG_BOXFLOAT)) !=
  2305. *(int32 *)((char *)b + (8 - TAG_BOXFLOAT))) ||
  2306. (*(int32 *)((char *)a + (12 - TAG_BOXFLOAT)) !=
  2307. *(int32 *)((char *)b + (12 - TAG_BOXFLOAT))))
  2308. return NO;
  2309. #else
  2310. if (double_float_val(a) != double_float_val(b))
  2311. return NO;
  2312. #endif
  2313. else return YES;
  2314. }
  2315. }
  2316. }
  2317. }
  2318. }
  2319. #ifdef TRACED_EQUAL
  2320. #undef equal_fn
  2321. #define equal_fn(a, b) traced_equal(a, b, __FILE__, __LINE__, 0)
  2322. #endif
  2323. static CSLbool vec_equal(Lisp_Object a, Lisp_Object b)
  2324. /*
  2325. * Here a and b are known to be vectors. Compare using recursive calls to
  2326. * EQUAL on all components.
  2327. */
  2328. {
  2329. Header ha = vechdr(a), hb = vechdr(b);
  2330. int32 l;
  2331. if (ha != hb) return NO;
  2332. l = (int32)doubleword_align_up(length_of_header(ha));
  2333. if (vector_holds_binary(ha))
  2334. { while ((l -= 4) != 0)
  2335. if (*((int32 *)((char *)a + l - TAG_VECTOR)) !=
  2336. *((int32 *)((char *)b + l - TAG_VECTOR))) return NO;
  2337. return YES;
  2338. }
  2339. else
  2340. { if (is_mixed_header(ha))
  2341. { while (l > 16)
  2342. { unsigned32 ea = *((unsigned32 *)((char *)a + l - TAG_VECTOR - 4)),
  2343. eb = *((unsigned32 *)((char *)b + l - TAG_VECTOR - 4));
  2344. if (ea != eb) return NO;
  2345. l -= 4;
  2346. }
  2347. }
  2348. while ((l -= 4) != 0)
  2349. { Lisp_Object ea = *((Lisp_Object *)((char *)a + l - TAG_VECTOR)),
  2350. eb = *((Lisp_Object *)((char *)b + l - TAG_VECTOR));
  2351. if (ea == eb) continue;
  2352. if (!equal(ea, eb)) return NO;
  2353. }
  2354. return YES;
  2355. }
  2356. }
  2357. CSLbool equalp(Lisp_Object a, Lisp_Object b)
  2358. /*
  2359. * a and b are not EQ at this stage.. I guarantee to have checked that
  2360. * before entering this general purpose code.
  2361. */
  2362. {
  2363. Lisp_Object nil = C_nil;
  2364. CSL_IGNORE(nil);
  2365. /*
  2366. * The for loop at the top here is so that equalp can iterate along the
  2367. * length of linear lists.
  2368. */
  2369. #ifdef CHECK_STACK
  2370. if (check_stack(__FILE__,__LINE__))
  2371. { err_printf("Stack too deep in equalp\n");
  2372. my_exit(EXIT_FAILURE);
  2373. }
  2374. #endif
  2375. for (;;)
  2376. {
  2377. int32 ta = (int32)a & TAG_BITS;
  2378. if (ta == TAG_CONS
  2379. #ifdef COMMON
  2380. && a != nil
  2381. #endif
  2382. )
  2383. { if (!consp(b)
  2384. #ifdef COMMON
  2385. || b == nil
  2386. #endif
  2387. ) return NO;
  2388. else
  2389. { Lisp_Object ca = qcar(a), cb = qcar(b);
  2390. if (ca == cb)
  2391. { a = qcdr(a);
  2392. b = qcdr(b);
  2393. if (a == b) return YES;
  2394. continue;
  2395. }
  2396. /*
  2397. * And here, because equalp() seems to be a very important low-level
  2398. * primitive, I unwind one level of the recursion that would arise
  2399. * with nested lists.
  2400. */
  2401. for (;;)
  2402. {
  2403. int32 tca = (int32)ca & TAG_BITS;
  2404. if (tca == TAG_CONS
  2405. #ifdef COMMON
  2406. && ca != nil
  2407. #endif
  2408. )
  2409. { if (!consp(cb)
  2410. #ifdef COMMON
  2411. || cb == nil
  2412. #endif
  2413. ) return NO;
  2414. else
  2415. { Lisp_Object cca = qcar(ca), ccb = qcar(cb);
  2416. if (cca == ccb)
  2417. { ca = qcdr(ca);
  2418. cb = qcdr(cb);
  2419. if (ca == cb) break;
  2420. continue;
  2421. }
  2422. /*
  2423. * Do a real recursion when I get down to args like
  2424. * ((x ...) ...) ((y ...) ...)
  2425. */
  2426. if (!equalp(cca, ccb)) return NO;
  2427. ca = qcdr(ca);
  2428. cb = qcdr(cb);
  2429. if (ca == cb) break;
  2430. continue;
  2431. }
  2432. }
  2433. else if (tca <= TAG_SYMBOL ||
  2434. ((int32)cb & TAG_BITS) != tca) return NO;
  2435. else switch (tca)
  2436. {
  2437. case TAG_NUMBERS:
  2438. { Header h = numhdr(ca);
  2439. if (h != numhdr(cb)) return NO;
  2440. if (type_of_header(h) == TYPE_BIGNUM)
  2441. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  2442. while (hh > (4 - TAG_NUMBERS))
  2443. { hh -= 4;
  2444. if (*(Lisp_Object *)((char *)ca + hh) !=
  2445. *(Lisp_Object *)((char *)cb + hh))
  2446. return NO;
  2447. }
  2448. break;
  2449. }
  2450. #ifdef COMMON
  2451. else if (!eql_numbers(ca, cb)) return NO;
  2452. else break;
  2453. #else
  2454. else return NO;
  2455. #endif
  2456. }
  2457. case TAG_VECTOR:
  2458. /* /* At present vec_equal() is not right here */
  2459. if (!vec_equal(ca, cb)) return NO;
  2460. break;
  2461. default:
  2462. case TAG_BOXFLOAT:
  2463. { Header h = flthdr(ca);
  2464. if (h != flthdr(cb)) return NO;
  2465. h = length_of_header(h);
  2466. #ifdef COMMON
  2467. if (h == 8) /* Single float */
  2468. {
  2469. #ifdef OLD_CODE
  2470. if (*(int32 *)(ca + (4 - TAG_BOXFLOAT)) !=
  2471. *(int32 *)(cb + (4 - TAG_BOXFLOAT)))
  2472. return NO;
  2473. #else
  2474. if (single_float_val(ca) !=
  2475. single_float_val(cb)) return NO;
  2476. #endif
  2477. else break;
  2478. }
  2479. else
  2480. #endif
  2481. {
  2482. #ifdef OLD_CODE
  2483. if ((*(int32 *)((char *)ca +
  2484. (8 - TAG_BOXFLOAT)) !=
  2485. *(int32 *)((char *)cb +
  2486. (8 - TAG_BOXFLOAT))) ||
  2487. (*(int32 *)((char *)ca +
  2488. (12 - TAG_BOXFLOAT)) !=
  2489. *(int32 *)((char *)cb +
  2490. (12 - TAG_BOXFLOAT)))) return NO;
  2491. #else
  2492. if (double_float_val(ca) !=
  2493. double_float_val(cb)) return NO;
  2494. #endif
  2495. else break;
  2496. }
  2497. }
  2498. }
  2499. break; /* out of the for (;;) loop */
  2500. }
  2501. a = qcdr(a);
  2502. b = qcdr(b);
  2503. if (a == b) return YES;
  2504. continue;
  2505. }
  2506. }
  2507. else if (ta <= TAG_SYMBOL ||
  2508. ((int32)b & TAG_BITS) != ta) return NO;
  2509. else switch (ta)
  2510. {
  2511. case TAG_NUMBERS:
  2512. { Header h = numhdr(a);
  2513. if (h != numhdr(b)) return NO;
  2514. if (type_of_header(h) == TYPE_BIGNUM)
  2515. { int32 hh = (int32)length_of_header(h) - TAG_NUMBERS;
  2516. while (hh > (4 - TAG_NUMBERS))
  2517. { hh -= 4;
  2518. if (*(Lisp_Object *)((char *)a + hh) !=
  2519. *(Lisp_Object *)((char *)b + hh))
  2520. return NO;
  2521. }
  2522. return YES;
  2523. }
  2524. #ifdef COMMON
  2525. else return eql_numbers(a, b);
  2526. #else
  2527. else return NO;
  2528. #endif
  2529. }
  2530. case TAG_VECTOR:
  2531. /* /* wrong for Common Lisp */
  2532. return vec_equal(a, b);
  2533. default:
  2534. case TAG_BOXFLOAT:
  2535. { Header h = flthdr(a);
  2536. if (h != flthdr(b)) return NO;
  2537. h = length_of_header(h);
  2538. #ifdef COMMON
  2539. if (h == 8) /* Single float */
  2540. {
  2541. #ifdef OLD_CODE
  2542. if (*(int32 *)(a + (4 - TAG_BOXFLOAT)) !=
  2543. *(int32 *)(b + (4 - TAG_BOXFLOAT))) return NO;
  2544. #else
  2545. if (single_float_val(a) != single_float_val(b))
  2546. return NO;
  2547. #endif
  2548. else return YES;
  2549. }
  2550. else
  2551. #endif
  2552. /*
  2553. * For the moment I view all non-single floats as double floats. Extra
  2554. * stuff will be needed here if I ever implement long floats as 3-word
  2555. * objects.
  2556. */
  2557. {
  2558. #ifdef OLD_CODE
  2559. if ((*(int32 *)((char *)a + (8 - TAG_BOXFLOAT)) !=
  2560. *(int32 *)((char *)b + (8 - TAG_BOXFLOAT))) ||
  2561. (*(int32 *)((char *)a + (12 - TAG_BOXFLOAT)) !=
  2562. *(int32 *)((char *)b + (12 - TAG_BOXFLOAT))))
  2563. return NO;
  2564. #else
  2565. if (double_float_val(a) != double_float_val(b))
  2566. return NO;
  2567. #endif
  2568. else return YES;
  2569. }
  2570. }
  2571. }
  2572. }
  2573. }
  2574. Lisp_Object Leq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2575. {
  2576. return onevalue(Lispify_predicate(a == b));
  2577. }
  2578. Lisp_Object Leql(Lisp_Object nil,
  2579. Lisp_Object a, Lisp_Object b)
  2580. {
  2581. return onevalue(Lispify_predicate(eql(a, b)));
  2582. }
  2583. Lisp_Object Leqcar(Lisp_Object nil,
  2584. Lisp_Object a, Lisp_Object b)
  2585. {
  2586. if (!consp(a)) return onevalue(nil);
  2587. a = qcar(a);
  2588. #ifdef COMMON
  2589. return onevalue(Lispify_predicate(eql(a, b)));
  2590. #else
  2591. return onevalue(Lispify_predicate(a == b));
  2592. #endif
  2593. }
  2594. Lisp_Object Lequalcar(Lisp_Object nil,
  2595. Lisp_Object a, Lisp_Object b)
  2596. {
  2597. if (!consp(a)) return onevalue(nil);
  2598. a = qcar(a);
  2599. if (a == b) return lisp_true;
  2600. else return onevalue(Lispify_predicate(equal(a, b)));
  2601. }
  2602. Lisp_Object Lcl_equal(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2603. {
  2604. if (a == b) return onevalue(lisp_true);
  2605. else return onevalue(Lispify_predicate(cl_equal(a, b)));
  2606. }
  2607. Lisp_Object Lequal(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2608. {
  2609. if (a == b) return onevalue(lisp_true);
  2610. else return onevalue(Lispify_predicate(equal(a, b)));
  2611. }
  2612. Lisp_Object Lequalp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2613. {
  2614. if (a == b) return onevalue(lisp_true);
  2615. else return onevalue(Lispify_predicate(equalp(a, b)));
  2616. }
  2617. Lisp_Object Lneq(Lisp_Object nil,
  2618. Lisp_Object a, Lisp_Object b)
  2619. {
  2620. CSLbool r;
  2621. #ifdef COMMON
  2622. r = cl_equal(a, b);
  2623. #else
  2624. r = equal(a, b);
  2625. #endif
  2626. return onevalue(Lispify_predicate(!r));
  2627. }
  2628. Lisp_Object Lnull(Lisp_Object nil, Lisp_Object a)
  2629. {
  2630. return onevalue(Lispify_predicate(a == nil));
  2631. }
  2632. Lisp_Object Lendp(Lisp_Object nil, Lisp_Object a)
  2633. {
  2634. if (a == nil) return onevalue(lisp_true);
  2635. else if (is_cons(a)) return onevalue(nil);
  2636. else return error(1, err_bad_endp, a);
  2637. }
  2638. Lisp_Object Lnreverse(Lisp_Object nil, Lisp_Object a)
  2639. {
  2640. Lisp_Object b = nil;
  2641. #ifdef COMMON
  2642. if (is_vector(a))
  2643. { int32 n = Llength(nil, a) - 0x10;
  2644. int32 i = TAG_FIXNUM;
  2645. while (n > i)
  2646. { Lisp_Object w = Laref2(nil, a, i);
  2647. Laset(nil, 3, a, i, Laref2(nil, a, n));
  2648. Laset(nil, 3, a, n, w);
  2649. i += 0x10;
  2650. n -= 0x10;
  2651. }
  2652. return onevalue(a);
  2653. }
  2654. #endif
  2655. while (consp(a))
  2656. { Lisp_Object c = a;
  2657. a = qcdr(a);
  2658. qcdr(c) = b;
  2659. b = c;
  2660. }
  2661. return onevalue(b);
  2662. }
  2663. #ifdef COMMON
  2664. /*
  2665. * nreverse0 is like nreverse except that if its input is atomic it gets
  2666. * returned intact rather than being converted to nil.
  2667. */
  2668. Lisp_Object Lnreverse0(Lisp_Object nil, Lisp_Object a)
  2669. {
  2670. Lisp_Object b = nil;
  2671. if (!consp(a)) return onevalue(a);
  2672. b = a;
  2673. a = qcdr(a);
  2674. qcdr(b) = nil;
  2675. while (consp(a))
  2676. { Lisp_Object c = a;
  2677. a = qcdr(a);
  2678. qcdr(c) = b;
  2679. b = c;
  2680. }
  2681. return onevalue(b);
  2682. }
  2683. #endif
  2684. Lisp_Object Lreverse(Lisp_Object nil, Lisp_Object a)
  2685. {
  2686. Lisp_Object r;
  2687. stackcheck1(0, a);
  2688. nil = C_nil;
  2689. r = nil;
  2690. while (consp(a))
  2691. { push(a);
  2692. r = cons(qcar(a), r);
  2693. pop(a);
  2694. errexit();
  2695. a = qcdr(a);
  2696. }
  2697. return onevalue(r);
  2698. }
  2699. Lisp_Object Lassoc(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2700. {
  2701. #ifdef TRACED_EQUAL
  2702. Lisp_Object save_b = b;
  2703. int pos = 0;
  2704. #endif
  2705. if (is_symbol(a) || is_fixnum(a))
  2706. { while (consp(b))
  2707. { Lisp_Object c = qcar(b);
  2708. if (consp(c) && a == qcar(c)) return onevalue(c);
  2709. b = qcdr(b);
  2710. }
  2711. return onevalue(nil);
  2712. }
  2713. while (consp(b))
  2714. { Lisp_Object c = qcar(b);
  2715. if (consp(c))
  2716. { Lisp_Object cc = qcar(c);
  2717. #ifdef COMMON
  2718. if (cl_equal(a, cc)) return onevalue(c);
  2719. #else
  2720. if (equal(a, cc))
  2721. {
  2722. #ifdef TRACED_EQUAL
  2723. trace_printf("Assoc YES %3d %3d ", pos, int_of_fixnum(Llength(nil,save_b)));
  2724. prin_to_stdout(a); trace_printf("\n");
  2725. #endif
  2726. return onevalue(c);
  2727. }
  2728. #endif
  2729. }
  2730. b = qcdr(b);
  2731. #ifdef TRACED_EQUAL
  2732. pos++;
  2733. #endif
  2734. }
  2735. #ifdef TRACED_EQUAL
  2736. trace_printf("Assoc NO %3d %3d ", pos, int_of_fixnum(Llength(nil,save_b)));
  2737. prin_to_stdout(a); trace_printf("\n");
  2738. #endif
  2739. return onevalue(nil);
  2740. }
  2741. Lisp_Object Latsoc(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2742. {
  2743. #ifdef COMMON
  2744. if (is_symbol(a) || is_fixnum(a))
  2745. { while (consp(b))
  2746. { Lisp_Object c = qcar(b);
  2747. if (consp(c) && a == qcar(c)) return onevalue(c);
  2748. b = qcdr(b);
  2749. }
  2750. return onevalue(nil);
  2751. }
  2752. #endif
  2753. while (consp(b))
  2754. { Lisp_Object c = qcar(b);
  2755. /*
  2756. * eql() can neither fail nor call the garbage collector, so I do
  2757. * not need to stack things here.
  2758. */
  2759. #ifdef COMMON
  2760. if (consp(c) && eql(a, qcar(c))) return onevalue(c);
  2761. #else
  2762. if (consp(c) && a == qcar(c)) return onevalue(c);
  2763. #endif
  2764. b = qcdr(b);
  2765. }
  2766. return onevalue(nil);
  2767. }
  2768. Lisp_Object Lmember(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2769. {
  2770. if (is_symbol(a) || is_fixnum(a))
  2771. { while (consp(b))
  2772. { if (a == qcar(b)) return onevalue(b);
  2773. b = qcdr(b);
  2774. }
  2775. return onevalue(nil);
  2776. }
  2777. while (consp(b))
  2778. { Lisp_Object cb = qcar(b);
  2779. #ifdef COMMON
  2780. if (cl_equal(a, cb)) return onevalue(b);
  2781. #else
  2782. if (equal(a, cb)) return onevalue(b);
  2783. #endif
  2784. b = qcdr(b);
  2785. }
  2786. return onevalue(nil);
  2787. }
  2788. Lisp_Object Lmemq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2789. {
  2790. #ifdef COMMON
  2791. if (is_symbol(a) || is_fixnum(a))
  2792. { while (consp(b))
  2793. { if (a == qcar(b)) return onevalue(b);
  2794. b = qcdr(b);
  2795. }
  2796. return onevalue(nil);
  2797. }
  2798. #endif
  2799. while (consp(b))
  2800. /*
  2801. * Note that eql() can never fail, and so checking for errors
  2802. * and stacking a and b across the call to it is not necessary.
  2803. */
  2804. {
  2805. #ifdef COMMON
  2806. if (eql(a, qcar(b))) return onevalue(b);
  2807. #else
  2808. if (a == qcar(b)) return onevalue(b);
  2809. #endif
  2810. b = qcdr(b);
  2811. }
  2812. return onevalue(nil);
  2813. }
  2814. static CSLbool smemq(Lisp_Object a, Lisp_Object b)
  2815. {
  2816. /*
  2817. * /* This is a bit worrying - it can use C recursion to arbitrary
  2818. * depth without any checking for overflow, and hence it can ESCAPE
  2819. * if (e.g.) given cyclic structures. Some alteration is needed. As
  2820. * things stand the code can never give wrong answers via GC rearrangement -
  2821. * the problem is closer to being that it can never call the GC.
  2822. */
  2823. #ifdef COMMON
  2824. Lisp_Object nil = C_nil;
  2825. #else
  2826. nil_as_base
  2827. #endif
  2828. while (consp(b))
  2829. { Lisp_Object w = qcar(b);
  2830. if (w == quote_symbol) return NO;
  2831. else if (smemq(a, w)) return YES;
  2832. else b = qcdr(b);
  2833. }
  2834. return (a == b);
  2835. }
  2836. Lisp_Object Lsmemq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2837. {
  2838. CSLbool r;
  2839. r = smemq(a, b);
  2840. errexit();
  2841. return onevalue(Lispify_predicate(r));
  2842. }
  2843. /*
  2844. * (defun contained (x y)
  2845. * (cond ((atom y) (equal x y))
  2846. * ((equal x y) 't)
  2847. * ('t (or (contained x (car y)) (contained x (cdr y))))))
  2848. */
  2849. static CSLbool containedeq(Lisp_Object nil, Lisp_Object x, Lisp_Object y)
  2850. {
  2851. while (consp(y))
  2852. { if (containedeq(nil, x, qcar(y))) return YES;
  2853. y = qcdr(y);
  2854. }
  2855. return (x == y);
  2856. }
  2857. static CSLbool containedequal(Lisp_Object nil, Lisp_Object x, Lisp_Object y)
  2858. {
  2859. while (consp(y))
  2860. { if (equal(x, y)) return YES;
  2861. if (containedequal(nil, x, qcar(y))) return YES;
  2862. y = qcdr(y);
  2863. }
  2864. return equal(x, y);
  2865. }
  2866. static Lisp_Object Lcontained(Lisp_Object nil, Lisp_Object x, Lisp_Object y)
  2867. {
  2868. CSLbool r;
  2869. if (is_symbol(x) || is_fixnum(x)) r = containedeq(nil, x, y);
  2870. else r = containedequal(nil, x, y);
  2871. errexit();
  2872. return onevalue(Lispify_predicate(r));
  2873. }
  2874. Lisp_Object Llast(Lisp_Object nil, Lisp_Object a)
  2875. {
  2876. Lisp_Object b;
  2877. if (!consp(a)) return aerror1("last", a);
  2878. while (b = qcdr(a), consp(b)) a = b;
  2879. return onevalue(qcar(a));
  2880. }
  2881. Lisp_Object Llastpair(Lisp_Object nil, Lisp_Object a)
  2882. {
  2883. Lisp_Object b;
  2884. if (!consp(a)) return onevalue(a); /* aerror1("lastpair", a); */
  2885. while (b = qcdr(a), consp(b)) a = b;
  2886. return onevalue(a);
  2887. }
  2888. Lisp_Object Llength(Lisp_Object nil, Lisp_Object a)
  2889. {
  2890. if (a == nil) return onevalue(fixnum_of_int(0));
  2891. if (is_cons(a))
  2892. { Lisp_Object n;
  2893. /*
  2894. * Possibly I should do something to trap cyclic lists.. ?
  2895. */
  2896. n = fixnum_of_int(1);
  2897. /*
  2898. * I have unrolled the loop here 4 times since I expect length to be
  2899. * tolerably heavily used. Look at the assembly code generated for
  2900. * this to see if it was useful or counterproductive!
  2901. */
  2902. for (;;)
  2903. { a = qcdr(a);
  2904. if (!consp(a)) return onevalue(n);
  2905. a = qcdr(a);
  2906. if (!consp(a)) return onevalue((Lisp_Object)((int32)n + (1 << 4)));
  2907. a = qcdr(a);
  2908. if (!consp(a)) return onevalue((Lisp_Object)((int32)n + (2 << 4)));
  2909. a = qcdr(a);
  2910. if (!consp(a)) return onevalue((Lisp_Object)((int32)n + (3 << 4)));
  2911. n = (Lisp_Object)((int32)n + (4 << 4));
  2912. }
  2913. }
  2914. #ifndef COMMON
  2915. return onevalue(fixnum_of_int(0)); /* aerror("length");??? */
  2916. #else
  2917. /*
  2918. * Common Lisp expects length to find the length of vectors
  2919. * as well as lists.
  2920. */
  2921. else if (!is_vector(a)) return aerror1("length", a);
  2922. else
  2923. { Header h = vechdr(a);
  2924. int32 n = length_of_header(h) - 4;
  2925. if (type_of_header(h) == TYPE_ARRAY)
  2926. { Lisp_Object dims = elt(a, 1);
  2927. Lisp_Object fillp = elt(a, 5);
  2928. if (consp(dims) && !consp(qcdr(dims))) dims = qcar(dims);
  2929. else return aerror1("length", a); /* Not one-dimensional */
  2930. if (is_fixnum(fillp)) dims = fillp;
  2931. return onevalue(dims);
  2932. }
  2933. if (header_of_bitvector(h))
  2934. { n = (n - 1)*8;
  2935. /* Dodgy constant on next line - critically dependent on tag codes used! */
  2936. n += ((h & 0x380) >> 7) + 1;
  2937. }
  2938. else if (type_of_header(h) != TYPE_STRING) n = n >> 2;
  2939. return onevalue(fixnum_of_int(n));
  2940. }
  2941. #endif
  2942. }
  2943. #ifdef COMMON
  2944. Lisp_Object MS_CDECL Lappend_n(Lisp_Object nil, int nargs, ...)
  2945. {
  2946. va_list a;
  2947. int i;
  2948. Lisp_Object r;
  2949. if (nargs == 0) return onevalue(nil);
  2950. va_start(a, nargs);
  2951. push_args(a, nargs);
  2952. /*
  2953. * The actual args have been passed a C args - I can not afford to
  2954. * risk garbage collection until they have all been moved somewhere safe,
  2955. * and here that safe place is the Lisp stack. I have to delay checking for
  2956. * overflow on same until all args have been pushed.
  2957. */
  2958. stackcheck0(nargs);
  2959. nil = C_nil;
  2960. r = nil;
  2961. /*
  2962. * rearrange order of items on the stack...
  2963. * The idea is that I will then reverse-copy the args in the order a1,
  2964. * a2 , ... to make a result list. But I want to pop the stack as soon as
  2965. * I can, so I need arg1 on the TOP of the stack.
  2966. */
  2967. for (i = 0; 2*i+1<nargs; i++)
  2968. { Lisp_Object temp = stack[-i];
  2969. stack[-i] = stack[i+1-nargs];
  2970. stack[i+1-nargs] = temp;
  2971. }
  2972. for (i = 0; i<nargs; i++)
  2973. { Lisp_Object w;
  2974. pop(w);
  2975. while (consp(w))
  2976. { push(w);
  2977. nil = C_nil;
  2978. if (!exception_pending()) r = cons(qcar(w), r);
  2979. pop(w);
  2980. w = qcdr(w);
  2981. }
  2982. }
  2983. nil = C_nil;
  2984. if (exception_pending()) return C_nil;
  2985. return onevalue(nreverse(r));
  2986. }
  2987. Lisp_Object Lappend_1(Lisp_Object nil, Lisp_Object a)
  2988. {
  2989. CSL_IGNORE(nil);
  2990. return onevalue(a);
  2991. }
  2992. #endif /* COMMON */
  2993. Lisp_Object Lappend(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  2994. {
  2995. Lisp_Object r = nil;
  2996. push(b);
  2997. stackcheck2(1, a, r);
  2998. while (consp(a))
  2999. { push(a);
  3000. r = cons(qcar(a), r);
  3001. pop(a);
  3002. errexitn(1);
  3003. a = qcdr(a);
  3004. }
  3005. pop(b);
  3006. while (r != nil)
  3007. { a = qcdr(r);
  3008. qcdr(r) = b;
  3009. b = r;
  3010. r = a;
  3011. }
  3012. return onevalue(b);
  3013. }
  3014. Lisp_Object Ldelete(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  3015. {
  3016. Lisp_Object r;
  3017. push2(a, b);
  3018. r = nil;
  3019. if (is_symbol(a) || is_fixnum(a))
  3020. { while (consp(b))
  3021. { Lisp_Object q = qcar(b);
  3022. if (q == stack[-1])
  3023. { b = qcdr(b);
  3024. break;
  3025. }
  3026. stack[0] = qcdr(b);
  3027. r = cons(qcar(b), r);
  3028. errexitn(2);
  3029. b = stack[0];
  3030. }
  3031. }
  3032. else
  3033. { while (consp(b))
  3034. { Lisp_Object q = qcar(b);
  3035. #ifdef COMMON
  3036. if (cl_equal(q, a))
  3037. #else
  3038. if (equal(q, a))
  3039. #endif
  3040. { b = qcdr(b);
  3041. break;
  3042. }
  3043. stack[0] = qcdr(b);
  3044. r = cons(qcar(b), r);
  3045. errexitn(2);
  3046. b = stack[0];
  3047. a = stack[-1];
  3048. }
  3049. }
  3050. popv(2);
  3051. while (r != nil)
  3052. { Lisp_Object w = qcdr(r);
  3053. qcdr(r) = b;
  3054. b = r;
  3055. r = w;
  3056. }
  3057. return onevalue(b);
  3058. }
  3059. Lisp_Object Ldeleq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  3060. {
  3061. Lisp_Object r;
  3062. push2(a, b);
  3063. r = nil;
  3064. while (consp(b))
  3065. { Lisp_Object q = qcar(b);
  3066. if (q == stack[-1])
  3067. { b = qcdr(b);
  3068. break;
  3069. }
  3070. stack[0] = qcdr(b);
  3071. r = cons(qcar(b), r);
  3072. errexitn(2);
  3073. b = stack[0];
  3074. }
  3075. popv(2);
  3076. while (r != nil)
  3077. { Lisp_Object w = qcdr(r);
  3078. qcdr(r) = b;
  3079. b = r;
  3080. r = w;
  3081. }
  3082. return onevalue(b);
  3083. }
  3084. Lisp_Object Lnconc(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  3085. {
  3086. Lisp_Object c;
  3087. CSL_IGNORE(nil);
  3088. if (!consp(a)) return onevalue(b);
  3089. c = a;
  3090. for (;;)
  3091. { Lisp_Object next = qcdr(c);
  3092. if (!consp(next))
  3093. { qcdr(c) = b;
  3094. return onevalue(a);
  3095. }
  3096. else c = next;
  3097. }
  3098. }
  3099. /* #ifndef COMMON */
  3100. static Lisp_Object Lsubstq(Lisp_Object a, Lisp_Object b, Lisp_Object c)
  3101. {
  3102. Lisp_Object w, nil = C_nil;
  3103. if (c == b) return onevalue(a);
  3104. #ifdef CHECK_STACK
  3105. if (check_stack(__FILE__,__LINE__)) return aerror("substq");
  3106. #endif
  3107. stackcheck3(0, a, b, c);
  3108. push3(a, b, c);
  3109. if (c == b)
  3110. { popv(2);
  3111. pop(a);
  3112. errexit();
  3113. return onevalue(a);
  3114. }
  3115. if (!consp(stack[0])) { pop(c); popv(2); return c; }
  3116. w = Lsubstq(stack[-2], stack[-1], qcar(stack[0]));
  3117. errexitn(3);
  3118. pop2(c, b);
  3119. a = stack[0];
  3120. stack[0] = w;
  3121. w = Lsubstq(a, b, qcdr(c));
  3122. pop(a);
  3123. errexit();
  3124. a = cons(a, w);
  3125. errexit();
  3126. return onevalue(a);
  3127. }
  3128. Lisp_Object MS_CDECL Lsubst(Lisp_Object nil, int nargs, ...)
  3129. {
  3130. Lisp_Object w, a, b, c;
  3131. va_list aa;
  3132. argcheck(nargs, 3, "subst");
  3133. #ifdef CHECK_STACK
  3134. if (check_stack(__FILE__,__LINE__)) return aerror("subst");
  3135. #endif
  3136. va_start(aa, nargs);
  3137. a = va_arg(aa, Lisp_Object);
  3138. b = va_arg(aa, Lisp_Object);
  3139. c = va_arg(aa, Lisp_Object);
  3140. va_end(aa);
  3141. if (c == b) return onevalue(a);
  3142. if (is_symbol(b) || is_fixnum(b)) return Lsubstq(a, b, c);
  3143. stackcheck3(0, a, b, c);
  3144. push3(a, b, c);
  3145. #ifdef COMMON
  3146. if (cl_equal(c, b))
  3147. #else
  3148. if (equal(c, b))
  3149. #endif
  3150. { popv(2);
  3151. pop(a);
  3152. errexit();
  3153. return onevalue(a);
  3154. }
  3155. if (!consp(stack[0])) { pop(c); popv(2); return c; }
  3156. w = Lsubst(nil, 3, stack[-2], stack[-1], qcar(stack[0]));
  3157. errexitn(3);
  3158. pop2(c, b);
  3159. a = stack[0];
  3160. stack[0] = w;
  3161. w = Lsubst(nil, 3, a, b, qcdr(c));
  3162. pop(a);
  3163. errexit();
  3164. a = cons(a, w);
  3165. errexit();
  3166. return onevalue(a);
  3167. }
  3168. /* #endif */
  3169. Lisp_Object Lsublis(Lisp_Object nil, Lisp_Object al, Lisp_Object x)
  3170. {
  3171. stackcheck2(0, al, x);
  3172. errexit();
  3173. #ifdef CHECK_STACK
  3174. if (check_stack(__FILE__,__LINE__)) return aerror("sublis");
  3175. #endif
  3176. push5(al, x, al, nil, nil);
  3177. #define carx stack[0]
  3178. #define cdrx stack[-1]
  3179. #define w stack[-2]
  3180. #define x stack[-3]
  3181. #define al stack[-4]
  3182. for (;;)
  3183. { if (!consp(w))
  3184. { if (!consp(x))
  3185. { Lisp_Object temp = x;
  3186. popv(5);
  3187. return temp;
  3188. }
  3189. carx = Lsublis(nil, al, qcar(x));
  3190. errexitn(5);
  3191. cdrx = Lsublis(nil, al, qcdr(x));
  3192. errexitn(5);
  3193. if (carx == qcar(x) && cdrx == qcdr(x))
  3194. { Lisp_Object temp = x;
  3195. popv(5);
  3196. return temp;
  3197. }
  3198. else
  3199. { Lisp_Object a1 = carx, a2 = cdrx;
  3200. popv(5);
  3201. return cons(a1, a2);
  3202. }
  3203. }
  3204. { Lisp_Object temp = qcar(w);
  3205. if (consp(temp))
  3206. { Lisp_Object v = qcar(temp);
  3207. #ifdef COMMON
  3208. if (cl_equal(v, x))
  3209. #else
  3210. if (equal(v, x))
  3211. #endif
  3212. { temp = qcdr(temp);
  3213. popv(5);
  3214. return temp;
  3215. }
  3216. }
  3217. }
  3218. w = qcdr(w);
  3219. }
  3220. }
  3221. #undef carx
  3222. #undef cdrx
  3223. #undef w
  3224. #undef x
  3225. #undef al
  3226. Lisp_Object Lsubla(Lisp_Object nil, Lisp_Object al, Lisp_Object x)
  3227. /*
  3228. * as sublis, but uses eq test rather than equal
  3229. */
  3230. {
  3231. stackcheck2(0, al, x);
  3232. errexit();
  3233. #ifdef CHECK_STACK
  3234. if (check_stack(__FILE__,__LINE__)) return aerror("subla");
  3235. #endif
  3236. push5(al, x, al, nil, nil);
  3237. #define carx stack[0]
  3238. #define cdrx stack[-1]
  3239. #define w stack[-2]
  3240. #define x stack[-3]
  3241. #define al stack[-4]
  3242. for (;;)
  3243. { if (!consp(w))
  3244. { if (!consp(x))
  3245. { Lisp_Object temp = x;
  3246. popv(5);
  3247. return temp;
  3248. }
  3249. carx = Lsubla(nil, al, qcar(x));
  3250. errexitn(5);
  3251. cdrx = Lsubla(nil, al, qcdr(x));
  3252. errexitn(5);
  3253. if (carx == qcar(x) && cdrx == qcdr(x))
  3254. { Lisp_Object temp = x;
  3255. popv(5);
  3256. return temp;
  3257. }
  3258. else
  3259. { Lisp_Object a1 = carx, a2 = cdrx;
  3260. popv(5);
  3261. return cons(a1, a2);
  3262. }
  3263. }
  3264. { Lisp_Object temp = qcar(w);
  3265. if (consp(temp))
  3266. { Lisp_Object v = qcar(temp);
  3267. if (v == x) { temp = qcdr(temp); popv(5); return temp; }
  3268. }
  3269. }
  3270. w = qcdr(w);
  3271. }
  3272. }
  3273. #undef carx
  3274. #undef cdrx
  3275. #undef w
  3276. #undef x
  3277. #undef al
  3278. setup_type const funcs2_setup[] =
  3279. {
  3280. {"assoc", too_few_2, Lassoc, wrong_no_2},
  3281. /*
  3282. * assoc** is expected to remain as the Standard Lisp version even if in
  3283. * a Common Lisp world I redefine assoc to be someting messier. xassoc was
  3284. * an earlier name I used for the same purpose, and is being withdrawn.
  3285. */
  3286. {"assoc**", too_few_2, Lassoc, wrong_no_2},
  3287. {"xassoc", too_few_2, Lassoc, wrong_no_2},
  3288. {"atsoc", too_few_2, Latsoc, wrong_no_2},
  3289. {"member", too_few_2, Lmember, wrong_no_2},
  3290. {"member**", too_few_2, Lmember, wrong_no_2},
  3291. {"memq", too_few_2, Lmemq, wrong_no_2},
  3292. {"contained", too_few_2, Lcontained, wrong_no_2},
  3293. {"restart-csl", Lrestart_csl, Lrestart_csl2, wrong_no_1},
  3294. {"eq", too_few_2, Leq, wrong_no_2},
  3295. {"iequal", too_few_2, Leq, wrong_no_2},
  3296. {"eqcar", too_few_2, Leqcar, wrong_no_2},
  3297. {"equalcar", too_few_2, Lequalcar, wrong_no_2},
  3298. {"eql", too_few_2, Leql, wrong_no_2},
  3299. {"equalp", too_few_2, Lequalp, wrong_no_2},
  3300. {"endp", Lendp, too_many_1, wrong_no_1},
  3301. {"getd", Lgetd, too_many_1, wrong_no_1},
  3302. {"last", Llast, too_many_1, wrong_no_1},
  3303. {"lastpair", Llastpair, too_many_1, wrong_no_1},
  3304. {"length", Llength, too_many_1, wrong_no_1},
  3305. {"make-bps", Lget_bps, too_many_1, wrong_no_1},
  3306. {"make-native", Lget_native, too_many_1, wrong_no_1},
  3307. {"symbol-env", Lsymbol_env, too_many_1, wrong_no_1},
  3308. {"symbol-make-fastget", Lsymbol_make_fastget1, Lsymbol_make_fastget, wrong_no_2},
  3309. {"symbol-fastgets", Lsymbol_fastgets, too_many_1, wrong_no_1},
  3310. {"symbol-fn-cell", Lsymbol_fn_cell, too_many_1, wrong_no_1},
  3311. {"symbol-argcount", Lsymbol_argcount, too_many_1, wrong_no_1},
  3312. {"symbol-set-env", too_few_2, Lsymbol_set_env, wrong_no_2},
  3313. {"symbol-set-native", wrong_no_na, wrong_no_nb, Lsymbol_set_native},
  3314. {"symbol-set-definition", too_few_2, Lsymbol_set_definition, wrong_no_2},
  3315. {"restore-c-code", Lrestore_c_code, too_many_1, wrong_no_1},
  3316. {"set-autoload", too_few_2, Lset_autoload, wrong_no_2},
  3317. {"remd", Lremd, too_many_1, wrong_no_1},
  3318. {"trace", Ltrace, too_many_1, wrong_no_1},
  3319. {"untrace", Luntrace, too_many_1, wrong_no_1},
  3320. {"trace-all", Ltrace_all, too_many_1, wrong_no_1},
  3321. {"double-execute", Ldouble, too_many_1, wrong_no_1},
  3322. {"undouble-execute", Lundouble, too_many_1, wrong_no_1},
  3323. {"macro-function", Lmacro_function, too_many_1, wrong_no_1},
  3324. {"symbol-name", Lsymbol_name, too_many_1, wrong_no_1},
  3325. {"plist", Lplist, too_many_1, wrong_no_1},
  3326. {"delete", too_few_2, Ldelete, wrong_no_2},
  3327. {"deleq", too_few_2, Ldeleq, wrong_no_2},
  3328. {"preserve", Lpreserve_1, Lpreserve, Lpreserve_0},
  3329. {"checkpoint", Lcheckpoint_1, Lcheckpoint, Lcheckpoint_0},
  3330. {"mkvect", Lmkvect, too_many_1, wrong_no_1},
  3331. {"nconc", too_few_2, Lnconc, wrong_no_2},
  3332. {"neq", too_few_2, Lneq, wrong_no_2},
  3333. {"not", Lnull, too_many_1, wrong_no_1},
  3334. {"null", Lnull, too_many_1, wrong_no_1},
  3335. {"reverse", Lreverse, too_many_1, wrong_no_1},
  3336. {"reversip", Lnreverse, too_many_1, wrong_no_1},
  3337. {"smemq", too_few_2, Lsmemq, wrong_no_2},
  3338. {"subla", too_few_2, Lsubla, wrong_no_2},
  3339. {"sublis", too_few_2, Lsublis, wrong_no_2},
  3340. {"subst", wrong_no_3a, wrong_no_3b, Lsubst},
  3341. {"symbol-protect", too_few_2, Lsymbol_protect, wrong_no_2},
  3342. #ifdef COMMON
  3343. {"symbol-package", Lsymbol_package, too_many_1, wrong_no_1},
  3344. {"symbol-plist", Lplist, too_many_1, wrong_no_1},
  3345. {"append", Lappend_1, Lappend, Lappend_n},
  3346. /*
  3347. * In Common Lisp mode I make EQUAL do what Common Lisp says it should, but
  3348. * also have EQUALS that is much the same but which also descends vectors.
  3349. */
  3350. {"equal", too_few_2, Lcl_equal, wrong_no_2},
  3351. {"equals", too_few_2, Lequal, wrong_no_2},
  3352. {"nreverse", Lnreverse, too_many_1, wrong_no_1},
  3353. {"nreverse0", Lnreverse0, too_many_1, wrong_no_1},
  3354. #else
  3355. {"append", too_few_2, Lappend, wrong_no_2},
  3356. /* In Standard Lisp mode EQUAL descends vectors (but does not case fold) */
  3357. /* I provide cl-equal to do what Common Lisp does. */
  3358. {"cl-equal", too_few_2, Lcl_equal, wrong_no_2},
  3359. {"equal", too_few_2, Lequal, wrong_no_2},
  3360. {"member", too_few_2, Lmember, wrong_no_2},
  3361. {"member", too_few_2, Lmember, wrong_no_2},
  3362. #endif
  3363. {NULL, 0, 0, 0}
  3364. };
  3365. /* end of fns2.c */