diff --git a/src/array.c b/src/array.c index f87188cb349759dd4468b7a0238fa3d087b321ec..b29321892933743ad32d383e98fba4b1d3aaa849 100644 --- a/src/array.c +++ b/src/array.c @@ -23,7 +23,7 @@ #include "stuff.h" #include "bignum.h" -RCSID("$Id: array.c,v 1.118 2001/09/24 14:21:10 grubba Exp $"); +RCSID("$Id: array.c,v 1.119 2001/09/25 05:55:09 hubbe Exp $"); PMOD_EXPORT struct array empty_array= { @@ -1582,31 +1582,14 @@ PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b) } } -int check_that_array_is_constant(struct array *a) +int array_is_constant(struct array *a, + struct processing *p) { array_fix_type_field(a); - if(a->type_field & (BIT_FUNCTION | BIT_OBJECT)) - { - int e; - for(e=0;e<a->size;e++) - { - switch(ITEM(a)[e].type) - { - case T_FUNCTION: - if(ITEM(a)[e].subtype == FUNCTION_BUILTIN) continue; - /* Fall through */ - case T_OBJECT: - if(ITEM(a)[e].u.object -> next == ITEM(a)[e].u.object) - { - /* This is a fake object used during the - * compilation! - */ - return 0; - } - } - } - } - return 1; + return svalues_are_constant(ITEM(a), + a->size, + a->type_field, + p); } node *make_node_from_array(struct array *a) @@ -1666,7 +1649,7 @@ node *make_node_from_array(struct array *a) mksvaluenode(ITEM(a)))); } - if(check_that_array_is_constant(a)) + if(array_is_constant(a,0)) { debug_malloc_touch(a); s.type=T_ARRAY; diff --git a/src/array.h b/src/array.h index 3985501645dcee860eb6a4b87458be8378ad6679..49c40523bc7966617363051f035c9d02ecf0278c 100644 --- a/src/array.h +++ b/src/array.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: array.h,v 1.37 2001/08/31 06:53:36 hubbe Exp $ + * $Id: array.h,v 1.38 2001/09/25 05:55:10 hubbe Exp $ */ #ifndef ARRAY_H #define ARRAY_H @@ -96,7 +96,6 @@ PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index); PMOD_EXPORT void simple_array_index_no_free(struct svalue *s, struct array *a,struct svalue *ind); PMOD_EXPORT void array_free_index(struct array *v,INT32 index); -PMOD_EXPORT void array_set_index(struct array *v,INT32 index, struct svalue *s); PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s); PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 index); PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size); @@ -113,7 +112,7 @@ PMOD_EXPORT struct array *copy_array(struct array *v); PMOD_EXPORT void check_array_for_destruct(struct array *v); PMOD_EXPORT INT32 array_find_destructed_object(struct array *v); INT32 *get_order(struct array *v, cmpfun fun); -int set_svalue_cmpfun(const struct svalue *a, const struct svalue *b); +INLINE int set_svalue_cmpfun(const struct svalue *a, const struct svalue *b); PMOD_EXPORT void sort_array_destructively(struct array *v); PMOD_EXPORT INT32 *get_set_order(struct array *a); PMOD_EXPORT INT32 *get_switch_order(struct array *a); @@ -135,14 +134,16 @@ INT32 * merge(struct array *a,struct array *b,INT32 opcode); PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper); PMOD_EXPORT struct array *add_arrays(struct svalue *argp, INT32 args); PMOD_EXPORT int array_equal_p(struct array *a, struct array *b, struct processing *p); -PMOD_EXPORT struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op); +PMOD_EXPORT struct array *merge_array_with_order(struct array *a, + struct array *b, INT32 op); PMOD_EXPORT struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op); PMOD_EXPORT struct array *merge_array_without_order(struct array *a, struct array *b, INT32 op); PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b); PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b); -int check_that_array_is_constant(struct array *a); +int array_is_constant(struct array *a, + struct processing *p); node *make_node_from_array(struct array *a); PMOD_EXPORT void push_array_items(struct array *a); void describe_array_low(struct array *a, struct processing *p, int indent); @@ -160,7 +161,7 @@ PMOD_EXPORT struct pike_string *implode(struct array *a,struct pike_string *del) PMOD_EXPORT struct array *copy_array_recursively(struct array *a,struct processing *p); PMOD_EXPORT void apply_array(struct array *a, INT32 args); PMOD_EXPORT struct array *reverse_array(struct array *a); -PMOD_EXPORT void array_replace(struct array *a, +void array_replace(struct array *a, struct svalue *from, struct svalue *to); PMOD_EXPORT void check_array(struct array *a); diff --git a/src/mapping.c b/src/mapping.c index 543a66ec578971f711ed5e60dfc2e6d22593de70..723c68c2d417b80c59acc36afd0dbf25e2ba85ca 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: mapping.c,v 1.137 2001/09/24 14:44:47 grubba Exp $"); +RCSID("$Id: mapping.c,v 1.138 2001/09/25 05:55:10 hubbe Exp $"); #include "main.h" #include "object.h" #include "mapping.h" @@ -1726,7 +1726,7 @@ node *make_node_from_mapping(struct mapping *m) mapping_fix_type_field(m); - if((m->data->ind_types | m->data->val_types) & (BIT_FUNCTION | BIT_OBJECT)) + if(!mapping_is_constant(m,0)) { struct array *ind, *val; node *n; @@ -2457,3 +2457,24 @@ void zap_all_mappings(void) } } +int mapping_is_constant(struct mapping *m, + struct processing *p) +{ + INT32 e; + struct keypair *k; + struct mapping_data *md=m->data; + + if( (md->ind_types | md->val_types) & ~(BIT_INT|BIT_FLOAT|BIT_STRING)) + { + md->valrefs++; + add_ref(md); + NEW_MAPPING_LOOP(md) + { + if(!svalues_are_constant(&k->ind, 1, md->ind_types, p)) return 0; + if(!svalues_are_constant(&k->val, 1, md->val_types, p)) return 0; + } + md->valrefs--; + free_mapping_data(md); + } + return 1; +} diff --git a/src/mapping.h b/src/mapping.h index 6b8158755eec58a824bbcbfb84bf270c98e11c3a..03be4c631659e1f2f86950e206fca250c29bab2d 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: mapping.h,v 1.39 2001/06/30 17:50:36 mast Exp $ + * $Id: mapping.h,v 1.40 2001/09/25 05:55:11 hubbe Exp $ */ #ifndef MAPPING_H #define MAPPING_H @@ -95,6 +95,12 @@ PMOD_PROTO void really_free_mapping(struct mapping *md); /* Prototypes begin here */ BLOCK_ALLOC(mapping, 511) + + + + + +static void check_mapping_type_fields(struct mapping *m); PMOD_EXPORT struct mapping *debug_allocate_mapping(int size); PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md); PMOD_EXPORT void do_free_mapping(struct mapping *m); @@ -154,10 +160,9 @@ PMOD_EXPORT struct mapping *add_mappings(struct svalue *argp, INT32 args); PMOD_EXPORT int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p); void describe_mapping(struct mapping *m,struct processing *p,int indent); node *make_node_from_mapping(struct mapping *m); -PMOD_EXPORT void f_m_delete(INT32 args); PMOD_EXPORT void f_aggregate_mapping(INT32 args); PMOD_EXPORT struct mapping *copy_mapping_recursively(struct mapping *m, - struct processing *p); + struct processing *p); PMOD_EXPORT void mapping_search_no_free(struct svalue *to, struct mapping *m, struct svalue *look_for, @@ -165,16 +170,18 @@ PMOD_EXPORT void mapping_search_no_free(struct svalue *to, void check_mapping(struct mapping *m); void check_all_mappings(void); void gc_mark_mapping_as_referenced(struct mapping *m); +void real_gc_cycle_check_mapping(struct mapping *m, int weak); unsigned gc_touch_all_mappings(void); void gc_check_all_mappings(void); void gc_mark_all_mappings(void); -void real_gc_cycle_check_mapping(struct mapping *m, int weak); void gc_cycle_check_all_mappings(void); void gc_zap_ext_weak_refs_in_mappings(void); void gc_free_all_unreferenced_mappings(void); void simple_describe_mapping(struct mapping *m); void debug_dump_mapping(struct mapping *m); void zap_all_mappings(void); +int mapping_is_constant(struct mapping *m, + struct processing *p); /* Prototypes end here */ #define allocate_mapping(X) dmalloc_touch(struct mapping *,debug_allocate_mapping(X)) diff --git a/src/multiset.c b/src/multiset.c index 04e3113ddaf20ea78bda1cfbd865a50c70eb7094..8588c2dbb04348c0cf842d19f8eebb4d5ab03a93 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -17,7 +17,7 @@ #include "gc.h" #include "security.h" -RCSID("$Id: multiset.c,v 1.38 2001/09/24 14:38:52 grubba Exp $"); +RCSID("$Id: multiset.c,v 1.39 2001/09/25 05:55:11 hubbe Exp $"); struct multiset *first_multiset; @@ -275,7 +275,7 @@ void describe_multiset(struct multiset *l,struct processing *p,int indent) node * make_node_from_multiset(struct multiset *l) { - if(check_that_array_is_constant(l->ind)) + if(multiset_is_constant(l,0)) { struct svalue s; s.type=T_MULTISET; @@ -438,3 +438,10 @@ void count_memory_in_multisets(INT32 *num_, INT32 *size_) *size_=size; } +int multiset_is_constant(struct multiset *m, + struct processing *p) +{ + return array_is_constant(m->ind, p); +} + + diff --git a/src/multiset.h b/src/multiset.h index 42ce9f6a82a6a0d64224ed691acc27820cb1afc0..48bdca8841cec242d9803f5fc530491f212018e9 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: multiset.h,v 1.18 2001/04/07 07:38:24 hubbe Exp $ + * $Id: multiset.h,v 1.19 2001/09/25 05:55:12 hubbe Exp $ */ #ifndef MULTISET_H #define MULTISET_H @@ -35,9 +35,9 @@ PMOD_EXPORT void do_free_multiset(struct multiset *l); PMOD_EXPORT void order_multiset(struct multiset *l); PMOD_EXPORT struct multiset *mkmultiset(struct array *ind); PMOD_EXPORT void multiset_insert(struct multiset *l, - struct svalue *ind); + struct svalue *v); struct array *multiset_indices(struct multiset *l); -PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *ind); +PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *v); PMOD_EXPORT void check_multiset_for_destruct(struct multiset *l); PMOD_EXPORT struct multiset *copy_multiset(struct multiset *tmp); PMOD_EXPORT struct multiset *merge_multisets(struct multiset *a, @@ -51,13 +51,15 @@ PMOD_EXPORT void f_aggregate_multiset(INT32 args); struct multiset *copy_multiset_recursively(struct multiset *l, struct processing *p); void gc_mark_multiset_as_referenced(struct multiset *l); +void real_gc_cycle_check_multiset(struct multiset *l, int weak); unsigned gc_touch_all_multisets(void); void gc_check_all_multisets(void); void gc_mark_all_multisets(void); -void real_gc_cycle_check_multiset(struct multiset *l, int weak); void gc_cycle_check_all_multisets(void); void gc_free_all_unreferenced_multisets(void); void count_memory_in_multisets(INT32 *num_, INT32 *size_); +int multiset_is_constant(struct multiset *m, + struct processing *p); /* Prototypes end here */ #define gc_cycle_check_multiset(X, WEAK) \ diff --git a/src/program.c b/src/program.c index aff13e32b48f89638a6037d55e39baafc60e1fd7..78ab12a1624de592dba6ffc23657bfeb3733e366 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.372 2001/09/24 16:42:48 grubba Exp $"); +RCSID("$Id: program.c,v 1.373 2001/09/25 05:55:12 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -3151,20 +3151,49 @@ PMOD_EXPORT int add_constant(struct pike_string *name, fatal("define_constant on nonshared string.\n"); #endif - n = isidentifier(name); + do { + if(c && + c->type == T_FUNCTION && + c->subtype != FUNCTION_BUILTIN && + c->u.object->prog) + { + struct identifier *id=ID_FROM_INT(c->u.object->prog, c->subtype); + if(c->u.object->prog == Pike_compiler->new_program) + { + if(id->identifier_flags & IDENTIFIER_FUNCTION) + { + return define_function(name, + id->type, + flags, + id->identifier_flags | IDENTIFIER_ALIAS, + & id->func, + id->opt_flags); + + } + else if(id->identifier_flags & IDENTIFIER_CONSTANT && + id->func.offset != -1) + { + c=& Pike_compiler->new_program->constants[id->func.offset].sval; + } + } + else + { + if(id->identifier_flags & IDENTIFIER_CONSTANT) + { + /* In this one case we allow fake objects to enter the + * mainstream... + */ + break; + } + } + } + + if(c && !svalues_are_constant(c,1,BIT_MIXED,0)) + yyerror("Constant values may not references this_object()"); + + }while(0); - /* - * FIXME: - * No constants should be allowed to contain - * any fake objects. (Fake objects can be - * detected thus: fake_ob->next == fake_ob - * - * I would prefer to find a way to detect - * this without recursing through arrays, - * mapping etc. etc. - * - * /Hubbe - */ + n = isidentifier(name); if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE) { diff --git a/src/svalue.c b/src/svalue.c index 426b26d7ba3dd1f95461bcdf25f26b468951e3b0..c0fea0b7469b9c15582ea5df34f602ac22c90fec 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -62,7 +62,7 @@ static int pike_isnan(double x) #endif /* HAVE__ISNAN */ #endif /* HAVE_ISNAN */ -RCSID("$Id: svalue.c,v 1.124 2001/09/24 16:49:20 grubba Exp $"); +RCSID("$Id: svalue.c,v 1.125 2001/09/25 05:55:13 hubbe Exp $"); struct svalue dest_ob_zero = { T_INT, 0, @@ -546,7 +546,7 @@ PMOD_EXPORT int svalue_is_true(const struct svalue *s) if(!s->u.object->prog) return 0; if (s->u.object->prog == pike_trampoline_program) { /* Trampoline */ - struct pike_trampoline *tramp = + struct pike_trampoline *tramp = (struct pike_trampoline *) get_storage(s->u.object, pike_trampoline_program); if (!tramp || !tramp->frame || !tramp->frame->current_object || !tramp->frame->current_object->prog) { @@ -1842,3 +1842,65 @@ PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s) return 0; /* make apcc happy */ } } + +int svalues_are_constant(struct svalue *s, + INT32 num, + TYPE_FIELD hint, + struct processing *p) +{ + if(hint & ~(BIT_STRING | BIT_INT | BIT_FLOAT)) + { + INT32 e; + for(e=0;e<num;e++) + { + switch(s->type) + { + case T_ARRAY: + case T_MAPPING: + case T_MULTISET: + { + struct processing curr; + curr.pointer_a = s->u.refs; + curr.next = p; + + for( ;p ;p=p->next) + if(p->pointer_a == (void *)s->u.refs) + return 1; + + switch(s->type) + { + case T_ARRAY: + if(!array_is_constant(s->u.array,&curr)) + return 0; + break; + + case T_MAPPING: + if(!mapping_is_constant(s->u.mapping,&curr)) + return 0; + break; + + case T_MULTISET: + if(!multiset_is_constant(s->u.multiset,&curr)) + return 0; + break; + } + } + + case T_FUNCTION: + if(s->subtype == FUNCTION_BUILTIN) continue; + /* Fall through */ + + case T_OBJECT: + if(s->u.object -> next == s->u.object) + { + /* This is a fake object used during the + * compilation! + */ + return 0; + } + } + s++; + } + } + return 1; +} diff --git a/src/svalue.h b/src/svalue.h index 6e3fc143afc9394fc7b7ecba2536b47268746c4a..8f4d99198fbfd4ee4541c8033191166d0a0044a8 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.96 2001/08/20 18:06:55 mast Exp $ + * $Id: svalue.h,v 1.97 2001/09/25 05:55:13 hubbe Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -468,6 +468,7 @@ PMOD_EXPORT void really_free_short_svalue(union anything *s, TYPE_T type); PMOD_EXPORT void really_free_svalue(struct svalue *s); PMOD_EXPORT void do_free_svalue(struct svalue *s); PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS); +PMOD_EXPORT void debug_free_mixed_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS); PMOD_EXPORT void assign_svalues_no_free(struct svalue *to, const struct svalue *from, size_t num, @@ -527,13 +528,18 @@ PMOD_EXPORT TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num) TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num); PMOD_EXPORT int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type); int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type); -#define gc_cycle_check_without_recurse gc_mark_without_recurse -#define gc_cycle_check_weak_without_recurse gc_mark_without_recurse void real_gc_free_svalue(struct svalue *s); void real_gc_free_short_svalue(union anything *u, TYPE_T type); PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s); +int svalues_are_constant(struct svalue *s, + INT32 num, + TYPE_FIELD hint, + struct processing *p); /* Prototypes end here */ +#define gc_cycle_check_without_recurse gc_mark_without_recurse +#define gc_cycle_check_weak_without_recurse gc_mark_without_recurse + #define gc_xmark_svalues(S,N) real_gc_xmark_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N) #define gc_check_svalues(S,N) real_gc_check_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N) #define gc_check_short_svalue(U,T) real_gc_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T)