From f1d1aa9e7a7fec40fce75895fe00fe14bb2e5b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Fri, 13 Jul 2012 13:30:51 +0200 Subject: [PATCH] Debug: Added disassemble(). --- lib/modules/Debug.pmod/module.pmod | 1 + src/builtin.cmod | 61 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/lib/modules/Debug.pmod/module.pmod b/lib/modules/Debug.pmod/module.pmod index d986e99497..81528332b9 100644 --- a/lib/modules/Debug.pmod/module.pmod +++ b/lib/modules/Debug.pmod/module.pmod @@ -11,6 +11,7 @@ constant describe_program = _describe_program; constant debug = _debug; constant optimizer_debug = _optimizer_debug; constant assembler_debug = _assembler_debug; +constant disassemble = Builtin._disassemble; constant dump_program_tables = _dump_program_tables; constant locate_references = _locate_references; constant describe = _describe; diff --git a/src/builtin.cmod b/src/builtin.cmod index ee5d1e7571..a833c76796 100644 --- a/src/builtin.cmod +++ b/src/builtin.cmod @@ -30,6 +30,7 @@ #include "gc.h" #include "block_alloc.h" #include "pikecode.h" +#include "opcodes.h" #include <ctype.h> #include <errno.h> @@ -1687,6 +1688,66 @@ PIKEFUN void _putenv (string var, void|string val) #endif /* !USE_SETENV */ } +#if defined(PIKE_DEBUG) && 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_DEBUG && PIKE_PORTABLE_BYTECODE */ + /* * Backtrace handling. */ -- GitLab