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