C:/Users/Dennis/src/lang/russell.orig/src/pass5c/allocate.c

Go to the documentation of this file.
00001 #define DEBUG
00002 /*
00003  *      Static Storage Allocator.
00004  *
00005  *      This routine walks the tree, associating with declarations and 
00006  *  parameters a level and displacement.  It also calculates the size of
00007  *  the activation record needed for a procedure.  
00008  *      Allocate expects a node of kind FUNCCONSTR.     
00009  *      Note that static nesting levels are reset here, to reflect the
00010  *  fact that some blocks actually require activation records.
00011  */
00012 
00013 # ifdef VERBOSE
00014 #   define IFVERBOSE(x) x
00015 # else
00016 #   define IFVERBOSE(x)
00017 # endif
00018 
00019 # include "parm.h"
00020 # include <stdio.h>
00021 # include "stree/ststructs.mh"
00022 # include "codeutil.h"
00023 # include "../pass4/sigs.h"
00024 
00025 # define MAXOBJSZ 512 /* Should agree with runtime */
00026 
00027 extern FILE * unparse_file;
00028 
00029 NODE * Vcurrent_func;       /* Immediately surrounding function construction */
00030 NODE * Vcurrent_ar;         /* Immediately surrounding construct (block */
00031                             /* or function) requiring an act. record.   */
00032 
00033 int Vstatic_level = -1;
00034 int Vnext_free;             /* Next location in activation record to be */
00035                             /* allocated.                               */
00036 int Vhigh_water;            /* max(Vnext_free, Vhigh_water) = highest   */
00037                             /* numbered location allocated so far.  At  */
00038                             /* the end of a fn this is the required a.r.*/
00039                             /* size.                                    */
00040 
00041 boolean Vextent_limited;     /* Variables can't outlive current function  */
00042                              /* activation & current block is executed    */
00043                              /* only once in current fn activation.       */
00044 boolean Vallocate_on_stack;  /* It is safe to allocate variables directly */
00045                              /* in the activation record in the current   */
00046                              /* context.                                  */
00047                              /* This implies Vextent_limited and callcc   */
00048                              /* can't be called.                          */
00049                              /* On the VAX it also means that a.r. must   */
00050                              /* always be stack allocated, since pointers */
00051                              /* to the middle of objects may o.w. result  */
00052                              /* Even if this is false, individual vars    */
00053                              /* may be allocated directly in a.r. if no   */
00054                              /* references to that particular             */
00055                              /* variable can be created.                  */
00056 boolean Vcallcc;             /* Current function may save a continuation  */
00057 
00058 extern boolean Nflag; /* No Callcc calls */
00059 extern boolean Vflag;
00060 extern boolean Gflag;
00061 extern boolean Rflag; /* Use registers as much as possible. */
00062 extern boolean hflag; /* Don't stack allocate variables.    */
00063 
00064 extern long max_addr_regs; /* Try to allocate this many non-parameter */
00065                            /* represented by pointers to registers    */
00066 extern long max_int_regs;  /* Number of non-pointers to allocate to regs */
00067 long n_addr_regs = 0;      /* Number of virtual registers allocated to */
00068 long n_int_regs = 0;       /* variables so far.                        */
00069                            /* Note that the distinction between int and  */
00070                            /* addr is very approximate.  All initialized */
00071                            /* variables, as well as all non-variables    */
00072                            /* count as ints.                             */
00073 
00074 extern int yynerrs;
00075 
00076 int n_decls;        /* Number of declarations in current block */
00077 
00078 /* List of blocks in current function */
00079 struct blocks {
00080     struct blocks * bl_next;
00081     NODE * bl_block;
00082 } * Vcurrent_blocks = NIL;
00083 
00084 /* Free nodes on current block list */
00085 void Vfree_blocks()
00086 {
00087     struct blocks *p;
00088 
00089     while (Vcurrent_blocks != NIL) {
00090         p = Vcurrent_blocks;
00091         Vcurrent_blocks = Vcurrent_blocks -> bl_next;
00092         free(p);
00093     }
00094 }
00095 
00096 /* Make sure variables declared in blocks parallel to block     */
00097 /* are not allocated directly in a.r., since their locations    */
00098 /* are no longer guaranteed to be retained until function exit. */
00099 void realloc_blocks(block)
00100 NODE * block;
00101 {
00102     struct blocks *p;
00103 
00104     /* Process preceding parallel blocks. */
00105       for(p = Vcurrent_blocks; p != NIL; p = p -> bl_next) {
00106         /* Blocks are added in preorder.                     */
00107         /* Thus p -> bl_block -> pre_num < block -> pre_num  */
00108         if (p -> bl_block -> post_num < block -> post_num /* not ancestor */) {
00109             switch (p -> bl_block -> kind) {
00110                 case BLOCKDENOTATION:
00111                     maplist(s, p -> bl_block -> bld_declaration_list, {
00112                       if (s -> decl_special & VAR_NONTR_REF) {
00113                         if (Vflag && (s -> decl_special & VAR_ON_STACK)) {
00114                             printf("Parallel blocks: Undoing stack allocation of %s:%s\n",
00115                                    Vcurrent_func -> fc_code_label,
00116                                    getname(s -> decl_id -> id_str_table_index));
00117                         }
00118                         s -> decl_special &= ~VAR_ON_STACK;
00119                       }
00120                     });
00121                     break;
00122                 default:
00123                     dbgmsg("realloc_blocks: bad list entry\n");
00124             }
00125         }
00126       }
00127 }
00128 
00129 /* Add a block to block list */
00130 void add_block(block)
00131 NODE * block;
00132 {
00133     struct blocks *p;
00134 
00135     if (block -> kind == MODPRIMARY) {
00136         dbgmsg("add_block: MODPRIMARY in block list\n");
00137         return;
00138     }
00139     if (block -> kind == BLOCKDENOTATION
00140         && (block -> bld_declaration_list == NIL
00141             || is_empty(block -> bld_declaration_list))) {
00142         /* No local declarations - ignore */
00143         return;
00144     }
00145     /* Add block to list */
00146       p = (struct blocks *) malloc(sizeof (struct blocks));
00147       p -> bl_block = block;
00148       p -> bl_next = Vcurrent_blocks;
00149       Vcurrent_blocks = p;
00150 }
00151 
00152 Vallocwalk(p)
00153 register NODE * p;
00154 {
00155 register NODE * v;
00156 int tp;
00157 
00158     if (p == NIL) return;
00159 
00160     /* Take care of nonexpression nodes first: */
00161     switch (p -> kind) {
00162         case DECLARATION:
00163                 {
00164                     /* level field has been set by import to be function */
00165                     /* nesting level.  It has been used by "accessible". */
00166                     /* It is reset here to a.r. nesting depth.           */
00167                     NODE * den = p -> decl_denotation;
00168                     boolean no_ref = (p -> decl_signature -> kind
00169                                       == VARSIGNATURE
00170                                       && !(p -> decl_special & VAR_NONTR_REF));
00171                     boolean allocate_in_ar =
00172                        (Vallocate_on_stack || (no_ref && !Vcallcc))
00173                         && den -> kind == APPLICATION
00174                         && ((tp = special_tp(den -> ap_operator -> signature
00175                                                   -> fsig_special))
00176                              == STD_NEW
00177                             || tp == PROD_NEW || tp == UNION_NEW
00178                             || tp == PTR_NEW  || tp == INIT_NEW  );
00179                     boolean allocate_in_reg =
00180                            allocate_in_ar
00181                            && (Rflag
00182                                || ((tp == STD_NEW || tp == INIT_NEW) ?
00183                                    (n_int_regs < max_int_regs)
00184                                    : (n_addr_regs < max_addr_regs)))
00185                             && !(p -> decl_special & (ID_IMPORTED
00186                                                       | VAR_NONTR_REF))
00187                             && (special_val(den -> ap_operator
00188                                                -> signature -> fsig_special)
00189                                 == 1
00190                                 || tp == PROD_NEW || tp == UNION_NEW);
00191 
00192                     if (hflag || allocate_in_reg) {
00193                         allocate_in_ar = FALSE;
00194                     }
00195                     p -> level = Vstatic_level;
00196                     if (allocate_in_reg) {
00197                           /* Note: Both Gflag and !Vcallcc hold at this   */
00198                           /* point. Store variable value in register.     */
00199                             extern int avail_loc;
00200 
00201                             if (Vflag) {
00202                               printf("Allocating value of %s:%s to v. register\n",
00203                                      Vcurrent_func -> fc_code_label,
00204                                      getname(p -> decl_id -> id_str_table_index));
00205                             }
00206                             p -> displacement = avail_loc++;
00207                             if (tp == STD_NEW) {
00208                                 p -> decl_special |= SIMPLE_VAR_IN_REG;
00209                                 n_int_regs++;
00210                             } else if (tp == INIT_NEW) {
00211                                 p -> decl_special |= INIT_VAR_IN_REG;
00212                                 n_int_regs++;
00213                             } else {
00214                                 p -> decl_special |= PTR_VAR_IN_REG;
00215                                 n_addr_regs++;
00216                             }
00217                     } else if (allocate_in_ar) {
00218                           /* Allocate variable directly in activation record */
00219                             if (Vflag) {
00220                               printf("Allocating %s:%s directly in act. record\n",
00221                                      Vcurrent_func -> fc_code_label,
00222                                      getname(p -> decl_id -> id_str_table_index));
00223                             }
00224                             p -> displacement = Vnext_free;
00225                             Vnext_free +=
00226                                  special_val(den -> ap_operator
00227                                                  -> signature -> fsig_special);
00228                             if (tp == STD_NEW) {
00229                                 p -> decl_special |= SIMPLE_VAR_ON_STACK;
00230                             } else if (tp == INIT_NEW) {
00231                                 p -> decl_special |= INIT_VAR_ON_STACK;
00232                             } else {
00233                                 p -> decl_special |= PTR_VAR_ON_STACK;
00234                             }
00235                     } else {
00236                         if (Vextent_limited
00237                             && den -> kind == APPLICATION
00238                             && ((tp = special_tp(den -> ap_operator -> signature
00239                                                      -> fsig_special))
00240                                == ARRAY_STD_NEW
00241                                || tp == ARRAY_PTR_NEW)) {
00242                             /* Allocate array contiguously */
00243                               if (Vflag && Gflag) {
00244                                 printf("Allocating %s:%s contiguously\n",
00245                                        Vcurrent_func -> fc_code_label,
00246                                        getname(p -> decl_id -> id_str_table_index));
00247                               }
00248                               p -> decl_special |= ARRAY_CONTIG;
00249                           }
00250                         if (p -> decl_needed) {
00251                           /* If ((Rflag || messy, ad hoc heuristic) && ... */
00252                           if ((Rflag || (n_int_regs < max_int_regs)
00253                                         && n_decls < max_int_regs + max_addr_regs
00254                                         && !is_int_const(p -> decl_denotation))
00255                               && !(p -> decl_special & ID_IMPORTED)) {
00256                             extern int avail_loc;
00257 
00258                             if (Vflag) {
00259                               printf("Binding of %s:%s stored in v. register\n",
00260                                      Vcurrent_func -> fc_code_label,
00261                                      getname(p -> decl_id -> id_str_table_index));
00262                             }
00263                             p -> decl_special |= ID_IN_REG;
00264                             p -> displacement = avail_loc++;
00265                             n_int_regs++;
00266                           } else {
00267                             p -> displacement = Vnext_free++;
00268                           }
00269                         }
00270                     }
00271                     if (p -> decl_denotation -> kind == FUNCCONSTR
00272                         && !(p -> decl_needed)) {
00273                         Vallocate(p -> decl_denotation, TRUE);
00274                     } else {
00275                         Vallocwalk(p -> decl_denotation);
00276                     }
00277                     return;
00278                 }
00279 
00280         case PARAMETER:
00281                 if (Vflag && p -> par_id != NIL
00282                     && is_real_def(p -> par_only_def)) {
00283                     printf( "Parameter %s:%s is known to be bound to: ",
00284                             Vcurrent_func -> fc_code_label,
00285                             getname(p -> par_id -> id_str_table_index));
00286                     unparse_file = stdout;
00287                     unparse(p -> par_only_def);
00288                     printf("\n");
00289                 }
00290                 p -> displacement = Vnext_free++;
00291                 p -> level = Vstatic_level;
00292                 return;
00293 
00294         case GUARDEDELEMENT:
00295                 Vallocwalk(p->ge_guard);
00296                 Vallocwalk(p->ge_element);
00297                 return;
00298 
00299         case EXTERNDEF:
00300                 return;
00301     }
00302 
00303     if (p -> signature -> kind == SIGNATURESIG) {
00304         /* signatures don't require storage for evaluation */
00305         return;
00306     }
00307 
00308     switch ( p -> kind ) {
00309 
00310         case BLOCKDENOTATION:
00311                 {
00312                     long old_int_regs = n_int_regs;
00313                     long old_addr_regs = n_addr_regs;
00314                     int old_n_decls = n_decls;
00315                     boolean escaping_env_ptrs
00316                       = (p->bld_flags & (CONTAINS_CLOSURE | CALLCC_CALL)) != 0;
00317                     boolean needs_ar = (p -> bld_flags & REQUIRES_AR) != 0;
00318                     boolean old_ccc = Vcallcc;
00319                     boolean old_aos;
00320                     boolean old_el;
00321                     struct blocks * old_Vcurrent_blocks;
00322                     NODE * old_ar;
00323                     int old_Vnext_free = Vnext_free;
00324                     int old_Vhigh_water = Vhigh_water;
00325 
00326                     if (p -> bld_declaration_list != NIL) {
00327                         n_decls = length(p -> bld_declaration_list);
00328                     } else {
00329                         n_decls = 0;
00330                     }
00331                     Vcallcc = (p -> bld_flags & CALLCC_CALL) != 0;
00332                     if (needs_ar) {
00333                         old_aos = Vallocate_on_stack;
00334                         old_el = Vextent_limited;
00335                         old_Vcurrent_blocks = Vcurrent_blocks;
00336                         old_ar = Vcurrent_ar;
00337                         Vcurrent_ar = p;
00338                         Vcurrent_func -> fc_complexity |= NESTED_AR_BLOCK;
00339                         Vextent_limited = (p -> signature -> kind
00340                                            == TYPESIGNATURE);
00341                         /* In this case, the import rule guarantees the */
00342                         /* desired property.                            */
00343                         Vallocate_on_stack = Vextent_limited && !Vcallcc;
00344                         Vcurrent_blocks = NIL;
00345                         Vhigh_water = Vnext_free = AR_FIRST_PARM;
00346                         Vstatic_level++;
00347                     } else {
00348                       /* If there is no potential for a pointer to the */
00349                       /* environment surviving block exit, we recycle  */
00350                       /* locations at the end of the block.  This      */
00351                       /* requires that potentially surviving variables */
00352                       /* (references) may not be allocated directly    */
00353                       /* in the activation record if there is a        */
00354                       /* subsequent parallel block.  Here we undo such */
00355                       /* allocations for preceding blocks.             */
00356                         realloc_blocks(p);
00357                         if (!escaping_env_ptrs) {
00358                           /* Remember this block for possible future fix-up */
00359                             add_block(p);
00360                         }
00361                     }
00362 
00363                     maplist(v,p->bld_declaration_list,Vallocwalk(v));
00364                     maplist(v,p->bld_den_seq,Vallocwalk(v));
00365                     if (needs_ar) {
00366                         Vallocate_on_stack = old_aos;
00367                         Vextent_limited = old_el;
00368                         Vcurrent_blocks = old_Vcurrent_blocks;
00369                         Vcallcc = old_ccc;
00370                         if (Vnext_free >= Vhigh_water) {
00371                           p -> ar_size = Vnext_free;
00372                         } else {
00373                           p -> ar_size = Vhigh_water;
00374                         }
00375                         if (p -> ar_size > MAXOBJSZ) {
00376                             errmsg0(p, "Too many local variables");
00377                         }
00378                         p -> ar_static_level = Vstatic_level;
00379                         p -> ar_static_link = old_ar;
00380                         Vnext_free = old_Vnext_free;
00381                         Vhigh_water = old_Vhigh_water;
00382                         Vcurrent_ar = old_ar;
00383                         Vstatic_level--;
00384                     } else if (!escaping_env_ptrs) {
00385                         if (Vnext_free > Vhigh_water) {
00386                             Vhigh_water = Vnext_free;
00387                         }
00388                         Vnext_free = old_Vnext_free;    
00389                     }
00390                     n_int_regs = old_int_regs;
00391                     n_addr_regs = old_addr_regs;
00392                     n_decls = old_n_decls;
00393                     break;
00394                 }
00395 
00396         case APPLICATION:
00397                 {
00398                     Vallocwalk(p->ap_operator);
00399                     maplist(v,p->ap_args,Vallocwalk(v));
00400                     break;
00401                 }
00402 
00403         case LOOPDENOTATION:
00404                 {
00405                     boolean old_aos = Vallocate_on_stack;
00406                     boolean old_el = Vextent_limited;
00407                     
00408                     Vallocate_on_stack = FALSE;
00409                     Vextent_limited = FALSE;
00410                     maplist(v,p->gl_list,Vallocwalk(v));
00411                     Vallocate_on_stack = old_aos;
00412                     Vextent_limited = old_el;
00413                     break;
00414                 }
00415 
00416         case QSTR:
00417         case UQSTR:
00418                 {
00419                     /* Selection type is handled as though it were */
00420                     /* in a loop, since it may be evaluated more   */
00421                     /* than once.                                  */
00422                     boolean old_aos = Vallocate_on_stack;
00423                     boolean old_el = Vextent_limited;
00424 
00425                     Vallocate_on_stack = FALSE;
00426                     Vextent_limited = FALSE;
00427                     Vallocwalk(p -> sel_type);
00428                     Vallocate_on_stack = old_aos;
00429                     Vextent_limited = old_el;
00430                     break;
00431                 }
00432 
00433         case GUARDEDLIST:
00434                 maplist(v,p->gl_list,Vallocwalk(v));
00435                 break;
00436 
00437         case OPRID:
00438         case LETTERID:
00439                 if (p -> sel_type != NIL) {
00440                     Vallocwalk(p->sel_type);
00441                 }
00442                 break;
00443 
00444         case FUNCCONSTR:
00445                 {
00446                     Vallocate (p, FALSE);
00447                     break;
00448                 }
00449 
00450         case REXTERNDEF:
00451                 break;
00452 
00453         case USELIST:
00454                 maplist(q, p -> usl_den_seq, Vallocwalk(q));
00455                 break;
00456 
00457         case MODPRIMARY:
00458                 if (p -> mp_type_modifier != NIL
00459                     && p -> mp_type_modifier -> kind == WITHLIST) {
00460                    /* Treat it as a block since it can overlay */
00461                    /* previously allocated locations           */
00462                        realloc_blocks(p);
00463                 }
00464                 Vallocwalk(p -> mp_primary);
00465                 if (p -> mp_type_modifier != NIL
00466                     && p -> mp_type_modifier -> kind == WITHLIST) {
00467                     /* reserve space for local type identifier */
00468                         p -> displacement = Vnext_free++;
00469                         p -> level = Vstatic_level;
00470                     maplist (q, p -> mp_type_modifier -> wl_component_list, {
00471                         Vallocwalk(q -> decl_denotation);
00472                     });
00473                 }
00474                 break;
00475 
00476         case ENUMERATION:
00477         case PRODCONSTRUCTION:
00478         case UNIONCONSTRUCTION:
00479                 /* Subexpressions are not evaluated, thus */
00480                 /* no storage needs to be allocated.      */
00481                 break;
00482 
00483         case EXTENSION:
00484                 Vallocwalk(p -> ext_denotation);
00485                 break;
00486 
00487         case RECORDCONSTRUCTION:
00488                 maplist(s, p -> rec_component_list, {
00489                   Vallocwalk(s -> re_denotation);
00490                 });
00491                 break;
00492 
00493         case WORDELSE:
00494                 break;
00495 
00496         case WORDCAND:
00497         case WORDCOR:
00498                 dbgmsg("Vallocate: cand or cor\n");
00499                 break;
00500 
00501         case RECORDELEMENT:
00502         case FUNCSIGNATURE:
00503         case LISTHEADER: /* should never get here */
00504         case VARSIGNATURE:
00505         case VALSIGNATURE:
00506         case TYPESIGNATURE:
00507         case TSCOMPONENT:
00508         case DEFCHARSIGS:
00509         case WITHLIST:
00510         case EXPORTLIST:
00511         case EXPORTELEMENT:
00512         case ALLCONSTANTS:
00513         case HIDELIST:
00514         case PARAMETER:
00515         case DECLARATION:
00516         case GUARDEDELEMENT:
00517         default:
00518                 dbgmsg("Vallocwalk: bad kind\n");
00519                 break;
00520     };
00521     return;
00522 }
00523 
00524 /* Compute the number of known vacuous parameters appearing at the */
00525 /* end of a a parameter list.                                      */
00526 static boolean found_non_vacuous; /* Saw a real argument */
00527 static n_vacuous;                 /* Number of vacuous arguments found so far */
00528 
00529 static void check_vacuous(p)
00530 NODE * p;
00531 {
00532     if (!found_non_vacuous) {
00533         if (vacuous_arg(p -> par_signature)) {
00534             n_vacuous++;
00535         } else {
00536             found_non_vacuous = TRUE;
00537         }
00538     }
00539 }
00540 
00541 int n_vacuous_params(p)
00542 NODE *p;    /* parameter list */
00543 {
00544     if (!Gflag) return(0);
00545                  /* Vax implementation passes everything explicitly */
00546     found_non_vacuous = FALSE;
00547     n_vacuous = 0;
00548     maprlist(p, check_vacuous);
00549     return(n_vacuous);
00550 }
00551 
00552 Vallocate (p, unused_decl)
00553 register NODE * p;
00554 boolean unused_decl;  /* Function object is never needed explicitly */
00555 {
00556         register NODE * v;
00557         boolean old_aos = Vallocate_on_stack;
00558         boolean old_el = Vextent_limited;
00559         boolean old_ccc = Vcallcc;
00560         long old_addr_regs = n_addr_regs;
00561         long old_int_regs = n_int_regs;
00562         struct blocks * old_Vcurrent_blocks = Vcurrent_blocks;
00563         NODE * old_func = Vcurrent_func;
00564         NODE * old_ar = Vcurrent_ar;
00565         int old_Vnext_free = Vnext_free;
00566         int old_Vhigh_water = Vhigh_water;
00567         NODE * op_sig = p -> signature;
00568         NODE * result_sig = p -> signature -> fsig_result_sig;
00569 
00570         ASSERT (p->kind == FUNCCONSTR,"Vallocate.c: arg not FUNCCONSTR\n");
00571         if (p->kind != FUNCCONSTR) {dbgmsg ("p is %x\n",p);};
00572         Vstatic_level++;
00573         Vcurrent_func = Vcurrent_ar = p;
00574         Vcurrent_blocks = NIL;
00575         Vhigh_water = Vnext_free = AR_FIRST_PARM;
00576         n_int_regs = n_addr_regs = 0;
00577         /* Determine whether stack allocation of variables is safe */
00578           {
00579               if (impure(op_sig)) {
00580                   /* Who knows what it does? */
00581                   Vextent_limited = FALSE;
00582 #                 ifdef VERBOSE
00583                     printf("Vallocate: impure operator signature\n");
00584 #                 endif
00585               } else if (result_sig -> kind == VARSIGNATURE) {
00586                   /* Can obviously return a variable */
00587                   Vextent_limited = FALSE;
00588 #                 ifdef VERBOSE
00589                     printf("Vallocate: variable result signature\n");
00590 #                 endif
00591               } else if (result_sig -> kind == VALSIGNATURE &&
00592                          !result_sig -> val_denotation -> signature
00593                                      -> ts_simple_type) {
00594                   ASSERT (has_sig(result_sig -> val_denotation),
00595                           "Missing result type signature");
00596                   Vextent_limited = FALSE;
00597 #                 ifdef VERBOSE
00598                       printf("Vallocate: bad value result\n");
00599 #                 endif
00600               } else if (result_sig -> kind == FUNCSIGNATURE
00601                          && impure(result_sig)) {
00602                   Vextent_limited = FALSE;
00603 #                 ifdef VERBOSE
00604                     printf("Vallocate: impure result signature\n");
00605 #                 endif
00606               } else {
00607                   /* Can only return a variable through arguments */
00608                   Vextent_limited = TRUE;
00609 #                 ifdef VERBOSE
00610                     printf("Vallocate: so far - so good\n");
00611 #                 endif
00612                   if (p -> ar_static_level != 0) {
00613                     maplist(q, op_sig -> fsig_param_list, {
00614                       NODE * sig = q -> par_signature;
00615 
00616                       if (sig -> kind == VARSIGNATURE) {
00617                           ASSERT (has_sig(sig -> var_denotation),
00618                                   "Missing parameter type signature");
00619                           if (!sig -> var_denotation -> signature
00620                                    -> ts_simple_type) {
00621                               Vextent_limited = FALSE;
00622                               IFVERBOSE(
00623                                 printf("Vallocate: bad parameter\n");
00624                               )
00625                           }
00626                       }
00627                     });
00628                   }  
00629               }
00630           }
00631         Vcallcc = FALSE;
00632         Vallocate_on_stack = Vextent_limited;
00633         if (!Gflag
00634              && (result_sig -> kind == FUNCSIGNATURE || !unused_decl)) {
00635             /* VAX runtime system & a.r. may be heap allocated */
00636             /* Could result in bad pointers                    */
00637             Vallocate_on_stack = FALSE;
00638 #           ifdef VERBOSE
00639                 printf("Vallocate: possible heap a.r.\n");
00640 #           endif
00641         } 
00642         if (!Nflag && (p -> fc_complexity & NO_CALLCC) == 0) {
00643             /* Must be able to copy environment w/o getting */
00644             /* part of the state                            */
00645             Vallocate_on_stack = FALSE;
00646             Vcallcc = TRUE;
00647 #           ifdef VERBOSE                             
00648                 printf("Vallocate: possible saved continuation\n"); 
00649 #           endif
00650         }
00651 #       ifdef VERBOSE
00652             printf("Vallocate: Vallocate_on_stack = %d\n",
00653                    Vallocate_on_stack);
00654 #       endif
00655         {
00656             NODE * params = p -> signature -> fsig_param_list;
00657             int n_params = length(params) - n_vacuous_params(params);
00658             register int i = 0;
00659 
00660             maplist (v,p->signature->fsig_param_list, {
00661                 if (i < n_params || Vstatic_level == 0) {
00662                   /* May be passed explicitly, reserve space */
00663                   Vallocwalk(v);
00664                 } else {
00665                   /* Map it onto the last real parameter */
00666                   v -> displacement = Vnext_free - 1;
00667                   v -> level = Vstatic_level;
00668                 }
00669                 i++;
00670             });
00671         }
00672         Vallocwalk (p->fc_body);
00673         p -> ar_static_level = Vstatic_level;
00674         if (Vnext_free >= Vhigh_water) {
00675             p -> ar_size = Vnext_free;
00676         } else {
00677             p -> ar_size = Vhigh_water;
00678         }
00679         if (p -> ar_size > MAXOBJSZ) {
00680             errmsg0(p, "Too many local variables");
00681         }
00682         p -> ar_static_link = old_ar;
00683         Vcurrent_func = old_func;
00684         Vcurrent_ar = old_ar;
00685         Vstatic_level--;
00686         Vnext_free = old_Vnext_free;
00687         Vhigh_water = old_Vhigh_water;
00688         Vallocate_on_stack = old_aos;
00689         Vextent_limited = old_el;
00690         Vcallcc = old_ccc;
00691         Vfree_blocks();
00692         Vcurrent_blocks = old_Vcurrent_blocks;
00693         n_int_regs = old_int_regs;
00694         n_addr_regs = old_addr_regs;
00695 }
00696 

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4