Remove broken OPTIMIZE=0 build mode (#47)
This commit is contained in:
parent
162a8b7409
commit
a92e74acac
1 changed files with 217 additions and 254 deletions
471
quickjs.c
471
quickjs.c
|
@ -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++) {
|
||||||
|
|
Loading…
Reference in a new issue