Skip to content

Commit a140e1c

Browse files
authored
Make -DDUMP_BYTECODE=64 print executed bytecode (#158)
Basically a poor man's bytecode tracer.
1 parent 39c8acd commit a140e1c

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

quickjs.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
8: dump stdlib functions
8282
16: dump bytecode in hex
8383
32: dump line number table
84+
64: dump executed bytecode
8485
*/
8586
//#define DUMP_BYTECODE (1)
8687
/* dump the occurence of the automatic GC */
@@ -14345,6 +14346,12 @@ typedef enum {
1434514346
#define FUNC_RET_YIELD 1
1434614347
#define FUNC_RET_YIELD_STAR 2
1434714348

14349+
#ifdef DUMP_BYTECODE
14350+
static void dump_single_byte_code(JSContext *ctx, const uint8_t *pc,
14351+
JSFunctionBytecode *b);
14352+
static void print_func_name(JSFunctionBytecode *b);
14353+
#endif
14354+
1434814355
/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */
1434914356
static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1435014357
JSValueConst this_obj, JSValueConst new_target,
@@ -14362,8 +14369,14 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1436214369
size_t alloca_size;
1436314370
JSInlineCache *ic;
1436414371

14372+
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 64)
14373+
#define DUMP_BYTECODE_OR_DONT(pc) dump_single_byte_code(ctx, pc, b);
14374+
#else
14375+
#define DUMP_BYTECODE_OR_DONT(pc)
14376+
#endif
14377+
1436514378
#if !DIRECT_DISPATCH
14366-
#define SWITCH(pc) switch (opcode = *pc++)
14379+
#define SWITCH(pc) DUMP_BYTECODE_OR_DONT(pc) switch (opcode = *pc++)
1436714380
#define CASE(op) case op
1436814381
#define DEFAULT default
1436914382
#define BREAK break
@@ -14374,7 +14387,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1437414387
#include "quickjs-opcode.h"
1437514388
[ OP_COUNT ... 255 ] = &&case_default
1437614389
};
14377-
#define SWITCH(pc) goto *dispatch_table[opcode = *pc++];
14390+
#define SWITCH(pc) DUMP_BYTECODE_OR_DONT(pc) goto *dispatch_table[opcode = *pc++];
1437814391
#define CASE(op) case_ ## op
1437914392
#define DEFAULT case_default
1438014393
#define BREAK SWITCH(pc)
@@ -14465,6 +14478,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
1446514478
ctx = b->realm; /* set the current realm */
1446614479
ic = b->ic;
1446714480

14481+
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 64)
14482+
print_func_name(b);
14483+
#endif
14484+
1446814485
restart:
1446914486
for(;;) {
1447014487
int call_argc;
@@ -27252,6 +27269,38 @@ static void dump_byte_code(JSContext *ctx, int pass,
2725227269
js_free(ctx, bits);
2725327270
}
2725427271

27272+
// caveat emptor: intended to be called during execution of bytecode
27273+
// and only works for pass3 bytecode
27274+
static __maybe_unused void dump_single_byte_code(JSContext *ctx,
27275+
const uint8_t *pc,
27276+
JSFunctionBytecode *b)
27277+
{
27278+
JSVarDef *args, *vars;
27279+
int line_num;
27280+
27281+
args = vars = b->vardefs;
27282+
if (vars)
27283+
vars = &vars[b->arg_count];
27284+
27285+
line_num = -1;
27286+
if (b->has_debug)
27287+
line_num = b->debug.line_num;
27288+
27289+
dump_byte_code(ctx, /*pass*/3, pc, short_opcode_info(*pc).size,
27290+
args, b->arg_count, vars, b->var_count,
27291+
b->closure_var, b->closure_var_count,
27292+
b->cpool, b->cpool_count,
27293+
NULL, line_num,
27294+
NULL, b);
27295+
}
27296+
27297+
static __maybe_unused void print_func_name(JSFunctionBytecode *b)
27298+
{
27299+
if (b->has_debug)
27300+
if (b->debug.source)
27301+
print_lines(b->debug.source, 0, 1);
27302+
}
27303+
2725527304
static __maybe_unused void dump_pc2line(JSContext *ctx, const uint8_t *buf, int len,
2725627305
int line_num)
2725727306
{

0 commit comments

Comments
 (0)