From d9a93b6e559f2ea0acf1a51ed8670937ed53e51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sun, 1 Jul 2001 21:09:50 -0700 Subject: [PATCH] more debug, more optimizations, new efuns: int2char, basetype new opcodes: F_CALL_BUILTIN1, F_CALL_BUILTIN1_AND_POP, F_BRANCH_IF_TYPE_IS_NOT Rev: src/builtin.cmod:1.53 Rev: src/builtin_functions.c:1.388 Rev: src/constants.c:1.31 Rev: src/constants.h:1.18 Rev: src/docode.c:1.124 Rev: src/interpret.c:1.211 Rev: src/interpret_functions.h:1.66 Rev: src/lex.c:1.91 Rev: src/modules/sprintf/sprintf.c:1.79 Rev: src/peep.c:1.49 Rev: src/peep.in:1.56 --- src/builtin.cmod | 102 +++++++++++++++++++++++++++++++++- src/builtin_functions.c | 35 ++++-------- src/constants.c | 23 +++++++- src/constants.h | 4 +- src/docode.c | 27 ++++++--- src/interpret.c | 3 +- src/interpret_functions.h | 39 ++++++++++++- src/lex.c | 5 +- src/modules/sprintf/sprintf.c | 44 ++++++++++++++- src/peep.c | 10 ++-- src/peep.in | 16 +++++- 11 files changed, 260 insertions(+), 48 deletions(-) diff --git a/src/builtin.cmod b/src/builtin.cmod index a570fbe277..d42372d8b0 100644 --- a/src/builtin.cmod +++ b/src/builtin.cmod @@ -1,5 +1,5 @@ /* -*- c -*- - * $Id: builtin.cmod,v 1.52 2001/07/01 15:39:16 grubba Exp $ + * $Id: builtin.cmod,v 1.53 2001/07/02 04:09:46 hubbe Exp $ */ #include "global.h" @@ -28,6 +28,106 @@ #include "builtin_functions.h" #include "fsort.h" + +/*! @decl string basetype(mixed x) + *! + *! Same as sprintf("%t",x); + *! + *! @seealso + *! @[sprintf()] + */ +PIKEFUN string basetype(mixed x) + efun; + optflags OPT_TRY_OPTIMIZE; +{ + int t=x->type; + if(x->type == T_OBJECT && x->u.object->prog) + { + ptrdiff_t fun=FIND_LFUN(x->u.object->prog, LFUN__SPRINTF); + if(fun != -1) + { + push_int('t'); + f_aggregate_mapping(0); + apply_low(x->u.object, fun, 2); + if(Pike_sp[-1].type == T_STRING) + { + stack_swap(); + pop_stack(); + return; + } + error("Non-string returned from _sprintf()\n"); + } + } + pop_stack(); + switch(t) + { + case T_ARRAY: push_constant_text("array"); break; + case T_FLOAT: push_constant_text("float"); break; + case T_FUNCTION: push_constant_text("function"); break; + case T_INT: push_constant_text("int"); break; + case T_LVALUE: push_constant_text("lvalue"); break; + case T_MAPPING: push_constant_text("mapping"); break; + case T_MULTISET: push_constant_text("multiset"); break; + case T_OBJECT: push_constant_text("object"); break; + case T_PROGRAM: push_constant_text("program"); break; + case T_STRING: push_constant_text("string"); break; + case T_TYPE: push_constant_text("type"); break; + case T_ZERO: push_constant_text("zero"); break; + case T_VOID: push_constant_text("void"); break; + case T_MAPPING_DATA: push_constant_text("mapping_data"); break; + default: push_constant_text("unknown"); break; + } +} + + +/*! @decl string int2char(int x) + *! + *! Same as sprintf("%c",x); + *! + *! @seealso + *! @[sprintf()] + */ +PIKEFUN string int2char(int|object x) + efun; + optflags OPT_TRY_OPTIMIZE; +{ + int c; + if(x->type == T_OBJECT && x->u.object->prog) + { + ptrdiff_t fun=FIND_LFUN(x->u.object->prog, LFUN__SPRINTF); + if(fun != -1) + { + push_int('c'); + f_aggregate_mapping(0); + apply_low(x->u.object, fun, 2); + if(Pike_sp[-1].type == T_STRING) + { + stack_swap(); + pop_stack(); + return; + } + error("Non-string returned from _sprintf()\n"); + } + } + if(x->type != T_INT) + error("Bad argument 1 to int2char.\n"); + + c=x->u.integer; + + if(c>=0 && c<256) + { + struct pike_string *s; + s=begin_shared_string(1); + s->str[0]=c; + RETURN end_shared_string(s); + }else{ + struct string_builder tmp; + init_string_builder(&tmp,0); + string_builder_putchar(&tmp, c); + RETURN finish_string_builder(&tmp); + } +} + /*! @decl array column(array data, mixed index) *! *! Extract a column from a two-dimensional array. diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 34d7dc305e..aa59700f32 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.387 2001/06/29 10:47:37 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.388 2001/07/02 04:09:47 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -2050,6 +2050,14 @@ void f__exit(INT32 args) if(Pike_sp[-args].type != T_INT) SIMPLE_BAD_ARG_ERROR("_exit", 1, "int"); +#ifdef PIKE_DEBUG + { + /* This will allow -p to work with _exit -Hubbe */ + extern void exit_lex(void); + exit_lex(); + } +#endif + exit(Pike_sp[-args].u.integer); } @@ -3506,10 +3514,6 @@ void f_gc(INT32 args) #undef TYPEP #endif -#ifdef AUTO_BIGNUM -/* This should probably be here whether AUTO_BIGNUM is defined or not, - * but it can wait a little. /Hubbe - */ #define TYPEP(ID,NAME,TYPE,TYPE_NAME) \ PMOD_EXPORT void ID(INT32 args) \ @@ -3532,17 +3536,6 @@ PMOD_EXPORT void ID(INT32 args) \ pop_n_elems(args); \ push_int(t); \ } -#else -#define TYPEP(ID,NAME,TYPE) \ -void ID(INT32 args) \ -{ \ - int t; \ - if(args<1) SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 1); \ - t=Pike_sp[-args].type == TYPE; \ - pop_n_elems(args); \ - push_int(t); \ -} -#endif /* AUTO_BIGNUM */ /*! @decl int programp(mixed arg) @@ -3632,21 +3625,13 @@ PMOD_EXPORT void f_programp(INT32 args) *! @[mappingp()], @[stringp()], @[functionp()] */ -#ifdef AUTO_BIGNUM + TYPEP(f_intp, "intp", T_INT, "int") TYPEP(f_mappingp, "mappingp", T_MAPPING, "mapping") TYPEP(f_arrayp, "arrayp", T_ARRAY, "array") TYPEP(f_multisetp, "multisetp", T_MULTISET, "multiset") TYPEP(f_stringp, "stringp", T_STRING, "string") TYPEP(f_floatp, "floatp", T_FLOAT, "float") -#else -TYPEP(f_intp, "intp", T_INT) -TYPEP(f_mappingp, "mappingp", T_MAPPING) -TYPEP(f_arrayp, "arrayp", T_ARRAY) -TYPEP(f_multisetp, "multisetp", T_MULTISET) -TYPEP(f_stringp, "stringp", T_STRING) -TYPEP(f_floatp, "floatp", T_FLOAT) -#endif /* AUTO_BIGNUM */ /*! @decl array sort(array(mixed) index, array(mixed) ... data) *! diff --git a/src/constants.c b/src/constants.c index 4defadce16..d076dc15e9 100644 --- a/src/constants.c +++ b/src/constants.c @@ -17,7 +17,7 @@ #include "security.h" #include "block_alloc.h" -RCSID("$Id: constants.c,v 1.30 2001/04/13 19:56:49 grubba Exp $"); +RCSID("$Id: constants.c,v 1.31 2001/07/02 04:09:47 hubbe Exp $"); struct mapping *builtin_constants = 0; @@ -69,6 +69,7 @@ PMOD_EXPORT void add_global_program(char *name, struct program *p) #define EXIT_BLOCK(X) do { \ free_type(X->type); \ free_string(X->name); \ + X->name=0; \ EXIT_PIKE_MEMOBJ(X); \ }while(0) BLOCK_ALLOC(callable,128) @@ -96,6 +97,8 @@ PMOD_EXPORT struct callable *low_make_callable(c_fun fun, if(!z) fatal("Gnapp!\n"); free_type(z); } + f->runs=0; + f->compiles=0; #endif return f; } @@ -168,6 +171,24 @@ PMOD_EXPORT struct callable *quick_add_efun(char *name, ptrdiff_t name_length, return ret; } +#ifdef PIKE_DEBUG +void present_constant_profiling(void) +{ + struct callable_block *b; + int e; + for(b=callable_blocks;b;b=b->next) + { + for(e=0;e<NELEM(b->x);e++) + { + if(b->x[e].name) + { + fprintf(stderr,"%010d @E@: %s\n",b->x[e].runs, b->x[e].name->str); + } + } + } +} +#endif + void cleanup_added_efuns(void) { #ifdef DO_PIKE_CLEANUP diff --git a/src/constants.h b/src/constants.h index 5bae6091a2..fffa9b3108 100644 --- a/src/constants.h +++ b/src/constants.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: constants.h,v 1.17 2001/04/07 07:38:24 hubbe Exp $ + * $Id: constants.h,v 1.18 2001/07/02 04:09:47 hubbe Exp $ */ #ifndef ADD_EFUN_H #define ADD_EFUN_H @@ -27,6 +27,8 @@ struct callable INT16 flags; #ifdef PIKE_DEBUG INT8 may_return_void; + long compiles; + long runs; #endif optimize_fun optimize; docode_fun docode; diff --git a/src/docode.c b/src/docode.c index fac76b113d..573831836d 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.123 2001/06/29 19:48:22 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.124 2001/07/02 04:09:48 hubbe Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -1159,14 +1159,23 @@ static int do_docode2(node *n, INT16 flags) if(!CAR(n)->u.sval.u.efun->docode || !CAR(n)->u.sval.u.efun->docode(n)) { - emit0(F_MARK); - PUSH_CLEANUP_FRAME(do_pop_mark, 0); - do_docode(CDR(n),0); - tmp1=store_constant(& CAR(n)->u.sval, - !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), - CAR(n)->name); - emit1(F_CALL_BUILTIN, DO_NOT_WARN((INT32)tmp1)); - POP_AND_DONT_CLEANUP; + if(count_args(CDR(n))==1) + { + do_docode(CDR(n),0); + tmp1=store_constant(& CAR(n)->u.sval, + !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), + CAR(n)->name); + emit1(F_CALL_BUILTIN1, DO_NOT_WARN((INT32)tmp1)); + }else{ + emit0(F_MARK); + PUSH_CLEANUP_FRAME(do_pop_mark, 0); + do_docode(CDR(n),0); + tmp1=store_constant(& CAR(n)->u.sval, + !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND), + CAR(n)->name); + emit1(F_CALL_BUILTIN, DO_NOT_WARN((INT32)tmp1)); + POP_AND_DONT_CLEANUP; + } } if(n->type == void_type_string) return 0; diff --git a/src/interpret.c b/src/interpret.c index 1f81d55d9c..1947a0e008 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.210 2001/07/01 22:29:41 mast Exp $"); +RCSID("$Id: interpret.c,v 1.211 2001/07/02 04:09:48 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -982,6 +982,7 @@ int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2) (*(s->u.efun->function))(args); #ifdef PIKE_DEBUG + s->u.efun->runs++; if(Pike_sp != expected_stack + !s->u.efun->may_return_void) { if(Pike_sp < expected_stack) diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 1c1ac074d5..984079e18a 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -1,5 +1,5 @@ /* - * $Id: interpret_functions.h,v 1.65 2001/06/29 19:48:49 hubbe Exp $ + * $Id: interpret_functions.h,v 1.66 2001/07/02 04:09:48 hubbe Exp $ * * Opcode definitions for the interpreter. */ @@ -862,6 +862,30 @@ OPCODE0_JUMP(F_BRANCH_WHEN_NON_ZERO,"branch if not zero") pop_stack(); BREAK +OPCODE1_JUMP(F_BRANCH_IF_TYPE_IS_NOT,"branch if type is !=") +/* fprintf(stderr,"******BRANCH IF TYPE IS NOT***** %s\n",get_name_of_type(arg1)); */ + if(Pike_sp[-1].type == T_OBJECT && + Pike_sp[-1].u.object->prog) + { + int fun=FIND_LFUN(Pike_sp[-1].u.object->prog, LFUN__IS_TYPE); + if(fun != -1) + { +/* fprintf(stderr,"******OBJECT OVERLOAD IN TYPEP***** %s\n",get_name_of_type(arg1)); */ + push_text(get_name_of_type(arg1)); + apply_low(Pike_sp[-2].u.object, fun, 1); + arg1=IS_ZERO(Pike_sp-1) ? T_FLOAT : T_OBJECT ; + pop_stack(); + } + } + if(Pike_sp[-1].type == arg1) + { + SKIPJUMP(); + }else{ + DOJUMP(); + } + pop_stack(); +BREAK + OPCODE1_JUMP(F_BRANCH_IF_LOCAL,"branch if local") if(IS_ZERO(Pike_fp->locals + arg1)) { @@ -1659,6 +1683,7 @@ MKAPPLY(OPCODE0,CALL_FUNCTION,"call function",APPLY_STACK, 0,0); do_trace_call(args); \ } \ (*(s->u.efun->function))(args); \ + s->u.efun->runs++; \ if(Pike_sp != expected_stack + !s->u.efun->may_return_void) \ { \ if(Pike_sp < expected_stack) \ @@ -1725,6 +1750,18 @@ OPCODE1(F_MARK_CALL_BUILTIN_AND_RETURN,"mark, call builtin & return") BREAK; +OPCODE1(F_CALL_BUILTIN1,"call builtin 1") +{ + DO_CALL_BUILTIN(1); +} +BREAK; + +OPCODE1(F_CALL_BUILTIN1_AND_POP,"call builtin1 & pop") +{ + DO_CALL_BUILTIN(1); + pop_stack(); +} +BREAK; /* Assume that the number of arguments is correct */ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded") diff --git a/src/lex.c b/src/lex.c index 091a161108..c6620d3abc 100644 --- a/src/lex.c +++ b/src/lex.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: lex.c,v 1.90 2001/06/29 18:19:30 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.91 2001/07/02 04:09:49 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -120,7 +120,10 @@ void exit_lex(void) #ifdef PIKE_DEBUG if(p_flag) { + extern void present_constant_profiling(void); int e; + present_constant_profiling(); + fprintf(stderr,"Opcode compiles: (opcode, compiled)\n"); for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++) { diff --git a/src/modules/sprintf/sprintf.c b/src/modules/sprintf/sprintf.c index 6e02b9b49e..1c5efeb277 100644 --- a/src/modules/sprintf/sprintf.c +++ b/src/modules/sprintf/sprintf.c @@ -103,7 +103,7 @@ */ #include "global.h" -RCSID("$Id: sprintf.c,v 1.78 2001/03/05 00:41:35 hubbe Exp $"); +RCSID("$Id: sprintf.c,v 1.79 2001/07/02 04:09:50 hubbe Exp $"); #include "pike_error.h" #include "array.h" #include "svalue.h" @@ -1474,6 +1474,7 @@ void f_sprintf(INT32 num_arg) Pike_error("Bad argument 1 to sprintf.\n"); } } +/* fprintf(stderr,"SPRINTF: %s\n",argp->u.string->str); */ init_string_builder(&r,0); SET_ONERROR(err_format_stack, free_sprintf_strings, &fs); @@ -1493,11 +1494,48 @@ void f_sprintf(INT32 num_arg) push_string(ret); } +static node *optimize_sprintf(node *n) +{ + node **arg0 = my_get_arg(&_CDR(n), 0); + node **arg1 = my_get_arg(&_CDR(n), 1); + node *ret; + int num_args=count_args(CDR(n)); + if(arg0 && arg1 && num_args == 2 && + (*arg0)->token == F_CONSTANT && + (*arg0)->u.sval.type == T_STRING && + (*arg0)->u.sval.u.string->size_shift == 0 && + (*arg0)->u.sval.u.string->len == 2 && + STR0((*arg0)->u.sval.u.string)[0]=='%') + { + switch(STR0((*arg0)->u.sval.u.string)[1]) + { + case 'c': + ADD_NODE_REF2(*arg1, + ret = mkefuncallnode("int2char",*arg1); + ); + return ret; + + case 't': + ADD_NODE_REF2(*arg1, + ret = mkefuncallnode("basetype",*arg1); + ); + return ret; + + default: break; + } + } + return 0; +} + void pike_module_init(void) { /* function(string|object, mixed ... : string) */ - ADD_EFUN("sprintf", f_sprintf, tFuncV(tOr(tStr, tObj), tMix, tStr), - OPT_TRY_OPTIMIZE); + ADD_EFUN2("sprintf", + f_sprintf, + tFuncV(tOr(tStr, tObj), tMix, tStr), + OPT_TRY_OPTIMIZE, + optimize_sprintf, + 0); } void pike_module_exit(void) diff --git a/src/peep.c b/src/peep.c index 68dac35ce1..127335c1ce 100644 --- a/src/peep.c +++ b/src/peep.c @@ -14,8 +14,10 @@ #include "stuff.h" #include "bignum.h" #include "opcodes.h" +#include "builtin_functions.h" +#include "constants.h" -RCSID("$Id: peep.c,v 1.48 2001/06/30 07:05:55 hubbe Exp $"); +RCSID("$Id: peep.c,v 1.49 2001/07/02 04:09:49 hubbe Exp $"); static void asm_opt(void); @@ -454,7 +456,7 @@ static INLINE ptrdiff_t insopt2(int f, INT32 a, INT32 b, #ifdef PIKE_DEBUG if(!hasarg2(f) && b) - fatal("hasarg(%d) is wrong!\n",f); + fatal("hasarg2(%d /*%s */) is wrong!\n",f,get_f_name(f)); #endif p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf); @@ -483,7 +485,7 @@ static INLINE ptrdiff_t insopt1(int f, INT32 a, int cl, struct pike_string *cf) { #ifdef PIKE_DEBUG if(!hasarg(f) && a) - fatal("hasarg(%d) is wrong!\n",f); + fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(f)); #endif return insopt2(f,a,0,cl, cf); @@ -493,7 +495,7 @@ static INLINE ptrdiff_t insopt0(int f, int cl, struct pike_string *cf) { #ifdef PIKE_DEBUG if(hasarg(f)) - fatal("hasarg(%d) is wrong!\n",f); + fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(f)); #endif return insopt2(f,0,0,cl, cf); } diff --git a/src/peep.in b/src/peep.in index 26dca99cca..7e4e175d3f 100644 --- a/src/peep.in +++ b/src/peep.in @@ -1,5 +1,5 @@ // -// $Id: peep.in,v 1.55 2001/06/29 19:48:49 hubbe Exp $ +// $Id: peep.in,v 1.56 2001/07/02 04:09:49 hubbe Exp $ // NOP : @@ -389,3 +389,17 @@ MKCALLOPTS(CALL_FUNCTION) MKCALLOPTS(CALL_LFUN) MKCALLOPTS(CALL_BUILTIN) +CALL_BUILTIN1 POP_VALUE : CALL_BUILTIN1_AND_POP ($1a) + +#define OPT_TYPEP(X,Y) \ + CALL_BUILTIN1 [ Pike_compiler->new_program->constants[$1a].sval.u.efun->function == X ] BRANCH_WHEN_ZERO : BRANCH_IF_TYPE_IS_NOT(Y) POINTER($2a); + +#if 1 +OPT_TYPEP(f_intp, T_INT) +OPT_TYPEP(f_stringp, T_STRING) +OPT_TYPEP(f_arrayp, T_ARRAY) +OPT_TYPEP(f_floatp, T_FLOAT) +OPT_TYPEP(f_mappingp, T_MAPPING) +OPT_TYPEP(f_multisetp, T_MULTISET) +#endif + -- GitLab