/test/language/unclassified/test_overload011.c
C | 2439 lines | 1834 code | 173 blank | 432 comment | 410 complexity | 786908f8b66825480dcd99b05168bb80 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- ANSI C code generated by SmartEiffel The GNU Eiffel Compiler, Eiffel tools and libraries
- Release 2.4 (??? June ??th 2008) [????]
- Copyright (C), 1994-2002 - INRIA - LORIA - ESIAL UHP Nancy 1 - FRANCE
- Copyright (C), 2003-2005 - INRIA - LORIA - IUT Charlemagne Nancy 2 - FRANCE
- D.COLNET, P.RIBET, C.ADRIAN, V.CROIZIER F.MERIZEN - SmartEiffel@loria.fr
- http://SmartEiffel.loria.fr
- C Compiler options used: -pipe
- */
- #ifdef __cplusplus
- }
- #endif
- #include "test_overload01.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- -- ------------------------------------------------------------------------------------------------------------
- -- Copyright notice below. Please read.
- --
- -- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P. - University of Nancy 1 - FRANCE
- -- Copyright(C) 2003-2005: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
- --
- -- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- -- documentation files (the "Software"), to deal in the Software without restriction, including without
- -- limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- -- the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
- -- conditions:
- --
- -- The above copyright notice and this permission notice shall be included in all copies or substantial
- -- portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
- -- LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
- -- EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- -- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- -- OR OTHER DEALINGS IN THE SOFTWARE.
- --
- -- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
- -- ------------------------------------------------------------------------------------------------------------
- */
- /*
- This file (SmartEiffel/sys/runtime/base.c) is included for _all_ modes of
- compilation (-boost, -no_check, ... -all_check).
- */
- /*
- Byte swapping function
- */
- void copy_swap_16(const uint16_t *src, uint16_t *dest, int count){
- while (count--) {
- *dest++ = (*src << 8) | (*src >> 8);
- src++;
- }
- }
- /*
- The wrapper for `malloc' (generated C code is supposed to use
- only `se_malloc' instead of direct `malloc').
- */
- void* se_malloc(size_t size) {
- void *result = malloc(size);
- if (result == NULL) {
- handle(SE_HANDLE_NO_MORE_MEMORY, NULL);
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(No_more_memory);
- #elif !defined(SE_BOOST)
- error0("No more memory.", NULL);
- #else
- fprintf(SE_ERR,"No more memory (malloc failed).\n");
- exit(EXIT_FAILURE);
- #endif
- }
- return result;
- }
- /*
- The wrapper for `calloc' (generated C code is supposed to use
- only `se_calloc' instead of direct `calloc').
- */
- void* se_calloc(size_t nmemb, size_t size) {
- void *result = calloc(nmemb,size);
- if (result == NULL) {
- handle(SE_HANDLE_NO_MORE_MEMORY, NULL);
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(No_more_memory);
- #elif !defined(SE_BOOST)
- error0("No more memory.", NULL);
- #else
- fprintf(SE_ERR,"No more memory (calloc failed).\n");
- exit(EXIT_FAILURE);
- #endif
- }
- return result;
- }
- /*
- The wrapper for `realloc' (generated C code is supposed to use
- only `se_realloc' instead of direct `realloc').
- */
- void* se_realloc(void* src, size_t size) {
- void *result = realloc(src, size);
- if (result == NULL) {
- handle(SE_HANDLE_NO_MORE_MEMORY, NULL);
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(No_more_memory);
- #elif !defined(SE_BOOST)
- error0("No more memory.", NULL);
- #else
- fprintf(SE_ERR,"No more memory (realloc failed).\n");
- exit(EXIT_FAILURE);
- #endif
- }
- return result;
- }
- /* ---------------------------------------------------------------------- */
- void se_die (int code) {
- handle(SE_HANDLE_DIE_WITH_CODE, &code);
- exit(code);
- }
- /*
- Runtime hooks
- */
- static se_runtime_handler_t** handlers = NULL;
- int handlers_count=0;
- void register_handler(se_runtime_handler_t*handler) {
- int new_count = handlers_count + 1;
- handlers = (se_runtime_handler_t**)se_realloc(handlers, (new_count) * sizeof(void*));
- handlers[handlers_count] = handler;
- handlers_count = new_count;
- }
- void _handle(se_handler_action_t action, void*data) {
- int i;
- for (i = 0; i < handlers_count; i++) {
- handlers[i](action, data);
- /* *** Check type of this array. Function pointer may have different size from data pointer. (PH 17/07/08) */
- }
- }
- /*
- -- ------------------------------------------------------------------------------------------------------------
- -- Copyright notice below. Please read.
- --
- -- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P. - University of Nancy 1 - FRANCE
- -- Copyright(C) 2003-2005: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
- --
- -- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- -- documentation files (the "Software"), to deal in the Software without restriction, including without
- -- limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- -- the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
- -- conditions:
- --
- -- The above copyright notice and this permission notice shall be included in all copies or substantial
- -- portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
- -- LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
- -- EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- -- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- -- OR OTHER DEALINGS IN THE SOFTWARE.
- --
- -- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
- -- ------------------------------------------------------------------------------------------------------------
- */
- #if defined __USE_POSIX || defined __unix__ || defined _POSIX_C_SOURCE
- /* macro read is used of read_stdin */
- void io_copy (char*source, char*target) {
- /* We use the low-level descriptor functions rather than stream-oriented functions.
- * This allows us to copy the file's permissions. */
- int src;
- int tgt;
- struct stat info;
- static char *buffer = NULL;
- static int bufsize = 0;
- int read_count, write_count, written;
- src=open (source, O_RDONLY);
- if (fstat (src, &info))
- return; /* Ooops */
- if (bufsize < info.st_blksize)
- buffer=se_realloc (buffer, info.st_blksize);
- tgt=creat (target, info.st_mode);
- do {
- read_count = read (src, buffer, info.st_blksize);
- write_count = 0; written = 0;
- while ((write_count < read_count) && (written >= 0))
- {
- written = write (tgt, buffer + write_count, read_count - write_count);
- write_count += written;
- }
- } while ((read_count > 0) && (written >= 0));
- close (src);
- close (tgt);
- }
- int io_same_physical_file(char*path1,char*path2) {
- struct stat info1, info2;
- if (stat(path1, &info1))
- return 0; /* oops */
- if (stat(path2, &info2))
- return 0; /* oops */
- return (info1.st_dev == info2.st_dev) && (info1.st_ino == info2.st_ino);
- }
- #else
- #define IO_COPY_BUFSIZE 4096
- int read_stdin(EIF_CHARACTER *buffer, int size) {
- int c;
- c = getc(stdin);
- if (c==EOF)
- return 0;
- *buffer = (EIF_CHARACTER)c;
- return 1;
- }
- void io_copy(char*source, char*target) {
- static char *buffer = NULL;
- int read_count;
- FILE*src=fopen(source, "rb");
- FILE*tgt=fopen(target, "wb");
- if(!buffer)
- buffer = (char*)se_malloc(IO_COPY_BUFSIZE);
- while ((read_count = fread(buffer, 1, IO_COPY_BUFSIZE, src)), read_count) {
- size_t dummy = fwrite(buffer, 1, read_count, tgt);
- }
- fclose(src);
- fclose(tgt);
- }
- int io_same_physical_file(char*path1,char*path2) {
- /* default implementation returns true only if the paths are the same */
- return !strcmp(path1, path2);
- }
- #endif
- int io_file_exists(char*source) {
- FILE*src=fopen(source, "rb");
- if (src!=NULL) {
- fclose(src);
- return 1;
- }
- else {
- return (errno != ENOENT);
- }
- }
- T53 M53={53,0};
- void se_prinT53(FILE* file,T53**o){
- if(*o==NULL){
- fprintf(file, "void");
- return;}
- fprintf(file,"COUNTER");
- fprintf(file,"#%p",(void*)*o);
- fprintf(file,"\n\t[ ");
- fprintf(file,"value = ");
- se_prinT2(file,(&((*o)->_value)));
- fprintf(file,"\n\t]");
- }/*--*/
- T49 M49={49,(void*)0,0,(void*)0,0};
- void se_prinT49(FILE* file,T49**o){
- if(*o==NULL){
- fprintf(file, "void");
- return;}
- fprintf(file,"STD_OUTPUT");
- fprintf(file,"#%p",(void*)*o);
- fprintf(file,"\n\t[ ");
- fprintf(file,"filter = ");
- se_prinT0(file,(T0**)(&((*o)->_filter)));
- fprintf(file,"\n\t ");
- fprintf(file,"buffer_position = ");
- se_prinT2(file,(&((*o)->_buffer_position)));
- fprintf(file,"\n\t ");
- fprintf(file,"buffer = ");
- se_prinT9(file,(&((*o)->_buffer)));
- fprintf(file,"\n\t ");
- fprintf(file,"capacity = ");
- se_prinT2(file,(&((*o)->_capacity)));
- fprintf(file,"\n\t]");
- }/*--*/
- T25 M25={25,0,(void*)0};
- void se_prinT25(FILE* file,T25**o){
- if(*o==NULL){
- fprintf(file, "void");
- return;}
- fprintf(file,"TEST_OVERLOAD01");
- fprintf(file,"#%p",(void*)*o);
- fprintf(file,"\n\t[ ");
- fprintf(file,"assertion_level = ");
- se_prinT2(file,(&((*o)->_assertion_level)));
- fprintf(file,"\n\t ");
- fprintf(file,"external_object = ");
- se_prinT8(file,(&((*o)->_external_object)));
- fprintf(file,"\n\t]");
- }/*--*/
- void se_prinT9(FILE* file,T9*o){
- fprintf(file,"NATIVE_ARRAY[CHARACTER]");
- fprintf(file,"#%p",(void*)*o);
- }/*--*/
- T7 M7={7,(void*)0,0,0};
- /*Aliased storage area or unicode storage.*/
- char*s26_0="";
- char*s26_212160365="require_check";
- char*s26_48390502="all_check";
- char*s26_1690381566="invariant_check";
- char*s26_1992063831="ensure_check";
- char*s26_1325941860="ERROR: \173""EIFFELTEST_TOOLS\175"".assert call ";
- char*s26_113001857=" in class ";
- char*s26_2167877="number ";
- char*s26_718083334="no_check or boost";
- char*s26_1075456615="Assertion level was ";
- char*s26_265093627="loop_check";
- char*s26_1682790378=" failed.\nRerun this test under the -sedb debugger to find out what is going wrong.\n";
- /*
- -- ------------------------------------------------------------------------------------------------------------
- -- Copyright notice below. Please read.
- --
- -- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P. - University of Nancy 1 - FRANCE
- -- Copyright(C) 2003-2005: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
- --
- -- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- -- documentation files (the "Software"), to deal in the Software without restriction, including without
- -- limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- -- the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
- -- conditions:
- --
- -- The above copyright notice and this permission notice shall be included in all copies or substantial
- -- portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
- -- LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
- -- EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- -- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- -- OR OTHER DEALINGS IN THE SOFTWARE.
- --
- -- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
- -- ------------------------------------------------------------------------------------------------------------
- */
- /*
- This file (SmartEiffel/sys/runtime/no_check.c) is automatically included
- when `ace.no_check' is true (ie. all modes except -boost).
- */
- int assertion_depth=1;
- /*
- To print object into the trace-stack :
- */
- void se_prinT0(FILE* file, T0** o) {
- if (*o == NULL) {
- fprintf(file,"Void");
- }
- else {
- fprintf(file,"#%p",(void*)*o);
- }
- }
- void se_prinT1(FILE* file, EIF_INTEGER_8* o) {
- fprintf(file,"%"PRId8,*o);
- }
- void se_prinT2(FILE* file, EIF_INTEGER* o) {
- fprintf(file,"%"PRId32,*o);
- }
- void se_prinT10(FILE* file, EIF_INTEGER_16* o) {
- fprintf(file,"%"PRId16,*o);
- }
- void se_prinT11(FILE* file,EIF_INTEGER_64* o) {
- fprintf(file,"%"PRId64,*o);
- }
- static void se_print_character(FILE* file, char c) {
- /* Produce a visible output of `c' using an Eiffelish notation.
- */
- if ((' ' <= c)&&(c <= '~')&&(c != '\'')&&(c != '\"')&&(c != '%')) {
- putc(c,file);
- }
- else {
- switch (c) {
- case '\b': fprintf(file,"%%B"); break;
- case '\f': fprintf(file,"%%F"); break;
- case '\n': fprintf(file,"%%N"); break;
- case '\r': fprintf(file,"%%R"); break;
- case '\t': fprintf(file,"%%T"); break;
- case '\0': fprintf(file,"%%U"); break;
- case '\'': fprintf(file,"%%\'"); break;
- case '\"': fprintf(file,"%%\""); break;
- case '%': fprintf(file,"%%%%"); break;
- default:
- fprintf(file,"%%/%d/", (int) ((unsigned char) c));
- }
- }
- }
- void se_prinT3(FILE* file,EIF_CHARACTER* o) {
- putc('\'',file);
- se_print_character(file, *o);
- putc('\'',file);
- }
- void se_prinT4(FILE* file, EIF_REAL_32* o) {
- fprintf(file, "%.7e", ((real64_t)*o));
- }
- void se_prinT5(FILE* file, EIF_REAL_64* o) {
- fprintf(file, "%.16e", *o);
- }
- void se_prinT12(FILE* file, EIF_REAL_EXTENDED* o) {
- fprintf(file, "%.19Le", *o);
- }
- void se_prinT6(FILE* file, EIF_BOOLEAN* o) {
- if (*o) {
- fprintf(file,"True");
- }
- else {
- fprintf(file,"False");
- }
- }
- void se_prinT7(FILE* file, EIF_STRING* o) {
- if (*o == NULL) {
- fprintf(file,"Void");
- }
- else {
- T3* storage = (*o)->_storage;
- int count = (*o)->_count;
- int i = 0;
- putc('\"',file);
- while (i < count) {
- se_print_character(file, storage[i++]);
- }
- putc('\"',file);
- }
- }
- void se_prinT8(FILE* file, EIF_POINTER* o) {
- if (*o == NULL) {
- fprintf(file,"NULL");
- }
- else {
- fprintf(file,"POINTER#%p",(void*)*o);
- }
- }
- /*
- The upper most context (SmartEiffel Dump stack Top) :
- */
- se_dump_stack* se_dst=NULL;
- int se_stack_size(se_dump_stack* ds) {
- int result = 0;
- while (ds != NULL) {
- ds = ds->caller;
- result ++;
- }
- return result;
- }
- void se_print_run_time_stack(void) {
- se_print_run_time_stack_in(SE_ERR);
- }
- void se_print_run_time_stack_in(FILE* file) {
- /* ANY.print_run_time_stack */
- se_dump_stack* origin;
- se_dump_stack* ds;
- se_dump_stack* ds2;
- int frame_count = 1;
- int rescue = 0;
- handle(SE_HANDLE_ENTER_PRINT_STACK, NULL);
- origin = se_dst;
- if (origin == NULL) {
- fprintf(file,"Empty stack.\n");
- return ;
- }
- else {
- while (origin->exception_origin != NULL) {
- origin = origin->exception_origin;
- }
- ds = origin;
- while (ds->caller != NULL) {
- ds = ds->caller;
- frame_count++;
- }
- }
- fprintf(file,"%d frames in current stack.\n",frame_count);
- fprintf(file,"===== Bottom of run-time stack =====\n");
- while (ds != NULL) {
- se_print_one_frame_in(file,ds);
- /* Next frame : */
- if (ds == origin) {
- ds = NULL;
- }
- else if (ds->exception_origin != NULL) {
- rescue = 1;
- ds = ds->exception_origin;
- }
- else {
- ds2 = se_dst;
- while (ds2->caller != ds) {
- ds2 = ds2->caller;
- }
- ds = ds2;
- }
- if (--frame_count) {
- if (!rescue) {
- fprintf(file,"======================================\n");
- }
- else {
- fprintf(file,"==== Rescue stack =================\n");
- }
- }
- }
- fprintf(file,"===== Top of run-time stack =====\n");
- handle(SE_HANDLE_EXIT_PRINT_STACK, NULL);
- }
- int se_print_one_frame(se_dump_stack* ds) {
- return se_print_one_frame_in(SE_ERR, ds);
- }
- int se_print_one_frame_in(FILE* file, se_dump_stack* ds) {
- /* Return 1 for an ordinary frame (not a cecil frame or some dynamic
- dispatch extra frame). */
- se_frame_descriptor* fd = ds->fd;
- int i = 0;
- int local_count = 0;
- char* local_format;
- int expanded;
- int id;
- void** var;
- if (fd == NULL) {
- fprintf(file,"External CECIL call.\n");
- return 0;
- }
- fprintf(file,"%s\n",fd->name);
- if (ds->p == 0) return 0;
- local_format = fd->local_format;
- if (fd->use_current) {
- fprintf(file,"Current = ");
- i = 2;
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i] - '0');
- i++;
- }
- i++;
- (se_prinT[id])(file, ds->current);
- fprintf(file,"\n");
- }
- while (local_count < fd->local_count) {
- while (local_format[i] != '%') {
- fprintf(file,"%c",local_format[i]);
- i++;
- }
- i++;
- expanded = ((local_format[i++] == 'E')?1:0);
- fprintf(file," = ");
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i] - '0');
- i++;
- }
- i++;
- if (ds->locals == NULL) {
- fprintf(file,"<unavailable>");
- }
- else {
- var = (ds->locals)[local_count];
- if (expanded) {
- (se_prinT[id])(file, (void**)(var));
- }
- else if (*var == NULL) {
- fprintf(file,"Void");
- }
- else {
- (se_prinT[((T0*)(*var))->id])(file, (void**)(var));
- }
- }
- fprintf(file,"\n");
- local_count++;
- }
- fprintf(file,"line %d ",se_position2line(ds->p));
- fflush(file);
- fprintf(file,"column %d ",se_position2column(ds->p));
- fflush(file);
- fprintf(file,"file %s \n",p[se_position2path_id(ds->p)]);
- fflush(file);
- return 1;
- }
- int se_rci(se_dump_stack*caller,void*C) {
- /* Where `caller' is supposed to be reference type non Void Current
- object. This function return 1 if the class invariant must be
- checked for `C' before leaving the routine.
- */
- if (caller != NULL) {
- se_frame_descriptor* fd = caller->fd;
- if (fd == NULL) {
- /* As for example when coming via CECIL. */
- return 0;
- }
- else {
- if (fd->use_current) {
- if (fd->local_format[1] == 'R') {
- if ((*((void**)caller->current)) == C) {
- return 0;
- }
- }
- }
- }
- }
- return 1;
- }
- void error0(char* m, char* vv) {
- /* When there is nothing more to do than to exit or to go back
- into the debugger.
- */
- static char*f="*** Error at Run Time ***: %s\n";
- fprintf(SE_ERR,f,m);
- if (vv!=NULL) fprintf(SE_ERR,f,vv);
- #ifdef SE_EXCEPTIONS
- print_exception();
- #endif
- #ifdef SE_SEDB
- sedb_break(se_dst,0);
- #else
- handle(SE_HANDLE_RUNTIME_ERROR, m);
- se_print_run_time_stack();
- fprintf(SE_ERR,f,m);
- if (vv!=NULL)
- fprintf(SE_ERR,f,vv);
- exit(EXIT_FAILURE);
- #endif
- }
- void error1(char*m,se_position position) {
- /* When there is nothing more to do than to exit or to go back
- into the debugger.
- */
- int l = se_position2line(position);
- int c = se_position2column(position);
- int f = se_position2path_id(position);
- char* f1 = "Line : %d column %d in %s.\n";
- char* f2 = "*** Error at Run Time ***: %s\n";
- fprintf(SE_ERR,f1,l,c,p[f]);
- fprintf(SE_ERR,f2,m);
- #ifdef SE_EXCEPTIONS
- print_exception();
- #endif
- #ifdef SE_SEDB
- sedb_break(se_dst,position);
- #else
- handle(SE_HANDLE_RUNTIME_ERROR, m);
- se_print_run_time_stack();
- fprintf(SE_ERR,f1,l,c,p[f]);
- fprintf(SE_ERR,f2,m);
- exit(EXIT_FAILURE);
- #endif
- }
- void se_print_string(FILE*stream, EIF_STRING s) {
- /* To print some Eiffel STRING. */
- if (s == NULL) {
- fprintf(stream,"Void");
- }
- else {
- int count = s->_count;
- EIF_CHARACTER* storage = s->_storage;
- int i = 0;
- fprintf(stream,"\"");
- while (count != 0) {
- fprintf(stream,"%c",storage[i]);
- i++;
- count--;
- }
- fprintf(stream,"\"");
- }
- }
- void se_print_bad_target(FILE*stream, int id, T0* o, int l, int c, int f) {
- /* Print Bad Target Type Error Message. */
- if (l != 0) {
- fprintf(stream,"Line : %d column %d in %s.\n",l,c,p[f]);
- }
- fprintf(stream,"*** Error at Run Time *** :\n");
- fprintf(stream," Target is not valid (not the good type).\n");
- fprintf(stream," Expected: ");
- se_print_string(stream,t[id]);
- fprintf(stream,", Actual: ");
- se_print_string(stream,t[o->id]);
- fprintf(stream,".\n");
- }
- void error2(T0*o, se_position position) {
- fprintf(SE_ERR,"Target Type ");
- se_print_string(SE_ERR,t[o->id]);
- fprintf(SE_ERR," is not valid.\n");
- error1("Bad target.",position);
- }
- T0* vc(T0* o, se_position position) {
- /*
- Void check for reference target.
- */
- if (o != NULL) {
- return o;
- }
- else {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Void_call_target);
- #else
- error1("Call with a Void target.",position);
- #endif
- return NULL;
- }
- }
- T0* se_string_inspect_check(T0* o, se_position position) {
- /*
- Void check for expression of type STRING in inspect.
- */
- if (o != NULL) {
- return o;
- }
- else {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Incorrect_inspect_value);
- #else
- error1("Expression just after \"inspect\" is Void.",position);
- #endif
- return NULL;
- }
- }
- T0* ci(int id, T0* o, se_position position) {
- /*
- Check Id for reference target.
- */
- if ( vc(o,position) != NULL) {
- if ( id == (o->id) ) {
- return o;
- }
- else {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(System_level_type_error);
- #else
- int l = se_position2line(position);
- int c = se_position2column(position);
- int f = se_position2path_id(position);
- se_print_bad_target(SE_ERR,id,o,l,c,f);
- se_print_run_time_stack();
- se_print_bad_target(SE_ERR,id,o,l,c,f);
- #ifdef SE_SEDB
- sedb_break(se_dst,0);
- #else
- exit(EXIT_FAILURE);
- #endif
- #endif
- }
- }
- return o;
- }
- void ac_req(int v,char*vv) {
- if (!v) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Precondition);
- #else
- error0("Require Assertion Violated.",vv);
- #endif
- }
- }
- void ac_ens(int v,char*vv) {
- if (!v) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Postcondition);
- #else
- error0("Ensure Assertion Violated.",vv);
- #endif
- }
- }
- void ac_inv(int v,char*vv) {
- if (!v) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Class_invariant);
- #else
- error0("Class Invariant Violation.",vv);
- #endif
- }
- }
- void ac_liv(int v,char*vv) {
- /* Assertion Check : Loop Invariant check. */
- if (!v) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Loop_invariant);
- #else
- error0("Loop Invariant Violation.",vv);
- #endif
- }
- }
- int ac_lvc(int lc,int lv1,int lv2) {
- /* Assertion Check : Loop Variant check. */
- if (lc == 0) {
- if (lv2 < 0) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Loop_variant);
- #else
- {
- char msg [64];
- sprintf(msg,"Bad First Variant Value = %d\n",lv2);
- error0(msg,NULL);
- }
- #endif
- }
- else {
- return lv2;
- }
- }
- else if ((lv2 < 0) || (lv2 >= lv1)) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Loop_variant);
- #else
- {
- char msg [512];
- sprintf(msg,
- "Bad loop variant.\nLoop body counter = %d (done)\n"
- "Previous Variant = %d\nNew Variant = %d\n",
- lc,lv1,lv2);
- error0(msg,NULL);
- }
- #endif
- }
- return lv2;
- }
- void ac_civ(int v,char*vv) {
- if (!v) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Check_instruction);
- #else
- error0("Check Assertion Violated.",vv);
- #endif
- }
- }
- T0* se_evobt(T0* o, se_position position) {
- /*
- Error Void Or Bad Type.
- */
- if (!o) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Void_call_target);
- #else
- error1("Target is Void.",position);
- #endif
- }
- else {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(System_level_type_error);
- #else
- error2(o,position);
- #endif
- }
- return o; /* Dummy return to avoid C warnings. */
- }
- void se_signal_handler(int sig) {
- printf("Received signal %d.\n",sig);
- #ifdef SE_SEDB
- signal(sig,se_signal_handler);
- sedb_signal_handler(sig);
- #else
- se_print_run_time_stack();
- exit(EXIT_FAILURE);
- #endif
- }
- void se_gc_check_id(void*o,int id) {
- if (id != (((T0*)o)->id)) {
- #ifdef SE_EXCEPTIONS
- internal_exception_handler(Routine_failure);
- #else
- fprintf(SE_ERR,"System-validity error detected during GC cycle.\n");
- se_print_bad_target(SE_ERR,id,(T0*)o,0,0,0);
- se_print_run_time_stack();
- fprintf(SE_ERR,"System-validity error detected during GC cycle.\n");
- se_print_bad_target(SE_ERR,id,(T0*)o,0,0,0);
- exit(EXIT_FAILURE);
- #endif
- }
- }
- se_dump_stack* se_new_dump_stack(se_dump_stack* copy) {
- se_dump_stack* result = NULL;
- se_frame_descriptor* fd;
- int i, j, o, p, n;
- int local_count;
- char* local_format;
- int id;
- void** var;
- int local_size;
- int expanded;
- void*** _i;
- void** _ref;
- char* _exp;
- if (copy != NULL) {
- fd = copy->fd;
- result = (se_dump_stack*)se_malloc(sizeof(se_dump_stack));
- if (result != NULL) {
- result->fd = fd;
- result->p = copy->p;
- result->caller = copy->caller;
- result->current = NULL;
- result->locals = NULL;
- result->exception_origin = NULL;
- if (fd != NULL) {
- local_format = fd->local_format;
- i = 0;
- if (fd->use_current) {
- result->current = copy->current;
- /* Place i after the Current definition: */
- i = 2;
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i++] - '0');
- }
- i++;
- }
- /*
- *
- * p: sum of the number of pointers ("indirections") per local
- * -> 1 for an expanded
- * -> 2 for a reference
- *
- * o: total malloc'ed size
- *
- * _i: access to the first indirection pointer
- *
- * _ref: access to the second indirection pointer of a reference object
- * _ref == (T0*)(*_i)
- *
- * _exp: access to a copy of the expanded object
- * _exp == *((char*)_i)
- *
- *
- *
- * For instance, if "0" is the first local, a reference and "4" is the
- * second local, an expanded type (say, a 6-byte structure noted
- * "XXXXXXXXXXX", with 64-bit padding "/"):
- *
- *
- *
- * result->locals
- * | ------------
- * | | |
- * | -----------|------------v--------------
- * -->| | | | |===+===|===+===|XXXXXXXXXXX|/|/|
- * |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|0|1|2|3|
- * |===+===| | | | |===+===| | | | | | | | |
- * ---|------------^--|-------------------
- * | | |
- * ------------ --------------------------> object
- *
- * |-> _i |-> _ref _exp <-|
- *
- *
- *
- * Note: Those "|->" denote the start value and way of
- * progression of the pointers
- *
- *
- * result->locals is defined as a (void***) but its real "type" depends on
- * which element is accessed (as in the live stack; but in the live stack,
- * only the first indirection is in the struct; the remaining data is on
- * the native stack).
- *
- */
- if (copy->locals != NULL) {
- j = i;
- local_count = local_size = p = o = 0;
- while (local_count < fd->local_count) {
- while (local_format[i++] != '%');
- expanded = ((local_format[i++] == 'E')?1:0);
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i++] - '0');
- }
- i++;
- if (expanded) {
- p++;
- o = se_strucT[id];
- o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
- local_size += o;
- }
- else {
- p+=2;
- }
- local_count++;
- }
- o = p * sizeof(void*) + local_size;
- result->locals = (void***)se_malloc(o);
- _i = result->locals;
- _exp = (char*)_i + o;
- _ref = (void**)_i + local_count;
- i = j;
- local_count = 0;
- while (local_count < fd->local_count) {
- while (local_format[i++] != '%');
- expanded = ((local_format[i++] == 'E')?1:0);
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i++] - '0');
- }
- i++;
- var = (copy->locals)[local_count];
- if (expanded) {
- o = n = se_strucT[id];
- o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
- _exp -= o;
- *(char**)_i = _exp;
- memset(_exp, 0, o);
- memcpy(_exp, var, n);
- }
- else {
- *_i = _ref;
- *_ref = *var;
- _ref++;
- }
- local_count++;
- _i++;
- }
- }
- }
- }
- }
- return result;
- }
- void se_delete_dump_stack(se_dump_stack* ds) {
- if (ds != NULL) {
- if (ds->locals != NULL) free(ds->locals);
- free(ds);
- }
- }
- void se_print_locals_in(FILE* file, se_dump_stack* ds, int enter) {
- se_frame_descriptor* fd = ds->fd;
- int i = 0;
- int local_count = 0;
- char* local_format;
- int expanded;
- int id;
- void** var;
- int printed = 0;
- int display;
- if (ds->p == 0) return;
- local_format = fd->local_format;
- if (fd->use_current) {
- i = 2;
- id = 0;
- while (local_format[i] != '%') {
- i++;
- }
- i++;
- }
- while (local_count < fd->local_count) {
- display = (strncmp(local_format+i, "Result%", 7)==0) != enter;
- if (display) {
- if (printed)
- fprintf(file,", ");
- else
- fprintf(file,"(");
- printed++;
- }
-
- while (local_format[i] != '%') {
- if (display) fprintf(file,"%c",local_format[i]);
- i++;
- }
- i++;
- expanded = ((local_format[i++] == 'E')?1:0);
- if (display) fprintf(file," = ");
- id = 0;
- while (local_format[i] != '%') {
- id = (id * 10) + (local_format[i] - '0');
- i++;
- }
- i++;
- if (display) {
- if (ds->locals == NULL) {
- fprintf(file,"<unavailable>");
- }
- else {
- var = (ds->locals)[local_count];
- if (expanded) {
- (se_prinT[id])(file, (void**)(var));
- }
- else if (*var == NULL) {
- fprintf(file,"Void");
- }
- else {
- (se_prinT[((T0*)(*var))->id])(file, (void**)(var));
- }
- }
- }
- local_count++;
- }
- if (printed)
- fprintf(file,")\n");
- else
- fprintf(file,"\n");
- }
- #ifdef SE_TRACE
- static int se_call_depth=0;
- void se_print_call_trace(se_dump_stack *ds) {
- int i;
- if (ds) {
- int enter = ds->caller == se_dst;
-
- if (enter)
- se_call_depth++;
- if (se_call_depth < 0)
- se_call_depth=0;
- for(i=se_call_depth<<1; i; i--)
- putchar(' ');
- if (enter) {
- printf("enter ");
- printf("%s", ds->fd->name);
- se_print_locals_in(stdout, ds, 1);
- } else {
- if (se_dst) {
- printf("leave ");
- printf("%s", se_dst->fd->name);
- se_print_locals_in(stdout, se_dst, 0);
- se_call_depth--;
- }
- }
- } else {
- for(i=se_call_depth<<1; i; i--)
- putchar(' ');
- printf("leave ");
- printf("%s", se_dst->fd->name);
- se_print_locals_in(stdout, se_dst, 0);
- se_call_depth--;
- }
- }
- #endif
- /*
- -- ------------------------------------------------------------------------------------------------------------
- -- Copyright notice below. Please read.
- --
- -- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P. - University of Nancy 1 - FRANCE
- -- Copyright(C) 2003-2005: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
- --
- -- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- -- documentation files (the "Software"), to deal in the Software without restriction, including without
- -- limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- -- the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
- -- conditions:
- --
- -- The above copyright notice and this permission notice shall be included in all copies or substantial
- -- portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
- -- LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
- -- EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- -- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- -- OR OTHER DEALINGS IN THE SOFTWARE.
- --
- -- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
- -- ------------------------------------------------------------------------------------------------------------
- */
- /*
- This file (SmartEiffel/sys/runtime/gc_lib.c) is automatically included
- when the Garbage Collector is used (default, unless option -no_gc has been
- selected).
- */
- /*
- The `mark_stack_and_registers' C function is called by the Garbage
- Collector (GC) of SmartEiffel. It has to be customized for some systems,
- but also for some C compilers. This file provides some definitions in the
- end and has to be completed for systems which need specific work.
- On some architectures, addresses increase as the stack grows; or,
- conversely, addresses decrease as the stack grows. A C compiler may be
- clever enough to hide some root object inside registers. Unfortunately all
- registers are not always accessible via the C `setjmp' function!
- Thus, in order to be able to use the GC on your architecture/C-compiler,
- you have to provide the correct `mark_stack_and_registers' function.
- What is the `mark_stack_and_registers' function supposed to do? The
- `mark_stack_and_registers' function is supposed to notify the GC with all
- the possible roots one can find in the C stack and registers by calling the
- `gc_mark' function. A root is an object which must not be collected. The
- SmartEiffel GC already knows about some root objects like once function
- results or manifest strings. The `mark_stack_and_registers' function has to
- notify the other possible roots. Obviously, one can find in the C stack any
- kind of adresses, but the `gc_mark' function is clever enough to determine
- if the passed pointer is an Eiffel object or not. When the passed pointer
- reaches some Eiffel object, this object as well as its descendant(s) are
- automatically marked as un-collectable.
- In order to provide the most appropriate `mark_stack_and_registers'
- function, the very first question is to know about the way the C stack is
- managed (addresses of the stack may increase or decrease as the C stack
- grows). The DEFAULT BEHAVIOUR FOR UNKNOWN SYSTEMS is to consider ADDRESSES
- DECREASE AS THE STACK GROWS, as it's the most common case. The global C
- variable `stack_bottom' is set with some pointer which is supposed to be
- the bottom of the stack (this variable is automatically initialized in the
- C main function). Note: using the current stack pointer inside
- `mark_stack_and_registers', it is quite obvious to determine if addresses
- increase or not as the C stack grows. Note2: on some systems, the stack is
- not in contiguous addresses. In such case, `mark_stack_and_registers' has
- to go through all the stack fragments.
- Some roots may be stored only in registers and not in the C stack. In
- order to reach the registers as well, the first attempt is to use setjmp,
- in the hope that setjmp will save registers in the stack! Note: this
- technique do not work on processors using windows registers (such as sparc
- processors).
- */
- int se_gc_strategy = SE_GC_DEFAULT_MEMORY_STRATEGY;
- int collector_counter = 0;
- static void gcna_align_mark(rsoc*c,void*o);
- static rsoc*rsocfl=NULL; /* ReSizable Object Chunk Free List. */
- void**stack_bottom=NULL;
- mch**gcmt=NULL; /* Garbage Collector Main Table. */
- int gcmt_max=2048;
- int gcmt_used=0;
- fsoc*fsocfl=NULL; /* Fixed Size Object Chunk Free List. */
- int gc_is_off=1;
- unsigned int fsoc_count=0;
- unsigned int rsoc_count=0;
- void*gcmt_tail_addr=NULL;
- static int chunk_rounded(int size) {
- int rounded_size = size;
- int diff = rounded_size%RSOC_SIZE;
- if (diff != 0) rounded_size += (RSOC_SIZE-diff);
- return rounded_size;
- }
- /* Return the index where chunk `c' is (or is to be) in the `gcmt',
- between `min' and `max' indexes. */
- static unsigned int binary_search_in_gcmt(register unsigned int min,
- register unsigned int max,
- register mch* c){
- register unsigned int mid;
- while (min<max){
- mid=(min+max)>>1;
- if (gcmt[mid]<c)
- min=mid+1;
- else
- max=mid;
- }
- if (gcmt[min]<c)
- return min+1;
- else
- return min;
- }
- static void may_free_rsocfl(void) {
- /* May free all chunks of `rsocfl' (ReSizable Object Chunk Free List)
- in some circumstances.
- */
- rsoc* next; register rsoc *current;
- unsigned int count = rsocfl_count();
- register unsigned int where = gcmt_used;
- register unsigned int how_many;
- if ((count > 50) && (count > (rsoc_count >> 1))) {
- current=rsocfl;
- rsocfl=NULL;
- while (NULL != current) {
- next=current->next;
- if (current->isize == current->header.size) {
- where = binary_search_in_gcmt(0, where-1, (mch*)current);
- how_many = gcmt_used - 1 - where;
- if (how_many > 0)
- memmove(gcmt+where, gcmt+where+1, how_many*sizeof(mch*));
- free(current); gcmt_used--; rsoc_count--;
- }
- else {
- current->next=rsocfl;
- rsocfl=current;
- }
- current = next;
- }
- }
- }
- int gc_memory_used(void) {
- int i;
- int result = 0;
- mch* mch;
- for (i = gcmt_used; i --> 0; ) {
- mch = gcmt[i];
- switch(mch->state_type) {
- case RSO_USED_CHUNK:
- case FSO_USED_CHUNK:
- case FSO_STORE_CHUNK:
- result += mch->size;
- break;
- default:
- break;
- }
- }
- return result;
- }
- void gc_sweep(void) {
- mch** p2 = gcmt;
- mch** p1 = gcmt+1;
- mch**eogcmt=gcmt+gcmt_used;
- if (FREE_CHUNK((*p2)->state_type)) {
- if (RSO_FREE_CHUNK == ((*p2)->state_type)) {
- ((rsoc*)(*p2))->next=NULL;
- rsocfl=((rsoc*)(*p2));
- }
- else {
- rsocfl=NULL;
- }
- }
- else {
- ((*gcmt)->swfp)(*p2);
- if (RSO_FREE_CHUNK==((*p2)->state_type)) {
- ((rsoc*)(*p2))->next=NULL;
- rsocfl=((rsoc*)(*p2));
- }
- else {
- rsocfl=NULL;
- }
- }
- while (p1 < eogcmt) {
- if (FREE_CHUNK((*p1)->state_type)) {
- if (RSO_FREE_CHUNK == ((*p1)->state_type)) {
- if (RSO_FREE_CHUNK == ((*p2)->state_type)) {
- if ( (((rsoc*)*p1)->isize==0) && ((char*)(*p2))+(*p2)->size == ((char*)(*p1))) {
- ((*p2)->size)+=((*p1)->size);
- p1++;
- }
- else {
- ((rsoc*)(*p1))->next=rsocfl;
- rsocfl=((rsoc*)(*p1));
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- else {
- ((rsoc*)(*p1))->next=rsocfl;
- rsocfl=((rsoc*)(*p1));
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- else {
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- else {
- ((*p1)->swfp)(*p1);
- if (RSO_FREE_CHUNK == ((*p1)->state_type)) {
- if (RSO_FREE_CHUNK == ((*p2)->state_type)) {
- if ( (((rsoc*)*p1)->isize==0) && ((char*)(*p2))+(*p2)->size == ((char*)(*p1))) {
- ((*p2)->size)+=((*p1)->size);
- p1++;
- }
- else {
- ((rsoc*)(*p1))->next=rsocfl;
- rsocfl=((rsoc*)(*p1));
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- else {
- ((rsoc*)(*p1))->next=rsocfl;
- rsocfl=((rsoc*)(*p1));
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- else {
- *(p2+1)=*p1; p2++; p1++;
- }
- }
- }
- gcmt_used=(p2-gcmt)+1;
- may_free_rsocfl();
- }
- /* return the mch containing p or NULL if p is not
- * a valid address or was externally allocated
- */
- mch * gc_find_chunk(void * p){
- if ((p>((void*)*gcmt))&&(p<=gcmt_tail_addr)) {
- int i1=0;
- int i2=gcmt_used-1;
- int m=i2>>1;
- mch*c;
- for (;i2>i1;m=((i1+i2)>>1)) {
- if (p<=((void*)gcmt[m+1])) {
- i2=m;
- }
- else {
- i1=m+1;
- }
- }
- c=gcmt[i2];
- if((char*)p<(char*)c+c->size) /* check for upper bound */
- if (!(FREE_CHUNK(c->state_type))){
- return c;
- }
- }
- return NULL;
- }
- void gc_mark(void*p) {
- mch * c;
- c = gc_find_chunk(p);
- if(NULL != c) {
- (c->amfp)(c,p);
- }
- }
- int gc_stack_size(void) {
- void*stack_top[2]={NULL,NULL};
- if (stack_top > stack_bottom) {
- return ((void**)stack_top)-((void**)stack_bottom);
- }
- else {
- return ((void**)stack_bottom)-((void**)stack_top);
- }
- }
- /*
- To delay Garbage Collection when the stack is too large.
- To allow fast increase of ceils.
- */
- #define FSOC_LIMIT (10240/((FSOC_SIZE)>>10))
- #define RSOC_LIMIT (10240/((RSOC_SIZE)>>10))
- /*
- When stack is too large, collection may be delayed.
- */
- #define GCLARGESTACK 50000
- int garbage_delayed(void) {
- /*
- To delay the first GC call.
- */
- if (gc_stack_size() > GCLARGESTACK) {
- if (fsoc_count_ceil <= fsoc_count) {
- if (rsoc_count_ceil <= rsoc_count) {
- if ((fsoc_count<FSOC_LIMIT)&&(rsoc_count<RSOC_LIMIT)) {
- fsoc_count_ceil++;
- rsoc_count_ceil++;
- return 1;
- }
- else return 0;
- }
- else {
- if (fsoc_count<FSOC_LIMIT) {
- fsoc_count_ceil++;
- return 1;
- }
- else return 0;
- }
- }
- else {
- if (rsoc_count_ceil <= rsoc_count) {
- if (rsoc_count<RSOC_LIMIT) {
- rsoc_count_ceil++;
- return 1;
- }
- else return 0;
- }
- else return 0;
- }
- }
- else {
- return 0;
- }
- }
- void gc_update_ceils(void) {
- /* This function is automatically called after each collection
- cycle.
- */
- if (se_gc_strategy == SE_GC_LOW_MEMORY_STRATEGY) {
- fsoc_count_ceil = fsoc_count;
- rsoc_count_ceil = rsoc_count;
- /* Todo: we should also consider to free unused chunks here. */
- return;
- }
- if (se_gc_strategy == SE_GC_HIGH_MEMORY_STRATEGY) {
- fsoc_count_ceil = (256 + fsoc_count) << 2;
- rsoc_count_ceil = (256 + rsoc_count) << 2;
- return;
- }
- /* The SE_GC_DEFAULT_MEMORY_STRATEGY. */
- /* Compute fsoc_count_ceil: */
- /* The lines commented out with --perf-- were killing performance under certain circumstances, *
- * especially with gcc -O3 <FM-15/04/2005> */
- /* --perf-- if (fsocfl == NULL) { */
- if (fsoc_count >= fsoc_count_ceil) {
- if (fsoc_count_ceil < FSOC_LIMIT) {
- fsoc_count_ceil <<= 1;
- }
- else {
- unsigned int c = fsoc_count + (fsoc_count/3);
- if (fsoc_count_ceil < c)
- fsoc_count_ceil = c;
- }
- }
- /* --perf-- }
- else {
- if (fsoc_count_ceil < fsoc_count) {
- fsoc_count_ceil = fsoc_count;
- }
- }
- */
- /* Compute rsoc_count_ceil: */
- /* --perf-- if (rsocfl == NULL) {*/
- if (rsoc_count >= rsoc_count_ceil) {
- if (rsoc_count_ceil < RSOC_LIMIT) {
- rsoc_count_ceil <<= 1;
- }
- else {
- unsigned int c = rsoc_count + (rsoc_count / 3);
- if (rsoc_count_ceil < c) {
- rsoc_count_ceil = c;
- }
- }
- }
- /* --perf -- }
- else {
- if (rsoc_count_ceil < rsoc_count) {
- rsoc_count_ceil = rsoc_count;
- }
- }
- */
- }
- static void gc_add_into_gcmt(mch*c) {
- /* Update the `gcmt' (Garbage Collector Main Table) by adding the
- new `mch' (Memory Chunk Header).`gcmt_used' is updated.
- */
- unsigned int where=0;
- unsigned how_many;
- if (gcmt_used>0){
- where=binary_search_in_gcmt(0, gcmt_used-1, c);
- if (gcmt_used == gcmt_max) {
- gcmt_max <<= 1;
- gcmt = ((mch**)(se_realloc(gcmt,(gcmt_max+1)*sizeof(void*))));
- }
- how_many = gcmt_used - where;
- if (how_many > 0)
- memmove(gcmt+where+1, gcmt+where, how_many*sizeof(mch*));
- }
- gcmt[where]=c;
- gcmt_used++;
- }
- static char*rso_from_store(na_env*nae,unsigned int size) {
- rsoh*r=(nae->store);
- nae->store_left-=size;
- if ((nae->store_left) > sizeof(rsoh)) {
- r->header.size=size;
- nae->store=((rsoh*)(((char*)(nae->store))+size));
- }
- else {
- r->header.size=size+nae->store_left;
- nae->store_left=0;
- }
- (r->header.magic_flag)=RSOH_UNMARKED;
- ((void)memset((r+1),0,r->header.size-sizeof(rsoh)));
- return (char*)(r+1);
- }
- static void rsoc_sweep(rsoc*c) {
- na_env*nae=c->nae;
- rsoh*gp=(rsoh*)&(c->first_header);
- rsoh*pp;
- rsoh*eoc=((rsoh*)(((char*)c)+c->header.size));
- c->free_list_of_large=NULL;
- if (c->header.size > RSOC_SIZE) {
- if (gp->header.magic_flag == RSOH_MARKED) {
- gp->header.magic_flag=RSOH_UNMARKED;
- /* No need to register chunks with no free_list_of_large
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- */
- }
- else {
- c->header.state_type=RSO_FREE_CHUNK;
- }
- return;
- }
- while (gp<eoc) {
- while (gp->header.magic_flag == RSOH_MARKED) {
- gp->header.magic_flag=RSOH_UNMARKED;
- gp=((rsoh*)(((char*)gp)+gp->header.size));
- if(gp>=eoc) {
- /* No need to register chunks with no free_list_of_large
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- */
- return;
- }
- }
- gp->header.magic_flag=RSOH_FREE;
- pp=(rsoh*)(((char*)gp)+gp->header.size);
- while ((pp<eoc)&&(pp->header.magic_flag != RSOH_MARKED)) {
- gp->header.size+=pp->header.size;
- pp=((rsoh*)(((char*)pp)+pp->header.size));
- }
- if (gp->header.size >= RSOC_MIN_STORE) {
- if (nae->store_left==0) {
- nae->store_left=gp->header.size;
- nae->store=gp;
- nae->store_chunk=c;
- }
- else if (nae->store->header.size < gp->header.size) {
- ((fll_rsoh*)nae->store)->nextflol=nae->store_chunk->free_list_of_large;
- nae->store_chunk->free_list_of_large=((fll_rsoh*)nae->store);
- nae->store_left=gp->header.size;
- nae->store=gp;
- nae->store_chunk=c;
- }
- else {
- ((fll_rsoh*)gp)->nextflol=c->free_list_of_large;
- c->free_list_of_large=((fll_rsoh*)gp);
- }
- }
- gp=pp;
- }
- if (((rsoh*)(&c->first_header))->header.size >=
- (c->header.size-sizeof(rsoc)+sizeof(rsoh))){
- c->header.state_type=RSO_FREE_CHUNK;
- nae->store_chunk=NULL;
- nae->store_left=0;
- }
- else{
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- }
- }
- /* *** To be removed */
- #ifdef __TINYC__
- static rsoc MRSOC = {
- #else
- static const rsoc MRSOC = {
- #endif
- {
- RSOC_SIZE,
- RSO_USED_CHUNK,
- ((void(*)(mch*,void*))gcna_align_mark),
- ((void(*)(mch*))rsoc_sweep)
- },
- 0,
- NULL,
- NULL,
- NULL,
- {
- {
- 0,
- RSOH_MARKED
- }
- }
- };
- static void rsoc_malloc(na_env*nae) {
- rsoc* r = ((rsoc*)(se_malloc(RSOC_SIZE)));
- rsoc_count++;
- *r=MRSOC;
- r->nae=nae;
- r->isize=RSOC_SIZE;
- nae->store=(&(r->first_header));
- nae->store_left=RSOC_SIZE-sizeof(rsoc)+sizeof(rsoh);
- nae->store_chunk=r;
- r->next=nae->chunk_list;
- nae->chunk_list=r;
- gc_add_into_gcmt((mch*)r);
- }
- static rsoc* rsocfl_best_fit(unsigned int size) {
- register unsigned int best_size = 0;
- unsigned int acceptable_loss;
- register rsoc *pc, *best_pc, *best_c, *c;
- if (NULL==rsocfl)
- return NULL;
- pc=NULL;
- best_pc=NULL;
- best_c=NULL;
- c=rsocfl;
- if (SE_GC_DEFAULT_MEMORY_STRATEGY == se_gc_strategy)
- acceptable_loss = (size >> 4);
- else if (SE_GC_LOW_MEMORY_STRATEGY == se_gc_strategy)
- acceptable_loss = 0;
- else /* SE_GC_HIGH_MEMORY_STRATEGY == se_gc_strategy */
- acceptable_loss = (size >> 2);
- while ((NULL!=c)&&(NULL==best_c)){
- if (c->header.size>=size){
- best_c=c;
- best_pc=pc;
- best_size=c->header.size;
- }
- pc=c;
- c=c->next;
- }
- if (NULL==c){
- if (NULL != best_pc)
- best_pc->next=best_c->next;
- else if (best_c==rsocfl)
- rsocfl=best_c->next;
- return best_c;
- }
- if ((best_size - size) > acceptable_loss){
- do {
- if ((c->header.size >= size) && (c->header.size < best_size)) {
- best_c = c;
- best_pc = pc;
- best_size = c->header.size;
- if ((best_size - size) <= acceptable_loss) break;
- }
- pc=c;
- c=c->next;
- }
- while(NULL!=c);
- }
- if (NULL==best_pc) {
- rsocfl = best_c->next;
- }
- else {
- best_pc->next=best_c->next;
- }
- return best_c;
- }
- static int get_store_in(rsoc*c,unsigned int size) {
- na_env*nae=c->nae;
- fll_rsoh*pf=NULL;
- fll_rsoh*f=c->free_list_of_large;
- while (f != NULL) {
- if (f->rsoh_field.size >= size) {
- nae->store_left=f->rsoh_field.size;
- nae->store=(rsoh*)f;
- nae->store_chunk=c;
- if (pf == NULL) {
- c->free_list_of_large=f->nextflol;
- }
- else {
- pf->nextflol=f->nextflol;
- }
- return 1;
- }
- pf = f;
- f = f->nextflol;
- }
- return 0;
- }
- char*new_na_from_chunk_list(na_env*nae,unsigned int size) {
- rsoc*c=nae->chunk_list;
- unsigned int csize;
- while (c != NULL) {
- if (get_store_in(c,size)) {
- return rso_from_store(nae,size);
- }
- c = c->next;
- }
- csize=size+(sizeof(rsoc)-sizeof(rsoh));
- c=rsocfl_best_fit(csize);
- if (c != NULL){
- if (c->header.size > RSOC_SIZE) {
- if (c->header.size-csize > RSOC_MIN_STORE*4) {
- int csize_left=c->header.size-csize;
- if ((csize_left%sizeof(double))!=0) {
- csize_left-=(csize_left%sizeof(double));
- csize=c->header.size-csize_left;
- }
- c->header.size=csize_left;
- c->next=rsocfl;
- rsocfl=c;
- c=(rsoc*)(((char*)c)+csize_left);
- c->isize=0; /* c split from a larger chunk */
- gc_add_into_gcmt((mch*)c);
- c->header.amfp=(void(*)(mch*,void*))gcna_align_mark;
- c->header.swfp=(void(*)(mch*))rsoc_sweep;
- }
- /* since objects bigger than RSOC_SIZE must be the only object in their chunk, we do not want to have
- some store left after them. Therefore, we do not set csize to c->header.size in an else block
- here. */
- c->header.size=csize;
- }
- else {
- csize=c->header.size;
- }
- c->header.state_type=RSO_USED_CHUNK;
- c->free_list_of_large=NULL;
- c->nae=nae;
- nae->store=(&(c->first_header));
- nae->store_left=csize-sizeof(rsoc)+sizeof(rsoh);
- nae->store_chunk=c;
- /* No need to register chunks with no free_list_of_large
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- */
- return rso_from_store(nae,size);
- }
- return NULL;
- }
- /* size in bytes, including header size */
- char*new_na(na_env*nae,unsigned int size) {
- if (size == 0) {
- #ifdef SE_BOOST
- handle(SE_HANDLE_RUNTIME_ERROR, NULL);
- se_print_run_time_stack();
- exit(EXIT_FAILURE);
- #else
- char msg[512];
- sprintf(msg, "Bad native array size: %d.\n", size);
- error0(msg, NULL);
- #endif
- }
- if (nae->store_left>0) {
- nae->store->header.size=nae->store_left;
- nae->store->header.magic_flag=RSOH_FREE;
- if (nae->store_left >= RSOC_MIN_STORE) {
- ((fll_rsoh*)(nae->store))->nextflol=nae->store_chunk->free_list_of_large;
- nae->store_chunk->free_list_of_large=((fll_rsoh*)nae->store);
- }
- nae->store_left=0;
- }
- if ((nae->store_chunk!=NULL)&&(get_store_in(nae->store_chunk,size))) {
- return rso_from_store(nae,size);
- }
- {
- char*r=new_na_from_chunk_list(nae,size);
- if (r!=NULL)
- return r;
- }
- if (rsoc_count<rsoc_count_ceil) {
- if((size+sizeof(rsoc)-sizeof(rsoh))>RSOC_SIZE){
- rsoc*c;
- rsoh*r;
- unsigned int rounded_size= chunk_rounded(size+sizeof(rsoc)-sizeof(rsoh));
- c=((rsoc*)(se_malloc(rounded_size)));
- r=(&(c->first_header));
- rsoc_count++;
- *c=MRSOC;
- c->isize = rounded_size;
- c->header.size=rounded_size;
- c->nae=nae;
- /* No need to register chunks with no free_list_of_large
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- */
- gc_add_into_gcmt((mch*)c);
- r->header.size=size;
- (r->header.magic_flag)=RSOH_UNMARKED;
- ((void)memset((r+1),0,size-sizeof(rsoh)));
- return (char*)(r+1);
- }
- else {
- rsoc_malloc(nae);
- return rso_from_store(nae,size);
- }
- }
- gc_start();
- if (size<=(nae->store_left)) {
- return rso_from_store(nae,size);
- }
- {
- char*r=new_na_from_chunk_list(nae,size);
- if (r!=NULL) {
- return r;
- }
- }
- if((size+sizeof(rsoc)-sizeof(rsoh))>RSOC_SIZE){
- rsoc*c;
- rsoh*r;
- unsigned int rounded_size = chunk_rounded(size+sizeof(rsoc)-sizeof(rsoh));
- c=((rsoc*)(se_malloc(rounded_size)));
- r=(&(c->first_header));
- rsoc_count++;
- *c=MRSOC;
- c->isize = rounded_size;
- c->header.size=rounded_size;
- c->nae=nae;
- /* No need to register chunks with no free_list_of_large
- c->next=nae->chunk_list;
- nae->chunk_list=c;
- */
- gc_add_into_gcmt((mch*)c);
- r->header.size=size;
- (r->header.magic_flag)=RSOH_UNMARKED;
- ((void)memset((r+1),0,size-sizeof(rsoh)));
- gc_update_ceils();
- return (char*)(r+1);
- }
- else {
- rsoc_malloc(nae);
- gc_update_ceils();
- return rso_from_store(nae,size);
- }
- }
- static void gcna_align_mark(rsoc*c,void*o) {
- na_env* nae = c->nae;
- fll_rsoh* f;
- fll_rsoh* pf;
- char* b = (char*)&(c->first_header);
- /* properly aligned ? */
- if (((((char*)o)-((char*)c))%sizeof(int)) != 0) {
- return;
- }
- /* already marked ? */
- if ((((rsoh*)o)-1)->header.magic_flag != RSOH_UNMARKED) {
- return;
- }
- if (((char*)o) < ((char*)(c+1))) {
- return;
- }
- /* a large chunck ? */
- if (c->header.size > RSOC_SIZE) {
- if (o == (c+1)) {
- nae->gc_mark((T0*)o);
- }
- return;
- }
- pf=NULL;
- f=c->free_list_of_large;
- while ((f != NULL) && (f < ((fll_rsoh*)o))) {
- pf=f;
- f=f->nextflol;
- }
- if (pf == NULL) {
- pf=(fll_rsoh*)b;
- }
- while ((((rsoh*)pf)+1) < (rsoh*)o) {
- pf = ((fll_rsoh*)(((char*)pf)+pf->rsoh_field.size));
- }
- if (o == (((rsoh*)pf)+1)) {
- nae->gc_mark((T0*)o);
- }
- }
- unsigned int rsocfl_count(void) {
- /* Returns the number of items in the ReSizable Object Free List.
- */
- register unsigned int r=0;
- register rsoc*p=rsocfl;
- while (p!=NULL) {
- r++;
- p=p->next;
- }
- return r;
- }
- unsigned int fsocfl_count(void) {
- register unsigned int r=0;
- register fsoc*p=fsocfl;
- while (p!=NULL) {
- r++;
- p=p->next;
- }
- return r;
- }
- void gc_dispose_before_exit(void) {
- mch** p = gcmt;
- mch**eogcmt=gcmt+gcmt_used;
- while (p < eogcmt) {
- if (((*p)->state_type == FSO_STORE_CHUNK) ||
- ((*p)->state_type == FSO_USED_CHUNK)) {
- ((*p)->swfp)(*p);
- }
- p++;
- }
- }
- fsoc* gc_fsoc_get1(void) {
- /* Get a `fsoc' (Fixed Size Object Chunk) from the free fsoc list or
- allocate a new one (using `se_malloc') only when the ceil is not
- yet reached. Otherwise, call the `gc_start()' function and
- return NULL.
- */
- fsoc* result;
- if (fsocfl != NULL) {
- result = fsocfl;
- fsocfl = fsocfl->next;
- return result;
- }
- else if (fsoc_count_ceil > fsoc_count) {
- result = ((fsoc*)se_malloc(FSOC_SIZE));
- fsoc_count++;
- gc_add_into_gcmt((mch*)result);
- return result;
- }
- else {
- gc_start();
- return NULL;
- }
- }
- fsoc* gc_fsoc_get2(void) {
- /* Get a `fsoc' (Fixed Size Object Chunk) or force the allocation of a
- new `fsoc' (using the `se_malloc' function). Update various ceils
- accordingly.
- */
- fsoc* result;
- if (fsocfl != NULL) {
- result = fsocfl;
- fsocfl=fsocfl->next;
- return result;
- }
- else {
- result = ((fsoc*)(se_malloc(FSOC_SIZE)));
- fsoc_count++;
- gc_update_ceils();
- gc_add_into_gcmt((mch*)result);
- return result;
- }
- }
- #if defined(__sparc__) || defined(sparc) || defined(__sparc)
- /* For SPARC architecture.
- As this part contains assembly code (asm), you must not use
- the flag -ansi of gcc compiler.
- */
- void mark_loop(void) {
- void** max = stack_bottom;
- void** stack_pointer;
- void* stack_top[2]={NULL,NULL};
- stack_pointer = stack_top;
- /* Addresses decrease as the stack grows. */
- while (stack_pointer <= max) {
- gc_mark(*(stack_pointer++));
- }
- }
- void mark_stack_and_registers(void) {
- # if defined(__sparcv9)
- asm(" flushw");
- # else
- asm(" ta 0x3 ! ST_FLUSH_WINDOWS");
- # endif
- mark_loop();
- }
- #elif defined(__ELATE__) || defined(ELATE)
- /* GNU Eiffel's VP (Virtual Processor) garbage collector for Elate.
- (c) 2000 Rudi Chiarito <rudi@amiga.com>
- Thanks to Andy Stout and Kevin Croombs at Tao Group for their
- precious help!
- ChangeLog:
- - 2000-06-12 Rudi Chiarito <rudi@amiga.com>
- * Version 1.0
- - 2001-01-01 Joseph Kiniry <kiniry@acm.org>
- * Integrated with new SE 0.75b
- - 2001-08-10 Rudi Chiarito <rudi@amiga.com>
- * Inlined and optimised range marking
- * Added some more comments
- * Added conditional breakpoint in mark_stack_and_registers
- - 2002-09-21 Rudi Chiarito <rudi@amiga.com>
- * Removed redundant 'ret'
- */
- __inline__ void mark_stack_and_registers(void)
- {
- void *pointer_to_gc_mark = &gc_mark;
- __asm__ __volatile__
- (
- /*
- WARNING: funky code ahead!
- \t and \n are needed to make the final output easier to read
- while debugging. Hopefully you'll never have to bother with all
- of this.
- Registers:
- p0 pointer to stack block
- p1 pointer to gc_mark()
- p2 scratch pointer
- i0 length of current stack block
- i1 scratch register
- */
- # ifdef __ELATE_SE_DEBUG_GC
- "\tqcall sys/cii/breakpt,(-:-)\n"
- # endif
- "\tsync\n" /* spill all the registers */
- "\tsyncreg\n" /* to the stack */
- "\tcpy.p %0,p1\n" /* pointer to gc_mark() */
- /* pointer to the current stack block */
- "\tcpy.p [gp+PROC_STACK],p0\n"
- /* point to last location in the block, before the descriptor */
- "\tcpy.p p0 + ([(p0 - STK_SIZE) + STK_LENGTH] - STK_SIZE - 4),p2\n"
- /* mark the contents of the current stack block */
- "\twhile p2>=sp\n"
- "\t\tgos p1,(p2 : -)\n"
- "\t\tsub.p 4,p2\n"
- "\tendwhile\n"
- /* now scan other blocks (if any) */
- "\tloop\n"
- "\t\tcpy.p [p0 - STK_SIZE + STK_LINK],p0\n" /* get next block */
- "\t\tbreakif p0=NULL\n"
- /* point to last location in the block, before the descriptor */
- "\t\tcpy.p p0 + ([(p0 - STK_SIZE) + STK_LENGTH] - STK_SIZE - 4),p2\n"
- /* mark this block */
- "\t\twhile p2>=p0\n"
- "\t\t\tgos p1,(p2 : -)\n"
- "\t\t\tsub.p 4,p2\n"
- "\t\tendwhile\n"
- "\tendloop\n"
- : /* no output */
- : "p" (pointer_to_gc_mark)
- : "p0", "p1", "p2", "i0"
- );
- }
- #elif defined(__hppa__) || defined(__hppa) || defined(__hp9000) || \
- defined(__hp9000s300) || defined(hp9000s300) || \
- defined(__hp9000s700) || defined(hp9000s700) || \
- defined(__hp9000s800) || defined(hp9000s800) || defined(hp9000s820)
- /****************************************************************************
- * Generic code for architectures where addresses increase as the stack grows.
- ****************************************************************************/
- void mark_stack_and_registers(void){
- void** max = stack_bottom;
- JMP_BUF registers; /* The jmp_buf buffer is in the C stack. */
- void**stack_pointer; /* Used to traverse the stack and registers assuming
- that `setjmp' will save registers in the C stack.
- */
- (void)SETJMP(registers); /* To fill the C stack with registers. */
- stack_pointer = (void**)(void*)(®isters) + ((sizeof(JMP_BUF)/sizeof(void*))-1);
- /* stack_pointer will traverse the JMP_BUF as well (jmp_buf size is added,
- otherwise stack_pointer would be below the registers structure). */
- # if !defined(SE_BOOST)
- if (stack_pointer < max) {
- fprintf(stderr, "Wrong stack direction: your stack decrease as the stack grows (or complex stack management). Please drop an e-mail to SmartEiffel@loria.fr\n");
- exit(1); }
- # endif
- while (stack_pointer >= max) {
- gc_mark(*(stack_pointer--));
- }
- }
- #else
- /****************************************************************************
- * Generic code for architectures where addresses decrease as the stack grows.
- ****************************************************************************/
- void mark_stack_and_registers(void){
- void** max = stack_bottom;
- JMP_BUF registers; /* The jmp_buf buffer is in the C stack. */
- void**stack_pointer; /* Used to traverse the stack and registers assuming
- that `setjmp' will save registers in the C stack.
- */
- (void)SETJMP(registers); /* To fill the C stack with registers. */
- stack_pointer = (void**)(void*)(®isters);
- # if !defined(SE_BOOST)
- if (stack_pointer > max) {
- fprintf(stderr, "Wrong stack direction: the stack addresses increase as the stack grows (or complex stack management). Please drop an e-mail to SmartEiffel@loria.fr\n");
- exit(1); }
- # endif
- while (stack_pointer <= max) {
- gc_mark(*(stack_pointer++));
- }
- }
- #endif
- unsigned int fsoc_count_ceil=40;
- unsigned int rsoc_count_ceil=8;
- /*COUNTER*/void r53increment(se_dump_stack*caller,T53* C){
- static se_frame_descriptor fd={"increment"" COUNTER",1,0,"%R53%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x06A00C04/*l12c2/counter.e*/;
- ds.caller=caller;
- ds.locals=NULL;
- ds.exception_origin=NULL;
- set_dump_stack_top(&ds);/*link*/
- ds.p=0x06A00F08/*l15c4/counter.e*/;
- /*SFN*/(C->_value/*ip*/)=r2_ix_43(&ds,(/*RF2*/(C)->_value/*ip*/),/*IC*/(T2)(INT8_C(1)));
- set_dump_stack_top(caller);/*unlink*/
- }/*--*/
- /*COUNTER*/void r53default_create(se_dump_stack*caller,T53* C){
- static se_frame_descriptor fd={"default_create"" COUNTER",1,0,"%R53%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x01A00C04/*l12c2/any.e*/;
- ds.caller=caller;
- ds.locals=NULL;
- ds.exception_origin=NULL;
- set_dump_stack_top(&ds);/*link*/
- set_dump_stack_top(caller);/*unlink*/
- }/*--*/
- /*STD_OUTPUT*/T6 r49can_put_character(se_dump_stack*caller,T49* C,T3 a1){
- T6 R=0;
- void**locals[2];
- static se_frame_descriptor fd={"can_put_character"" STD_OUTPUT",1,2,"%R49%c%E3%Result%E6%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x05001104/*l17c2/terminal_output_stream.e*/;
- ds.caller=caller;
- ds.locals=locals;
- ds.exception_origin=NULL;
- locals[0]=(void**)&a1;
- locals[1]=(void**)&R;
- set_dump_stack_top(&ds);/*link*/
- ds.p=0x05001308/*l19c4/terminal_output_stream.e*/;
- R=((T6)(1));
- set_dump_stack_top(caller);/*unlink*/
- return R;
- }/*--*/
- /*STD_OUTPUT*/void r49put_new_line(se_dump_stack*caller,T49* C){
- static se_frame_descriptor fd={"put_new_line"" STD_OUTPUT",1,0,"%R49%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x04010604/*l262c2/output_stream_tools.e*/;
- ds.caller=caller;
- ds.locals=NULL;
- ds.exception_origin=NULL;
- set_dump_stack_top(&ds);/*link*/
- if(fd.assertion_flag){
- fd.assertion_flag=0;
- ds.p=0x04010908/*l265c4/output_stream_tools.e*/;
- ac_req(/*RF1is_connected*/1,"is_connected");
- ds.p=0x04010A08/*l266c4/output_stream_tools.e*/;
- ac_req(r6_px_not(&ds,(T6)(r49is_filtered(&ds,C))),"not is_filtered");
- fd.assertion_flag=1;
- }
- ds.p=0x04010C08/*l268c4/output_stream_tools.e*/;
- r49put_character(&ds,C,((T3)'\n'));
- set_dump_stack_top(caller);/*unlink*/
- }/*--*/
- /*STD_OUTPUT*/void r49dispose(se_dump_stack*caller,T49* C){
- static se_frame_descriptor fd={"dispose"" STD_OUTPUT",1,0,"%R49%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x06209004/*l144c2/std_output.e*/;
- ds.caller=caller;
- ds.locals=NULL;
- ds.exception_origin=NULL;
- set_dump_stack_top(&ds);/*link*/
- set_dump_stack_top(caller);/*unlink*/
- }/*--*/
- T0*oBC13std_output=(void*)0;
- int fBC13std_output=0;
- /*STD_OUTPUT*/T0* r49std_output(se_dump_stack*caller,T49* C){
- /*[INTERNAL_C_LOCAL list*/
- T0* tmp0;
- /*INTERNAL_C_LOCAL list]*/
- void**locals[1];
- static se_frame_descriptor fd={"std_output"" STD_OUTPUT",1,1,"%R49%Result%R49%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x01A0B104/*l177c2/any.e*/;
- ds.caller=caller;
- ds.locals=locals;
- ds.exception_origin=NULL;
- locals[0]=(void**)&oBC13std_output;
- set_dump_stack_top(&ds);/*link*/
- if(fBC13std_output==0){fBC13std_output=1;{
- tmp0/*new*/=((T0*)(new49()));
- r49make(&ds,((T49*)tmp0/*new*/));
- oBC13std_output=tmp0/*new*/;
- /*tmp0.unlock*/
- }
- fBC13std_output=2;}
- else{
- ac_req(fBC13std_output==2, "Recursive once function.");
- }
- set_dump_stack_top(caller);/*unlink*/
- return oBC13std_output;
- }/*--*/
- /*STD_OUTPUT*/void r49filtered_flush(se_dump_stack*caller,T49* C){
- static se_frame_descriptor fd={"filtered_flush"" STD_OUTPUT",1,0,"%R49%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x06203904/*l57c2/std_output.e*/;
- ds.caller=caller;
- ds.locals=NULL;
- ds.exception_origin=NULL;
- set_dump_stack_top(&ds);/*link*/
- if(fd.assertion_flag){
- fd.assertion_flag=0;
- ds.p=0x03603A08/*l58c4/output_stream.e*/;
- ac_req(/*RF1is_connected*/1,"is_connected");
- fd.assertion_flag=1;
- }
- ds.p=0x06203B2E/*l59c23/std_output.e*/;
- if(r2_ix_62(&ds,(/*RF2*/(C)->_buffer_position/*i4p*/),/*IC*/(T2)(INT8_C(0)))){
- ds.p=0x06203C0A/*l60c5/std_output.e*/;
- r49write_buffer(&ds,C);
- }
- ds.p=0x06203E08/*l62c4/std_output.e*/;
- io_flush(stdout);
- set_dump_stack_top(caller);/*unlink*/
- }/*--*/
- /*STD_OUTPUT*/void r49filtered_put_character(se_dump_stack*caller,T49* C,T3 a1){
- void**locals[1];
- static se_frame_descriptor fd={"filtered_put_character"" STD_OUTPUT",1,1,"%R49%c%E3%",1};
- se_dump_stack ds;
- ds.fd=&fd;
- ds.current=(void*)&C;
- ds.p=0x06202D04/*l45c2/std_output.e*/;
- ds.caller=caller;
- ds.locals=locals;
- ds.exception_origin=NULL;
- locals[0]=(void**)&a1;
- set_dump_stack_top(&ds);/*link*/
- if(fd.assertion_flag){
- fd.assertion_flag=0;
- ds.p=0x03603308/*l51c4/output_stream.e*/;
- ac_req(/*RF1is_connected*/1,"is_connected");
- ds.p=0x03603408/*l52c4/output_stream.e*/;
- ac_req(r49can_put_character(&ds,C,a1),"can_put_character(c)");
- fd.assertion_flag=1;
- }
- ds.p=0x06202F2E/*l47c23/std_output.e*/;
- if(r2_ix_6261(&ds,(/*RF2*/(C)->_buffer_position/*i4p*/),/*IC*/(T2)(INT16_C(4096)))){
- ds.p=0x0620300A/*l48c5/std_output.e*/;
- r49write_buffer(&ds,C);
- }
- ds.p=0x06203216/*l50c11/std_output.e*/;
- r9put(&ds,(/*RF2*/(C)->_buffer/*i4p*/),a1,(/*RF2*/(C)->_buffer_position/*i4p*/));
- ds.p=0x06203308/*l51c4/std_output.e*/;