diff --git a/src/language.yacc b/src/language.yacc index a802f9a4daa7f3f0ec8354c286258e1b2ba134fc..ef124c23ba096e67eb6d1a052d182a5b605730af 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -110,7 +110,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.208 2000/08/18 22:05:40 grubba Exp $"); +RCSID("$Id: language.yacc,v 1.209 2000/08/30 21:58:15 grubba Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -711,7 +711,8 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0 check_node_hash($<n>$)->u.sval.u.string, $1 & (~ID_EXTERN), IDENTIFIER_PIKE_FUNCTION, - 0); + 0, + OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT); if ($1 & ID_VARIANT) { fprintf(stderr, "Function number: %d\n", @@ -728,6 +729,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0 node *check_args = NULL; int save_line = lex.current_line; int num_required_args = 0; + struct identifier *i; #ifdef PIKE_DEBUG struct pike_string *save_file = lex.current_file; lex.current_file = $8->current_file; @@ -785,7 +787,6 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0 } if ($1 & ID_VARIANT) { - int i = isidentifier($4->u.sval.u.string); struct pike_string *bad_arg_str; MAKE_CONSTANT_SHARED_STRING(bad_arg_str, "Bad number of arguments!\n"); @@ -820,6 +821,9 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0 check_node_hash($<n>9)->u.sval.u.string, $1); + i = ID_FROM_INT(Pike_compiler->new_program, f); + i->opt_flags = Pike_compiler->compiler_frame->opt_flags; + if ($1 & ID_VARIANT) { fprintf(stderr, "Function number: %d\n", f); } @@ -1729,7 +1733,8 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args type, 0, IDENTIFIER_PIKE_FUNCTION, - 0); + 0, + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); n=0; #if 0 if(Pike_compiler->compiler_pass > 1 && @@ -1757,6 +1762,8 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args i->type, ID_STATIC | ID_PRIVATE | ID_INLINE); + i->opt_flags = Pike_compiler->compiler_frame->opt_flags; + pop_compiler_frame(); free_node($1); @@ -1848,7 +1855,8 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args type, 0, IDENTIFIER_PIKE_FUNCTION, - 0); + 0, + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); n=0; #if 0 if(Pike_compiler->compiler_pass > 1 && @@ -1877,6 +1885,8 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args i->type, ID_STATIC | ID_PRIVATE | ID_INLINE); + i->opt_flags = Pike_compiler->compiler_frame->opt_flags; + pop_compiler_frame(); free_node($2); @@ -1983,7 +1993,8 @@ optional_create_arguments: /* empty */ { $$ = 0; } Pike_compiler->compiler_frame->current_function_number= define_function(create_string, type, - ID_STATIC, IDENTIFIER_PIKE_FUNCTION, 0); + ID_STATIC, IDENTIFIER_PIKE_FUNCTION, 0, + OPT_SIDE_EFFECT); /* Third: Generate the initialization code. * diff --git a/src/las.c b/src/las.c index 8825a221717a6998493fb52224f8601256e6992c..14a0f12f921f8b9bdffa84431c0bc9cefca6e980 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.198 2000/08/28 10:29:47 grubba Exp $"); +RCSID("$Id: las.c,v 1.199 2000/08/30 21:58:16 grubba Exp $"); #include "language.h" #include "interpret.h" @@ -617,16 +617,59 @@ node *debug_mknode(short token, node *a, node *b) break; case F_APPLY: - if(a && a->token == F_CONSTANT && - a->u.sval.type == T_FUNCTION && - a->u.sval.subtype == FUNCTION_BUILTIN) { - res->node_info |= a->u.sval.u.efun->flags; - }else{ - res->node_info |= OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; /* for now */ - if(a) res->tree_info |= a->tree_info; + unsigned INT16 opt_flags = OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; + struct identifier *i = NULL; + + if (a) { + switch(a->token) { + case F_CONSTANT: + if (a->u.sval.type == T_FUNCTION) { + if (a->u.sval.subtype == FUNCTION_BUILTIN) { + opt_flags = a->u.sval.u.efun->flags; + } else if (a->u.sval.u.object->prog) { + i = ID_FROM_INT(a->u.sval.u.object->prog, a->u.sval.subtype); + } else { + yyerror("Calling function in destructed module."); + } + } + break; + case F_EXTERNAL: + { + struct program_state *state = Pike_compiler; + int program_id = a->u.integer.a; + while (state && (state->new_program->id != program_id)) { + state = state->previous; + } + if (state) { + i = ID_FROM_INT(state->new_program, a->u.integer.b); + } else { + yyerror("Parent has left."); + } + } + break; + case F_LOCAL: + /* FIXME: Should lookup functions in the local scope. */ + default: + res->tree_info |= a->tree_info; + } + if (i && IDENTIFIER_IS_FUNCTION(i->identifier_flags)) { +#ifdef PIKE_DEBUG + /* Temporary check to see that the flags aren't reset somewhere. */ + if (i->opt_flags != (OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND)) { + my_yyerror("Identifier %s has opt_flags 0x%04x!", + i->name->str, i->opt_flags); + } +#endif /* PIKE_DEBUG */ + res->node_info |= i->opt_flags; + } else { + res->node_info |= opt_flags; + } + } else { + res->node_info |= opt_flags; + } + if(b) res->tree_info |= b->tree_info; } - if(b) res->tree_info |= b->tree_info; break; case F_POP_VALUE: @@ -4368,7 +4411,8 @@ int dooptcode(struct pike_string *name, type, modifiers, IDENTIFIER_C_FUNCTION | vargs, - &tmp); + &tmp, + foo->u.efun->flags); free_node(n); return ret; } @@ -4399,7 +4443,8 @@ int dooptcode(struct pike_string *name, type, modifiers, IDENTIFIER_PIKE_FUNCTION | vargs, - &tmp); + &tmp, + Pike_compiler->compiler_frame->opt_flags); #ifdef PIKE_DEBUG diff --git a/src/las.h b/src/las.h index a602fd25d20eabe06678f771e24a503698927cf8..6e77ba1fad1f792a06bbf8e94de4f52cc64fa008 100644 --- a/src/las.h +++ b/src/las.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: las.h,v 1.41 2000/08/14 17:48:50 grubba Exp $ + * $Id: las.h,v 1.42 2000/08/30 21:58:16 grubba Exp $ */ #ifndef LAS_H #define LAS_H @@ -53,6 +53,7 @@ struct compiler_frame int current_function_number; int recur_label; int is_inline; + unsigned int opt_flags; struct local_variable variable[MAX_LOCAL]; }; diff --git a/src/program.c b/src/program.c index 9f4deaf841941feee61013b4db879a67a79daaf6..48d443475ec5e995af6920e5081faf69d09406f0 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.267 2000/08/28 19:35:04 hubbe Exp $"); +RCSID("$Id: program.c,v 1.268 2000/08/30 21:58:17 grubba Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -2553,9 +2553,10 @@ PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags) */ INT32 define_function(struct pike_string *name, struct pike_string *type, - INT16 flags, - INT8 function_flags, - union idptr *func) + unsigned INT8 flags, + unsigned INT8 function_flags, + union idptr *func, + unsigned INT16 opt_flags) { struct identifier *funp,fun; struct reference ref; @@ -2641,6 +2642,8 @@ INT32 define_function(struct pike_string *name, funp->identifier_flags=function_flags; + funp->opt_flags = opt_flags; + free_string(funp->type); copy_shared_string(funp->type, type); }else{ @@ -2675,6 +2678,8 @@ INT32 define_function(struct pike_string *name, else fun.func.offset = -1; + fun.opt_flags = opt_flags; + ref.identifier_offset=Pike_compiler->new_program->num_identifiers; add_to_identifiers(fun); } @@ -2740,6 +2745,8 @@ make_a_new_def: else fun.func.offset = -1; + fun.opt_flags = opt_flags; + i=Pike_compiler->new_program->num_identifiers; add_to_identifiers(fun); @@ -3429,7 +3436,9 @@ struct program *compile(struct pike_string *prog, return p; } -PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags) +PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32), + char *type, unsigned INT8 flags, + unsigned INT16 opt_flags) { int ret; struct pike_string *name_tmp,*type_tmp; @@ -3445,13 +3454,15 @@ PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT1 type_tmp, flags, IDENTIFIER_C_FUNCTION, - &tmp); + &tmp, + opt_flags); }else{ ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, - 0); + 0, + opt_flags); } free_string(name_tmp); free_string(type_tmp); @@ -3459,19 +3470,19 @@ PMOD_EXPORT int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT1 } PMOD_EXPORT int quick_add_function(char *name, - int name_length, - void (*cfun)(INT32), - char *type, - int type_length, - INT16 flags, - int opt_flags) + int name_length, + void (*cfun)(INT32), + char *type, + int type_length, + unsigned INT8 flags, + unsigned INT16 opt_flags) { int ret; struct pike_string *name_tmp,*type_tmp; union idptr tmp; /* fprintf(stderr,"ADD_FUNC: %s\n",name); */ - name_tmp=make_shared_binary_string(name,name_length); - type_tmp=make_shared_binary_string(type,type_length); + name_tmp = make_shared_binary_string(name,name_length); + type_tmp = make_shared_binary_string(type,type_length); if(cfun) { @@ -3480,13 +3491,15 @@ PMOD_EXPORT int quick_add_function(char *name, type_tmp, flags, IDENTIFIER_C_FUNCTION, - &tmp); + &tmp, + opt_flags); }else{ ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, - 0); + 0, + opt_flags); } free_string(name_tmp); free_string(type_tmp); @@ -3921,6 +3934,7 @@ void push_compiler_frame(int lexical_scope) f->recur_label=-1; f->is_inline=0; f->num_args=-1; + f->opt_flags = OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND; /* FIXME: Should be 0. */ Pike_compiler->compiler_frame=f; } diff --git a/src/program.h b/src/program.h index 8a275889a95abbf3cdf9a4c861bf9d723e83fee7..f729129bb5ebb738895fec1e0b506351d60f2b12 100644 --- a/src/program.h +++ b/src/program.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: program.h,v 1.108 2000/08/29 00:09:47 hubbe Exp $ + * $Id: program.h,v 1.109 2000/08/30 21:58:17 grubba Exp $ */ #ifndef PROGRAM_H #define PROGRAM_H @@ -146,8 +146,9 @@ struct identifier { struct pike_string *name; struct pike_string *type; - unsigned INT16 identifier_flags; /* IDENTIFIER_??? */ - unsigned INT16 run_time_type; + unsigned INT8 identifier_flags; /* IDENTIFIER_??? */ + unsigned INT8 run_time_type; /* PIKE_T_??? */ + unsigned INT16 opt_flags; /* OPT_??? */ #ifdef PROFILING unsigned INT32 num_calls; unsigned INT32 total_time; @@ -432,9 +433,10 @@ PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * ty PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags); INT32 define_function(struct pike_string *name, struct pike_string *type, - INT16 flags, - INT8 function_flags, - union idptr *func); + unsigned INT8 flags, + unsigned INT8 function_flags, + union idptr *func, + unsigned INT16 opt_flags); int really_low_find_shared_string_identifier(struct pike_string *name, struct program *prog, int flags); @@ -460,14 +462,16 @@ char *get_line(unsigned char *pc,struct program *prog,INT32 *linep); void my_yyerror(char *fmt,...) ATTRIBUTE((format(printf,1,2))); struct program *compile(struct pike_string *prog, struct object *handler); -int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags); +int pike_add_function2(char *name, void (*cfun)(INT32), + char *type, unsigned INT8 flags, + unsigned INT16 opt_flags); PMOD_EXPORT int quick_add_function(char *name, - int name_length, - void (*cfun)(INT32), - char *type, - int type_length, - INT16 flags, - int opt_flags); + int name_length, + void (*cfun)(INT32), + char *type, + int type_length, + unsigned INT8 flags, + unsigned INT16 opt_flags); void check_all_programs(void); void init_program(void); void cleanup_program(void); @@ -499,11 +503,15 @@ int yyexplain_not_implements(struct program *a, struct program *b, int flags); void *parent_storage(int depth); /* Prototypes end here */ -#define ADD_FUNCTION(NAME,FUNC,TYPE,FLAGS) \ - quick_add_function(NAME,CONSTANT_STRLEN(NAME),FUNC,TYPE,CONSTANT_STRLEN(TYPE),FLAGS,0) +#define ADD_FUNCTION(NAME, FUNC, TYPE, FLAGS) \ + quick_add_function(NAME, CONSTANT_STRLEN(NAME), FUNC, TYPE,\ + CONSTANT_STRLEN(TYPE), FLAGS, \ + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND) -#define ADD_PROTOTYPE(NAME,TYPE,FLAGS) \ - quick_add_function(NAME,CONSTANT_STRLEN(NAME),0,TYPE,CONSTANT_STRLEN(TYPE),FLAGS,0) +#define ADD_PROTOTYPE(NAME, TYPE, FLAGS) \ + quick_add_function(NAME, CONSTANT_STRLEN(NAME), 0, TYPE, \ + CONSTANT_STRLEN(TYPE), FLAGS, \ + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND) #define ADD_INT_CONSTANT(NAME,CONST,FLAGS) \ quick_add_integer_constant(NAME,CONSTANT_STRLEN(NAME),CONST,FLAGS) @@ -511,25 +519,31 @@ void *parent_storage(int depth); #define PIKE_MAP_VARIABLE(NAME,OFFSET,TYPE,RTTYPE,FLAGS) \ quick_map_variable(NAME,CONSTANT_STRLEN(NAME),OFFSET,TYPE,CONSTANT_STRLEN(TYPE),RTTYPE,FLAGS) -#define ADD_FUNCTION_DTYPE(NAME,FUN,DTYPE,FLAGS) do { \ - DTYPE_START; \ - {DTYPE} \ - { \ - struct pike_string *_t; \ - DTYPE_END(_t); \ - quick_add_function(NAME,CONSTANT_STRLEN(NAME),FUN,_t->str,_t->len,FLAGS,0); \ - free_string(_t); \ - } \ +#define ADD_FUNCTION_DTYPE(NAME,FUN,DTYPE,FLAGS) do { \ + DTYPE_START; \ + {DTYPE} \ + { \ + struct pike_string *_t; \ + DTYPE_END(_t); \ + quick_add_function(NAME, CONSTANT_STRLEN(NAME), FUN, \ + _t->str, _t->len, FLAGS, \ + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND); \ + free_string(_t); \ + } \ } while (0) +#define pike_add_function(NAME, CFUN, TYPE, FLAGS) \ + pike_add_function2(NAME, CFUN, TYPE, FLAGS, \ + OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND) + #ifndef NO_PIKE_SHORTHAND #define add_function pike_add_function #endif #define START_NEW_PROGRAM_ID(ID) do { \ - start_new_program(); \ - Pike_compiler->new_program->id=PIKE_CONCAT3(PROG_,ID,_ID); \ - }while(0) + start_new_program(); \ + Pike_compiler->new_program->id=PIKE_CONCAT3(PROG_,ID,_ID); \ + }while(0) #ifdef DEBUG_MALLOC #define end_program() ((struct program *)debug_malloc_pass(debug_end_program())) @@ -557,3 +571,11 @@ void *parent_storage(int depth); #endif /* PROGRAM_H */ + +/* Kludge... */ +#ifndef LAS_H +/* FIXME: Needed for the OPT_??? macros. + * Maybe they should be moved here, since las.h includes this file anyway? + */ +#include "las.h" +#endif /* !LAS_H */