Bug Summary

File:src/gf_imps.c
Warning:line 1137, column 2
Value stored to 'clos' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gf_imps.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c gf_imps.c
1/*****************************************************************************
2 *
3 * gf_imps.c: Constructing lazy getters for imports
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8/*
9 * To Do:
10 * saving and restoring where information in gen0{x}State
11 * More efficient mechanism for constants
12 */
13#include "gf_add.h"
14#include "gf_imps.h"
15#include "gf_java.h"
16#include "gf_prog.h"
17#include "gf_rtime.h"
18#include "gf_util.h"
19#include "optinfo.h"
20#include "store.h"
21#include "sefo.h"
22#include "lib.h"
23#include "tfsat.h"
24#include "tform.h"
25#include "symbol.h"
26#include "strops.h"
27#include "table.h"
28#include "int.h"
29
30/*****************************************************************************
31 *
32 * :: Local function declarations.
33 *
34 ****************************************************************************/
35
36localstatic Foam gen0GetLibImport (Syme, TForm);
37localstatic void gen0RestorePreviousState (GenFoamState);
38localstatic GenFoamState gen0UsePreviousState (AInt);
39localstatic void gen0SetSymeInit (Syme, AInt);
40localstatic Foam gen0LazyFunGet (TForm, Foam);
41localstatic Foam gen0LazyFunGetByArgs (Length, Length, Foam);
42localstatic Foam gen0LazyConstGet (Syme, Foam, Foam, Foam);
43localstatic Foam gen0FindLazySig (AIntList, FoamTag, AIntList, Foam);
44localstatic Foam gen0MakeGetExport (Foam, Foam, Foam);
45localstatic Foam gen0BuildLazyFun0 (FoamSig);
46localstatic Foam gen0BuildLazyFun1 (FoamSig);
47localstatic Foam gen0BuildLazyFun2 (void);
48localstatic int gen0GetLazyFunFormat (FoamSig);
49
50localstatic Foam gen0GVectFn (Lib);
51localstatic int gen0GVectIdx (Lib, Syme);
52localstatic Foam gen0GVectFnByName (String);
53localstatic int gen0GVectIdxByName (String, AInt);
54localstatic Foam gen0MakeLazyGloFn (TForm, Foam, int);
55localstatic Foam gen0MakeLazyGloDom (Foam, int);
56localstatic Foam gen0MakeLazyGloCat (Foam, int);
57
58localstatic Foam gen0DelayedInit (Foam, int);
59localstatic Foam gen0DelayedGetExport (Foam, Foam, Foam);
60localstatic Foam gen0GetBuiltin (String, AInt, Length, Length);
61
62localstatic Foam gen0StdLazyRef (FoamSig sig);
63localstatic Bool gen0IsStdLazySig (FoamSig sig);
64
65/*****************************************************************************
66 *
67 * :: Generate initialization code for an imported symbol
68 *
69 ****************************************************************************/
70
71void
72gen0InitImport(Syme syme)
73{
74 GenSaveState ss;
75 TForm exporter;
76 Foam foam, call;
77 AInt symeLexLevel = gen0GetImportLexLevel(syme);
78 int idx;
79
80 exporter = symeExporter(syme);
81 syme = symeExportingSyme(syme);
82
83 idx = gen0MoveToImportPlace(&ss, symeLexLevel);
84
85 gen0SetSymeInit(syme, int0((int) 0));
86
87 if (tfIsArchive(exporter))
88 exporter = tfArchiveLib(exporter, syme);
89
90 if (tfIsLibrary(exporter))
91 call = gen0GetLibImport(syme, exporter);
92 else if (tfIsJavaImport(exporter))
93 call = gfjGetImport(syme);
94 else
95 call = gen0GetDomImport(syme, gen0GetDomain(exporter, idx));
96
97 foam = gen0NewLex(idx, gen0VarIndex(syme)((((UShort) ((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_VarIndex))) ? ((syme)->fieldv)[symeIndex(syme
,SYFI_VarIndex)] : (symeFieldInfo[SYFI_VarIndex].def))) != (0x7FFF
)) ? ((UShort) ((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_VarIndex))) ? ((syme)->fieldv)[symeIndex(syme
,SYFI_VarIndex)] : (symeFieldInfo[SYFI_VarIndex].def))) : ((UShort
) ((((((symeOriginal(syme))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme))->lib) : ((void*)0)), (symeOriginal(syme
)))->locmask) & (1 << (SYFI_VarIndex))) ? ((symeOriginal
(syme))->fieldv)[symeIndex(symeOriginal(syme),SYFI_VarIndex
)] : (symeFieldInfo[SYFI_VarIndex].def))))
);
98
99 gen0UseStackedFormat(int0((int) 0));
100 gen0AddStmt(foamNewDef(foam, call)foamNew(FOAM_Def, 2, foam, call), NULL((void*)0));
101
102 gen0RestoreFromImportPlace(&ss);
103}
104
105Foam
106gen0GetDomainLex(TForm tf)
107{
108 GenSaveState ss;
109 Foam foam;
110 AInt lexLevel;
111 int level, idx;
112
113 assert(!tfIsLibrary(tf))do { if (!(!tfIsLibrary(tf))) _do_assert(("!tfIsLibrary(tf)")
,"gf_imps.c",113); } while (0)
;
114 lexLevel = (AInt) gen0GetSefoLexLevel(tfExpr(tf)tfToAbSyn(tf));
115 level = gen0FoamImportLevel(lexLevel);
116
117 idx = gen0MoveToImportPlace(&ss, lexLevel);
118
119 foam = gen0GetDomain(tf, idx);
120
121 gen0AddLexLevels(foam, level);
122 gen0RestoreFromImportPlace(&ss);
123
124 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Lex)
125 gen0UseStackedFormat(foam->foamLex.level);
126
127 return foam;
128}
129
130Foam
131gen0GetLazyBuiltin(String libName, AInt gloId, Length nIn, Length nOut)
132{
133 GenSaveState ss;
134 Foam foam;
135 int level;
136
137 level = gen0RootEnv();
138
139 (void) gen0MoveToImportPlace(&ss, 1);
140
141 foam = gen0GetBuiltin(libName, gloId, nIn, nOut);
142
143 gen0AddLexLevels(foam, level);
144 gen0RestoreFromImportPlace(&ss);
145
146 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Lex)
147 gen0UseStackedFormat(foam->foamLex.level);
148
149 return foam;
150
151}
152
153
154localstatic GenFoamState
155gen0UsePreviousState(AInt level)
156{
157 GenFoamState tmp = gen0State;
158 gen0State = gen0NthState(level);
159
160 return tmp;
161}
162
163localstatic void
164gen0RestorePreviousState(GenFoamState state)
165{
166 gen0State = state;
167}
168
169int
170gen0MoveToImportPlace(GenSaveState *ss, AInt lexLevel)
171{
172 FoamList savedLines;
173 FoamList *savedPlace, *wherePlace = NULL((void*)0);
174 AInt level;
175 Bool deep;
176 int idx;
177
178 level = gen0FoamImportLevel(lexLevel);
179 ss->state = gen0UsePreviousState(level);
180
181 if (gen0InDeep(gen0State->progType)((gen0State->progType) >= PT_DeepStart)) {
182 deep = true1;
183 gen0ProgUseBaseState();
184 } else
185 deep = false((int) 0);
186
187 if (gen0State->whereNest)
188 idx = gen0State->whereNest -
189 (lexLevel - gen0State->stabLevel);
190 else
191 idx = 0;
192
193 if (lexLevel < gen0State->stabLevel)
194 idx = gen0State->whereNest;
195
196 if (gen0State->whereNest /*&& gen0State->importPlace*/) {
197 wherePlace = gen0State->importPlace;
198 if (idx)
199 gen0State->importPlace = (FoamList *)
200 listElt(AInt)(AInt_listPointer->Elt)(gen0State->importPlacePrev,
201 idx - 1);
202 }
203
204 if (gen0State->importPlace != NULL((void*)0)) {
205 savedLines = gen0State->lines;
206 savedPlace = gen0State->importPlace;
207 gen0State->lines = *gen0State->importPlace;
208 gen0State->importPlace = NULL((void*)0);
209 }
210 else {
211 savedLines = NULL((void*)0);
212 savedPlace = NULL((void*)0);
213 }
214 ss->savedLines = savedLines;
215 ss->savedPlace = savedPlace;
216 ss->wherePlace = wherePlace;
217 ss->deep = deep;
218 ss->idx = idx;
219
220 return idx;
221}
222
223void
224gen0RestoreFromImportPlace(GenSaveState *ss)
225{
226 FoamList savedLines = ss->savedLines;
227 FoamList *savedPlace = ss->savedPlace;
228 FoamList *wherePlace = ss->wherePlace;
229 Bool deep = ss->deep;
230
231 if (savedPlace != NULL((void*)0)) {
232 gen0State->importPlace = savedPlace;
233 *gen0State->importPlace = gen0State->lines;
234 gen0State->lines = savedLines;
235 }
236
237 if (gen0State->whereNest && savedPlace != NULL((void*)0))
238 gen0State->importPlace = wherePlace;
239
240 gen0RestorePreviousState(ss->state);
241 if (deep)
242 gen0ProgUseUpperState();
243}
244
245
246Bool
247gen0AddImportPlace(FoamList *var)
248{
249 /* Don't bother if there is already a place */
250 if (gen0State->importPlace == NULL((void*)0)) {
251 *var = gen0State->lines;
252 gen0State->importPlace = var;
253 gen0State->lines = listNil(Foam)((FoamList) 0);
254 return true1;
255 }
256 else
257 return false((int) 0);
258}
259
260void
261gen0ResetImportPlace(FoamList var)
262{
263 gen0State->lines = listNConcat(Foam)(Foam_listPointer->NConcat)(gen0State->lines, var);
264 gen0State->importPlace = NULL((void*)0);
265}
266
267
268localstatic Foam
269gen0GetLibImport(Syme syme, TForm exporter)
270{
271 TForm tf = symeType(syme);
272 Foam initfn, foam;
273 int idx;
274
275 initfn = gen0GVectFn(tfLibraryLib(exporter));
276 idx = gen0GVectIdx(tfLibraryLib(exporter), syme);
277
278 if (tfSatDom(tf))
279 foam = gen0MakeLazyGloDom(initfn, idx);
280 else if (tfSatCat(tf))
281 foam = gen0MakeLazyGloCat(initfn, idx);
282 else if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
)
283 foam = gen0MakeLazyGloFn(tf, initfn, idx);
284 else {
285 foam = foamNew(FOAM_CCall, 3,
286 FOAM_Word, initfn, foamNewSInt(idx)foamNew(FOAM_SInt, 1, (AInt)(idx)));
287 foamPure(foam)((foam)->hdr.info.pure) = true1;
288 }
289 return foam;
290}
291
292localstatic void
293gen0SetSymeInit(Syme syme, AInt level)
294{
295 SymeList l = gen0NthState(level)->funImportList;
296 for(; l != 0; l = cdr(l)((l)->rest))
297 if (symeEqual(syme, car(l)((l)->first))) {
298 symeSetImportInit(car(l))(((((((l)->first))->kind == SYME_Trigger ? libGetAllSymes
((((l)->first))->lib) : ((void*)0)), (((l)->first)))
->bits) |= (0x0008))
;
299 return;
300 }
301 return;
302}
303
304/*****************************************************************************
305 *
306 * :: decls for lazy environments
307 *
308 ****************************************************************************/
309
310#define gen0LazyEnvSize3 3
311static String gen0LazyEnvNames[] = { "getter", "flag", "self" };
312static FoamTag gen0LazyEnvTypes[] = { FOAM_Clos, FOAM_Bool, FOAM_Clos };
313static AInt gen0LazyEnvFmts [] = { emptyFormatSlot4, emptyFormatSlot4,
314 emptyFormatSlot4 };
315
316static Foam gen0LazyFun2Const;
317
318/*****************************************************************************
319 *
320 * :: Lazy-import getting operations
321 *
322 ****************************************************************************/
323
324Foam
325gen0GetDomImport(Syme syme, Foam dom)
326{
327 String str = symeString(syme)((((syme)->id))->str);
328 TForm tf = symeType(syme);
329 TForm otf = symeType(symeOriginal(syme));
330 Foam call, name, type;
331 FoamTag fmType = gen0Type(tf, NULL((void*)0));
332
333 tfFollow(tf)((tf) = tfFollowFn(tf));
334 name = foamNewSInt(gen0StrHash(str))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(str)));
335 type = gen0TypeHash(tf, otf, str);
336
337#if 0
338 genfExportDEBUG(dbOut, "---LazGet: %9d (%s from %s)\n",
339 type, str, "???");
340#endif
341
342 if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
) {
343 /*
344 * NB: When calling this function, we will have to
345 * cast the arguments and return types if necessary.
346 */
347 call = gen0LazyFunGet(otf, gen0DelayedGetExport(dom, name, type));
348 }
349 else if (tfSatType(tf)) {
350 /* Don't use lazy gets for imported types. */
351 call = gen0MakeGetExport(dom, name, type);
352 if (fmType != FOAM_Word) {
353 foamNewCast(fmType, call)foamNew(FOAM_Cast, 2, fmType, call);
354 }
355 }
356 else
357 call = gen0LazyConstGet(syme, dom, name, type);
358
359 return call;
360}
361
362Bool
363gen0IsLazyConst(TForm tf)
364{
365 tfFollow(tf)((tf) = tfFollowFn(tf));
366
367 return !(tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
|| tfSatType(tf));
368}
369
370/*****************************************************************************
371 *
372 * :: Internal helper routines
373 *
374 ****************************************************************************/
375
376localstatic Foam gen0LazySigCall (FoamSig, Foam);
377localstatic Foam gen0StdLazySigCall (FoamSig, Foam);
378localstatic FoamSig gen0AddLazySig (FoamSig);
379
380localstatic Foam
381gen0LazyFunGet(TForm tf, Foam forcingFn)
382{
383 TForm tfret = tfMapRet(tf)tfFollowArg(tf, 1);
384 Foam val;
385 AIntList inArgs;
386 FoamTag retType;
387 AIntList retVals;
388 AInt retfmt;
389 Length i;
390
391 inArgs = listNil(AInt)((AIntList) 0);
392 for (i = 0; i < tfMapArgc(tf); i += 1) {
393 AInt type, fmt;
394 type = gen0Type(tfMapArgN(tf, i), &fmt);
395 type = (fmt << 8) + type;
396 inArgs = listCons(AInt)(AInt_listPointer->Cons)(type, inArgs);
397 }
398 inArgs = listNReverse(AInt)(AInt_listPointer->NReverse)(inArgs);
399
400 tfFollow(tfret)((tfret) = tfFollowFn(tfret));
401 retType = gen0Type(tfret, &retfmt);
402 retType = retType + (retfmt << 8);
403 retVals = listNil(AInt)((AIntList) 0);
404
405 if (tfIsMulti(tfret)(((tfret)->tag) == TF_Multiple) && !tfIsNone(tfret)((((tfret)->tag) == TF_Multiple) && tfMultiArgc(tfret
) == 0)
) {
406 for (i=0 ; i < tfMultiArgc(tfret); i++)
407 retVals = listCons(AInt)(AInt_listPointer->Cons)(gen0Type(tfMultiArgN(tfret, i)tfFollowArg(tfret, i), NULL((void*)0)),
408 retVals);
409 retVals = listNReverse(AInt)(AInt_listPointer->NReverse)(retVals);
410 }
411
412 val = gen0FindLazySig(inArgs, retType, retVals, forcingFn);
413
414 listFree(AInt)(AInt_listPointer->Free)(inArgs);
415 listFree(AInt)(AInt_listPointer->Free)(retVals);
416
417 return val;
418}
419
420/*
421 * Get a lazy function which takes 'inArgs' FOAM_Word arguments, and
422 * returns 'outArgs'
423 */
424
425localstatic Foam
426gen0LazyFunGetByArgs(Length nInArgs, Length nOutArgs, Foam forcingFn)
427{
428 Foam val;
429 AIntList inSig = listNil(AInt)((AIntList) 0);
430 FoamTag retType;
431 int i;
432
433 /* !! Could build a ddecl if nOutArgs >= 2 */
434 assert(nOutArgs < 2)do { if (!(nOutArgs < 2)) _do_assert(("nOutArgs < 2"),"gf_imps.c"
,434); } while (0)
;
435
436 for (i=0; i < nInArgs; i++) {
437 inSig = listCons(AInt)(AInt_listPointer->Cons)((AInt) FOAM_Word, inSig);
438 }
439
440 if (nOutArgs == 0)
441 retType = FOAM_NOp;
442 else
443 retType = FOAM_Word;
444
445 val = gen0FindLazySig(inSig, retType, listNil(AInt)((AIntList) 0), forcingFn);
446
447 return val;
448}
449
450localstatic Foam
451gen0LazyConstGet(Syme syme, Foam dom, Foam name, Foam type)
452{
453 Foam call;
454
455 call = gen0BuiltinCCall(FOAM_Word, "lazyGetExport!", "runtime", 3,
456 dom, name, type);
457 foamPure(call)((call)->hdr.info.pure) = true1;
458
459 return call;
460}
461
462Foam
463gen0LazyValue(Foam var, Syme syme)
464{
465 Foam foam;
466 FoamTag type = gen0Type(symeType(syme), NULL((void*)0));
467
468 if (symeIsImport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Import)
&& tfIsLibrary(symeExporter(syme)))
469 return foamNewCast(type, var)foamNew(FOAM_Cast, 2, type, var);
470
471 foam = gen0BuiltinCCall(FOAM_Word,
472 "lazyForceImport",
473 "runtime", 1, var);
474 foamSyme(var)((var)->hdr.syme) = syme;
475 foamPure(foam)((foam)->hdr.info.pure) = true1;
476 return type == FOAM_Word ? foam : foamNewCast(type, foam)foamNew(FOAM_Cast, 2, type, foam);
477}
478
479localstatic Foam
480gen0FindLazySig(AIntList inArgs, FoamTag retType, AIntList outVals,
481 Foam forcingFn)
482{
483 FoamSig sig, realsig = NULL((void*)0);
484 Foam foam;
485 FoamTag *rets;
486 AIntList l;
487 int i, nRets;
488
489 l = outVals;
490 rets = NULL((void*)0);
491 nRets = listLength(AInt)(AInt_listPointer->_Length)(outVals);
492 while (l != listNil(AInt)((AIntList) 0)) {
493 if (car(l)((l)->first) != FOAM_Word)
494 break;
495 l = cdr(l)((l)->rest);
496 }
497
498 if (l != listNil(AInt)((AIntList) 0)) {
499 l = outVals;
500 rets = (FoamTag*) stoAlloc(OB_Other0, nRets*sizeof(FoamTag));
501 for (i=0; i < nRets; i++) {
502 rets[i] = car(l)((l)->first);
503 l = cdr(l)((l)->rest);
504 }
505 }
506
507 sig = foamSigNew(inArgs, retType, nRets, rets);
508
509 if (gen0IsStdLazySig(sig))
510 foam = gen0StdLazySigCall(sig, forcingFn);
511 else {
512 FoamSigList siglst;
513 siglst = gen0LazySigList;
514 while (siglst != listNil(FoamSig)((FoamSigList) 0)) {
515 if (foamSigEqual(car(siglst)((siglst)->first), sig))
516 break;
517 siglst = cdr(siglst)((siglst)->rest);
518 }
519
520 if (siglst == listNil(FoamSig)((FoamSigList) 0))
521 realsig = gen0AddLazySig(sig);
522 else
523 realsig = car(siglst)((siglst)->first);
524
525 foam = gen0LazySigCall(realsig, forcingFn);
526 }
527
528 if (sig != realsig) foamSigFree(sig);
529 return foam;
530}
531
532localstatic Foam
533gen0LazySigCall(FoamSig sig, Foam forcingFn)
534{
535 Foam call, env;
536
537 env = foamNewEnv(gen0RootEnv())foamNew(FOAM_Env, 1, (AInt)(gen0RootEnv()));
538 call = foamNew(FOAM_OCall, 4, FOAM_Clos,
539 foamCopy(sig->ref), env,
540 forcingFn);
541 gen0UseStackedFormat(env->foamEnv.level);
542 foamPure(call)((call)->hdr.info.pure) = true1;
543
544 return call;
545
546}
547
548localstatic Foam
549gen0StdLazySigCall(FoamSig sig, Foam forcingFn)
550{
551 Foam call;
552
553 call = foamNew(FOAM_CCall, 3, FOAM_Clos,
554 gen0StdLazyRef(sig),
555 forcingFn);
556
557 foamPure(call)((call)->hdr.info.pure) = true1;
558 return call;
559}
560
561localstatic FoamSig
562gen0AddLazySig(FoamSig sig)
563{
564 sig->constNum = gen0FwdProgNum--;
565 sig->ref = foamNewConst(sig->constNum)foamNew(FOAM_Const, 1, (AInt)(sig->constNum));
566
567 gen0LazySigList = listCons(FoamSig)(FoamSig_listPointer->Cons)(sig, gen0LazySigList);
568 return sig;
569}
570
571
572localstatic Foam
573gen0MakeGetExport(Foam dom, Foam name, Foam type)
574{
575 Foam call;
576 call = gen0BuiltinCCall(FOAM_Word, "domainGetExport!",
577 "runtime", 3,
578 dom, name, type);
579 foamPure(call)((call)->hdr.info.pure) = true1;
580 return call;
581}
582
583void
584gen0IssueLazyFunctions()
585{
586 FoamSigList funs = gen0LazySigList;
587
588 while (funs) {
589 gen0AddConst(car(funs)((funs)->first)->constNum, gen0NumProgs);
590 gen0BuildLazyFun0(car(funs)((funs)->first));
591 funs = cdr(funs)((funs)->rest);
592 }
593
594 foamFree(gen0LazyFun2Const);
595 gen0LazyFun2Const = NULL((void*)0);
596
597 /* global lists freed in gen0GenFoamFini */
598}
599
600localstatic Foam
601gen0BuildLazyFun0(FoamSig fun)
602{
603 GenFoamState saved;
604 Foam foam, clos, envInfo, decl;
605
606 clos = gen0ProgClosEmpty();
607 foam = gen0ProgInitEmpty(strCopy("lazyFnGetter"), NULL((void*)0));
608
609 saved = gen0ProgSaveState(PT_ExFn);
610
611 gen0ProgPushFormat(gen0GetLazyFunFormat(fun));
612
613 decl = foamNewDecl(FOAM_Word, strCopy("init"),foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),strCopy("init"), (AInt)
(0x7FFF), 4)
614 emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),strCopy("init"), (AInt)
(0x7FFF), 4)
;
615 gen0AddParam(decl);
616
617 gen0AddStmt(foamNewDef(foamNewLex(int0, int0),foamNew(FOAM_Def, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(((int) 0))), foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew(FOAM_Par
, 1, (AInt)(((int) 0)))))
618 foamNewCast(FOAM_Clos, foamNewPar(int0)))foamNew(FOAM_Def, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(((int) 0))), foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew(FOAM_Par
, 1, (AInt)(((int) 0)))))
, NULL((void*)0));
619
620 gen0AddStmt(foamNewSet(foamNewLex(int0, 1),foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(1)), foamNew(FOAM_Bool, 1, (AInt)(((int) 0))))
621 foamNewBool(false))foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(1)), foamNew(FOAM_Bool, 1, (AInt)(((int) 0))))
, NULL((void*)0));
622 gen0AddStmt(foamNewSet(foamNewLex(int0, 2),foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(2)), gen0BuildLazyFun1(fun))
623 gen0BuildLazyFun1(fun))foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (
AInt)(2)), gen0BuildLazyFun1(fun))
, NULL((void*)0));
624 envInfo = foamNewEInfo(foamNewEnv(int0))foamNew(FOAM_EInfo, 1, foamNew(FOAM_Env, 1, (AInt)(((int) 0))
))
;
625 foamLazy(envInfo)((envInfo)->hdr.info.lazy) = true1;
626 gen0AddStmt(foamNewSet(envInfo,foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, gen0BuildLazyFun2()))
627 foamNewCast(FOAM_Word,foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, gen0BuildLazyFun2()))
628 gen0BuildLazyFun2()))foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, gen0BuildLazyFun2()))
,
629 NULL((void*)0));
630 gen0AddStmt(foamNewReturn(foamNewLex(int0, 2))foamNew(FOAM_Return, 1, foamNew(FOAM_Lex, 2, (AInt)(((int) 0)
), (AInt)(2)))
, NULL((void*)0));
631
632 gen0ProgFiniEmpty(foam, FOAM_Clos, int0((int) 0));
633
634 gen0ProgRestoreState(saved);
635 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
636 foamProgSetGetter(foam)((foam)->foamProg.infoBits |= (1 << 3));
637 return clos;
638}
639
640localstatic Foam
641gen0BuildLazyFun1(FoamSig sig)
642{
643 GenFoamState saved;
644 Foam result, foam, clos, ccall, tmp;
645 AIntList l;
646 AInt retType, retFmt;
647 static const char *letters = "abcdefghijklmnopqrstuvwxyz";
648 char x[2];
649 int i, inArgc, callLabel;
650
651 clos = gen0ProgClosEmpty();
652 foam = gen0ProgInitEmpty(strCopy("lazyGetter"), NULL((void*)0));
653
654 saved = gen0ProgSaveState(PT_ExFn);
655
656 assert(sig->nRets != 1)do { if (!(sig->nRets != 1)) _do_assert(("sig->nRets != 1"
),"gf_imps.c",656); } while (0)
;
657 if (sig->nRets != 0)
658 retFmt = gen0MFmtNumberForSig(sig->nRets, sig->rets);
659 else
660 retFmt = sig->retType >> 8;
661
662 x[1] = 0;
663 i = 0;
664 for (l = sig->inArgs; l ; l = cdr(l)((l)->rest)) {
665 AInt type, fmt;
666 type = car(l)((l)->first) & 0xFF;
667 fmt = car(l)((l)->first) >> 8;
668 x[0] = letters[i];
669 gen0AddParam(foamNewDecl(type, strCopy(x), fmt)foamNew(FOAM_Decl,4,(AInt)(type),strCopy(x), (AInt) (0x7FFF),
fmt)
);
670 if (i<26) i++; else i=0;
671 }
672 inArgc = listLength(AInt)(AInt_listPointer->_Length)(sig->inArgs);
673
674 tmp = gen0TempLocal(FOAM_Clos)gen0TempLocal0(FOAM_Clos, 4);
675 callLabel = gen0State->labelNo++;
676 gen0AddStmt(foamNewIf(foamNewLex(1, 1), callLabel)foamNew(FOAM_If, 2, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt)(1)
), callLabel)
, NULL((void*)0));
677 gen0AddStmt(foamNewSet(foamCopy(tmp),foamNew(FOAM_Set, 2, foamCopy(tmp), foamNew(FOAM_Cast, 2, FOAM_Clos
, foamNew(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt
)(1), (AInt)(((int) 0))))))
678 foamNewCast(FOAM_Clos,foamNew(FOAM_Set, 2, foamCopy(tmp), foamNew(FOAM_Cast, 2, FOAM_Clos
, foamNew(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt
)(1), (AInt)(((int) 0))))))
679 foamNew(FOAM_CCall, 2,foamNew(FOAM_Set, 2, foamCopy(tmp), foamNew(FOAM_Cast, 2, FOAM_Clos
, foamNew(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt
)(1), (AInt)(((int) 0))))))
680 FOAM_Word,foamNew(FOAM_Set, 2, foamCopy(tmp), foamNew(FOAM_Cast, 2, FOAM_Clos
, foamNew(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt
)(1), (AInt)(((int) 0))))))
681 foamNewLex(1, int0))))foamNew(FOAM_Set, 2, foamCopy(tmp), foamNew(FOAM_Cast, 2, FOAM_Clos
, foamNew(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt
)(1), (AInt)(((int) 0))))))
,
682 NULL((void*)0));
683 /* Zap this function */
684 gen0AddStmt(foamNewSet(foamNewCEnv(foamNewLex(1, 2)),foamNew(FOAM_Set, 2, foamNew(FOAM_CEnv, 1, foamNew(FOAM_Lex, 2
, (AInt)(1), (AInt)(2))), foamNew(FOAM_CEnv, 1, foamCopy(tmp)
))
685 foamNewCEnv(foamCopy(tmp)))foamNew(FOAM_Set, 2, foamNew(FOAM_CEnv, 1, foamNew(FOAM_Lex, 2
, (AInt)(1), (AInt)(2))), foamNew(FOAM_CEnv, 1, foamCopy(tmp)
))
, NULL((void*)0));
686 gen0AddStmt(foamNewSet(foamNewCProg(foamNewLex(1, 2)),foamNew(FOAM_Set, 2, foamNew(FOAM_CProg, 1, foamNew(FOAM_Lex,
2, (AInt)(1), (AInt)(2))), foamNew(FOAM_CProg, 1, foamCopy(tmp
)))
687 foamNewCProg(foamCopy(tmp)))foamNew(FOAM_Set, 2, foamNew(FOAM_CProg, 1, foamNew(FOAM_Lex,
2, (AInt)(1), (AInt)(2))), foamNew(FOAM_CProg, 1, foamCopy(tmp
)))
, NULL((void*)0));
688 /* Now tell the world */
689 gen0AddStmt(foamNewSet(foamNewLex(1, 1), foamNewBool(true))foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt)(1
)), foamNew(FOAM_Bool, 1, (AInt)(1)))
, NULL((void*)0));
690
691 gen0AddStmt(foamNewLabel(callLabel)foamNew(FOAM_Label, 1, (AInt)(callLabel)), NULL((void*)0));
692 /* Call the retrieved function */
693 ccall = foamNewEmpty(FOAM_CCall, inArgc + 2);
694
695 retType = sig->retType & 0xFF;
696 ccall->foamCCall.type = retType;
697
698 ccall->foamCCall.op = foamNewLex(1, 2)foamNew(FOAM_Lex, 2, (AInt)(1), (AInt)(2));
699 for (i=0; i<inArgc; i++)
700 ccall->foamCCall.argv[i] = foamNewPar(i)foamNew(FOAM_Par, 1, (AInt)(i));
701
702 if (retType != FOAM_NOp)
703 result = ccall;
704 else if (retFmt == emptyFormatSlot4) {
705 gen0AddStmt(ccall, NULL((void*)0));
706 result = foamNew(FOAM_Values, int0((int) 0));
707 } else {
708 assert(retFmt != 0)do { if (!(retFmt != 0)) _do_assert(("retFmt != 0"),"gf_imps.c"
,708); } while (0)
;
709 tmp = gen0TempFrDDecl(retFmt, true1);
710 gen0AddStmt(foamNewSet(tmp, foamNewMFmt(retFmt, ccall))foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_MFmt, 2, retFmt, ccall
))
,
711 NULL((void*)0));
712 result = foamCopy(tmp);
713 }
714
715 gen0AddStmt(foamNewReturn(result)foamNew(FOAM_Return, 1, result), NULL((void*)0));
716 gen0ProgPushFormat(emptyFormatSlot4);
717 gen0ProgFiniEmpty(foam, retType, retFmt);
718 foam->foamProg.format = retFmt;
719 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
720 gen0ProgRestoreState(saved);
721 return clos;
722}
723
724/**!! We only need one of these per file */
725localstatic Foam
726gen0BuildLazyFun2()
727{
728 GenFoamState saved;
729 Foam foam, clos, tmp, envInfo;
730 int testLabel;
731
732 if (gen0LazyFun2Const != NULL((void*)0))
733 return foamCopy(gen0LazyFun2Const);
734
735 clos = gen0ProgClosEmpty();
736 foam = gen0ProgInitEmpty(strCopy("lazyGetter2"), NULL((void*)0));
737
738 saved = gen0ProgSaveState(PT_ExFn);
739 testLabel = gen0State->labelNo++;
740 tmp = gen0TempLocal(FOAM_Clos)gen0TempLocal0(FOAM_Clos, 4);
741
742 gen0AddStmt(foamNewIf(foamNewLex(1,1), testLabel)foamNew(FOAM_If, 2, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt)(1)
), testLabel)
, NULL((void*)0));
743 gen0AddStmt(foamNewSet(tmp,foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew
(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt
)(((int) 0))))))
744 foamNewCast(FOAM_Clos,foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew
(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt
)(((int) 0))))))
745 foamNew(FOAM_CCall, 2,foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew
(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt
)(((int) 0))))))
746 FOAM_Word,foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew
(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt
)(((int) 0))))))
747 foamNewLex(1, int0))))foamNew(FOAM_Set, 2, tmp, foamNew(FOAM_Cast, 2, FOAM_Clos, foamNew
(FOAM_CCall, 2, FOAM_Word, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt
)(((int) 0))))))
,
748 NULL((void*)0));
749 gen0AddStmt(foamNewSet(foamNewLex(1, 1), foamNewBool(true))foamNew(FOAM_Set, 2, foamNew(FOAM_Lex, 2, (AInt)(1), (AInt)(1
)), foamNew(FOAM_Bool, 1, (AInt)(1)))
, NULL((void*)0));
750
751 /* Zap this function */
752 gen0AddStmt(foamNewSet(foamNewCEnv(foamNewLex(1, 2)),foamNew(FOAM_Set, 2, foamNew(FOAM_CEnv, 1, foamNew(FOAM_Lex, 2
, (AInt)(1), (AInt)(2))), foamNew(FOAM_CEnv, 1, foamCopy(tmp)
))
753 foamNewCEnv(foamCopy(tmp)))foamNew(FOAM_Set, 2, foamNew(FOAM_CEnv, 1, foamNew(FOAM_Lex, 2
, (AInt)(1), (AInt)(2))), foamNew(FOAM_CEnv, 1, foamCopy(tmp)
))
, NULL((void*)0));
754 gen0AddStmt(foamNewSet(foamNewCProg(foamNewLex(1, 2)),foamNew(FOAM_Set, 2, foamNew(FOAM_CProg, 1, foamNew(FOAM_Lex,
2, (AInt)(1), (AInt)(2))), foamNew(FOAM_CProg, 1, foamCopy(tmp
)))
755 foamNewCProg(foamCopy(tmp)))foamNew(FOAM_Set, 2, foamNew(FOAM_CProg, 1, foamNew(FOAM_Lex,
2, (AInt)(1), (AInt)(2))), foamNew(FOAM_CProg, 1, foamCopy(tmp
)))
, NULL((void*)0));
756 envInfo = foamNewEInfo(foamNewEnv(1))foamNew(FOAM_EInfo, 1, foamNew(FOAM_Env, 1, (AInt)(1)));
757 foamLazy(envInfo)((envInfo)->hdr.info.lazy) = true1;
758 gen0AddStmt(foamNewSet(envInfo,foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, foamNew(FOAM_Nil, (int) 0)))
759 foamNewCast(FOAM_Word,foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, foamNew(FOAM_Nil, (int) 0)))
760 foamNewNil()))foamNew(FOAM_Set, 2, envInfo, foamNew(FOAM_Cast, 2, FOAM_Word
, foamNew(FOAM_Nil, (int) 0)))
,
761 NULL((void*)0));
762 gen0AddStmt(foamNewLabel(testLabel)foamNew(FOAM_Label, 1, (AInt)(testLabel)), NULL((void*)0));
763 gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, ((int) 0))), NULL((void*)0));
764
765 gen0ProgPushFormat(emptyFormatSlot4);
766 gen0ProgFiniEmpty(foam, FOAM_NOp, int0((int) 0));
767 foam->foamProg.format = 0;
768 gen0ProgRestoreState(saved);
769 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
770 foamProgSetGetter(foam)((foam)->foamProg.infoBits |= (1 << 3));
771
772 gen0LazyFun2Const = clos;
773 return foamCopy(clos);
774
775}
776
777localstatic int
778gen0GetLazyFunFormat(FoamSig sig)
779{
780 if (gen0LazyFunFormat)
781 return gen0LazyFunFormat;
782
783 gen0LazyFunFormat =
784 gen0StdDeclFormat(gen0LazyEnvSize3, gen0LazyEnvNames,
785 gen0LazyEnvTypes, gen0LazyEnvFmts);
786
787 return gen0LazyFunFormat;
788}
789
790/*****************************************************************************
791 *
792 * :: Standard Signatures
793 *
794 ****************************************************************************/
795
796localstatic void gen0StdGetsCreate0 (AIntList);
797localstatic void gen0StdGetsCreate1 (AIntList, FoamTag, int);
798localstatic String gen0StdLazyName (AIntList, AInt, int);
799
800/*
801 * Because practically all files call a function of none, two and
802 * three args, returning any of no values, one value, two values
803 * or a closure, we instantiate these exactly once (in runtime.as).
804 */
805
806
807localstatic Foam
808gen0StdLazyRef(FoamSig sig)
809{
810 Foam decl;
811
812 decl = foamNewGDecl(FOAM_Clos,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),gen0StdLazyName(sig->
inArgs, sig->retType, sig->nRets), FOAM_Nil,4, (AInt)(FOAM_GDecl_Import
),(AInt)(FOAM_Proto_Foam))
813 gen0StdLazyName(sig->inArgs, sig->retType, sig->nRets),foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),gen0StdLazyName(sig->
inArgs, sig->retType, sig->nRets), FOAM_Nil,4, (AInt)(FOAM_GDecl_Import
),(AInt)(FOAM_Proto_Foam))
814 FOAM_Nil,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),gen0StdLazyName(sig->
inArgs, sig->retType, sig->nRets), FOAM_Nil,4, (AInt)(FOAM_GDecl_Import
),(AInt)(FOAM_Proto_Foam))
815 emptyFormatSlot,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),gen0StdLazyName(sig->
inArgs, sig->retType, sig->nRets), FOAM_Nil,4, (AInt)(FOAM_GDecl_Import
),(AInt)(FOAM_Proto_Foam))
816 FOAM_GDecl_Import, FOAM_Proto_Foam)foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),gen0StdLazyName(sig->
inArgs, sig->retType, sig->nRets), FOAM_Nil,4, (AInt)(FOAM_GDecl_Import
),(AInt)(FOAM_Proto_Foam))
;
817 return foamNewGlo(gen0AddGlobal(decl))foamNew(FOAM_Glo, 1, (AInt)(gen0AddGlobal(decl)));
818}
819
820void
821gen0StdLazyGetsCreate()
822{
823 AIntList args;
824
825 /* No arguments */
826 args = listNil(AInt)((AIntList) 0);
827 gen0StdGetsCreate0(args);
828
829 /* One (closure) argument */
830 args = listCons(AInt)(AInt_listPointer->Cons)(FOAM_Clos, args);
831 gen0StdGetsCreate0(args);
832
833 /* One (word) argument */
834 car(args)((args)->first) = FOAM_Word;
835 gen0StdGetsCreate0(args);
836
837 /* One (word) argument */
838 args = listCons(AInt)(AInt_listPointer->Cons)(FOAM_Word, args);
839 gen0StdGetsCreate0(args);
840
841 /* One (word) argument */
842 args = listCons(AInt)(AInt_listPointer->Cons)(FOAM_Word, args);
843 gen0StdGetsCreate0(args);
844}
845
846localstatic void
847gen0StdGetsCreate0(AIntList args)
848{
849 FoamTag retType;
850 int nRets;
851
852 /* Returning a closure */
853 retType = FOAM_Clos;
854 nRets = 0;
855 gen0StdGetsCreate1(args, retType, nRets);
856
857
858 /* Returning nothing */
859 retType = FOAM_NOp;
860 nRets = 0;
861 gen0StdGetsCreate1(args, retType, nRets);
862
863
864 /* Returning a word */
865 retType = FOAM_Word;
866 nRets = 0;
867 gen0StdGetsCreate1(args, retType, nRets);
868
869
870 /* Returning two words */
871 retType = FOAM_NOp;
872 nRets = 2;
873 gen0StdGetsCreate1(args, retType, nRets);
874}
875
876localstatic void
877gen0StdGetsCreate1(AIntList args, FoamTag retType, int nRets)
878{
879 Foam foam, decl;
880 FoamSig sig;
881 String name;
882 AInt idx;
883
884 retType = retType + (emptyFormatSlot4 << 8);
885
886 sig = foamSigNew(args, retType, nRets, NULL((void*)0));
887 gen0AddLazySig(sig);
888 foam = foamNewClos(foamNewEnv(int0), foamCopy(sig->ref))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(((int) 0))),
foamCopy(sig->ref))
;
889 name = gen0StdLazyName(args, retType, nRets);
890 decl = foamNewGDecl(FOAM_Clos, name, emptyFormatSlot,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),name, 4,FOAM_Nil, (AInt
)(FOAM_GDecl_Export),(AInt)(FOAM_Proto_Foam))
891 FOAM_Nil,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),name, 4,FOAM_Nil, (AInt
)(FOAM_GDecl_Export),(AInt)(FOAM_Proto_Foam))
892 FOAM_GDecl_Export, FOAM_Proto_Foam)foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),name, 4,FOAM_Nil, (AInt
)(FOAM_GDecl_Export),(AInt)(FOAM_Proto_Foam))
;
893 idx = gen0AddGlobal(decl);
894 gen0AddStmt(foamNewSet(foamNewGlo(idx), foam)foamNew(FOAM_Set, 2, foamNew(FOAM_Glo, 1, (AInt)(idx)), foam), NULL((void*)0));
895 gen0BuiltinExports = listCons(AInt)(AInt_listPointer->Cons)(idx, gen0BuiltinExports);
896 gen0BuiltinExports = listCons(AInt)(AInt_listPointer->Cons)(int0((int) 0), gen0BuiltinExports);
897}
898
899
900localstatic String
901gen0StdLazyName(AIntList args, AInt retType, int nRets)
902{
903 String name, tmp;
904 retType = retType & 0xFF;
905
906 name = strCopy(gen0StdLazyNamePrefix()"stdGet");
907 while (args != listNil(AInt)((AIntList) 0)) {
908 tmp = name;
909 name = strConcat(name, foamInfo(car(args) & 0xFF)(foamInfoTable [(int)(((args)->first) & 0xFF)-(int)FOAM_START
])
.str);
910 strFree(tmp);
911 args = cdr(args)((args)->rest);
912 }
913
914 tmp = name;
915 name = strPrintf("%sRet%s%d", name, foamInfo(retType)(foamInfoTable [(int)(retType)-(int)FOAM_START]).str, nRets);
916 strFree(tmp);
917
918 return name;
919}
920
921
922localstatic Bool
923gen0IsStdLazySig(FoamSig sig)
924{
925 AIntList lst;
926 AIntList inArgs = sig->inArgs;
927 FoamTag retType = sig->retType & 0xFF;
928 int nRets = sig->nRets;
929 FoamTag *rets = sig->rets;
930 Bool ok;
931
932 lst = inArgs;
933
934 if (listLength(AInt)(AInt_listPointer->_Length)(inArgs) > 3)
935 return false((int) 0);
936
937 if (listLength(AInt)(AInt_listPointer->_Length)(inArgs) == 1)
938 ok = ((car(inArgs)((inArgs)->first) & 0xFF) == FOAM_Word
939 || (car(inArgs)((inArgs)->first) & 0xFF) == FOAM_Clos);
940 else {
941 ok = true1;
942 while (ok && inArgs != listNil(AInt)((AIntList) 0)) {
943 ok = (car(inArgs)((inArgs)->first) & 0xFF) == FOAM_Word;
944 inArgs = cdr(inArgs)((inArgs)->rest);
945 }
946 }
947 if (!ok)
948 return false((int) 0);
949
950 if (retType != FOAM_NOp && retType != FOAM_Word)
951 return false((int) 0);
952
953 if (nRets > 2)
954 return false((int) 0);
955
956 ok = true1;
957 if (rets) {
958 int i;
959 for (i=0; i<nRets; i++)
960 ok = rets[i] && ok;
961 }
962
963 if (!ok)
964 return false((int) 0);
965
966 return true1;
967}
968
969/*****************************************************************************
970 *
971 * :: Global getters
972 *
973 ****************************************************************************/
974
975/*
976 * To avoid instantiating an entire library at initialisation time,
977 * we use Global Vector functions that simply return a vector containing
978 * the globals from a particular module, instantiating the module if
979 * necessary. As a further enhancement, newly created domains are
980 * pointers to the real domain (this is controlled by the
981 * "runtimeMakeFakeDomain" which ensures that a domain is initialised
982 * iff an export/hashcode is needed.
983 *
984 * Similarly, functions are not completely instantiated until they are
985 * called, and type returning functions do not cause instantiation until
986 * an export or hashcode is needed.
987 *
988 */
989localstatic AIntList gen0GVectFindExports (String);
990localstatic void gen0GVectPutExports (String, AIntList);
991localstatic void gen0GVectIssueFn (String, AIntList);
992localstatic AInt gen0GlobalRef (Lib, Syme);
993
994static Table gen0GVectTable;
995static Table gen0GVectFnTable;
996
997
998
999void
1000gen0InitGVectTable()
1001{
1002 gen0GVectTable = tblNew((TblHashFun)strHash,
1003 (TblEqFun)strEqual);
1004 gen0GVectFnTable = tblNew((TblHashFun)strHash,
1005 (TblEqFun)strEqual);
1006}
1007
1008void
1009gen0FiniGVectTable()
1010{
1011 tblFree(gen0GVectTable);
1012 tblFree(gen0GVectFnTable);
1013 gen0GVectTable = NULL((void*)0);
1014 gen0GVectFnTable = NULL((void*)0);
1015}
1016
1017localstatic Foam
1018gen0GVectFn(Lib lib)
1019{
1020 String libName = libGetFileId(lib);
1021
1022 return gen0GVectFnByName(libName);
1023}
1024
1025localstatic Foam
1026gen0GVectFnByName(String libName)
1027{
1028 Foam res, var;
1029 int num;
1030 res = (Foam) tblElt(gen0GVectFnTable, (TblKey) libName, (TblElt) NULL((void*)0));
1031
1032 if (res) return foamCopy(res->foamDef.lhs);
1033
1034 num = gen0FwdProgNum--;
1035
1036 res = gen0Temp(FOAM_Clos)gen0Temp0(FOAM_Clos, 4);
1037 var = foamNewDef(res,foamNew(FOAM_Def, 2, res, foamNew(FOAM_Clos,2, foamNew(FOAM_Env
, 1, (AInt)(((int) 0))), foamNew(FOAM_Const, 1, (AInt)(num)))
)
1038 foamNewClos(foamNewEnv(int0),foamNew(FOAM_Def, 2, res, foamNew(FOAM_Clos,2, foamNew(FOAM_Env
, 1, (AInt)(((int) 0))), foamNew(FOAM_Const, 1, (AInt)(num)))
)
1039 foamNewConst(num)))foamNew(FOAM_Def, 2, res, foamNew(FOAM_Clos,2, foamNew(FOAM_Env
, 1, (AInt)(((int) 0))), foamNew(FOAM_Const, 1, (AInt)(num)))
)
;
1040 gen0AddInit(var);
1041 tblSetElt(gen0GVectFnTable, (TblKey) libName, (TblElt) var);
1042
1043 return foamCopy(res);
1044}
1045
1046localstatic int
1047gen0GVectIdx(Lib lib, Syme syme)
1048{
1049 AInt globNo = gen0GlobalRef(lib, syme);
1050 String name = libGetFileId(lib);
1051
1052 return gen0GVectIdxByName(name, globNo);
1053
1054}
1055
1056localstatic int
1057gen0GVectIdxByName(String libName, AInt globNo)
1058{
1059 AIntList lst;
1060 int len;
1061
1062 lst = gen0GVectFindExports(libName);
1063
1064 len = listLength(AInt)(AInt_listPointer->_Length)(lst);
1065
1066 gen0GVectPutExports(libName, listCons(AInt)(AInt_listPointer->Cons)(globNo, lst));
1067
1068 return (AInt) len;
1069}
1070
1071void
1072gen0IssueGVectFns()
1073{
1074 TableIterator it;
1075
1076 for (tblITER(it, gen0GVectTable)_tblITER(&(it), gen0GVectTable); tblMORE(it)((it).curr <= (it).last); tblSTEP(it)((((it).link=(it).link->next))==0 ? _tblSTEP(&(it)) : 1
)
) {
1077 AIntList globs;
1078 String libName;
1079 Foam defn;
1080
1081 libName = (String) tblKEY(it)((it).link->key);
1082 globs = (AIntList) tblELT(it)((it).link->elt);
1083 defn = (Foam) tblElt(gen0GVectFnTable,
1084 (TblKey) libName, (TblElt) NULL((void*)0));
1085 assert(defn)do { if (!(defn)) _do_assert(("defn"),"gf_imps.c",1085); } while
(0)
;
1086 gen0AddConst(defn->foamDef.rhs->foamClos.prog->foamConst.index,
1087 gen0NumProgs);
1088 gen0GVectIssueFn(libName, globs);
1089 }
1090
1091}
1092
1093localstatic AIntList
1094gen0GVectFindExports(String libName)
1095{
1096 return (AIntList) tblElt(gen0GVectTable,
1097 (TblKey) libName,
1098 (TblElt) listNil(AInt)((AIntList) 0));
1099}
1100
1101localstatic void
1102gen0GVectPutExports(String libName, AIntList globs)
1103{
1104 tblSetElt(gen0GVectTable, (TblKey) libName, (TblElt) globs);
1105}
1106
1107/*
1108 * Produce the following code:
1109 * xxxArr = NULL;
1110 * ...
1111 * xxxInit(int n)
1112 * {
1113 * if (xxxArr) goto l1;
1114 * xxxArr = arrNew(n);
1115 * xxxArr[0] = Global<xxx>;
1116 * ...
1117 * l1:
1118 * return xxxArr[n];
1119 * }
1120 */
1121localstatic void
1122gen0GVectIssueFn(String libName, AIntList globs)
1123{
1124 GenFoamState saved;
1125 Foam foam, clos, decl, ini;
1126 String fnName;
1127 int initLabel;
1128 Foam var, flag, ret;
1129 int i, len = listLength(AInt)(AInt_listPointer->_Length)(globs);
1130
1131 fnName = strPrintf("%s-init", libName);
1132 var = gen0TempLex(FOAM_Word)gen0TempLex0(FOAM_Word, 4);
1133 flag = gen0TempLex(FOAM_Bool)gen0TempLex0(FOAM_Bool, 4);
1134
1135 gen0AddInit(foamNewSet(foamCopy(flag), foamNewBool(int0))foamNew(FOAM_Set, 2, foamCopy(flag), foamNew(FOAM_Bool, 1, (AInt
)(((int) 0))))
);
1136
1137 clos = gen0ProgClosEmpty();
Value stored to 'clos' is never read
1138 foam = gen0ProgInitEmpty(fnName, NULL((void*)0));
1139
1140 saved = gen0ProgSaveState(PT_ExFn);
1141
1142 gen0IncLexLevels(flag, 1);
1143
1144 decl = foamNewDecl(FOAM_SInt, strCopy("idx"), emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_SInt),strCopy("idx"), (AInt) (
0x7FFF), 4)
;
1145 gen0AddParam(decl);
1146
1147 initLabel = gen0State->labelNo++;
1148 gen0AddStmt(foamNewIf(foamCopy(flag), initLabel)foamNew(FOAM_If, 2, foamCopy(flag), initLabel), NULL((void*)0));
1149 gen0AddStmt(foamNewSet(foamCopy(flag), foamNewBool(1))foamNew(FOAM_Set, 2, foamCopy(flag), foamNew(FOAM_Bool, 1, (AInt
)(1)))
, NULL((void*)0));
1150
1151 /* Make a call to the initialiser */
1152 decl = foamNewGDecl(FOAM_Clos,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),(strCopy(libName)), FOAM_Nil
,4, (AInt)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Init))
1153 gen0InitialiserName(libName),foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),(strCopy(libName)), FOAM_Nil
,4, (AInt)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Init))
1154 FOAM_Nil, emptyFormatSlot,foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),(strCopy(libName)), FOAM_Nil
,4, (AInt)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Init))
1155 FOAM_GDecl_Import, FOAM_Proto_Init)foamNew(FOAM_GDecl,6,(AInt)(FOAM_Clos),(strCopy(libName)), FOAM_Nil
,4, (AInt)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Init))
;
1156 ini = foamNewEmpty(FOAM_CCall, 2);
1157 ini->foamCCall.type = FOAM_NOp;
1158 ini->foamCCall.op = foamNewGlo(gen0AddGlobal(decl))foamNew(FOAM_Glo, 1, (AInt)(gen0AddGlobal(decl)));
1159 gen0AddStmt(ini, NULL((void*)0));
1160
1161 gen0AddStmt(foamNewLabel(initLabel)foamNew(FOAM_Label, 1, (AInt)(initLabel)), NULL((void*)0));
1162
1163 for (i = len - 1; i > 0; globs = cdr(globs)((globs)->rest), i -= 1) {
1164 Foam glo = foamNewGlo(car(globs))foamNew(FOAM_Glo, 1, (AInt)(((globs)->first)));
1165 int nextLabel = gen0State->labelNo++;
1166 gen0AddStmt(foamNewIf(foamNew(FOAM_BCall, 3, FOAM_BVal_SIntNE,foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntNE, foamNew
(FOAM_Par, 1, (AInt)(((int) 0))), foamNew(FOAM_SInt, 1, (AInt
)(i))), nextLabel)
1167 foamNewPar(int0),foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntNE, foamNew
(FOAM_Par, 1, (AInt)(((int) 0))), foamNew(FOAM_SInt, 1, (AInt
)(i))), nextLabel)
1168 foamNewSInt(i)),foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntNE, foamNew
(FOAM_Par, 1, (AInt)(((int) 0))), foamNew(FOAM_SInt, 1, (AInt
)(i))), nextLabel)
1169 nextLabel)foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntNE, foamNew
(FOAM_Par, 1, (AInt)(((int) 0))), foamNew(FOAM_SInt, 1, (AInt
)(i))), nextLabel)
, NULL((void*)0));
1170 gen0AddStmt(foamNewReturn(foamNewCast(FOAM_Word, glo))foamNew(FOAM_Return, 1, foamNew(FOAM_Cast, 2, FOAM_Word, glo)
)
, NULL((void*)0));
1171 gen0AddStmt(foamNewLabel(nextLabel)foamNew(FOAM_Label, 1, (AInt)(nextLabel)), NULL((void*)0));
1172 }
1173
1174 ret = foamNewCast(FOAM_Word, foamNewGlo(car(globs)))foamNew(FOAM_Cast, 2, FOAM_Word, foamNew(FOAM_Glo, 1, (AInt)(
((globs)->first))))
;
1175
1176 gen0AddStmt(foamNewReturn(ret)foamNew(FOAM_Return, 1, ret), NULL((void*)0));
1177
1178 gen0ProgPushFormat(emptyFormatSlot4);
1179 gen0ProgFiniEmpty(foam, FOAM_Word, int0((int) 0));
1180 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
1181 gen0ProgRestoreState(saved);
1182
1183 foamFree(flag);
1184}
1185
1186localstatic AInt
1187gen0GlobalRef(Lib lib, Syme syme)
1188{
1189 TForm exporter;
1190 Foam decl;
1191 AInt globNo;
1192
1193 exporter = symeExporter(syme);
1194 if (tfIsArchive(exporter))
1195 exporter = tfArchiveLib(exporter, syme);
1196
1197 /* Pull the binding */
1198 decl = foamNewGDecl(gen0Type(symeType(syme), NULL),foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
1199 gen0GlobalName(libGetFileId(lib),foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
1200 syme),foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
1201 FOAM_Nil,foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
1202 emptyFormatSlot,foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
1203 FOAM_GDecl_Import, FOAM_Proto_Foam)foamNew(FOAM_GDecl,6,(AInt)(gen0Type(symeType(syme), ((void*)
0))),gen0GlobalName(libGetFileId(lib), syme), FOAM_Nil,4, (AInt
)(FOAM_GDecl_Import),(AInt)(FOAM_Proto_Foam))
;
1204 globNo = gen0AddGlobal(decl);
1205
1206 return globNo;
1207}
1208
1209/*
1210 * Map-Valued globals:
1211 * [args]->[res]
1212 * Issue the following code:
1213 *
1214 * init:
1215 * (Set fn (Call MakeFnInitter-<n> initfn idx))
1216 *
1217 * (Def (Const MakeFnInitter-<n>)
1218 * ..
1219 * (CCall (CCall initfn idx) args))
1220 *
1221 * This is precisely what we do for imports in any case.
1222 */
1223
1224localstatic Foam
1225gen0MakeLazyGloFn(TForm tf, Foam initfn, int idx)
1226{
1227 Foam call;
1228
1229 call = gen0LazyFunGet(tf, gen0DelayedInit(initfn, idx));
1230
1231 return call;
1232}
1233
1234/*
1235 * DomainMap Valued Globals
1236 * We could make these extra-lazy by making appropriate wrappers that
1237 * terminate in a call to makeLazyDomFrInit. However,
1238 * this may incur too much static cost, so it has been left.
1239 * Note that the method used loses PRef information
1240 * --- To fix this would require that the 'PRef 0' slot be
1241 * made into a function, and thus changes to gf_add, of_hfold.
1242 */
1243
1244/*
1245 * Domain Valued Globals
1246 *
1247 * (Call MkFakeDomain (mklambda initfn idx))
1248 *
1249 * Ditto Cat Globals
1250 */
1251
1252localstatic Foam
1253gen0MakeLazyGloDom(Foam initfn, int idx)
1254{
1255 Foam call;
1256
1257 call = gen0BuiltinCCall(FOAM_Word, "rtLazyDomFrInit",
1258 "runtime", 2, initfn, foamNewSInt(idx)foamNew(FOAM_SInt, 1, (AInt)(idx)));
1259
1260 foamPure(call)((call)->hdr.info.pure) = true1;
1261 return call;
1262}
1263
1264localstatic Foam
1265gen0MakeLazyGloCat(Foam initfn, int idx)
1266{
1267 Foam call;
1268
1269 call = gen0BuiltinCCall(FOAM_Word, "rtLazyCatFrInit",
1270 "runtime", 2, initfn, foamNewSInt(idx)foamNew(FOAM_SInt, 1, (AInt)(idx)));
1271
1272 foamPure(call)((call)->hdr.info.pure) = true1;
1273 return call;
1274}
1275
1276/*
1277 * Globals: helper fns
1278 */
1279localstatic Foam
1280gen0DelayedInit(Foam initfn, int idx)
1281{
1282 Foam foam;
1283
1284 foam = gen0BuiltinCCall(FOAM_Word, "rtDelayedInit!",
1285 "runtime", 2, initfn, foamNewSInt(idx)foamNew(FOAM_SInt, 1, (AInt)(idx)));
1286
1287 foamPure(foam)((foam)->hdr.info.pure) = true1;
1288 return foam;
1289}
1290
1291localstatic Foam
1292gen0DelayedGetExport(Foam dom, Foam name, Foam type)
1293{
1294 Foam foam;
1295
1296 foam = gen0BuiltinCCall(FOAM_Word, "rtDelayedGetExport!",
1297 "runtime", 3, dom, name, type);
1298
1299 foamPure(foam)((foam)->hdr.info.pure) = true1;
1300 return foam;
1301}
1302
1303
1304/*****************************************************************************
1305 *
1306 * :: Builtin getters
1307 *
1308 ****************************************************************************/
1309
1310static Table gen0BuiltinTable;
1311
1312/*
1313 * For the moment assume all builtin functions
1314 * take FOAM_Word arguments and return (possibly 0) FOAM_Words
1315 */
1316
1317void
1318gen0InitBuiltinTable()
1319{
1320 gen0BuiltinTable = tblNew((TblHashFun) aintPtrHash,
1321 (TblEqFun) aintPtrEqual);
1322}
1323
1324void
1325gen0FiniBuiltinTable()
1326{
1327 tblFree(gen0BuiltinTable);
1328 gen0BuiltinTable = NULL((void*)0);
1329}
1330
1331
1332localstatic Foam
1333gen0GetBuiltin(String libName, AInt glNo,
1334 Length inArgs, Length outArgs)
1335{
1336 Foam call, env, initfn, tmp;
1337 int idx;
1338
1339 if (gen0BuiltinTable == NULL((void*)0)) gen0InitBuiltinTable();
1340
1341 tmp = (Foam) tblElt(gen0BuiltinTable, (TblElt) glNo, (TblKey) NULL((void*)0));
1342
1343 if (tmp != NULL((void*)0))
1344 return foamCopy(tmp);
1345
1346 tmp = gen0TempLex(FOAM_Clos)gen0TempLex0(FOAM_Clos, 4);
1347
1348 initfn = gen0GVectFnByName(libName);
1349 idx = gen0GVectIdxByName(libName, glNo);
1350
1351 env = foamNewEnv(gen0RootEnv())foamNew(FOAM_Env, 1, (AInt)(gen0RootEnv()));
1352 call = gen0LazyFunGetByArgs(inArgs, outArgs,
1353 gen0DelayedInit(initfn, idx));
1354
1355 gen0AddStmt(foamNewDef(tmp, call)foamNew(FOAM_Def, 2, tmp, call), NULL((void*)0));
1356
1357 tblSetElt(gen0BuiltinTable, (TblKey) glNo, (TblElt) tmp);
1358
1359 return foamCopy(tmp);
1360
1361}