diff --git a/src/docode.c b/src/docode.c index bb188a8f9ed48831162d35e6958adc17e8dd26fd..20cb71dbcedc2b56987254dbaf8b1dd595006611 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.5 1996/12/01 13:03:54 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.6 1996/12/04 00:27:10 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -419,6 +419,9 @@ static int do_docode2(node *n,int flags) switch(CDR(n)->token) { case F_LOCAL: + if(CDR(n)->u.number >= local_variables->max_number_of_locals) + yyerror("Illegal to use local variable here."); + if(do_docode(CAR(n),0)!=1) yyerror("RHS is void!"); emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL, CDR(n)->u.number ); @@ -985,6 +988,8 @@ static int do_docode2(node *n,int flags) } case F_LOCAL: + if(n->u.number >= local_variables->max_number_of_locals) + yyerror("Illegal to use local variable here."); if(flags & DO_LVALUE) { emit(F_LOCAL_LVALUE,n->u.number); diff --git a/src/language.yacc b/src/language.yacc index 0406e25501861153e0ce2c4707ed721384658b9f..002786ca0baba959ce9e2b4d6d5c43de9dde08c9 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -156,7 +156,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.13 1996/11/28 03:42:13 hubbe Exp $"); +RCSID("$Id: language.yacc,v 1.14 1996/12/04 00:27:10 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -185,7 +185,7 @@ void add_local_name(struct pike_string *,struct pike_string *); /* * The names and types of arguments and auto variables. */ -struct locals *local_variables; +struct locals *local_variables = 0; static int varargs; static INT32 current_modifiers; @@ -425,6 +425,7 @@ constant_name: F_IDENTIFIER '=' expr0 add_constant($1,&tmp, current_modifiers); } else { tmp=eval_low($3); + free_node($3); if(tmp < 1) { yyerror("Error in constant definition."); diff --git a/src/las.c b/src/las.c index 4238d87a1681e5540f69dafc9023c02c0ed69a31..2cf80c8f4daac7053d47f378531d31b396f6ee2e 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.8 1996/11/25 21:33:08 hubbe Exp $"); +RCSID("$Id: las.c,v 1.9 1996/12/04 00:27:11 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -24,6 +24,7 @@ RCSID("$Id: las.c,v 1.8 1996/11/25 21:33:08 hubbe Exp $"); #include "memory.h" #include "operators.h" #include "callback.h" +#include "macros.h" #define LASDEBUG @@ -120,12 +121,65 @@ INT32 count_args(node *n) } } + +#define NODES 256 + +struct node_chunk +{ + struct node_chunk *next; + node nodes[NODES]; +}; + +static struct node_chunk *node_chunks=0; +static node *free_nodes=0; + +void free_all_nodes() +{ + if(!local_variables) + { + node *tmp; + struct node_chunk *tmp2; +#ifdef DEBUG + int e=0; + for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) e+=NODES; + for(tmp=free_nodes;tmp;tmp=CAR(tmp)) e--; + if(e) + { + int e2=e; + for(tmp2=node_chunks;tmp2;tmp2=tmp2->next) + { + for(e=0;e<NODES;e++) + { + for(tmp=free_nodes;tmp;tmp=CAR(tmp)) + if(tmp==tmp2->nodes+e) + break; + + if(!tmp) + fprintf(stderr,"Free node at %p.\n",(tmp2->nodes+e)); + } + } + fatal("Failed to free %d nodes when compiling!\n",e2); + } +#endif + while(node_chunks) + { + tmp2=node_chunks; + node_chunks=tmp2->next; + free((char *)tmp2); + } + free_nodes=0; + } +} + void free_node(node *n) { if(!n) return; - if(n->type) free_string(n->type); switch(n->token) { + case USHRT_MAX: + fatal("Freeing node again!\n"); + break; + case F_CONSTANT: free_svalue(&(n->u.sval)); break; @@ -134,16 +188,32 @@ void free_node(node *n) if(car_is_node(n)) free_node(CAR(n)); if(cdr_is_node(n)) free_node(CDR(n)); } - free((char *)n); + n->token=USHRT_MAX; + if(n->type) free_string(n->type); + CAR(n)=free_nodes; + free_nodes=n; } /* here starts routines to make nodes */ - static node *mkemptynode() { node *res; - res=(node *)xalloc(sizeof(node)); + if(!free_nodes) + { + int e; + struct node_chunk *tmp=ALLOC_STRUCT(node_chunk); + tmp->next=node_chunks; + node_chunks=tmp; + + for(e=0;e<NODES-1;e++) + CAR(tmp->nodes+e)=tmp->nodes+e+1; + CAR(tmp->nodes+e)=0; + free_nodes=tmp->nodes; + } + res=free_nodes; + free_nodes=CAR(res); + res->token=0; res->line_number=current_line; res->type=0; res->node_info=0; diff --git a/src/las.h b/src/las.h index 62caadd02b651ab5f3b607a2335d6493dba09305..736754f4a0f880025734dd83e84e30c32a307a13 100644 --- a/src/las.h +++ b/src/las.h @@ -78,6 +78,8 @@ extern int num_parse_error; int car_is_node(node *n); int cdr_is_node(node *n); INT32 count_args(node *n); +struct node_chunk; +void free_all_nodes(); void free_node(node *n); node *mknode(short token,node *a,node *b); node *mkstrnode(struct pike_string *str); @@ -103,6 +105,7 @@ node **my_get_arg(node **a,int n); void print_tree(node *n); struct used_vars; void fix_type_field(node *n); +struct timer_oflo; int eval_low(node *n); void dooptcode(struct pike_string *name,node *n, int args); INT32 get_opt_info(); diff --git a/src/program.c b/src/program.c index 7d509775dadd724eb9cae4c696bd80bcd7d3d73c..9f34f7aadfc3408124682f07471d29dd5ffb09ae 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.9 1996/11/19 09:35:24 hubbe Exp $"); +RCSID("$Id: program.c,v 1.10 1996/12/04 00:27:12 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -399,8 +399,8 @@ struct program *end_program() struct pike_string *s; s=make_shared_string("__INIT"); tmp.offset=PC; - ins_byte(0, A_PROGRAM); /* num args */ ins_byte(0, A_PROGRAM); /* num locals */ + ins_byte(0, A_PROGRAM); /* num args */ dooptcode(s,mknode(F_ARG_LIST,init_node,mknode(F_RETURN,mkintnode(0),0)),0); define_function(s, function_type_string, @@ -408,6 +408,7 @@ struct program *end_program() IDENTIFIER_PIKE_FUNCTION, & tmp); free_string(s); + init_node=0; } if (num_parse_error > 0) @@ -533,7 +534,7 @@ struct program *end_program() #undef POP #undef PROGRAM_STATE threads_disabled--; - + free_all_nodes(); return prog; }