Add unary_plus and unary_minus opcodes

This commit is contained in:
Ilmir Usmanov
2014-10-15 15:20:49 +04:00
parent 819361c234
commit 032031a861
5 changed files with 105 additions and 18 deletions
+78
View File
@@ -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 */
+3 -1
View File
@@ -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) \
+4 -17
View File
@@ -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:
+2
View File
@@ -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);
+18
View File
@@ -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");