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;
|
return ret_value;
|
||||||
} /* opfunc_remainder */
|
} /* 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, substraction, dst, var_left, var_right) \
|
||||||
p##_3 (a, division, 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, 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) \
|
#define OP_JUMPS(p, a) \
|
||||||
p##_2 (a, jmp_up, opcode_1, opcode_2) \
|
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
|
static void
|
||||||
boolean_true (void)
|
boolean_true (void)
|
||||||
{
|
{
|
||||||
@@ -1652,18 +1641,16 @@ parse_unary_expression (void)
|
|||||||
{
|
{
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
NEXT (unary_expression);
|
NEXT (unary_expression);
|
||||||
integer_zero ();
|
DUMP_OPCODE_2 (unary_plus, ID(2), ID(1));
|
||||||
DUMP_OPCODE_3 (addition, ID(3), ID(1), ID(2));
|
STACK_DROP (IDX, 1);
|
||||||
STACK_DROP (IDX, 2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOK_MINUS:
|
case TOK_MINUS:
|
||||||
{
|
{
|
||||||
STACK_PUSH (IDX, next_temp_name ());
|
STACK_PUSH (IDX, next_temp_name ());
|
||||||
NEXT (unary_expression);
|
NEXT (unary_expression);
|
||||||
integer_zero ();
|
DUMP_OPCODE_2 (unary_minus, ID(2), ID(1));
|
||||||
DUMP_OPCODE_3 (substraction, ID(3), ID(1), ID(2));
|
STACK_DROP (IDX, 1);
|
||||||
STACK_DROP (IDX, 2);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOK_COMPL:
|
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 (division, "%s = %s - %s;", dst, var_left, var_right);
|
||||||
PP_OP_3 (multiplication, "%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_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_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_right, "%s = %s >> %s;", dst, var_left, var_right);
|
||||||
PP_OP_3 (b_shift_uright, "%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