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 */ 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_minus1, 1, 0, 1, none_int)
DEF( push_0, 1, 0, 1, none_int) DEF( push_0, 1, 0, 1, none_int)
DEF( push_1, 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( is_null, 1, 1, 1, none)
DEF(typeof_is_undefined, 1, 1, 1, none) DEF(typeof_is_undefined, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none) DEF( typeof_is_function, 1, 1, 1, none)
#endif
#undef DEF #undef DEF
#undef def #undef def

214
quickjs.c
View file

@ -46,7 +46,6 @@
#include "libregexp.h" #include "libregexp.h"
#include "libbf.h" #include "libbf.h"
#define SHORT_OPCODES 1
#if defined(EMSCRIPTEN) #if defined(EMSCRIPTEN)
#define DIRECT_DISPATCH 0 #define DIRECT_DISPATCH 0
#else #else
@ -14153,11 +14152,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
#else #else
static const void * const dispatch_table[256] = { static const void * const dispatch_table[256] = {
#define DEF(id, size, n_pop, n_push, f) && case_OP_ ## id, #define DEF(id, size, n_pop, n_push, f) && case_OP_ ## id,
#if SHORT_OPCODES
#define def(id, size, n_pop, n_push, f) #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" #include "quickjs-opcode.h"
[ OP_COUNT ... 255 ] = &&case_default [ 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)]); *sp++ = JS_DupValue(ctx, b->cpool[get_u32(pc)]);
pc += 4; pc += 4;
BREAK; BREAK;
#if SHORT_OPCODES
CASE(OP_push_minus1): CASE(OP_push_minus1):
CASE(OP_push_0): CASE(OP_push_0):
CASE(OP_push_1): CASE(OP_push_1):
@ -14306,7 +14300,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
sp[-1] = val; sp[-1] = val;
} }
BREAK; BREAK;
#endif
CASE(OP_push_atom_value): CASE(OP_push_atom_value):
*sp++ = JS_AtomToValue(ctx, get_u32(pc)); *sp++ = JS_AtomToValue(ctx, get_u32(pc));
pc += 4; pc += 4;
@ -14557,14 +14550,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
goto exception; goto exception;
} }
BREAK; BREAK;
#if SHORT_OPCODES
CASE(OP_call0): CASE(OP_call0):
CASE(OP_call1): CASE(OP_call1):
CASE(OP_call2): CASE(OP_call2):
CASE(OP_call3): CASE(OP_call3):
call_argc = opcode - OP_call0; call_argc = opcode - OP_call0;
goto has_call_argc; goto has_call_argc;
#endif
CASE(OP_call): CASE(OP_call):
CASE(OP_tail_call): CASE(OP_tail_call):
{ {
@ -14979,7 +14970,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
} }
BREAK; BREAK;
#if SHORT_OPCODES
CASE(OP_get_loc8): *sp++ = JS_DupValue(ctx, var_buf[*pc++]); BREAK; 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_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; 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_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_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; CASE(OP_set_var_ref3): set_value(ctx, var_refs[3]->pvalue, JS_DupValue(ctx, sp[-1])); BREAK;
#endif
CASE(OP_get_var_ref): 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))) if (unlikely(js_poll_interrupts(ctx)))
goto exception; goto exception;
BREAK; BREAK;
#if SHORT_OPCODES
CASE(OP_goto16): CASE(OP_goto16):
pc += (int16_t)get_u16(pc); pc += (int16_t)get_u16(pc);
if (unlikely(js_poll_interrupts(ctx))) 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))) if (unlikely(js_poll_interrupts(ctx)))
goto exception; goto exception;
BREAK; BREAK;
#endif
CASE(OP_if_true): CASE(OP_if_true):
{ {
int res; int res;
@ -15248,7 +15235,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
goto exception; goto exception;
} }
BREAK; BREAK;
#if SHORT_OPCODES
CASE(OP_if_true8): CASE(OP_if_true8):
{ {
int res; int res;
@ -15289,7 +15275,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
goto exception; goto exception;
} }
BREAK; BREAK;
#endif
CASE(OP_catch): CASE(OP_catch):
{ {
int32_t diff; int32_t diff;
@ -16498,7 +16483,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
} else { } else {
goto free_and_set_false; goto free_and_set_false;
} }
#if SHORT_OPCODES
CASE(OP_is_undefined): CASE(OP_is_undefined):
if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED) { if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_UNDEFINED) {
goto set_true; goto set_true;
@ -16527,7 +16511,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
} }
free_and_set_true: free_and_set_true:
JS_FreeValue(ctx, sp[-1]); JS_FreeValue(ctx, sp[-1]);
#endif
set_true: set_true:
sp[-1] = JS_TRUE; sp[-1] = JS_TRUE;
BREAK; BREAK;
@ -18001,7 +17984,6 @@ static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = {
#undef FMT #undef FMT
}; };
#if SHORT_OPCODES
/* After the final compilation pass, short opcodes are used. Their /* After the final compilation pass, short opcodes are used. Their
opcodes overlap with the temporary opcodes which cannot appear in opcodes overlap with the temporary opcodes which cannot appear in
the final bytecode. Their description is after the temporary 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) \ #define short_opcode_info(op) \
opcode_info[(op) >= OP_TEMP_START ? \ opcode_info[(op) >= OP_TEMP_START ? \
(op) + (OP_TEMP_END - OP_TEMP_START) : (op)] (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); 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:
case OP_throw_error: case OP_throw_error:
case OP_goto: case OP_goto:
#if SHORT_OPCODES
case OP_goto8: case OP_goto8:
case OP_goto16: case OP_goto16:
#endif
case OP_ret: case OP_ret:
return FALSE; return FALSE;
default: default:
@ -26672,7 +26649,6 @@ static void dump_byte_code(JSContext *ctx, int pass,
pos_next = pos + oi->size; pos_next = pos + oi->size;
if (op < OP_COUNT) { if (op < OP_COUNT) {
switch (oi->fmt) { switch (oi->fmt) {
#if SHORT_OPCODES
case OP_FMT_label8: case OP_FMT_label8:
pos++; pos++;
addr = (int8_t)tab[pos]; addr = (int8_t)tab[pos];
@ -26681,7 +26657,6 @@ static void dump_byte_code(JSContext *ctx, int pass,
pos++; pos++;
addr = (int16_t)get_u16(tab + pos); addr = (int16_t)get_u16(tab + pos);
goto has_addr; goto has_addr;
#endif
case OP_FMT_atom_label_u8: case OP_FMT_atom_label_u8:
case OP_FMT_atom_label_u16: case OP_FMT_atom_label_u16:
pos += 4; pos += 4;
@ -26795,14 +26770,12 @@ static void dump_byte_code(JSContext *ctx, int pass,
case OP_FMT_u32: case OP_FMT_u32:
printf(" %u", get_u32(tab + pos)); printf(" %u", get_u32(tab + pos));
break; break;
#if SHORT_OPCODES
case OP_FMT_label8: case OP_FMT_label8:
addr = get_i8(tab + pos); addr = get_i8(tab + pos);
goto has_addr1; goto has_addr1;
case OP_FMT_label16: case OP_FMT_label16:
addr = get_i16(tab + pos); addr = get_i16(tab + pos);
goto has_addr1; goto has_addr1;
#endif
case OP_FMT_label: case OP_FMT_label:
addr = get_u32(tab + pos); addr = get_u32(tab + pos);
goto has_addr1; goto has_addr1;
@ -26824,11 +26797,9 @@ static void dump_byte_code(JSContext *ctx, int pass,
printf(" %u", addr + pos); printf(" %u", addr + pos);
printf(",%u", get_u16(tab + pos + 4)); printf(",%u", get_u16(tab + pos + 4));
break; break;
#if SHORT_OPCODES
case OP_FMT_const8: case OP_FMT_const8:
idx = get_u8(tab + pos); idx = get_u8(tab + pos);
goto has_pool_idx; goto has_pool_idx;
#endif
case OP_FMT_const: case OP_FMT_const:
idx = get_u32(tab + pos); idx = get_u32(tab + pos);
goto has_pool_idx; 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) static void push_short_int(DynBuf *bc_out, int val)
{ {
#if SHORT_OPCODES
if (val >= -1 && val <= 7) { if (val >= -1 && val <= 7) {
dbuf_putc(bc_out, OP_push_0 + val); dbuf_putc(bc_out, OP_push_0 + val);
return; return;
@ -29028,14 +28998,12 @@ static void push_short_int(DynBuf *bc_out, int val)
dbuf_put_u16(bc_out, val); dbuf_put_u16(bc_out, val);
return; return;
} }
#endif
dbuf_putc(bc_out, OP_push_i32); dbuf_putc(bc_out, OP_push_i32);
dbuf_put_u32(bc_out, val); dbuf_put_u32(bc_out, val);
} }
static void put_short_code(DynBuf *bc_out, int op, int idx) static void put_short_code(DynBuf *bc_out, int op, int idx)
{ {
#if SHORT_OPCODES
if (idx < 4) { if (idx < 4) {
switch (op) { switch (op) {
case OP_get_loc: case OP_get_loc:
@ -29086,7 +29054,6 @@ static void put_short_code(DynBuf *bc_out, int op, int idx)
return; return;
} }
} }
#endif
dbuf_putc(bc_out, op); dbuf_putc(bc_out, op);
dbuf_put_u16(bc_out, idx); 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 */ /* peephole optimizations and resolve goto/labels */
static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) 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; const uint8_t *bc_buf;
DynBuf bc_out; DynBuf bc_out;
LabelSlot *label_slots, *ls; LabelSlot *label_slots, *ls;
RelocEntry *re, *re_next; RelocEntry *re, *re_next;
CodeContext cc; CodeContext cc;
int label; int label;
#if SHORT_OPCODES
JumpSlot *jp; JumpSlot *jp;
#endif
label_slots = s->label_slots; 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; cc.bc_len = bc_len = s->byte_code.size;
js_dbuf_init(ctx, &bc_out); js_dbuf_init(ctx, &bc_out);
#if SHORT_OPCODES
if (s->jump_size) { if (s->jump_size) {
s->jump_slots = js_mallocz(s->ctx, sizeof(*s->jump_slots) * s->jump_size); s->jump_slots = js_mallocz(s->ctx, sizeof(*s->jump_slots) * s->jump_size);
if (s->jump_slots == NULL) if (s->jump_slots == NULL)
return -1; return -1;
} }
#endif
/* XXX: Should skip this phase if not generating SHORT_OPCODES */
if (s->line_number_size) { if (s->line_number_size) {
s->line_number_slots = js_mallocz(s->ctx, sizeof(*s->line_number_slots) * 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) 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); assert(label >= 0 && label < s->label_count);
ls = &label_slots[label]; ls = &label_slots[label];
#if SHORT_OPCODES
jp = &s->jump_slots[s->jump_count++]; jp = &s->jump_slots[s->jump_count++];
jp->op = op; jp->op = op;
jp->size = 4; jp->size = 4;
@ -29371,7 +29333,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
break; break;
} }
} }
#endif
dbuf_putc(&bc_out, op); dbuf_putc(&bc_out, op);
dbuf_put_u32(&bc_out, ls->addr - bc_out.size); dbuf_put_u32(&bc_out, ls->addr - bc_out.size);
if (ls->addr == -1) { if (ls->addr == -1) {
@ -29397,13 +29358,11 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
assert(label >= 0 && label < s->label_count); assert(label >= 0 && label < s->label_count);
ls = &label_slots[label]; ls = &label_slots[label];
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
#if SHORT_OPCODES
jp = &s->jump_slots[s->jump_count++]; jp = &s->jump_slots[s->jump_count++];
jp->op = op; jp->op = op;
jp->size = 4; jp->size = 4;
jp->pos = bc_out.size + 5; jp->pos = bc_out.size + 5;
jp->label = label; jp->label = label;
#endif
dbuf_putc(&bc_out, op); dbuf_putc(&bc_out, op);
dbuf_put_u32(&bc_out, atom); dbuf_put_u32(&bc_out, atom);
dbuf_put_u32(&bc_out, ls->addr - bc_out.size); 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; goto no_change;
case OP_null: case OP_null:
#if SHORT_OPCODES
/* transform null strict_eq into is_null */ /* transform null strict_eq into is_null */
if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (code_match(&cc, pos_next, OP_strict_eq, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num; 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; op = cc.op ^ OP_if_false ^ OP_if_true;
goto has_label; goto has_label;
} }
#endif
/* fall thru */ /* fall thru */
case OP_push_false: case OP_push_false:
case OP_push_true: case OP_push_true:
@ -29501,7 +29458,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
push_short_int(&bc_out, val); push_short_int(&bc_out, val);
break; break;
#if SHORT_OPCODES
case OP_push_const: case OP_push_const:
case OP_fclosure: case OP_fclosure:
{ {
@ -29526,7 +29482,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
} }
} }
goto no_change; goto no_change;
#endif
case OP_push_atom_value: case OP_push_atom_value:
{ {
JSAtom atom = get_u32(bc_buf + pos + 1); 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; pos_next = cc.pos;
break; break;
} }
#if SHORT_OPCODES
if (atom == JS_ATOM_empty_string) { if (atom == JS_ATOM_empty_string) {
JS_FreeAtom(ctx, atom); JS_FreeAtom(ctx, atom);
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_push_empty_string); dbuf_putc(&bc_out, OP_push_empty_string);
break; break;
} }
#endif
} }
goto no_change; goto no_change;
@ -29578,7 +29532,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
val = 0; val = 0;
goto has_constant_test; goto has_constant_test;
} }
#if SHORT_OPCODES
/* transform undefined strict_eq -> is_undefined */ /* transform undefined strict_eq -> is_undefined */
if (code_match(&cc, pos_next, OP_strict_eq, -1)) { if (code_match(&cc, pos_next, OP_strict_eq, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num; 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; op = cc.op ^ OP_if_false ^ OP_if_true;
goto has_label; goto has_label;
} }
#endif
goto no_change; goto no_change;
case OP_insert2: 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 (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; if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
#if SHORT_OPCODES
if (cc.atom == JS_ATOM_empty_string) { if (cc.atom == JS_ATOM_empty_string) {
JS_FreeAtom(ctx, cc.atom); JS_FreeAtom(ctx, cc.atom);
dbuf_putc(&bc_out, OP_push_empty_string); dbuf_putc(&bc_out, OP_push_empty_string);
} else } else {
#endif
{
dbuf_putc(&bc_out, OP_push_atom_value); dbuf_putc(&bc_out, OP_push_atom_value);
dbuf_put_u32(&bc_out, cc.atom); 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); put_short_code(&bc_out, op, idx);
} }
break; break;
#if SHORT_OPCODES
case OP_get_arg: case OP_get_arg:
case OP_get_var_ref: 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); put_short_code(&bc_out, op, idx);
} }
break; break;
#endif
case OP_put_loc: case OP_put_loc:
case OP_put_arg: case OP_put_arg:
case OP_put_var_ref: case OP_put_var_ref:
@ -29789,7 +29736,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
} }
goto no_change; goto no_change;
#if SHORT_OPCODES
case OP_typeof: case OP_typeof:
/* simplify typeof tests */ /* 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)) { 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; goto no_change;
#endif
default: default:
no_change: no_change:
@ -29841,85 +29786,84 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
for(i = 0; i < s->label_count; i++) { for(i = 0; i < s->label_count; i++) {
assert(label_slots[i].first_reloc == NULL); 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; /* more jump optimizations */
switch (op = jp->op) { patch_offsets = 0;
case OP_goto16: for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) {
delta = 1; LabelSlot *ls;
/* fall thru */ JumpSlot *jp1;
case OP_if_false: int j, pos, diff, delta;
case OP_if_true:
case OP_goto: delta = 3;
pos = jp->pos; switch (op = jp->op) {
diff = s->label_slots[jp->label].addr - pos; case OP_goto16:
if (diff >= -128 && diff <= 127 + delta) { delta = 1;
//put_u8(bc_out.buf + pos, diff); /* fall thru */
jp->size = 1; case OP_if_false:
if (op == OP_goto16) { case OP_if_true:
bc_out.buf[pos - 1] = jp->op = OP_goto8; case OP_goto:
} else { pos = jp->pos;
bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false); diff = s->label_slots[jp->label].addr - pos;
} if (diff >= -128 && diff <= 127 + delta) {
goto shrink; //put_u8(bc_out.buf + pos, diff);
} else jp->size = 1;
if (diff == (int16_t)diff && op == OP_goto) { if (op == OP_goto16) {
//put_u16(bc_out.buf + pos, diff); bc_out.buf[pos - 1] = jp->op = OP_goto8;
jp->size = 2; } else {
delta = 2; bc_out.buf[pos - 1] = jp->op = OP_if_false8 + (op - OP_if_false);
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;
} }
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; 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); js_free(ctx, s->jump_slots);
s->jump_slots = NULL; s->jump_slots = NULL;
#endif
js_free(ctx, s->label_slots); js_free(ctx, s->label_slots);
s->label_slots = NULL; s->label_slots = NULL;
/* XXX: should delay until copying to runtime bytecode function */ /* 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 */ /* call pops a variable number of arguments */
if (oi->fmt == OP_FMT_npop || oi->fmt == OP_FMT_npop_u16) { if (oi->fmt == OP_FMT_npop || oi->fmt == OP_FMT_npop_u16) {
n_pop += get_u16(bc_buf + pos + 1); n_pop += get_u16(bc_buf + pos + 1);
} else { } else if (oi->fmt == OP_FMT_npopx) {
#if SHORT_OPCODES n_pop += op - OP_call0;
if (oi->fmt == OP_FMT_npopx) {
n_pop += op - OP_call0;
}
#endif
} }
if (stack_len < n_pop) { if (stack_len < n_pop) {
@ -30068,7 +30008,6 @@ static __exception int compute_stack_size(JSContext *ctx,
diff = get_u32(bc_buf + pos + 1); diff = get_u32(bc_buf + pos + 1);
pos_next = pos + 1 + diff; pos_next = pos + 1 + diff;
break; break;
#if SHORT_OPCODES
case OP_goto16: case OP_goto16:
diff = (int16_t)get_u16(bc_buf + pos + 1); diff = (int16_t)get_u16(bc_buf + pos + 1);
pos_next = pos + 1 + diff; 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)) if (ss_check(ctx, s, pos + 1 + diff, op, stack_len))
goto fail; goto fail;
break; break;
#endif
case OP_if_true: case OP_if_true:
case OP_if_false: case OP_if_false:
case OP_catch: case OP_catch: