Add unary_plus and unary_minus opcodes
This commit is contained in:
@@ -299,3 +299,81 @@ opfunc_remainder (opcode_t opdata, /**< operation data */
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_remainder */
|
||||
|
||||
/**
|
||||
* 'Unary "+"' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4, 11.4.6
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_unary_plus (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
const idx_t dst_var_idx = opdata.data.remainder.dst;
|
||||
const idx_t var_idx = opdata.data.remainder.var_left;
|
||||
|
||||
int_data->pos++;
|
||||
|
||||
ecma_completion_value_t ret_value;
|
||||
|
||||
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
|
||||
ECMA_TRY_CATCH (num_value, ecma_op_to_number (var_value.u.value), ret_value);
|
||||
|
||||
ecma_number_t *var_p, *res_p;
|
||||
var_p = (ecma_number_t*) ECMA_GET_POINTER (num_value.u.value.value);
|
||||
|
||||
res_p = ecma_alloc_number ();
|
||||
*res_p = *var_p;
|
||||
ret_value = set_variable_value (int_data,
|
||||
dst_var_idx,
|
||||
ecma_make_number_value (res_p));
|
||||
|
||||
ecma_dealloc_number (res_p);
|
||||
|
||||
ECMA_FINALIZE (num_value);
|
||||
ECMA_FINALIZE (var_value);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_unary_plus */
|
||||
|
||||
/**
|
||||
* 'Unary "-"' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 11.4, 11.4.7
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_unary_minus (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
const idx_t dst_var_idx = opdata.data.remainder.dst;
|
||||
const idx_t var_idx = opdata.data.remainder.var_left;
|
||||
|
||||
int_data->pos++;
|
||||
|
||||
ecma_completion_value_t ret_value;
|
||||
|
||||
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
|
||||
ECMA_TRY_CATCH (num_value, ecma_op_to_number (var_value.u.value), ret_value);
|
||||
|
||||
ecma_number_t *var_p, *res_p;
|
||||
var_p = (ecma_number_t*) ECMA_GET_POINTER (num_value.u.value.value);
|
||||
|
||||
res_p = ecma_alloc_number ();
|
||||
*res_p = ecma_number_negate (*var_p);
|
||||
ret_value = set_variable_value (int_data,
|
||||
dst_var_idx,
|
||||
ecma_make_number_value (res_p));
|
||||
|
||||
ecma_dealloc_number (res_p);
|
||||
|
||||
ECMA_FINALIZE (num_value);
|
||||
ECMA_FINALIZE (var_value);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_unary_minus */
|
||||
|
||||
@@ -160,7 +160,9 @@ opcode_counter_t read_meta_opcode_counter (opcode_meta_type expected_type, int_d
|
||||
p##_3 (a, substraction, dst, var_left, var_right) \
|
||||
p##_3 (a, division, dst, var_left, var_right) \
|
||||
p##_3 (a, multiplication, dst, var_left, var_right) \
|
||||
p##_3 (a, remainder, dst, var_left, var_right)
|
||||
p##_3 (a, remainder, dst, var_left, var_right) \
|
||||
p##_2 (a, unary_minus, dst, var) \
|
||||
p##_2 (a, unary_plus, dst, var)
|
||||
|
||||
#define OP_JUMPS(p, a) \
|
||||
p##_2 (a, jmp_up, opcode_1, opcode_2) \
|
||||
|
||||
@@ -500,17 +500,6 @@ token_after_newlines_must_be_keyword (keyword kw)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
integer_zero (void)
|
||||
{
|
||||
STACK_DECLARE_USAGE (IDX)
|
||||
|
||||
STACK_PUSH (IDX, next_temp_name ());
|
||||
DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_SMALLINT, 0);
|
||||
|
||||
STACK_CHECK_USAGE_LHS ();
|
||||
}
|
||||
|
||||
static void
|
||||
boolean_true (void)
|
||||
{
|
||||
@@ -1652,18 +1641,16 @@ parse_unary_expression (void)
|
||||
{
|
||||
STACK_PUSH (IDX, next_temp_name ());
|
||||
NEXT (unary_expression);
|
||||
integer_zero ();
|
||||
DUMP_OPCODE_3 (addition, ID(3), ID(1), ID(2));
|
||||
STACK_DROP (IDX, 2);
|
||||
DUMP_OPCODE_2 (unary_plus, ID(2), ID(1));
|
||||
STACK_DROP (IDX, 1);
|
||||
break;
|
||||
}
|
||||
case TOK_MINUS:
|
||||
{
|
||||
STACK_PUSH (IDX, next_temp_name ());
|
||||
NEXT (unary_expression);
|
||||
integer_zero ();
|
||||
DUMP_OPCODE_3 (substraction, ID(3), ID(1), ID(2));
|
||||
STACK_DROP (IDX, 2);
|
||||
DUMP_OPCODE_2 (unary_minus, ID(2), ID(1));
|
||||
STACK_DROP (IDX, 1);
|
||||
break;
|
||||
}
|
||||
case TOK_COMPL:
|
||||
|
||||
@@ -215,6 +215,8 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
||||
PP_OP_3 (division, "%s = %s - %s;", dst, var_left, var_right);
|
||||
PP_OP_3 (multiplication, "%s = %s * %s;", dst, var_left, var_right);
|
||||
PP_OP_3 (remainder, "%s = %s %% %s;", dst, var_left, var_right);
|
||||
PP_OP_2 (unary_minus, "%s = -%s;", dst, var);
|
||||
PP_OP_2 (unary_plus, "%s = +%s;", dst, var);
|
||||
PP_OP_3 (b_shift_left, "%s = %s << %s;", dst, var_left, var_right);
|
||||
PP_OP_3 (b_shift_right, "%s = %s >> %s;", dst, var_left, var_right);
|
||||
PP_OP_3 (b_shift_uright, "%s = %s >>> %s;", dst, var_left, var_right);
|
||||
|
||||
Reference in New Issue
Block a user