void routineEntry(SymTableNodePtr routineIdPtr) { if(debugger) debugger->traceRoutineEntry(routineIdPtr); memset(&returnValue, 0, sizeof(StackItem)); //------------------------------ // Switch to new code segment... codeSegmentPtr = routineIdPtr->defn.info.routine.codeSegment; //---------------------------------------------- // Allocate local variables onto system stack... for(SymTableNodePtr varIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.locals); varIdPtr != nullptr; varIdPtr = varIdPtr->next) if(varIdPtr->defn.info.data.varType == VAR_TYPE_NORMAL) allocLocal((TypePtr)(varIdPtr->typePtr)); }
/*-----------------------------------------------------------------*/ int allocVariables (symbol * symChain) { symbol *sym; symbol *csym; int stack = 0; int saveLevel = 0; /* go thru the symbol chain */ for (sym = symChain; sym; sym = sym->next) { /* if this is a typedef then add it */ /* to the typedef table */ if (IS_TYPEDEF (sym->etype)) { /* check if the typedef already exists */ csym = findSym (TypedefTab, NULL, sym->name); if (csym && csym->level == sym->level) werror (E_DUPLICATE_TYPEDEF, sym->name); SPEC_EXTR (sym->etype) = 0; addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0); continue; /* go to the next one */ } /* make sure it already exists */ csym = findSymWithLevel (SymbolTab, sym); if (!csym || (csym && csym->level != sym->level)) csym = sym; /* check the declaration */ checkDecl (csym, 0); /* if this is a function or a pointer to a */ /* function then do args processing */ if (funcInChain (csym->type)) { processFuncArgs (csym); } /* if this is an extern variable then change */ /* the level to zero temporarily */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) { saveLevel = csym->level; csym->level = 0; } /* if this is a literal then it is an enumerated */ /* type so need not allocate it space for it */ if (IS_LITERAL (sym->etype)) continue; /* generate the actual declaration */ if (csym->level) { allocLocal (csym); if (csym->onStack) stack += getSize (csym->type); } else allocGlobal (csym); /* restore the level */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) csym->level = saveLevel; } return stack; }
/*-----------------------------------------------------------------*/ static symbol * createStackSpil (symbol * sym) { symbol *sloc = NULL; struct dbuf_s dbuf; D (D_ALLOC, ("createStackSpil: for sym %p %s\n", sym, sym->name)); /* first go try and find a free one that is already existing on the stack */ if (applyToSet (_G.stackSpil, isFreeSTM8, &sloc, sym)) { /* found a free one : just update & return */ sym->usl.spillLoc = sloc; sym->stackSpil = 1; sloc->isFree = 0; addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: found existing\n")); return sym; } /* could not then have to create one , this is the hard part we need to allocate this on the stack : this is really a hack!! but cannot think of anything better at this time */ dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "sloc%d", _G.slocNum++); sloc = newiTemp (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); SPEC_SCLS (sloc->etype) = S_AUTO; SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE (sloc->etype) = 0; allocLocal (sloc); sloc->isref = 1; /* to prevent compiler warning */ wassertl (currFunc, "Local variable used outside of function."); /* if it is on the stack then update the stack */ if (IN_STACK (sloc->etype)) { if (currFunc) currFunc->stack += getSize (sloc->type); _G.stackExtend += getSize (sloc->type); } else { _G.dataExtend += getSize (sloc->type); } /* add it to the stackSpil set */ addSetHead (&_G.stackSpil, sloc); sym->usl.spillLoc = sloc; sym->stackSpil = 1; /* add it to the set of itempStack set of the spill location */ addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: created new\n")); return sym; }