From 6301cba0c3a4801b3512aa7b79f9f1a9236222ba Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 24 Jul 2014 21:09:02 +0400 Subject: [PATCH] Implementing equal_value, not_equal_value, less_than, greater_than opcodes. --- src/libcoreint/opcodes.c | 174 +++++++++++++++++++++++- src/libecmaoperations/ecma-comparison.c | 14 +- src/libecmaoperations/ecma-comparison.h | 4 +- 3 files changed, 179 insertions(+), 13 deletions(-) diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index b565ccc92..edc27460a 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -14,6 +14,7 @@ */ #include "ecma-alloc.h" +#include "ecma-comparison.h" #include "ecma-conversion.h" #include "ecma-exceptions.h" #include "ecma-helpers.h" @@ -340,12 +341,8 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */ op(b_xor) \ op(logical_and) \ op(logical_or) \ - op(equal_value) \ - op(not_equal_value) \ op(equal_value_type) \ op(not_equal_value_type) \ - op(less_than) \ - op(greater_than) \ op(less_or_equal_than) \ op(greater_or_equal_than) \ op(nop) \ @@ -835,6 +832,175 @@ opfunc_remainder(OPCODE opdata, /**< operation data */ return ret_value; } /* opfunc_remainder */ +/** + * 'Equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_equal_value(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.equal_value.dst; + const T_IDX left_var_idx = opdata.data.equal_value.var_left; + const T_IDX right_var_idx = opdata.data.equal_value.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_abstract_equality_compare( left_value.value, right_value.value); + + ret_value = set_variable_value( int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE)); + + ECMA_FINALIZE(right_value); + ECMA_FINALIZE(left_value); + + return ret_value; +} /* opfunc_equal_value */ + +/** + * 'Does-not-equals' opcode handler. + * + * See also: ECMA-262 v5, 11.9.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_not_equal_value(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.not_equal_value.dst; + const T_IDX left_var_idx = opdata.data.not_equal_value.var_left; + const T_IDX right_var_idx = opdata.data.not_equal_value.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + + bool is_equal = ecma_op_abstract_equality_compare( left_value.value, right_value.value); + + ret_value = set_variable_value( int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE + : ECMA_SIMPLE_VALUE_TRUE)); + + + ECMA_FINALIZE(right_value); + ECMA_FINALIZE(left_value); + + return ret_value; +} /* opfunc_not_equal_value */ + +/** + * 'Less-than' opcode handler. + * + * See also: ECMA-262 v5, 11.8.1 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_less_than(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.less_than.dst; + const T_IDX left_var_idx = opdata.data.less_than.var_left; + const T_IDX right_var_idx = opdata.data.less_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH(compare_result, + ecma_op_abstract_relational_compare (left_value.value, + right_value.value, + true), + ret_value); + + ecma_simple_value_t res; + + if ( ecma_is_value_undefined( compare_result.value) ) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT( ecma_is_value_boolean( compare_result.value) ); + + res = compare_result.value.value; + } + + ret_value = set_variable_value( int_data, dst_var_idx, ecma_make_simple_value( res)); + + ECMA_FINALIZE(compare_result); + ECMA_FINALIZE(right_value); + ECMA_FINALIZE(left_value); + + return ret_value; +} /* opfunc_less_than */ + +/** + * 'Greater-than' opcode handler. + * + * See also: ECMA-262 v5, 11.8.2 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +opfunc_greater_than(OPCODE opdata, /**< operation data */ + struct __int_data *int_data) /**< interpreter context */ +{ + const T_IDX dst_var_idx = opdata.data.greater_than.dst; + const T_IDX left_var_idx = opdata.data.greater_than.var_left; + const T_IDX right_var_idx = opdata.data.greater_than.var_right; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH(left_value, get_variable_value( int_data, left_var_idx, false), ret_value); + ECMA_TRY_CATCH(right_value, get_variable_value( int_data, right_var_idx, false), ret_value); + ECMA_TRY_CATCH(compare_result, + ecma_op_abstract_relational_compare (right_value.value, + left_value.value, + false), + ret_value); + + ecma_simple_value_t res; + + if ( ecma_is_value_undefined( compare_result.value) ) + { + res = ECMA_SIMPLE_VALUE_FALSE; + } + else + { + JERRY_ASSERT( ecma_is_value_boolean( compare_result.value) ); + + res = compare_result.value.value; + } + + ret_value = set_variable_value( int_data, dst_var_idx, ecma_make_simple_value( res)); + + ECMA_FINALIZE(compare_result); + ECMA_FINALIZE(right_value); + ECMA_FINALIZE(left_value); + + return ret_value; +} /* opfunc_greater_than */ + /** * 'Register variable declaration' opcode handler. * diff --git a/src/libecmaoperations/ecma-comparison.c b/src/libecmaoperations/ecma-comparison.c index 134721326..e695d71c5 100644 --- a/src/libecmaoperations/ecma-comparison.c +++ b/src/libecmaoperations/ecma-comparison.c @@ -35,8 +35,8 @@ * false - otherwise. */ bool -ecma_abstract_equality_compare(ecma_value_t x, /**< first operand */ - ecma_value_t y) /**< second operand */ +ecma_op_abstract_equality_compare(ecma_value_t x, /**< first operand */ + ecma_value_t y) /**< second operand */ { const bool is_x_undefined = ecma_is_value_undefined( x); const bool is_x_null = ecma_is_value_null( x); @@ -99,7 +99,7 @@ ecma_abstract_equality_compare(ecma_value_t x, /**< first operand */ { JERRY_UNIMPLEMENTED(); } -} /* ecma_abstract_equality_compare */ +} /* ecma_op_abstract_equality_compare */ /** * ECMA abstract relational comparison routine. @@ -110,9 +110,9 @@ ecma_abstract_equality_compare(ecma_value_t x, /**< first operand */ * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t -ecma_abstract_relational_compare(ecma_value_t x, /**< first operand */ - ecma_value_t y, /**< second operand */ - bool left_first) /**< 'LeftFirst' flag */ +ecma_op_abstract_relational_compare(ecma_value_t x, /**< first operand */ + ecma_value_t y, /**< second operand */ + bool left_first) /**< 'LeftFirst' flag */ { ecma_completion_value_t ret_value, px, py; @@ -167,7 +167,7 @@ ecma_abstract_relational_compare(ecma_value_t x, /**< first operand */ ECMA_FINALIZE( prim_first_converted_value); return ret_value; -} /* ecma_abstract_relational_compare */ +} /* ecma_op_abstract_relational_compare */ /** * @} diff --git a/src/libecmaoperations/ecma-comparison.h b/src/libecmaoperations/ecma-comparison.h index 2e810f425..50c8fc525 100644 --- a/src/libecmaoperations/ecma-comparison.h +++ b/src/libecmaoperations/ecma-comparison.h @@ -26,8 +26,8 @@ * @{ */ -extern bool ecma_abstract_equality_compare( ecma_value_t x, ecma_value_t y); -extern ecma_completion_value_t ecma_abstract_relational_compare(ecma_value_t x, ecma_value_t y, bool left_first); +extern bool ecma_op_abstract_equality_compare( ecma_value_t x, ecma_value_t y); +extern ecma_completion_value_t ecma_op_abstract_relational_compare(ecma_value_t x, ecma_value_t y, bool left_first); /** * @}