diff --git a/src/docode.c b/src/docode.c index c6ca18ddf92c8207041865ae4f37e9e5584ac12e..558e3250245c2b423b950eda44edaf4aeec81a7b 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.128 2001/08/13 23:15:58 mast Exp $"); +RCSID("$Id: docode.c,v 1.129 2001/08/15 03:31:55 hubbe Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -426,15 +426,13 @@ static inline struct compiler_frame *find_local_frame(INT32 depth) int do_lfun_call(int id,node *args) { - emit0(F_MARK); - PUSH_CLEANUP_FRAME(do_pop_mark, 0); - do_docode(args,0); #if 1 if(id == Pike_compiler->compiler_frame->current_function_number) { int n=count_args(args); if(n == Pike_compiler->compiler_frame->num_args) { + do_docode(args,0); if(Pike_compiler->compiler_frame->is_inline) { Pike_compiler->compiler_frame->recur_label=do_jump(F_RECUR, @@ -444,13 +442,15 @@ int do_lfun_call(int id,node *args) Pike_compiler->compiler_frame->recur_label=do_jump(F_POINTER, Pike_compiler->compiler_frame->recur_label); } + return 1; } - else - emit1(F_CALL_LFUN, id); } - else #endif - emit1(F_CALL_LFUN, id); + + emit0(F_MARK); + PUSH_CLEANUP_FRAME(do_pop_mark, 0); + do_docode(args,0); + emit1(F_CALL_LFUN, id); POP_AND_DONT_CLEANUP; return 1; } diff --git a/src/interpret.c b/src/interpret.c index 0da244a59c022fe4802cad0ea849526c844f05a0..d67de37fa690e9bfec036bce9131b495fdbfa322 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.239 2001/08/03 17:45:10 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.240 2001/08/15 03:31:55 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -618,7 +618,6 @@ PMOD_EXPORT void find_external_context(struct external_variable_context *loc, )); } - #ifdef PIKE_DEBUG void print_return_value(void) { @@ -1035,7 +1034,7 @@ static void do_trace_call(INT32 args) }) \ if(X->flags & PIKE_FRAME_MALLOCED_LOCALS) \ { \ - free_svalues(X->locals,X->num_locals,BIT_MIXED); \ + free_mixed_svalues(X->locals,X->num_locals); \ free((char *)(X->locals)); \ } \ DO_IF_DMALLOC( \ @@ -1053,7 +1052,6 @@ static void do_trace_call(INT32 args) BLOCK_ALLOC(pike_frame,128) - int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) { struct object *o; @@ -1528,7 +1526,7 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) assign_svalue(save_sp,Pike_sp-1); pop_n_elems(Pike_sp-save_sp-1); - destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */ + low_destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */ } if(save_sp+1 > Pike_sp) @@ -1542,44 +1540,53 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) } -void low_return(void) -{ - struct svalue *save_sp=Pike_fp->save_sp; -#ifdef PIKE_DEBUG - if(Pike_mark_sp < Pike_fp->save_mark_sp) - fatal("Popped below save_mark_sp!\n"); - if(Pike_sp<Pike_interpreter.evaluator_stack) - fatal("Stack error (also simple).\n"); -#endif - Pike_mark_sp=Pike_fp->save_mark_sp; + +#define low_return_profiling() #ifdef PROFILING #ifdef HAVE_GETHRTIME - { - struct identifier *function; - long long time_passed, time_in_children, self_time; - time_in_children= Pike_interpreter.accounted_time - Pike_fp->children_base; - time_passed = gethrtime() - Pike_interpreter.time_base - Pike_fp->start_time; - self_time=time_passed - time_in_children; - Pike_interpreter.accounted_time+=self_time; - function = Pike_fp->context.prog->identifiers + Pike_fp->ident; - function->total_time=Pike_fp->self_time_base + (INT32)(time_passed /1000); - function->self_time+=(INT32)( self_time /1000); - } +#undef low_return_profiling +#define low_return_profiling() do { \ + struct identifier *function; \ + long long time_passed, time_in_children, self_time; \ + time_in_children=Pike_interpreter.accounted_time-Pike_fp->children_base; \ + time_passed = gethrtime()-Pike_interpreter.time_base - Pike_fp->start_time; \ + self_time=time_passed - time_in_children; \ + Pike_interpreter.accounted_time+=self_time; \ + function = Pike_fp->context.prog->identifiers + Pike_fp->ident; \ + function->total_time=Pike_fp->self_time_base + (INT32)(time_passed /1000); \ + function->self_time+=(INT32)( self_time /1000); \ +}while(0) #endif #endif - POP_PIKE_FRAME(); +#define basic_low_return() \ + struct svalue *save_sp=Pike_fp->save_sp; \ + DO_IF_DEBUG( \ + if(Pike_mark_sp < Pike_fp->save_mark_sp) \ + fatal("Popped below save_mark_sp!\n"); \ + if(Pike_sp<Pike_interpreter.evaluator_stack) \ + fatal("Stack error (also simple).\n"); \ + ) \ + \ + Pike_mark_sp=Pike_fp->save_mark_sp; \ + \ + POP_PIKE_FRAME() + + +void low_return(void) +{ + basic_low_return(); if(save_sp+1 < Pike_sp) { assign_svalue(save_sp,Pike_sp-1); pop_n_elems(Pike_sp-save_sp-1); - destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */ + /* consider using a flag for immediate destruct instead... */ + destruct_objects_to_destruct(); } - - if(save_sp+1 > Pike_sp) + else if(save_sp+1 > Pike_sp) { push_int(0); }else{ @@ -1587,6 +1594,19 @@ void low_return(void) } } +void low_return_pop(void) +{ + basic_low_return(); + + if(save_sp < Pike_sp) + { + pop_n_elems(Pike_sp-save_sp); + /* consider using a flag for immediate destruct instead... */ + destruct_objects_to_destruct(); + } +} + + void unlink_previous_frame(void) { struct pike_frame *current, *prev; @@ -1681,7 +1701,7 @@ static int o_catch(PIKE_OPCODE_T *pc) UNSETJMP(tmp); Pike_fp->expendible=expendible; Pike_fp->flags=flags; - destruct_objects_to_destruct(); + low_destruct_objects_to_destruct(); return 0; }else{ struct svalue **save_mark_sp=Pike_mark_sp; diff --git a/src/interpret.h b/src/interpret.h index f3adb957c70dab9206cc5a2a7df6806ac7ec6c00..fe5d4fa9bc7eb4331db42366a1d39fc52257891d 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: interpret.h,v 1.95 2001/08/13 23:31:03 hubbe Exp $ + * $Id: interpret.h,v 1.96 2001/08/15 03:31:55 hubbe Exp $ */ #ifndef INTERPRET_H #define INTERPRET_H @@ -159,6 +159,7 @@ extern const char *Pike_check_c_stack_errmsg; #define pop_stack() do{ free_svalue(--Pike_sp); debug_check_stack(); }while(0) +#define pop_2_elems() do { pop_stack(); pop_stack(); }while(0) #ifdef __ECL #define MAYBE_CAST_TO_LONG(X) (X) @@ -171,7 +172,7 @@ extern const char *Pike_check_c_stack_errmsg; check__positive(x_, ("Popping negative number of args.... (%ld) \n", \ MAYBE_CAST_TO_LONG(x_))); \ Pike_sp -= x_; debug_check_stack(); \ - free_svalues(Pike_sp, x_, BIT_MIXED); \ + free_mixed_svalues(Pike_sp, x_); \ } } while (0) #define stack_pop_n_elems_keep_top(X) \ @@ -329,6 +330,7 @@ PMOD_EXPORT void find_external_context(struct external_variable_context *loc, int arg2); int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2); void low_return(void); +void low_return_pop(void); void unlink_previous_frame(void); void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2); PMOD_EXPORT void f_call_function(INT32 args); diff --git a/src/object.c b/src/object.c index 57af4442aab7d6fd85679b3be9400e08eea3f544..394f78a7fe5b88dc5b0139c1fcdfc63833849d1b 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.179 2001/07/13 11:26:39 grubba Exp $"); +RCSID("$Id: object.c,v 1.180 2001/08/15 03:31:55 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -749,7 +749,7 @@ static struct callback *destruct_object_evaluator_callback =0; * destructed by schedule_really_free_object. It links the object back into the * list of objects first. Adds a reference, destructs it and then frees it. */ -PMOD_EXPORT void destruct_objects_to_destruct(void) +void low_destruct_objects_to_destruct(void) { struct object *o, *next; @@ -784,7 +784,11 @@ PMOD_EXPORT void destruct_objects_to_destruct(void) free_object(o); } while ((o = next)); } +} +void destruct_objects_to_destruct_cb(void) +{ + low_destruct_objects_to_destruct(); if(destruct_object_evaluator_callback) { remove_callback(destruct_object_evaluator_callback); @@ -841,7 +845,7 @@ PMOD_EXPORT void schedule_really_free_object(struct object *o) { destruct_object_evaluator_callback= add_to_callback(&evaluator_callbacks, - (callback_func)destruct_objects_to_destruct, + (callback_func)destruct_objects_to_destruct_cb, 0,0); } } else { diff --git a/src/object.h b/src/object.h index 968e1faf4ab928d3fc6a53d93c2359288be09a71..bfb3b2c4f9c5f86cc6fc378273ed5874951f7277 100644 --- a/src/object.h +++ b/src/object.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: object.h,v 1.63 2001/07/12 23:15:41 hubbe Exp $ + * $Id: object.h,v 1.64 2001/08/15 03:31:55 hubbe Exp $ */ #ifndef OBJECT_H #define OBJECT_H @@ -55,11 +55,10 @@ extern struct program *magic_set_index_program; #include "block_alloc_h.h" /* Prototypes begin here */ BLOCK_ALLOC(object, 511) -PMOD_EXPORT struct program *get_program_for_object_being_destructed(struct object * o); PMOD_EXPORT struct object *low_clone(struct program *p); PMOD_EXPORT void call_c_initializers(struct object *o); -void call_prog_event(struct object *o,int event); -void call_pike_initializers(struct object *o, int); +void call_prog_event(struct object *o, int event); +void call_pike_initializers(struct object *o, int args); PMOD_EXPORT void do_free_object(struct object *o); PMOD_EXPORT struct object *debug_clone_object(struct program *p, int args); PMOD_EXPORT struct object *fast_clone_object(struct program *p, int args); @@ -72,9 +71,9 @@ PMOD_EXPORT struct object *get_master(void); PMOD_EXPORT struct object *debug_master(void); struct destroy_called_mark; PTR_HASH_ALLOC(destroy_called_mark,128) -static void call_destroy(struct object *o, int foo); -PMOD_EXPORT void destruct(struct object *o); -PMOD_EXPORT void destruct_objects_to_destruct(void); +PMOD_EXPORT struct program *get_program_for_object_being_destructed(struct object * o); +void destruct(struct object *o); +void low_destruct_objects_to_destruct(void); PMOD_EXPORT void schedule_really_free_object(struct object *o); PMOD_EXPORT void low_object_index_no_free(struct svalue *to, struct object *o, @@ -137,6 +136,7 @@ void check_all_objects(void); #define PIKE_OBJ_DESTRUCTED(o) (o->prog) #define PIKE_OBJ_INITED(o) (o->prog && (o->prog->flags & PROGRAM_PASS_1_DONE)) +#define destruct_objects_to_destruct() do{ if(objects_to_destruct) low_destruct_objects_to_destruct(); }while(0) #endif /* OBJECT_H */ diff --git a/src/svalue.c b/src/svalue.c index fc601d04317fa9a7a823fc1c44de1e5d8e48e621..ca428b118ced46259c92f1eb152b81c1ed578c71 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.115 2001/08/13 23:32:36 hubbe Exp $"); +RCSID("$Id: svalue.c,v 1.116 2001/08/15 03:31:55 hubbe Exp $"); struct svalue dest_ob_zero = { T_INT, 0, @@ -300,6 +300,19 @@ PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hin } } +PMOD_EXPORT void debug_free_mixed_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS) +{ + while(num--) + { +#ifdef DEBUG_MALLOC + if(s->type <= MAX_REF_TYPE) + debug_malloc_update_location(s->u.refs DMALLOC_PROXY_ARGS); +#endif + free_svalue(s++); + } +} + + PMOD_EXPORT void assign_svalues_no_free(struct svalue *to, const struct svalue *from, size_t num, @@ -345,7 +358,7 @@ PMOD_EXPORT void assign_svalues(struct svalue *to, size_t num, TYPE_FIELD types) { - free_svalues(to,num,BIT_MIXED); + free_mixed_svalues(to,num); assign_svalues_no_free(to,from,num,types); } @@ -833,52 +846,6 @@ PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b) safe_check_destructed(a); safe_check_destructed(b); - if (((a->type == T_TYPE) || - (a->type == T_FUNCTION) || (a->type == T_PROGRAM)) && - ((b->type == T_FUNCTION) || - (b->type == T_PROGRAM) || (b->type == T_TYPE))) { - if (a->type != T_TYPE) { - /* Try converting a to a program, and then to a type. */ - struct svalue aa; - int res; - aa.u.program = program_from_svalue(a); - if (!aa.u.program) { - Pike_error("Bad argument to comparison."); - } - type_stack_mark(); - push_object_type(0, aa.u.program->id); - aa.u.type = pop_unfinished_type(); - aa.type = T_TYPE; - res = is_lt(&aa, b); - free_type(aa.u.type); - return res; - } - if (b->type != T_TYPE) { - /* Try converting b to a program, and then to a type. */ - struct svalue bb; - int res; - bb.u.program = program_from_svalue(b); - if (!bb.u.program) { - Pike_error("Bad argument to comparison."); - } - type_stack_mark(); - push_object_type(0, bb.u.program->id); - bb.u.type = pop_unfinished_type(); - bb.type = T_TYPE; - res = is_lt(a, &bb); - free_type(bb.u.type); - return res; - } - - /* At this point both a and b have type T_TYPE */ -#ifdef PIKE_DEBUG - if ((a->type != T_TYPE) || (b->type != T_TYPE)) { - fatal("Unexpected types in comparison.\n"); - } -#endif /* PIKE_DEBUG */ - return !pike_types_le(b->u.type, a->u.type); - } - if (a->type != b->type) { if(a->type == T_FLOAT && b->type==T_INT) @@ -895,6 +862,12 @@ PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b) return (FLOAT_TYPE)a->u.integer < b->u.float_number; #endif + if (((a->type == T_TYPE) || + (a->type == T_FUNCTION) || (a->type == T_PROGRAM)) && + ((b->type == T_FUNCTION) || + (b->type == T_PROGRAM) || (b->type == T_TYPE))) + goto compare_types; + if(a->type == T_OBJECT) { a_is_object: @@ -949,28 +922,74 @@ PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b) } switch(a->type) { - case T_OBJECT: - goto a_is_object; - - default: - Pike_error("Bad type to comparison.\n"); - - case T_INT: - return a->u.integer < b->u.integer; - - case T_STRING: - return my_strcmp(a->u.string, b->u.string) < 0; - - case T_FLOAT: + case T_OBJECT: + goto a_is_object; + + default: + Pike_error("Bad type to comparison.\n"); + + case T_INT: + return a->u.integer < b->u.integer; + + case T_STRING: + return my_strcmp(a->u.string, b->u.string) < 0; + + case T_FLOAT: #ifdef HAVE_ISLESS - return isless(a->u.float_number, b->u.float_number); + return isless(a->u.float_number, b->u.float_number); #else - if (PIKE_ISNAN(a->u.float_number) || PIKE_ISNAN(b->u.float_number)) { - return 0; - } - return a->u.float_number < b->u.float_number; + if (PIKE_ISNAN(a->u.float_number) || PIKE_ISNAN(b->u.float_number)) { + return 0; + } + return a->u.float_number < b->u.float_number; #endif + + case T_PROGRAM: + case T_FUNCTION: + compare_types: + if (a->type != T_TYPE) { + /* Try converting a to a program, and then to a type. */ + struct svalue aa; + int res; + aa.u.program = program_from_svalue(a); + if (!aa.u.program) { + Pike_error("Bad argument to comparison."); + } + type_stack_mark(); + push_object_type(0, aa.u.program->id); + aa.u.type = pop_unfinished_type(); + aa.type = T_TYPE; + res = is_lt(&aa, b); + free_type(aa.u.type); + return res; + } + if (b->type != T_TYPE) { + /* Try converting b to a program, and then to a type. */ + struct svalue bb; + int res; + bb.u.program = program_from_svalue(b); + if (!bb.u.program) { + Pike_error("Bad argument to comparison."); + } + type_stack_mark(); + push_object_type(0, bb.u.program->id); + bb.u.type = pop_unfinished_type(); + bb.type = T_TYPE; + res = is_lt(a, &bb); + free_type(bb.u.type); + return res; + } + + /* At this point both a and b have type T_TYPE */ +#ifdef PIKE_DEBUG + if ((a->type != T_TYPE) || (b->type != T_TYPE)) { + fatal("Unexpected types in comparison.\n"); + } +#endif /* PIKE_DEBUG */ + /* fall through */ + case T_TYPE: + return !pike_types_le(b->u.type, a->u.type); } } @@ -1259,28 +1278,6 @@ PMOD_EXPORT void print_svalue (FILE *out, const struct svalue *s) free (str.str); } -/* NOTE: Must handle num being negative. */ -PMOD_EXPORT void clear_svalues(struct svalue *s, ptrdiff_t num) -{ - struct svalue dum; - dum.type=T_INT; - dum.subtype=NUMBER_NUMBER; - dum.u.refs=0; - dum.u.integer=0; - while(num-- > 0) *(s++)=dum; -} - -/* NOTE: Must handle num being negative. */ -PMOD_EXPORT void clear_svalues_undefined(struct svalue *s, ptrdiff_t num) -{ - struct svalue dum; - dum.type=T_INT; - dum.subtype=NUMBER_UNDEFINED; - dum.u.refs=0; - dum.u.integer=0; - while(num-- > 0) *(s++)=dum; -} - PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to, const struct svalue *from, size_t num, diff --git a/src/svalue.h b/src/svalue.h index ce9c794f6f06695e62f4dc4f31ca3ed27a79d836..76770d821609b549e103c9b644aaf506c656b366 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.94 2001/08/13 22:41:17 mast Exp $ + * $Id: svalue.h,v 1.95 2001/08/15 03:31:56 hubbe Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -430,12 +430,36 @@ static inline union anything *dmalloc_check_union(union anything *u,int type, ch extern struct svalue dest_ob_zero; +#define free_mixed_svalues(X,Y) do { \ + struct svalue *s_=(X); \ + ptrdiff_t num_=(Y); \ + while(num_--) \ + { \ + dmalloc_touch_svalue(s_); \ + free_svalue(s_++); \ + } \ +}while(0); + #ifdef DEBUG_MALLOC -#define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z), DMALLOC_LOCATION()) +#define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z), DMALLOC_LOCATION()); #else -#define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z)) +#define free_svalues(X,Y,Z) debug_free_svalues((X),(Y),(Z)); #endif +#define low_clear_svalues(X,Y,N) do { \ + struct svalue *s_=(X); \ + ptrdiff_t num_=(Y); \ + for(;num_-- > 0;s_++) \ + { \ + s_->type=PIKE_T_INT; \ + s_->subtype=(N); \ + s_->u.integer=0; \ + } \ +}while(0) + +#define clear_svalues(X,Y) low_clear_svalues((X),(Y),NUMBER_NUMBER) +#define clear_svalues_undefined(X,Y) low_clear_svalues((X),(Y),NUMBER_UNDEFINED) + /* Prototypes begin here */ PMOD_EXPORT void really_free_short_svalue(union anything *s, TYPE_T type); PMOD_EXPORT void really_free_svalue(struct svalue *s); @@ -479,8 +503,6 @@ PMOD_EXPORT int is_equal(const struct svalue *a, const struct svalue *b); PMOD_EXPORT int is_lt(const struct svalue *a, const struct svalue *b); PMOD_EXPORT void describe_svalue(const struct svalue *s,int indent,struct processing *p); PMOD_EXPORT void print_svalue (FILE *out, const struct svalue *s); -PMOD_EXPORT void clear_svalues(struct svalue *s, ptrdiff_t num); -PMOD_EXPORT void clear_svalues_undefined(struct svalue *s, ptrdiff_t num); PMOD_EXPORT void copy_svalues_recursively_no_free(struct svalue *to, const struct svalue *from, size_t num,