Browse Source

Add DUK_USE_SHUFFLE_TORTURE to compiler

- Feature detection.

- Commented out shuffle torture flag to Makefile.

- Compiler fixes to support shuffle torture: must flag even small values
  with shuffle prevention flags so that they don't get shuffled forcibly.
  These are not bugs as such because small flags fields are never shuffled
  in normal operation.  But it's cleaner to flag fields semantically anyway.

- Need as variant of loadint helper to avoid shuffling when duk__emit_xxx()
  functions emit loadint for indirect opcodes like MPUTOBJI.

- Use negative "no shuffle" marker for output shuffle registers; when
  shuffle torture is enabled even a zero register is shuffled.

- Other minor fixes
pull/156/head
Sami Vaarala 10 years ago
parent
commit
78d3c596dd
  1. 1
      Makefile
  2. 5
      src/duk_features.h.in
  3. 151
      src/duk_js_compiler.c

1
Makefile

@ -188,6 +188,7 @@ CCOPTS_FEATURES += -DDUK_OPT_SELF_TESTS
#CCOPTS_FEATURES += -DDUK_OPT_NO_PC2LINE
#CCOPTS_FEATURES += -DDUK_OPT_NO_VERBOSE_ERRORS
#CCOPTS_FEATURES += -DDUK_OPT_GC_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_SHUFFLE_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_NO_MS_RESIZE_STRINGTABLE
CCOPTS_FEATURES += -DDUK_OPT_DEBUG_BUFSIZE=512
#CCOPTS_FEATURES += -DDUK_OPT_NO_STRICT_DECL

5
src/duk_features.h.in

@ -2648,6 +2648,11 @@ typedef FILE duk_file;
#define DUK_USE_ESBC_MAX_LINENUMBER 0x7fff0000L
#define DUK_USE_ESBC_MAX_BYTES 0x7fff0000L
#undef DUK_USE_SHUFFLE_TORTURE
#if defined(DUK_OPT_SHUFFLE_TORTURE)
#define DUK_USE_SHUFFLE_TORTURE
#endif
/*
* User panic handler, panic exit behavior for default panic handler
*/

151
src/duk_js_compiler.c

@ -108,6 +108,7 @@ DUK_LOCAL_DECL void duk__emit_extraop_b(duk_compiler_ctx *comp_ctx, duk_small_ui
DUK_LOCAL_DECL void duk__emit_extraop_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop, duk_regconst_t bc);
DUK_LOCAL_DECL void duk__emit_extraop_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop_flags);
DUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val);
DUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val);
DUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);
DUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);
DUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);
@ -1128,9 +1129,9 @@ DUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op
/* Important main primitive. */
DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c) {
duk_instr_t ins = 0;
duk_int_t a_out = 0;
duk_int_t b_out = 0;
duk_int_t c_out = 0;
duk_int_t a_out = -1;
duk_int_t b_out = -1;
duk_int_t c_out = -1;
duk_int_t tmp;
DUK_DDD(DUK_DDDPRINT("emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld",
@ -1154,7 +1155,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
/* Slot A */
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {
#else
if (a <= DUK_BC_A_MAX) {
#endif
;
} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {
DUK_D(DUK_DPRINT("out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld", (long) a));
@ -1171,7 +1176,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
* is expressed indirectly, but there is no output shuffling.
*/
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) == 0);
duk__emit_load_int32(comp_ctx, tmp, a);
duk__emit_load_int32_noshuffle(comp_ctx, tmp, a);
DUK_ASSERT(DUK_OP_CSVARI == DUK_OP_CSVAR + 1);
DUK_ASSERT(DUK_OP_CSREGI == DUK_OP_CSREG + 1);
DUK_ASSERT(DUK_OP_CSPROPI == DUK_OP_CSPROP + 1);
@ -1195,7 +1200,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
DUK_ASSERT((op_flags & 0xff) != DUK_OP_CALL);
DUK_ASSERT((op_flags & 0xff) != DUK_OP_NEW);
b = b & ~DUK__CONST_MARKER;
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (0) {
#else
if (b <= 0xff) {
#endif
ins |= DUK_ENC_OP_A_B_C(0, 0, 0x100, 0); /* const flag for B */
} else if (b <= DUK_BC_BC_MAX) {
comp_ctx->curr_func.needs_shuffle = 1;
@ -1207,7 +1216,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
goto error_outofregs;
}
} else {
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) {
#else
if (b <= 0xff) {
#endif
;
} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) {
if (b > DUK_BC_B_MAX) {
@ -1231,7 +1244,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
* an indirect version of the opcode is used.
*/
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);
duk__emit_load_int32(comp_ctx, tmp, b);
duk__emit_load_int32_noshuffle(comp_ctx, tmp, b);
DUK_ASSERT(DUK_OP_CALLI == DUK_OP_CALL + 1);
DUK_ASSERT(DUK_OP_NEWI == DUK_OP_NEW + 1);
DUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1);
@ -1254,7 +1267,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);
c = c & ~DUK__CONST_MARKER;
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (0) {
#else
if (c <= 0xff) {
#endif
ins |= DUK_ENC_OP_A_B_C(0, 0, 0, 0x100); /* const flag for C */
} else if (c <= DUK_BC_BC_MAX) {
comp_ctx->curr_func.needs_shuffle = 1;
@ -1266,7 +1283,11 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
goto error_outofregs;
}
} else {
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) {
#else
if (c <= 0xff) {
#endif
;
} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) {
if (c > DUK_BC_C_MAX) {
@ -1289,7 +1310,7 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
* normally. Use an indirect variant instead.
*/
DUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);
duk__emit_load_int32(comp_ctx, tmp, c);
duk__emit_load_int32_noshuffle(comp_ctx, tmp, c);
DUK_ASSERT(DUK_EXTRAOP_INITGETI == DUK_EXTRAOP_INITGET + 1);
DUK_ASSERT(DUK_EXTRAOP_INITSETI == DUK_EXTRAOP_INITSET + 1);
a++; /* indirect opcode follows direct */
@ -1327,21 +1348,23 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
}
/* Output shuffling: only one output register is realistically possible.
* Zero is OK to check against: if the target register was zero, it is
* never shuffled.
*
* (Zero would normally be an OK marker value: if the target register
* was zero, it would never be shuffled. But with DUK_USE_SHUFFLE_TORTURE
* this is no longer true, so use -1 as a marker instead.)
*/
if (a_out != 0) {
DUK_ASSERT(b_out == 0);
DUK_ASSERT(c_out == 0);
if (a_out >= 0) {
DUK_ASSERT(b_out < 0);
DUK_ASSERT(c_out < 0);
duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out));
} else if (b_out != 0) {
DUK_ASSERT(a_out == 0);
DUK_ASSERT(c_out == 0);
} else if (b_out >= 0) {
DUK_ASSERT(a_out < 0);
DUK_ASSERT(c_out < 0);
duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out));
} else if (c_out != 0) {
DUK_ASSERT(b_out == 0);
DUK_ASSERT(c_out == 0);
} else if (c_out >= 0) {
DUK_ASSERT(b_out < 0);
DUK_ASSERT(c_out < 0);
duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));
}
@ -1352,12 +1375,12 @@ DUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_f
}
DUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b) {
duk__emit_a_b_c(comp_ctx, op_flags, a, b, 0);
duk__emit_a_b_c(comp_ctx, op_flags | DUK__EMIT_FLAG_NO_SHUFFLE_C, a, b, 0);
}
#if 0 /* unused */
DUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {
duk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0);
duk__emit_a_b_c(comp_ctx, op_flags | DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C, a, 0, 0);
}
#endif
@ -1381,7 +1404,11 @@ DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_fl
goto error_outofregs;
}
#if defined(DUK_USE_SHUFFLE_TORTURE)
if (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {
#else
if (a <= DUK_BC_A_MAX) {
#endif
ins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc);
duk__emit(comp_ctx, ins);
} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {
@ -1435,9 +1462,11 @@ DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, du
DUK_LOCAL void duk__emit_extraop_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop_flags, duk_regconst_t b, duk_regconst_t c) {
DUK_ASSERT_DISABLE((extraop_flags & 0xff) >= DUK_BC_EXTRAOP_MIN); /* unsigned */
DUK_ASSERT((extraop_flags & 0xff) <= DUK_BC_EXTRAOP_MAX);
/* Setting "no shuffle A" would be prudent but not necessary, assert covers it. */
/* Setting "no shuffle A" is covered by the assert, but it's needed
* with DUK_USE_SHUFFLE_TORTURE.
*/
duk__emit_a_b_c(comp_ctx,
DUK_OP_EXTRA | (extraop_flags & ~0xff), /* transfer flags */
DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A | (extraop_flags & ~0xff), /* transfer flags */
extraop_flags & 0xff,
b,
c);
@ -1446,9 +1475,11 @@ DUK_LOCAL void duk__emit_extraop_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_
DUK_LOCAL void duk__emit_extraop_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop_flags, duk_regconst_t b) {
DUK_ASSERT_DISABLE((extraop_flags & 0xff) >= DUK_BC_EXTRAOP_MIN); /* unsigned */
DUK_ASSERT((extraop_flags & 0xff) <= DUK_BC_EXTRAOP_MAX);
/* Setting "no shuffle A" would be prudent but not necessary, assert covers it. */
/* Setting "no shuffle A" is covered by the assert, but it's needed
* with DUK_USE_SHUFFLE_TORTURE.
*/
duk__emit_a_b_c(comp_ctx,
DUK_OP_EXTRA | (extraop_flags & ~0xff), /* transfer flags */
DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A | (extraop_flags & ~0xff), /* transfer flags */
extraop_flags & 0xff,
b,
0);
@ -1457,9 +1488,11 @@ DUK_LOCAL void duk__emit_extraop_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t
DUK_LOCAL void duk__emit_extraop_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop, duk_regconst_t bc) {
DUK_ASSERT_DISABLE(extraop >= DUK_BC_EXTRAOP_MIN); /* unsigned */
DUK_ASSERT(extraop <= DUK_BC_EXTRAOP_MAX);
/* Setting "no shuffle A" would be prudent but not necessary, assert covers it. */
/* Setting "no shuffle A" is covered by the assert, but it's needed
* with DUK_USE_SHUFFLE_TORTURE.
*/
duk__emit_a_bc(comp_ctx,
DUK_OP_EXTRA,
DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A,
extraop,
bc);
}
@ -1467,15 +1500,18 @@ DUK_LOCAL void duk__emit_extraop_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t
DUK_LOCAL void duk__emit_extraop_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t extraop_flags) {
DUK_ASSERT_DISABLE((extraop_flags & 0xff) >= DUK_BC_EXTRAOP_MIN); /* unsigned */
DUK_ASSERT((extraop_flags & 0xff) <= DUK_BC_EXTRAOP_MAX);
/* Setting "no shuffle A" would be prudent but not necessary, assert covers it. */
/* Setting "no shuffle A" is covered by the assert, but it's needed
* with DUK_USE_SHUFFLE_TORTURE.
*/
duk__emit_a_b_c(comp_ctx,
DUK_OP_EXTRA | (extraop_flags & ~0xff), /* transfer flags */
DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_B |
DUK__EMIT_FLAG_NO_SHUFFLE_C | (extraop_flags & ~0xff), /* transfer flags */
extraop_flags & 0xff,
0,
0);
}
DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
DUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val, duk_small_uint_t op_flags) {
/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX
* would only shuffle once (instead of twice). The current code works
* though, and has a smaller compiler footprint.
@ -1484,18 +1520,39 @@ DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, d
if ((val >= (duk_int32_t) DUK_BC_BC_MIN - (duk_int32_t) DUK_BC_LDINT_BIAS) &&
(val <= (duk_int32_t) DUK_BC_BC_MAX - (duk_int32_t) DUK_BC_LDINT_BIAS)) {
DUK_DDD(DUK_DDDPRINT("emit LDINT to reg %ld for %ld", (long) reg, (long) val));
duk__emit_a_bc(comp_ctx, DUK_OP_LDINT, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));
duk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));
} else {
duk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT;
duk_int32_t lo = val & ((((duk_int32_t) 1) << DUK_BC_LDINTX_SHIFT) - 1);
DUK_ASSERT(lo >= 0);
DUK_DDD(DUK_DDDPRINT("emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld",
(long) reg, (long) val, (long) hi, (long) lo));
duk__emit_a_bc(comp_ctx, DUK_OP_LDINT, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));
duk__emit_a_bc(comp_ctx, DUK_OP_LDINTX, reg, (duk_regconst_t) lo);
duk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));
duk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t) lo);
}
}
DUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
duk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);
}
#if defined(DUK_USE_SHUFFLE_TORTURE)
/* Used by duk__emit*() calls so that we don't shuffle the loadints that
* are needed to handle indirect opcodes.
*/
DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
duk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);
}
#else
DUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_reg_t reg, duk_int32_t val) {
/* When torture not enabled, can just use the same helper because
* 'reg' won't get spilled.
*/
DUK_ASSERT(reg <= DUK_BC_A_MAX);
duk__emit_load_int32(comp_ctx, reg, val);
}
#endif
DUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) {
duk_hbuffer_dynamic *h;
duk_int_t curr_pc;
@ -1602,11 +1659,19 @@ DUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t trycatc
}
DUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {
duk__emit_a_b_c(comp_ctx, DUK_OP_IF, 0 /*false*/, regconst, 0);
duk__emit_a_b_c(comp_ctx,
DUK_OP_IF | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C,
0 /*false*/,
regconst,
0 /*unused*/);
}
DUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {
duk__emit_a_b_c(comp_ctx, DUK_OP_IF, 1 /*true*/, regconst, 0);
duk__emit_a_b_c(comp_ctx,
DUK_OP_IF | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C,
1 /*true*/,
regconst,
0 /*unused*/);
}
DUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) {
@ -3581,7 +3646,7 @@ DUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {
(duk_regconst_t) reg_res,
(duk_regconst_t) reg_res);
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE,
(duk_regconst_t) reg_obj,
rc_key,
(duk_regconst_t) reg_res);
@ -4119,7 +4184,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk__ivalue_toforcedreg(comp_ctx, left, reg_temp);
duk__emit_a_b(comp_ctx,
DUK_OP_IF,
DUK_OP_IF | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) args_truthval,
(duk_regconst_t) reg_temp); /* skip jump conditionally */
pc_jump = duk__emit_jump_empty(comp_ctx);
@ -4285,7 +4350,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
}
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE,
(duk_regconst_t) reg_obj,
rc_key,
rc_res);
@ -4414,7 +4479,7 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
(duk_regconst_t) reg_temp,
(duk_regconst_t) reg_res);
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE,
(duk_regconst_t) reg_obj,
rc_key,
(duk_regconst_t) reg_temp);
@ -4926,7 +4991,7 @@ DUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res,
reg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/); /* don't allow const */
rc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
duk__emit_a_b_c(comp_ctx,
DUK_OP_PUTPROP,
DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE,
(duk_regconst_t) reg_obj,
rc_key,
(duk_regconst_t) (reg_temps + 0));
@ -5608,7 +5673,7 @@ DUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re
#endif
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) ret_flags /*flags*/,
rc_val /*reg*/);
}
@ -6695,7 +6760,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
}
duk__emit_a_b_c(comp_ctx,
DUK_OP_DECLVAR,
DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) declvar_flags /*flags*/,
rc_name /*name*/,
(duk_regconst_t) reg_temp /*value*/);
@ -6780,7 +6845,7 @@ DUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ct
}
duk__emit_a_b_c(comp_ctx,
DUK_OP_DECLVAR,
DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) declvar_flags /*flags*/,
rc_name /*name*/,
(duk_regconst_t) 0 /*value*/);
@ -7073,12 +7138,12 @@ DUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expec
DUK_ASSERT(comp_ctx->curr_func.catch_depth == 0); /* fast returns are always OK here */
if (reg_stmt_value >= 0) {
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) (DUK_BC_RETURN_FLAG_HAVE_RETVAL | DUK_BC_RETURN_FLAG_FAST) /*flags*/,
(duk_regconst_t) reg_stmt_value /*reg*/);
} else {
duk__emit_a_b(comp_ctx,
DUK_OP_RETURN,
DUK_OP_RETURN | DUK__EMIT_FLAG_NO_SHUFFLE_A,
(duk_regconst_t) DUK_BC_RETURN_FLAG_FAST /*flags*/,
(duk_regconst_t) 0 /*reg(ignored)*/);
}

Loading…
Cancel
Save