diff --git a/src/Makefile.in b/src/Makefile.in index 332f12436ba67326343bdd82f06e8fd03042ea7f..a0a3fe1b288d5ba8d210f964c31a8e86bc8ead6c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.206 2000/08/14 16:01:14 grubba Exp $ +# $Id: Makefile.in,v 1.207 2000/08/24 04:04:39 hubbe Exp $ # # This line is needed on some machines. @@ -428,8 +428,10 @@ gdb_verify: module_testsuites testsuite master.pike @echo >>.gdbinit handle SIGUSR1 nostop noprint pass @echo >>.gdbinit handle SIGUSR2 nostop noprint pass @echo >>.gdbinit handle SIGLWP nostop noprint pass + @echo >>.gdbinit handle SIG32 nostop noprint pass @echo >>.gdbinit break debug_fatal - @echo >>.gdbinit run -m$(TMP_BUILDDIR)/master.pike $(PIKEOPTS) $(TMP_BINDIR)/test_pike.pike --no-watchdog -v -v $(TESTARGS) + @if test "$(TESTARGS)" = "" ; then args="-a" ; else args="$(TESTARGS)" ; fi; \ + echo >>.gdbinit run -m$(TMP_BUILDDIR)/master.pike $(PIKEOPTS) $(TMP_BINDIR)/test_pike.pike --no-watchdog -v -v $$args gdb ./pike @rm .gdbinit diff --git a/src/backend.c b/src/backend.c index d0c80c1fc58535781b631a7fa36de2c655be3651..2f5d76c0259fdbf2a87fb411e20cf758953a1c0f 100644 --- a/src/backend.c +++ b/src/backend.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: backend.c,v 1.55 2000/08/17 18:48:27 grubba Exp $"); +RCSID("$Id: backend.c,v 1.56 2000/08/24 04:04:39 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include <errno.h> @@ -677,6 +677,7 @@ void backend(void) if(SETJMP(back)) { ONERROR tmp; + t_flag=0; SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); *(sp++)=throw_value; throw_value.type=T_INT; diff --git a/src/block_alloc.h b/src/block_alloc.h index 7416df8d09cf3985b2981268cea2663478a777f6..31a1e5f806fa60e9b7968017344016d2e8ba15dd 100644 --- a/src/block_alloc.h +++ b/src/block_alloc.h @@ -1,4 +1,4 @@ -/* $Id: block_alloc.h,v 1.23 2000/08/10 09:21:19 grubba Exp $ */ +/* $Id: block_alloc.h,v 1.24 2000/08/24 04:04:40 hubbe Exp $ */ #undef PRE_INIT_BLOCK #undef INIT_BLOCK #undef EXIT_BLOCK @@ -140,6 +140,7 @@ inline struct DATA * \ struct DATA *PIKE_CONCAT(find_,DATA)(void *ptr) \ { \ size_t hval = (size_t)ptr; \ + if(!PIKE_CONCAT(DATA,_hash_table_size)) return 0; \ hval%=PIKE_CONCAT(DATA,_hash_table_size); \ return PIKE_CONCAT(really_low_find_,DATA)(ptr, hval); \ } \ diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 1b5b6a20f8fb36ae2d8bb1e73e20a3cab88037c2..6a17afbe61ec92573c0cda9565ad7d599b2b0596 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.299 2000/08/17 19:15:16 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.300 2000/08/24 04:04:40 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -5472,6 +5472,9 @@ void f_enumerate(INT32 args) } } +/* FIXME: This is not accurate anymore! (crash risk!) + * The function of in->parent_offset has changed! + */ PMOD_EXPORT void f_inherit_list(INT32 args) { struct program *p; @@ -5500,6 +5503,7 @@ PMOD_EXPORT void f_inherit_list(INT32 args) for(e=0;e<p->num_inherits;e++) { struct inherit *in=p->inherits+e; + if(in->inherit_level==1) { if(in->parent_offset) diff --git a/src/compilation.h b/src/compilation.h index 38667b7756b8fba9f905eed5cac61d17c00b5987..3f26f59e0057207b2d485e1cfd8fcf3aa433bdb3 100644 --- a/src/compilation.h +++ b/src/compilation.h @@ -1,5 +1,5 @@ /* - * $Id: compilation.h,v 1.19 2000/08/17 19:10:05 grubba Exp $ + * $Id: compilation.h,v 1.20 2000/08/24 04:04:40 hubbe Exp $ * * Compilator state push / pop operator construction file * @@ -140,6 +140,7 @@ ZMEMBER(struct mapping *,module_index_cache,0) STACKMEMBER(unsigned char *,type_stackp,type_stack) STACKMEMBER(unsigned char **,pike_type_mark_stackp,pike_type_mark_stack) + ZMEMBER(INT32,parent_identifier,0) SEND #undef PCODE diff --git a/src/docode.c b/src/docode.c index 6c179c65bd12a4733d8058cb80931c3232221235..c4e8bcf2b71729e9f03446ef52e4df67047f405e 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.79 2000/08/16 10:49:19 grubba Exp $"); +RCSID("$Id: docode.c,v 1.80 2000/08/24 04:04:40 hubbe Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -302,7 +302,7 @@ static int do_docode2(node *n,int flags) case F_EXTERNAL: { int level = 0; - struct program_state *state = Pike_compiler->previous; + struct program_state *state = Pike_compiler; while (state && (state->new_program->id != n->u.integer.a)) { state = state->previous; level++; @@ -312,13 +312,30 @@ static int do_docode2(node *n,int flags) emit1(F_NUMBER,0); return 1; } - if(flags & WANT_LVALUE) + if(level) { - emit2(F_EXTERNAL_LVALUE, n->u.integer.b, level); - return 2; + if(flags & WANT_LVALUE) + { + emit2(F_EXTERNAL_LVALUE, n->u.integer.b, level); + return 2; + }else{ + emit2(F_EXTERNAL, n->u.integer.b, level); + return 1; + } }else{ - emit2(F_EXTERNAL, n->u.integer.b, level); - return 1; + if(flags & WANT_LVALUE) + { + emit1(F_GLOBAL_LVALUE, n->u.integer.b); + return 2; + }else{ + if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(state->new_program,n->u.integer.b)->identifier_flags)) + { + emit1(F_LFUN, n->u.integer.b); + }else{ + emit1(F_GLOBAL, n->u.integer.b); + } + return 1; + } } } break; @@ -508,6 +525,7 @@ static int do_docode2(node *n,int flags) CDR(n)->u.integer.a ); break; + /* FIXME: Make special case for F_EXTERNAL */ case F_IDENTIFIER: if(!IDENTIFIER_IS_VARIABLE( ID_FROM_INT(Pike_compiler->new_program, CDR(n)->u.id.number)->identifier_flags)) { @@ -831,6 +849,13 @@ static int do_docode2(node *n,int flags) { return do_lfun_call(CAR(n)->u.id.number,CDR(n)); } + else if(CAR(n)->token == F_EXTERNAL && + CAR(n)->u.integer.a == Pike_compiler->new_program->id && + IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program, + CAR(n)->u.integer.b)->identifier_flags)) + { + return do_lfun_call(CAR(n)->u.integer.b,CDR(n)); + } else { struct pike_string *tmp; @@ -1242,7 +1267,7 @@ static int do_docode2(node *n,int flags) int x=0; struct object *o; - for(o=Pike_compiler->fake_object->parent;o!=n->u.sval.u.object;o=o->parent) + for(o=Pike_compiler->fake_object;o!=n->u.sval.u.object;o=o->parent) x++; emit2(F_EXTERNAL, n->u.sval.subtype, x); Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT; diff --git a/src/interpret.c b/src/interpret.c index e4f1e29e1e7a72b34b01c8777c5a51e7e11f86ae..99dbc8b82e07f12fdfe5c103e27301a361efece2 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.165 2000/08/17 18:45:04 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.166 2000/08/24 04:04:40 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -59,6 +59,11 @@ RCSID("$Id: interpret.c,v 1.165 2000/08/17 18:45:04 grubba Exp $"); #define TRACE_LEN (100 + t_flag * 10) +#ifdef PIKE_DEBUG +static char trace_buffer[2000]; +#endif + + /* Pike_sp points to first unused value on stack * (much simpler than letting it point at the last used value.) */ @@ -371,6 +376,184 @@ union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t) } } +inline void pike_trace(int level,char *fmt, ...) ATTRIBUTE((format (printf, 2, 3))); +inline void pike_trace(int level,char *fmt, ...) +{ + if(t_flag > level) + { + va_list args; + va_start(args,fmt); + vsprintf(trace_buffer,fmt,args); + va_end(args); + write_to_stderr(trace_buffer,strlen(trace_buffer)); + } +} + +#ifdef PIKE_DEBUG + +void my_describe_inherit_structure(struct program *p) +{ + struct inherit *in,*last=0; + int e,i=0; + last=p->inherits-1; + + fprintf(stderr,"PROGRAM[%d]: inherits=%d identifers_refs=%d ppid=%d\n", + p->id, + p->num_inherits, + p->num_identifier_references, + p->parent_program_id); + for(e=0;e<p->num_identifier_references;e++) + { + in=INHERIT_FROM_INT(p,e); + while(last < in) + { + last++; + fprintf(stderr,"[%d]%*s parent{ offset=%d ident=%d id=%d } id{ level=%d } prog=%d\n", + last - p->inherits, + last->inherit_level*2,"", + last->parent_offset, + last->parent_identifier, + last->prog->parent_program_id, + last->identifier_level, + last->prog->id); + i=0; + } + + fprintf(stderr," %*s %d,%d: %s\n", + in->inherit_level*2,"", + e,i, + ID_FROM_INT(p,e)->name->str); + i++; + } +} + +#define TRACE(X) pike_trace X +#else +#define TRACE(X) +#endif + +PMOD_EXPORT void find_external_context(struct external_variable_context *loc, + int arg2) +{ + struct program *p; + INT32 e,off; + TRACE((4,"-find_external_context(%d, inherit=%d)\n",arg2,loc->inherit - loc->o->prog->inherits)); + + if(!loc->o) + error("Current object is destructed\n"); + + while(--arg2>=0) + { +#ifdef PIKE_DEBUG + if(t_flag>8) + my_describe_inherit_structure(loc->o->prog); +#endif + + TRACE((4,"- i->parent_offset=%d i->parent_identifier=%d\n", + loc->inherit->parent_offset, + loc->inherit->parent_identifier)); + TRACE((4,"- o->parent_identifier=%d inherit->identifier_level=%d\n", + loc->o->parent_identifier, + loc->inherit->identifier_level)); + + switch(loc->inherit->parent_offset) + { + default: + { + struct external_variable_context tmp=*loc; +#ifdef PIKE_DEBUG + if(!loc->inherit->inherit_level) + fatal("Gahhh! inherit level zero in wrong place!\n"); +#endif + while(tmp.inherit->inherit_level >= loc->inherit->inherit_level) + { + TRACE((5,"- inherit-- (%d >= %d)\n",tmp.inherit->inherit_level, loc->inherit->inherit_level)); + tmp.inherit--; + } + + + find_external_context(&tmp, + loc->inherit->parent_offset); + loc->o=tmp.o; + loc->parent_identifier = + loc->inherit->parent_identifier+ + tmp.inherit->identifier_level; + } + break; + + case -17: + TRACE((5,"- Following inherit->parent\n")); + loc->parent_identifier=loc->inherit->parent_identifier; + loc->o=loc->inherit->parent; + break; + + case -18: + TRACE((5,"- Following o->parent\n")); + loc->parent_identifier=loc->o->parent_identifier; + loc->o=loc->o->parent; + break; + } + + if(!loc->o) + error("Parent was lost during cloning.\n"); + + if(!(p=loc->o->prog)) + error("Attempting to access variable in destructed object\n"); + +#ifdef DEBUG_MALLOC + if (loc->o->refs == 0x55555555) { + fprintf(stderr, "The object %p has been zapped!\n", loc->o); + describe(p); + fatal("Object zapping detected.\n"); + } + if (p->refs == 0x55555555) { + fprintf(stderr, "The program %p has been zapped!\n", p); + describe(p); + fprintf(stderr, "Which taken from the object %p\n", loc->o); + describe(loc->o); + fatal("Looks like the program %p has been zapped!\n", p); + } +#endif /* DEBUG_MALLOC */ + +#ifdef PIKE_DEBUG + if(loc->parent_identifier < 0 || + loc->parent_identifier > p->num_identifier_references) + fatal("Identifier out of range, loc->parent_identifer=%d!\n", + loc->parent_identifier); +#endif + + loc->inherit=INHERIT_FROM_INT(p, loc->parent_identifier); + +#ifdef PIKE_DEBUG + if(t_flag>28) + my_describe_inherit_structure(p); +#endif + + TRACE((5,"- Parent identifier = %d (%s), inherit # = %d\n", + loc->parent_identifier, + ID_FROM_INT(p, loc->parent_identifier)->name->str, + loc->inherit - p->inherits)); + +#ifdef DEBUG_MALLOC + if (loc->inherit->storage_offset == 0x55555555) { + fprintf(stderr, "The inherit %p has been zapped!\n", loc->inherit); + debug_malloc_dump_references(loc->inherit,0,2,0); + fprintf(stderr, "It was extracted from the program %p %d\n", p, loc->parent_identifier); + describe(p); + fprintf(stderr, "Which was in turn taken from the object %p\n", loc->o); + describe(loc->o); + fatal("Looks like the program %p has been zapped!\n", p); + } +#endif /* DEBUG_MALLOC */ + } + + TRACE((4,"--find_external_context: parent_id=%d (%s)\n", + loc->parent_identifier, + ID_FROM_INT(loc->o->prog,loc->parent_identifier)->name->str + )); +} + + #ifdef PIKE_DEBUG void print_return_value(void) { @@ -397,11 +580,6 @@ void print_return_value(void) #endif struct callback_list evaluator_callbacks; - -#ifdef PIKE_DEBUG -static char trace_buffer[200]; -#endif - #define CASE(X) case (X)-F_OFFSET: #define DOJUMP() \ diff --git a/src/interpret.h b/src/interpret.h index a8acfe003683ad4d206f00d37cb7c6dccfc8f853..b8e5c71098c064920e677da8bce2e22fe5f893f4 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: interpret.h,v 1.65 2000/08/23 18:46:36 grubba Exp $ + * $Id: interpret.h,v 1.66 2000/08/24 04:04:41 hubbe Exp $ */ #ifndef INTERPRET_H #define INTERPRET_H @@ -63,6 +63,13 @@ struct pike_frame char *current_storage; }; +struct external_variable_context +{ + struct object *o; + struct inherit *inherit; + int parent_identifier; +}; + #ifdef PIKE_DEBUG #define debug_check_stack() do{if(Pike_sp<Pike_interpreter.evaluator_stack)fatal("Stack error.\n");}while(0) #define check__positive(X,Y) if((X)<0) fatal Y @@ -226,6 +233,8 @@ struct backlog; void dump_backlog(void); BLOCK_ALLOC(pike_frame,128) +PMOD_EXPORT void find_external_context(struct external_variable_context *loc, + int arg2); PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2); PMOD_EXPORT void f_call_function(INT32 args); PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset); diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 61fa3772a473eda71c75914050429b176c3eb8a9..cdb4eea431843d94fb2da812f1157766fe268aa1 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.30 2000/08/10 08:36:45 grubba Exp $ + * $Id: interpret_functions.h,v 1.31 2000/08/24 04:04:41 hubbe Exp $ * * Opcode definitions for the interpreter. */ @@ -102,92 +102,26 @@ BREAK; OPCODE2(F_EXTERNAL,"external") { - struct inherit *inherit; - struct program *p; - struct object *o; - INT32 i; - - inherit=&Pike_fp->context; - - o=Pike_fp->current_object; - - if(!o) - error("Current object is destructed\n"); + struct external_variable_context loc; + + loc.o=Pike_fp->current_object; + if(!loc.o->prog) + error("Cannot access parent of destructed object.\n"); + + loc.parent_identifier=Pike_fp->fun; + loc.inherit=INHERIT_FROM_INT(loc.o->prog, Pike_fp->fun); - while(1) - { - if(inherit->parent_offset) - { -#ifdef PIKE_DEBUG - if(t_flag>4) - { - sprintf(trace_buffer,"- Following o->parent (accumulator+=%d)\n",inherit->parent_offset-1); - write_to_stderr(trace_buffer,strlen(trace_buffer)); - } -#endif - - i=o->parent_identifier; - o=o->parent; - arg2+=inherit->parent_offset-1; - }else{ -#ifdef PIKE_DEBUG - if(t_flag>4) - { - sprintf(trace_buffer,"- Following inherit->parent (accumulator+=%d)\n",inherit->parent_offset-1); - write_to_stderr(trace_buffer,strlen(trace_buffer)); - } -#endif - 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"); - -#ifdef DEBUG_MALLOC - if (o->refs == 0x55555555) { - fprintf(stderr, "The object %p has been zapped!\n", o); - describe(p); - fatal("Object zapping detected.\n"); - } - if (p->refs == 0x55555555) { - fprintf(stderr, "The program %p has been zapped!\n", p); - describe(p); - fprintf(stderr, "Which taken from the object %p\n", o); - describe(o); - fatal("Looks like the program %p has been zapped!\n", p); - } -#endif /* DEBUG_MALLOC */ - + find_external_context(&loc, arg2); + #ifdef PIKE_DEBUG - if(i < 0 || i > p->num_identifier_references) - fatal("Identifier out of range!\n"); + TRACE((5,"- Identifier=%d Offset=%d\n", + arg1, + loc.inherit->identifier_level)); #endif - - inherit=INHERIT_FROM_INT(p, i); - -#ifdef DEBUG_MALLOC - if (inherit->storage_offset == 0x55555555) { - fprintf(stderr, "The inherit %p has been zapped!\n", inherit); - debug_malloc_dump_references(inherit,0,2,0); - fprintf(stderr, "It was extracted from the program %p %d\n", p, i); - describe(p); - fprintf(stderr, "Which was in turn taken from the object %p\n", o); - describe(o); - fatal("Looks like the program %p has been zapped!\n", p); - } -#endif /* DEBUG_MALLOC */ - - if(!arg2) break; - --arg2; - } - + low_object_index_no_free(Pike_sp, - o, - arg1 + inherit->identifier_level); + loc.o, + arg1 + loc.inherit->identifier_level); Pike_sp++; print_return_value(); } @@ -195,47 +129,27 @@ BREAK; OPCODE2(F_EXTERNAL_LVALUE,"& external") { - struct inherit *inherit; - struct program *p; - struct object *o; - INT32 i,id=arg1; - - inherit=&Pike_fp->context; - o=Pike_fp->current_object; - - if(!o) - error("Parent was lost during cloning.\n"); - - if(!(o->prog)) - error("Attempting to access variable in destructed object\n"); - - while(1) - { - if(inherit->parent_offset) - { - i=o->parent_identifier; - o=o->parent; - arg2+=inherit->parent_offset-1; - }else{ - i=inherit->parent_identifier; - o=inherit->parent; - } - - 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(!arg2) break; - arg2--; - } + struct external_variable_context loc; + + loc.o=Pike_fp->current_object; + if(!loc.o->prog) + error("Cannot access parent of destructed object.\n"); + + loc.parent_identifier=Pike_fp->fun; + loc.inherit=INHERIT_FROM_INT(loc.o->prog, Pike_fp->fun); - ref_push_object(o); + find_external_context(&loc, arg2); + +#ifdef PIKE_DEBUG + TRACE((5,"- Identifier=%d Offset=%d\n", + arg1, + loc.inherit->identifier_level)); +#endif + + + ref_push_object(loc.o); Pike_sp->type=T_LVALUE; - Pike_sp->u.integer=id + inherit->identifier_level; + Pike_sp->u.integer=arg1 + loc.inherit->identifier_level; Pike_sp++; } BREAK; diff --git a/src/las.c b/src/las.c index 1db6710d529d39d8f033630ea9496e33a13c6b67..60dcbd38d1de88fb1260682fc7f36a6bb1b6d5ec 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.191 2000/08/16 10:20:23 grubba Exp $"); +RCSID("$Id: las.c,v 1.192 2000/08/24 04:04:41 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -876,6 +876,9 @@ node *debug_mklocalnode(int var, int depth) node *debug_mkidentifiernode(int i) { +#if 1 + return mkexternalnode(Pike_compiler->new_program, i); +#else node *res = mkemptynode(); res->token = F_IDENTIFIER; copy_shared_string(res->type, ID_FROM_INT(Pike_compiler->new_program, i)->type); @@ -901,6 +904,7 @@ node *debug_mkidentifiernode(int i) check_tree(res,0); return res; +#endif } node *debug_mktrampolinenode(int i) @@ -965,7 +969,8 @@ node *debug_mkexternalnode(struct program *parent_prog, int i) res->u.integer.b = i; /* Bzot-i-zot */ - Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT; + if(parent_prog != Pike_compiler->new_program) + Pike_compiler->new_program->flags |= PROGRAM_USES_PARENT; return freeze_node(res); } @@ -1079,7 +1084,7 @@ void resolv_constant(node *n) case F_EXTERNAL: { - struct program_state *state = Pike_compiler->previous; + struct program_state *state = Pike_compiler; while (state && (state->new_program->id != n->u.integer.a)) { state = state->previous; @@ -2424,7 +2429,7 @@ void fix_type_field(node *n) { int program_id = CAR(n)->u.integer.a; int id_no = CAR(n)->u.integer.b; - struct program_state *state = Pike_compiler->previous; + struct program_state *state = Pike_compiler; name="external symbol"; diff --git a/src/main.c b/src/main.c index 22e588e6b72c38e64c8f984790e96f778bb9f12c..d974762cd7a4dca00bdb5b551f90b023dc457e7a 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: main.c,v 1.99 2000/08/22 17:28:22 grubba Exp $"); +RCSID("$Id: main.c,v 1.100 2000/08/24 04:04:41 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -525,6 +525,7 @@ int dbm_main(int argc, char **argv) num=throw_value.u.integer; }else{ ONERROR tmp; + t_flag=0; SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); push_svalue(& throw_value); APPLY_MASTER("handle_error", 1); diff --git a/src/object.c b/src/object.c index 926caa111f44d9391824cf4321026ace2973ef4f..5dd1f07c1a2dd1f2dccf214b9eec931c21312854 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.144 2000/08/20 17:07:19 grubba Exp $"); +RCSID("$Id: object.c,v 1.145 2000/08/24 04:04:41 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -1506,43 +1506,22 @@ struct program *magic_set_index_program=0; void push_magic_index(struct program *type, int inherit_no, int parent_level) { - struct inherit *inherit; - struct object *o,*magic; - struct program *p; + struct external_variable_context loc; + struct object *magic; - o=Pike_fp->current_object; - if(!o) error("Illegal magic index call.\n"); - - inherit=INHERIT_FROM_INT(Pike_fp->current_object->prog, Pike_fp->fun); - - while(parent_level--) - { - int i; - if(inherit->parent_offset) - { - i=o->parent_identifier; - o=o->parent; - parent_level+=inherit->parent_offset-1; - }else{ - i=inherit->parent_identifier; - o=inherit->parent; - } - - if(!o) - error("Parent was lost!\n"); - - if(!(p=o->prog)) - error("Attempting to access variable in destructed object\n"); - - inherit=INHERIT_FROM_INT(p, i); - } + loc.o=Pike_fp->current_object; + if(!loc.o) error("Illegal magic index call.\n"); + loc.parent_identifier=Pike_fp->fun; + loc.inherit=INHERIT_FROM_INT(Pike_fp->current_object->prog, Pike_fp->fun); + + find_external_context(&loc, parent_level); magic=low_clone(type); - add_ref(MAGIC_O2S(magic)->o=o); - MAGIC_O2S(magic)->inherit = inherit + inherit_no; + add_ref(MAGIC_O2S(magic)->o=loc.o); + MAGIC_O2S(magic)->inherit = loc.inherit + inherit_no; #ifdef DEBUG - if(inherit + inherit_no >= o->prog->inherits + o->prog->num_inherit) + if(loc.inherit + inherit_no >= loc.o->prog->inherits + loc.o->prog->num_inherit) fatal("Magic index blahonga!\n"); #endif push_object(magic); diff --git a/src/program.c b/src/program.c index 86974a2440c3e40798cb9569e6530acb3bae4752..2196050c13226100d37ed88f07bf8caae757a50d 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.264 2000/08/17 19:11:34 grubba Exp $"); +RCSID("$Id: program.c,v 1.265 2000/08/24 04:04:42 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -740,6 +740,7 @@ void low_start_new_program(struct program *p, } e=2; } + Pike_compiler->parent_identifier=id; if(idp) *idp=id; init_type_stack(); @@ -775,7 +776,7 @@ void low_start_new_program(struct program *p, Pike_compiler->fake_object->prev=Pike_compiler->fake_object; Pike_compiler->fake_object->refs=1; Pike_compiler->fake_object->parent=0; - Pike_compiler->fake_object->parent_identifier=0; + Pike_compiler->fake_object->parent_identifier=-1; Pike_compiler->fake_object->prog=p; add_ref(p); @@ -861,13 +862,13 @@ void low_start_new_program(struct program *p, i.storage_offset=0; i.inherit_level=0; i.parent=0; - i.parent_identifier=0; - i.parent_offset=1; + i.parent_identifier=-1; + i.parent_offset=-18; i.name=0; + Pike_compiler->new_program->parent_program_id=compilation_depth>0 && Pike_compiler->previous->new_program ? Pike_compiler->previous->new_program->id : -1; add_to_inherits(i); } - Pike_compiler->init_node=0; Pike_compiler->num_parse_error=0; @@ -1656,15 +1657,84 @@ void rename_last_inherit(struct pike_string *n) n); } +static int locate_parent_state(struct program_state **state, + struct inherit **i, + int *parent_identifier, + int depth) +{ + int result=1; + if(depth<=0) return depth; + while(depth-->0) + { + if( (*i)->parent_offset != -17) + { + int tmp=(*i)->parent_identifier; + if( (*i)->parent_offset > 0) + { + int po=(*i)->parent_offset; + *parent_identifier = (*state)->parent_identifier; + *state = (*state)->previous; + result++; + fprintf(stderr,"INHERIT: state=state->previous (po=%d)\n",po); + + if(po>1) + { + *i=INHERIT_FROM_INT( (*state)->new_program, + *parent_identifier); + + result+=locate_parent_state(state,i,parent_identifier, po-1); + } + } + + if(tmp != -1) + { + if( *parent_identifier == -4711) + { + *parent_identifier = tmp; + }else{ + *parent_identifier = tmp + INHERIT_FROM_INT( (*state)->new_program, + *parent_identifier)->identifier_level; + } + } + }else{ + fprintf(stderr,"INHERIT: Bailout!\n"); + return result+depth+1; + } + *i = INHERIT_FROM_INT( (*state)->new_program, *parent_identifier); + } + return result; +} + + +static int find_depth(struct program_state *state, + struct inherit *i, + int parent_identifier, + int depth) +{ +#if 0 + int e; + struct inherit *oi; + for(e=0;e<=parent_offset;e++) state=state->previous; + oi=INHERIT_FROM_INT(state->new_program, parent_identifier); + parent_offset+=i->parent_offset; +#endif + + return locate_parent_state(&state, + &i, + &parent_identifier, + depth); +} + /* * make this program inherit another program */ -void low_inherit(struct program *p, - struct object *parent, - int parent_identifier, - int parent_offset, - INT32 flags, - struct pike_string *name) +static void really_low_inherit(struct program *p, + struct object *parent, + int parent_identifier, + int parent_offset, + INT32 flags, + struct pike_string *name, + int parent_identifier_offset) { int e; ptrdiff_t inherit_offset, storage_offset; @@ -1679,16 +1749,27 @@ void low_inherit(struct program *p, if(p->flags & PROGRAM_USES_PARENT) { + struct program_state *state=Pike_compiler; + if(!parent && !parent_offset) { yyerror("Parent pointer lost, cannot inherit!"); /* We inherit it anyway, to avoid causing more errors */ } + +#if 0 + /* FIXME: we don't really need to set thsi flag on ALL + * previous compilations, but I'm too lazy to figure out + * exactly how deep down we need to go... + */ + for(e=0;e<compilation_depth;e++,state=state->previous) + state->new_program->flags |= PROGRAM_USES_PARENT; +#endif } - /* parent offset was increased by one for above test.. */ + /* parent offset was increased by 42 for above test.. */ if(parent_offset) - parent_offset--; + parent_offset-=42; if(!(p->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) @@ -1715,6 +1796,8 @@ void low_inherit(struct program *p, inherit.identifier_level += Pike_compiler->new_program->num_identifier_references; inherit.storage_offset += storage_offset; inherit.inherit_level ++; + + if(!e) { if(parent) @@ -1722,7 +1805,8 @@ void low_inherit(struct program *p, if(parent->next == parent) { struct object *o; - for(o=Pike_compiler->fake_object->parent;o!=parent;o=o->parent) + inherit.parent_offset=0; + for(o=Pike_compiler->fake_object;o!=parent;o=o->parent) { #ifdef PIKE_DEBUG if(!o) fatal("low_inherit with odd Pike_compiler->fake_object as parent!\n"); @@ -1732,10 +1816,10 @@ void low_inherit(struct program *p, }else{ inherit.parent=parent; inherit.parent_identifier=parent_identifier; - inherit.parent_offset=0; + inherit.parent_offset=-17; } }else{ - inherit.parent_offset+=parent_offset; + inherit.parent_offset=parent_offset; inherit.parent_identifier=parent_identifier; } }else{ @@ -1743,34 +1827,50 @@ void low_inherit(struct program *p, { if(parent && parent->next != parent && inherit.parent_offset) { + /* Fake object */ struct object *par=parent; int e,pid=parent_identifier; + for(e=1;e<inherit.parent_offset;e++) { struct inherit *in; if(!par->prog) { par=0; - pid=0; + pid=-1; break; } in=INHERIT_FROM_INT(par->prog, pid); - if(in->parent_offset) + switch(in->parent_offset) { - pid=par->parent_identifier; - par=par->parent; - e-=in->parent_offset-1; - }else{ - pid=in->parent_identifier; - par=in->parent; + default: + { + struct external_variable_context tmp; + struct inherit *in2=in; + while(in2->identifier_level >= in->identifier_level) in2--; + tmp.o=par; + tmp.inherit=in2; + tmp.parent_identifier=pid; + find_external_context(&tmp, in->parent_offset); + par=tmp.o; + pid=tmp.parent_identifier; + } + break; + + case -17: + pid=in->parent_identifier; + par=in->parent; + break; + + case -18: + par=par->parent_identifier; + par=par->parent; } } inherit.parent=par; - inherit.parent_offset=0; - }else{ - inherit.parent_offset+=parent_offset; + inherit.parent_offset=-17; } } } @@ -1831,17 +1931,29 @@ void low_inherit(struct program *p, } } +void low_inherit(struct program *p, + struct object *parent, + int parent_identifier, + int parent_offset, + INT32 flags, + struct pike_string *name) +{ + really_low_inherit(p,parent,parent_identifier,parent_offset,flags,name,0); +} + + PMOD_EXPORT 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); + really_low_inherit(p, + s->type == T_FUNCTION ? s->u.object : 0, + s->type == T_FUNCTION ? s->subtype : -1, + 0, + flags, + name, + Pike_compiler->new_program->num_identifiers ); } void compiler_do_inherit(node *n, @@ -1850,7 +1962,7 @@ void compiler_do_inherit(node *n, { struct program *p; struct identifier *i; - INT32 numid, offset; + INT32 numid=-1, offset=0,parentoff=0;; if(!n) { @@ -1863,11 +1975,12 @@ void compiler_do_inherit(node *n, p=Pike_compiler->new_program; offset=0; numid=n->u.id.number; + parentoff=Pike_compiler->new_program->num_identifiers; goto continue_inherit; case F_EXTERNAL: { - struct program_state *state = Pike_compiler->previous; + struct program_state *state = Pike_compiler; offset = 0; /* FIXME: Should this be zero or 1? */ while (state && (state->new_program->id != n->u.integer.a)) { @@ -1880,6 +1993,12 @@ void compiler_do_inherit(node *n, } p = state->new_program; numid = n->u.integer.b; + if(offset==-1) + { + parentoff=Pike_compiler->new_program->num_identifiers; + }else{ + parentoff=~INHERIT_FROM_INT(p,numid)->identifier_level; + } } continue_inherit: @@ -1902,12 +2021,13 @@ void compiler_do_inherit(node *n, return; } - low_inherit(p, - 0, - numid, - offset+1, - flags, - name); + really_low_inherit(p, + 0, + numid, + offset+42, + flags, + name, + parentoff); break; default: @@ -3231,6 +3351,7 @@ struct program *compile(struct pike_string *prog, lex.pragmas = 0; } + compilation_depth=-1; low_start_new_program(0,0,0,0); initialize_buf(&used_modules); @@ -3245,7 +3366,6 @@ struct program *compile(struct pike_string *prog, debug_malloc_name(Pike_compiler->new_program, lex.current_file->str, lex.current_line); #endif } - compilation_depth=0; /* start_line_numbering(); */ @@ -4255,69 +4375,16 @@ int yyexplain_not_implements(struct program *a, struct program *b, int flags) PMOD_EXPORT void *parent_storage(int depth) { - struct inherit *inherit; - struct program *p; - struct object *o; - INT32 i; + struct external_variable_context loc; - inherit=&Pike_fp->context; - o=Pike_fp->current_object; - - if(!o) - error("Current object is destructed\n"); + loc.o=Pike_fp->current_object; + if(!loc.o->prog) + error("Cannot access parent of destructed object.\n"); + + loc.parent_identifier=Pike_fp->fun; + loc.inherit=INHERIT_FROM_INT(loc.o->prog, Pike_fp->fun); - while(1) - { - if(inherit->parent_offset) - { - i=o->parent_identifier; - o=o->parent; - depth+=inherit->parent_offset-1; - }else{ - i=inherit->parent_identifier; - o=inherit->parent; - } - - if(!o) return 0; - if(!(p=o->prog)) return 0; - -#ifdef DEBUG_MALLOC - if (o->refs == 0x55555555) { - fprintf(stderr, "The object %p has been zapped!\n", o); - describe(p); - fatal("Object zapping detected.\n"); - } - if (p->refs == 0x55555555) { - fprintf(stderr, "The program %p has been zapped!\n", p); - describe(p); - fprintf(stderr, "Which taken from the object %p\n", o); - describe(o); - fatal("Looks like the program %p has been zapped!\n", p); - } -#endif /* DEBUG_MALLOC */ - -#ifdef PIKE_DEBUG - if(i < 0 || i > p->num_identifier_references) - fatal("Identifier out of range!\n"); -#endif - - inherit=INHERIT_FROM_INT(p, i); - -#ifdef DEBUG_MALLOC - if (inherit->storage_offset == 0x55555555) { - fprintf(stderr, "The inherit %p has been zapped!\n", inherit); - debug_malloc_dump_references(inherit,0,2,0); - fprintf(stderr, "It was extracted from the program %p %d\n", p, i); - describe(p); - fprintf(stderr, "Which was in turn taken from the object %p\n", o); - describe(o); - fatal("Looks like the program %p has been zapped!\n", p); - } -#endif /* DEBUG_MALLOC */ - - if(!depth) break; - --depth; - } + find_external_context(&loc, depth); - return o->storage + inherit->storage_offset; + return loc.o->storage + loc.inherit->storage_offset; } diff --git a/src/program.h b/src/program.h index fa57bdf8002fa924c3493bb49a31d2962768d7d4..ba9a6759c4a44f14fa6b4c1d8e377e917c19dab7 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.104 2000/08/15 15:53:10 grubba Exp $ + * $Id: program.h,v 1.105 2000/08/24 04:04:42 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -194,10 +194,9 @@ struct reference INT16 id_flags; /* static, private etc.. */ }; - struct inherit { - INT16 inherit_level; /* really needed? */ + INT16 inherit_level; INT16 identifier_level; INT16 parent_identifier; INT16 parent_offset; @@ -260,6 +259,7 @@ struct program struct object *prot; #endif INT32 id; /* used to identify program in caches */ + INT32 parent_program_id; /* storage_needed - storage needed in object struct * the first inherit[0].storage_offset bytes are not used and are * subtracted when inheriting. diff --git a/src/testsuite.in b/src/testsuite.in index 880aa5f38605b7f78341d752bee9bd1e4f472d9f..debc5635a76fa42dfd9de8eaf97e9d249ede092e 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.322 2000/08/21 23:48:24 mast Exp $"]]); +test_true([["$Id: testsuite.in,v 1.323 2000/08/24 04:04:42 hubbe Exp $"]]); cond([[all_constants()->_verify_internals]], [[ @@ -596,77 +596,104 @@ test_any([[ test_program([[ + int errors; int tests; -string indent(string code) -{ - string tmp=" "+replace(code,"\n","\n "); - while(strlen(tmp) && tmp[-1]==' ') tmp=tmp[..strlen(tmp)-2]; - return tmp; -} +#define indent(X) (X) -void low_generate(int depth,string code, string acc, string ans, int cnt) +int maxdepth; + +void low_generate(int depth, + array(string) code, + string acc, + string ans, + int cnt) { - if(!depth) + mixed tmp; + if(--depth<0) { - mixed tmp; - string res="Error"; + string res="None"; tests++; - string test=code+"\nmixed Q() { return "+acc+"();}"; + + if(!(tests & 63)) + { + __signal_watchdog(); + werror("\r%d: %d ",maxdepth,tests); + } + + string test=code*"\n"+"\n" + "mixed Q() { return "+acc+"();}\n" + "int main() { trace(9); werror(\"%O\\n\","+acc+"()); }\n" + ; mixed err=catch { - res=compile_string(test)()->Q(); + mixed tmp=compile_string(test)(); + res=tmp->Q(); if(res != ans) - throw("Test failed"); + throw("Test failed"); }; if(err) { errors++; werror("\nTest failed:\n----------------------------------\n%s\n---------------------------------\nexpected answer: %O\nAnswer received: %O\n",test,ans,res); if(err!="Test failed") - werror("%s\n",master()->describe_backtrace(err)); + { + string tmp=master()->describe_backtrace(err); + array s=tmp/"\n"; + s=s[..20]; + werror("%s\n",s*"\n"); + } + return; } }else{ - depth--; - low_generate(depth, - sprintf("class C%d {\n%s\n};",cnt,indent(code)), - sprintf("C%d()->%s",cnt,acc), - ans,cnt+1); - - low_generate(depth, - sprintf("class C%d {\n%s\n};\ninherit C%d;",cnt,indent(code),cnt), - acc, - ans,cnt+1); - - low_generate(depth, - sprintf("%s\nclass C%d { string F%d() { return %s()+\"F%d\"; } };",code,cnt,cnt+1,acc,cnt+1), - sprintf("C%d()->F%d",cnt,cnt+1), - sprintf("%sF%d",ans,cnt+1),cnt+2); + code+ + ({sprintf("string F%d(){ return %s()+\"F%d\"; }",cnt,acc,cnt)}), + sprintf("F%d",cnt), + sprintf("%sF%d",ans,cnt), + cnt+1); + for(int e=0;e<sizeof(code);e++) + { + low_generate(depth, + code[..e-1]+({ + sprintf("class C%d {\n%s\n};",cnt,indent(code[e..]*"\n")) + }), + sprintf("C%d()->%s",cnt,acc), + ans,cnt+1); + } + if(sscanf(acc,"%s()->%s",string classname,string rest)) { - low_generate(depth, - sprintf("%s\nclass C%d {\n inherit %s;\n" - " string F%d() { return %s()+\"F%d\"; }\n};",code,cnt,classname,cnt+1,rest,cnt+1), - sprintf("C%d()->F%d",cnt,cnt+1), - sprintf("%sF%d",ans,cnt+1),cnt+2); + low_generate(depth, + code+({sprintf("inherit %s;",classname) }), + rest, + ans, + cnt); } } } int a() { - for(int e=0;e<7;e++) - low_generate(e, - "string X(){return \"X\";}", + werror("Testing vtables and scope access.\n"); + int total_tests; + for(maxdepth=1;maxdepth<9 && !errors;maxdepth++) + { + low_generate(maxdepth, + ({ "string X(){return \"X\";}" }), "X", "X",0); - - if(errors) werror("%d/%d tests failed.\n",errors,tests); + werror("\r%d: %d\n",maxdepth,tests); + total_tests+=tests; + tests=0; + } + + if(errors) werror("%d/%d tests failed.\n",errors,total_tests); return !errors; } + ]]) diff --git a/src/threads.c b/src/threads.c index 6148f226a81c28e05a192ae3b6004fa78d19e44a..3804305e05425816af1556f7446cc9454e9c399b 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.138 2000/08/18 22:28:48 grubba Exp $"); +RCSID("$Id: threads.c,v 1.139 2000/08/24 04:04:42 hubbe Exp $"); PMOD_EXPORT int num_threads = 1; PMOD_EXPORT int threads_disabled = 0; @@ -623,6 +623,7 @@ TH_RETURN_TYPE new_thread_func(void * data) if(throw_severity < THROW_EXIT) { ONERROR tmp; + t_flag=0; SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); assign_svalue_no_free(Pike_sp++, & throw_value); APPLY_MASTER("handle_error", 1);