more debugging
This commit is contained in:
128
source/quickjs.c
128
source/quickjs.c
@@ -11936,6 +11936,14 @@ static __exception int get_lvalue (JSParseState *s, int *popcode, int *pscope, J
|
||||
}
|
||||
}
|
||||
/* remove the last opcode */
|
||||
{
|
||||
const char *fn = JS_ToCString(s->ctx, fd->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: get_lvalue truncating bc from %zu to %d (opcode=%d)\n",
|
||||
fd->byte_code.size, fd->last_opcode_pos, opcode);
|
||||
}
|
||||
if (fn) JS_FreeCString(s->ctx, fn);
|
||||
}
|
||||
fd->byte_code.size = fd->last_opcode_pos;
|
||||
fd->last_opcode_pos = -1;
|
||||
|
||||
@@ -12062,7 +12070,23 @@ static void put_lvalue (JSParseState *s, int opcode, int scope, JSValue name, in
|
||||
emit_prop_key (s, name); /* name has refcount */
|
||||
break;
|
||||
case OP_get_array_el:
|
||||
{
|
||||
const char *fn = JS_ToCString(s->ctx, s->cur_func->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: emitting put_array_el at bc position %zu\n", s->cur_func->byte_code.size);
|
||||
}
|
||||
if (fn) JS_FreeCString(s->ctx, fn);
|
||||
}
|
||||
emit_op (s, OP_put_array_el);
|
||||
{
|
||||
const char *fn = JS_ToCString(s->ctx, s->cur_func->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: after emit, bc size=%zu, last byte=0x%02x\n",
|
||||
s->cur_func->byte_code.size,
|
||||
s->cur_func->byte_code.buf[s->cur_func->byte_code.size - 1]);
|
||||
}
|
||||
if (fn) JS_FreeCString(s->ctx, fn);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
@@ -13267,6 +13291,14 @@ static void emit_return (JSParseState *s, BOOL hasval) {
|
||||
top = top->prev;
|
||||
}
|
||||
|
||||
{
|
||||
const char *fn = JS_ToCString(s->ctx, s->cur_func->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: emitting return at bc position %zu, hasval=%d\n",
|
||||
s->cur_func->byte_code.size, hasval);
|
||||
}
|
||||
if (fn) JS_FreeCString(s->ctx, fn);
|
||||
}
|
||||
emit_op (s, hasval ? OP_return : OP_return_undef);
|
||||
}
|
||||
|
||||
@@ -15289,10 +15321,28 @@ static __exception int resolve_variables (JSContext *ctx, JSFunctionDef *s) {
|
||||
}
|
||||
|
||||
line_num = 0; /* avoid warning */
|
||||
|
||||
/* Debug: check if this is create_actor */
|
||||
int is_create_actor = 0;
|
||||
if (!JS_IsNull(s->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, s->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
is_create_actor = 1;
|
||||
printf("DEBUG resolve_variables: processing create_actor, bc_len=%d\n", bc_len);
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
|
||||
for (pos = 0; pos < bc_len; pos = pos_next) {
|
||||
op = bc_buf[pos];
|
||||
len = opcode_info[op].size;
|
||||
pos_next = pos + len;
|
||||
|
||||
if (is_create_actor) {
|
||||
printf("DEBUG: pos=%d op=0x%02x len=%d bc_out.size=%zu\n",
|
||||
pos, op, len, bc_out.size);
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case OP_line_num:
|
||||
line_num = get_u32 (bc_buf + pos + 1);
|
||||
@@ -15380,8 +15430,12 @@ static __exception int resolve_variables (JSContext *ctx, JSFunctionDef *s) {
|
||||
/* remove dead code */
|
||||
int line = -1;
|
||||
dbuf_put (&bc_out, bc_buf + pos, len);
|
||||
int old_pos = pos + len;
|
||||
pos = skip_dead_code (s, bc_buf, bc_len, pos + len, &line);
|
||||
pos_next = pos;
|
||||
if (is_create_actor && pos != old_pos) {
|
||||
printf("DEBUG: skip_dead_code skipped from %d to %d (skipped %d bytes)\n", old_pos, pos, pos - old_pos);
|
||||
}
|
||||
if (pos < bc_len && line >= 0 && line_num != line) {
|
||||
line_num = line;
|
||||
s->line_number_size++;
|
||||
@@ -15508,6 +15562,10 @@ static __exception int resolve_variables (JSContext *ctx, JSFunctionDef *s) {
|
||||
}
|
||||
}
|
||||
|
||||
if (is_create_actor) {
|
||||
printf("DEBUG: resolve_variables finished. bc_out.size=%zu (was bc_len=%d)\n", bc_out.size, bc_len);
|
||||
}
|
||||
|
||||
/* set the new byte code */
|
||||
dbuf_free (&s->byte_code);
|
||||
s->byte_code = bc_out;
|
||||
@@ -15771,6 +15829,21 @@ static __exception int resolve_labels (JSContext *ctx, JSFunctionDef *s) {
|
||||
cc.bc_len = bc_len = s->byte_code.size;
|
||||
js_dbuf_init (ctx, &bc_out);
|
||||
|
||||
/* Debug: dump original bytecode for create_actor */
|
||||
if (!JS_IsNull(s->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, s->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("=== ORIGINAL bytecode for %s ===\n", fn);
|
||||
printf("bc_len=%d\n", bc_len);
|
||||
for (int di = 0; di < bc_len; di++) {
|
||||
printf("%02x ", bc_buf[di]);
|
||||
if ((di + 1) % 16 == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
|
||||
#if SHORT_OPCODES
|
||||
if (s->jump_size) {
|
||||
s->jump_slots
|
||||
@@ -16330,6 +16403,10 @@ static __exception int resolve_labels (JSContext *ctx, JSFunctionDef *s) {
|
||||
assert (label_slots[i].first_reloc == NULL);
|
||||
}
|
||||
#if SHORT_OPCODES
|
||||
/* NOTE: Jump shrink optimization disabled due to bytecode corruption bug.
|
||||
The memmove-based shrinking was not correctly updating all position
|
||||
references, leading to invalid opcodes (0 bytes) in the output. */
|
||||
#if 0
|
||||
if (OPTIMIZE) {
|
||||
/* more jump optimizations */
|
||||
int patch_offsets = 0;
|
||||
@@ -16403,6 +16480,7 @@ static __exception int resolve_labels (JSContext *ctx, JSFunctionDef *s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pjs_free (s->jump_slots);
|
||||
s->jump_slots = NULL;
|
||||
#endif
|
||||
@@ -16420,6 +16498,20 @@ static __exception int resolve_labels (JSContext *ctx, JSFunctionDef *s) {
|
||||
JS_ThrowOutOfMemory (ctx);
|
||||
return -1;
|
||||
}
|
||||
/* Debug: dump bytecode for create_actor */
|
||||
if (!JS_IsNull(s->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, s->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("=== resolve_labels output for %s ===\n", fn);
|
||||
printf("bc_len=%zu\n", bc_out.size);
|
||||
for (size_t di = 0; di < bc_out.size; di++) {
|
||||
printf("%02x ", bc_out.buf[di]);
|
||||
if ((di + 1) % 16 == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
/* XXX: not safe */
|
||||
@@ -16442,6 +16534,7 @@ typedef struct StackSizeState {
|
||||
int *pred_pc; /* predecessor PC that first set stack at pos */
|
||||
int *pred_stack; /* stack height at predecessor */
|
||||
uint8_t *is_op_start; /* bitmap: 1 if pos is start of instruction */
|
||||
const char *func_name; /* function name for error messages */
|
||||
} StackSizeState;
|
||||
|
||||
static void print_backtrace_chain (StackSizeState *s, int pos, int max_depth) {
|
||||
@@ -16515,6 +16608,7 @@ static __exception int ss_check (JSContext *ctx, StackSizeState *s, int pos, int
|
||||
int boundary_valid = s->is_op_start[pos];
|
||||
|
||||
printf ("=== STACK ANALYSIS ERROR ===\n");
|
||||
printf ("Function: %s\n", s->func_name ? s->func_name : "?");
|
||||
printf ("Inconsistent stack at pc=%d:\n", pos);
|
||||
printf (" expected: %d (first path)\n", s->stack_level_tab[pos]);
|
||||
printf (" got: %d (conflicting path)\n", stack_len);
|
||||
@@ -16603,6 +16697,7 @@ static __exception int compute_stack_size (JSContext *ctx, JSFunctionDef *fd, in
|
||||
bc_buf = fd->byte_code.buf;
|
||||
s->bc_buf = bc_buf;
|
||||
s->bc_len = fd->byte_code.size;
|
||||
s->func_name = JS_IsNull(fd->func_name) ? "?" : JS_ToCString(ctx, fd->func_name);
|
||||
|
||||
/* bc_len > 0 */
|
||||
s->stack_level_tab
|
||||
@@ -16787,6 +16882,15 @@ static JSValue js_create_function (JSContext *ctx, JSFunctionDef *fd) {
|
||||
int function_size, byte_code_offset, cpool_offset;
|
||||
int closure_var_offset, vardefs_offset;
|
||||
|
||||
/* Debug: check initial bytecode size */
|
||||
if (!JS_IsNull(fd->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, fd->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: js_create_function START, bc_size=%zu\n", fd->byte_code.size);
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
|
||||
/* recompute scope linkage */
|
||||
for (scope = 0; scope < fd->scope_count; scope++) {
|
||||
fd->scopes[scope].first = -1;
|
||||
@@ -16834,7 +16938,23 @@ static JSValue js_create_function (JSContext *ctx, JSFunctionDef *fd) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Debug: check bytecode size before resolve_variables */
|
||||
if (!JS_IsNull(fd->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, fd->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: before resolve_variables, bc_size=%zu\n", fd->byte_code.size);
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
if (resolve_variables (ctx, fd)) goto fail;
|
||||
/* Debug: check bytecode size after resolve_variables */
|
||||
if (!JS_IsNull(fd->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, fd->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: after resolve_variables, bc_size=%zu\n", fd->byte_code.size);
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
|
||||
#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 2)
|
||||
if (!fd->strip_debug) {
|
||||
@@ -16844,6 +16964,14 @@ static JSValue js_create_function (JSContext *ctx, JSFunctionDef *fd) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Debug: check bytecode size before resolve_labels */
|
||||
if (!JS_IsNull(fd->func_name)) {
|
||||
const char *fn = JS_ToCString(ctx, fd->func_name);
|
||||
if (fn && strcmp(fn, "create_actor") == 0) {
|
||||
printf("DEBUG: before resolve_labels, bc_size=%zu\n", fd->byte_code.size);
|
||||
}
|
||||
if (fn) JS_FreeCString(ctx, fn);
|
||||
}
|
||||
if (resolve_labels (ctx, fd)) goto fail;
|
||||
|
||||
if (compute_stack_size (ctx, fd, &stack_size) < 0) goto fail;
|
||||
|
||||
Reference in New Issue
Block a user