diff --git a/src/ChangeLog b/src/ChangeLog index 7c461f6abe5a59920c5f86edf11fb717e20bebba..e94c664e5ac1997282b425afc69218f8f7d4719f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +Wed Jan 21 11:37:44 1998 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * objects can now access variables in their parents + * Compiler is now two-pass -> no more prototypes + * New efun: cpp() + * you can now access a class name from inside itself + * fork() now returns an object + * new option to pike: -w + * keyword varargs removed + * inline keyword now enforced + * New functions: Stdio.cp(), Process.create_process() + * Lot of modifications for NT + Thu Jan 1 16:56:09 1998 Fredrik Hubinette <hubbe@cytocin.hubbe.net> * threads.c: new methods added: wait and status diff --git a/src/acconfig.h b/src/acconfig.h index a5bc2a68a08e0cf00f332a4d56ec891cce4bcb82..875f66a88ec7cf9dea0946b0ad912183efb7fb3f 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -12,6 +12,9 @@ /* Define this if you want run time self tests */ #undef DEBUG +/* Define this if you want malloc debugging */ +#undef DEBUG_MALLOC + @TOP@ /* Enable profiling */ diff --git a/src/array.c b/src/array.c index 5057bda103c0645dc7184a667141e7b0990325ba..577aafe4b570c5d4409da803429950467a436908 100644 --- a/src/array.c +++ b/src/array.c @@ -1560,6 +1560,12 @@ void zap_all_arrays(void) a=&empty_array; do { + +#if defined(DEBUG) && defined(DEBUG_MALLOC) + if(verbose_debug_exit) + debug_dump_array(a); +#endif + a->refs++; free_svalues(ITEM(a), a->size, a->type_field); a->size=0; @@ -1572,6 +1578,7 @@ void zap_all_arrays(void) } while (a != & empty_array); } + void count_memory_in_arrays(INT32 *num_, INT32 *size_) { INT32 num=0, size=0; diff --git a/src/array.h b/src/array.h index 009bccf099f1088f25fd22c0f82a000ae19f286f..1521461953d14a7de3bb187ea0fada213b2f191b 100644 --- a/src/array.h +++ b/src/array.h @@ -63,8 +63,8 @@ struct array *low_allocate_array(INT32 size,INT32 extra_space); void really_free_array(struct array *v); void array_index_no_free(struct svalue *s,struct array *v,INT32 index); void array_index(struct svalue *s,struct array *v,INT32 index); -void simple_array_index(struct svalue *s,struct array *a,struct svalue *ind); -void simple_array_index_no_free(struct svalue *s,struct array *a,struct svalue *ind); +void simple_array_index_no_free(struct svalue *s, + struct array *a,struct svalue *ind); void array_free_index(struct array *v,INT32 index); void array_set_index(struct array *v,INT32 index, struct svalue *s); void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s); diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 996623426614d38a22351924c690ad91fc9b2a67..ae891e48af4e102d671b7197742fff5b344d92ab 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.61 1998/01/15 17:54:14 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.62 1998/01/25 08:25:03 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -615,40 +615,17 @@ void f_throw(INT32 args) pike_throw(); } -static struct callback_list exit_callbacks; - -struct callback *add_exit_callback(callback_func call, - void *arg, - callback_func free_func) -{ - return add_to_callback(&exit_callbacks, call, arg, free_func); -} - void f_exit(INT32 args) { - ONERROR tmp; - int i; if(args < 1) error("Too few arguments to exit.\n"); if(sp[-args].type != T_INT) error("Bad argument 1 to exit.\n"); - i=sp[-args].u.integer; - -#ifdef _REENTRANT - if(num_threads>1) exit(i); -#endif - - SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); - - call_callback(&exit_callbacks, (void *)0); - free_callback(&exit_callbacks); - - exit_modules(); - - UNSET_ONERROR(tmp); - exit(i); + assign_svalue(&throw_value, sp-args); + throw_severity=THROW_EXIT; + pike_throw(); } void f_time(INT32 args) diff --git a/src/builtin_functions.h b/src/builtin_functions.h index f7385358f6721f3855f309fbc091a9afba6eee2b..b67145bb6f96cf67a20a5407671263468705f699 100644 --- a/src/builtin_functions.h +++ b/src/builtin_functions.h @@ -23,7 +23,6 @@ void f_random(INT32 args); void f_random_seed(INT32 args); void f_query_num_arg(INT32 args); void f_search(INT32 args); -void f_call_function(INT32 args); void f_backtrace(INT32 args); void f_add_constant(INT32 args); void f_combine_path(INT32 args); @@ -35,9 +34,6 @@ void f_allocate(INT32 args); void f_rusage(INT32 args); void f_this_object(INT32 args); void f_throw(INT32 args); -struct callback *add_exit_callback(callback_func call, - void *arg, - callback_func free_func); void f_exit(INT32 args); void f_time(INT32 args); void f_crypt(INT32 args); diff --git a/src/cpp.c b/src/cpp.c index 56a29c2ba21246f014aab0dc6db94d39d53e6ba8..d220474a1aacd3642bc8c23d58a5e84ada4d81a0 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -1989,12 +1989,14 @@ void f_cpp(INT32 args) if(this.defines) free_hashtable(this.defines, free_one_define); + free_string(this.current_file); + if(this.compile_errors) { + toss_buffer(&this.buf); error("Cpp() failed\n"); }else{ pop_n_elems(args); - free_string(this.current_file); push_string(low_free_buf(&this.buf)); } } @@ -2046,4 +2048,9 @@ void exit_cpp() pike_predefs=tmp->next; free((char *)tmp); } + free_string(defined_macro->link.s); + free((char *)defined_macro); + + free_string(constant_macro->link.s); + free((char *)constant_macro); } diff --git a/src/dmalloc.h b/src/dmalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..a62fcdf1bebc11b89acb0170ac2b431518bf8890 --- /dev/null +++ b/src/dmalloc.h @@ -0,0 +1,24 @@ +#ifdef DEBUG_MALLOC + +extern int verbose_debug_malloc; +extern int verbose_debug_exit; +#define main dbm_main +extern void *debug_malloc(size_t, const char *, int); +extern char *debug_xalloc(long, const char *, int); +extern void *debug_calloc(size_t, size_t, const char *, int); +extern void *debug_realloc(void *, size_t, const char *, int); +extern void debug_free(void *, const char *, int); +extern char *debug_strdup(const char *, const char *, int); +void *debug_malloc_update_location(void *,const char *, int); +#define malloc(x) debug_malloc((x), __FILE__, __LINE__) +#define xalloc(x) debug_xalloc((x), __FILE__, __LINE__) +#define calloc(x, y) debug_calloc((x), (y), __FILE__, __LINE__) +#define realloc(x, y) debug_realloc((x), (y), __FILE__, __LINE__) +#define free(x) debug_free((x), __FILE__, __LINE__) +#define strdup(x) debug_strdup((x), __FILE__, __LINE__) +#define DO_IF_DMALLOC(X) X +#else +#define DO_IF_DMALLOC(X) +extern char *xalloc(long); +#define debug_malloc_update_location(X,Y,Z) (X) +#endif diff --git a/src/docode.c b/src/docode.c index 4110312c1cad4b1dc525c8f3938e87593a0eb15d..c92c110c06928bcea9c46b79cf2d33a4ccd20126 100644 --- a/src/docode.c +++ b/src/docode.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: docode.c,v 1.24 1998/01/13 22:56:42 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.25 1998/01/25 08:25:05 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -807,7 +807,7 @@ static int do_docode2(node *n,int flags) if(current_switch_jumptable[e]==-1) current_switch_jumptable[e]=current_switch_default; - sp[-1].u.array=order_array(sp[-1].u.array,order); + order_array(sp[-1].u.array,order); reorder((void *)(current_switch_jumptable+1),cases,sizeof(INT32)*2,order); free((char *)order); diff --git a/src/dynamic_buffer.c b/src/dynamic_buffer.c index be27f8ecc01893f4dc893e93fef77990637d641d..8efd3267539377d2c0b2ad0164a392393158633c 100644 --- a/src/dynamic_buffer.c +++ b/src/dynamic_buffer.c @@ -54,7 +54,7 @@ void low_my_binary_strcat(const char *b,INT32 l,dynamic_buffer *buf) MEMCPY(low_make_buf_space(l,buf),b,l); } -void initialize_buf(dynamic_buffer *buf) +void debug_initialize_buf(dynamic_buffer *buf) { buf->s.str=(char *)xalloc((buf->bufsize=BUFFER_BEGIN_SIZE)); *(buf->s.str)=0; diff --git a/src/dynamic_buffer.h b/src/dynamic_buffer.h index 2858274a0a47367f536ec6c28868b27d03375681..d7917786222a153ce895526742fed26944691b0c 100644 --- a/src/dynamic_buffer.h +++ b/src/dynamic_buffer.h @@ -25,12 +25,12 @@ struct dynamic_buffer_s typedef struct dynamic_buffer_s dynamic_buffer; /* Prototypes begin here */ -char *low_make_buf_space(INT32 space,dynamic_buffer *buf); +char *low_make_buf_space(INT32 space, dynamic_buffer *buf); void low_my_putchar(char b,dynamic_buffer *buf); void low_my_binary_strcat(const char *b,INT32 l,dynamic_buffer *buf); -void initialize_buf(dynamic_buffer *buf); +void debug_initialize_buf(dynamic_buffer *buf); void low_reinit_buf(dynamic_buffer *buf); -void low_init_buf_with_string(string s,dynamic_buffer *buf); +void low_init_buf_with_string(string s, dynamic_buffer *buf); string complex_free_buf(void); void toss_buffer(dynamic_buffer *buf); char *simple_free_buf(void); @@ -45,4 +45,12 @@ void init_buf_with_string(string s); char *return_buf(void); /* Prototypes end here */ +#ifdef DEBUG_MALLOC +#define initialize_buf(X) \ + do { dynamic_buffer *b_=(X); debug_initialize_buf(b_); \ + debug_malloc_update_location(b_->s.str,__FILE__,__LINE__); } while(0) +#else +#define initialize_buf debug_initialize_buf +#endif + #endif diff --git a/src/error.c b/src/error.c index 0f192049c253fa77cf0b613d4bbfd7c67c2001f6..c21871d1b9fb9ca9628596ffefce0f9093c4f294 100644 --- a/src/error.c +++ b/src/error.c @@ -24,12 +24,24 @@ JMP_BUF *init_recovery(JMP_BUF *r) r->mark_sp=mark_sp - mark_stack; r->previous=recoveries; r->onerror=0; + r->severity=THROW_ERROR; recoveries=r; return r; } -void pike_throw(void) ATTRIBUTE((noreturn)) +void pike_throw() ATTRIBUTE((noreturn)) { + while(recoveries && throw_severity > recoveries->severity) + { + while(recoveries->onerror) + { + (*recoveries->onerror->func)(recoveries->onerror->arg); + recoveries->onerror=recoveries->onerror->previous; + } + + recoveries=recoveries->previous; + } + if(!recoveries) fatal("No error recovery context.\n"); @@ -63,6 +75,7 @@ void pike_throw(void) ATTRIBUTE((noreturn)) } struct svalue throw_value = { T_INT }; +int throw_severity; void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn)) { @@ -98,6 +111,7 @@ void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn)) free_svalue(& throw_value); sp--; throw_value = *sp; + throw_severity=THROW_ERROR; in_error=0; pike_throw(); /* Hope someone is catching, or we will be out of balls. */ diff --git a/src/error.h b/src/error.h index 4ca1565d50b79bc9eb345d970e2047d8153f7784..9c275f159e912cbea3aee09819c8321871be05a2 100644 --- a/src/error.h +++ b/src/error.h @@ -25,6 +25,9 @@ typedef void (*error_call)(void *); struct frame; #endif +#define THROW_ERROR 1 +#define THROW_EXIT 1000 + typedef struct ONERROR { struct ONERROR *previous; @@ -39,11 +42,13 @@ typedef struct JMP_BUF struct frame *fp; INT32 sp; INT32 mark_sp; + INT32 severity; ONERROR *onerror; } JMP_BUF; extern JMP_BUF *recoveries; extern struct svalue throw_value; +extern int throw_severity; #define SETJMP(X) setjmp((init_recovery(&X)->recovery)) #define UNSETJMP(X) recoveries=X.previous; diff --git a/src/fdlib.c b/src/fdlib.c index f63504eaef51fb5a99a9ed0ef610f175043c30c4..bb7d1f88aa2399ee0bd7744c85485bb8becb04c8 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -7,7 +7,7 @@ long da_handle[MAX_OPEN_FILEDESCRIPTORS]; int fd_type[MAX_OPEN_FILEDESCRIPTORS]; int first_free_handle; -#define FDDEBUG(X) +#define FDDEBUG(X) X char *fd_info(int fd) { @@ -185,6 +185,7 @@ FD fd_accept(FD fd, struct sockaddr *addr, int *addrlen) return new_fd; } + #define SOCKFUN(NAME,X1,X2) \ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \ FDDEBUG(fprintf(stderr, #NAME " on %d (%d)\n",fd,da_handle[fd])); \ @@ -215,7 +216,28 @@ int PIKE_CONCAT(fd_,NAME) X1 { SOCKET ret; \ SOCKFUN2(bind, struct sockaddr *, int) +#if 1 +int fd_connect (FD fd, struct sockaddr *a, int len) +{ + SOCKET ret; + FDDEBUG(fprintf(stderr, "connect on %d (%d)\n",fd,da_handle[fd]) + for(ret=0;ret<len;ret++) + fprintf(stderr," %02x",((unsigned char *)a)[ret]); + fprintf(stderr,"\n"); + ) + if(fd_type[fd] != FD_SOCKET) + { + errno=ENOTSUPP; + return -1; + } + ret=connect((SOCKET)da_handle[fd],a,len); + if(ret == SOCKET_ERROR) errno=WSAGetLastError(); + FDDEBUG(fprintf(stderr, "connect returned %d (%d)\n",ret,errno)); + return (int)ret; +} +#else SOCKFUN2(connect, struct sockaddr *, int) +#endif SOCKFUN4(getsockopt,int,int,void*,int*) SOCKFUN4(setsockopt,int,int,void*,int) SOCKFUN2(getsockname,struct sockaddr *,int *) @@ -396,10 +418,12 @@ int fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct timeval *t) int fd_ioctl(FD fd, int cmd, void *data) { int ret; + FDEBUG(fprintf("ioctl(%d (%d,%d,%p)\n",fd,da_handle[fd],cmd,data)) switch(fd_type[fd]) { case FD_SOCKET: ret=ioctlsocket((SOCKET)da_handle[fd], cmd, data); + FDDEBUG(fprintf(stderr,"ioctlsocket returned %ld (%d)\n",ret,errno)); if(ret==SOCKET_ERROR) { errno=WSAGetLastError(); diff --git a/src/gc.c b/src/gc.c index f96489e0c0e8da70b64f51874e37ac7d82910fd1..3f8567e938498805765e11cdac67c4b9af0b08d8 100644 --- a/src/gc.c +++ b/src/gc.c @@ -317,8 +317,11 @@ void describe_something(void *a, int t) fprintf(stderr,"**Program id: %ld\n",(long)(p->id)); if(!p->num_linenumbers) { + int e; fprintf(stderr,"**The program was written in C.\n"); - break; + fprintf(stderr,"**identifiers:\n"); + for(e=0;e<p->num_identifiers;e++) + fprintf(stderr,"*** %s\n",p->identifiers[e].name->str); } for(pos=0;pos<(long)p->num_program && pos<100;pos++) @@ -338,6 +341,11 @@ void describe_something(void *a, int t) debug_dump_array((struct array *)a); break; + case T_MAPPING: + fprintf(stderr,"**Describing mapping:\n"); + debug_dump_mapping((struct mapping *)a); + break; + case T_STRING: { struct pike_string *s=(struct pike_string *)a; diff --git a/src/global.h b/src/global.h index 50b9fb55721e6e9bb8a6562f6c1402d4c6d2675e..d5abb067c188aa88919b628388fe79796708abf2 100644 --- a/src/global.h +++ b/src/global.h @@ -155,6 +155,7 @@ char *alloca (); #endif #include "port.h" +#include "dmalloc.h" #ifdef BUFSIZ diff --git a/src/interpret.c b/src/interpret.c index 8633eaeb29a0728862ef1d2444052be737764f25..1c645e071f96dc38af4ae7079fb24ea1ac2a39d1 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.60 1998/01/24 18:36:44 per Exp $"); +RCSID("$Id: interpret.c,v 1.61 1998/01/25 08:25:07 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -532,7 +532,6 @@ static int eval_instruction(unsigned char *pc) if((nonblock=query_nonblocking(2))) set_nonblocking(2,0); - file=get_line(pc-1,fp->context.prog,&linep); while((f=STRCHR(file,'/'))) file=f+1; fprintf(stderr,"- %s:%4ld:(%lx): %-25s %4ld %4ld\n", @@ -624,31 +623,38 @@ static int eval_instruction(unsigned char *pc) { struct inherit *inherit; struct program *p; - INT32 id=GET_ARG(); - struct object *o=fp->context.parent; - INT32 i=fp->context.parent_identifier; + struct object *o; + INT32 i,id=GET_ARG(); + + inherit=&fp->context; + + o=fp->current_object; + + if(!o) + error("Current object is destructed\n"); while(1) { - if(!o) - error("Parent no longer exists\n"); - - if(!(p=o->prog)) - error("Attempting to access variable in destructed object\n"); - - inherit=INHERIT_FROM_INT(p, i); - - if(!accumulator) break; - --accumulator; - - if(p->identifier_references[id].inherit_offset==0) + if(inherit->parent_offset) { i=o->parent_identifier; o=o->parent; + accumulator+=inherit->parent_offset-1; }else{ i=inherit->parent_identifier; o=inherit->parent; } + + if(!o) + error("Parent was lost during cloning.\n"); + + if(!(p=o->prog)) + error("Attempting to access variable in destructed object\n"); + + inherit=INHERIT_FROM_INT(p, i); + + if(!accumulator) break; + --accumulator; } low_object_index_no_free(sp, @@ -663,12 +669,27 @@ static int eval_instruction(unsigned char *pc) { struct inherit *inherit; struct program *p; - INT32 id=GET_ARG(); - struct object *o=fp->context.parent; - INT32 i=fp->context.parent_identifier; + struct object *o; + INT32 i,id=GET_ARG(); + + inherit=&fp->context; + o=fp->current_object; + if(!o) + error("Current object is destructed\n"); + while(1) { + if(inherit->parent_offset) + { + i=o->parent_identifier; + o=o->parent; + accumulator+=inherit->parent_offset-1; + }else{ + i=inherit->parent_identifier; + o=inherit->parent; + } + if(!o) error("Parent no longer exists\n"); @@ -679,15 +700,6 @@ static int eval_instruction(unsigned char *pc) if(!accumulator) break; accumulator--; - - if(p->identifier_references[id].inherit_offset==0) - { - i=o->parent_identifier; - o=o->parent; - }else{ - i=inherit->parent_identifier; - o=inherit->parent; - } } ref_push_object(o); @@ -1563,7 +1575,6 @@ void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) new_frame.parent_frame = fp; new_frame.current_object = o; new_frame.context = p->inherits[ ref->inherit_offset ]; - if(!ref->inherit_offset) new_frame.context.parent=o->parent; function = new_frame.context.prog->identifiers + ref->identifier_offset; diff --git a/src/language.yacc b/src/language.yacc index 1e858ae3c0e9f9d91ebf2d31920a4b092c846b4b..dc141a3e9b866a895d5d9f3e9a50ce0e73e424b5 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -129,7 +129,6 @@ %token F_SUB_EQ %token F_TYPEOF %token F_VAL_LVAL -%token F_VARARGS %token F_VOID_ID %token F_WHILE %token F_XOR_EQ @@ -162,7 +161,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.53 1998/01/20 02:30:35 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.54 1998/01/25 08:25:08 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -280,7 +279,6 @@ int yylex(YYSTYPE *yylval); %type <number> F_STATIC %type <number> F_STRING_ID %type <number> F_SWITCH -%type <number> F_VARARGS %type <number> F_VOID_ID %type <number> F_WHILE %type <number> arguments @@ -345,6 +343,7 @@ int yylex(YYSTYPE *yylval); %type <n> unused2 %type <n> while %type <n> optional_comma_expr +%type <n> low_program_ref %% all: program; @@ -368,7 +367,7 @@ optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; } | { $$=0; } ; -program_ref: string_constant +low_program_ref: string_constant { ref_push_string($1); push_string($1); @@ -377,60 +376,39 @@ program_ref: string_constant if(sp[-1].type != T_PROGRAM) my_yyerror("Couldn't cast string \"%s\" to program",$1->str); + $$=mksvaluenode(sp-1); + pop_stack(); } | idents { if(last_identifier) { - push_string(last_identifier); + ref_push_string(last_identifier); last_identifier->refs++; }else{ push_constant_text(""); } - - resolv_constant($1); - switch(sp[-1].type) - { - case T_OBJECT: - if(!sp[-1].u.object->prog) - { - pop_stack(); - push_int(0); - }else{ - struct program *p=sp[-1].u.object->prog; - p->refs++; - pop_stack(); - push_program(p); - } - break; - - case T_FUNCTION: - if(program_from_function(sp-1)) - break; - - default: - yyerror("Illegal program identifier"); - pop_stack(); - push_int(0); - - case T_PROGRAM: - break; - } + $$=$1; + } + ; - free_node($1); +program_ref: low_program_ref + { + resolv_program($1); } ; - -inheritance: modifiers F_INHERIT program_ref optional_rename_inherit ';' + +inheritance: modifiers F_INHERIT low_program_ref optional_rename_inherit ';' { if(!(new_program->flags & PROGRAM_PASS_1_DONE)) { - struct pike_string *s=sp[-2].u.string; + struct pike_string *s=sp[-1].u.string; if($4) s=$4; - do_inherit(sp-1,$1,s); + compiler_do_inherit($3,$1,s); } if($4) free_string($4); - pop_n_elems(2); + pop_n_elems(1); + free_node($3); } ; @@ -544,11 +522,6 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER for(; e>=0; e--) { push_finished_type(compiler_frame->variable[e].type); - if($1 & ID_VARARGS) - { - push_type(T_VOID); - push_type(T_OR); - } } push_type(T_FUNCTION); @@ -644,12 +617,11 @@ modifier: F_NO_MASK { $$ = ID_NOMASK; } | F_STATIC { $$ = ID_STATIC; } | F_PRIVATE { $$ = ID_PRIVATE; } | F_PUBLIC { $$ = ID_PUBLIC; } - | F_VARARGS { $$ = ID_VARARGS; } | F_PROTECTED { $$ = ID_PROTECTED; } - | F_INLINE { $$ = ID_INLINE | ID_NOMASK; } + | F_INLINE { $$ = ID_INLINE; } ; -modifiers: modifier_list { $$=current_modifiers=$1; } ; +modifiers: modifier_list { $$=current_modifiers=$1 | lex.pragmas; } ; modifier_list: /* empty */ { $$ = 0; } | modifier modifier_list { $$ = $1 | $2; } @@ -892,7 +864,14 @@ lambda: F_LAMBDA fix_comp_stack($<number>2); - push_type(T_MIXED); + + $4=mknode(F_ARG_LIST,$4,mknode(F_RETURN,mkintnode(0),0)); + type=find_return_type($4); + + if(type) + push_finished_type(type); + else + push_type(T_MIXED); e=$3-1; if(varargs) @@ -919,7 +898,7 @@ lambda: F_LAMBDA name=make_shared_string(buf); f=dooptcode(name, - mknode(F_ARG_LIST,$4,mknode(F_RETURN,mkintnode(0),0)), + $4, type, ID_PRIVATE); } @@ -1506,3 +1485,12 @@ int islocal(struct pike_string *str) return e; return -1; } + +void cleanup_compiler(void) +{ + if(last_identifier) + { + free_string(last_identifier); + last_identifier=0; + } +} diff --git a/src/las.c b/src/las.c index 2b8a6092c3afc48727eee184d32f276e2d365e72..b626c7b93b9c70c45f1f801a935ba367d5660a4b 100644 --- a/src/las.c +++ b/src/las.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: las.c,v 1.42 1998/01/19 18:38:46 hubbe Exp $"); +RCSID("$Id: las.c,v 1.43 1998/01/25 08:25:08 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -124,6 +124,30 @@ INT32 count_args(node *n) } } +struct pike_string *find_return_type(node *n) +{ + struct pike_string *a,*b; + + if(!n) return 0; + if(!(n->tree_info & OPT_RETURN)) return 0; + if(car_is_node(n)) + a=find_return_type(CAR(n)); + else + a=0; + + if(cdr_is_node(n)) + b=find_return_type(CDR(n)); + else + b=0; + + if(a) + { + if(b && a!=b) return mixed_type_string; + return a; + } + return b; +} + #define NODES 256 @@ -535,6 +559,37 @@ void resolv_constant(node *n) } } +void resolv_program(node *n) +{ + resolv_constant(n); + switch(sp[-1].type) + { + case T_OBJECT: + if(!sp[-1].u.object->prog) + { + pop_stack(); + push_int(0); + }else{ + f_object_program(1); + } + break; + + case T_FUNCTION: + if(program_from_function(sp-1)) + break; + + default: + yyerror("Illegal program identifier"); + pop_stack(); + push_int(0); + + case T_PROGRAM: + break; + } +} + + + node *index_node(node *n, struct pike_string * id) { node *ret; diff --git a/src/las.h b/src/las.h index 49194b5e5560dc4883162b8ac1478d66f18b7470..c6ca978291c4874cd483e9ca6178f23f120e0fa3 100644 --- a/src/las.h +++ b/src/las.h @@ -61,8 +61,9 @@ struct compiler_frame int car_is_node(node *n); int cdr_is_node(node *n); INT32 count_args(node *n); +struct pike_string *find_return_type(node *n); struct node_chunk; -void free_all_nodes(void); +void free_all_nodes(); void free_node(node *n); node *mknode(short token,node *a,node *b); node *mkstrnode(struct pike_string *str); @@ -78,6 +79,7 @@ node *mkexternalnode(int level, struct identifier *id); node *mkcastnode(struct pike_string *type,node *n); void resolv_constant(node *n); +void resolv_program(node *n); node *index_node(node *n, struct pike_string * id); int node_is_eq(node *a,node *b); node *mkconstantsvaluenode(struct svalue *s); diff --git a/src/lex.c b/src/lex.c index 5ded11d4a5d4153bc0adaa32d521f72e0a2ca6eb..c62b6ab02bb1c0fb885a20959e44077c5d010bfe 100644 --- a/src/lex.c +++ b/src/lex.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: lex.c,v 1.39 1998/01/16 23:02:39 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.40 1998/01/25 08:25:09 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -502,7 +502,11 @@ static int yylex2(YYSTYPE *yylval) READBUF(C!='\n'); if (strcmp(buf, "all_inline") == 0) { - lex.pragmas |= PRAGMA_ALL_INLINE; + lex.pragmas |= ID_INLINE; + } + else if (strcmp(buf, "all_nomask") == 0) + { + lex.pragmas |= ID_NOMASK; } break; } @@ -843,9 +847,6 @@ static int yylex2(YYSTYPE *yylval) case TWO_CHAR('t','y'): if(ISWORD("typeof")) return F_TYPEOF; break; - case TWO_CHAR('v','a'): - if(ISWORD("varargs")) return F_VARARGS; - break; case TWO_CHAR('v','o'): if(ISWORD("void")) return F_VOID_ID; break; diff --git a/src/lex.h b/src/lex.h index 3432fc4016acd8f17b26aecabc18a40c038c4bdb..15a38a36dd1e58c394c6940db3df0b991405e56d 100644 --- a/src/lex.h +++ b/src/lex.h @@ -49,8 +49,6 @@ struct hash_entry; struct hash_table; #endif -#define PRAGMA_ALL_INLINE 1 - struct lex { char *pos; diff --git a/src/main.c b/src/main.c index d4660242d34b19abbfa326dee53d819e97014d15..baf74afd7c682fab7bc930d34eb12a229d667bf7 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: main.c,v 1.34 1998/01/16 22:33:06 grubba Exp $"); +RCSID("$Id: main.c,v 1.35 1998/01/25 08:25:10 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -22,6 +22,7 @@ RCSID("$Id: main.c,v 1.34 1998/01/16 22:33:06 grubba Exp $"); #include "threads.h" #include "dynamic_load.h" #include "gc.h" +#include "multiset.h" #include "mapping.h" #include "cpp.h" @@ -58,10 +59,19 @@ struct callback *add_post_master_callback(callback_func call, } +static struct callback_list exit_callbacks; + +struct callback *add_exit_callback(callback_func call, + void *arg, + callback_func free_func) +{ + return add_to_callback(&exit_callbacks, call, arg, free_func); +} + int main(int argc, char **argv) { JMP_BUF back; - int e, num; + int e, num, do_backend; char *p; struct array *a; #ifdef DECLARE_ENVIRON @@ -268,28 +278,41 @@ int main(int argc, char **argv) if(SETJMP(back)) { - ONERROR tmp; - SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); - assign_svalue_no_free(sp, & throw_value); - sp++; - APPLY_MASTER("handle_error", 1); + if(throw_severity == THROW_EXIT) + { + num=throw_value.u.integer; + }else{ + ONERROR tmp; + SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); + assign_svalue_no_free(sp, & throw_value); + sp++; + APPLY_MASTER("handle_error", 1); + pop_stack(); + UNSET_ONERROR(tmp); + num=10; + } + }else{ + back.severity=THROW_EXIT; + + apply(master(),"_main",2); pop_stack(); - UNSET_ONERROR(tmp); - exit(10); + + backend(); + num=0; } - - apply(master(),"_main",2); - pop_stack(); - UNSETJMP(back); - backend(); + do_exit(num); +} + +void do_exit(int num) +{ + call_callback(&exit_callbacks, (void *)0); + free_callback(&exit_callbacks); - push_int(0); - f_exit(1); + exit_modules(); - /* NOT REACHED */ - return(-1); /* To avoid warnings. */ + exit(num); } @@ -315,6 +338,7 @@ void low_exit_main(void) void cleanup_added_efuns(void); void cleanup_pike_types(void); void cleanup_program(void); + void cleanup_compiler(void); th_cleanup(); exit_dynamic_load(); @@ -325,13 +349,82 @@ void low_exit_main(void) cleanup_added_efuns(); cleanup_pike_types(); cleanup_program(); + cleanup_compiler(); do_gc(); cleanup_callbacks(); +#if defined(DEBUG) && defined(DEBUG_MALLOC) + if(verbose_debug_exit) + { + INT32 num,size,recount=0; + + count_memory_in_arrays(&num, &size); + if(num || size) + { + recount++; + fprintf(stderr,"Arrays left: %d (%d bytes) (zapped)\n",num,size); + } + + zap_all_arrays(); + + count_memory_in_mappings(&num, &size); + if(num || size) + { + recount++; + fprintf(stderr,"Mappings left: %d (%d bytes) (zapped)\n",num,size); + } + + zap_all_mappings(); + + count_memory_in_multisets(&num, &size); + if(num || size) + fprintf(stderr,"Multisets left: %d (%d bytes)\n",num,size); + + + if(recount) + { + fprintf(stderr,"Garbage collecting..\n"); + do_gc(); + + count_memory_in_arrays(&num, &size); + fprintf(stderr,"Arrays left: %d (%d bytes)\n",num,size); + count_memory_in_mappings(&num, &size); + fprintf(stderr,"Mappings left: %d (%d bytes)\n",num,size); + count_memory_in_multisets(&num, &size); + fprintf(stderr,"Multisets left: %d (%d bytes)\n",num,size); + } + + + count_memory_in_programs(&num, &size); + if(num || size) + fprintf(stderr,"Programs left: %d (%d bytes)\n",num,size); + + { + struct program *p; + for(p=first_program;p;p=p->next) + { + describe_something(p, T_PROGRAM); + } + } + + + count_memory_in_objects(&num, &size); + if(num || size) + fprintf(stderr,"Objects left: %d (%d bytes)\n",num,size); + + count_memory_in_strings(&num, &size); + if(num || size) + fprintf(stderr,"Strings left: %d (%d bytes) (zapped)\n",num,size); + + cleanup_shared_string_table(); + } +#else + zap_all_arrays(); zap_all_mappings(); cleanup_shared_string_table(); +#endif } diff --git a/src/main.h b/src/main.h index d9362f9734d7b9f4eb7f7be4622aae1fbebc2c94..64e65a99271217f3f1df7b79e001d8e864c0068b 100644 --- a/src/main.h +++ b/src/main.h @@ -14,7 +14,11 @@ extern int d_flag, t_flag, a_flag, l_flag, c_flag, p_flag; struct callback *add_post_master_callback(callback_func call, void *arg, callback_func free_func); -void main(int argc, char **argv, char **env); +struct callback *add_exit_callback(callback_func call, + void *arg, + callback_func free_func); +int main(int argc, char **argv); +void do_exit(int num); void low_init_main(void); void exit_main(void); void init_main(void); diff --git a/src/mapping.c b/src/mapping.c index 62066d19ea553095308cc9b65ded44bebfa0a981..226ccc7f59f1330193b94ca10f264ec67c8deb0d 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: mapping.c,v 1.26 1998/01/13 01:51:28 grubba Exp $"); +RCSID("$Id: mapping.c,v 1.27 1998/01/25 08:25:10 hubbe Exp $"); #include "main.h" #include "object.h" #include "mapping.h" @@ -624,17 +624,23 @@ struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op) ai=mapping_indices(a); av=mapping_values(a); - zipper=get_set_order(ai); - order_array(ai, zipper); - order_array(av, zipper); - free((char *)zipper); + if(ai->size > 1) + { + zipper=get_set_order(ai); + order_array(ai, zipper); + order_array(av, zipper); + free((char *)zipper); + } bi=mapping_indices(b); bv=mapping_values(b); - zipper=get_set_order(bi); - order_array(bi, zipper); - order_array(bv, zipper); - free((char *)zipper); + if(bi->size > 1) + { + zipper=get_set_order(bi); + order_array(bi, zipper); + order_array(bv, zipper); + free((char *)zipper); + } zipper=merge(ai,bi,op); @@ -714,7 +720,7 @@ int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p) void describe_mapping(struct mapping *m,struct processing *p,int indent) { struct processing doing; - INT32 e,d; + INT32 e,d,q; struct keypair *k; char buf[40]; @@ -739,15 +745,16 @@ void describe_mapping(struct mapping *m,struct processing *p,int indent) sprintf(buf,"([ /* %ld elements */\n",(long) m->size); my_strcat(buf); - d=0; + q=0; LOOP(m) { - if(d) + if(q) { - my_strcat(",\n"); + my_putchar(','); + my_putchar('\n'); } else { - d=1; + q=1; } for(d=0; d<indent; d++) my_putchar(' '); describe_svalue(& k->ind, indent+2, p); @@ -938,9 +945,6 @@ void check_mapping(struct mapping *m) if(m->size > (m->hashsize + 3) * AVG_LINK_LENGTH) fatal("Pretty mean hashtable there buster!.\n"); - if(m->size < (m->hashsize - 3) * MIN_LINK_LENGTH) - fatal("Hashsize is too small for mapping.\n"); - if(m->size > 0 && (!m->ind_types || !m->val_types)) fatal("Mapping type fields are... wrong.\n"); @@ -1065,6 +1069,37 @@ void gc_free_all_unreferenced_mappings(void) } } +#ifdef DEBUG + +void simple_describe_mapping(struct mapping *m) +{ + char *s; + init_buf(); + describe_mapping(m,0,2); + s=simple_free_buf(); + fprintf(stderr,"%s\n",s); + free(s); +} + + +void debug_dump_mapping(struct mapping *m) +{ + fprintf(stderr,"Refs=%d, next=%p, prev=%p, size=%d, hashsize=%d\n", + m->refs, + m->next, + m->prev, + m->size, + m->hashsize); + fprintf(stderr,"Indices type field = "); + debug_dump_type_field(m->ind_types); + fprintf(stderr,"\n"); + fprintf(stderr,"Values type field = "); + debug_dump_type_field(m->val_types); + fprintf(stderr,"\n"); + simple_describe_mapping(m); +} +#endif + void zap_all_mappings(void) { INT32 e; @@ -1075,6 +1110,11 @@ void zap_all_mappings(void) { m->refs++; +#if defined(DEBUG) && defined(DEBUG_MALLOC) + if(verbose_debug_exit) + debug_dump_mapping(m); +#endif + for(e=0;e<m->hashsize;e++) { while((k=m->hash[e])) diff --git a/src/mapping.h b/src/mapping.h index 4efb98b5ac8301a0ce01828912fa3aa074cd8dcc..e077b9b6e55e0ab2c73b37b2aba0844c4198a19e 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -72,6 +72,8 @@ void gc_mark_mapping_as_referenced(struct mapping *m); void gc_check_all_mappings(void); void gc_mark_all_mappings(void); void gc_free_all_unreferenced_mappings(void); +void simple_describe_mapping(struct mapping *m); +void debug_dump_mapping(struct mapping *m); void zap_all_mappings(void); void count_memory_in_mappings(INT32 *num_, INT32 *size_); /* Prototypes end here */ diff --git a/src/module.c b/src/module.c index 24a282a519594e24de15af4144a8cd01b8b557df..0814f40b2a0848c72363c7de72526c3972cc1b40 100644 --- a/src/module.c +++ b/src/module.c @@ -36,9 +36,8 @@ void init_modules(void) { unsigned int e; struct mapping *m = allocate_mapping(10); - m->refs++; push_text("_static_modules"); - push_mapping(m); + ref_push_mapping(m); f_add_constant(2); for(e=0;e<NELEM(module_list);e++) @@ -54,6 +53,7 @@ void init_modules(void) mapping_insert(m, sp-2, sp-1); pop_n_elems(2); } + free_mapping(m); } void exit_modules(void) diff --git a/src/modules/Image/colortable.c b/src/modules/Image/colortable.c index 15916b7d4bd94aa2b66f8e945c037cbd9d10ab0b..2fa41aec5cd10b2c864de4fd7235b535f1d418e1 100644 --- a/src/modules/Image/colortable.c +++ b/src/modules/Image/colortable.c @@ -1,11 +1,11 @@ #include <config.h> -/* $Id: colortable.c,v 1.35 1998/01/21 23:51:38 grubba Exp $ */ +/* $Id: colortable.c,v 1.36 1998/01/25 08:26:38 hubbe Exp $ */ /* **! module Image **! note -**! $Id: colortable.c,v 1.35 1998/01/21 23:51:38 grubba Exp $ +**! $Id: colortable.c,v 1.36 1998/01/25 08:26:38 hubbe Exp $ **! class colortable **! **! This object keeps colortable information, @@ -21,7 +21,7 @@ #undef COLORTABLE_REDUCE_DEBUG #include "global.h" -RCSID("$Id: colortable.c,v 1.35 1998/01/21 23:51:38 grubba Exp $"); +RCSID("$Id: colortable.c,v 1.36 1998/01/25 08:26:38 hubbe Exp $"); #include <sys/types.h> #include <sys/stat.h> @@ -46,6 +46,7 @@ RCSID("$Id: colortable.c,v 1.35 1998/01/21 23:51:38 grubba Exp $"); #include "image.h" #include "colortable.h" +#include "dmalloc.h" struct program *image_colortable_program; extern struct program *image_program; diff --git a/src/modules/Image/encodings/gif.c b/src/modules/Image/encodings/gif.c index cec07adab80dcdf8dc9b35cfd0dd3ce2ad957f0e..bebbb87077d45d0142a40258d5fbb7f3f6bb17c2 100644 --- a/src/modules/Image/encodings/gif.c +++ b/src/modules/Image/encodings/gif.c @@ -1,9 +1,9 @@ -/* $Id: gif.c,v 1.29 1998/01/21 23:51:39 grubba Exp $ */ +/* $Id: gif.c,v 1.30 1998/01/25 08:27:14 hubbe Exp $ */ /* **! module Image **! note -**! $Id: gif.c,v 1.29 1998/01/21 23:51:39 grubba Exp $ +**! $Id: gif.c,v 1.30 1998/01/25 08:27:14 hubbe Exp $ **! submodule GIF **! **! This submodule keep the GIF encode/decode capabilities @@ -31,7 +31,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: gif.c,v 1.29 1998/01/21 23:51:39 grubba Exp $"); +RCSID("$Id: gif.c,v 1.30 1998/01/25 08:27:14 hubbe Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -2135,28 +2135,25 @@ void init_image_gif(void) /** constants **/ - push_int(GIF_RENDER); - add_constant(make_shared_string("RENDER"),sp-1,0); - push_int(GIF_EXTENSION); - add_constant(make_shared_string("EXTENSION"),sp-1,0); + add_integer_constant("RENDERER",GIF_RENDER,0); + add_integer_constant("EXTENSION",GIF_EXTENSION,0); - push_int(GIF_LOOSE_GCE); - add_constant(make_shared_string("LOOSE_GCE"),sp-1,0); - push_int(GIF_NETSCAPE_LOOP); - add_constant(make_shared_string("NETSCAPE_LOOP"),sp-1,0); + add_integer_constant("LOOSE_GCE",GIF_LOOSE_GCE,0); + add_integer_constant("NETSCAPE_LOOP",GIF_NETSCAPE_LOOP,0); - push_int(GIF_ERROR_PREMATURE_EOD); - add_constant(make_shared_string("ERROR_PREMATURE_EOD"),sp-1,0); - push_int(GIF_ERROR_UNKNOWN_DATA); - add_constant(make_shared_string("ERROR_UNKNOWN_DATA"),sp-1,0); - push_int(GIF_ERROR_TOO_MUCH_DATA); - add_constant(make_shared_string("ERROR_TOO_MUCH_DATA"),sp-1,0); + add_integer_constant("ERROR_PREMATURE_EOD",GIF_ERROR_PREMATURE_EOD,0); + add_integer_constant("ERROR_UNKNOWN_DATA",GIF_ERROR_UNKNOWN_DATA,0); + add_integer_constant("ERROR_TOO_MUCH_DATA",GIF_ERROR_TOO_MUCH_DATA,0); /** done **/ image_gif_module_program=end_program(); push_object(clone_object(image_gif_module_program,0)); - add_constant(make_shared_string("GIF"),sp-1,0); + { + struct pike_string *s=make_shared_string("GIF"); + add_constant(s,sp-1,0); + free_string(s); + } pop_stack(); } diff --git a/src/modules/Image/encodings/png.c b/src/modules/Image/encodings/png.c index 21cdafdeb7de15603ee99b99de254d744593379f..afdca70d523db2cdbb0dd7f3bee8da7eefb50599 100644 --- a/src/modules/Image/encodings/png.c +++ b/src/modules/Image/encodings/png.c @@ -1,9 +1,9 @@ -/* $Id: png.c,v 1.1 1997/11/12 03:37:52 mirar Exp $ */ +/* $Id: png.c,v 1.2 1998/01/25 08:27:14 hubbe Exp $ */ /* **! module Image **! note -**! $Id: png.c,v 1.1 1997/11/12 03:37:52 mirar Exp $ +**! $Id: png.c,v 1.2 1998/01/25 08:27:14 hubbe Exp $ **! submodule PNG **! **! This submodule keep the PNG encode/decode capabilities @@ -23,7 +23,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: png.c,v 1.1 1997/11/12 03:37:52 mirar Exp $"); +RCSID("$Id: png.c,v 1.2 1998/01/25 08:27:14 hubbe Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -45,13 +45,17 @@ void image_png__module_value(INT32 args) void init_image_png(void) { + struct pike_string *s; + struct program *p; start_new_program(); add_function("_module_value",image_png__module_value, "function(:object)",0); - push_object(clone_object(end_program(),0)); - add_constant(make_shared_string("PNG"),sp-1,0); + push_object(clone_object(p=end_program(),0)); + free_program(p); + add_constant(s=make_shared_string("PNG"),sp-1,0); + free_string(s); pop_stack(); } diff --git a/src/modules/Image/encodings/pnm.c b/src/modules/Image/encodings/pnm.c index 256207152f3d0045a5e7bf220f8662f6f909fe3e..5ee0c43e11a284655a619b0733b4786a1d6f7e69 100644 --- a/src/modules/Image/encodings/pnm.c +++ b/src/modules/Image/encodings/pnm.c @@ -1,9 +1,9 @@ -/* $Id: pnm.c,v 1.11 1998/01/16 22:09:17 grubba Exp $ */ +/* $Id: pnm.c,v 1.12 1998/01/25 08:27:15 hubbe Exp $ */ /* **! module Image **! note -**! $Id: pnm.c,v 1.11 1998/01/16 22:09:17 grubba Exp $ +**! $Id: pnm.c,v 1.12 1998/01/25 08:27:15 hubbe Exp $ **! submodule PNM **! **! This submodule keeps the PNM encode/decode capabilities @@ -49,7 +49,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: pnm.c,v 1.11 1998/01/16 22:09:17 grubba Exp $"); +RCSID("$Id: pnm.c,v 1.12 1998/01/25 08:27:15 hubbe Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -609,7 +609,11 @@ void init_image_pnm(void) image_pnm_module_program=end_program(); push_object(clone_object(image_pnm_module_program,0)); - add_constant(make_shared_string("PNM"),sp-1,0); + { + struct pike_string *s=make_shared_string("PNM"); + add_constant(s,sp-1,0); + free_string(s); + } pop_stack(); } diff --git a/src/modules/Image/encodings/x.c b/src/modules/Image/encodings/x.c index dfc0ef0bc74a9958923098fd366415183f532800..d8ce3ebf17102b8ff8d3984414e0a16e04715c02 100644 --- a/src/modules/Image/encodings/x.c +++ b/src/modules/Image/encodings/x.c @@ -1,9 +1,9 @@ -/* $Id: x.c,v 1.4 1998/01/19 23:51:24 grubba Exp $ */ +/* $Id: x.c,v 1.5 1998/01/25 08:27:15 hubbe Exp $ */ /* **! module Image **! note -**! $Id: x.c,v 1.4 1998/01/19 23:51:24 grubba Exp $ +**! $Id: x.c,v 1.5 1998/01/25 08:27:15 hubbe Exp $ **! submodule X **! **! This submodule handles encoding and decoding of @@ -29,7 +29,7 @@ #include <winsock.h> #endif -RCSID("$Id: x.c,v 1.4 1998/01/19 23:51:24 grubba Exp $"); +RCSID("$Id: x.c,v 1.5 1998/01/25 08:27:15 hubbe Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -668,6 +668,7 @@ struct program *image_x_module_program=NULL; void init_image_x(void) { + struct pike_string *s; start_new_program(); add_function("encode_truecolor",x_encode_truecolor, @@ -679,7 +680,8 @@ void init_image_x(void) image_x_module_program=end_program(); push_object(clone_object(image_x_module_program,0)); - add_constant(make_shared_string("X"),sp-1,0); + add_constant(s=make_shared_string("X"),sp-1,0); + free_string(s); pop_stack(); } diff --git a/src/modules/Yp/yp.c b/src/modules/Yp/yp.c index 163afc9212dc8856e54d18bc953341a068f6ceaf..71fffa5c3a72396458b79f2f6796847135df63c4 100644 --- a/src/modules/Yp/yp.c +++ b/src/modules/Yp/yp.c @@ -216,11 +216,12 @@ void pike_module_init(void) add_function("map", f_map, "function(string,function|array(function):void)", 0); add_function("order", f_order, "function(string:int)", 0); - add_program_constant("Domain", end_program(), 0); + end_class("Domain", 0); } void pike_module_exit(void) { + } #else diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index fdb99d8b7ad2fb954324f5dcba85fd201caac8b0..63a226996382fbcedba6a0549e20e71e02d71796 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -60,6 +60,8 @@ # endif #endif +#include "dmalloc.h" + struct array *encode_stat(struct stat *s) { struct array *a; diff --git a/src/modules/files/file.c b/src/modules/files/file.c index ea96e5e793ae2b2b060a14a1f1e6bce087e33dbe..209693236553c90f10534f879ed50387597e6b1e 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -6,7 +6,7 @@ #define READ_BUFFER 8192 #include "global.h" -RCSID("$Id: file.c,v 1.68 1998/01/21 23:51:41 grubba Exp $"); +RCSID("$Id: file.c,v 1.69 1998/01/25 08:28:00 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -75,6 +75,9 @@ RCSID("$Id: file.c,v 1.68 1998/01/21 23:51:41 grubba Exp $"); #include <netdb.h> #endif +#include "dmalloc.h" + + #ifndef SEEK_SET #define SEEK_SET 0 #endif diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c index a05a3196877d18ab69210b2f041d9229eeda2cd7..1f89819ea4d78e12ff6ca32b88619ee5d1e04066 100644 --- a/src/modules/files/socket.c +++ b/src/modules/files/socket.c @@ -57,6 +57,8 @@ #include <sys/socketvar.h> #endif +#include "dmalloc.h" + struct port { int fd; @@ -227,7 +229,7 @@ static void port_bind(INT32 args) addr.sin_family = AF_INET; THREADS_ALLOW(); - tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || fd_listen(fd, 16384) < 0; + tmp=fd_bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 || fd_listen(fd, 5) < 0; THREADS_DISALLOW(); if(tmp) diff --git a/src/modules/files/socktest.pike b/src/modules/files/socktest.pike index 0094853eb4bcc3a82c0289eea003212179b1009f..9b65cb5db27d93921bccc16a0dc746636fb9d8b7 100755 --- a/src/modules/files/socktest.pike +++ b/src/modules/files/socktest.pike @@ -1,6 +1,6 @@ #!/usr/local/bin/pike -/* $Id: socktest.pike,v 1.6 1998/01/13 23:01:25 hubbe Exp $ */ +/* $Id: socktest.pike,v 1.7 1998/01/25 08:28:01 hubbe Exp $ */ import Stdio; import String; @@ -90,7 +90,7 @@ class Socket { input_buffer+=foo; } - varargs void create(object o) + void create(object|void o) { daemon->got_callback(); daemon->start(); @@ -152,6 +152,7 @@ array(object(Socket)) stdtest() if(!sock2) { werror("Accept returned 0\n"); + sleep(1); exit(1); } sock2=Socket(sock2); @@ -278,7 +279,7 @@ void accept_callback() object o=port1::accept(); if(!o) { - perror("Accept failed"); + werror("Accept failed"); } o=Socket(o); o->expected_data=strmult("foobar",4711); @@ -286,17 +287,20 @@ void accept_callback() int main() { - for(portno1=2001;portno1<65536;portno1++) - if(port1::bind(portno1, accept_callback)) - break; - - if(portno1==65536) perror("Bind failed.\n"); + if(!port1::bind(0, accept_callback)) + { + werror("Bind failed.\n"); + exit(1); + } + sscanf(port1::query_address(),"%*s %d",portno1); - for(portno2=2001;portno2<65536;portno2++) - if(port2::bind(portno2)) - break; + if(!port2::bind(0)) + { + werror("Bind failed.\n"); + exit(1); + } - if(portno2==65536) perror("Bind failed.\n"); + sscanf(port2::query_address(),"%*s %d",portno2); werror("Doing simple tests. "); stdtest(); diff --git a/src/modules/spider/accesseddb.c b/src/modules/spider/accesseddb.c index 691b28ce1c835adf4ec55a584fe965710508dd39..98695a64128358243cab7c5179cbb1d73f5ba7ed 100644 --- a/src/modules/spider/accesseddb.c +++ b/src/modules/spider/accesseddb.c @@ -54,6 +54,7 @@ #include <sys/stat.h> #include <fcntl.h> +#include "dmalloc.h" #include "accesseddb.h" #define COOKIE 0x11223344 diff --git a/src/modules/spider/dumudp.c b/src/modules/spider/dumudp.c index 93120f80feebedcd2e4566d143b0efb570f674e0..2beb5172677b1f04cc2d46160cbd91a0385ed977 100644 --- a/src/modules/spider/dumudp.c +++ b/src/modules/spider/dumudp.c @@ -1,7 +1,7 @@ #include "config.h" #include "global.h" -RCSID("$Id: dumudp.c,v 1.31 1998/01/21 19:57:17 hubbe Exp $"); +RCSID("$Id: dumudp.c,v 1.32 1998/01/25 08:28:24 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -77,6 +77,8 @@ RCSID("$Id: dumudp.c,v 1.31 1998/01/21 19:57:17 hubbe Exp $"); #include <netdb.h> #endif +#include "dmalloc.h" + struct dumudp { int fd; struct svalue read_callback; diff --git a/src/modules/spider/spider.c b/src/modules/spider/spider.c index 0f37b6684435b4b5beaa011e09d938f8a7dca0c6..5c0d310ecfd398e53b7fea77eafc8bd2b222ce22 100644 --- a/src/modules/spider/spider.c +++ b/src/modules/spider/spider.c @@ -40,7 +40,7 @@ #include "threads.h" #include "operators.h" -RCSID("$Id: spider.c,v 1.50 1998/01/16 22:33:15 grubba Exp $"); +RCSID("$Id: spider.c,v 1.51 1998/01/25 08:28:24 hubbe Exp $"); #ifdef HAVE_PWD_H #include <pwd.h> @@ -79,6 +79,8 @@ RCSID("$Id: spider.c,v 1.50 1998/01/16 22:33:15 grubba Exp $"); #include <errno.h> +#include "dmalloc.h" + #include "accesseddb.h" #define MAX_PARSE_RECURSE 102 diff --git a/src/modules/system/system.c b/src/modules/system/system.c index e05e1dd1821bb04320a9628795a19cdd63887a90..e449f02a87a29e43afd69a491d5c2d64f67358ca 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.38 1998/01/21 19:59:11 hubbe Exp $ + * $Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $ * * System-call module for Pike * @@ -14,7 +14,7 @@ #include "system.h" #include "global.h" -RCSID("$Id: system.c,v 1.38 1998/01/21 19:59:11 hubbe Exp $"); +RCSID("$Id: system.c,v 1.39 1998/01/25 08:28:45 hubbe Exp $"); #ifdef HAVE_WINSOCK2_H #include <winsock2.h> #endif @@ -68,6 +68,7 @@ RCSID("$Id: system.c,v 1.38 1998/01/21 19:59:11 hubbe Exp $"); #include <sys/stat.h> #endif /* HAVE_SYS_STAT_H */ +#include "dmalloc.h" /* * Functions */ diff --git a/src/multiset.c b/src/multiset.c index 2ff4603447ccc707a48e991833f76c8ba1b7c1e2..be87bc9a2895861fccb8dfedc617d27f8493765b 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -66,6 +66,7 @@ void really_free_multiset(struct multiset *l) static void order_multiset(struct multiset *l) { INT32 *order; + if(l->ind->size < 2) return; order = get_set_order(l->ind); l->ind = order_array(l->ind, order); free((char *)order); @@ -316,3 +317,4 @@ void count_memory_in_multisets(INT32 *num_, INT32 *size_) *num_=num; *size_=size; } + diff --git a/src/object.c b/src/object.c index 9fbae6a701da157b814b25e857099b924be9c2b3..3ea12bf3045863a02121d7966f2a5257c67034b3 100644 --- a/src/object.c +++ b/src/object.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: object.c,v 1.32 1998/01/15 05:59:42 hubbe Exp $"); +RCSID("$Id: object.c,v 1.33 1998/01/25 08:25:12 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -201,15 +201,10 @@ struct object *get_master(void) error("Couldn't load master program. (%s)\n",master_file); } } - master_object=clone_object(master_program,0); + master_object=low_clone(master_program); call_c_initializers(master_object); call_pike_initializers(master_object,0); - - apply_lfun(master_object,LFUN___INIT,0); - pop_stack(); - apply_lfun(master_object,LFUN_CREATE,0); - pop_stack(); inside = 0; return master_object; diff --git a/src/peep.c b/src/peep.c index 0339a6054714bd67b25b2d2c0b5859a41ca43ee6..67847598727b49b6a1f2452b2650e34e4173fc2d 100644 --- a/src/peep.c +++ b/src/peep.c @@ -159,9 +159,9 @@ void assemble(void) max_label = c->arg; - labels=(INT32 *)xalloc(sizeof(INT32) * (max_label+1)); - jumps=(INT32 *)xalloc(sizeof(INT32) * (max_label+1)); - uses=(INT32 *)xalloc(sizeof(INT32) * (max_label+1)); + labels=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); + jumps=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); + uses=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); for(e=0;e<=max_label;e++) { diff --git a/src/pike_memory.c b/src/pike_memory.c index e5d158ad153c6b2019755b8e81777e0bf4b82d58..5b4b88783d881ef31e1e6008a878975fcb5c7f4a 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -8,17 +8,6 @@ #include "error.h" #include "pike_macros.h" -char *xalloc(SIZE_T size) -{ - char *ret; - if(!size) return 0; - - ret=(char *)malloc(size); - if(ret) return ret; - - error("Out of memory.\n"); - return 0; -} /* strdup() is used by several modules, so let's provide it */ #ifndef HAVE_STRDUP @@ -94,6 +83,7 @@ void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order) { INT32 e; char *tmp; + if(nitems<2) return; tmp=xalloc(size * nitems); #undef DOSIZE #define DOSIZE(X,Y) \ @@ -406,3 +396,301 @@ void memfill(char *to, } } } + +#ifdef DEBUG_MALLOC + +#undef xalloc +#undef malloc +#undef free +#undef realloc +#undef calloc +#undef xalloc +#undef strdup +#undef main + +int verbose_debug_malloc = 0; +int verbose_debug_exit = 1; + +#define BSIZE 16382 +#define HSIZE 65599 + +struct memloc +{ + struct memloc *next; + const char *filename; + int line; + int times; +}; + +struct memhdr +{ + struct memhdr *next; + size_t size; + void *data; + struct memloc *locations; +}; + +static struct memhdr *hash[HSIZE]; + +struct memhdr_block +{ + struct memhdr_block *next; + struct memhdr memhdrs[BSIZE]; +}; + +static struct memhdr_block *memhdr_blocks=0; +static struct memhdr *free_memhdrs=0; + +static struct memhdr *alloc_memhdr(void) +{ + struct memhdr *tmp; + if(!free_memhdrs) + { + struct memhdr_block *n; + int e; + n=(struct memhdr_block *)malloc(sizeof(struct memhdr_block)); + if(!n) + { + fprintf(stderr,"Fatal: out of memory.\n"); + verbose_debug_exit=0; + exit(17); + } + n->next=memhdr_blocks; + memhdr_blocks=n; + + for(e=0;e<BSIZE;e++) + { + n->memhdrs[e].next=free_memhdrs; + free_memhdrs=n->memhdrs+e; + } + } + + tmp=free_memhdrs; + free_memhdrs=tmp->next; + return tmp; +} + +struct memloc_block +{ + struct memloc_block *next; + struct memloc memlocs[BSIZE]; +}; + +static struct memloc_block *memloc_blocks=0; +static struct memloc *free_memlocs=0; + +static struct memloc *alloc_memloc(void) +{ + struct memloc *tmp; + if(!free_memlocs) + { + struct memloc_block *n; + int e; + n=(struct memloc_block *)malloc(sizeof(struct memloc_block)); + if(!n) + { + fprintf(stderr,"Fatal: out of memory.\n"); + verbose_debug_exit=0; + exit(17); + } + n->next=memloc_blocks; + memloc_blocks=n; + + for(e=0;e<BSIZE;e++) + { + n->memlocs[e].next=free_memlocs; + free_memlocs=n->memlocs+e; + } + } + + tmp=free_memlocs; + free_memlocs=tmp->next; + return tmp; +} + +static struct memhdr *find_memhdr(void *p) +{ + struct memhdr *mh; + unsigned long h=(long)p; + h%=HSIZE; + for(mh=hash[h]; mh; mh=mh->next) + if(mh->data==p) + return mh; + return NULL; +} + +static void add_location(struct memhdr *mh, const char *fn, int line) +{ + struct memloc *ml; + for(ml=mh->locations;ml;ml=ml->next) + if(ml->filename==fn && ml->line==line) + return; + + ml=alloc_memloc(); + ml->line=line; + ml->filename=fn; + ml->next=mh->locations; + ml->times++; + mh->locations=ml; +} + +static void make_memhdr(void *p, int s, const char *fn, int line) +{ + struct memhdr *mh=alloc_memhdr(); + struct memloc *ml=alloc_memloc(); + unsigned long h=(long)p; + h%=HSIZE; + mh->next=hash[h]; + mh->data=p; + mh->size=s; + mh->locations=ml; + ml->filename=fn; + ml->line=line; + ml->next=0; + ml->times=1; + hash[h]=mh; +} + +static int remove_memhdr(void *p) +{ + struct memhdr **prev,*mh; + unsigned long h=(long)p; + h%=HSIZE; + for(prev=hash+h;(mh=*prev);prev=&(mh->next)) + { + if(mh->data==p) + { + struct memloc *ml; + while((ml=mh->locations)) + { + mh->locations=ml->next; + ml->next=free_memlocs; + free_memlocs=ml; + } + *prev=mh->next; + mh->next=free_memhdrs; + free_memhdrs=mh; + + return 1; + } + } + return 0; +} + +void *debug_malloc(size_t s, const char *fn, int line) +{ + void *m=malloc(s); + if(m) make_memhdr(m, s, fn, line); + + if(verbose_debug_malloc) + fprintf(stderr, "malloc(%d) => %p (%s:%d)\n", s, m, fn, line); + + return m; +} + +char *debug_xalloc(long size, const char *fn, int line) +{ + char *ret; + if(!size) return 0; + + ret=(char *)debug_malloc(size,fn, line); + if(ret) return ret; + + error("Out of memory.\n"); + return 0; +} + +void *debug_calloc(size_t a, size_t b, const char *fn, int line) +{ + void *m=calloc(a, b); + + if(m) make_memhdr(m, a*b, fn, line); + + if(verbose_debug_malloc) + fprintf(stderr, "calloc(%d,%d) => %p (%s:%d)\n", a, b, m, fn, line); + + return m; +} + +void *debug_realloc(void *p, size_t s, const char *fn, int line) +{ + void *m; + m=realloc(p, s); + if(m) { + if(p) remove_memhdr(p); + make_memhdr(m, s, fn, line); + } + if(verbose_debug_malloc) + fprintf(stderr, "realloc(%p,%d) => %p (%s:%d)\n", p, s, m, fn,line); + return m; +} + +void debug_free(void *p, const char *fn, int line) +{ + remove_memhdr(p); + free(p); + if(verbose_debug_malloc) + fprintf(stderr, "free(%p) (%s:%d)\n", p, fn,line); +} + +char *debug_strdup(const char *s, const char *fn, int line) +{ + char *m=strdup(s); + + if(m) make_memhdr(m, strlen(s)+1, fn, line); + + if(verbose_debug_malloc) + fprintf(stderr, "strdup(\"%s\") => %p (%s:%d)\n", s, m, fn, line); + return m; +} + +static void cleanup_memhdrs() +{ + unsigned long h; + if(verbose_debug_exit) + { + for(h=0;h<HSIZE;h++) + { + struct memhdr *m; + for(m=hash[h];m;m=m->next) + { + struct memloc *l; + fprintf(stderr, "LEAK: (%p) %d bytes (%ld refs?)\n",m->data, m->size,(long)*(INT32 *)m->data); + for(l=m->locations;l;l=l->next) + fprintf(stderr," *** %s:%d (%d times)\n",l->filename, l->line, l->times); + } + } + } +} + +int main(int argc, char *argv[]) +{ + extern int dbm_main(int, char **); + atexit(cleanup_memhdrs); + return dbm_main(argc, argv); +} + +void * debug_malloc_update_location(void *p,const char *fn, int line) +{ + struct memhdr *mh=find_memhdr(p); + if(mh) + add_location(mh, fn, line); + return p; +} + + +#else + +char *xalloc(long size) +{ + char *ret; + if(!size) return 0; + + ret=(char *)malloc(size); + if(ret) return ret; + + error("Out of memory.\n"); + return 0; +} + +#endif diff --git a/src/pike_memory.h b/src/pike_memory.h index e53a9fe6ef9d676fa3f6634ceed07be7f49ab81f..5e97061800d1ae43d18ab367c90f2463725d4b39 100644 --- a/src/pike_memory.h +++ b/src/pike_memory.h @@ -34,7 +34,6 @@ struct mem_searcher }; /* Prototypes begin here */ -char *xalloc(SIZE_T size); void swap(char *a, char *b, INT32 size); void reverse(char *memory, INT32 nitems, INT32 size); void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order); diff --git a/src/pike_types.c b/src/pike_types.c index ffc041098081be6acd1701744e6344d20989442c..f83fc612bbb56241ba4276763ce73a4b417bf557 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.28 1998/01/16 22:33:07 grubba Exp $"); +RCSID("$Id: pike_types.c,v 1.29 1998/01/25 08:25:13 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -212,7 +212,7 @@ void push_finished_type(struct pike_string *type) for(e=type->len-1;e>=0;e--) push_type(type->str[e]); } -struct pike_string *pop_unfinished_type(void) +struct pike_string *debug_pop_unfinished_type(void) { int len,e; struct pike_string *s; @@ -226,7 +226,7 @@ struct pike_string *pop_unfinished_type(void) return s; } -struct pike_string *pop_type(void) +struct pike_string *debug_pop_type(void) { struct pike_string *s; s=pop_unfinished_type(); diff --git a/src/pike_types.h b/src/pike_types.h index bf7934a3d1cbde7a36286ac97adbffd86d6402ee..00646b53a404fa1a692040e0e340bf65bdfc0a3e 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -66,8 +66,8 @@ void type_stack_reverse(void); void push_type_int(unsigned INT32 i); void push_unfinished_type(char *s); void push_finished_type(struct pike_string *type); -struct pike_string *pop_unfinished_type(void); -struct pike_string *pop_type(void); +struct pike_string *debug_pop_unfinished_type(void); +struct pike_string *debug_pop_type(void); struct pike_string *parse_type(char *s); void stupid_describe_type(char *a,INT32 len); void simple_describe_type(struct pike_string *s); @@ -87,4 +87,13 @@ char *get_name_of_type(int t); void cleanup_pike_types(void); /* Prototypes end here */ +#ifdef DEBUG_MALLOC +#define pop_type() ((struct pike_string *)debug_malloc_update_location(debug_pop_type(),__FILE__,__LINE__)) +#define pop_unfinished_type() \ + ((struct pike_string *)debug_malloc_update_location(debug_pop_unfinished_type(),__FILE__,__LINE__)) +#else +#define pop_type debug_pop_type +#define pop_unfinished_type debug_pop_unfinished_type +#endif + #endif diff --git a/src/program.c b/src/program.c index 2ef634b5cb13eb84d75ef0f89c5d97df1707aade..3c5ea79646ad5bd0b328892e5faeb2e7c841ab63 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.53 1998/01/22 00:51:04 grubba Exp $"); +RCSID("$Id: program.c,v 1.54 1998/01/25 08:25:14 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -185,8 +185,7 @@ struct node_s *find_module_identifier(struct pike_string *ident) while(--e>=0) { push_svalue(modules+e); - push_string(ident); - ident->refs++; + ref_push_string(ident); f_index(2); if(!IS_UNDEFINED(sp-1)) @@ -250,7 +249,8 @@ struct program *id_to_program(INT32 id) h=id & (ID_TO_PROGRAM_CACHE_SIZE-1); if((p=id_to_program_cache[h])) - if(p->id==id) return p; + if(p->id==id) + return p; if(id) { @@ -258,11 +258,7 @@ struct program *id_to_program(INT32 id) { if(id==p->id) { - if(id_to_program_cache[h]) - free_program(id_to_program_cache[h]); - id_to_program_cache[h]=p; - p->refs++; return p; } } @@ -434,6 +430,7 @@ void low_start_new_program(struct program *p, i.inherit_level=0; i.parent=0; i.parent_identifier=0; + i.parent_offset=1; i.name=0; add_to_inherits(i); } @@ -728,17 +725,16 @@ struct program *end_first_pass(int finish) if(init_node) { union idptr tmp; - struct pike_string *s; - s=make_shared_string("__INIT"); dooptcode(s, mknode(F_ARG_LIST, init_node,mknode(F_RETURN,mkintnode(0),0)), function_type_string, 0); - free_string(s); init_node=0; } + free_string(s); + pop_compiler_frame(); /* Pop __INIT local variables */ exit_type_stack(); @@ -894,16 +890,17 @@ void rename_last_inherit(struct pike_string *n) /* * make this program inherit another program */ -void do_inherit(struct svalue *prog, - INT32 flags, - struct pike_string *name) +void low_inherit(struct program *p, + struct object *parent, + int parent_identifier, + int parent_offset, + INT32 flags, + struct pike_string *name) { int e, inherit_offset, storage_offset; struct inherit inherit; struct pike_string *s; - struct program *p=program_from_svalue(prog); - if(!p) { @@ -925,10 +922,13 @@ void do_inherit(struct svalue *prog, inherit.inherit_level ++; if(!e) { - if(prog->type == T_FUNCTION) + if(parent) { - inherit.parent=prog->u.object; - inherit.parent_identifier=prog->subtype; + inherit.parent=parent; + inherit.parent_identifier=parent_identifier; + inherit.parent_offset=0; + }else{ + inherit.parent_offset+=parent_offset; } } if(inherit.parent) inherit.parent->refs++; @@ -989,6 +989,71 @@ void do_inherit(struct svalue *prog, } } +void do_inherit(struct svalue *s, + INT32 flags, + struct pike_string *name) +{ + struct program *p=program_from_svalue(s); + low_inherit(p, + s->type == T_FUNCTION ? s->u.object : 0, + s->subtype, + 0, + flags, + name); +} + +void compiler_do_inherit(node *n, + INT32 flags, + struct pike_string *name) +{ + switch(n->token) + { + case F_EXTERNAL: + { + struct identifier *i; + struct program *p=parent_compilation(n->u.integer.a); + INT32 numid=n->u.integer.b; + + if(!p) + { + yyerror("Failed to resolv external constant.\n"); + return; + } + + i=ID_FROM_INT(p, numid); + + if(IDENTIFIER_IS_CONSTANT(i->identifier_flags)) + { + struct svalue *s=PROG_FROM_INT(new_program, numid)->constants + i->func.offset; + if(s->type != T_PROGRAM) + { + yyerror("Inherit identifier is not a program"); + return; + }else{ + p=s->u.program; + } + }else{ + yyerror("Inherit identifier is not a constant program"); + return; + } + + low_inherit(p, + 0, + 0, + n->u.integer.a, + flags, + name); + break; + } + + default: + resolv_program(n); + do_inherit(sp-1, flags, name); + pop_stack(); + } +} + + void simple_do_inherit(struct pike_string *s, INT32 flags, struct pike_string *name) @@ -1092,7 +1157,7 @@ int define_variable(struct pike_string *name, struct pike_string *type, INT32 flags) { - int n; + int n, run_time_type; #ifdef DEBUG if(name!=debug_findstring(name)) @@ -1126,30 +1191,32 @@ int define_variable(struct pike_string *name, if(PROG_FROM_INT(new_program, n) == new_program) my_yyerror("Variable '%s' defined twice.",name->str); - if(ID_FROM_INT(new_program, n)->type != type) - my_yyerror("Illegal to redefine inherited variable with different type."); - - if(ID_FROM_INT(new_program, n)->identifier_flags != flags) - my_yyerror("Illegal to redefine inherited variable with different type."); + if(!(IDENTIFIERP(n)->id_flags & ID_INLINE)) + { + if(ID_FROM_INT(new_program, n)->type != type) + my_yyerror("Illegal to redefine inherited variable with different type."); + + if(ID_FROM_INT(new_program, n)->identifier_flags != flags) + my_yyerror("Illegal to redefine inherited variable with different type."); + return n; + } + } - } else { - int run_time_type=compile_type_to_runtime_type(type); + run_time_type=compile_type_to_runtime_type(type); - switch(run_time_type) - { + switch(run_time_type) + { case T_FUNCTION: case T_PROGRAM: run_time_type = T_MIXED; - } - - n=low_define_variable(name,type,flags, - add_storage(run_time_type == T_MIXED ? - sizeof(struct svalue) : - sizeof(union anything)), - run_time_type); - - } + + n=low_define_variable(name,type,flags, + add_storage(run_time_type == T_MIXED ? + sizeof(struct svalue) : + sizeof(union anything)), + run_time_type); + return n; } @@ -1240,11 +1307,16 @@ int add_constant(struct pike_string *name, if(PROG_FROM_INT(new_program, n) == new_program) my_yyerror("Identifier '%s' defined twice.",name->str); - new_program->identifier_references[n]=ref; - } else { - n=new_program->num_identifier_references; - add_to_identifier_references(ref); + if(!(IDENTIFIERP(n)->id_flags & ID_INLINE)) + { + /* override */ + new_program->identifier_references[n]=ref; + + return n; + } } + n=new_program->num_identifier_references; + add_to_identifier_references(ref); return n; } @@ -1355,7 +1427,6 @@ INT32 define_function(struct pike_string *name, i=isidentifier(name); - if(i >= 0) { /* already defined */ @@ -1383,65 +1454,70 @@ INT32 define_function(struct pike_string *name, my_yyerror("Illegal to redefine 'nomask' function %s.",name->str); } - /* We modify the old definition if it is in this program */ - if(ref.inherit_offset==0) + if(!(ref.id_flags & ID_INLINE)) { - if(func) - funp->func = *func; - else - funp->func.offset = -1; - - funp->identifier_flags=function_flags; - }else{ - /* Otherwise we make a new definition */ - copy_shared_string(fun.name, name); - copy_shared_string(fun.type, type); - - fun.run_time_type=T_FUNCTION; - - fun.identifier_flags=function_flags; - - if(func) - fun.func = *func; - else - fun.func.offset = -1; - - ref.identifier_offset=new_program->num_identifiers; - add_to_identifiers(fun); + /* We modify the old definition if it is in this program */ + if(ref.inherit_offset==0) + { + if(func) + funp->func = *func; + else + funp->func.offset = -1; + + funp->identifier_flags=function_flags; + }else{ + /* Otherwise we make a new definition */ + copy_shared_string(fun.name, name); + copy_shared_string(fun.type, type); + + fun.run_time_type=T_FUNCTION; + + fun.identifier_flags=function_flags; + + if(func) + fun.func = *func; + else + fun.func.offset = -1; + + ref.identifier_offset=new_program->num_identifiers; + add_to_identifiers(fun); + } + + ref.inherit_offset = 0; + ref.id_flags = flags; + new_program->identifier_references[i]=ref; + return i; } + } - ref.inherit_offset = 0; - ref.id_flags = flags; - new_program->identifier_references[i]=ref; - }else{ - /* define it */ - - copy_shared_string(fun.name, name); - copy_shared_string(fun.type, type); - - fun.identifier_flags=function_flags; - - fun.run_time_type=T_FUNCTION; - - if(func) - fun.func = *func; - else - fun.func.offset = -1; + /* define a new function */ - i=new_program->num_identifiers; + copy_shared_string(fun.name, name); + copy_shared_string(fun.type, type); + + fun.identifier_flags=function_flags; + + fun.run_time_type=T_FUNCTION; + + if(func) + fun.func = *func; + else + fun.func.offset = -1; + + i=new_program->num_identifiers; #ifdef PROFILING - fun.num_calls = 0; + fun.num_calls = 0; #endif /* PROFILING */ + + add_to_identifiers(fun); + + ref.id_flags = flags; + ref.identifier_offset = i; + ref.inherit_offset = 0; + + i=new_program->num_identifier_references; + add_to_identifier_references(ref); - add_to_identifiers(fun); - - ref.id_flags = flags; - ref.identifier_offset = i; - ref.inherit_offset = 0; - - i=new_program->num_identifier_references; - add_to_identifier_references(ref); - } return i; } @@ -1746,6 +1822,8 @@ struct program *compile(struct pike_string *prog) if(p && !num_parse_error) { low_start_new_program(p,0,0); + free_program(p); + p=0; compiler_pass=2; lex.pos=prog->str; yyparse(); /* Parse da program again */ @@ -1819,8 +1897,8 @@ void check_all_programs(void) void cleanup_program(void) { -#ifdef FIND_FUNCTION_HASHSIZE int e; +#ifdef FIND_FUNCTION_HASHSIZE for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) @@ -1830,6 +1908,7 @@ void cleanup_program(void) } } #endif + } #ifdef GC2 diff --git a/src/program.h b/src/program.h index 7e2aee546425911ec87ea30cb620e7ffd933573f..de26fe64c2f59d27a91f903e570bc184a0fcab55 100644 --- a/src/program.h +++ b/src/program.h @@ -100,8 +100,8 @@ union idptr #define IDENTIFIER_PIKE_FUNCTION 1 #define IDENTIFIER_C_FUNCTION 2 #define IDENTIFIER_FUNCTION 3 -#define IDENTIFIER_VARARGS 4 -#define IDENTIFIER_CONSTANT 8 +#define IDENTIFIER_CONSTANT 4 +#define IDENTIFIER_VARARGS 8 #define IDENTIFIER_IS_FUNCTION(X) ((X) & IDENTIFIER_FUNCTION) #define IDENTIFIER_IS_CONSTANT(X) ((X) & IDENTIFIER_CONSTANT) @@ -131,10 +131,9 @@ struct identifier #define ID_NOMASK 0x04 #define ID_PUBLIC 0x08 #define ID_PROTECTED 0x10 -#define ID_VARARGS 0x20 -#define ID_INLINE 0x40 -#define ID_HIDDEN 0x80 /* needed? */ -#define ID_INHERITED 0x100 +#define ID_INLINE 0x20 +#define ID_HIDDEN 0x40 /* needed? */ +#define ID_INHERITED 0x80 struct reference { @@ -149,6 +148,7 @@ struct inherit INT16 inherit_level; /* really needed? */ INT16 identifier_level; INT16 parent_identifier; + INT16 parent_offset; INT32 storage_offset; struct object *parent; struct program *prog; @@ -250,9 +250,18 @@ int low_reference_inherited_identifier(int e, int reference_inherited_identifier(struct pike_string *super_name, struct pike_string *function_name); void rename_last_inherit(struct pike_string *n); -void do_inherit(struct svalue *prog, +void low_inherit(struct program *p, + struct object *parent, + int parent_identifier, + int parent_offset, + INT32 flags, + struct pike_string *name); +void do_inherit(struct svalue *s, INT32 flags, struct pike_string *name); +void compiler_do_inherit(node *n, + INT32 flags, + struct pike_string *name); void simple_do_inherit(struct pike_string *s, INT32 flags, struct pike_string *name); diff --git a/src/stralloc.c b/src/stralloc.c index 2ff1752a106cffc76ec023f71c8e1f312193f533..576674f22e31cae9f6dce0f81d70eff17750d39d 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -127,7 +127,7 @@ static void rehash(void) /* note that begin_shared_string expects the _exact_ size of the string, * not the maximum size */ -struct pike_string *begin_shared_string(int len) +struct pike_string *debug_begin_shared_string(int len) { struct pike_string *t; t=(struct pike_string *)xalloc(len + sizeof(struct pike_string)); @@ -168,7 +168,7 @@ struct pike_string *end_shared_string(struct pike_string *s) return s; } -struct pike_string * make_shared_binary_string(const char *str,int len) +struct pike_string * debug_make_shared_binary_string(const char *str,int len) { struct pike_string *s; int h=StrHash(str,len); @@ -186,7 +186,7 @@ struct pike_string * make_shared_binary_string(const char *str,int len) return s; } -struct pike_string *make_shared_string(const char *str) +struct pike_string *debug_make_shared_string(const char *str) { return make_shared_binary_string(str, strlen(str)); } @@ -221,6 +221,12 @@ void really_free_string(struct pike_string *s) free((char *)s); } +void debug_free_string(struct pike_string *s) +{ + if(--s->refs<=0) + really_free_string(s); +} + /* * String table status @@ -642,10 +648,31 @@ void init_shared_string_table(void) MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size); } +#ifdef DEBUG_MALLOC +struct shared_string_location *all_shared_string_locations; +#endif + + void cleanup_shared_string_table(void) { unsigned INT32 e; struct pike_string *s,*next; + +#if defined(DEBUG) && defined(DEBUG_MALLOC) + while(all_shared_string_locations) + { + struct shared_string_location *x=all_shared_string_locations; + all_shared_string_locations=x->next; + free_string(x->s); + x->s=0; + } + + if(verbose_debug_exit) + { + fprintf(stderr,"Leaked strings \n"); + dump_stralloc_strings(); + } +#endif for(e=0;e<htable_size;e++) { for(s=base_table[e];s;s=next) @@ -660,12 +687,18 @@ void cleanup_shared_string_table(void) base_table[e]=0; } free((char *)base_table); + base_table=0; + num_strings=0; } void count_memory_in_strings(INT32 *num, INT32 *size) { unsigned INT32 e, num_=0, size_=0; - if(!base_table) return; + if(!base_table) + { + *num=*size=0; + return; + } size_+=htable_size * sizeof(struct pike_string *); for(e=0;e<htable_size;e++) { diff --git a/src/stralloc.h b/src/stralloc.h index d35dd6265802ebb07fcd4e9147f6176a2c2d5d01..35388541b24878b6a4debbdfe55c0cd41df7bca2 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -33,19 +33,46 @@ struct pike_string *debug_findstring(const struct pike_string *foo); #define reference_shared_string(s) (s)->refs++ #define copy_shared_string(to,s) ((to)=(s))->refs++ + + +#ifdef DEBUG_MALLOC +struct shared_string_location +{ + struct pike_string *s; + struct shared_string_location *next; +}; + +extern struct shared_string_location *all_shared_string_locations; + +#define MAKE_CONSTANT_SHARED_STRING(var, text) do { \ + static struct shared_string_location str_; \ + if(!str_.s) { \ + str_.s=make_shared_string((text)); \ + str_.next=all_shared_string_locations; \ + all_shared_string_locations=&str_; \ + } \ + copy_shared_string((var),str_.s); \ +}while(0) + + +#else #define MAKE_CONSTANT_SHARED_STRING(var, text) \ do { static struct pike_string *str_; \ if(!str_) str_=make_shared_string((text)); \ copy_shared_string((var), str_); \ }while(0) +#endif + + + /* Prototypes begin here */ struct pike_string *binary_findstring(const char *foo, INT32 l); struct pike_string *findstring(const char *foo); -struct pike_string *begin_shared_string(int len); +struct pike_string *debug_begin_shared_string(int len); struct pike_string *end_shared_string(struct pike_string *s); -struct pike_string * make_shared_binary_string(const char *str,int len); -struct pike_string *make_shared_string(const char *str); +struct pike_string * debug_make_shared_binary_string(const char *str,int len); +struct pike_string *debug_make_shared_string(const char *str); void unlink_pike_string(struct pike_string *s); void really_free_string(struct pike_string *s); struct pike_string *add_string_status(int verbose); @@ -76,4 +103,17 @@ void count_memory_in_strings(INT32 *num, INT32 *size); void gc_mark_all_strings(void); /* Prototypes end here */ +#ifdef DEBUG_MALLOC +#define make_shared_string(X) \ + ((struct pike_string *)debug_malloc_update_location(debug_make_shared_string(X),__FILE__,__LINE__)) +#define make_shared_binary_string(X,Y) \ + ((struct pike_string *)debug_malloc_update_location(debug_make_shared_binary_string((X),(Y)),__FILE__,__LINE__)) +#define begin_shared_string(X) \ + ((struct pike_string *)debug_malloc_update_location(debug_begin_shared_string(X),__FILE__,__LINE__)) +#else +#define make_shared_string debug_make_shared_string +#define make_shared_binary_string debug_make_shared_binary_string +#define begin_shared_string debug_begin_shared_string +#endif + #endif /* STRALLOC_H */ diff --git a/src/testsuite.in b/src/testsuite.in index 444c296361b61227eaaf9fe2a206c9c12c78910d..b7ca74092b33e74776dd1f98140ff213d9360f13 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.67 1998/01/20 02:30:39 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.68 1998/01/25 08:25:15 hubbe Exp $"]]) test_eq(1e1,10.0) test_eq(1E1,10.0) test_eq(1e+1,10.0) @@ -12,6 +12,9 @@ test_eq([[cpp("#define MAX(X,Y) ((X)>(Y)?(X):(Y))\n#define MAX3(X,Y,Z) MAX(MAX(X test_program([[class foo { program x() { return class {}; }}; class bar { inherit foo; program x() { return class {}; }} int a() { return foo()->x != bar()->x(); }]]) +// Testing the 'inline' keyword +test_program([[class foo { inline int c() { return time(); } int d() { return c(); } }; class bar { inherit foo; int c() { return 0; } } int a() { return !bar()->d(); }]],0) + test_any([[object o=class foo{int c;class bar{void create(){c++;};}}(); o->bar(); return o->c;]],1) test_do([[add_constant("GURKA2",class foo { int c; class bar{void create() {c+=17;}}}()); ]]) test_any([[class x { inherit GURKA2.bar; }(); return GURKA2->c;]],17) diff --git a/src/threads.c b/src/threads.c index 18d755981391ab48617ea706acac79700b348d6b..98f621e4d184a6b6f6af52a059a30f23086d9600 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.52 1998/01/15 05:59:43 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.53 1998/01/25 08:25:16 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -181,14 +181,22 @@ void *new_thread_func(void * data) THREADS_FPRINTF((stderr,"THREAD %08x INITED\n",(unsigned int)thread_id)); if(SETJMP(back)) { - ONERROR tmp; - SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); - assign_svalue_no_free(sp++, & throw_value); - APPLY_MASTER("handle_error", 1); - pop_stack(); - UNSET_ONERROR(tmp); + if(throw_severity < THROW_EXIT) + { + ONERROR tmp; + SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); + assign_svalue_no_free(sp++, & throw_value); + APPLY_MASTER("handle_error", 1); + pop_stack(); + UNSET_ONERROR(tmp); + } + if(throw_severity == THROW_EXIT) + { + do_exit(throw_value.u.integer); + } } else { INT32 args=arg.args->size; + back.severity=THROW_EXIT; push_array_items(arg.args); arg.args=0; f_call_function(args);