diff --git a/src/apply_low.h b/src/apply_low.h index ba757a648a48495a6742a6b51866d348aa4c2e7e..b6b362dd8b07a53b8e849cea5d8010cc55be3b9f 100644 --- a/src/apply_low.h +++ b/src/apply_low.h @@ -129,6 +129,12 @@ new_frame->pc = 0; #ifdef SCOPE new_frame->scope=scope; +#ifdef PIKE_DEBUG + if(new_frame->fun == scope->fun) + { + fatal("Que? A function cannot be parented by itself!\n"); + } +#endif #else new_frame->scope=0; #endif diff --git a/src/docode.c b/src/docode.c index 3861ffc228476a5ca0c243200a5c8e45ea812060..840b7b041dae5353c0208b58967b205a58c71745 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.133 2001/09/28 00:01:44 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.134 2001/09/29 06:19:26 hubbe Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -2013,8 +2013,16 @@ static int do_docode2(node *n, INT16 flags) } case F_TRAMPOLINE: - emit1(F_TRAMPOLINE,n->u.id.number); + { + struct compiler_frame *f; + int depth=0; + for(f=Pike_compiler->compiler_frame; + f!=n->u.trampoline.frame;f=f->previous) + depth++; + + emit2(F_TRAMPOLINE,n->u.trampoline.ident,depth); return 1; + } case F_IDENTIFIER: if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program, n->u.id.number)->identifier_flags)) diff --git a/src/interpret_functions.h b/src/interpret_functions.h index a64bb0bab424cf0c471d6732aa2d202fd6a85a3c..3ac1ad6904da01b1f1e5b10187ef26acdc8898e4 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.94 2001/09/28 00:01:44 hubbe Exp $ + * $Id: interpret_functions.h,v 1.95 2001/09/29 06:19:27 hubbe Exp $ * * Opcode definitions for the interpreter. */ @@ -274,9 +274,11 @@ OPCODE1(F_LFUN, "local function", { print_return_value(); }); -OPCODE1(F_TRAMPOLINE, "trampoline", { +OPCODE2(F_TRAMPOLINE, "trampoline", { struct object *o=low_clone(pike_trampoline_program); - add_ref( ((struct pike_trampoline *)(o->storage))->frame=Pike_fp ); + struct pike_frame *f=Pike_fp; + while(arg2--) f=f->scope; + add_ref( ((struct pike_trampoline *)(o->storage))->frame=f ); ((struct pike_trampoline *)(o->storage))->func=arg1+Pike_fp->context.identifier_level; push_object(o); /* Make it look like a function. */ diff --git a/src/language.yacc b/src/language.yacc index fa3b24c59fa93ea72cb3afb1cfe653a819a649ff..6228eff5c4f0b461e5d6adcb41257663ecb6edf8 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -112,7 +112,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.261 2001/09/28 00:01:45 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.262 2001/09/29 06:19:27 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -1872,7 +1872,7 @@ lambda: TOK_LAMBDA push_compiler_frame1 ID_STATIC | ID_PRIVATE | ID_INLINE); if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED) { - $$ = mktrampolinenode(f); + $$ = mktrampolinenode(f, Pike_compiler->compiler_frame->previous); } else { $$ = mkidentifiernode(f); } @@ -1943,19 +1943,26 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args name=make_shared_string(buf); - id=define_function(name, - type, - 0, - IDENTIFIER_PIKE_FUNCTION, - 0, - OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); + if(Pike_compiler->compiler_pass > 1) + { + id=isidentifier(name); + }else{ + id=define_function(name, + type, + 0, + IDENTIFIER_PIKE_FUNCTION, + 0, + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); + } n=0; -#if 0 if(Pike_compiler->compiler_pass > 1 && (i=ID_FROM_INT(Pike_compiler->new_program, id))) - if(!(i->identifier_flags & IDENTIFIER_SCOPED)) + { + if(i->identifier_flags & IDENTIFIER_SCOPED) + n = mktrampolinenode(id, Pike_compiler->compiler_frame->previous); + else n = mkidentifiernode(id); -#endif + } low_add_local_name(Pike_compiler->compiler_frame->previous, $1->u.sval.u.string, type, n); @@ -2004,11 +2011,9 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args if(Pike_compiler->compiler_frame->lexical_scope & (SCOPE_SCOPE_USED | SCOPE_SCOPED)) { - $$ = mknode(F_ASSIGN, mktrampolinenode($<number>3), - mklocalnode(localid,0)); + $$ = mktrampolinenode($<number>3,Pike_compiler->compiler_frame); }else{ - $$ = mknode(F_ASSIGN, mkidentifiernode($<number>3), - mklocalnode(localid,0)); + $$ = mkidentifiernode($<number>3); } } } @@ -2081,20 +2086,26 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args name=make_shared_string(buf); - - id=define_function(name, - type, - 0, - IDENTIFIER_PIKE_FUNCTION, - 0, - OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); + if(Pike_compiler->compiler_pass > 1) + { + id=isidentifier(name); + }else{ + id=define_function(name, + type, + 0, + IDENTIFIER_PIKE_FUNCTION, + 0, + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); + } n=0; -#if 0 if(Pike_compiler->compiler_pass > 1 && (i=ID_FROM_INT(Pike_compiler->new_program, id))) - if(!(i->identifier_flags & IDENTIFIER_SCOPED)) + { + if(i->identifier_flags & IDENTIFIER_SCOPED) + n = mktrampolinenode(id, Pike_compiler->compiler_frame->previous); + else n = mkidentifiernode(id); -#endif + } low_add_local_name(Pike_compiler->compiler_frame->previous, $2->u.sval.u.string, type, n); @@ -2144,11 +2155,9 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args if(Pike_compiler->compiler_frame->lexical_scope & (SCOPE_SCOPE_USED | SCOPE_SCOPED)) { - $$ = mknode(F_ASSIGN, mktrampolinenode($<number>5), - mklocalnode(localid,0)); + $$ = mktrampolinenode($<number>5,Pike_compiler->compiler_frame); }else{ - $$ = mknode(F_ASSIGN, mkidentifiernode($<number>5), - mklocalnode(localid,0)); + $$ = mkidentifiernode($<number>5); } } } @@ -3015,7 +3024,7 @@ optional_block: ';' /* EMPTY */ { $$=0; } ID_STATIC | ID_PRIVATE | ID_INLINE); if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED) { - $$ = mktrampolinenode(f); + $$ = mktrampolinenode(f,Pike_compiler->compiler_frame->previous); } else { $$ = mkidentifiernode(f); } diff --git a/src/las.c b/src/las.c index 55a756ded31efc19b5d21bea4beaf80023adf192..34946b5ada498611e021aeeefe83e3a6443f3f57 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.268 2001/09/28 00:01:45 hubbe Exp $"); +RCSID("$Id: las.c,v 1.269 2001/09/29 06:19:27 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -1301,9 +1301,11 @@ node *debug_mkidentifiernode(int i) #endif } -node *debug_mktrampolinenode(int i) +node *debug_mktrampolinenode(int i, struct compiler_frame *frame) { + struct compiler_frame *f; node *res = mkemptynode(); + res->token = F_TRAMPOLINE; copy_pike_type(res->type, ID_FROM_INT(Pike_compiler->new_program, i)->type); @@ -1319,9 +1321,15 @@ node *debug_mktrampolinenode(int i) #ifdef __CHECKER__ _CDR(res) = 0; #endif - res->u.id.number = i; + res->u.trampoline.ident=i; + res->u.trampoline.frame=frame; + + for(f=Pike_compiler->compiler_frame;f != frame;f=f->previous) + f->lexical_scope|=SCOPE_SCOPED; + f->lexical_scope|=SCOPE_SCOPE_USED; + #ifdef SHARED_NODES - res->u.id.prog = Pike_compiler->new_program; + res->u.trampoline.prog = Pike_compiler->new_program; #endif /* SHARED_NODES */ res = freeze_node(res); @@ -1864,13 +1872,20 @@ int node_is_eq(node *a,node *b) switch(a->token) { + case F_TRAMPOLINE: /* FIXME, the context has to be the same! */ +#ifdef SHARED_NODES + if(a->u.trampoline.prog != b->u.trampoline.prog) + return 0; +#endif + return a->u.trampoline.ident == b->u.trampoline.ident && + a->u.trampoline.frame == b->u.trampoline.frame; + case F_EXTERNAL: case F_LOCAL: return a->u.integer.a == b->u.integer.a && a->u.integer.b == b->u.integer.b; case F_IDENTIFIER: - case F_TRAMPOLINE: /* FIXME, the context has to be the same! */ return a->u.id.number == b->u.id.number; case F_CAST: @@ -2370,7 +2385,7 @@ static void low_print_tree(node *foo,int needlval) case F_TRAMPOLINE: if (Pike_compiler->new_program) { fprintf(stderr, "trampoline<%s>", - ID_FROM_INT(Pike_compiler->new_program, foo->u.id.number)->name->str); + ID_FROM_INT(Pike_compiler->new_program, foo->u.trampoline.ident)->name->str); } else { fprintf(stderr, "trampoline<unknown identifier>"); } @@ -3355,7 +3370,7 @@ void fix_type_field(node *n) copy_pike_type(n->type, zero_type_string); } else { type_a=CAR(n)->type; - if(!check_indexing(type_a, int_type_string, n)) + if(!match_types(type_a, array_type_string)) if(!Pike_compiler->catch_level) my_yyerror("[*] on non-array."); n->type=index_type(type_a, int_type_string, n); diff --git a/src/las.h b/src/las.h index a2567aea14ffab2383a0c3ce57511fb0e7805dd6..871c6393023e55a5ddf7f840a0958d04f2d4fb81 100644 --- a/src/las.h +++ b/src/las.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: las.h,v 1.52 2001/08/13 23:15:58 mast Exp $ + * $Id: las.h,v 1.53 2001/09/29 06:19:27 hubbe Exp $ */ #ifndef LAS_H #define LAS_H @@ -137,7 +137,7 @@ node *debug_mkefuncallnode(char *function, node *args); node *debug_mkopernode(char *oper_id, node *arg1, node *arg2); node *debug_mklocalnode(int var, int depth); node *debug_mkidentifiernode(int i); -node *debug_mktrampolinenode(int i); +node *debug_mktrampolinenode(int i, struct compiler_frame *depth); node *debug_mkexternalnode(struct program *prog, int i); node *debug_mkcastnode(struct pike_type *type, node *n); node *debug_mksoftcastnode(struct pike_type *type, node *n); @@ -188,7 +188,7 @@ void resolv_program(node *n); #define mkopernode(oper_id, arg1, arg2) dmalloc_touch(node *, debug_mkopernode(oper_id, dmalloc_touch(node *, arg1), dmalloc_touch(node *, arg2))) #define mklocalnode(var, depth) dmalloc_touch(node *, debug_mklocalnode(var, depth)) #define mkidentifiernode(i) dmalloc_touch(node *, debug_mkidentifiernode(i)) -#define mktrampolinenode(i) dmalloc_touch(node *, debug_mktrampolinenode(i)) +#define mktrampolinenode(i,f) dmalloc_touch(node *, debug_mktrampolinenode(i, f)) #define mkexternalnode(parent_prog, i) dmalloc_touch(node *, debug_mkexternalnode(parent_prog, i)) #define mkcastnode(type, n) dmalloc_touch(node *, debug_mkcastnode(type, dmalloc_touch(node *, n))) #define mksoftcastnode(type, n) dmalloc_touch(node *, debug_mksoftcastnode(type, dmalloc_touch(node *, n))) diff --git a/src/pike_types.h b/src/pike_types.h index d5b1dca53c558a101b7d5677e3ccc57aefaf7dda..9aa0dd01ba3834cc8219fa9a099b3e38819b33b5 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: pike_types.h,v 1.72 2001/08/30 23:32:16 mast Exp $ + * $Id: pike_types.h,v 1.73 2001/09/29 06:19:28 hubbe Exp $ */ #ifndef PIKE_TYPES_H #define PIKE_TYPES_H @@ -81,6 +81,8 @@ extern unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4]; #endif /* USE_PIKE_TYPE */ +struct compiler_frame; + /* Also used in struct node_identifier */ union node_data { @@ -89,6 +91,14 @@ union node_data int number; struct program *prog; } id; + struct + { + int ident; + struct compiler_frame *frame; +#ifdef SHARED_NODES + struct program *prog; +#endif + } trampoline; struct svalue sval; struct { diff --git a/src/program.c b/src/program.c index db48582bdbc987da25f2b0dcc2c36965cd3968f8..68e05628a3e4ff557fe12ec5a41882c5bbfb8c8c 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.377 2001/09/27 15:17:47 grubba Exp $"); +RCSID("$Id: program.c,v 1.378 2001/09/29 06:19:28 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -3216,21 +3216,18 @@ PMOD_EXPORT int add_constant(struct pike_string *name, id->opt_flags); } - else if(id->identifier_flags & IDENTIFIER_CONSTANT && + else if((id->identifier_flags & IDENTIFIER_CONSTANT) && id->func.offset != -1) { c=& Pike_compiler->new_program->constants[id->func.offset].sval; } } -#if 0 else { - /* Actually, we do not allow fake objects to enter - * the mainstream, but it would be possible to do so. - * I will leave this code here just in case someone wants - * to use it in the future - */ - if(id->identifier_flags & IDENTIFIER_CONSTANT) + if((id->identifier_flags & IDENTIFIER_CONSTANT) && + id->func.offset != -1 && + INHERIT_FROM_INT(c->u.object->prog, c->subtype)->prog-> + constants[id->func.offset].sval.type == T_PROGRAM) { /* In this one case we allow fake objects to enter the * mainstream... @@ -3238,7 +3235,6 @@ PMOD_EXPORT int add_constant(struct pike_string *name, break; } } -#endif } if(c && !svalues_are_constant(c,1,BIT_MIXED,0))