diff --git a/src/pike_types.c b/src/pike_types.c index 5c16993dadcc745beacf9c0032288da6b48419fe..a0caa6386212b092fa926c259a09d77af2b504e3 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.38 1998/04/10 22:24:21 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.39 1998/04/14 22:10:49 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -645,7 +645,15 @@ char *low_describe_type(char *t) case T_FLOAT: my_strcat("float"); break; case T_PROGRAM: my_strcat("program"); break; case T_OBJECT: - my_strcat("object"); + if(EXTRACT_INT(t+1)) + { + char buffer[100]; + sprintf(buffer,"object(%s %ld)",*t?"is":"implements",(long)EXTRACT_INT(t+1)); + my_strcat(buffer); + }else{ + my_strcat("object"); + } + t+=sizeof(INT32)+1; /* Prog id */ break; @@ -856,12 +864,7 @@ static struct pike_string *low_object_fun_type(char *t, if(!p) return 0; i=FIND_LFUN(p, LFUN_CALL); - if(EXTRACT_UCHAR(t+1) || - (p->identifier_references[i].id_flags & ID_NOMASK) || - (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED)) - return ID_FROM_INT(p, i)->type; - - return 0; + return ID_FROM_INT(p, i)->type; } static struct pike_string *low_object_lfun_type(char *t, short lfun) @@ -872,12 +875,7 @@ static struct pike_string *low_object_lfun_type(char *t, short lfun) if(!p) return 0; i=FIND_LFUN(p, LFUN_CALL); - if(EXTRACT_UCHAR(t+1) || - (p->identifier_references[i].id_flags & ID_NOMASK) || - (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED)) - return ID_FROM_INT(p, i)->type; - - return 0; + return ID_FROM_INT(p, i)->type; } #define A_EXACT 1 @@ -1090,10 +1088,10 @@ static char *low_match_types(char *a,char *b, int flags) if(EXTRACT_UCHAR(a+1)) { - if(low_get_storage(bp,ap)==-1) + if(!implements(ap,bp)) return 0; }else{ - if(low_get_storage(ap,bp)==-1) + if(!implements(bp,ap)) return 0; } } diff --git a/src/program.c b/src/program.c index 1996e4b7eb8555d4ab17e140f9bc89981bc01504..cbb34db8e6ecf6cb5e9a42809a7f962f1425b152 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.79 1998/04/14 19:24:12 grubba Exp $"); +RCSID("$Id: program.c,v 1.80 1998/04/14 22:10:50 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -2023,12 +2023,19 @@ void my_yyerror(char *fmt,...) ATTRIBUTE((format(printf,1,2))) struct program *compile(struct pike_string *prog) { +#ifdef DEBUG + JMP_BUF tmp; +#endif struct program *p; struct lex save_lex; int save_depth=compilation_depth; int saved_threads_disabled = threads_disabled; void yyparse(void); - ONERROR just_in_case; + +#ifdef DEBUG + if(SETJMP(tmp)) + fatal("Compiler exited with longjump!\n"); +#endif save_lex=lex; @@ -2037,11 +2044,6 @@ struct program *compile(struct pike_string *prog) lex.current_file=make_shared_string("-"); lex.pragmas=0; - threads_disabled++; - SET_ONERROR(just_in_case, restore_threads_disabled, saved_threads_disabled); - - /* fprintf(stderr, "compile() Enter: threads_disabled:%d, compilation_depth:%d\n", threads_disabled, compilation_depth); */ - start_new_program(); compilation_depth=0; @@ -2049,6 +2051,7 @@ struct program *compile(struct pike_string *prog) compiler_pass=1; lex.pos=prog->str; + yyparse(); /* Parse da program */ p=end_first_pass(0); @@ -2074,13 +2077,15 @@ struct program *compile(struct pike_string *prog) /* fprintf(stderr, "compile() Leave: threads_disabled:%d, compilation_depth:%d\n", threads_disabled, compilation_depth); */ co_signal(&threads_disabled_change); - UNSET_ONERROR(just_in_case); - free_string(lex.current_file); lex=save_lex; compilation_depth=save_depth; +#ifdef DEBUG + UNSETJMP(tmp); +#endif + if(!p) error("Compilation failed.\n"); return p; } @@ -2467,3 +2472,49 @@ void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2))) pop_stack(); } } + + + +/* returns 1 if a implements b */ +static int low_implements(struct program *a, struct program *b) +{ + int e,num=0; + struct pike_string *s=findstring("__INIT"); + for(e=0;e<b->num_identifier_references;e++) + { + struct identifier *bid=ID_FROM_INT(b,e); + int i; + if(s==bid->name) continue; + i=find_shared_string_identifier(bid->name,a); + if(i!=-1) + { + if(!match_types(ID_FROM_INT(a,i)->type, bid->type)) + return 0; + fprintf(stderr,"%s\n",bid->name->str); + num++; + } + } + return num; +} + +#define IMPLEMENTS_CACHE_SIZE 4711 +struct implements_cache_s { INT32 aid, bid, ret; }; +static struct implements_cache_s implements_cache[IMPLEMENTS_CACHE_SIZE]; + +/* returns 1 if a implements b, but faster */ +int implements(struct program *a, struct program *b) +{ + unsigned long hval; + if(!a || !b) return -1; + if(a==b) return 1; + hval = a->id*9248339 + b->id; + hval %= IMPLEMENTS_CACHE_SIZE; + if(implements_cache[hval].aid==a->id && implements_cache[hval].bid==b->id) + { + return implements_cache[hval].ret; + } + /* Do it the tedious way */ + implements_cache[hval].aid=a->id; + implements_cache[hval].bid=b->id; + return implements_cache[hval].ret=low_implements(a,b); +} diff --git a/src/program.h b/src/program.h index 28cc72511024d0492c6a767aabc4cc90d8789884..b28c2c61cd900b259732851160e39ff57fe43481 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.39 1998/04/10 22:24:22 hubbe Exp $ + * $Id: program.h,v 1.40 1998/04/14 22:10:50 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -360,6 +360,8 @@ struct program *program_from_svalue(struct svalue *s); struct find_child_cache_s; int find_child(struct program *parent, struct program *child); void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2))); +struct implements_cache_s; +int implements(struct program *a, struct program *b); /* Prototypes end here */