Remove broken OPTIMIZE=0 build mode (#47)

This commit is contained in:
Ben Noordhuis 2023-11-12 13:34:08 +01:00 committed by GitHub
parent 162a8b7409
commit a92e74acac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

471
quickjs.c
View file

@ -46,7 +46,6 @@
#include "libregexp.h" #include "libregexp.h"
#include "libbf.h" #include "libbf.h"
#define OPTIMIZE 1
#define SHORT_OPCODES 1 #define SHORT_OPCODES 1
#if defined(EMSCRIPTEN) #if defined(EMSCRIPTEN)
#define DIRECT_DISPATCH 0 #define DIRECT_DISPATCH 0
@ -23891,7 +23890,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
if (js_parse_expect(s, ')')) if (js_parse_expect(s, ')'))
return -1; return -1;
if (OPTIMIZE) { {
/* move the `next` code here */ /* move the `next` code here */
DynBuf *bc = &s->cur_func->byte_code; DynBuf *bc = &s->cur_func->byte_code;
int chunk_size = pos_expr - pos_next; int chunk_size = pos_expr - pos_next;
@ -24283,7 +24282,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
/* XXX: check continue case */ /* XXX: check continue case */
close_scopes(s, s->cur_func->scope_level, block_scope_level); close_scopes(s, s->cur_func->scope_level, block_scope_level);
if (OPTIMIZE && label_test != label_body && label_cont != label_test) { if (label_test != label_body && label_cont != label_test) {
/* move the increment code here */ /* move the increment code here */
DynBuf *bc = &s->cur_func->byte_code; DynBuf *bc = &s->cur_func->byte_code;
int chunk_size = pos_body - pos_cont; int chunk_size = pos_body - pos_cont;
@ -28653,7 +28652,7 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s)
break; break;
case OP_gosub: case OP_gosub:
s->jump_size++; s->jump_size++;
if (OPTIMIZE) { {
/* remove calls to empty finalizers */ /* remove calls to empty finalizers */
int label; int label;
LabelSlot *ls; LabelSlot *ls;
@ -28691,19 +28690,17 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s)
} }
goto no_change; goto no_change;
case OP_insert3: case OP_insert3:
if (OPTIMIZE) { /* Transformation: insert3 put_array_el|put_ref_value drop -> put_array_el|put_ref_value */
/* Transformation: insert3 put_array_el|put_ref_value drop -> put_array_el|put_ref_value */ if (code_match(&cc, pos_next, M2(OP_put_array_el, OP_put_ref_value), OP_drop, -1)) {
if (code_match(&cc, pos_next, M2(OP_put_array_el, OP_put_ref_value), OP_drop, -1)) { dbuf_putc(&bc_out, cc.op);
dbuf_putc(&bc_out, cc.op); pos_next = cc.pos;
pos_next = cc.pos; if (cc.line_num != -1 && cc.line_num != line_num) {
if (cc.line_num != -1 && cc.line_num != line_num) { line_num = cc.line_num;
line_num = cc.line_num; s->line_number_size++;
s->line_number_size++; dbuf_putc(&bc_out, OP_line_num);
dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num);
dbuf_put_u32(&bc_out, line_num);
}
break;
} }
break;
} }
goto no_change; goto no_change;
@ -28717,7 +28714,7 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s)
case OP_throw: case OP_throw:
case OP_throw_error: case OP_throw_error:
case OP_ret: case OP_ret:
if (OPTIMIZE) { {
/* remove dead code */ /* remove dead code */
int line = -1; int line = -1;
dbuf_put(&bc_out, bc_buf + pos, len); dbuf_put(&bc_out, bc_buf + pos, len);
@ -28814,34 +28811,32 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s)
goto no_change; goto no_change;
case OP_dup: case OP_dup:
if (OPTIMIZE) { /* Transformation: dup if_false(l1) drop, l1: if_false(l2) -> if_false(l2) */
/* Transformation: dup if_false(l1) drop, l1: if_false(l2) -> if_false(l2) */ /* Transformation: dup if_true(l1) drop, l1: if_true(l2) -> if_true(l2) */
/* Transformation: dup if_true(l1) drop, l1: if_true(l2) -> if_true(l2) */ if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), OP_drop, -1)) {
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), OP_drop, -1)) { int lab0, lab1, op1, pos1, line1, pos2;
int lab0, lab1, op1, pos1, line1, pos2; lab0 = lab1 = cc.label;
lab0 = lab1 = cc.label; assert(lab1 >= 0 && lab1 < s->label_count);
assert(lab1 >= 0 && lab1 < s->label_count); op1 = cc.op;
op1 = cc.op; pos1 = cc.pos;
pos1 = cc.pos; line1 = cc.line_num;
line1 = cc.line_num; while (code_match(&cc, (pos2 = get_label_pos(s, lab1)), OP_dup, op1, OP_drop, -1)) {
while (code_match(&cc, (pos2 = get_label_pos(s, lab1)), OP_dup, op1, OP_drop, -1)) { lab1 = cc.label;
lab1 = cc.label; }
} if (code_match(&cc, pos2, op1, -1)) {
if (code_match(&cc, pos2, op1, -1)) { s->jump_size++;
s->jump_size++; update_label(s, lab0, -1);
update_label(s, lab0, -1); update_label(s, cc.label, +1);
update_label(s, cc.label, +1); dbuf_putc(&bc_out, op1);
dbuf_putc(&bc_out, op1); dbuf_put_u32(&bc_out, cc.label);
dbuf_put_u32(&bc_out, cc.label); pos_next = pos1;
pos_next = pos1; if (line1 != -1 && line1 != line_num) {
if (line1 != -1 && line1 != line_num) { line_num = line1;
line_num = line1; s->line_number_size++;
s->line_number_size++; dbuf_putc(&bc_out, OP_line_num);
dbuf_putc(&bc_out, OP_line_num); dbuf_put_u32(&bc_out, line_num);
dbuf_put_u32(&bc_out, line_num);
}
break;
} }
break;
} }
} }
goto no_change; goto no_change;
@ -29267,7 +29262,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
case OP_goto: case OP_goto:
label = get_u32(bc_buf + pos + 1); label = get_u32(bc_buf + pos + 1);
has_goto: has_goto:
if (OPTIMIZE) { {
int line1 = -1; int line1 = -1;
/* Use custom matcher because multiple labels can follow */ /* Use custom matcher because multiple labels can follow */
label = find_jump_target(s, label, &op1, &line1); label = find_jump_target(s, label, &op1, &line1);
@ -29297,14 +29292,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
case OP_gosub: case OP_gosub:
label = get_u32(bc_buf + pos + 1); label = get_u32(bc_buf + pos + 1);
if (0 && OPTIMIZE) {
label = find_jump_target(s, label, &op1, NULL);
if (op1 == OP_ret) {
update_label(s, label, -1);
/* empty finally clause: remove gosub */
break;
}
}
goto has_label; goto has_label;
case OP_catch: case OP_catch:
@ -29314,25 +29301,23 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
case OP_if_true: case OP_if_true:
case OP_if_false: case OP_if_false:
label = get_u32(bc_buf + pos + 1); label = get_u32(bc_buf + pos + 1);
if (OPTIMIZE) { label = find_jump_target(s, label, &op1, NULL);
label = find_jump_target(s, label, &op1, NULL); /* transform if_false/if_true(l1) label(l1) -> drop label(l1) */
/* transform if_false/if_true(l1) label(l1) -> drop label(l1) */ if (code_has_label(&cc, pos_next, label)) {
if (code_has_label(&cc, pos_next, label)) { update_label(s, label, -1);
dbuf_putc(&bc_out, OP_drop);
break;
}
/* transform if_false(l1) goto(l2) label(l1) -> if_false(l2) label(l1) */
if (code_match(&cc, pos_next, OP_goto, -1)) {
int pos1 = cc.pos;
int line1 = cc.line_num;
if (code_has_label(&cc, pos1, label)) {
if (line1 >= 0) line_num = line1;
pos_next = pos1;
update_label(s, label, -1); update_label(s, label, -1);
dbuf_putc(&bc_out, OP_drop); label = cc.label;
break; op ^= OP_if_true ^ OP_if_false;
}
/* transform if_false(l1) goto(l2) label(l1) -> if_false(l2) label(l1) */
if (code_match(&cc, pos_next, OP_goto, -1)) {
int pos1 = cc.pos;
int line1 = cc.line_num;
if (code_has_label(&cc, pos1, label)) {
if (line1 >= 0) line_num = line1;
pos_next = pos1;
update_label(s, label, -1);
label = cc.label;
op ^= OP_if_true ^ OP_if_false;
}
} }
} }
has_label: has_label:
@ -29408,9 +29393,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
atom = get_u32(bc_buf + pos + 1); atom = get_u32(bc_buf + pos + 1);
label = get_u32(bc_buf + pos + 5); label = get_u32(bc_buf + pos + 5);
is_with = bc_buf[pos + 9]; is_with = bc_buf[pos + 9];
if (OPTIMIZE) { label = find_jump_target(s, label, &op1, NULL);
label = find_jump_target(s, label, &op1, NULL);
}
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);
@ -29434,103 +29417,94 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
break; break;
case OP_drop: case OP_drop:
if (OPTIMIZE) { /* remove useless drops before return */
/* remove useless drops before return */ if (code_match(&cc, pos_next, OP_return_undef, -1)) {
if (code_match(&cc, pos_next, OP_return_undef, -1)) { if (cc.line_num >= 0) line_num = cc.line_num;
if (cc.line_num >= 0) line_num = cc.line_num; break;
break;
}
} }
goto no_change; goto no_change;
case OP_null: case OP_null:
#if SHORT_OPCODES #if SHORT_OPCODES
if (OPTIMIZE) { /* 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; add_pc2line_info(s, bc_out.size, line_num);
add_pc2line_info(s, bc_out.size, line_num); dbuf_putc(&bc_out, OP_is_null);
dbuf_putc(&bc_out, OP_is_null); pos_next = cc.pos;
pos_next = cc.pos; break;
break; }
} /* transform null strict_neq if_false/if_true -> is_null if_true/if_false */
/* transform null strict_neq if_false/if_true -> is_null if_true/if_false */ if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -1)) {
if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -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); dbuf_putc(&bc_out, OP_is_null);
dbuf_putc(&bc_out, OP_is_null); pos_next = cc.pos;
pos_next = cc.pos; label = cc.label;
label = cc.label; 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 #endif
/* fall thru */ /* fall thru */
case OP_push_false: case OP_push_false:
case OP_push_true: case OP_push_true:
if (OPTIMIZE) { val = (op == OP_push_true);
val = (op == OP_push_true); if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) {
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) { has_constant_test:
has_constant_test: if (cc.line_num >= 0) line_num = cc.line_num;
if (cc.line_num >= 0) line_num = cc.line_num; if (val == cc.op - OP_if_false) {
if (val == cc.op - OP_if_false) { /* transform null if_false(l1) -> goto l1 */
/* transform null if_false(l1) -> goto l1 */ /* transform false if_false(l1) -> goto l1 */
/* transform false if_false(l1) -> goto l1 */ /* transform true if_true(l1) -> goto l1 */
/* transform true if_true(l1) -> goto l1 */ pos_next = cc.pos;
pos_next = cc.pos; op = OP_goto;
op = OP_goto; label = cc.label;
label = cc.label; goto has_goto;
goto has_goto; } else {
} else { /* transform null if_true(l1) -> nop */
/* transform null if_true(l1) -> nop */ /* transform false if_true(l1) -> nop */
/* transform false if_true(l1) -> nop */ /* transform true if_false(l1) -> nop */
/* transform true if_false(l1) -> nop */ pos_next = cc.pos;
pos_next = cc.pos; update_label(s, cc.label, -1);
update_label(s, cc.label, -1); break;
break;
}
} }
} }
goto no_change; goto no_change;
case OP_push_i32: case OP_push_i32:
if (OPTIMIZE) { /* transform i32(val) neg -> i32(-val) */
/* transform i32(val) neg -> i32(-val) */ val = get_i32(bc_buf + pos + 1);
val = get_i32(bc_buf + pos + 1); if ((val != INT32_MIN && val != 0)
if ((val != INT32_MIN && val != 0) && code_match(&cc, pos_next, OP_neg, -1)) {
&& code_match(&cc, pos_next, OP_neg, -1)) { if (cc.line_num >= 0) line_num = cc.line_num;
if (code_match(&cc, cc.pos, OP_drop, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num; if (cc.line_num >= 0) line_num = cc.line_num;
if (code_match(&cc, cc.pos, OP_drop, -1)) { } else {
if (cc.line_num >= 0) line_num = cc.line_num; add_pc2line_info(s, bc_out.size, line_num);
} else { push_short_int(&bc_out, -val);
add_pc2line_info(s, bc_out.size, line_num);
push_short_int(&bc_out, -val);
}
pos_next = cc.pos;
break;
} }
/* remove push/drop pairs generated by the parser */ pos_next = cc.pos;
if (code_match(&cc, pos_next, OP_drop, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
pos_next = cc.pos;
break;
}
/* Optimize constant tests: `if (0)`, `if (1)`, `if (!0)`... */
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) {
val = (val != 0);
goto has_constant_test;
}
add_pc2line_info(s, bc_out.size, line_num);
push_short_int(&bc_out, val);
break; break;
} }
goto no_change; /* remove push/drop pairs generated by the parser */
if (code_match(&cc, pos_next, OP_drop, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
pos_next = cc.pos;
break;
}
/* Optimize constant tests: `if (0)`, `if (1)`, `if (!0)`... */
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) {
val = (val != 0);
goto has_constant_test;
}
add_pc2line_info(s, bc_out.size, line_num);
push_short_int(&bc_out, val);
break;
#if SHORT_OPCODES #if SHORT_OPCODES
case OP_push_const: case OP_push_const:
case OP_fclosure: case OP_fclosure:
if (OPTIMIZE) { {
int idx = get_u32(bc_buf + pos + 1); int idx = get_u32(bc_buf + pos + 1);
if (idx < 256) { if (idx < 256) {
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
@ -29542,7 +29516,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
goto no_change; goto no_change;
case OP_get_field: case OP_get_field:
if (OPTIMIZE) { {
JSAtom atom = get_u32(bc_buf + pos + 1); JSAtom atom = get_u32(bc_buf + pos + 1);
if (atom == JS_ATOM_length) { if (atom == JS_ATOM_length) {
JS_FreeAtom(ctx, atom); JS_FreeAtom(ctx, atom);
@ -29554,7 +29528,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
goto no_change; goto no_change;
#endif #endif
case OP_push_atom_value: case OP_push_atom_value:
if (OPTIMIZE) { {
JSAtom atom = get_u32(bc_buf + pos + 1); JSAtom atom = get_u32(bc_buf + pos + 1);
/* remove push/drop pairs generated by the parser */ /* remove push/drop pairs generated by the parser */
if (code_match(&cc, pos_next, OP_drop, -1)) { if (code_match(&cc, pos_next, OP_drop, -1)) {
@ -29576,79 +29550,73 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
case OP_to_propkey: case OP_to_propkey:
case OP_to_propkey2: case OP_to_propkey2:
if (OPTIMIZE) { /* remove redundant to_propkey/to_propkey2 opcodes when storing simple data */
/* remove redundant to_propkey/to_propkey2 opcodes when storing simple data */ if (code_match(&cc, pos_next, M3(OP_get_loc, OP_get_arg, OP_get_var_ref), -1, OP_put_array_el, -1)
if (code_match(&cc, pos_next, M3(OP_get_loc, OP_get_arg, OP_get_var_ref), -1, OP_put_array_el, -1) || code_match(&cc, pos_next, M3(OP_push_i32, OP_push_const, OP_push_atom_value), OP_put_array_el, -1)
|| code_match(&cc, pos_next, M3(OP_push_i32, OP_push_const, OP_push_atom_value), OP_put_array_el, -1) || code_match(&cc, pos_next, M4(OP_undefined, OP_null, OP_push_true, OP_push_false), OP_put_array_el, -1)) {
|| code_match(&cc, pos_next, M4(OP_undefined, OP_null, OP_push_true, OP_push_false), OP_put_array_el, -1)) { break;
break;
}
} }
goto no_change; goto no_change;
case OP_undefined: case OP_undefined:
if (OPTIMIZE) { /* remove push/drop pairs generated by the parser */
/* remove push/drop pairs generated by the parser */ if (code_match(&cc, pos_next, OP_drop, -1)) {
if (code_match(&cc, pos_next, OP_drop, -1)) { if (cc.line_num >= 0) line_num = cc.line_num;
if (cc.line_num >= 0) line_num = cc.line_num; pos_next = cc.pos;
pos_next = cc.pos; break;
break;
}
/* transform undefined return -> return_undefined */
if (code_match(&cc, pos_next, OP_return, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_return_undef);
pos_next = cc.pos;
break;
}
/* transform undefined if_true(l1)/if_false(l1) -> nop/goto(l1) */
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) {
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;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_is_undefined);
pos_next = cc.pos;
break;
}
/* transform undefined strict_neq if_false/if_true -> is_undefined if_true/if_false */
if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_is_undefined);
pos_next = cc.pos;
label = cc.label;
op = cc.op ^ OP_if_false ^ OP_if_true;
goto has_label;
}
#endif
} }
/* transform undefined return -> return_undefined */
if (code_match(&cc, pos_next, OP_return, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_return_undef);
pos_next = cc.pos;
break;
}
/* transform undefined if_true(l1)/if_false(l1) -> nop/goto(l1) */
if (code_match(&cc, pos_next, M2(OP_if_false, OP_if_true), -1)) {
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;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_is_undefined);
pos_next = cc.pos;
break;
}
/* transform undefined strict_neq if_false/if_true -> is_undefined if_true/if_false */
if (code_match(&cc, pos_next, OP_strict_neq, M2(OP_if_false, OP_if_true), -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_is_undefined);
pos_next = cc.pos;
label = cc.label;
op = cc.op ^ OP_if_false ^ OP_if_true;
goto has_label;
}
#endif
goto no_change; goto no_change;
case OP_insert2: case OP_insert2:
if (OPTIMIZE) { /* Transformation:
/* Transformation: insert2 put_field(a) drop -> put_field(a)
insert2 put_field(a) drop -> put_field(a) insert2 put_var_strict(a) drop -> put_var_strict(a)
insert2 put_var_strict(a) drop -> put_var_strict(a) */
*/ if (code_match(&cc, pos_next, M2(OP_put_field, OP_put_var_strict), OP_drop, -1)) {
if (code_match(&cc, pos_next, M2(OP_put_field, OP_put_var_strict), 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); dbuf_putc(&bc_out, cc.op);
dbuf_putc(&bc_out, cc.op); dbuf_put_u32(&bc_out, cc.atom);
dbuf_put_u32(&bc_out, cc.atom); pos_next = cc.pos;
pos_next = cc.pos; break;
break;
}
} }
goto no_change; goto no_change;
case OP_dup: case OP_dup:
if (OPTIMIZE) { {
/* Transformation: dup put_x(n) drop -> put_x(n) */ /* Transformation: dup put_x(n) drop -> put_x(n) */
int op1, line2 = -1; int op1, line2 = -1;
/* Transformation: dup put_x(n) -> set_x(n) */ /* Transformation: dup put_x(n) -> set_x(n) */
@ -29675,7 +29643,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
goto no_change; goto no_change;
case OP_get_loc: case OP_get_loc:
if (OPTIMIZE) { {
/* transformation: /* transformation:
get_loc(n) post_dec put_loc(n) drop -> dec_loc(n) get_loc(n) post_dec put_loc(n) drop -> dec_loc(n)
get_loc(n) post_inc put_loc(n) drop -> inc_loc(n) get_loc(n) post_inc put_loc(n) drop -> inc_loc(n)
@ -29744,25 +29712,23 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
} }
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
put_short_code(&bc_out, op, idx); put_short_code(&bc_out, op, idx);
break;
} }
goto no_change; break;
#if SHORT_OPCODES #if SHORT_OPCODES
case OP_get_arg: case OP_get_arg:
case OP_get_var_ref: case OP_get_var_ref:
if (OPTIMIZE) { {
int idx; int idx;
idx = get_u16(bc_buf + pos + 1); idx = get_u16(bc_buf + pos + 1);
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
put_short_code(&bc_out, op, idx); put_short_code(&bc_out, op, idx);
break;
} }
goto no_change; break;
#endif #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:
if (OPTIMIZE) { {
/* transformation: put_x(n) get_x(n) -> set_x(n) */ /* transformation: put_x(n) get_x(n) -> set_x(n) */
int idx; int idx;
idx = get_u16(bc_buf + pos + 1); idx = get_u16(bc_buf + pos + 1);
@ -29775,13 +29741,12 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
} }
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
put_short_code(&bc_out, op, idx); put_short_code(&bc_out, op, idx);
break;
} }
goto no_change; break;
case OP_post_inc: case OP_post_inc:
case OP_post_dec: case OP_post_dec:
if (OPTIMIZE) { {
/* transformation: /* transformation:
post_inc put_x drop -> inc put_x post_inc put_x drop -> inc put_x
post_inc perm3 put_field drop -> inc put_field post_inc perm3 put_field drop -> inc put_field
@ -29826,40 +29791,38 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
#if SHORT_OPCODES #if SHORT_OPCODES
case OP_typeof: case OP_typeof:
if (OPTIMIZE) { /* 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)) { if (cc.line_num >= 0) line_num = cc.line_num;
if (cc.line_num >= 0) line_num = cc.line_num; int op1 = (cc.op == OP_strict_eq || cc.op == OP_eq) ? OP_strict_eq : OP_strict_neq;
int op1 = (cc.op == OP_strict_eq || cc.op == OP_eq) ? OP_strict_eq : OP_strict_neq; int op2 = -1;
int op2 = -1; switch (cc.atom) {
switch (cc.atom) { case JS_ATOM_undefined:
case JS_ATOM_undefined: op2 = OP_typeof_is_undefined;
op2 = OP_typeof_is_undefined; break;
break; case JS_ATOM_function:
case JS_ATOM_function: op2 = OP_typeof_is_function;
op2 = OP_typeof_is_function; break;
}
if (op2 >= 0) {
/* transform typeof(s) == "<type>" into is_<type> */
if (op1 == OP_strict_eq) {
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, op2);
JS_FreeAtom(ctx, cc.atom);
pos_next = cc.pos;
break; break;
} }
if (op2 >= 0) { if (op1 == OP_strict_neq && code_match(&cc, cc.pos, OP_if_false, -1)) {
/* transform typeof(s) == "<type>" into is_<type> */ /* transform typeof(s) != "<type>" if_false into is_<type> if_true */
if (op1 == OP_strict_eq) { 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);
dbuf_putc(&bc_out, op2); dbuf_putc(&bc_out, op2);
JS_FreeAtom(ctx, cc.atom); JS_FreeAtom(ctx, cc.atom);
pos_next = cc.pos; pos_next = cc.pos;
break; label = cc.label;
} op = OP_if_true;
if (op1 == OP_strict_neq && code_match(&cc, cc.pos, OP_if_false, -1)) { goto has_label;
/* transform typeof(s) != "<type>" if_false into is_<type> if_true */
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, op2);
JS_FreeAtom(ctx, cc.atom);
pos_next = cc.pos;
label = cc.label;
op = OP_if_true;
goto has_label;
}
} }
} }
} }
@ -29879,7 +29842,7 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
assert(label_slots[i].first_reloc == NULL); assert(label_slots[i].first_reloc == NULL);
} }
#if SHORT_OPCODES #if SHORT_OPCODES
if (OPTIMIZE) { {
/* more jump optimizations */ /* more jump optimizations */
int patch_offsets = 0; int patch_offsets = 0;
for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) { for (i = 0, jp = s->jump_slots; i < s->jump_count; i++, jp++) {