From 6bc92806759b40126683c90bb36a68b2ba630090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Fri, 10 Apr 1998 15:24:22 -0700 Subject: [PATCH] Stdio.FILE x; now means object that x is an object that inherits Stdio.FILE. Rev: src/ChangeLog:1.145 Rev: src/interpret.c:1.76 Rev: src/language.yacc:1.72 Rev: src/lex.c:1.50 Rev: src/pike_memory.c:1.20 Rev: src/pike_types.c:1.38 Rev: src/program.c:1.76 Rev: src/program.h:1.39 Rev: src/testsuite.in:1.88 --- src/ChangeLog | 6 ++ src/interpret.c | 4 +- src/language.yacc | 108 ++++++++++++++++++++++++++++-------- src/lex.c | 8 ++- src/pike_memory.c | 47 ++++++++++++++-- src/pike_types.c | 138 +++++++++++++++++++++++++++++++++++----------- src/program.c | 20 ++++--- src/program.h | 4 +- src/testsuite.in | 14 ++++- 9 files changed, 276 insertions(+), 73 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index bb0420236d..03348512c1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +Fri Apr 10 15:05:11 1998 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * language.yacc: it is now possible to use class names as types + in most places. + * pike_types.c: object(foo) now means 'object that inherits foo' + Thu Apr 9 15:11:07 1998 Fredrik Hubinette <hubbe@cytocin.hubbe.net> * Recursive module references now generates errors diff --git a/src/interpret.c b/src/interpret.c index 661f866ef4..5fcd7002e2 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.75 1998/04/10 18:06:05 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.76 1998/04/10 22:24:19 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -915,7 +915,7 @@ static int eval_instruction(unsigned char *pc) pop_n_elems(3); break; - CASE(F_GLOBAL_LVALUE) + CASE(F_GLOBAL_LVALUE); { struct identifier *i; INT32 tmp=GET_ARG() + fp->context.identifier_level; diff --git a/src/language.yacc b/src/language.yacc index 027cd24787..da11774490 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -107,6 +107,8 @@ %token F_IMPORT %token F_INHERIT %token F_INLINE +%token F_LOCAL_ID +%token F_FINAL_ID %token F_INT_ID %token F_LAMBDA %token F_MULTISET_ID @@ -169,7 +171,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.71 1998/04/10 04:35:19 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.72 1998/04/10 22:24:20 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -290,6 +292,8 @@ int yylex(YYSTYPE *yylval); %type <n> cast %type <n> simple_type +%type <n> simple_type2 +%type <n> simple_identifier_type %type <n> string_constant %type <n> string %type <n> F_STRING @@ -328,6 +332,7 @@ int yylex(YYSTYPE *yylval); %type <n> idents %type <n> lambda %type <n> local_name_list +%type <n> local_name_list2 %type <n> low_idents %type <n> lvalue %type <n> lvalue_list @@ -335,6 +340,7 @@ int yylex(YYSTYPE *yylval); %type <n> m_expr_list %type <n> m_expr_list2 %type <n> new_local_name +%type <n> new_local_name2 %type <n> optional_else_part %type <n> return %type <n> sscanf @@ -485,14 +491,7 @@ type_or_error: simple_type copy_shared_string(compiler_frame->current_type,$1->u.sval.u.string); free_node($1); } - | /* empty */ - { - yyerror("Missing type."); - if(compiler_frame->current_type) - free_string(compiler_frame->current_type); - copy_shared_string(compiler_frame->current_type, - mixed_type_string); - } + ; def: modifiers type_or_error optional_stars F_IDENTIFIER @@ -599,7 +598,7 @@ optional_identifier: F_IDENTIFIER | /* empty */ { $$=0; } ; -new_arg_name: type optional_dot_dot_dot optional_identifier +new_arg_name: type7 optional_dot_dot_dot optional_identifier { if(varargs) yyerror("Can't define more arguments after ..."); @@ -641,8 +640,10 @@ arguments2: new_arg_name { $$ = 1; } ; modifier: F_NO_MASK { $$ = ID_NOMASK; } + | F_FINAL_ID { $$ = ID_NOMASK; } | F_STATIC { $$ = ID_STATIC; } - | F_PRIVATE { $$ = ID_PRIVATE; } + | F_PRIVATE { $$ = ID_PRIVATE | ID_STATIC; } + | F_LOCAL_ID { $$ = ID_INLINE; } | F_PUBLIC { $$ = ID_PUBLIC; } | F_PROTECTED { $$ = ID_PROTECTED; } | F_INLINE { $$ = ID_INLINE; } @@ -665,12 +666,34 @@ cast: '(' type ')' free_string(s); } ; + +type6: type | identifier_type ; type: type '*' { push_type(T_ARRAY); } | type2 ; -simple_type: type2 +type7: type7 '*' { push_type(T_ARRAY); } + | type4 + ; + +simple_type: type4 + { + struct pike_string *s=pop_type(); + $$=mkstrnode(s); + free_string(s); + } + ; + +simple_type2: type2 + { + struct pike_string *s=pop_type(); + $$=mkstrnode(s); + free_string(s); + } + ; + +simple_identifier_type: identifier_type { struct pike_string *s=pop_type(); $$=mkstrnode(s); @@ -678,8 +701,27 @@ simple_type: type2 } ; +identifier_type: idents + { + struct program *p; + resolv_program($1); + if((p=program_from_svalue(sp-1))) + { + push_type_int(sp[-1].u.program->id); + }else{ + push_type_int(0); + } + push_type(0); + push_type(T_OBJECT); + pop_stack(); + free_node($1); + } + ; + +type4: type2 | identifier_type + type2: type2 '|' type3 { push_type(T_OR); } - | type3 + | type3 ; type3: F_INT_ID { push_type(T_INT); } @@ -695,7 +737,7 @@ type3: F_INT_ID { push_type(T_INT); } | F_FUNCTION_ID opt_function_type { push_type(T_FUNCTION); } ; -opt_object_type: /* Empty */ { push_type_int(0); } +opt_object_type: /* Empty */ { push_type_int(0); push_type(0); } | '(' program_ref ')' { struct program *p=program_from_svalue(sp-1); @@ -707,6 +749,7 @@ opt_object_type: /* Empty */ { push_type_int(0); } push_type_int(0); } pop_n_elems(2); + push_type(0); } ; @@ -728,7 +771,7 @@ opt_function_type: '(' } type_stack_mark(); } - type ')' + type7 ')' { type_stack_reverse(); type_stack_reverse(); @@ -745,16 +788,16 @@ function_type_list: /* Empty */ optional_comma | function_type_list2 optional_comma ; -function_type_list2: type +function_type_list2: type7 | function_type_list2 ',' { type_stack_reverse(); type_stack_mark(); } - type + type7 ; -opt_array_type: '(' type ')' +opt_array_type: '(' type7 ')' | { push_type(T_MIXED); } ; @@ -763,12 +806,12 @@ opt_mapping_type: '(' type_stack_mark(); type_stack_mark(); } - type ':' + type7 ':' { type_stack_reverse(); type_stack_mark(); } - type + type7 { type_stack_reverse(); type_stack_reverse(); @@ -822,7 +865,7 @@ new_local_name: optional_stars F_IDENTIFIER push_finished_type($<n>0->u.sval.u.string); while($1--) push_type(T_ARRAY); add_local_name($2->u.sval.u.string, pop_type()); - $$=mknode(F_ASSIGN,mkintnode(0), mklocalnode(islocal($2->u.sval.u.string))); + $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($2->u.sval.u.string))); free_node($2); } | optional_stars F_IDENTIFIER '=' expr0 @@ -835,6 +878,20 @@ new_local_name: optional_stars F_IDENTIFIER } ; +new_local_name2: F_IDENTIFIER + { + add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); + $$=mknode(F_ASSIGN,mkintnode(0),mklocalnode(islocal($1->u.sval.u.string))); + free_node($1); + } + | F_IDENTIFIER '=' expr0 + { + add_local_name($1->u.sval.u.string, $<n>0->u.sval.u.string); + $$=mknode(F_ASSIGN,$3, mklocalnode(islocal($1->u.sval.u.string))); + free_node($1); + } + ; + block:'{' { @@ -856,6 +913,10 @@ local_name_list: new_local_name | local_name_list ',' { $<n>$=$<n>0; } new_local_name { $$=mknode(F_ARG_LIST,$1,$4); } ; +local_name_list2: new_local_name2 + | local_name_list2 ',' { $<n>$=$<n>0; } new_local_name { $$=mknode(F_ARG_LIST,$1,$4); } + ; + statements: { $$=0; } | statements statement { @@ -1136,7 +1197,8 @@ optional_comma_expr: { $$=0; } ; comma_expr: comma_expr2 - | simple_type local_name_list { $$=$2; free_node($1); } + | simple_type2 local_name_list { $$=$2; free_node($1); } + | simple_identifier_type local_name_list2 { $$=$2; free_node($1); } ; @@ -1452,7 +1514,7 @@ sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')' lvalue: expr4 | '[' low_lvalue_list ']' { $$=mknode(F_ARRAY_LVALUE, $2,0); } - | type F_IDENTIFIER + | type6 F_IDENTIFIER { add_local_name($2->u.sval.u.string,pop_type()); $$=mklocalnode(islocal($2->u.sval.u.string)); diff --git a/src/lex.c b/src/lex.c index 51882968f7..681ab6dad1 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.49 1998/04/06 20:36:20 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.50 1998/04/10 22:24:20 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -814,6 +814,9 @@ static int yylex2(YYSTYPE *yylval) case TWO_CHAR('e','l'): if(ISWORD("else")) return F_ELSE; break; + case TWO_CHAR('f','i'): + if(ISWORD("final")) return F_FINAL_ID; + break; case TWO_CHAR('f','l'): if(ISWORD("float")) return F_FLOAT_ID; break; @@ -841,6 +844,9 @@ static int yylex2(YYSTYPE *yylval) case TWO_CHAR('l','a'): if(ISWORD("lambda")) return F_LAMBDA; break; + case TWO_CHAR('l','o'): + if(ISWORD("local")) return F_LOCAL_ID; + break; case TWO_CHAR('m','a'): if(ISWORD("mapping")) return F_MAPPING_ID; break; diff --git a/src/pike_memory.c b/src/pike_memory.c index cba84ca1c6..67d1fa5d31 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -9,7 +9,7 @@ #include "pike_macros.h" #include "gc.h" -RCSID("$Id: pike_memory.c,v 1.19 1998/04/06 04:29:27 hubbe Exp $"); +RCSID("$Id: pike_memory.c,v 1.20 1998/04/10 22:24:20 hubbe Exp $"); /* strdup() is used by several modules, so let's provide it */ #ifndef HAVE_STRDUP @@ -466,6 +466,10 @@ int verbose_debug_exit = 1; #define LHSIZE 1109891 #define FLSIZE 8803 #define DEBUG_MALLOC_PAD 8 +#define FREE_DELAY 256 + +static void *blocks_to_free[FREE_DELAY]; +static unsigned int blocks_to_free_ptr=0; struct fileloc { @@ -490,7 +494,7 @@ BLOCK_ALLOC(memloc, 16382) struct memhdr { struct memhdr *next; - size_t size; + long size; void *data; struct memloc *locations; }; @@ -526,7 +530,14 @@ void check_pad(struct memhdr *mh) { long q,e; char *mem=mh->data; - size_t size=mh->size; + size_t size; + if(mh->size < 0) + { + fprintf(stderr,"Freeing block %p twice (size %ld)!\n",mem, ~mh->size); + dump_memhdr_locations(mh, 0); + abort(); + } + size=mh->size; q= (((long)mem) ^ 0x555555) + (size * 9248339); /* fprintf(stderr,"Checking %p(%d) %ld\n",mem, size, q); */ @@ -745,6 +756,7 @@ static int remove_memhdr(void *p, int already_gone) { if(mh->data==p) { + if(mh->size < 0) mh->size=~mh->size; if(!already_gone) check_pad(mh); *prev=mh->next; @@ -814,11 +826,25 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line) void debug_free(void *p, const char *fn, int line) { + struct memhdr *mh; + if(!p) return; mt_lock(&debug_malloc_mutex); - if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; - free(p); if(verbose_debug_malloc) fprintf(stderr, "free(%p) (%s:%d)\n", p, fn,line); + if((mh=find_memhdr(p))) + { + void *p2; + add_location(mh, location_number(fn,line)); + MEMSET(p, 0x55, mh->size); + mh->size = ~mh->size; + blocks_to_free_ptr++; + blocks_to_free_ptr%=FREE_DELAY; + p2=blocks_to_free[blocks_to_free_ptr]; + blocks_to_free[blocks_to_free_ptr]=p; + p=p2; + } + if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; + free(p); mt_unlock(&debug_malloc_mutex); } @@ -862,6 +888,15 @@ void cleanup_memhdrs() { unsigned long h; mt_lock(&debug_malloc_mutex); + for(h=0;h<FREE_DELAY;h++) + { + void *p; + if((p=blocks_to_free[h])) + { + if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; + free(p); + } + } if(verbose_debug_exit) { int first=1; @@ -878,7 +913,7 @@ void cleanup_memhdrs() } - fprintf(stderr, "LEAK: (%p) %d bytes\n",m->data, m->size); + fprintf(stderr, "LEAK: (%p) %ld bytes\n",m->data, m->size); #ifdef DEBUG describe_something(m->data, attempt_to_identify(m->data),0); #endif diff --git a/src/pike_types.c b/src/pike_types.c index 53511ee460..5c16993dad 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.37 1998/04/09 02:47:47 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.38 1998/04/10 22:24:21 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -46,6 +46,11 @@ static int type_length(char *t); * note that the type after T_MANY can be T_VOID * T_MIXED matches anything except T_VOID * T_UNKNOWN only matches T_MIXED and T_UNKNOWN + * objects are coded thus: + * T_OBJECT <0/1> <program_id> + * ^ + * 0 means 'inherits' + * 1 means 'is' */ struct pike_string *string_type_string; @@ -90,7 +95,7 @@ static void CHECK_TYPE(struct pike_string *s) if(type_length(s->str) != s->len) { stupid_describe_type(s->str,s->len); - fatal("Length of type is wrong.\n"); + fatal("Length of type is wrong. (should be %d, is %d)\n",type_length(s->str),s->len); } } #else @@ -164,6 +169,7 @@ static int type_length(char *t) break; case T_OBJECT: + t++; t+=sizeof(INT32); break; } @@ -271,6 +277,7 @@ static void push_unfinished_type_with_markers(char *s, struct pike_string **am) push_type(EXTRACT_UCHAR(s+ ++e)); push_type(EXTRACT_UCHAR(s+ ++e)); push_type(EXTRACT_UCHAR(s+ ++e)); + push_type(EXTRACT_UCHAR(s+ ++e)); break; default: @@ -339,6 +346,7 @@ static void internal_parse_typeA(char **_s) else if(!strcmp(buf,"object")) { push_type_int(0); + push_type(0); push_type(T_OBJECT); } else if(!strcmp(buf,"program")) push_type(T_PROGRAM); @@ -583,8 +591,10 @@ void stupid_describe_type(char *a,INT32 len) case T_STRING: printf("string"); break; case T_PROGRAM: printf("program"); break; case T_OBJECT: - printf("object(%ld)",(long)EXTRACT_INT(a+e+1)); - e+=sizeof(INT32); + printf("object(%s %ld)", + EXTRACT_UCHAR(a+e+1)?"inherits":"clone of", + (long)EXTRACT_INT(a+e+2)); + e+=sizeof(INT32)+1; break; case T_FUNCTION: printf("function"); break; case T_ARRAY: printf("array"); break; @@ -636,7 +646,7 @@ char *low_describe_type(char *t) case T_PROGRAM: my_strcat("program"); break; case T_OBJECT: my_strcat("object"); - t+=4; + t+=sizeof(INT32)+1; /* Prog id */ break; case T_STRING: my_strcat("string"); break; @@ -837,6 +847,38 @@ static struct pike_string *or_pike_types(struct pike_string *a, return pop_unfinished_type(); } +static struct pike_string *low_object_fun_type(char *t, + struct pike_string *tmp) +{ + struct program *p; + int i; + p=id_to_program(EXTRACT_INT(t+2)); + 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; +} + +static struct pike_string *low_object_lfun_type(char *t, short lfun) +{ + struct program *p; + int i; + p=id_to_program(EXTRACT_INT(t+2)); + 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; +} #define A_EXACT 1 #define B_EXACT 2 @@ -952,25 +994,17 @@ static char *low_match_types(char *a,char *b, int flags) return a; case TWOT(T_OBJECT, T_FUNCTION): { - struct program *p; - if((p=id_to_program(EXTRACT_INT(a+1)))) - { - int i=FIND_LFUN(p,LFUN_CALL); - if(i == -1) return 0; - return low_match_types(ID_FROM_INT(p, i)->type->str, b, flags); - } + struct pike_string *s; + if((s=low_object_lfun_type(a, LFUN_CALL))) + return low_match_types(s->str,b,flags); return a; } case TWOT(T_FUNCTION, T_OBJECT): { - struct program *p; - if((p=id_to_program(EXTRACT_INT(b+1)))) - { - int i=FIND_LFUN(p,LFUN_CALL); - if(i == -1) return 0; - return low_match_types(a, ID_FROM_INT(p, i)->type->str, flags); - } + struct pike_string *s; + if((s=low_object_lfun_type(b, LFUN_CALL))) + return low_match_types(a,s->str,flags); return a; } } @@ -1030,10 +1064,40 @@ static char *low_match_types(char *a,char *b, int flags) break; case T_OBJECT: - a++; - b++; - if(!EXTRACT_INT(a) || !EXTRACT_INT(b)) break; - if(EXTRACT_INT(a) != EXTRACT_INT(b)) return 0; + /* object(* 0) matches any object */ + if(!EXTRACT_INT(a+2) || !EXTRACT_INT(b+2)) break; + + /* object(x *) =? object(x *) */ + if(EXTRACT_UCHAR(a+1) == EXTRACT_UCHAR(b+1)) + { + /* x? */ + if(EXTRACT_UCHAR(a+1)) + { + /* object(1 x) =? object(1 x) */ + if(EXTRACT_INT(a+2) != EXTRACT_INT(b+2)) return 0; + }else{ + /* object(0 *) =? object(0 *) */ + break; + } + } + + { + struct program *ap,*bp; + ap=id_to_program(EXTRACT_UCHAR(a+2)); + bp=id_to_program(EXTRACT_UCHAR(b+2)); + + if(!ap || !bp) break; + + if(EXTRACT_UCHAR(a+1)) + { + if(low_get_storage(bp,ap)==-1) + return 0; + }else{ + if(low_get_storage(ap,bp)==-1) + return 0; + } + } + break; case T_MULTISET: @@ -1121,6 +1185,7 @@ static int low_get_return_type(char *a,char *b) case T_PROGRAM: push_type_int(0); + push_type(0); push_type(T_OBJECT); return 1; @@ -1155,7 +1220,7 @@ static struct pike_string *debug_low_index_type(char *t, node *n) { case T_OBJECT: { - struct program *p=id_to_program(EXTRACT_INT(t)); + struct program *p=id_to_program(EXTRACT_INT(t+1)); if(p && n) { if(n->token == F_ARROW) @@ -1181,8 +1246,16 @@ static struct pike_string *debug_low_index_type(char *t, node *n) reference_shared_string(int_type_string); return int_type_string; }else{ - reference_shared_string(ID_FROM_INT(p, i)->type); - return ID_FROM_INT(p, i)->type; + if(EXTRACT_UCHAR(t) || + (p->identifier_references[i].id_flags & ID_NOMASK) || + (ID_FROM_INT(p, i)->identifier_flags & IDENTIFIER_PROTOTYPED)) + { + reference_shared_string(ID_FROM_INT(p, i)->type); + return ID_FROM_INT(p, i)->type; + }else{ + reference_shared_string(mixed_type_string); + return mixed_type_string; + } } } } @@ -1276,16 +1349,16 @@ static int low_check_indexing(char *type, char *index_type, node *n) case T_OBJECT: { - struct program *p=id_to_program(EXTRACT_INT(type)); + struct program *p=id_to_program(EXTRACT_INT(type+1)); if(p) { if(n->token == F_ARROW) { - if(FIND_LFUN(p,LFUN_ARROW) != -1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW) != -1) - return 1; + if(FIND_LFUN(p,LFUN_ARROW)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_ARROW)!=-1) + return 1; }else{ - if(FIND_LFUN(p,LFUN_INDEX) != -1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX) != -1) - return 1; + if(FIND_LFUN(p,LFUN_INDEX)!=-1 || FIND_LFUN(p,LFUN_ASSIGN_INDEX)!=-1) + return 1; } return !!low_match_types(string_type_string->str, index_type,0); }else{ @@ -1440,8 +1513,10 @@ struct pike_string *get_type_of_svalue(struct svalue *s) if(s->u.object->prog) { push_type_int(s->u.object->prog->id); + push_type(1); }else{ push_type_int(0); + push_type(0); } push_type(T_OBJECT); return pop_unfinished_type(); @@ -1470,6 +1545,7 @@ struct pike_string *get_type_of_svalue(struct svalue *s) { type_stack_mark(); push_type_int(s->u.program->id); + push_type(1); push_type(T_OBJECT); type_stack_mark(); diff --git a/src/program.c b/src/program.c index 5bbb7d645a..268b268b39 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.75 1998/04/10 18:38:15 grubba Exp $"); +RCSID("$Id: program.c,v 1.76 1998/04/10 22:24:21 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -2287,12 +2287,12 @@ static struct get_storage_cache INT32 oid, pid, offset; } get_storage_cache[GET_STORAGE_CACHE_SIZE]; -char *get_storage(struct object *o, struct program *p) +int low_get_storage(struct program *o, struct program *p) { INT32 oid,pid, offset; unsigned INT32 hval; - if(!o->prog) return 0; - oid=o->prog->id; + if(!o) return 0; + oid=o->id; pid=p->id; hval=oid*9248339 + pid; hval%=GET_STORAGE_CACHE_SIZE; @@ -2307,11 +2307,11 @@ char *get_storage(struct object *o, struct program *p) }else{ INT32 e; offset=-1; - for(e=0;e<o->prog->num_inherits;e++) + for(e=0;e<o->num_inherits;e++) { - if(o->prog->inherits[e].prog==p) + if(o->inherits[e].prog==p) { - offset=o->prog->inherits[e].storage_offset; + offset=o->inherits[e].storage_offset; break; } } @@ -2321,6 +2321,12 @@ char *get_storage(struct object *o, struct program *p) get_storage_cache[hval].offset=offset; } + return offset; +} + +char *get_storage(struct object *o, struct program *p) +{ + int offset= low_get_storage(o->prog, p); if(offset == -1) return 0; return o->storage + offset; } diff --git a/src/program.h b/src/program.h index eb3be4ccd2..28cc725110 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.38 1998/04/09 02:49:48 hubbe Exp $ + * $Id: program.h,v 1.39 1998/04/10 22:24:22 hubbe Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -108,6 +108,7 @@ union idptr #define IDENTIFIER_FUNCTION 3 #define IDENTIFIER_CONSTANT 4 #define IDENTIFIER_VARARGS 8 +#define IDENTIFIER_PROTOTYPED 16 #define IDENTIFIER_IS_FUNCTION(X) ((X) & IDENTIFIER_FUNCTION) #define IDENTIFIER_IS_CONSTANT(X) ((X) & IDENTIFIER_CONSTANT) @@ -350,6 +351,7 @@ void count_memory_in_programs(INT32 *num_, INT32 *size_); void push_compiler_frame(void); void pop_local_variables(int level); void pop_compiler_frame(void); +int low_get_storage(struct program *o, struct program *p); char *get_storage(struct object *o, struct program *p); struct program *low_program_from_function(struct program *p, INT32 i); diff --git a/src/testsuite.in b/src/testsuite.in index 50f4989717..30ea496b47 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -test_true([["$Id: testsuite.in,v 1.87 1998/04/10 04:49:55 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.88 1998/04/10 22:24:22 hubbe Exp $"]]) test_eq(1e1,10.0) test_eq(1E1,10.0) test_eq(1e+1,10.0) @@ -13,6 +13,13 @@ bar"]],[["foo\nbar"]]) test_true([[stringp(#string "Makefile")]]) test_any([[class Bar { array(int) foo = ({}); }; class Foo { inherit Bar; array(int) foo = ({1}); }; return sizeof(Foo()->foo);]],1) +test_compile([[Stdio.File foo=Stdio.File();]]) +test_compile([[class { Stdio.File foo=Stdio.File(); }]]) +test_compile_any([[void foo(Stdio.FILE f) {}]]) +test_compile_any([[void foo(array(Stdio.FILE) f) {}]]) +test_compile_any([[void foo(array(Stdio.FILE) f) {}]]) +test_compile_any([[Stdio.File foo(array(Stdio.FILE) f) { return f[0]; }]]) +test_compile([[Stdio.File foo=Stdio.FILE();]]) test_any([[object(Stdio.File) f; f=Stdio.File(); return 1]],1) test_compile([[int t=gauge { string foo; };]]) @@ -171,7 +178,10 @@ test_program(inherit test;) test_program(inherit test; int a() { return foo; } ) test_define_program(test,[[class TEST { int a() { return 1; } }]]) test_program(inherit test; inherit TEST; ) -test_compile_error(class c { object(Stdio.File) foo; object(Regexp) bar=foo; }) + +dnl This test cannot be performed without a way to tell the +dnl compiler that foo *is* an Stdio.File, not inherits an Stdio.File +dnl test_compile_error(class c { object(Stdio.File) foo; object(Regexp) bar=foo; }) test_do(class c { object foo; object(Regexp) bar=foo; }) test_do(class c { object(Stdio.File) foo; object bar=foo; }) test_any(if(int i=1) return i; return 0;,1) -- GitLab