pike.git/
src/
builtin.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2001-06-18
2001-06-18 15:45:29 by Henrik Grubbström (Grubba) <grubba@grubba.org>
d27df52670e073694dea89e27461d880881b7036 (
206
lines) (+
205
/-
1
)
[
Show
|
Annotate
]
Branch:
7.9
Added an experimental deferred backtrace.
Rev: src/builtin.cmod:1.33
1:
/* -*- c -*-
-
* $Id: builtin.cmod,v 1.
32
2001/06/
06
08
:
12
:
10
hubbe
Exp $
+
* $Id: builtin.cmod,v 1.
33
2001/06/
18
15
:
45
:
29
grubba
Exp $
*/ #include "global.h"
634:
pop_stack(); }
+
/*
+
* Backtrace handling.
+
*/
-
+
/*! @class BacktraceFrame
+
*/
-
+
PIKECLASS backtrace_frame
+
{
+
CVAR struct pike_frame *frame;
+
CVAR INT_TYPE lineno;
+
CVAR struct pike_string *filename;
+
+
INIT
+
{
+
THIS->frame = NULL;
+
THIS->filename = NULL;
+
THIS->lineno = 0;
+
}
+
+
EXIT
+
{
+
if (THIS->frame) {
+
free_pike_frame(THIS->frame);
+
}
+
if (THIS->filename) {
+
free_string(THIS->filename);
+
}
+
THIS->frame = NULL;
+
THIS->filename = NULL;
+
THIS->lineno = 0;
+
}
+
+
PIKEFUN string _sprintf(int c, mapping|void opts)
+
{
+
struct pike_frame *f = THIS->frame;
+
INT_TYPE numargs = 0;
+
+
pop_n_elems(args);
+
+
if (!f) {
+
push_text("backtrace_frame( empty )");
+
return;
+
}
+
push_text("backtrace_frame(");
+
if (f->pc) {
+
if (!THIS->filename) {
+
THIS->filename =
+
make_shared_string(get_line(f->pc, f->context.prog,
+
&THIS->lineno));
+
}
+
ref_push_string(THIS->filename);
+
push_text(":");
+
push_int(THIS->lineno);
+
push_text(", ");
+
f_add(4);
+
} else {
+
push_text("Unknown file, ");
+
}
+
if (f->current_object->prog) {
+
ref_push_object(f->current_object);
+
Pike_sp[-1].subtype = f->fun;
+
Pike_sp[-1].type = PIKE_T_FUNCTION;
+
f_function_name(1);
+
push_text("(), ");
+
f_add(2);
+
} else {
+
push_text("destructed_function(), ");
+
}
+
+
if (f->locals) {
+
numargs =
+
DO_NOT_WARN((INT_TYPE) MINIMUM(f->num_args, Pike_sp - f->locals));
+
if (numargs < 0) numargs = 0;
+
}
+
if (numargs) {
+
push_text("Args: ");
+
push_int(numargs);
+
f_add(2);
+
} else {
+
push_text("No args");
+
}
+
push_text(")");
+
f_add(5);
+
}
+
+
PIKEFUN int _sizeof()
+
{
+
struct pike_frame *f = THIS->frame;
+
INT_TYPE numargs = 0;
+
+
if (!f) {
+
push_int(0);
+
return;
+
}
+
if (f->locals) {
+
numargs =
+
DO_NOT_WARN((INT_TYPE) MINIMUM(f->num_args, Pike_sp - f->locals));
+
if (numargs < 0) numargs = 0;
+
}
+
push_int(numargs + 3);
+
}
+
+
PIKEFUN mixed `[](int index)
+
{
+
struct pike_frame *f = THIS->frame;
+
+
if (!f) {
+
index_error("pike_frame->`[]", Pike_sp-args, args, NULL, Pike_sp-args,
+
"Indexing the empty array with %"PRINTPIKEINT"d.\n", index);
+
}
+
if (index < 0) {
+
index_error("pike_frame->`[]", Pike_sp-args, args, NULL, Pike_sp-args,
+
"Indexing with negative index (%"PRINTPIKEINT"d)\n", index);
+
}
+
if (!(f->current_object && f->context.prog)) {
+
index_error("pike_frame->`[]", Pike_sp-args, args, NULL, Pike_sp-args,
+
"Indexing the NULL value with %"PRINTPIKEINT"d.\n", index);
+
}
+
+
pop_n_elems(args);
+
+
switch(index) {
+
case 0: /* Filename */
+
if (f->pc) {
+
if (!THIS->filename) {
+
THIS->filename =
+
make_shared_string(get_line(f->pc, f->context.prog,
+
&THIS->lineno));
+
}
+
ref_push_string(THIS->filename);
+
} else {
+
push_int(0);
+
}
+
return;
+
case 1: /* Linenumber */
+
if (f->pc) {
+
if (!THIS->filename) {
+
THIS->filename =
+
make_shared_string(get_line(f->pc, f->context.prog,
+
&THIS->lineno));
+
}
+
push_int(THIS->lineno);
+
} else {
+
push_int(0);
+
}
+
return;
+
case 2: /* Function */
+
if (f->current_object->prog) {
+
ref_push_object(f->current_object);
+
Pike_sp[-1].subtype = f->fun;
+
Pike_sp[-1].type = PIKE_T_FUNCTION;
+
} else {
+
push_int(0);
+
Pike_sp[-1].subtype = NUMBER_DESTRUCTED;
+
}
+
return;
+
default: /* Arguments */
+
{
+
INT32 numargs = 0;
+
if ((index > 2) && (f->locals)) {
+
numargs =
+
DO_NOT_WARN((INT32) MINIMUM(f->num_args, Pike_sp - f->locals));
+
if (numargs < 0) numargs = 0;
+
index -= 3;
+
if (index < numargs) {
+
push_svalue(f->locals + index);
+
return;
+
}
+
}
+
bad_arg_error("backtrace_frame->`[]", Pike_sp-args, args, 1,
+
"int(0..)", Pike_sp-args,
+
"Bad argument 1 to backtrace_frame->`[](): "
+
"Expected int(0..%d)\n",
+
numargs+2);
+
}
+
/* NOT_REACHED */
+
return;
+
}
+
}
+
};
+
+
/*! @endclass
+
*/
+
+
/*! Deferred backtrace.
+
*/
+
PIKEFUN array(object) new_backtrace()
+
/* efun; */
+
{
+
struct pike_frame *f;
+
int size = 0;
+
+
for (f = Pike_fp->next; f; f = f->next) {
+
struct object *o = low_clone(backtrace_frame_program);
+
call_c_initializers(o);
+
add_ref(OBJ2_BACKTRACE_FRAME(o)->frame = f);
+
push_object(o);
+
size++;
+
}
+
+
f_aggregate(size);
+
f_reverse(1);
+
}
+
void init_builtin(void) { INIT }