home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)allocate.c 1.4 3/2/88
- */
- #include <stdio.h>
- #include "assert.h"
- #include "addresses.h"
- #include "nodes.h"
- #include "map.h"
- #include "sequence.h"
- #include "system.h"
- #include "semantics.h"
- #include "flags.h"
- #include "builtins.h"
- #include "evaluate.h"
- #include "opNames.h"
- #include "allocate.h"
- #include "trace.h"
- #include "option.h"
- #include "genutils.h"
-
- /*
- * This is the allocation pass of the compiler. The basic purpose is to
- * traverse the tree, deciding on the concrete type and implementation kind
- * of each variable and constant (constants should be easy), to allocate
- * space in the activation records and object data areas, and to determine
- * the address of each thing. In addition, since we are stupid about
- * generating code, we also need to allocate the addresses of the temporaries
- * used in expression evaluation, in particular, multiple assignments.
- *
- * The current algorithm for determining concrete type and implementation
- * kind information is very simple. Integers, Characters, Booleans, Real are
- * Direct Builtins, Strings, Time and Conditions are
- * Local Builtins, and everything else, including arrays and vectors, are
- * Globals.
- */
-
- static void doChildren(), allocateSpaceInObject(),
- allocateSpaceInActivation();
-
- static Map allocMap;
- Address nullAddress = {0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- AllocationInfoPtr allocateAllocationInfo(p)
- NodePtr p;
- {
- AllocationInfoPtr ap;
- ap = (AllocationInfoPtr) Map_Lookup(allocMap, (int) p);
- assert((int) ap == NIL || (int) ap == 1);
- ap = (AllocationInfoPtr) calloc(sizeof(AllocationInfo), 1);
- Map_Insert(allocMap, (int)p, (int) ap);
- return(ap);
- }
-
- AllocationInfoPtr fetchAllocationInfo(p)
- NodePtr p;
- {
- AllocationInfoPtr ap;
- ap = (AllocationInfoPtr) Map_Lookup(allocMap, (int) p);
- assert((int) ap != NIL);
- return(ap);
- }
-
- typedef struct DeclInfo {
- NodePtr scope;
- NodePtr identList;
- struct DeclInfo *next;
- } DeclInfo, *DeclInfoPtr;
-
- static DeclInfoPtr stack = NULL;
-
- static void push(p)
- NodePtr p;
- {
- register DeclInfoPtr t;
- t = (DeclInfoPtr) malloc(sizeof(DeclInfo));
- t->scope = p;
- t->identList = NN;
- t->next = stack;
- stack = t;
- }
-
- static void swap()
- {
- DeclInfoPtr temp, temp2;
- assert(stack != NULL);
- assert(stack->next != NULL);
- temp2 = stack->next->next;
- temp = stack;
- stack = stack->next;
- temp->next = stack->next;
- stack->next = temp;
- assert(stack != NULL);
- assert(stack->next != NULL);
- assert(temp2 == stack->next->next);
- }
-
- static void writeAddress(fp, a)
- FILE *fp;
- Address a;
- {
- DD d;
- d.kind = DD_Address;
- d.value.address = a;
- displayDD(fp, d, '\0');
- }
-
- extern FILE *treeFile;
-
- static void pop()
- {
- register NodePtr p;
- DeclInfoPtr this = stack;
- Symbol st;
- Tag tag;
- stack = this->next;
- tag = this->scope->tag;
- if (tag == P_OBLIT) {
- allocateSpaceInObject(this->scope, this->identList, FALSE);
- } else if (tag == P_INITDEF) {
- assert(stack != NULL);
- assert(stack->scope != NULL);
- assert(stack->scope->tag == P_OBLIT);
- allocateSpaceInActivation((NodePtr)((int)(stack->scope)+1),
- this->identList, FALSE);
- } else if (tag == P_OPDEF || tag == P_OPSIG ||
- tag == P_PROCESSDEF || tag == P_RECOVERYDEF) {
- allocateSpaceInActivation(this->scope, this->identList, FALSE);
- } else if (tag == P_COMP) {
- allocateSpaceInObject(this->scope, this->identList, FALSE);
- } else if (tag == P_ATLIT) {
- assert(Sequence_Length(this->identList) == 0);
- } else {
- assert(FALSE);
- }
-
- IFTRACE(allocate, 1) {
- fprintf(stdout, "%s ", tagNames[(int)this->scope->tag]);
- if (this->scope->tag == P_OPDEF) {
- fprintf(stdout, "%s ",
- ON_Name(this->scope->b.opdef.sig->b.opsig.name->b.opname.id));
- } else if (this->scope->tag == P_OPSIG) {
- fprintf(stdout, "%s ", ON_Name(this->scope->b.opsig.name->b.opname.id));
- } else if (this->scope->tag == P_OBLIT) {
- st = ST_Fetch(this->scope->b.oblit.name->b.symdef.symbol);
- fprintf(stdout, "%s ", ST_SymbolName(st));
- }
- if (Sequence_Length(this->identList) == 0) {
- fprintf(stdout, "defines nothing");
- } else {
- fprintf(stdout, "defines:\n ");
- Sequence_For(p, this->identList)
- fprintf(stdout, "%s ", ST_SymbolName(ST_Fetch(p->b.symref.symbol)));
- writeAddress(stdout, ST_Fetch(p->b.symdef.symbol)->v.address);
- fprintf(stdout, ", ");
- Sequence_Next
- }
- fprintf(stdout, "\n");
- }
- free((char *)this);
- }
-
- void allocate();
-
- void initializeAllocate()
- {
- }
-
- void ATCTToSizeAndKind(at, ct, isAttached, size, ak)
- NodePtr at, ct;
- Boolean isAttached;
- int *size;
- AllocateKind *ak;
- {
- OID atOID, ctOID;
- at = figureOutAT(at);
- atOID = at->b.atlit.id;
- if (atOID == OIDOfBuiltin(B_INSTAT, BOOLEANINDEX) ||
- atOID == OIDOfBuiltin(B_INSTAT, CHARACTERINDEX)) {
- *ak = AK_Boring; *size = 1;
- } else if (atOID == OIDOfBuiltin(B_INSTAT, INTEGERINDEX) ||
- atOID == OIDOfBuiltin(B_INSTAT, REALINDEX)) {
- *ak = AK_Boring; *size = 4;
- } else if (atOID == OIDOfBuiltin(B_INSTAT, STRINGINDEX) ||
- atOID == OIDOfBuiltin(B_INSTAT, TIMEINDEX)) {
- *ak = AK_Local ; *size = 4;
- } else if (atOID == OIDOfBuiltin(B_INSTAT, CONDITIONINDEX) ||
- atOID == OIDOfBuiltin(B_INSTAT, NODEINDEX)) {
- if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
- *size = 4;
- } else {
- if (ct == NULL && at->b.atlit.f.cannotBeConformedTo) {
- extern NodePtr OTLookup();
- assert(at->b.atlit.codeOID != NULL);
- ct = OTLookup(at->b.atlit.codeOID);
- }
- if (ct != NULL) {
- ctOID = getID(ct);
- if (ctOID == OIDOfBuiltin(B_INSTCT, BOOLEANINDEX) ||
- ctOID == OIDOfBuiltin(B_INSTCT, CHARACTERINDEX)) {
- *ak = AK_Boring; *size = 1;
- } else if (ctOID == OIDOfBuiltin(B_INSTCT, INTEGERINDEX) ||
- ctOID == OIDOfBuiltin(B_INSTCT, REALINDEX)) {
- *ak = AK_Boring; *size = 4;
- } else if (ctOID == OIDOfBuiltin(B_INSTCT, STRINGINDEX) ||
- ctOID == OIDOfBuiltin(B_INSTCT, TIMEINDEX)) {
- *ak = AK_Local ; *size = 4;
- } else if (ctOID == OIDOfBuiltin(B_INSTCT, CONDITIONINDEX) ||
- ctOID == OIDOfBuiltin(B_INSTCT, NODEINDEX)) {
- if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
- *size = 4; /* local => we know CT */
- } else {
- if (isAttached) *ak = AK_AttachedLocal; else *ak = AK_Local;
- *size = 4; /* local => we know CT */
- }
- } else if (isAttached) {
- *ak = AK_AttachedGlobal; *size = 8;
- } else {
- *ak = AK_Global; *size = 8;
- }
- }
- }
-
- void figureSizeAndKind(sym, size, ak)
- Symbol sym;
- int *size;
- AllocateKind *ak;
- {
- ATCTToSizeAndKind(sym->value.ATinfo, sym->value.CTinfo, sym->isAttached,
- size, ak);
- if (*size == 1) *size = 4;
- }
-
- static void allocateSpaceInObject(scope, identList, secondTry)
- NodePtr scope, identList;
- Boolean secondTry;
- {
- int sizes[NUMKINDS], offsets[NUMKINDS];
- int size, i, offset;
- AllocateKind ak;
- register NodePtr p;
- register Symbol sym;
- AllocationInfoPtr ap;
- int firstinstanceoffset = firstInstanceOffset;
-
- assert(!secondTry);
- for (i = 0; i < NUMKINDS; i++) {
- sizes [i] = 0;
- offsets[i] = 0;
- }
- /*
- * Allocate the monitor lock.
- */
- if (scope->tag == P_OBLIT && scope->b.oblit.monitor != NN &&
- ! scope->b.oblit.monitor->b.monitor.mayBeElided) {
- sizes[AK_Monitor] += 8; offsets[AK_Monitor] = sizes[AK_Monitor];
- }
- if (scope->tag == P_OBLIT && scope->b.oblit.f.immutable) {
- /* we allocate space for the ownOID field */
- firstinstanceoffset += sizeof(OID);
- }
- Sequence_For(p, identList)
- assert(p->tag == P_SYMDEF);
- sym = ST_Fetch(p->b.symdef.symbol);
- figureSizeAndKind(sym, &size, &ak);
- sizes [ak] += size;
- Sequence_Next
- Sequence_For(p, identList)
- assert(p->tag == P_SYMDEF);
- sym = ST_Fetch(p->b.symdef.symbol);
- figureSizeAndKind(sym, &size, &ak);
- sym->v.address = nullAddress;
- sym->v.address.base = Global;
- offset = firstinstanceoffset;
- for (i = ak+1; i < NUMKINDS; i++) {
- offset += sizes[i];
- }
- offset += offsets[ak];
- sym->v.address.offset = offset;
- offsets[ak] += size;
- Sequence_Next
- for (i = 0; i < NUMKINDS; i++) {
- assert(offsets[i] == sizes[i]);
- }
- ap = allocateAllocationInfo(scope);
- ap->isDataArea = TRUE;
- ap->isActivation = FALSE;
- ap->scope = scope;
- ap->identList = identList;
- ap->parameterSize = 0;
- ap->resultSize = 0;
- ap->boringSize = sizes[AK_Boring];
- ap->localSize = sizes[AK_Local];
- ap->attachedLocalSize = sizes[AK_AttachedLocal];
- ap->globalSize = sizes[AK_Global];
- ap->attachedGlobalSize = sizes[AK_AttachedGlobal];
- ap->monitorSize = sizes[AK_Monitor];
- ap->invokeQueueSize = sizes[AK_InvokeQueue];
- }
-
- static void allocateSpaceInActivation(scope, identList, secondTry)
- NodePtr scope, identList;
- Boolean secondTry;
- {
- int resultSize = 0, resultOffset = 0,
- parameterSize = 0, parameterOffset = 0,
- sizes[NUMKINDS], offsets[NUMKINDS],
- assignToRegs[NUMKINDS], nextReg[NUMKINDS];
- register NodePtr p;
- register Symbol sym;
- NodePtr paramList = NULL, resultList = NULL;
- AllocationInfoPtr ap;
- register int i, whichReg;
- int size, offset, nAvailable, nextFreeReg;
- #ifdef sun
- int nAvailableAddress, nAvailableData;
- int nextFreeRegAddress, nextFreeRegData;
- #endif
- AllocateKind ak;
- RAInfo regs[NALLOCATABLE];
-
- for (i = 0; i < NUMKINDS; i++) {
- sizes [i] = 0; assignToRegs[i] = 0;
- offsets[i] = 0; nextReg[i] = 0;
- }
- if (! secondTry) {
- for (i = 0; i < NALLOCATABLE; i++) {
- regs[i].isAllocated = FALSE;
- }
- /*
- * TODO: When I know how to get rid of the InvokeQueue, I can change this.
- */
- sizes[AK_InvokeQueue] = sizeof(InvokeQueue);
- offsets[AK_InvokeQueue] = sizes[AK_InvokeQueue];
-
- Sequence_For(p, identList)
- assert(p->tag == P_SYMDEF ||
- p->tag == P_SYMREF);
- sym = ST_Fetch(p->b.symdef.symbol);
- switch (sym->itsKind) {
- case ST_Param:
- parameterSize += 8;
- Sequence_Add(¶mList, p);
- break;
- case ST_Result:
- resultSize += 8;
- Sequence_Add(&resultList, p);
- break;
- case ST_Var:
- case ST_Const:
- figureSizeAndKind(sym, &size, &ak);
- sizes [ak] += size;
- break;
- default:
- assert(FALSE);
- break;
- }
- Sequence_Next
- /*
- * Decide which variables go in the registers. We need to adjust the
- * required sizes of the various storage classes. For now, we will
- * just put locals, then data, then globals into the available registers.
- */
- # define MIN(A,B) ((A) < (B) ? (A) : (B))
-
- IFOPTION(allocateregisters, 1) {
- #ifdef vax
- nAvailable = NALLOCATABLE * sizeof(int);
- nextFreeReg = MINALLOCATABLE;
- #endif
- #ifdef sun
- nAvailableAddress = 2 * sizeof(int);
- nAvailableData = (NALLOCATABLE-2) * sizeof(int);
- nextFreeRegAddress = MINALLOCATABLE;
- nextFreeRegData = MINALLOCATABLE + 2;
- nAvailable = nAvailableAddress;
- nextFreeReg = nextFreeRegAddress;
- #endif
- assignToRegs[AK_Local] = MIN(nAvailable, sizes[AK_Local]) / sizeof(int);
- sizes[AK_Local] -= assignToRegs[AK_Local] * sizeof(int);
- nextReg[AK_Local] = nextFreeReg;
- nAvailable -= assignToRegs[AK_Local] * sizeof(int);
- nextFreeReg += assignToRegs[AK_Local];
-
- assignToRegs[AK_AttachedLocal] = MIN(nAvailable, sizes[AK_AttachedLocal]) / sizeof(int);
- sizes[AK_AttachedLocal] -= assignToRegs[AK_AttachedLocal] * sizeof(int);
- nextReg[AK_AttachedLocal] = nextFreeReg;
- nAvailable -= assignToRegs[AK_AttachedLocal] * sizeof(int);
- nextFreeReg += assignToRegs[AK_AttachedLocal];
- #ifdef sun
- nAvailableAddress = nAvailable;
- nextFreeRegAddress = nextFreeReg;
- nAvailable = nAvailableData;
- nextFreeReg = nextFreeRegData;
- #endif
- assignToRegs[AK_Boring] = MIN(nAvailable, sizes[AK_Boring]) / sizeof(int);
- sizes[AK_Boring] -= assignToRegs[AK_Boring] * sizeof(int);
- nextReg[AK_Boring] = nextFreeReg;
- nAvailable -= assignToRegs[AK_Boring] * sizeof(int);
- nextFreeReg += assignToRegs[AK_Boring];
- #ifdef sun
- nAvailableData = nAvailable;
- nextFreeRegData = nextFreeReg;
- nAvailable = nAvailableAddress;
- nextFreeReg = nextFreeRegAddress;
- #endif
- assignToRegs[AK_Global] = MIN(nAvailable, sizes[AK_Global])
- / ( 2 * sizeof(int));
- sizes[AK_Global] -= assignToRegs[AK_Global] * 8;
- nextReg[AK_Global] = nextFreeReg;
- nAvailable -= assignToRegs[AK_Global] * 8;
- nextFreeReg += assignToRegs[AK_Global];
-
- assignToRegs[AK_AttachedGlobal] = MIN(nAvailable, sizes[AK_AttachedGlobal])
- / ( 2 * sizeof(int));
- sizes[AK_AttachedGlobal] -= assignToRegs[AK_AttachedGlobal] * 8;
- nextReg[AK_AttachedGlobal] = nextFreeReg;
- nAvailable -= assignToRegs[AK_AttachedGlobal] * 8;
- nextFreeReg += assignToRegs[AK_AttachedGlobal];
- #ifdef sun
- nAvailableAddress = nAvailable;
- nextFreeRegAddress = nextFreeReg;
- #endif
- }
- } else {
- ap = fetchAllocationInfo(scope);
- for (i = 0 ; i < NALLOCATABLE; i++) {
- regs[i] = ap->regs[i];
- }
- sizes[AK_AttachedGlobal] = ap->attachedGlobalSize;
- sizes[AK_Global] = ap->globalSize;
- sizes[AK_AttachedLocal] = ap->attachedLocalSize;
- sizes[AK_Local] = ap->localSize;
- sizes[AK_Boring] = ap->boringSize;
- sizes[AK_Monitor] = ap->monitorSize;
- sizes[AK_InvokeQueue] = ap->invokeQueueSize;
- parameterSize = ap->parameterSize;
- resultSize = ap->resultSize;
- }
- Sequence_For(p, identList)
- assert(p->tag == P_SYMDEF ||
- p->tag == P_SYMREF);
- sym = ST_Fetch(p->b.symdef.symbol);
- switch (sym->itsKind) {
- case ST_Param:
- parameterOffset += 8;
- offset = firstParameterOffset + parameterSize - parameterOffset;
- if (secondTry) {
- assert(sym->v.address.offset == offset);
- } else {
- sym->v.address = nullAddress;
- sym->v.address.base = Local;
- sym->v.address.offset = offset;
- }
- break;
- case ST_Result:
- resultOffset += 8;
- offset =
- firstParameterOffset + parameterSize + resultSize - resultOffset;
- if (secondTry) {
- assert(sym->v.address.offset == offset);
- } else {
- sym->v.address = nullAddress;
- sym->v.address.base = Local;
- sym->v.address.offset = offset;
- }
- break;
- case ST_Var:
- case ST_Const:
- figureSizeAndKind(sym, &size, &ak);
- if (secondTry && sym->v.address.base == Register) {
- /* do nothing - all done */
- } else if (!secondTry && OPTION(allocateregisters, 1) &&
- assignToRegs[ak] > 0) {
- /* assign it to a register */
- sym->v.address = nullAddress;
- sym->v.address.base = Register;
- sym->v.address.offset = nextReg[ak];
- whichReg = sym->v.address.offset - MINALLOCATABLE;
- regs[whichReg].isAllocated = TRUE;
- regs[whichReg].isAttached =
- (ak == AK_AttachedLocal || ak == AK_AttachedGlobal);
- regs[whichReg].itsKind = ak;
- assignToRegs[ak] --;
- nextReg[ak] ++;
- if (ak == AK_Global || ak == AK_AttachedGlobal) {
- /* do the next register, too */
- regs[whichReg+1].isAllocated = TRUE;
- regs[whichReg+1].isAttached = ak == AK_AttachedGlobal;
- regs[whichReg+1].itsKind = ak;
- nextReg[ak] ++;
- }
- } else {
- offset = firstLocalOffset;
- for (i = ak+1; i < NUMKINDS; i++) {
- offset += sizes[i];
- }
- /*
- * Note that on locals, since the stack grows backwards we increment
- * the offset before we take the address of the thing.
- */
- offsets[ak] += size;
- offset += offsets[ak];
- if (secondTry && sym->v.address.offset != -offset) {
- TRACE3(allocate, 1, "%s changed from %d to %d", ST_SymbolName(sym),
- sym->v.address.offset, -offset);
- }
- sym->v.address = nullAddress;
- sym->v.address.base = Local;
- sym->v.address.offset = - offset;
- }
- break;
- default:
- assert(FALSE);
- break;
- }
- Sequence_Next
- assert(parameterOffset == parameterSize);
- assert(resultOffset == resultSize);
- if (!secondTry) {
- for (i = 0; i < NUMKINDS; i++) {
- assert(offsets[i] == sizes[i]);
- }
- ap = allocateAllocationInfo(scope);
- ap->isDataArea = FALSE;
- ap->isActivation = TRUE;
- ap->scope = scope;
- ap->identList = identList;
- ap->parameterSize = parameterSize;
- ap->resultSize = resultSize;
- ap->attachedGlobalSize = sizes[AK_AttachedGlobal];
- ap->globalSize = sizes[AK_Global];
- ap->attachedLocalSize = sizes[AK_AttachedLocal];
- ap->localSize = sizes[AK_Local];
- ap->boringSize = sizes[AK_Boring];
- ap->monitorSize = sizes[AK_Monitor];
- ap->invokeQueueSize = sizes[AK_InvokeQueue];
- ap->paramList = paramList;
- ap->resultList = resultList;
- for (i = 0; i < NALLOCATABLE; i++)
- ap->regs[i] = regs[i];
- }
- }
-
- #define doChildren(p) {\
- Sequence_For(child, p)\
- if (child != NULL) allocate(child);\
- Sequence_Next\
- }
-
-
- #define ISANABSTRACTTYPEID(X) \
- ((X) == OIDOfBuiltin(B_INSTAT, ABSTRACTTYPEINDEX) || \
- (X) == OIDOfBuiltin(B_INSTAT, SIGNATUREINDEX))
-
- Boolean isARealImport(st, gen)
- register Symbol st;
- Boolean gen;
- {
- #undef PASSABSTRACTTYPES
- #ifdef PASSABSTRACTTYPES
- register NodePtr at;
- Boolean result;
- if (! st->isManifest) return(TRUE);
- at = figureOutAT(st->value.ATinfo);
- assert(at->tag == P_ATLIT);
- if (at->b.atlit.f.writeSeparately) return(FALSE);
- result = ISANABSTRACTTYPEID(at->b.atlit.id);
- return(! result);
- #else
- if (gen) {
- return(! st->isManifest);
- } else {
- return(st->value.value == NN);
- }
- #endif
- }
-
- static Boolean doneFirstObject;
-
- void doAllocate(p, finalPass)
- NodePtr p;
- Boolean finalPass;
- {
- NodePtr scope;
- AllocationInfoPtr aip;
- if (!finalPass) {
- if (allocMap != (Map) NULL) Map_Destroy(allocMap);
- allocMap = Map_Create();
- doneFirstObject = FALSE;
- allocate(p);
- } else {
- Map_For(allocMap, scope, aip)
- if (! aip->isActivation) continue;
- /* redo the allocation to fix the temporary stuff */
- allocateSpaceInActivation(scope, aip->identList, TRUE);
- IFTRACE(allocate, 1) {
- fprintf(stdout, "%s ", tagNames[(int)aip->scope->tag]);
- if (aip->scope->tag == P_OPDEF) {
- fprintf(stdout, "%s ",
- ON_Name(aip->scope->b.opdef.sig->b.opsig.name->b.opname.id));
- } else if (aip->scope->tag == P_OPSIG) {
- fprintf(stdout, "%s ", ON_Name(aip->scope->b.opsig.name->b.opname.id));
- }
-
- if (Sequence_Length(aip->identList) == 0) {
- fprintf(stdout, "defines nothing");
- } else {
- fprintf(stdout, "defines:\n ");
- Sequence_For(p, aip->identList)
- fprintf(stdout, "%s ", ST_SymbolName(ST_Fetch(p->b.symref.symbol)));
- writeAddress(stdout, ST_Fetch(p->b.symdef.symbol)->v.address);
- fprintf(stdout, ", ");
- Sequence_Next
- }
- fprintf(stdout, "\n");
- }
- Map_Next
- }
- }
-
- Boolean isAManifestConstant(sym)
- Symbol sym;
- {
- if (sym->isManifest) {
- if (! Zflag) return(TRUE);
- if (sym->value.value->tag != P_OBLIT) return(TRUE);
- if (sym->value.value->b.oblit.f.immutable) return(TRUE);
- }
- return(FALSE);
- }
-
- void allocate(p)
- NodePtr p;
- {
- NodePtr setqs, q, r, s, phoneyInitially;
- Symbol sym, paramsym;
- register NodePtr child;
-
- if ((int) p <= 0x200) return;
-
- switch (p->tag) {
- case P_OBLIT:
- if (doneFirstObject) return;
- doneFirstObject = TRUE;
- /*
- * We push a phoney initially, and when we hit initially it should be
- * there, under the object record. When we get to the initially we
- * will have to find this one.
- */
- phoneyInitially = Construct(P_INITDEF, 2, NULL, NULL);
- push(p);
- push(phoneyInitially);
- setqs = p->b.oblit.setq;
- Sequence_For(q, setqs)
- /*
- * For each import that is a real import, we declare space as a parameter
- * for the initially. If the import is used outside of the initially, then
- * we also allocate space for it in the object itself. The initially code
- * will assign the parameter to the newly allocated space.
- */
- assert(q->tag == P_SETQ);
- r = q->b.setq.inner;
- assert(r->tag == P_SYMDEF);
- sym = ST_Fetch(r->b.symref.symbol);
- if (isARealImport(sym, TRUE)) {
- /*
- * This is a real import.
- */
- assert(sym->isImport);
- s = Construct(P_SYMDEF, 0);
- s->b.symdef.ident = r->b.symref.ident;
- s->b.symdef.symbol = ST_Create(p, s->b.symdef.ident);
- q->b.setq.param = s;
- paramsym = ST_Fetch(s->b.symdef.symbol);
- *paramsym = *sym;
- paramsym->itsKind = ST_Param;
- Sequence_Add(&stack->identList, s);
- if (sym->usedOutsideInitially)
- Sequence_Add(&stack->next->identList, q->b.setq.inner);
- }
- Sequence_Next
- swap();
- /* This is a do children, but don't do my own name. */
- Sequence_For(child, p)
- if (child != NULL && child != p->b.oblit.name) allocate(child);
- Sequence_Next
- assert(stack->scope->tag == P_OBLIT);
- if (stack->next != NULL && stack->next->scope == phoneyInitially) {
- swap();
- pop();
- }
- pop();
- break;
- case P_COMP:
- push(p);
- doneFirstObject = TRUE;
- doChildren(p);
- pop();
- break;
- case P_PARAM:
- assert(p->b.param.move == p->b.param.sym->b.symdef.symbol->isMove);
- assert(p->b.param.isAttached == p->b.param.sym->b.symdef.symbol->isAttached);
- case P_VARDECL:
- doChildren(p);
- break;
- case P_CONSTDECL:
- sym = p->b.constdecl.sym->b.symdef.symbol;
- if (isAManifestConstant(sym)) return;
- doChildren(p);
- break;
- case P_PROCESSDEF:
- case P_RECOVERYDEF:
- case P_OPDEF:
- push(p);
- doChildren(p);
- pop();
- break;
- case P_ATLIT:
- if (doneFirstObject) return;
- doneFirstObject = TRUE;
- push(p);
- q = p->b.atlit.ops;
- /* q is a sequence of operation signatures. */
- Sequence_For(s, q)
- if (Map_Lookup(allocMap, (int)s) == NIL) {
- push(s);
- allocate(s);
- pop();
- }
- Sequence_Next
- pop();
- break;
- case P_INITDEF:
- /*
- * We cheated before, now we reverse the order of the two top ones, and
- * continue.
- */
- swap();
- assert(stack->scope->tag == P_INITDEF);
- stack->scope = p;
- doChildren(p);
- pop();
- break;
- case P_SYMDEF:
- Sequence_Add(&stack->identList, p);
- break;
- case P_GLOBALREF:
- break;
- case P_SETQ:
- break;
- default:
- doChildren(p);
- break;
- }
- }
-