00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025
00026 #include <alloca.h>
00027
00028 #include <string.h>
00029 #include <stdlib.h>
00030
00031 #ifdef emacs
00032 # include "lisp.h"
00033 # include "blockinput.h"
00034 # ifdef EMACS_FREE
00035 # undef free
00036 # define free EMACS_FREE
00037 # endif
00038 #else
00039 # define memory_full() abort ()
00040 #endif
00041
00042
00043 #if !defined (__GNUC__) || __GNUC__ < 2
00044
00045
00046
00047 # ifndef alloca
00048
00049 # ifdef emacs
00050 # ifdef static
00051
00052
00053
00054
00055 # ifndef STACK_DIRECTION
00056 you
00057 lose
00058 -- must know STACK_DIRECTION at compile-time
00059
00060
00061 # endif
00062 # endif
00063 # endif
00064
00065
00066
00067
00068 # if defined (CRAY) && defined (CRAY_STACKSEG_END)
00069 long i00afunc ();
00070 # define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
00071 # else
00072 # define ADDRESS_FUNCTION(arg) &(arg)
00073 # endif
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 # ifndef STACK_DIRECTION
00084 # define STACK_DIRECTION 0
00085 # endif
00086
00087 # if STACK_DIRECTION != 0
00088
00089 # define STACK_DIR STACK_DIRECTION
00090
00091 # else
00092
00093 static int stack_dir;
00094 # define STACK_DIR stack_dir
00095
00096 static void
00097 find_stack_direction (void)
00098 {
00099 static char *addr = NULL;
00100 auto char dummy;
00101
00102 if (addr == NULL)
00103 {
00104 addr = ADDRESS_FUNCTION (dummy);
00105
00106 find_stack_direction ();
00107 }
00108 else
00109 {
00110
00111 if (ADDRESS_FUNCTION (dummy) > addr)
00112 stack_dir = 1;
00113 else
00114 stack_dir = -1;
00115 }
00116 }
00117
00118 # endif
00119
00120
00121
00122
00123
00124
00125
00126
00127 # ifndef ALIGN_SIZE
00128 # define ALIGN_SIZE sizeof(double)
00129 # endif
00130
00131 typedef union hdr
00132 {
00133 char align[ALIGN_SIZE];
00134 struct
00135 {
00136 union hdr *next;
00137 char *deep;
00138 } h;
00139 } header;
00140
00141 static header *last_alloca_header = NULL;
00142
00143
00144
00145
00146
00147
00148
00149
00150 void *
00151 alloca (size_t size)
00152 {
00153 auto char probe;
00154 register char *depth = ADDRESS_FUNCTION (probe);
00155
00156 # if STACK_DIRECTION == 0
00157 if (STACK_DIR == 0)
00158 find_stack_direction ();
00159 # endif
00160
00161
00162
00163
00164 {
00165 register header *hp;
00166
00167 # ifdef emacs
00168 BLOCK_INPUT;
00169 # endif
00170
00171 for (hp = last_alloca_header; hp != NULL;)
00172 if ((STACK_DIR > 0 && hp->h.deep > depth)
00173 || (STACK_DIR < 0 && hp->h.deep < depth))
00174 {
00175 register header *np = hp->h.next;
00176
00177 free (hp);
00178
00179 hp = np;
00180 }
00181 else
00182 break;
00183
00184 last_alloca_header = hp;
00185
00186 # ifdef emacs
00187 UNBLOCK_INPUT;
00188 # endif
00189 }
00190
00191 if (size == 0)
00192 return NULL;
00193
00194
00195
00196 {
00197
00198 register header *new;
00199
00200 size_t combined_size = sizeof (header) + size;
00201 if (combined_size < sizeof (header))
00202 memory_full ();
00203
00204 new = malloc (combined_size);
00205
00206 if (! new)
00207 memory_full ();
00208
00209 new->h.next = last_alloca_header;
00210 new->h.deep = depth;
00211
00212 last_alloca_header = new;
00213
00214
00215
00216 return (void *) (new + 1);
00217 }
00218 }
00219
00220 # if defined (CRAY) && defined (CRAY_STACKSEG_END)
00221
00222 # ifdef DEBUG_I00AFUNC
00223 # include <stdio.h>
00224 # endif
00225
00226 # ifndef CRAY_STACK
00227 # define CRAY_STACK
00228 # ifndef CRAY2
00229
00230 struct stack_control_header
00231 {
00232 long shgrow:32;
00233 long shaseg:32;
00234 long shhwm:32;
00235 long shsize:32;
00236 };
00237
00238
00239
00240
00241
00242
00243
00244
00245 struct stack_segment_linkage
00246 {
00247 long ss[0200];
00248 long sssize:32;
00249 long ssbase:32;
00250 long:32;
00251 long sspseg:32;
00252
00253 long:32;
00254 long sstcpt:32;
00255 long sscsnm;
00256
00257 long ssusr1;
00258 long ssusr2;
00259 long sstpid;
00260 long ssgvup;
00261 long sscray[7];
00262 long ssa0;
00263 long ssa1;
00264 long ssa2;
00265 long ssa3;
00266 long ssa4;
00267 long ssa5;
00268 long ssa6;
00269 long ssa7;
00270 long sss0;
00271 long sss1;
00272 long sss2;
00273 long sss3;
00274 long sss4;
00275 long sss5;
00276 long sss6;
00277 long sss7;
00278 };
00279
00280 # else
00281
00282
00283 struct stk_stat
00284 {
00285 long now;
00286 long maxc;
00287
00288
00289 long high_water;
00290 long overflows;
00291 long hits;
00292 long extends;
00293 long stko_mallocs;
00294 long underflows;
00295 long stko_free;
00296 long stkm_free;
00297 long segments;
00298 long maxs;
00299 long pad_size;
00300 long current_address;
00301 long current_size;
00302
00303
00304 long initial_address;
00305 long initial_size;
00306 };
00307
00308
00309
00310
00311
00312 struct stk_trailer
00313 {
00314 long this_address;
00315 long this_size;
00316
00317 long unknown2;
00318 long unknown3;
00319 long link;
00320
00321 long unknown5;
00322 long unknown6;
00323 long unknown7;
00324 long unknown8;
00325 long unknown9;
00326 long unknown10;
00327 long unknown11;
00328 long unknown12;
00329 long unknown13;
00330 long unknown14;
00331 };
00332
00333 # endif
00334 # endif
00335
00336 # ifdef CRAY2
00337
00338
00339
00340 static long
00341 i00afunc (long *address)
00342 {
00343 struct stk_stat status;
00344 struct stk_trailer *trailer;
00345 long *block, size;
00346 long result = 0;
00347
00348
00349
00350
00351
00352
00353 STKSTAT (&status);
00354
00355
00356
00357 trailer = (struct stk_trailer *) (status.current_address
00358 + status.current_size
00359 - 15);
00360
00361
00362
00363
00364 if (trailer == 0)
00365 abort ();
00366
00367
00368
00369 while (trailer != 0)
00370 {
00371 block = (long *) trailer->this_address;
00372 size = trailer->this_size;
00373 if (block == 0 || size == 0)
00374 abort ();
00375 trailer = (struct stk_trailer *) trailer->link;
00376 if ((block <= address) && (address < (block + size)))
00377 break;
00378 }
00379
00380
00381
00382
00383 result = address - block;
00384
00385 if (trailer == 0)
00386 {
00387 return result;
00388 }
00389
00390 do
00391 {
00392 if (trailer->this_size <= 0)
00393 abort ();
00394 result += trailer->this_size;
00395 trailer = (struct stk_trailer *) trailer->link;
00396 }
00397 while (trailer != 0);
00398
00399
00400
00401
00402
00403
00404 return (result);
00405 }
00406
00407 # else
00408
00409
00410
00411
00412
00413
00414 static long
00415 i00afunc (long address)
00416 {
00417 long stkl = 0;
00418
00419 long size, pseg, this_segment, stack;
00420 long result = 0;
00421
00422 struct stack_segment_linkage *ssptr;
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 stkl = CRAY_STACKSEG_END ();
00433 ssptr = (struct stack_segment_linkage *) stkl;
00434
00435
00436
00437
00438
00439
00440
00441 pseg = ssptr->sspseg;
00442 size = ssptr->sssize;
00443
00444 this_segment = stkl - size;
00445
00446
00447
00448
00449
00450 while (!(this_segment <= address && address <= stkl))
00451 {
00452 # ifdef DEBUG_I00AFUNC
00453 fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
00454 # endif
00455 if (pseg == 0)
00456 break;
00457 stkl = stkl - pseg;
00458 ssptr = (struct stack_segment_linkage *) stkl;
00459 size = ssptr->sssize;
00460 pseg = ssptr->sspseg;
00461 this_segment = stkl - size;
00462 }
00463
00464 result = address - this_segment;
00465
00466
00467
00468
00469
00470
00471 while (pseg != 0)
00472 {
00473 # ifdef DEBUG_I00AFUNC
00474 fprintf (stderr, "%011o %011o\n", pseg, size);
00475 # endif
00476 stkl = stkl - pseg;
00477 ssptr = (struct stack_segment_linkage *) stkl;
00478 size = ssptr->sssize;
00479 pseg = ssptr->sspseg;
00480 result += size;
00481 }
00482 return (result);
00483 }
00484
00485 # endif
00486 # endif
00487
00488 # endif
00489 #endif