From e8ff1f4a3a2e387900f42033ccc463d65c4cc869 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 12 Nov 2023 13:35:41 +0100 Subject: [PATCH] Remove broken SHORT_OPCODES=0 build mode (#49) --- quickjs-opcode.h | 2 - quickjs.c | 214 +++++++++++++++++------------------------------ 2 files changed, 76 insertions(+), 140 deletions(-) diff --git a/quickjs-opcode.h b/quickjs-opcode.h index 02785e7..f08b94c 100644 --- a/quickjs-opcode.h +++ b/quickjs-opcode.h @@ -283,7 +283,6 @@ def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ -#if SHORT_OPCODES DEF( push_minus1, 1, 0, 1, none_int) DEF( push_0, 1, 0, 1, none_int) DEF( push_1, 1, 0, 1, none_int) @@ -356,7 +355,6 @@ DEF( is_undefined, 1, 1, 1, none) DEF( is_null, 1, 1, 1, none) DEF(typeof_is_undefined, 1, 1, 1, none) DEF( typeof_is_function, 1, 1, 1, none) -#endif #undef DEF #undef def diff --git a/quickjs.c b/quickjs.c index bac5860..32165cd 100644 --- a/quickjs.c +++ b/quickjs.c @@ -46,7 +46,6 @@ #include "libregexp.h" #include "libbf.h" -#define SHORT_OPCODES 1 #if defined(EMSCRIPTEN) #define DIRECT_DISPATCH 0 #else @@ -14153,11 +14152,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, #else static const void * const dispatch_table[256] = { #define DEF(id, size, n_pop, n_push, f) && case_OP_ ## id, -#if SHORT_OPCODES #define def(id, size, n_pop, n_push, f) -#else -#define def(id, size, n_pop, n_push, f) && case_default, -#endif #include "quickjs-opcode.h" [ OP_COUNT ... 255 ] = &&case_default }; @@ -14264,7 +14259,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, *sp++ = JS_DupValue(ctx, b->cpool[get_u32(pc)]); pc += 4; BREAK; -#if SHORT_OPCODES CASE(OP_push_minus1): CASE(OP_push_0): CASE(OP_push_1): @@ -14306,7 +14300,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sp[-1] = val; } BREAK; -#endif CASE(OP_push_atom_value): *sp++ = JS_AtomToValue(ctx, get_u32(pc)); pc += 4; @@ -14557,14 +14550,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, goto exception; } BREAK; -#if SHORT_OPCODES CASE(OP_call0): CASE(OP_call1): CASE(OP_call2): CASE(OP_call3): call_argc = opcode - OP_call0; goto has_call_argc; -#endif CASE(OP_call): CASE(OP_tail_call): { @@ -14979,7 +14970,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } BREAK; -#if SHORT_OPCODES CASE(OP_get_loc8): *sp++ = JS_DupValue(ctx, var_buf[*pc++]); BREAK; CASE(OP_put_loc8): set_value(ctx, &var_buf[*pc++], *--sp); BREAK; CASE(OP_set_loc8): set_value(ctx, &var_buf[*pc++], JS_DupValue(ctx, sp[-1])); BREAK; @@ -15020,7 +15010,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_set_var_ref1): set_value(ctx, var_refs[1]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_var_ref2): set_value(ctx, var_refs[2]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_var_ref3): set_value(ctx, var_refs[3]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK; -#endif CASE(OP_get_var_ref): { @@ -15196,7 +15185,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (unlikely(js_poll_interrupts(ctx))) goto exception; BREAK; -#if SHORT_OPCODES CASE(OP_goto16): pc += (int16_t)get_u16(pc); if (unlikely(js_poll_interrupts(ctx))) @@ -15207,7 +15195,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (unlikely(js_poll_interrupts(ctx))) goto exception; BREAK; -#endif CASE(OP_if_true): { int res; @@ -15248,7 +15235,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, goto exception; } BREAK; -#if SHORT_OPCODES CASE(OP_if_true8): { int res; @@ -15289,7 +15275,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, goto exception; } BREAK; -#endif CASE(OP_catch): { int32_t diff; @@ -16498,7 +16483,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } else { goto free_and_set_false; } -#if SHORT_OPCODES CASE(OP_is_undefined): if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED) { goto set_true; @@ -16527,7 +16511,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } free_and_set_true: JS_FreeValue(ctx, sp[-1]); -#endif set_true: sp[-1] = JS_TRUE; BREAK; @@ -18001,7 +17984,6 @@ static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = { #undef FMT }; -#if SHORT_OPCODES /* After the final compilation pass, short opcodes are used. Their opcodes overlap with the temporary opcodes which cannot appear in the final bytecode. Their description is after the temporary @@ -18009,9 +17991,6 @@ static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = { #define short_opcode_info(op) \ opcode_info[(op) >= OP_TEMP_START ? \ (op) + (OP_TEMP_END - OP_TEMP_START) : (op)] -#else -#define short_opcode_info(op) opcode_info[op] -#endif static __exception int next_token(JSParseState *s); @@ -19282,10 +19261,8 @@ static BOOL js_is_live_code(JSParseState *s) { case OP_throw: case OP_throw_error: case OP_goto: -#if SHORT_OPCODES case OP_goto8: case OP_goto16: -#endif case OP_ret: return FALSE; default: @@ -26672,7 +26649,6 @@ static void dump_byte_code(JSContext *ctx, int pass, pos_next = pos + oi->size; if (op < OP_COUNT) { switch (oi->fmt) { -#if SHORT_OPCODES case OP_FMT_label8: pos++; addr = (int8_t)tab[pos]; @@ -26681,7 +26657,6 @@ static void dump_byte_code(JSContext *ctx, int pass, pos++; addr = (int16_t)get_u16(tab + pos); goto has_addr; -#endif case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u16: pos += 4; @@ -26795,14 +26770,12 @@ static void dump_byte_code(JSContext *ctx, int pass, case OP_FMT_u32: printf(" %u", get_u32(tab + pos)); break; -#if SHORT_OPCODES case OP_FMT_label8: addr = get_i8(tab + pos); goto has_addr1; case OP_FMT_label16: addr = get_i16(tab + pos); goto has_addr1; -#endif case OP_FMT_label: addr = get_u32(tab + pos); goto has_addr1; @@ -26824,11 +26797,9 @@ static void dump_byte_code(JSContext *ctx, int pass, printf(" %u", addr + pos); printf(",%u", get_u16(tab + pos + 4)); break; -#if SHORT_OPCODES case OP_FMT_const8: idx = get_u8(tab + pos); goto has_pool_idx; -#endif case OP_FMT_const: idx = get_u32(tab + pos); goto has_pool_idx; @@ -29013,7 +28984,6 @@ static int find_jump_target(JSFunctionDef *s, int label, int *pop, int *pline) static void push_short_int(DynBuf *bc_out, int val) { -#if SHORT_OPCODES if (val >= -1 && val <= 7) { dbuf_putc(bc_out, OP_push_0 + val); return; @@ -29028,14 +28998,12 @@ static void push_short_int(DynBuf *bc_out, int val) dbuf_put_u16(bc_out, val); return; } -#endif dbuf_putc(bc_out, OP_push_i32); dbuf_put_u32(bc_out, val); } static void put_short_code(DynBuf *bc_out, int op, int idx) { -#if SHORT_OPCODES if (idx < 4) { switch (op) { case OP_get_loc: @@ -29086,7 +29054,6 @@ static void put_short_code(DynBuf *bc_out, int op, int idx) return; } } -#endif dbuf_putc(bc_out, op); dbuf_put_u16(bc_out, idx); } @@ -29094,16 +29061,14 @@ static void put_short_code(DynBuf *bc_out, int op, int idx) /* peephole optimizations and resolve goto/labels */ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) { - int pos, pos_next, bc_len, op, op1, len, i, line_num; + int pos, pos_next, bc_len, op, op1, len, i, line_num, patch_offsets; const uint8_t *bc_buf; DynBuf bc_out; LabelSlot *label_slots, *ls; RelocEntry *re, *re_next; CodeContext cc; int label; -#if SHORT_OPCODES JumpSlot *jp; -#endif label_slots = s->label_slots; @@ -29113,14 +29078,12 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) cc.bc_len = bc_len = s->byte_code.size; js_dbuf_init(ctx, &bc_out); -#if SHORT_OPCODES if (s->jump_size) { s->jump_slots = js_mallocz(s->ctx, sizeof(*s->jump_slots) * s->jump_size); if (s->jump_slots == NULL) return -1; } -#endif - /* XXX: Should skip this phase if not generating SHORT_OPCODES */ + if (s->line_number_size) { s->line_number_slots = js_mallocz(s->ctx, sizeof(*s->line_number_slots) * s->line_number_size); if (s->line_number_slots == NULL) @@ -29327,7 +29290,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) } assert(label >= 0 && label < s->label_count); ls = &label_slots[label]; -#if SHORT_OPCODES jp = &s->jump_slots[s->jump_count++]; jp->op = op; jp->size = 4; @@ -29371,7 +29333,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) break; } } -#endif dbuf_putc(&bc_out, op); dbuf_put_u32(&bc_out, ls->addr - bc_out.size); if (ls->addr == -1) { @@ -29397,13 +29358,11 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) assert(label >= 0 && label < s->label_count); ls = &label_slots[label]; add_pc2line_info(s, bc_out.size, line_num); -#if SHORT_OPCODES jp = &s->jump_slots[s->jump_count++]; jp->op = op; jp->size = 4; jp->pos = bc_out.size + 5; jp->label = label; -#endif dbuf_putc(&bc_out, op); dbuf_put_u32(&bc_out, atom); dbuf_put_u32(&bc_out, ls->addr - bc_out.size); @@ -29425,7 +29384,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) goto no_change; case OP_null: -#if SHORT_OPCODES /* transform null strict_eq into is_null */ if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; @@ -29444,7 +29402,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) op = cc.op ^ OP_if_false ^ OP_if_true; goto has_label; } -#endif /* fall thru */ case OP_push_false: case OP_push_true: @@ -29501,7 +29458,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) push_short_int(&bc_out, val); break; -#if SHORT_OPCODES case OP_push_const: case OP_fclosure: { @@ -29526,7 +29482,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) } } goto no_change; -#endif + case OP_push_atom_value: { JSAtom atom = get_u32(bc_buf + pos + 1); @@ -29537,14 +29493,12 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) pos_next = cc.pos; break; } -#if SHORT_OPCODES if (atom == JS_ATOM_empty_string) { JS_FreeAtom(ctx, atom); add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_push_empty_string); break; } -#endif } goto no_change; @@ -29578,7 +29532,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) val = 0; goto has_constant_test; } -#if SHORT_OPCODES /* transform undefined strict_eq -> is_undefined */ if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; @@ -29597,7 +29550,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) op = cc.op ^ OP_if_false ^ OP_if_true; goto has_label; } -#endif goto no_change; case OP_insert2: @@ -29669,13 +29621,10 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) if (code_match(&cc, pos_next, OP_push_atom_value, OP_add, OP_dup, OP_put_loc, idx, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num); -#if SHORT_OPCODES if (cc.atom == JS_ATOM_empty_string) { JS_FreeAtom(ctx, cc.atom); dbuf_putc(&bc_out, OP_push_empty_string); - } else -#endif - { + } else { dbuf_putc(&bc_out, OP_push_atom_value); dbuf_put_u32(&bc_out, cc.atom); } @@ -29714,7 +29663,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) put_short_code(&bc_out, op, idx); } break; -#if SHORT_OPCODES case OP_get_arg: case OP_get_var_ref: { @@ -29724,7 +29672,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) put_short_code(&bc_out, op, idx); } break; -#endif case OP_put_loc: case OP_put_arg: case OP_put_var_ref: @@ -29789,7 +29736,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) } goto no_change; -#if SHORT_OPCODES case OP_typeof: /* simplify typeof tests */ if (code_match(&cc, pos_next, OP_push_atom_value, M4(OP_strict_eq, OP_strict_neq, OP_eq, OP_neq), -1)) { @@ -29827,7 +29773,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) } } goto no_change; -#endif default: no_change: @@ -29841,85 +29786,84 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) for(i = 0; i < s->label_count; i++) { assert(label_slots[i].first_reloc == NULL); } -#if SHORT_OPCODES - { - /* more jump optimizations */ - int patch_offsets = 0; - for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) { - LabelSlot *ls; - JumpSlot *jp1; - int j, pos, diff, delta; - delta = 3; - switch (op = jp->op) { - case OP_goto16: - delta = 1; - /* fall thru */ - case OP_if_false: - case OP_if_true: - case OP_goto: - pos = jp->pos; - diff = s->label_slots[jp->label].addr - pos; - if (diff >= -128 && diff <= 127 + delta) { - //put_u8(bc_out.buf + pos, diff); - jp->size = 1; - if (op == OP_goto16) { - bc_out.buf[pos - 1] = jp->op = OP_goto8; - } else { - bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false); - } - goto shrink; - } else - if (diff == (int16_t)diff && op == OP_goto) { - //put_u16(bc_out.buf + pos, diff); - jp->size = 2; - delta = 2; - bc_out.buf[pos - 1] = jp->op = OP_goto16; - shrink: - /* XXX: should reduce complexity, using 2 finger copy scheme */ - memmove(bc_out.buf + pos + jp->size, bc_out.buf + pos + jp->size + delta, - bc_out.size - pos - jp->size - delta); - bc_out.size -= delta; - patch_offsets++; - for (j = 0, ls = s->label_slots; j < s->label_count; j++, ls++) { - if (ls->addr > pos) - ls->addr -= delta; - } - for (j = i + 1, jp1 = jp + 1; j < s->jump_count; j++, jp1++) { - if (jp1->pos > pos) - jp1->pos -= delta; - } - for (j = 0; j < s->line_number_count; j++) { - if (s->line_number_slots[j].pc > pos) - s->line_number_slots[j].pc -= delta; - } - continue; + /* more jump optimizations */ + patch_offsets = 0; + for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) { + LabelSlot *ls; + JumpSlot *jp1; + int j, pos, diff, delta; + + delta = 3; + switch (op = jp->op) { + case OP_goto16: + delta = 1; + /* fall thru */ + case OP_if_false: + case OP_if_true: + case OP_goto: + pos = jp->pos; + diff = s->label_slots[jp->label].addr - pos; + if (diff >= -128 && diff <= 127 + delta) { + //put_u8(bc_out.buf + pos, diff); + jp->size = 1; + if (op == OP_goto16) { + bc_out.buf[pos - 1] = jp->op = OP_goto8; + } else { + bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false); } + goto shrink; + } else + if (diff == (int16_t)diff && op == OP_goto) { + //put_u16(bc_out.buf + pos, diff); + jp->size = 2; + delta = 2; + bc_out.buf[pos - 1] = jp->op = OP_goto16; + shrink: + /* XXX: should reduce complexity, using 2 finger copy scheme */ + memmove(bc_out.buf + pos + jp->size, bc_out.buf + pos + jp->size + delta, + bc_out.size - pos - jp->size - delta); + bc_out.size -= delta; + patch_offsets++; + for (j = 0, ls = s->label_slots; j < s->label_count; j++, ls++) { + if (ls->addr > pos) + ls->addr -= delta; + } + for (j = i + 1, jp1 = jp + 1; j < s->jump_count; j++, jp1++) { + if (jp1->pos > pos) + jp1->pos -= delta; + } + for (j = 0; j < s->line_number_count; j++) { + if (s->line_number_slots[j].pc > pos) + s->line_number_slots[j].pc -= delta; + } + continue; + } + break; + } + } + + if (patch_offsets) { + JumpSlot *jp1; + int j; + for (j = 0, jp1 = s->jump_slots; j < s->jump_count; j++, jp1++) { + int diff1 = s->label_slots[jp1->label].addr - jp1->pos; + switch (jp1->size) { + case 1: + put_u8(bc_out.buf + jp1->pos, diff1); + break; + case 2: + put_u16(bc_out.buf + jp1->pos, diff1); + break; + case 4: + put_u32(bc_out.buf + jp1->pos, diff1); break; } } - if (patch_offsets) { - JumpSlot *jp1; - int j; - for (j = 0, jp1 = s->jump_slots; j < s->jump_count; j++, jp1++) { - int diff1 = s->label_slots[jp1->label].addr - jp1->pos; - switch (jp1->size) { - case 1: - put_u8(bc_out.buf + jp1->pos, diff1); - break; - case 2: - put_u16(bc_out.buf + jp1->pos, diff1); - break; - case 4: - put_u32(bc_out.buf + jp1->pos, diff1); - break; - } - } - } } + js_free(ctx, s->jump_slots); s->jump_slots = NULL; -#endif js_free(ctx, s->label_slots); s->label_slots = NULL; /* XXX: should delay until copying to runtime bytecode function */ @@ -30034,12 +29978,8 @@ static __exception int compute_stack_size(JSContext *ctx, /* call pops a variable number of arguments */ if (oi->fmt == OP_FMT_npop || oi->fmt == OP_FMT_npop_u16) { n_pop += get_u16(bc_buf + pos + 1); - } else { -#if SHORT_OPCODES - if (oi->fmt == OP_FMT_npopx) { - n_pop += op - OP_call0; - } -#endif + } else if (oi->fmt == OP_FMT_npopx) { + n_pop += op - OP_call0; } if (stack_len < n_pop) { @@ -30068,7 +30008,6 @@ static __exception int compute_stack_size(JSContext *ctx, diff = get_u32(bc_buf + pos + 1); pos_next = pos + 1 + diff; break; -#if SHORT_OPCODES case OP_goto16: diff = (int16_t)get_u16(bc_buf + pos + 1); pos_next = pos + 1 + diff; @@ -30083,7 +30022,6 @@ static __exception int compute_stack_size(JSContext *ctx, if (ss_check(ctx, s, pos + 1 + diff, op, stack_len)) goto fail; break; -#endif case OP_if_true: case OP_if_false: case OP_catch: