6816ee | 2015-03-15 | Martin Nilsson | | /* -*- c -*-
|
9944b0 | 2015-03-08 | Martin Nilsson | | || This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/
#include "global.h"
#include "module.h"
#include "pike_error.h"
#include "interpret.h"
#include "pike_embed.h"
#include "module_support.h"
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | #include "builtin_functions.h"
|
48d159 | 2015-03-16 | Martin Nilsson | | #include "mapping.h"
#include "multiset.h"
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | |
DECLARATIONS
|
34a679 | 2015-03-08 | Martin Nilsson | |
/*! @decl int(0..) map_all_objects(function(object:void) cb)
*! @belongs Debug
*!
*! Call cb for all objects that currently exist. The callback will
*! not be called with destructed objects as it's argument.
*!
*! Objects might be missed if @[cb] creates new objects or destroys
*! old ones.
*!
*! This function is only intended to be used for debug purposes.
*!
*! @returns
*! The total number of objects
*!
*! @seealso
*! @[next_object()]
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..) map_all_objects(function(object:void) cb)
|
34a679 | 2015-03-08 | Martin Nilsson | | {
struct object *o = first_object;
INT32 total = 0;
while( o )
{
struct object *next = o->next;
if( o->prog )
{
ref_push_object( o );
safe_apply_svalue( Pike_sp-2, 1, 1 );
pop_stack();
}
total++;
o = next;
}
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | RETURN total;
|
34a679 | 2015-03-08 | Martin Nilsson | | }
|
9944b0 | 2015-03-08 | Martin Nilsson | |
|
6816ee | 2015-03-15 | Martin Nilsson | | /*! @decl int refs(string|array|mapping|multiset|function|object|program o)
*! @belongs Debug
*!
*! Return the number of references @[o] has.
*!
*! It is mainly meant for debugging the Pike runtime, but can also be
*! used to control memory usage.
*!
*! @note
*! Note that the number of references will always be at least one since
*! the value is located on the stack when this function is executed.
*!
*! @seealso
|
48d159 | 2015-03-16 | Martin Nilsson | | *! @[next()], @[prev()]
|
6816ee | 2015-03-15 | Martin Nilsson | | */
PIKEFUN int refs(string|array|mapping|multiset|function|object|program o)
{
RETURN o->u.refs[0];
}
|
48d159 | 2015-03-16 | Martin Nilsson | | /*! @decl object next_object(object o)
*! @decl object next_object()
*!
*! Returns the next object from the list of all objects.
*!
*! All objects are stored in a linked list.
*!
*! @returns
*! If no arguments have been given @[next_object()] will return the first
*! object from the list.
*!
*! If @[o] has been specified the object after @[o] on the list will be
*! returned.
*!
*! @note
*! This function is not recomended to use.
*!
*! @seealso
*! @[destruct()]
*/
PIKEFUN object next_object(void|object o)
{
if (!o)
o = first_object;
else
o = Pike_sp[-args].u.object->next;
while(o && !o->prog) o=o->next;
pop_n_elems(args);
if(o)
ref_push_object(o);
else
push_int(0);
}
/*! @decl mixed next(mixed x)
*!
*! Find the next object/array/mapping/multiset/program or string.
*!
*! All objects, arrays, mappings, multisets, programs and strings are
*! stored in linked lists inside Pike. This function returns the next
*! item on the corresponding list. It is mainly meant for debugging
*! the Pike runtime, but can also be used to control memory usage.
*!
*! @seealso
*! @[next_object()], @[prev()]
*/
|
64226c | 2015-03-16 | Martin Nilsson | | PIKEFUN mixed next(mixed x)
rawtype tOr6(tFunc(tStr,tStr),
tFunc(tObj,tObj),
tFunc(tMapping,tMapping),
tFunc(tMultiset,tMultiset),
tFunc(tPrg(tObj),tPrg(tObj)),
tFunc(tArray,tArray));
|
48d159 | 2015-03-16 | Martin Nilsson | | {
|
64226c | 2015-03-16 | Martin Nilsson | | struct svalue tmp = *x;
|
48d159 | 2015-03-16 | Martin Nilsson | | switch(TYPEOF(tmp))
{
|
64226c | 2015-03-16 | Martin Nilsson | | case T_OBJECT:
tmp.u.object=tmp.u.object->next;
while(tmp.u.object && !tmp.u.object->prog)
tmp.u.object=tmp.u.object->next;
break;
|
48d159 | 2015-03-16 | Martin Nilsson | | case T_ARRAY: tmp.u.array=tmp.u.array->next; break;
case T_MAPPING: tmp.u.mapping=tmp.u.mapping->next; break;
case T_MULTISET:tmp.u.multiset=tmp.u.multiset->next; break;
case T_PROGRAM: tmp.u.program=tmp.u.program->next; break;
case T_STRING: tmp.u.string=next_pike_string(tmp.u.string); break;
default:
SIMPLE_BAD_ARG_ERROR("next", 1,
"object|array|mapping|multiset|program|string");
}
|
64226c | 2015-03-16 | Martin Nilsson | |
|
48d159 | 2015-03-16 | Martin Nilsson | | if(tmp.u.refs)
|
64226c | 2015-03-16 | Martin Nilsson | | assign_svalue(Pike_sp-1, &tmp);
else
|
48d159 | 2015-03-16 | Martin Nilsson | | {
pop_stack();
push_int(0);
}
}
/*! @decl mixed prev(mixed x)
*!
*! Find the previous object/array/mapping/multiset or program.
*!
*! All objects, arrays, mappings, multisets and programs are
*! stored in linked lists inside Pike. This function returns the previous
*! item on the corresponding list. It is mainly meant for debugging
*! the Pike runtime, but can also be used to control memory usage.
*!
*! @note
*! Unlike @[next()] this function does not work on strings.
*!
*! @seealso
*! @[next_object()], @[next()]
*/
|
64226c | 2015-03-16 | Martin Nilsson | | PIKEFUN mixed prev(mixed x)
rawtype tOr5(tFunc(tObj,tObj),
tFunc(tMapping,tMapping),
tFunc(tMultiset,tMultiset),
tFunc(tPrg(tObj),tPrg(tObj)),
tFunc(tArray,tArray));
|
48d159 | 2015-03-16 | Martin Nilsson | | {
|
64226c | 2015-03-16 | Martin Nilsson | | struct svalue tmp = *x;
|
48d159 | 2015-03-16 | Martin Nilsson | | switch(TYPEOF(tmp))
{
|
64226c | 2015-03-16 | Martin Nilsson | | case T_OBJECT:
tmp.u.object=tmp.u.object->prev;
while(tmp.u.object && !tmp.u.object->prog)
tmp.u.object=tmp.u.object->prev;
break;
|
48d159 | 2015-03-16 | Martin Nilsson | | case T_ARRAY: tmp.u.array=tmp.u.array->prev; break;
case T_MAPPING: tmp.u.mapping=tmp.u.mapping->prev; break;
case T_MULTISET:tmp.u.multiset=tmp.u.multiset->prev; break;
case T_PROGRAM: tmp.u.program=tmp.u.program->prev; break;
default:
SIMPLE_BAD_ARG_ERROR("prev", 1, "object|array|mapping|multiset|program");
}
if(tmp.u.refs)
|
64226c | 2015-03-16 | Martin Nilsson | | assign_svalue(Pike_sp-1, &tmp);
else
|
48d159 | 2015-03-16 | Martin Nilsson | | {
pop_stack();
push_int(0);
}
}
|
9944b0 | 2015-03-08 | Martin Nilsson | | #ifdef PIKE_DEBUG
/* This function is for debugging *ONLY*
* do not document please. /Hubbe
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int leak(array|mapping|multiset|object|function|program|string|type val)
|
4a9aec | 2015-03-08 | Henrik Grubbström (Grubba) | | export;
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
INT32 i;
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | if(!REFCOUNTED_TYPE(TYPEOF(*val)))
SIMPLE_BAD_ARG_ERROR("leak", 1,
|
9944b0 | 2015-03-08 | Martin Nilsson | | "array|mapping|multiset|object|"
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | "function|program|string|type");
|
9944b0 | 2015-03-08 | Martin Nilsson | |
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | add_ref(val->u.dummy);
i = val->u.refs[0];
RETURN i;
|
9944b0 | 2015-03-08 | Martin Nilsson | | }
/*! @decl int(0..) debug(int(0..) level)
*! @belongs Debug
*!
*! Set the run-time debug level.
*!
*! @returns
*! The old debug level will be returned.
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | *!
|
9944b0 | 2015-03-08 | Martin Nilsson | | *! @note
*! This function is only available if the Pike runtime has been compiled
*! with RTL debug.
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..) debug(int(0..) d)
|
4a9aec | 2015-03-08 | Henrik Grubbström (Grubba) | | export;
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
pop_n_elems(args);
push_int(d_flag);
d_flag = d;
}
/*! @decl int(0..) optimizer_debug(int(0..) level)
*! @belongs Debug
*!
*! Set the optimizer debug level.
*!
*! @returns
*! The old optimizer debug level will be returned.
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | *!
|
9944b0 | 2015-03-08 | Martin Nilsson | | *! @note
*! This function is only available if the Pike runtime has been compiled
*! with RTL debug.
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..) optimizer_debug(int(0..) l)
|
4a9aec | 2015-03-08 | Henrik Grubbström (Grubba) | | export;
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
pop_n_elems(args);
push_int(l_flag);
l_flag = l;
}
/*! @decl int(0..) assembler_debug(int(0..) level)
*! @belongs Debug
*!
*! Set the assembler debug level.
*!
*! @returns
*! The old assembler debug level will be returned.
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | *!
|
9944b0 | 2015-03-08 | Martin Nilsson | | *! @note
*! This function is only available if the Pike runtime has been compiled
*! with RTL debug.
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..) assembler_debug(int(0..) l)
|
4a9aec | 2015-03-08 | Henrik Grubbström (Grubba) | | export;
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
pop_n_elems(args);
push_int(a_flag);
a_flag = l;
}
/*! @decl void dump_program_tables(program p, int(0..)|void indent)
*! @belongs Debug
*!
*! Dumps the internal tables for the program @[p] on stderr.
*!
*! @param p
*! Program to dump.
*!
*! @param indent
*! Number of spaces to indent the output.
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN void dump_program_tables(program p, int(0..)|void indent)
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | dump_program_tables(p, indent?indent->u.integer:0);
|
9944b0 | 2015-03-08 | Martin Nilsson | | pop_n_elems(args);
}
#ifdef YYDEBUG
/*! @decl int(0..) compiler_trace(int(0..) level)
*! @belongs Debug
*!
*! Set the compiler trace level.
*!
*! @returns
*! The old compiler trace level will be returned.
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | *!
|
9944b0 | 2015-03-08 | Martin Nilsson | | *! @note
*! This function is only available if the Pike runtime has been compiled
*! with RTL debug.
*/
|
da8b64 | 2015-03-08 | Henrik Grubbström (Grubba) | | PIKEFUN int(0..) compiler_trace(int(0..) yyd)
|
4a9aec | 2015-03-08 | Henrik Grubbström (Grubba) | | export;
|
9944b0 | 2015-03-08 | Martin Nilsson | | {
extern int yydebug;
pop_n_elems(args);
push_int(yydebug);
yydebug = yyd;
}
#endif /* YYDEBUG */
|
4e5a84 | 2015-04-10 | Martin Nilsson | | #if defined(PIKE_PORTABLE_BYTECODE)
/*! @decl void disassemble(function fun)
*! @belongs Debug
*!
*! Disassemble a Pike function to @[Stdio.stderr].
*!
*! @note
*! This function is only available if the Pike runtime
*! has been compiled with debug enabled.
*/
PIKEFUN void disassemble(function fun)
{
if ((TYPEOF(*fun) != T_FUNCTION) ||
(SUBTYPEOF(*fun) == FUNCTION_BUILTIN)) {
fprintf(stderr,
"Disassembly only supported for functions implemented in Pike.\n");
} else if (!fun->u.object->prog) {
fprintf(stderr, "Function in destructed object.\n");
} else {
int f = SUBTYPEOF(*fun);
struct reference *ptr = PTR_FROM_INT(fun->u.object->prog, f);
struct program *p = PROG_FROM_PTR(fun->u.object->prog, ptr);
struct identifier *id = p->identifiers + ptr->identifier_offset;
if (id->func.offset >= 0) {
struct pike_string *tripples =
p->strings[read_program_data(p->program + id->func.offset, -1)];
switch(tripples->size_shift) {
#define CASE(SHIFT) \
case SHIFT: \
{ \
PIKE_CONCAT(p_wchar, SHIFT) *str = \
PIKE_CONCAT(STR, SHIFT)(tripples); \
int i=0; \
while(i < tripples->len) { \
fprintf(stderr, "@@@ %d: %s, %d, %d\n", \
i/3, \
instrs[*str - F_OFFSET]. \
name, \
str[1], str[2]); \
str += 3; \
i += 3; \
} \
} \
break
CASE(0);
CASE(1);
CASE(2);
#undef CASE
}
} else {
fprintf(stderr, "Prototype.\n");
}
}
pop_n_elems(args);
push_int(0);
}
#endif /* PIKE_PORTABLE_BYTECODE */
|
9944b0 | 2015-03-08 | Martin Nilsson | | #endif /* PIKE_DEBUG */
|
19a3f3 | 2015-03-15 | Martin Nilsson | |
PIKE_MODULE_INIT
{
INIT;
#ifdef PIKE_DEBUG
ADD_INT_CONSTANT("HAVE_DEBUG", 1, 0);
#endif
}
|