|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)lab.c 5.1 (Berkeley) 6/5/85"; ! 9: #endif not lint ! 10: ! 11: #include "whoami.h" ! 12: #include "0.h" ! 13: #include "tree.h" ! 14: #include "opcode.h" ! 15: #include "objfmt.h" ! 16: #ifdef PC ! 17: # include "pc.h" ! 18: # include <pcc.h> ! 19: #endif PC ! 20: #include "tree_ty.h" ! 21: ! 22: /* ! 23: * Label enters the definitions ! 24: * of the label declaration part ! 25: * into the namelist. ! 26: */ ! 27: label(r, l) ! 28: struct tnode *r; ! 29: int l; ! 30: { ! 31: static bool label_order = FALSE; ! 32: static bool label_seen = FALSE; ! 33: #ifdef PC ! 34: char extname[ BUFSIZ ]; ! 35: #endif PC ! 36: #ifndef PI0 ! 37: register struct tnode *ll; ! 38: register struct nl *p, *lp; ! 39: ! 40: lp = NIL; ! 41: #else ! 42: send(REVLAB, r); ! 43: #endif ! 44: if ( ! progseen ) { ! 45: level1(); ! 46: } ! 47: line = l; ! 48: #ifndef PI1 ! 49: if (parts[ cbn ] & (CPRT|TPRT|VPRT|RPRT)){ ! 50: if ( opt( 's' ) ) { ! 51: standard(); ! 52: error("Label declarations should precede const, type, var and routine declarations"); ! 53: } else { ! 54: if ( !label_order ) { ! 55: label_order = TRUE; ! 56: warning(); ! 57: error("Label declarations should precede const, type, var and routine declarations"); ! 58: } ! 59: } ! 60: } ! 61: if (parts[ cbn ] & LPRT) { ! 62: if ( opt( 's' ) ) { ! 63: standard(); ! 64: error("All labels should be declared in one label part"); ! 65: } else { ! 66: if ( !label_seen ) { ! 67: label_seen = TRUE; ! 68: warning(); ! 69: error("All labels should be declared in one label part"); ! 70: } ! 71: } ! 72: } ! 73: parts[ cbn ] |= LPRT; ! 74: #endif ! 75: #ifndef PI0 ! 76: for (ll = r; ll != TR_NIL; ll = ll->list_node.next) { ! 77: l = (int) getlab(); ! 78: p = enter(defnl((char *) ll->list_node.list, LABEL, NLNIL, ! 79: (int) l)); ! 80: /* ! 81: * Get the label for the eventual target ! 82: */ ! 83: p->value[1] = (int) getlab(); ! 84: p->chain = lp; ! 85: p->nl_flags |= (NFORWD|NMOD); ! 86: p->value[NL_GOLEV] = NOTYET; ! 87: p->value[NL_ENTLOC] = l; ! 88: lp = p; ! 89: # ifdef OBJ ! 90: /* ! 91: * This operator is between ! 92: * the bodies of two procedures ! 93: * and provides a target for ! 94: * gotos for this label via TRA. ! 95: */ ! 96: (void) putlab((char *) l); ! 97: (void) put(2, O_GOTO | cbn<<8, (long)p->value[1]); ! 98: # endif OBJ ! 99: # ifdef PC ! 100: /* ! 101: * labels have to be .globl otherwise /lib/c2 may ! 102: * throw them away if they aren't used in the function ! 103: * which defines them. ! 104: */ ! 105: extlabname( extname , p -> symbol , cbn ); ! 106: putprintf(" .globl %s", 0, (int) extname); ! 107: if ( cbn == 1 ) { ! 108: stabglabel( extname , line ); ! 109: } ! 110: # endif PC ! 111: } ! 112: gotos[cbn] = lp; ! 113: # ifdef PTREE ! 114: { ! 115: pPointer Labels = LabelDCopy( r ); ! 116: ! 117: pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels; ! 118: } ! 119: # endif PTREE ! 120: #endif ! 121: } ! 122: ! 123: #ifndef PI0 ! 124: /* ! 125: * Gotoop is called when ! 126: * we get a statement "goto label" ! 127: * and generates the needed tra. ! 128: */ ! 129: gotoop(s) ! 130: char *s; ! 131: { ! 132: register struct nl *p; ! 133: #ifdef PC ! 134: char extname[ BUFSIZ ]; ! 135: #endif PC ! 136: ! 137: gocnt++; ! 138: p = lookup(s); ! 139: if (p == NIL) ! 140: return; ! 141: # ifdef OBJ ! 142: (void) put(2, O_TRA4, (long)p->value[NL_ENTLOC]); ! 143: # endif OBJ ! 144: # ifdef PC ! 145: if ( cbn == bn ) { ! 146: /* ! 147: * local goto. ! 148: */ ! 149: extlabname( extname , p -> symbol , bn ); ! 150: /* ! 151: * this is a funny jump because it's to a label that ! 152: * has been declared global. ! 153: * Although this branch is within this module ! 154: * the assembler will complain that the destination ! 155: * is a global symbol. ! 156: * The complaint arises because the assembler ! 157: * doesn't change relative jumps into absolute jumps. ! 158: * and this may cause a branch displacement overflow ! 159: * when the module is subsequently linked with ! 160: * the rest of the program. ! 161: */ ! 162: # ifdef vax ! 163: putprintf(" jmp %s", 0, (int) extname); ! 164: # endif vax ! 165: # ifdef mc68000 ! 166: putprintf(" jra %s", 0, (int) extname); ! 167: # endif mc68000 ! 168: } else { ! 169: /* ! 170: * Non-local goto. ! 171: * ! 172: * Close all active files between top of stack and ! 173: * frame at the destination level. Then call longjmp ! 174: * to unwind the stack to the destination level. ! 175: * ! 176: * For nested routines the end of the frame ! 177: * is calculated as: ! 178: * __disply[bn].fp + sizeof(local frame) ! 179: * (adjusted by (sizeof int) to get just past the end). ! 180: * The size of the local frame is dumped out by ! 181: * the second pass as an assembler constant. ! 182: * The main routine may not be compiled in this ! 183: * module, so its size may not be available. ! 184: * However all of its variables will be globally ! 185: * declared, so only the known runtime temporaries ! 186: * will be in its stack frame. ! 187: */ ! 188: parts[ bn ] |= NONLOCALGOTO; ! 189: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) ! 190: , "_PCLOSE" ); ! 191: if ( bn > 1 ) { ! 192: p = lookup( enclosing[ bn - 1 ] ); ! 193: sprintf( extname, "%s%d+%d", ! 194: FRAME_SIZE_LABEL, p -> value[NL_ENTLOC], sizeof(int)); ! 195: p = lookup(s); ! 196: putLV( extname , bn , 0 , NNLOCAL , PCCTM_PTR | PCCT_CHAR ); ! 197: } else { ! 198: putLV((char *) 0 , bn , -( DPOFF1 + sizeof( int ) ) , LOCALVAR , ! 199: PCCTM_PTR | PCCT_CHAR ); ! 200: } ! 201: putop( PCC_CALL , PCCT_INT ); ! 202: putdot( filename , line ); ! 203: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) ! 204: , "_longjmp" ); ! 205: putLV((char *) 0 , bn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); ! 206: extlabname( extname , p -> symbol , bn ); ! 207: putLV( extname , 0 , 0 , NGLOBAL , PCCTM_PTR|PCCT_STRTY ); ! 208: putop( PCC_CM , PCCT_INT ); ! 209: putop( PCC_CALL , PCCT_INT ); ! 210: putdot( filename , line ); ! 211: } ! 212: # endif PC ! 213: if (bn == cbn) ! 214: if (p->nl_flags & NFORWD) { ! 215: if (p->value[NL_GOLEV] == NOTYET) { ! 216: p->value[NL_GOLEV] = level; ! 217: p->value[NL_GOLINE] = line; ! 218: } ! 219: } else ! 220: if (p->value[NL_GOLEV] == DEAD) { ! 221: recovered(); ! 222: error("Goto %s is into a structured statement", p->symbol); ! 223: } ! 224: } ! 225: ! 226: /* ! 227: * Labeled is called when a label ! 228: * definition is encountered, and ! 229: * marks that it has been found and ! 230: * patches the associated GOTO generated ! 231: * by gotoop. ! 232: */ ! 233: labeled(s) ! 234: char *s; ! 235: { ! 236: register struct nl *p; ! 237: #ifdef PC ! 238: char extname[ BUFSIZ ]; ! 239: #endif PC ! 240: ! 241: p = lookup(s); ! 242: if (p == NIL) ! 243: return; ! 244: if (bn != cbn) { ! 245: error("Label %s not defined in correct block", s); ! 246: return; ! 247: } ! 248: if ((p->nl_flags & NFORWD) == 0) { ! 249: error("Label %s redefined", s); ! 250: return; ! 251: } ! 252: p->nl_flags &= ~NFORWD; ! 253: # ifdef OBJ ! 254: patch4((PTR_DCL) p->value[NL_ENTLOC]); ! 255: # endif OBJ ! 256: # ifdef PC ! 257: extlabname( extname , p -> symbol , bn ); ! 258: putprintf( "%s:" , 0 , (int) extname ); ! 259: # endif PC ! 260: if (p->value[NL_GOLEV] != NOTYET) ! 261: if (p->value[NL_GOLEV] < level) { ! 262: recovered(); ! 263: error("Goto %s from line %d is into a structured statement", s, (char *) p->value[NL_GOLINE]); ! 264: } ! 265: p->value[NL_GOLEV] = level; ! 266: } ! 267: #endif ! 268: ! 269: #ifdef PC ! 270: /* ! 271: * construct the long name of a label based on it's static nesting. ! 272: * into a caller-supplied buffer (that should be about BUFSIZ big). ! 273: */ ! 274: extlabname( buffer , name , level ) ! 275: char buffer[]; ! 276: char *name; ! 277: int level; ! 278: { ! 279: char *starthere; ! 280: int i; ! 281: ! 282: starthere = &buffer[0]; ! 283: for ( i = 1 ; i < level ; i++ ) { ! 284: sprintf( starthere , EXTFORMAT , enclosing[ i ] ); ! 285: starthere += strlen( enclosing[ i ] ) + 1; ! 286: } ! 287: sprintf( starthere , EXTFORMAT , "" ); ! 288: starthere += 1; ! 289: sprintf( starthere , LABELFORMAT , name ); ! 290: starthere += strlen( name ) + 1; ! 291: if ( starthere >= &buffer[ BUFSIZ ] ) { ! 292: panic( "extlabname" ); ! 293: } ! 294: } ! 295: #endif PC
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.