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);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
assert (+0 === -0);
|
||||
assert (1/-0 === -Infinity);
|
||||
assert (1/+0 === Infinity);
|
||||
assert ("3" -+-+-+ "1" + "1" / "3" * "6" + "2" === "42");
|
||||
Reference in New Issue
Block a user