pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:2526:   /*! @class BacktraceFrame    */      PIKECLASS backtrace_frame   {    PIKEVAR mixed _fun flags ID_PROTECTED|ID_PRIVATE;   #ifdef PIKE_DEBUG    PIKEVAR program oprog flags ID_PROTECTED|ID_PRIVATE;   #endif    PIKEVAR array args; +  PIKEVAR array vars;    -  +  PIKEVAR array _var_names flags ID_PROTECTED|ID_PRIVATE; +  PIKEVAR array _var_types flags ID_PROTECTED|ID_PRIVATE; +     /* These are cleared when filename and lineno have been initialized    * from them. */    PIKEVAR program prog flags ID_PROTECTED|ID_PRIVATE;    CVAR PIKE_OPCODE_T *pc;       /* These two are considered to be uninitialized from prog, pc and    * fun as long as lineno == 0. */    CVAR struct pike_string *filename;    CVAR INT_TYPE lineno;   
pike.git/src/builtin.cmod:2588:    }       /*! @decl int(0..1) _is_type(string t)    *! This object claims to be an array for backward compatibility.    */    PIKEFUN int(0..1) _is_type(string t)    {    RETURN (t == literal_array_string);    }    -  static void fill_in_file_and_line() +  static void fill_in_file_and_line(int with_var_info)    {    struct pike_string *file = NULL; -  assert (THIS->lineno == 0); +  struct local_variable_info vars = { {0,}, {0, }, 0 }; +  assert ((THIS->lineno == 0) || with_var_info);       if (THIS->pc && THIS->prog) { -  file = low_get_line(THIS->pc, THIS->prog, &THIS->lineno, NULL); +  file = low_get_line(THIS->pc, THIS->prog, &THIS->lineno, +  with_var_info?&vars:NULL);    THIS->pc = NULL;    }    else if (TYPEOF(THIS->_fun) == PIKE_T_FUNCTION) {   #ifdef PIKE_DEBUG    if (THIS->_fun.u.object->prog &&    THIS->_fun.u.object->prog != THIS->oprog) {    struct identifier *id = ID_FROM_INT(THIS->oprog, SUBTYPEOF(THIS->_fun));    /* FIXME: Dump dmalloc info for the object? */    Pike_fatal("Lost track of function pointer! Function name was %s.\n",    id->name?id->name->str:"<no name>");
pike.git/src/builtin.cmod:2619:    }    else if (THIS->prog) {    file = low_get_program_line (THIS->prog, &THIS->lineno);    }       if (file) {    if (!THIS->filename) THIS->filename = file;    else free_string (file);    }    +  if (with_var_info) { +  int i; +  struct array *names = allocate_array(vars.num_local); +  struct array *types = allocate_array(vars.num_local); +     if (THIS->prog) { -  +  for (i = 0; i < vars.num_local; i++) { +  SET_SVAL(ITEM(names)[i], PIKE_T_STRING, 0, +  string, THIS->prog->strings[vars.names[i]]); +  add_ref(ITEM(names)[i].u.string); +  assign_svalue_no_free(ITEM(types) + i, +  &THIS->prog->constants[vars.types[i]].sval); +  } +  } +  THIS->_var_names = names; +  THIS->_var_types = types; +  +  if (THIS->prog) {    free_program(THIS->prog);    THIS->prog = NULL;    }    } -  +  }       PIKEFUN string `filename()    {    if (!THIS->lineno) { -  fill_in_file_and_line(); +  fill_in_file_and_line(0);    }    if (THIS->filename) {    ref_push_string(THIS->filename);    return;    }    push_undefined();    }       PIKEFUN string `line()    {    if (!THIS->lineno) { -  fill_in_file_and_line(); +  fill_in_file_and_line(0);    }    push_int(THIS->lineno);    }    -  +  PIKEFUN array `->var_names() +  { +  if (!THIS->_var_names) { +  fill_in_file_and_line(1); +  } +  ref_push_array(THIS->_var_names); +  } +  +  PIKEFUN array `->var_types() +  { +  if (!THIS->_var_types) { +  fill_in_file_and_line(1); +  } +  ref_push_array(THIS->_var_types); +  } +     /*! @decl string _sprintf(int c, mapping|void opts)    */    PIKEFUN string _sprintf(int c, mapping|void opts)    flags ID_PROTECTED;    {    pop_n_elems(args);       if (c != 'O') {    push_undefined ();    return;    }       push_static_text("backtrace_frame(");    -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);       if (THIS->filename) {    ref_push_string(THIS->filename);    push_static_text(":");    push_int(THIS->lineno);    push_static_text(", ");    f_add(4);    } else {    push_static_text("Unknown file, ");    }
pike.git/src/builtin.cmod:2762:    return;    }       if (end >= numargs)    end = numargs-1;    }       for (i = index; i <= end; i++) {    switch(i) {    case 0: /* Filename */ -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);    if (THIS->filename)    ref_push_string(THIS->filename);    else    push_int(0);    break;    case 1: /* Linenumber */ -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);    push_int(THIS->lineno);    break;    case 2: /* Function */    push_svalue(&THIS->_fun);    break;    default: /* Arguments */    {    if ((i > 2) && (THIS->args) && (i-3 < THIS->args->size)) {    push_svalue(THIS->args->item + (i - 3));    break;
pike.git/src/builtin.cmod:2818:    else if (index < 0)    index += numargs;       if (args > 2) {    pop_n_elems(args - 2);    args = 2;    }       switch(index) {    case 0: /* Filename */ -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);    if (TYPEOF(*value) != PIKE_T_STRING) {    if ((TYPEOF(*value) != PIKE_T_INT) ||    (value->u.integer)) {    SIMPLE_ARG_TYPE_ERROR("`[]=", 2, "string|int(0..0)");    }    if (THIS->filename) {    free_string(THIS->filename);    THIS->filename = NULL;    }    } else {    if (THIS->filename) {    free_string(THIS->filename);    THIS->filename = NULL;    }    copy_shared_string(THIS->filename, value->u.string);    }    break;       case 1: /* Linenumber */ -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);    if (TYPEOF(*value) != PIKE_T_INT)    SIMPLE_ARG_TYPE_ERROR("`[]=", 2, "int(1..)");    THIS->lineno = value->u.integer;    break;       case 2: /* Function */ -  if (THIS->lineno == 0) fill_in_file_and_line(); +  if (THIS->lineno == 0) fill_in_file_and_line(0);    assign_svalue(&THIS->_fun, value);    break;    default: /* Arguments */    assign_svalue(THIS->args->item + index - 3, value);    break;    }    stack_swap();    pop_stack();    }   
pike.git/src/builtin.cmod:2979:    object, f->current_object);    add_ref(f->current_object);    function = ID_FROM_INT(f->current_object->prog, f->fun);   #ifdef PIKE_DEBUG    add_ref(bf->oprog = bf->_fun.u.object->prog);   #endif    }    }       if (f->locals) { -  INT32 numargs = (INT32) MINIMUM(f->num_args, -  stack_top - f->locals); +  INT32 numlocals = (INT32)(stack_top - f->locals); +  INT32 numargs = (INT32) MINIMUM(f->num_args, numlocals);    INT32 varargs = 0;       if(of && of->locals) {    /* f->num_args can be too large, so this is necessary for some    * reason. I don't know why. /mast    *    * possibly because f->num_args was uninitialized for c_initializers    * /arne    * */    -  +  numlocals = (INT32)MINIMUM(numlocals, of->locals - f->locals);    numargs = (INT32)MINIMUM(f->num_args,of->locals - f->locals);    }    -  +  numlocals = MAXIMUM(numlocals, 0);    numargs = MAXIMUM(numargs, 0);       /* Handle varargs... */    if (function && (function->identifier_flags & IDENTIFIER_VARARGS) &&    (f->locals + numargs < stack_top) &&    (TYPEOF(f->locals[numargs]) == T_ARRAY)) {    varargs = f->locals[numargs].u.array->size;    }    -  +  if (numlocals) { +  bf->vars = allocate_array_no_init(numlocals, 0); +  bf->vars->type_field = +  assign_svalues_no_free(bf->vars->item, f->locals, +  numlocals, BIT_MIXED); +  if (bf->vars->type_field & BIT_OBJECT) { +  ptrdiff_t i; +  for (i = 0; i < bf->vars->size; i++) { +  /* FIXME: What about arrays of objects (eg varargs). */ +  struct svalue *s = ITEM(bf->vars) + i; +  if ((TYPEOF(*s) == T_OBJECT) && +  s->u.object->prog && +  (s->u.object->prog->flags & +  (PROGRAM_DESTRUCT_IMMEDIATE|PROGRAM_CLEAR_STORAGE))) { +  /* It is typically a bad idea to have extra references +  * to objects with these flags. The flags are usually +  * used by stuff like mutex keys and encryption keys +  * respectively. +  */ +  struct object *o = clone_fake_object(s->u.object->prog); +  free_object(s->u.object); +  SET_SVAL(*s, T_OBJECT, 0, object, o); +  } +  } +  } +  } +     if (numargs + varargs) {    bf->args = allocate_array_no_init(numargs + varargs, 0);    bf->args->type_field =    assign_svalues_no_free(bf->args->item, f->locals, numargs, BIT_MIXED);    if (varargs) {    bf->args->type_field |=    assign_svalues_no_free(bf->args->item + numargs,    f->locals[numargs].u.array->item,    varargs, BIT_MIXED);    }