pike.git
/
src
/
builtin.cmod
version
»
Context lines:
10
20
40
80
file
none
3
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); }