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