http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/5977aa27/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/src-separate/duk_js_compiler.c
----------------------------------------------------------------------
diff --git 
a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/src-separate/duk_js_compiler.c
 
b/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/src-separate/duk_js_compiler.c
deleted file mode 100644
index 3983c7c..0000000
--- 
a/thirdparty/civetweb-1.10/src/third_party/duktape-1.5.2/src-separate/duk_js_compiler.c
+++ /dev/null
@@ -1,7865 +0,0 @@
-/*
- *  Ecmascript compiler.
- *
- *  Parses an input string and generates a function template result.
- *  Compilation may happen in multiple contexts (global code, eval
- *  code, function code).
- *
- *  The parser uses a traditional top-down recursive parsing for the
- *  statement level, and an operator precedence based top-down approach
- *  for the expression level.  The attempt is to minimize the C stack
- *  depth.  Bytecode is generated directly without an intermediate
- *  representation (tree), at the cost of needing two passes over each
- *  function.
- *
- *  The top-down recursive parser functions are named "duk__parse_XXX".
- *
- *  Recursion limits are in key functions to prevent arbitrary C recursion:
- *  function body parsing, statement parsing, and expression parsing.
- *
- *  See doc/compiler.rst for discussion on the design.
- *
- *  A few typing notes:
- *
- *    - duk_regconst_t: unsigned, no marker value for "none"
- *    - duk_reg_t: signed, < 0 = none
- *    - PC values: duk_int_t, negative values used as markers
- */
-
-#include "duk_internal.h"
-
-/* if highest bit of a register number is set, it refers to a constant instead 
*/
-#define DUK__CONST_MARKER                 DUK_JS_CONST_MARKER
-
-/* for array and object literals */
-#define DUK__MAX_ARRAY_INIT_VALUES        20
-#define DUK__MAX_OBJECT_INIT_PAIRS        10
-
-/* XXX: hack, remove when const lookup is not O(n) */
-#define DUK__GETCONST_MAX_CONSTS_CHECK    256
-
-/* These limits are based on bytecode limits.  Max temps is limited
- * by duk_hcompiledfunction nargs/nregs fields being 16 bits.
- */
-#define DUK__MAX_CONSTS                   DUK_BC_BC_MAX
-#define DUK__MAX_FUNCS                    DUK_BC_BC_MAX
-#define DUK__MAX_TEMPS                    0xffffL
-
-/* Initial bytecode size allocation. */
-#define DUK__BC_INITIAL_INSTS 256
-
-#define DUK__RECURSION_INCREASE(comp_ctx,thr)  do { \
-               DUK_DDD(DUK_DDDPRINT("RECURSION INCREASE: %s:%ld", (const char 
*) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \
-               duk__recursion_increase((comp_ctx)); \
-       } while (0)
-
-#define DUK__RECURSION_DECREASE(comp_ctx,thr)  do { \
-               DUK_DDD(DUK_DDDPRINT("RECURSION DECREASE: %s:%ld", (const char 
*) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \
-               duk__recursion_decrease((comp_ctx)); \
-       } while (0)
-
-/* Value stack slot limits: these are quite approximate right now, and
- * because they overlap in control flow, some could be eliminated.
- */
-#define DUK__COMPILE_ENTRY_SLOTS          8
-#define DUK__FUNCTION_INIT_REQUIRE_SLOTS  16
-#define DUK__FUNCTION_BODY_REQUIRE_SLOTS  16
-#define DUK__PARSE_STATEMENTS_SLOTS       16
-#define DUK__PARSE_EXPR_SLOTS             16
-
-/* Temporary structure used to pass a stack allocated region through
- * duk_safe_call().
- */
-typedef struct {
-       duk_small_uint_t flags;
-       duk_compiler_ctx comp_ctx_alloc;
-       duk_lexer_point lex_pt_alloc;
-} duk__compiler_stkstate;
-
-/*
- *  Prototypes
- */
-
-/* lexing */
-DUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, 
duk_small_int_t expect);
-DUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, 
duk_small_int_t expect);
-DUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);
-
-/* function helpers */
-DUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx 
*comp_ctx, duk_reg_t *out_stmt_value_reg);
-DUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, 
duk_bool_t force_no_namebind);
-DUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);
-
-/* code emission */
-DUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx 
*comp_ctx, duk_int_t pc);
-DUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins);
-#if 0  /* unused */
-DUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, 
duk_small_uint_t op);
-#endif
-DUK_LOCAL_DECL 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_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t 
op_flags, duk_regconst_t a, duk_regconst_t b);
-#if 0  /* unused */
-DUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t 
op_flags, duk_regconst_t a);
-#endif
-DUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, 
duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);
-DUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t 
op, duk_regconst_t abc);
-DUK_LOCAL_DECL 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_LOCAL_DECL void duk__emit_extraop_b(duk_compiler_ctx *comp_ctx, 
duk_small_uint_t extraop_flags, duk_regconst_t b);
-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);
-DUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t 
jump_pc, duk_int_t target_pc);
-DUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t 
jump_pc);
-DUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t 
ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t 
const_varname, duk_small_uint_t flags);
-DUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, 
duk_regconst_t regconst);
-DUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, 
duk_regconst_t regconst);
-DUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx);
-
-/* ivalue/ispec helpers */
-DUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec 
*src, duk_ispec *dst);
-DUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue 
*src, duk_ivalue *dst);
-DUK_LOCAL_DECL duk_bool_t duk__is_whole_get_int32(duk_double_t x, duk_int32_t 
*ival);
-DUK_LOCAL_DECL duk_reg_t duk__alloctemps(duk_compiler_ctx *comp_ctx, 
duk_small_int_t num);
-DUK_LOCAL_DECL duk_reg_t duk__alloctemp(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, 
duk_reg_t temp_next);
-DUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL
-duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
-                                         duk_ispec *x,
-                                         duk_reg_t forced_reg,
-                                         duk_small_uint_t flags);
-DUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, 
duk_ispec *x, duk_reg_t forced_reg);
-DUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, 
duk_ivalue *x, duk_reg_t forced_reg);
-DUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue 
*x);
-DUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, 
duk_ivalue *x);
-DUK_LOCAL_DECL
-duk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,
-                                          duk_ivalue *x,
-                                          duk_reg_t forced_reg,
-                                          duk_small_uint_t flags);
-DUK_LOCAL_DECL duk_reg_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *x);
-#if 0  /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, 
duk_ivalue *x);
-#endif
-DUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *x, duk_int_t forced_reg);
-DUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx 
*comp_ctx, duk_ivalue *x);
-DUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx 
*comp_ctx, duk_ivalue *x);
-
-/* identifier handling */
-DUK_LOCAL_DECL duk_reg_t duk__lookup_active_register_binding(duk_compiler_ctx 
*comp_ctx);
-DUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_reg_t 
*out_reg_varbind, duk_regconst_t *out_rc_varname);
-
-/* label handling */
-DUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring 
*h_label, duk_int_t pc_label, duk_int_t label_id);
-DUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, 
duk_int_t label_id, duk_small_uint_t flags);
-DUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, 
duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t 
*out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);
-DUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, 
duk_int_t len);
-
-/* top-down expression parser */
-DUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);
-DUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue 
*left, duk_ivalue *res);
-DUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx);
-
-/* exprtop is the top level variant which resets nud/led counts */
-DUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, 
duk_small_uint_t rbp_flags);
-DUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, 
duk_small_uint_t rbp_flags);
-
-/* convenience helpers */
-#if 0  /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#endif
-#if 0  /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#endif
-DUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags, duk_reg_t forced_reg);
-DUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#if 0  /* unused */
-DUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx 
*comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);
-#endif
-DUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_small_uint_t rbp_flags);
-DUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-DUK_LOCAL_DECL duk_reg_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#if 0  /* unused */
-DUK_LOCAL_DECL duk_reg_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#endif
-DUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags, duk_reg_t forced_reg);
-DUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx 
*comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);
-#if 0  /* unused */
-DUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_small_uint_t rbp_flags);
-#endif
-
-/* expression parsing helpers */
-DUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL duk_bool_t duk__nud_object_literal_key_check(duk_compiler_ctx 
*comp_ctx, duk_small_uint_t new_key_flags);
-
-/* statement parsing */
-DUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_small_uint_t expr_flags, duk_reg_t *out_reg_varbind, duk_regconst_t 
*out_rc_varname);
-DUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_small_uint_t expr_flags);
-DUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_int_t pc_label_site);
-DUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_int_t pc_label_site);
-DUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res);
-DUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_int_t pc_label_site);
-DUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res, duk_int_t pc_label_site);
-DUK_LOCAL_DECL void duk__parse_break_or_continue_stmt(duk_compiler_ctx 
*comp_ctx, duk_ivalue *res);
-DUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res);
-DUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, 
duk_ivalue *res);
-DUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue 
*res, duk_bool_t allow_source_elem);
-DUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, 
duk_int_t label_id);
-DUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t 
allow_source_elem, duk_bool_t expect_eof);
-
-DUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, 
duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_small_int_t 
expect_token);
-DUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);
-DUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, 
duk_bool_t is_decl, duk_bool_t is_setget);
-DUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, 
duk_bool_t is_decl, duk_bool_t is_setget);
-
-/*
- *  Parser control values for tokens.  The token table is ordered by the
- *  DUK_TOK_XXX defines.
- *
- *  The binding powers are for lbp() use (i.e. for use in led() context).
- *  Binding powers are positive for typing convenience, and bits at the
- *  top should be reserved for flags.  Binding power step must be higher
- *  than 1 so that binding power "lbp - 1" can be used for right associative
- *  operators.  Currently a step of 2 is used (which frees one more bit for
- *  flags).
- */
-
-/* XXX: actually single step levels would work just fine, clean up */
-
-/* binding power "levels" (see doc/compiler.rst) */
-#define DUK__BP_INVALID                0             /* always terminates 
led() */
-#define DUK__BP_EOF                    2
-#define DUK__BP_CLOSING                4             /* token closes 
expression, e.g. ')', ']' */
-#define DUK__BP_FOR_EXPR               DUK__BP_CLOSING    /* bp to use when 
parsing a top level Expression */
-#define DUK__BP_COMMA                  6
-#define DUK__BP_ASSIGNMENT             8
-#define DUK__BP_CONDITIONAL            10
-#define DUK__BP_LOR                    12
-#define DUK__BP_LAND                   14
-#define DUK__BP_BOR                    16
-#define DUK__BP_BXOR                   18
-#define DUK__BP_BAND                   20
-#define DUK__BP_EQUALITY               22
-#define DUK__BP_RELATIONAL             24
-#define DUK__BP_SHIFT                  26
-#define DUK__BP_ADDITIVE               28
-#define DUK__BP_MULTIPLICATIVE         30
-#define DUK__BP_POSTFIX                32
-#define DUK__BP_CALL                   34
-#define DUK__BP_MEMBER                 36
-
-#define DUK__TOKEN_LBP_BP_MASK         0x1f
-#define DUK__TOKEN_LBP_FLAG_NO_REGEXP  (1 << 5)   /* regexp literal must not 
follow this token */
-#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6)   /* terminates expression; 
e.g. post-increment/-decrement */
-#define DUK__TOKEN_LBP_FLAG_UNUSED     (1 << 7)   /* spare */
-
-#define DUK__TOKEN_LBP_GET_BP(x)       ((duk_small_uint_t) (((x) & 
DUK__TOKEN_LBP_BP_MASK) * 2))
-
-#define DUK__MK_LBP(bp)                ((bp) >> 1)    /* bp is assumed to be 
even */
-#define DUK__MK_LBP_FLAGS(bp,flags)    (((bp) >> 1) | (flags))
-
-DUK_LOCAL const duk_uint8_t duk__token_lbp[] = {
-       DUK__MK_LBP(DUK__BP_EOF),                                 /* 
DUK_TOK_EOF */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_IDENTIFIER */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_BREAK */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_CASE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_CATCH */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_CONTINUE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_DEBUGGER */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_DEFAULT */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_DELETE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DO 
*/
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_ELSE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_FINALLY */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_FOR */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_FUNCTION */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IF 
*/
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_IN 
*/
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* 
DUK_TOK_INSTANCEOF */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_NEW */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_RETURN */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_SWITCH */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_THIS */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_THROW */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_TRY */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_TYPEOF */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_VAR */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_CONST */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_VOID */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_WHILE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_WITH */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_CLASS */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_ENUM */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_EXPORT */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_EXTENDS */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_IMPORT */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_SUPER */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_NULL */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_TRUE */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_FALSE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_GET */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_SET */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_IMPLEMENTS */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_INTERFACE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_LET */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_PACKAGE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_PRIVATE */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_PROTECTED */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_PUBLIC */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_STATIC */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_YIELD */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_LCURLY */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_RCURLY */
-       DUK__MK_LBP(DUK__BP_MEMBER),                              /* 
DUK_TOK_LBRACKET */
-       DUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_RBRACKET */
-       DUK__MK_LBP(DUK__BP_CALL),                                /* 
DUK_TOK_LPAREN */
-       DUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_RPAREN */
-       DUK__MK_LBP(DUK__BP_MEMBER),                              /* 
DUK_TOK_PERIOD */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_SEMICOLON */
-       DUK__MK_LBP(DUK__BP_COMMA),                               /* 
DUK_TOK_COMMA */
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LT 
*/
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GT 
*/
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LE 
*/
-       DUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GE 
*/
-       DUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_EQ 
*/
-       DUK__MK_LBP(DUK__BP_EQUALITY),                            /* 
DUK_TOK_NEQ */
-       DUK__MK_LBP(DUK__BP_EQUALITY),                            /* 
DUK_TOK_SEQ */
-       DUK__MK_LBP(DUK__BP_EQUALITY),                            /* 
DUK_TOK_SNEQ */
-       DUK__MK_LBP(DUK__BP_ADDITIVE),                            /* 
DUK_TOK_ADD */
-       DUK__MK_LBP(DUK__BP_ADDITIVE),                            /* 
DUK_TOK_SUB */
-       DUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* 
DUK_TOK_MUL */
-       DUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* 
DUK_TOK_DIV */
-       DUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* 
DUK_TOK_MOD */
-       DUK__MK_LBP(DUK__BP_POSTFIX),                             /* 
DUK_TOK_INCREMENT */
-       DUK__MK_LBP(DUK__BP_POSTFIX),                             /* 
DUK_TOK_DECREMENT */
-       DUK__MK_LBP(DUK__BP_SHIFT),                               /* 
DUK_TOK_ALSHIFT */
-       DUK__MK_LBP(DUK__BP_SHIFT),                               /* 
DUK_TOK_ARSHIFT */
-       DUK__MK_LBP(DUK__BP_SHIFT),                               /* 
DUK_TOK_RSHIFT */
-       DUK__MK_LBP(DUK__BP_BAND),                                /* 
DUK_TOK_BAND */
-       DUK__MK_LBP(DUK__BP_BOR),                                 /* 
DUK_TOK_BOR */
-       DUK__MK_LBP(DUK__BP_BXOR),                                /* 
DUK_TOK_BXOR */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_LNOT */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_BNOT */
-       DUK__MK_LBP(DUK__BP_LAND),                                /* 
DUK_TOK_LAND */
-       DUK__MK_LBP(DUK__BP_LOR),                                 /* 
DUK_TOK_LOR */
-       DUK__MK_LBP(DUK__BP_CONDITIONAL),                         /* 
DUK_TOK_QUESTION */
-       DUK__MK_LBP(DUK__BP_INVALID),                             /* 
DUK_TOK_COLON */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_EQUALSIGN */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_ADD_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_SUB_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_MUL_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_DIV_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_MOD_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_ALSHIFT_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_ARSHIFT_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_RSHIFT_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_BAND_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_BOR_EQ */
-       DUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* 
DUK_TOK_BXOR_EQ */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_NUMBER */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_STRING */
-       DUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* 
DUK_TOK_REGEXP */
-};
-
-/*
- *  Misc helpers
- */
-
-DUK_LOCAL void duk__recursion_increase(duk_compiler_ctx *comp_ctx) {
-       DUK_ASSERT(comp_ctx != NULL);
-       DUK_ASSERT(comp_ctx->recursion_depth >= 0);
-       if (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {
-               DUK_ERROR_RANGE(comp_ctx->thr, 
DUK_STR_COMPILER_RECURSION_LIMIT);
-       }
-       comp_ctx->recursion_depth++;
-}
-
-DUK_LOCAL void duk__recursion_decrease(duk_compiler_ctx *comp_ctx) {
-       DUK_ASSERT(comp_ctx != NULL);
-       DUK_ASSERT(comp_ctx->recursion_depth > 0);
-       comp_ctx->recursion_depth--;
-}
-
-DUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments(duk_compiler_ctx 
*comp_ctx, duk_hstring *h) {
-       DUK_UNREF(comp_ctx);
-       DUK_ASSERT(h != NULL);
-       return DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h);
-}
-
-DUK_LOCAL duk_bool_t 
duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compiler_ctx *comp_ctx, 
duk_hstring *h) {
-       DUK_ASSERT(h != NULL);
-       return (comp_ctx->curr_func.is_strict &&
-               DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h));
-}
-
-/*
- *  Parser duk__advance() token eating functions
- */
-
-/* XXX: valstack handling is awkward.  Add a valstack helper which
- * avoids dup():ing; valstack_copy(src, dst)?
- */
-
-DUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t 
expect) {
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-       duk_bool_t regexp;
-
-       DUK_ASSERT(comp_ctx->curr_token.t >= 0 && comp_ctx->curr_token.t <= 
DUK_TOK_MAXVAL);  /* MAXVAL is inclusive */
-
-       /*
-        *  Use current token to decide whether a RegExp can follow.
-        *
-        *  We can use either 't' or 't_nores'; the latter would not
-        *  recognize keywords.  Some keywords can be followed by a
-        *  RegExp (e.g. "return"), so using 't' is better.  This is
-        *  not trivial, see doc/compiler.rst.
-        */
-
-       regexp = 1;
-       if (duk__token_lbp[comp_ctx->curr_token.t] & 
DUK__TOKEN_LBP_FLAG_NO_REGEXP) {
-               regexp = 0;
-       }
-       if (comp_ctx->curr_func.reject_regexp_in_adv) {
-               comp_ctx->curr_func.reject_regexp_in_adv = 0;
-               regexp = 0;
-       }
-
-       if (expect >= 0 && comp_ctx->curr_token.t != expect) {
-               DUK_D(DUK_DPRINT("parse error: expect=%ld, got=%ld",
-                                (long) expect, (long) comp_ctx->curr_token.t));
-               DUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);
-       }
-
-       /* make current token the previous; need to fiddle with valstack 
"backing store" */
-       DUK_MEMCPY(&comp_ctx->prev_token, &comp_ctx->curr_token, 
sizeof(duk_token));
-       duk_copy(ctx, comp_ctx->tok11_idx, comp_ctx->tok21_idx);
-       duk_copy(ctx, comp_ctx->tok12_idx, comp_ctx->tok22_idx);
-
-       /* parse new token */
-       duk_lexer_parse_js_input_element(&comp_ctx->lex,
-                                        &comp_ctx->curr_token,
-                                        comp_ctx->curr_func.is_strict,
-                                        regexp);
-
-       DUK_DDD(DUK_DDDPRINT("advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T "
-                            "prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T",
-                            (long) comp_ctx->curr_token.t,
-                            (long) comp_ctx->curr_token.t_nores,
-                            (long) comp_ctx->curr_token.start_line,
-                            (long) comp_ctx->curr_token.lineterm,
-                            (duk_tval *) duk_get_tval(ctx, 
comp_ctx->tok11_idx),
-                            (duk_tval *) duk_get_tval(ctx, 
comp_ctx->tok12_idx),
-                            (long) comp_ctx->prev_token.t,
-                            (long) comp_ctx->prev_token.t_nores,
-                            (long) comp_ctx->prev_token.start_line,
-                            (long) comp_ctx->prev_token.lineterm,
-                            (duk_tval *) duk_get_tval(ctx, 
comp_ctx->tok21_idx),
-                            (duk_tval *) duk_get_tval(ctx, 
comp_ctx->tok22_idx)));
-}
-
-/* advance, expecting current token to be a specific token; parse next token 
in regexp context */
-DUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t 
expect) {
-       duk__advance_helper(comp_ctx, expect);
-}
-
-/* advance, whatever the current token is; parse next token in regexp context 
*/
-DUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {
-       duk__advance_helper(comp_ctx, -1);
-}
-
-/*
- *  Helpers for duk_compiler_func.
- */
-
-/* init function state: inits valstack allocations */
-DUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {
-       duk_compiler_func *func = &comp_ctx->curr_func;
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-       duk_idx_t entry_top;
-
-       entry_top = duk_get_top(ctx);
-
-       DUK_MEMZERO(func, sizeof(*func));  /* intentional overlap with earlier 
memzero */
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
-       func->h_name = NULL;
-       func->h_consts = NULL;
-       func->h_funcs = NULL;
-       func->h_decls = NULL;
-       func->h_labelnames = NULL;
-       func->h_labelinfos = NULL;
-       func->h_argnames = NULL;
-       func->h_varmap = NULL;
-#endif
-
-       duk_require_stack(ctx, DUK__FUNCTION_INIT_REQUIRE_SLOTS);
-
-       DUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * 
sizeof(duk_compiler_instr));
-       /* code_idx = entry_top + 0 */
-
-       duk_push_array(ctx);
-       func->consts_idx = entry_top + 1;
-       func->h_consts = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 1);
-       DUK_ASSERT(func->h_consts != NULL);
-
-       duk_push_array(ctx);
-       func->funcs_idx = entry_top + 2;
-       func->h_funcs = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 2);
-       DUK_ASSERT(func->h_funcs != NULL);
-       DUK_ASSERT(func->fnum_next == 0);
-
-       duk_push_array(ctx);
-       func->decls_idx = entry_top + 3;
-       func->h_decls = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 3);
-       DUK_ASSERT(func->h_decls != NULL);
-
-       duk_push_array(ctx);
-       func->labelnames_idx = entry_top + 4;
-       func->h_labelnames = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 4);
-       DUK_ASSERT(func->h_labelnames != NULL);
-
-       duk_push_dynamic_buffer(ctx, 0);
-       func->labelinfos_idx = entry_top + 5;
-       func->h_labelinfos = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, 
entry_top + 5);
-       DUK_ASSERT(func->h_labelinfos != NULL);
-       DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && 
!DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));
-
-       duk_push_array(ctx);
-       func->argnames_idx = entry_top + 6;
-       func->h_argnames = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 6);
-       DUK_ASSERT(func->h_argnames != NULL);
-
-       duk_push_object_internal(ctx);
-       func->varmap_idx = entry_top + 7;
-       func->h_varmap = DUK_GET_HOBJECT_POSIDX(ctx, entry_top + 7);
-       DUK_ASSERT(func->h_varmap != NULL);
-}
-
-/* reset function state (prepare for pass 2) */
-DUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {
-       duk_compiler_func *func = &comp_ctx->curr_func;
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-
-       /* reset bytecode buffer but keep current size; pass 2 will
-        * require same amount or more.
-        */
-       DUK_BW_RESET_SIZE(thr, &func->bw_code);
-
-       duk_hobject_set_length_zero(thr, func->h_consts);
-       /* keep func->h_funcs; inner functions are not reparsed to avoid 
O(depth^2) parsing */
-       func->fnum_next = 0;
-       /* duk_hobject_set_length_zero(thr, func->h_funcs); */
-       duk_hobject_set_length_zero(thr, func->h_labelnames);
-       duk_hbuffer_reset(thr, func->h_labelinfos);
-       /* keep func->h_argnames; it is fixed for all passes */
-
-       /* truncated in case pass 3 needed */
-       duk_push_object_internal(ctx);
-       duk_replace(ctx, func->varmap_idx);
-       func->h_varmap = DUK_GET_HOBJECT_POSIDX(ctx, func->varmap_idx);
-       DUK_ASSERT(func->h_varmap != NULL);
-}
-
-/* cleanup varmap from any null entries, compact it, etc; returns number
- * of final entries after cleanup.
- */
-DUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-       duk_hobject *h_varmap;
-       duk_hstring *h_key;
-       duk_tval *tv;
-       duk_uint32_t i, e_next;
-       duk_int_t ret;
-
-       /* [ ... varmap ] */
-
-       h_varmap = DUK_GET_HOBJECT_NEGIDX(ctx, -1);
-       DUK_ASSERT(h_varmap != NULL);
-
-       ret = 0;
-       e_next = DUK_HOBJECT_GET_ENEXT(h_varmap);
-       for (i = 0; i < e_next; i++) {
-               h_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);
-               if (!h_key) {
-                       continue;
-               }
-
-               DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, 
i));
-
-               /* The entries can either be register numbers or 'null' values.
-                * Thus, no need to DECREF them and get side effects.  
DECREF'ing
-                * the keys (strings) can cause memory to be freed but no side
-                * effects as strings don't have finalizers.  This is why we can
-                * rely on the object properties not changing from underneath 
us.
-                */
-
-               tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);
-               if (!DUK_TVAL_IS_NUMBER(tv)) {
-                       DUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));
-                       DUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);
-                       DUK_HSTRING_DECREF(thr, h_key);
-                       /* when key is NULL, value is garbage so no need to set 
*/
-               } else {
-                       ret++;
-               }
-       }
-
-       duk_compact(ctx, -1);
-
-       return ret;
-}
-
-/* convert duk_compiler_func into a function template, leaving the result
- * on top of stack.
- */
-/* XXX: awkward and bloated asm -- use faster internal accesses */
-DUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx, 
duk_bool_t force_no_namebind) {
-       duk_compiler_func *func = &comp_ctx->curr_func;
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-       duk_hcompiledfunction *h_res;
-       duk_hbuffer_fixed *h_data;
-       duk_size_t consts_count;
-       duk_size_t funcs_count;
-       duk_size_t code_count;
-       duk_size_t code_size;
-       duk_size_t data_size;
-       duk_size_t i;
-       duk_tval *p_const;
-       duk_hobject **p_func;
-       duk_instr_t *p_instr;
-       duk_compiler_instr *q_instr;
-       duk_tval *tv;
-
-       DUK_DDD(DUK_DDDPRINT("converting duk_compiler_func to 
function/template"));
-
-       /*
-        *  Push result object and init its flags
-        */
-
-       /* Valstack should suffice here, required on function valstack init */
-
-       (void) duk_push_compiledfunction(ctx);
-       h_res = (duk_hcompiledfunction *) DUK_GET_HOBJECT_NEGIDX(ctx, -1);  /* 
XXX: specific getter */
-       DUK_ASSERT(h_res != NULL);
-
-       if (func->is_function) {
-               DUK_DDD(DUK_DDDPRINT("function -> set NEWENV"));
-               DUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);
-
-               if (!func->is_arguments_shadowed) {
-                       /* arguments object would be accessible; note that 
shadowing
-                        * bindings are arguments or function declarations, 
neither
-                        * of which are deletable, so this is safe.
-                        */
-
-                       if (func->id_access_arguments || func->may_direct_eval) 
{
-                               DUK_DDD(DUK_DDDPRINT("function may access 
'arguments' object directly or "
-                                                    "indirectly -> set 
CREATEARGS"));
-                               DUK_HOBJECT_SET_CREATEARGS((duk_hobject *) 
h_res);
-                       }
-               }
-       } else if (func->is_eval && func->is_strict) {
-               DUK_DDD(DUK_DDDPRINT("strict eval code -> set NEWENV"));
-               DUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);
-       } else {
-               /* non-strict eval: env is caller's env or global env (direct 
vs. indirect call)
-                * global code: env is is global env
-                */
-               DUK_DDD(DUK_DDDPRINT("non-strict eval code or global code -> no 
NEWENV"));
-               DUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) h_res));
-       }
-
-       if (func->is_function && !func->is_decl && func->h_name != NULL && 
!force_no_namebind) {
-               /* Object literal set/get functions have a name (property
-                * name) but must not have a lexical name binding, see
-                * test-bug-getset-func-name.js.
-                */
-               DUK_DDD(DUK_DDDPRINT("function expression with a name -> set 
NAMEBINDING"));
-               DUK_HOBJECT_SET_NAMEBINDING((duk_hobject *) h_res);
-       }
-
-       if (func->is_strict) {
-               DUK_DDD(DUK_DDDPRINT("function is strict -> set STRICT"));
-               DUK_HOBJECT_SET_STRICT((duk_hobject *) h_res);
-       }
-
-       if (func->is_notail) {
-               DUK_DDD(DUK_DDDPRINT("function is notail -> set NOTAIL"));
-               DUK_HOBJECT_SET_NOTAIL((duk_hobject *) h_res);
-       }
-
-       /*
-        *  Build function fixed size 'data' buffer, which contains bytecode,
-        *  constants, and inner function references.
-        *
-        *  During the building phase 'data' is reachable but incomplete.
-        *  Only incref's occur during building (no refzero or GC happens),
-        *  so the building process is atomic.
-        */
-
-       consts_count = duk_hobject_get_length(thr, func->h_consts);
-       funcs_count = duk_hobject_get_length(thr, func->h_funcs) / 3;
-       code_count = DUK_BW_GET_SIZE(thr, &func->bw_code) / 
sizeof(duk_compiler_instr);
-       code_size = code_count * sizeof(duk_instr_t);
-
-       data_size = consts_count * sizeof(duk_tval) +
-                   funcs_count * sizeof(duk_hobject *) +
-                   code_size;
-
-       DUK_DDD(DUK_DDDPRINT("consts_count=%ld, funcs_count=%ld, code_size=%ld 
-> "
-                            "data_size=%ld*%ld + %ld*%ld + %ld = %ld",
-                            (long) consts_count, (long) funcs_count, (long) 
code_size,
-                            (long) consts_count, (long) sizeof(duk_tval),
-                            (long) funcs_count, (long) sizeof(duk_hobject *),
-                            (long) code_size, (long) data_size));
-
-       duk_push_fixed_buffer(ctx, data_size);
-       h_data = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
-       DUK_ASSERT(h_data != NULL);
-
-       DUK_HCOMPILEDFUNCTION_SET_DATA(thr->heap, h_res, (duk_hbuffer *) 
h_data);
-       DUK_HEAPHDR_INCREF(thr, h_data);
-
-       p_const = (duk_tval *) (void *) 
DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);
-       for (i = 0; i < consts_count; i++) {
-               DUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* const limits */
-               tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, 
func->h_consts, (duk_uarridx_t) i);
-               DUK_ASSERT(tv != NULL);
-               DUK_TVAL_SET_TVAL(p_const, tv);
-               p_const++;
-               DUK_TVAL_INCREF(thr, tv);  /* may be a string constant */
-
-               DUK_DDD(DUK_DDDPRINT("constant: %!T", (duk_tval *) tv));
-       }
-
-       p_func = (duk_hobject **) p_const;
-       DUK_HCOMPILEDFUNCTION_SET_FUNCS(thr->heap, h_res, p_func);
-       for (i = 0; i < funcs_count; i++) {
-               duk_hobject *h;
-               DUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX);  /* func limits */
-               tv = duk_hobject_find_existing_array_entry_tval_ptr(thr->heap, 
func->h_funcs, (duk_uarridx_t) (i * 3));
-               DUK_ASSERT(tv != NULL);
-               DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));
-               h = DUK_TVAL_GET_OBJECT(tv);
-               DUK_ASSERT(h != NULL);
-               DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(h));
-               *p_func++ = h;
-               DUK_HOBJECT_INCREF(thr, h);
-
-               DUK_DDD(DUK_DDDPRINT("inner function: %p -> %!iO",
-                                    (void *) h, (duk_heaphdr *) h));
-       }
-
-       p_instr = (duk_instr_t *) p_func;
-       DUK_HCOMPILEDFUNCTION_SET_BYTECODE(thr->heap, h_res, p_instr);
-
-       /* copy bytecode instructions one at a time */
-       q_instr = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(thr, 
&func->bw_code);
-       for (i = 0; i < code_count; i++) {
-               p_instr[i] = q_instr[i].ins;
-       }
-       /* Note: 'q_instr' is still used below */
-
-       DUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == 
DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);
-
-       duk_pop(ctx);  /* 'data' (and everything in it) is reachable through 
h_res now */
-
-       /*
-        *  Init object properties
-        *
-        *  Properties should be added in decreasing order of access frequency.
-        *  (Not very critical for function templates.)
-        */
-
-       DUK_DDD(DUK_DDDPRINT("init function properties"));
-
-       /* [ ... res ] */
-
-       /* _Varmap: omitted if function is guaranteed not to do slow path 
identifier
-        * accesses or if it would turn out to be empty of actual register 
mappings
-        * after a cleanup.  When debugging is enabled, we always need the 
varmap to
-        * be able to lookup variables at any point.
-        */
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-       if (1) {
-#else
-       if (func->id_access_slow ||     /* directly uses slow accesses */
-           func->may_direct_eval ||    /* may indirectly slow access through a 
direct eval */
-           funcs_count > 0) {          /* has inner functions which may slow 
access (XXX: this can be optimized by looking at the inner functions) */
-#endif
-               duk_int_t num_used;
-               duk_dup(ctx, func->varmap_idx);
-               num_used = duk__cleanup_varmap(comp_ctx);
-               DUK_DDD(DUK_DDDPRINT("cleaned up varmap: %!T (num_used=%ld)",
-                                    (duk_tval *) duk_get_tval(ctx, -1), (long) 
num_used));
-
-               if (num_used > 0) {
-                       duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VARMAP, 
DUK_PROPDESC_FLAGS_NONE);
-               } else {
-                       DUK_DDD(DUK_DDDPRINT("varmap is empty after cleanup -> 
no need to add"));
-                       duk_pop(ctx);
-               }
-       }
-
-       /* _Formals: omitted if function is guaranteed not to need a 
(non-strict) arguments object */
-       if (1) {
-               /* XXX: Add a proper condition.  If formals list is omitted, 
recheck
-                * handling for 'length' in duk_js_push_closure(); it currently 
relies
-                * on _Formals being set.  Removal may need to be conditional 
to debugging
-                * being enabled/disabled too.
-                */
-               duk_dup(ctx, func->argnames_idx);
-               duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_FORMALS, 
DUK_PROPDESC_FLAGS_NONE);
-       }
-
-       /* name */
-       if (func->h_name) {
-               duk_push_hstring(ctx, func->h_name);
-               duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_NAME, 
DUK_PROPDESC_FLAGS_NONE);
-       }
-
-       /* _Source */
-#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)
-       if (0) {
-               /* XXX: Currently function source code is not stored, as it is 
not
-                * required by the standard.  Source code should not be stored 
by
-                * default (user should enable it explicitly), and the source 
should
-                * probably be compressed with a trivial text compressor; 
average
-                * compression of 20-30% is quite easy to achieve even with a 
trivial
-                * compressor (RLE + backwards lookup).
-                *
-                * Debugging needs source code to be useful: sometimes input 
code is
-                * not found in files as it may be generated and then eval()'d, 
given
-                * by dynamic C code, etc.
-                *
-                * Other issues:
-                *
-                *   - Need tokenizer indices for start and end to substring
-                *   - Always normalize function declaration part?
-                *   - If we keep _Formals, only need to store body
-                */
-
-               /*
-                *  For global or eval code this is straightforward.  For 
functions
-                *  created with the Function constructor we only get the 
source for
-                *  the body and must manufacture the "function ..." part.
-                *
-                *  For instance, for constructed functions (v8):
-                *
-                *    > a = new Function("foo", "bar", "print(foo)");
-                *    [Function]
-                *    > a.toString()
-                *    'function anonymous(foo,bar) {\nprint(foo)\n}'
-                *
-                *  Similarly for e.g. getters (v8):
-                *
-                *    > x = { get a(foo,bar) { print(foo); } }
-                *    { a: [Getter] }
-                *    > Object.getOwnPropertyDescriptor(x, 'a').get.toString()
-                *    'function a(foo,bar) { print(foo); }'
-                */
-
-#if 0
-               duk_push_string(ctx, "XXX");
-               duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_SOURCE, 
DUK_PROPDESC_FLAGS_NONE);
-#endif
-       }
-#endif  /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */
-
-       /* _Pc2line */
-#if defined(DUK_USE_PC2LINE)
-       if (1) {
-               /*
-                *  Size-optimized pc->line mapping.
-                */
-
-               DUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);
-               duk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) 
code_count);  /* -> pushes fixed buffer */
-               duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_PC2LINE, 
DUK_PROPDESC_FLAGS_NONE);
-
-               /* XXX: if assertions enabled, walk through all valid PCs
-                * and check line mapping.
-                */
-       }
-#endif  /* DUK_USE_PC2LINE */
-
-       /* fileName */
-       if (comp_ctx->h_filename) {
-               /*
-                *  Source filename (or equivalent), for identifying thrown 
errors.
-                */
-
-               duk_push_hstring(ctx, comp_ctx->h_filename);
-               duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_FILE_NAME, 
DUK_PROPDESC_FLAGS_NONE);
-       }
-
-       /*
-        *  Init remaining result fields
-        *
-        *  'nregs' controls how large a register frame is allocated.
-        *
-        *  'nargs' controls how many formal arguments are written to registers:
-        *  r0, ... r(nargs-1).  The remaining registers are initialized to
-        *  undefined.
-        */
-
-       DUK_ASSERT(func->temp_max >= 0);
-       h_res->nregs = (duk_uint16_t) func->temp_max;
-       h_res->nargs = (duk_uint16_t) duk_hobject_get_length(thr, 
func->h_argnames);
-       DUK_ASSERT(h_res->nregs >= h_res->nargs);  /* pass2 allocation handles 
this */
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-       h_res->start_line = (duk_uint32_t) func->min_line;
-       h_res->end_line = (duk_uint32_t) func->max_line;
-#endif
-
-       DUK_DD(DUK_DDPRINT("converted function: %!ixT",
-                          (duk_tval *) duk_get_tval(ctx, -1)));
-
-       /*
-        *  Compact the function template.
-        */
-
-       duk_compact(ctx, -1);
-
-       /*
-        *  Debug dumping
-        */
-
-#ifdef DUK_USE_DDDPRINT
-       {
-               duk_hcompiledfunction *h;
-               duk_instr_t *p, *p_start, *p_end;
-
-               h = (duk_hcompiledfunction *) duk_get_hobject(ctx, -1);
-               p_start = (duk_instr_t *) 
DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, h);
-               p_end = (duk_instr_t *) 
DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, h);
-
-               p = p_start;
-               while (p < p_end) {
-                       DUK_DDD(DUK_DDDPRINT("BC %04ld: %!I        ; 0x%08lx 
op=%ld (%!C) a=%ld b=%ld c=%ld",
-                                            (long) (p - p_start),
-                                            (duk_instr_t) (*p),
-                                            (unsigned long) (*p),
-                                            (long) DUK_DEC_OP(*p),
-                                            (long) DUK_DEC_OP(*p),
-                                            (long) DUK_DEC_A(*p),
-                                            (long) DUK_DEC_B(*p),
-                                            (long) DUK_DEC_C(*p)));
-                       p++;
-               }
-       }
-#endif
-}
-
-/*
- *  Code emission helpers
- *
- *  Some emission helpers understand the range of target and source reg/const
- *  values and automatically emit shuffling code if necessary.  This is the
- *  case when the slot in question (A, B, C) is used in the standard way and
- *  for opcodes the emission helpers explicitly understand (like DUK_OP_CALL).
- *
- *  The standard way is that:
- *    - slot A is a target register
- *    - slot B is a source register/constant
- *    - slot C is a source register/constant
- *
- *  If a slot is used in a non-standard way the caller must indicate this
- *  somehow.  If a slot is used as a target instead of a source (or vice
- *  versa), this can be indicated with a flag to trigger proper shuffling
- *  (e.g. DUK__EMIT_FLAG_B_IS_TARGET).  If the value in the slot is not
- *  register/const related at all, the caller must ensure that the raw value
- *  fits into the corresponding slot so as to not trigger shuffling.  The
- *  caller must set a "no shuffle" flag to ensure compilation fails if
- *  shuffling were to be triggered because of an internal error.
- *
- *  For slots B and C the raw slot size is 9 bits but one bit is reserved for
- *  the reg/const indicator.  To use the full 9-bit range for a raw value,
- *  shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag.
- *  Shuffling is only done for A, B, and C slots, not the larger BC or ABC 
slots.
- *
- *  There is call handling specific understanding in the A-B-C emitter to
- *  convert call setup and call instructions into indirect ones if necessary.
- */
-
-/* Code emission flags, passed in the 'opcode' field.  Opcode + flags
- * fit into 16 bits for now, so use duk_small_uint.t.
- */
-#define DUK__EMIT_FLAG_NO_SHUFFLE_A      (1 << 8)
-#define DUK__EMIT_FLAG_NO_SHUFFLE_B      (1 << 9)
-#define DUK__EMIT_FLAG_NO_SHUFFLE_C      (1 << 10)
-#define DUK__EMIT_FLAG_A_IS_SOURCE       (1 << 11)  /* slot A is a source 
(default: target) */
-#define DUK__EMIT_FLAG_B_IS_TARGET       (1 << 12)  /* slot B is a target 
(default: source) */
-#define DUK__EMIT_FLAG_C_IS_TARGET       (1 << 13)  /* slot C is a target 
(default: source) */
-#define DUK__EMIT_FLAG_B_IS_TARGETSOURCE (1 << 14)  /* slot B is both a target 
and a source (used by extraops like DUK_EXTRAOP_INSTOF */
-#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT  (1 << 15)  /* reserve a jumpslot 
after instr before target spilling, used for NEXTENUM */
-
-/* XXX: clarify on when and where DUK__CONST_MARKER is allowed */
-/* XXX: opcode specific assertions on when consts are allowed */
-
-/* XXX: macro smaller than call? */
-DUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) {
-       duk_compiler_func *func;
-       func = &comp_ctx->curr_func;
-       return (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / 
sizeof(duk_compiler_instr));
-}
-
-DUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, 
duk_int_t pc) {
-       DUK_ASSERT(pc >= 0);
-       DUK_ASSERT((duk_size_t) pc < (duk_size_t) 
(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / 
sizeof(duk_compiler_instr)));
-       return ((duk_compiler_instr *) (void *) 
DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + pc;
-}
-
-/* emit instruction; could return PC but that's not needed in the majority
- * of cases.
- */
-DUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {
-#if defined(DUK_USE_PC2LINE)
-       duk_int_t line;
-#endif
-       duk_compiler_instr *instr;
-
-       DUK_DDD(DUK_DDDPRINT("duk__emit: 0x%08lx curr_token.start_line=%ld 
prev_token.start_line=%ld pc=%ld --> %!I",
-                            (unsigned long) ins,
-                            (long) comp_ctx->curr_token.start_line,
-                            (long) comp_ctx->prev_token.start_line,
-                            (long) duk__get_current_pc(comp_ctx),
-                            (duk_instr_t) ins));
-
-       instr = (duk_compiler_instr *) (void *) 
DUK_BW_ENSURE_GETPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, 
sizeof(duk_compiler_instr));
-       DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, 
sizeof(duk_compiler_instr));
-
-#if defined(DUK_USE_PC2LINE)
-       /* The line number tracking is a bit inconsistent right now, which
-        * affects debugger accuracy.  Mostly call sites emit opcodes when
-        * they have parsed a token (say a terminating semicolon) and called
-        * duk__advance().  In this case the line number of the previous
-        * token is the most accurate one (except in prologue where
-        * prev_token.start_line is 0).  This is probably not 100% correct
-        * right now.
-        */
-       /* approximation, close enough */
-       line = comp_ctx->prev_token.start_line;
-       if (line == 0) {
-               line = comp_ctx->curr_token.start_line;
-       }
-#endif
-
-       instr->ins = ins;
-#if defined(DUK_USE_PC2LINE)
-       instr->line = line;
-#endif
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-       if (line < comp_ctx->curr_func.min_line) {
-               comp_ctx->curr_func.min_line = line;
-       }
-       if (line > comp_ctx->curr_func.max_line) {
-               comp_ctx->curr_func.max_line = line;
-       }
-#endif
-
-       /* Limit checks for bytecode byte size and line number. */
-       if (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {
-               goto fail_bc_limit;
-       }
-#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS)
-#if defined(DUK_USE_BUFLEN16)
-       /* Buffer length is bounded to 0xffff automatically, avoid compile 
warning. */
-       if (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {
-               goto fail_bc_limit;
-       }
-#else
-       if (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {
-               goto fail_bc_limit;
-       }
-#endif
-#endif
-
-       return;
-
-  fail_bc_limit:
-       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);
-}
-
-/* Update function min/max line from current token.  Needed to improve
- * function line range information for debugging, so that e.g. opening
- * curly brace is covered by line range even when no opcodes are emitted
- * for the line containing the brace.
- */
-DUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) {
-#if defined(DUK_USE_DEBUGGER_SUPPORT)
-       duk_int_t line;
-
-       line = comp_ctx->curr_token.start_line;
-       if (line == 0) {
-               return;
-       }
-       if (line < comp_ctx->curr_func.min_line) {
-               comp_ctx->curr_func.min_line = line;
-       }
-       if (line > comp_ctx->curr_func.max_line) {
-               comp_ctx->curr_func.max_line = line;
-       }
-#else
-       DUK_UNREF(comp_ctx);
-#endif
-}
-
-#if 0 /* unused */
-DUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t 
op) {
-       duk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0));
-}
-#endif
-
-/* 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 = -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",
-                            (unsigned long) op_flags, (long) a, (long) b, 
(long) c));
-
-       /* We could rely on max temp/const checks: if they don't exceed BC
-        * limit, nothing here can either (just asserts would be enough).
-        * Currently we check for the limits, which provides additional
-        * protection against creating invalid bytecode due to compiler
-        * bugs.
-        */
-
-       DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */
-       DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);
-
-       /* Input shuffling happens before the actual operation, while output
-        * shuffling happens afterwards.  Output shuffling decisions are still
-        * made at the same time to reduce branch clutter; output shuffle 
decisions
-        * are recorded into X_out variables.
-        */
-
-       /* 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));
-               goto error_outofregs;
-       } else if (a <= DUK_BC_BC_MAX) {
-               comp_ctx->curr_func.needs_shuffle = 1;
-               tmp = comp_ctx->curr_func.shuffle1;
-               if (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {
-                       duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, 
a));
-               } else {
-                       duk_small_int_t op = op_flags & 0xff;
-                       if (op == DUK_OP_CSVAR || op == DUK_OP_CSREG || op == 
DUK_OP_CSPROP) {
-                               /* Special handling for call setup 
instructions.  The target
-                                * is expressed indirectly, but there is no 
output shuffling.
-                                */
-                               DUK_ASSERT((op_flags & 
DUK__EMIT_FLAG_A_IS_SOURCE) == 0);
-                               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);
-                               op_flags++;  /* indirect opcode follows direct 
*/
-                       } else {
-                               /* Output shuffle needed after main operation */
-                               a_out = a;
-                       }
-               }
-               a = tmp;
-       } else {
-               DUK_D(DUK_DPRINT("out of regs: 'a' (reg) needs shuffling but 
does not fit into BC, a: %ld", (long) a));
-               goto error_outofregs;
-       }
-
-       /* Slot B */
-
-       if (b & DUK__CONST_MARKER) {
-               DUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);
-               DUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);
-               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;
-                       tmp = comp_ctx->curr_func.shuffle2;
-                       duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, 
tmp, b));
-                       b = tmp;
-               } else {
-                       DUK_D(DUK_DPRINT("out of regs: 'b' (const) needs 
shuffling but does not fit into BC, b: %ld", (long) b));
-                       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) {
-                               /* Note: 0xff != DUK_BC_B_MAX */
-                               DUK_D(DUK_DPRINT("out of regs: 'b' (reg) needs 
shuffling but shuffle prohibited, b: %ld", (long) b));
-                               goto error_outofregs;
-                       }
-               } else if (b <= DUK_BC_BC_MAX) {
-                       comp_ctx->curr_func.needs_shuffle = 1;
-                       tmp = comp_ctx->curr_func.shuffle2;
-                       if (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) {
-                               /* Output shuffle needed after main operation */
-                               b_out = b;
-                       }
-                       if (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET) || 
(op_flags & DUK__EMIT_FLAG_B_IS_TARGETSOURCE)) {
-                               duk_small_int_t op = op_flags & 0xff;
-                               if (op == DUK_OP_CALL || op == DUK_OP_NEW ||
-                                   op == DUK_OP_MPUTOBJ || op == 
DUK_OP_MPUTARR) {
-                                       /* Special handling for 
CALL/NEW/MPUTOBJ/MPUTARR shuffling.
-                                        * For each, slot B identifies the 
first register of a range
-                                        * of registers, so normal shuffling 
won't work.  Instead,
-                                        * an indirect version of the opcode is 
used.
-                                        */
-                                       DUK_ASSERT((op_flags & 
DUK__EMIT_FLAG_B_IS_TARGET) == 0);
-                                       
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);
-                                       DUK_ASSERT(DUK_OP_MPUTARRI == 
DUK_OP_MPUTARR + 1);
-                                       op_flags++;  /* indirect opcode follows 
direct */
-                               } else {
-                                       duk__emit(comp_ctx, 
DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b));
-                               }
-                       }
-                       b = tmp;
-               } else {
-                       DUK_D(DUK_DPRINT("out of regs: 'b' (reg) needs 
shuffling but does not fit into BC, b: %ld", (long) b));
-                       goto error_outofregs;
-               }
-       }
-
-       /* Slot C */
-
-       if (c & DUK__CONST_MARKER) {
-               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;
-                       tmp = comp_ctx->curr_func.shuffle3;
-                       duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, 
tmp, c));
-                       c = tmp;
-               } else {
-                       DUK_D(DUK_DPRINT("out of regs: 'c' (const) needs 
shuffling but does not fit into BC, c: %ld", (long) c));
-                       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) {
-                               /* Note: 0xff != DUK_BC_C_MAX */
-                               DUK_D(DUK_DPRINT("out of regs: 'c' (reg) needs 
shuffling but shuffle prohibited, c: %ld", (long) c));
-                               goto error_outofregs;
-                       }
-               } else if (c <= DUK_BC_BC_MAX) {
-                       comp_ctx->curr_func.needs_shuffle = 1;
-                       tmp = comp_ctx->curr_func.shuffle3;
-                       if (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) {
-                               /* Output shuffle needed after main operation */
-                               c_out = c;
-                       } else {
-                               duk_small_int_t op = op_flags & 0xff;
-                               if (op == DUK_OP_EXTRA &&
-                                   (a == DUK_EXTRAOP_INITGET || a == 
DUK_EXTRAOP_INITSET)) {
-                                       /* Special shuffling for 
INITGET/INITSET, where slot C
-                                        * identifies a register pair and 
cannot be shuffled
-                                        * normally.  Use an indirect variant 
instead.
-                                        */
-                                       DUK_ASSERT((op_flags & 
DUK__EMIT_FLAG_C_IS_TARGET) == 0);
-                                       
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 
*/
-                               } else {
-                                       duk__emit(comp_ctx, 
DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c));
-                               }
-                       }
-                       c = tmp;
-               } else {
-                       DUK_D(DUK_DPRINT("out of regs: 'c' (reg) needs 
shuffling but does not fit into BC, c: %ld", (long) c));
-                       goto error_outofregs;
-               }
-       }
-
-       /* Main operation */
-
-       DUK_ASSERT_DISABLE(a >= DUK_BC_A_MIN);  /* unsigned */
-       DUK_ASSERT(a <= DUK_BC_A_MAX);
-       DUK_ASSERT_DISABLE(b >= DUK_BC_B_MIN);  /* unsigned */
-       DUK_ASSERT(b <= DUK_BC_B_MAX);
-       DUK_ASSERT_DISABLE(c >= DUK_BC_C_MIN);  /* unsigned */
-       DUK_ASSERT(c <= DUK_BC_C_MAX);
-
-       ins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);
-       duk__emit(comp_ctx, ins);
-
-       /* NEXTENUM needs a jump slot right after the main instruction.
-        * When the JUMP is taken, output spilling is not needed so this
-        * workaround is possible.  The jump slot PC is exceptionally
-        * plumbed through comp_ctx to minimize call sites.
-        */
-       if (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) {
-               comp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx);
-               duk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);
-       }
-
-       /* Output shuffling: only one output register is realistically possible.
-        *
-        * (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);
-               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);
-               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);
-               duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));
-       }
-
-       return;
-
- error_outofregs:
-       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
-}
-
-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 | 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 | DUK__EMIT_FLAG_NO_SHUFFLE_B | 
DUK__EMIT_FLAG_NO_SHUFFLE_C, a, 0, 0);
-}
-#endif
-
-DUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t 
op_flags, duk_regconst_t a, duk_regconst_t bc) {
-       duk_instr_t ins;
-       duk_int_t tmp;
-
-       /* allow caller to give a const number with the DUK__CONST_MARKER */
-       bc = bc & (~DUK__CONST_MARKER);
-
-       DUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */
-       DUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);
-       DUK_ASSERT_DISABLE(bc >= DUK_BC_BC_MIN);  /* unsigned */
-       DUK_ASSERT(bc <= DUK_BC_BC_MAX);
-       DUK_ASSERT((bc & DUK__CONST_MARKER) == 0);
-
-       if (bc <= DUK_BC_BC_MAX) {
-               ;
-       } else {
-               /* No BC shuffling now. */
-               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) {
-               goto error_outofregs;
-       } else if (a <= DUK_BC_BC_MAX) {
-               comp_ctx->curr_func.needs_shuffle = 1;
-               tmp = comp_ctx->curr_func.shuffle1;
-               ins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);
-               if (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {
-                       duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, 
a));
-                       duk__emit(comp_ctx, ins);
-               } else {
-                       duk__emit(comp_ctx, ins);
-                       duk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, 
a));
-               }
-       } else {
-               goto error_outofregs;
-       }
-       return;
-
- error_outofregs:
-       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
-}
-
-DUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, 
duk_regconst_t abc) {
-       duk_instr_t ins;
-
-       DUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN);  /* unsigned */
-       DUK_ASSERT(op <= DUK_BC_OP_MAX);
-       DUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN);  /* unsigned */
-       DUK_ASSERT(abc <= DUK_BC_ABC_MAX);
-       DUK_ASSERT((abc & DUK__CONST_MARKER) == 0);
-
-       if (abc <= DUK_BC_ABC_MAX) {
-               ;
-       } else {
-               goto error_outofregs;
-       }
-       ins = DUK_ENC_OP_ABC(op, abc);
-       DUK_DDD(DUK_DDDPRINT("duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld 
(%!C) abc=%ld (%!I)",
-                            (unsigned long) ins, (long) 
comp_ctx->curr_token.start_line,
-                            (long) duk__get_current_pc(comp_ctx), (long) op, 
(long) op,
-                            (long) abc, (duk_instr_t) ins));
-       duk__emit(comp_ctx, ins);
-       return;
-
- error_outofregs:
-       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
-}
-
-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" is covered by the assert, but it's needed
-        * with DUK_USE_SHUFFLE_TORTURE.
-        */
-       duk__emit_a_b_c(comp_ctx,
-                       DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A | 
(extraop_flags & ~0xff),  /* transfer flags */
-                       extraop_flags & 0xff,
-                       b,
-                       c);
-}
-
-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" is covered by the assert, but it's needed
-        * with DUK_USE_SHUFFLE_TORTURE.
-        */
-       duk__emit_a_b_c(comp_ctx,
-                       DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A | 
(extraop_flags & ~0xff),  /* transfer flags */
-                       extraop_flags & 0xff,
-                       b,
-                       0);
-}
-
-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" is covered by the assert, but it's needed
-        * with DUK_USE_SHUFFLE_TORTURE.
-        */
-       duk__emit_a_bc(comp_ctx,
-                      DUK_OP_EXTRA | DUK__EMIT_FLAG_NO_SHUFFLE_A,
-                      extraop,
-                      bc);
-}
-
-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" is covered by the assert, but it's needed
-        * with DUK_USE_SHUFFLE_TORTURE.
-        */
-       duk__emit_a_b_c(comp_ctx,
-                       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_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.
-        */
-
-       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 | 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 | 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_int_t curr_pc;
-       duk_int_t offset;
-
-       curr_pc = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));
-       offset = (duk_int_t) target_pc - (duk_int_t) curr_pc - 1;
-       DUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN);
-       DUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX);
-       duk__emit_abc(comp_ctx, DUK_OP_JUMP, (duk_regconst_t) (offset + 
DUK_BC_JUMP_BIAS));
-}
-
-DUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) {
-       duk_int_t ret;
-
-       ret = duk__get_current_pc(comp_ctx);  /* useful for patching jumps 
later */
-       duk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);
-       return ret;
-}
-
-/* Insert an empty jump in the middle of code emitted earlier.  This is
- * currently needed for compiling for-in.
- */
-DUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t 
jump_pc) {
-#if defined(DUK_USE_PC2LINE)
-       duk_int_t line;
-#endif
-       duk_compiler_instr *instr;
-       duk_size_t offset;
-
-       offset = jump_pc * sizeof(duk_compiler_instr),
-       instr = (duk_compiler_instr *) (void *)
-               DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,
-                                         &comp_ctx->curr_func.bw_code,
-                                         offset,
-                                         sizeof(duk_compiler_instr));
-
-#if defined(DUK_USE_PC2LINE)
-       line = comp_ctx->curr_token.start_line;  /* approximation, close enough 
*/
-#endif
-       instr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);
-#if defined(DUK_USE_PC2LINE)
-       instr->line = line;
-#endif
-
-       DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, 
sizeof(duk_compiler_instr));
-       if (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {
-               goto fail_bc_limit;
-       }
-       return;
-
-  fail_bc_limit:
-       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);
-}
-
-/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is 
intentional
- * to allow e.g. an INVALID opcode be overwritten with a JUMP (label 
management uses this).
- */
-DUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, 
duk_int_t target_pc) {
-       duk_compiler_instr *instr;
-       duk_int_t offset;
-
-       /* allow negative PCs, behave as a no-op */
-       if (jump_pc < 0) {
-               DUK_DDD(DUK_DDDPRINT("duk__patch_jump(): nop call, jump_pc=%ld 
(<0), target_pc=%ld",
-                                    (long) jump_pc, (long) target_pc));
-               return;
-       }
-       DUK_ASSERT(jump_pc >= 0);
-
-       /* XXX: range assert */
-       instr = duk__get_instr_ptr(comp_ctx, jump_pc);
-       DUK_ASSERT(instr != NULL);
-
-       /* XXX: range assert */
-       offset = target_pc - jump_pc - 1;
-
-       instr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS);
-       DUK_DDD(DUK_DDDPRINT("duk__patch_jump(): jump_pc=%ld, target_pc=%ld, 
offset=%ld",
-                            (long) jump_pc, (long) target_pc, (long) offset));
-}
-
-DUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t 
jump_pc) {
-       duk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx));
-}
-
-DUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t 
ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t 
const_varname, duk_small_uint_t flags) {
-       duk_compiler_instr *instr;
-
-       DUK_ASSERT((reg_catch & DUK__CONST_MARKER) == 0);
-
-       instr = duk__get_instr_ptr(comp_ctx, ldconst_pc);
-       DUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);
-       DUK_ASSERT(instr != NULL);
-       if (const_varname & DUK__CONST_MARKER) {
-               /* Have a catch variable. */
-               const_varname = const_varname & (~DUK__CONST_MARKER);
-               if (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) 
{
-                       /* Catch attempts to use out-of-range reg/const.  
Without this
-                        * check Duktape 0.12.0 could generate invalid code 
which caused
-                        * an assert failure on execution.  This error is 
triggered e.g.
-                        * for functions with a lot of constants and a 
try-catch statement.
-                        * Shuffling or opcode semantics change is needed to 
fix the issue.
-                        * See: test-bug-trycatch-many-constants.js.
-                        */
-                       DUK_D(DUK_DPRINT("failed to patch trycatch: flags=%ld, 
reg_catch=%ld, const_varname=%ld (0x%08lx)",
-                                        (long) flags, (long) reg_catch, (long) 
const_varname, (long) const_varname));
-                       DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);
-               }
-               instr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);
-       } else {
-               /* No catch variable, e.g. a try-finally; replace LDCONST with
-                * NOP to avoid a bogus LDCONST.
-                */
-               instr->ins = DUK_ENC_OP_A(DUK_OP_EXTRA, DUK_EXTRAOP_NOP);
-       }
-
-       instr = duk__get_instr_ptr(comp_ctx, trycatch_pc);
-       DUK_ASSERT(instr != NULL);
-       DUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN);
-       DUK_ASSERT(flags <= DUK_BC_A_MAX);
-       instr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch);
-}
-
-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 | 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 | 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) {
-       duk__emit_extraop_bc(comp_ctx, DUK_EXTRAOP_INVALID, 0);
-}
-
-/*
- *  Peephole optimizer for finished bytecode.
- *
- *  Does not remove opcodes; currently only straightens out unconditional
- *  jump chains which are generated by several control structures.
- */
-
-DUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {
-       duk_compiler_instr *bc;
-       duk_small_uint_t iter;
-       duk_int_t i, n;
-       duk_int_t count_opt;
-
-       bc = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code);
-#if defined(DUK_USE_BUFLEN16)
-       /* No need to assert, buffer size maximum is 0xffff. */
-#else
-       DUK_ASSERT((duk_size_t) DUK_BW_GET_SIZE(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr) <= (duk_size_t) 
DUK_INT_MAX);  /* bytecode limits */
-#endif
-       n = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, 
&comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));
-
-       for (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) {
-               count_opt = 0;
-
-               for (i = 0; i < n; i++) {
-                       duk_instr_t ins;
-                       duk_int_t target_pc1;
-                       duk_int_t target_pc2;
-
-                       ins = bc[i].ins;
-                       if (DUK_DEC_OP(ins) != DUK_OP_JUMP) {
-                               continue;
-                       }
-
-                       target_pc1 = i + 1 + DUK_DEC_ABC(ins) - 
DUK_BC_JUMP_BIAS;
-                       DUK_DDD(DUK_DDDPRINT("consider jump at pc %ld; 
target_pc=%ld", (long) i, (long) target_pc1));
-                       DUK_ASSERT(target_pc1 >= 0);
-                       DUK_ASSERT(target_pc1 < n);
-
-                       /* Note: if target_pc1 == i, we'll optimize a jump to 
itself.
-                        * This does not need to be checked for explicitly; the 
case
-                        * is rare and max iter breaks us out.
-                        */
-
-                       ins = bc[target_pc1].ins;
-                       if (DUK_DEC_OP(ins) != DUK_OP_JUMP) {
-                               continue;
-                       }
-
-                       target_pc2 = target_pc1 + 1 + DUK_DEC_ABC(ins) - 
DUK_BC_JUMP_BIAS;
-
-                       DUK_DDD(DUK_DDDPRINT("optimizing jump at pc %ld; old 
target is %ld -> new target is %ld",
-                                            (long) i, (long) target_pc1, 
(long) target_pc2));
-
-                       bc[i].ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i 
+ 1) + DUK_BC_JUMP_BIAS);
-
-                       count_opt++;
-               }
-
-               DUK_DD(DUK_DDPRINT("optimized %ld jumps on peephole round %ld", 
(long) count_opt, (long) (iter + 1)));
-
-               if (count_opt == 0) {
-                       break;
-               }
-       }
-}
-
-/*
- *  Intermediate value helpers
- */
-
-#define DUK__ISREG(comp_ctx,x)              (((x) & DUK__CONST_MARKER) == 0)
-#define DUK__ISCONST(comp_ctx,x)            (((x) & DUK__CONST_MARKER) != 0)
-#define DUK__ISTEMP(comp_ctx,x)             (DUK__ISREG((comp_ctx), (x)) && 
(duk_regconst_t) (x) >= (duk_regconst_t) ((comp_ctx)->curr_func.temp_first))
-#define DUK__GETTEMP(comp_ctx)              ((comp_ctx)->curr_func.temp_next)
-#define DUK__SETTEMP(comp_ctx,x)            ((comp_ctx)->curr_func.temp_next = 
(x))  /* dangerous: must only lower (temp_max not updated) */
-#define DUK__SETTEMP_CHECKMAX(comp_ctx,x)   
duk__settemp_checkmax((comp_ctx),(x))
-#define DUK__ALLOCTEMP(comp_ctx)            duk__alloctemp((comp_ctx))
-#define DUK__ALLOCTEMPS(comp_ctx,count)     duk__alloctemps((comp_ctx),(count))
-
-/* Flags for intermediate value coercions.  A flag for using a forced reg
- * is not needed, the forced_reg argument suffices and generates better
- * code (it is checked as it is used).
- */
-#define DUK__IVAL_FLAG_ALLOW_CONST          (1 << 0)  /* allow a constant to 
be returned */
-#define DUK__IVAL_FLAG_REQUIRE_TEMP         (1 << 1)  /* require a (mutable) 
temporary as a result (or a const if allowed) */
-#define DUK__IVAL_FLAG_REQUIRE_SHORT        (1 << 2)  /* require a short 
(8-bit) reg/const which fits into bytecode B/C slot */
-
-/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(ctx,x) */
-
-#if 0  /* enable manually for dumping */
-#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), 
(ispec)); } while (0)
-#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), 
(ivalue)); } while (0)
-
-DUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {
-       DUK_D(DUK_DPRINT("ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, 
value=%!T",
-                        (long) x->t, (unsigned long) x->regconst, (long) 
x->valstack_idx,
-                        duk_get_tval((duk_context *) comp_ctx->thr, 
x->valstack_idx)));
-}
-DUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {
-       DUK_D(DUK_DPRINT("ivalue dump: t=%ld op=%ld "
-                        "x1={t=%ld regconst=0x%08lx valstack_idx=%ld 
value=%!T} "
-                        "x2={t=%ld regconst=0x%08lx valstack_idx=%ld 
value=%!T}",
-                        (long) x->t, (long) x->op,
-                        (long) x->x1.t, (unsigned long) x->x1.regconst, (long) 
x->x1.valstack_idx,
-                        duk_get_tval((duk_context *) comp_ctx->thr, 
x->x1.valstack_idx),
-                        (long) x->x2.t, (unsigned long) x->x2.regconst, (long) 
x->x2.valstack_idx,
-                        duk_get_tval((duk_context *) comp_ctx->thr, 
x->x2.valstack_idx)));
-}
-#else
-#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)
-#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)
-#endif
-
-DUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, 
duk_ispec *dst) {
-       duk_context *ctx = (duk_context *) comp_ctx->thr;
-
-       dst->t = src->t;
-       dst->regconst = src->regconst;
-       duk_copy(ctx, src->valstack_idx, dst->valstack_idx);
-}
-
-DUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, 
duk_ivalue *dst) {
-       duk_context *ctx = (duk_context *) comp_ctx->thr;
-
-       dst->t = src->t;
-       dst->op = src->op;
-       dst->x1.t = src->x1.t;
-       dst->x1.regconst = src->x1.regconst;
-       dst->x2.t = src->x2.t;
-       dst->x2.regconst = src->x2.regconst;
-       duk_copy(ctx, src->x1.valstack_idx, dst->x1.valstack_idx);
-       duk_copy(ctx, src->x2.valstack_idx, dst->x2.valstack_idx);
-}
-
-/* XXX: to util */
-DUK_LOCAL duk_bool_t duk__is_whole_get_int32(duk_double_t x, duk_int32_t 
*ival) {
-       duk_small_int_t c;
-       duk_int32_t t;
-
-       c = DUK_FPCLASSIFY(x);
-       if (c == DUK_FP_NORMAL || (c == DUK_FP_ZERO && !DUK_SIGNBIT(x))) {
-               /* Don't allow negative zero as it will cause trouble with
-                * LDINT+LDINTX.  But positive zero is OK.
-                */
-               t = (duk_int32_t) x;
-               if ((duk_double_t) t == x) {
-                       *ival = t;
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-DUK_LOCAL duk_reg_t duk__alloctemps(duk_compiler_ctx *comp_ctx, 
duk_small_int_t num) {
-       duk_reg_t res;
-
-       res = comp_ctx->curr_func.temp_next;
-       comp_ctx->curr_func.temp_next += num;
-
-       if (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) {  /* == 
DUK__MAX_TEMPS is OK */
-               DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);
-       }
-
-       /* maintain highest 'used' temporary, needed to figure out nregs of 
function */
-       if (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) {
-               comp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next;
-       }
-
-       return res;
-}
-
-DUK_LOCAL duk_reg_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {
-       return duk__alloctemps(comp_ctx, 1);
-}
-
-DUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_reg_t 
temp_next) {
-       comp_ctx->curr_func.temp_next = temp_next;
-       if (temp_next > comp_ctx->curr_func.temp_max) {
-               comp_ctx->curr_func.temp_max = temp_next;
-       }
-}
-
-/* get const for value at valstack top */
-DUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-       duk_compiler_func *f = &comp_ctx->curr_func;
-       duk_tval *tv1;
-       duk_int_t i, n, n_check;
-
-       n = (duk_int_t) duk_get_length(ctx, f->consts_idx);
-
-       tv1 = DUK_GET_TVAL_NEGIDX(ctx, -1);
-       DUK_ASSERT(tv1 != NULL);
-
-#if defined(DUK_USE_FASTINT)
-       /* Explicit check for fastint downgrade. */
-       DUK_TVAL_CHKFAST_INPLACE(tv1);
-#endif
-
-       /* Sanity workaround for handling functions with a large number of
-        * constants at least somewhat reasonably.  Otherwise checking whether
-        * we already have the constant would grow very slow (as it is O(N^2)).
-        */
-       n_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? 
DUK__GETCONST_MAX_CONSTS_CHECK : n);
-       for (i = 0; i < n_check; i++) {
-               duk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, 
f->h_consts, i);
-
-               /* Strict equality is NOT enough, because we cannot use the same
-                * constant for e.g. +0 and -0.
-                */
-               if (duk_js_samevalue(tv1, tv2)) {
-                       DUK_DDD(DUK_DDDPRINT("reused existing constant for %!T 
-> const index %ld",
-                                            (duk_tval *) tv1, (long) i));
-                       duk_pop(ctx);
-                       return (duk_regconst_t) (i | DUK__CONST_MARKER);
-               }
-       }
-
-       if (n > DUK__MAX_CONSTS) {
-               DUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);
-       }
-
-       DUK_DDD(DUK_DDDPRINT("allocating new constant for %!T -> const index 
%ld",
-                            (duk_tval *) tv1, (long) n));
-       (void) duk_put_prop_index(ctx, f->consts_idx, n);  /* invalidates tv1, 
tv2 */
-       return (duk_regconst_t) (n | DUK__CONST_MARKER);
-}
-
-/* Get the value represented by an duk_ispec to a register or constant.
- * The caller can control the result by indicating whether or not:
- *
- *   (1) a constant is allowed (sometimes the caller needs the result to
- *       be in a register)
- *
- *   (2) a temporary register is required (usually when caller requires
- *       the register to be safely mutable; normally either a bound
- *       register or a temporary register are both OK)
- *
- *   (3) a forced register target needs to be used
- *
- * Bytecode may be emitted to generate the necessary value.  The return
- * value is either a register or a constant.
- */
-
-DUK_LOCAL
-duk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,
-                                         duk_ispec *x,
-                                         duk_reg_t forced_reg,
-                                         duk_small_uint_t flags) {
-       duk_hthread *thr = comp_ctx->thr;
-       duk_context *ctx = (duk_context *) thr;
-
-       DUK_DDD(DUK_DDDPRINT("duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, "
-                            "forced_reg=%ld, flags 0x%08lx: allow_const=%ld 
require_temp=%ld require_short=%ld",
-                            (long) x->t,
-                            (long) x->regconst,
-                            (duk_tval *) duk_get_tval(ctx, x->valstack_idx),
-                            (long) forced_reg,
-                            (unsigned long) flags,
-                            (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 
0),
-                            (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 
: 0),
-                            (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 
: 0)));
-
-       switch (x->t) {
-       case DUK_ISPEC_VALUE: {
-               duk_tval *tv;
-
-               tv = DUK_GET_TVAL_POSIDX(ctx, x->valstack_idx);
-               DUK_ASSERT(tv != NULL);
-
-               switch (DUK_TVAL_GET_TAG(tv)) {
-               case DUK_TAG_UNDEFINED: {
-                       /* Note: although there is no 'undefined' literal, 
undefined
-                        * values can occur during compilation as a result of 
e.g.
-                        * the 'void' operator.
-                        */
-                       duk_reg_t dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                       duk__emit_extraop_bc(comp_ctx, DUK_EXTRAOP_LDUNDEF, 
(duk_regconst_t) dest);
-                       return (duk_regconst_t) dest;
-               }
-               case DUK_TAG_NULL: {
-                       duk_reg_t dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                       duk__emit_extraop_bc(comp_ctx, DUK_EXTRAOP_LDNULL, 
(duk_regconst_t) dest);
-                       return (duk_regconst_t) dest;
-               }
-               case DUK_TAG_BOOLEAN: {
-                       duk_reg_t dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                       duk__emit_extraop_bc(comp_ctx,
-                                            (DUK_TVAL_GET_BOOLEAN(tv) ? 
DUK_EXTRAOP_LDTRUE : DUK_EXTRAOP_LDFALSE),
-                                            (duk_regconst_t) dest);
-                       return (duk_regconst_t) dest;
-               }
-               case DUK_TAG_POINTER: {
-                       DUK_UNREACHABLE();
-                       break;
-               }
-               case DUK_TAG_STRING: {
-                       duk_hstring *h;
-                       duk_reg_t dest;
-                       duk_regconst_t constidx;
-
-                       h = DUK_TVAL_GET_STRING(tv);
-                       DUK_UNREF(h);
-                       DUK_ASSERT(h != NULL);
-
-#if 0  /* XXX: to be implemented? */
-                       /* Use special opcodes to load short strings */
-                       if (DUK_HSTRING_GET_BYTELEN(h) <= 2) {
-                               /* Encode into a single opcode (18 bits can 
encode 1-2 bytes + length indicator) */
-                       } else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) {
-                               /* Encode into a double constant (53 bits can 
encode 6*8 = 48 bits + 3-bit length */
-                       }
-#endif
-                       duk_dup(ctx, x->valstack_idx);
-                       constidx = duk__getconst(comp_ctx);
-
-                       if (flags & DUK__IVAL_FLAG_ALLOW_CONST) {
-                               return constidx;
-                       }
-
-                       dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                       duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, 
(duk_regconst_t) dest, constidx);
-                       return (duk_regconst_t) dest;
-               }
-               case DUK_TAG_OBJECT: {
-                       DUK_UNREACHABLE();
-                       break;
-               }
-               case DUK_TAG_BUFFER: {
-                       DUK_UNREACHABLE();
-                       break;
-               }
-               case DUK_TAG_LIGHTFUNC: {
-                       DUK_UNREACHABLE();
-                       break;
-               }
-#if defined(DUK_USE_FASTINT)
-               case DUK_TAG_FASTINT:
-#endif
-               default: {
-                       /* number */
-                       duk_reg_t dest;
-                       duk_regconst_t constidx;
-                       duk_double_t dval;
-                       duk_int32_t ival;
-
-                       DUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));
-                       DUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));
-                       dval = DUK_TVAL_GET_NUMBER(tv);
-
-                       if (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {
-                               /* A number can be loaded either through a 
constant, using
-                                * LDINT, or using LDINT+LDINTX.  LDINT is 
always a size win,
-                                * LDINT+LDINTX is not if the constant is used 
multiple times.
-                                * Currently always prefer LDINT+LDINTX over a 
double constant.
-                                */
-
-                               if (duk__is_whole_get_int32(dval, &ival)) {
-                                       dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                                       duk__emit_load_int32(comp_ctx, dest, 
ival);
-                                       return (duk_regconst_t) dest;
-                               }
-                       }
-
-                       duk_dup(ctx, x->valstack_idx);
-                       constidx = duk__getconst(comp_ctx);
-
-                       if (flags & DUK__IVAL_FLAG_ALLOW_CONST) {
-                               return constidx;
-                       } else {
-                               dest = (forced_reg >= 0 ? forced_reg : 
DUK__ALLOCTEMP(comp_ctx));
-                               duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, 
(duk_regconst_t) dest, constidx);
-                               return (duk_regconst_t) dest;
-                       }
-               }
-               }  /* end switch */
-       }
-       case DUK_ISPEC_REGCONST: {
-               if (forced_reg >= 0) {
-                       if (x->regconst & DUK__CONST_MARKER) {
-                               duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, 
forced_reg, x->regconst);
-                       } else if (x->regconst != (duk_regconst_t) forced_reg) {
-                               duk__emit_a_bc(comp_ctx, DUK_OP_LDREG, 
forced_reg, x->regconst);
-                       } else {
-                               ; /* already in correct reg */
-                       }
-                       return (duk_regconst_t) forced_reg;
-               }
-
-               DUK_ASSERT(forced_reg < 0);
-               if (x->regconst & DUK__CONST_MARKER) {
-                       if (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {
-                               duk_reg_t dest = DUK__ALLOCTEMP(comp_ctx);
-                               duk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, 
(duk_regconst_t) dest, x->regconst);
-                               return (duk_regconst_t) dest;
-                       }
-                       return x->regconst;
-               }
-
-               DUK_ASSERT(forced_reg < 0 && !(x->regconst & 
DUK__CONST_MARKER));
-               if ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && 
!DUK__ISTEMP(comp_ctx, x->regconst)) {
-                       duk_reg_t dest = DUK__ALLOCTEMP(comp_ctx);
-                       d

<TRUNCATED>

Reply via email to