Remove broken SHORT_OPCODES=0 build mode (#49)

This commit is contained in:
Ben Noordhuis 2023-11-12 13:35:41 +01:00 committed by GitHub
parent a92e74acac
commit e8ff1f4a3a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 140 deletions

View file

@ -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

214
quickjs.c
View file

@ -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: