From da02a37a02b15f724f2155991fbbffaf394790d3 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Thu, 8 Sep 2016 23:38:45 -0700 Subject: [PATCH] Remove several ecma_op_object_get_[own_]property calls. The ecma_op_object_get_[own_]property calls should be phased out from the project eventually and virtual properties should be introduced instead. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-globals.h | 1 + jerry-core/ecma/base/ecma-helpers-value.c | 12 + jerry-core/ecma/base/ecma-helpers.h | 1 + jerry-core/ecma/base/ecma-lcache.c | 2 - .../ecma-builtin-array-prototype.c | 204 ++++++++------ .../builtin-objects/ecma-builtin-helpers.c | 19 +- .../ecma-builtin-object-prototype.c | 5 +- .../ecma-builtin-regexp-prototype.c | 59 ++-- .../ecma/builtin-objects/ecma-builtins.c | 2 +- jerry-core/ecma/operations/ecma-conversion.c | 84 +++--- jerry-core/ecma/operations/ecma-lex-env.c | 12 +- .../ecma/operations/ecma-objects-arguments.c | 126 ++------- .../ecma/operations/ecma-objects-arguments.h | 6 +- .../ecma/operations/ecma-objects-general.c | 95 ------- .../ecma/operations/ecma-objects-general.h | 2 - jerry-core/ecma/operations/ecma-objects.c | 258 ++++++++++++++---- jerry-core/ecma/operations/ecma-objects.h | 7 +- jerry-core/ecma/operations/ecma-reference.c | 21 +- .../ecma/operations/ecma-regexp-object.c | 8 +- jerry-core/jerry.c | 12 +- jerry-core/vm/opcodes-ecma-relational.c | 2 +- jerry-core/vm/vm.c | 4 +- 22 files changed, 479 insertions(+), 463 deletions(-) diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 3dbe77b1f..99f4eeda2 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -79,6 +79,7 @@ typedef enum ECMA_SIMPLE_VALUE_TRUE, /**< boolean true */ ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */ ECMA_SIMPLE_VALUE_NULL, /**< null value */ + ECMA_SIMPLE_VALUE_NOT_FOUND, /**< a special value returned by ecma_op_object_find */ ECMA_SIMPLE_VALUE_REGISTER_REF, /**< register reference, a special "base" value for vm */ ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma values */ } ecma_simple_value_t; diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 76b4330e4..5a74106b8 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -221,6 +221,18 @@ ecma_is_value_false (ecma_value_t value) /**< ecma value */ return ecma_is_value_equal_to_simple_value (value, ECMA_SIMPLE_VALUE_FALSE); } /* ecma_is_value_false */ +/** + * Check if the value is not found. + * + * @return true - if the value contains ecma-not-found simple value, + * false - otherwise. + */ +inline bool __attr_pure___ __attr_always_inline___ +ecma_is_value_found (ecma_value_t value) /**< ecma value */ +{ + return value != ecma_make_simple_value (ECMA_SIMPLE_VALUE_NOT_FOUND); +} /* ecma_is_value_found */ + /** * Check if the value is array hole. * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 2c32e372d..655727d71 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -120,6 +120,7 @@ extern bool ecma_is_value_null (ecma_value_t) __attr_pure___; extern bool ecma_is_value_boolean (ecma_value_t) __attr_pure___; extern bool ecma_is_value_true (ecma_value_t) __attr_pure___; extern bool ecma_is_value_false (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_found (ecma_value_t) __attr_pure___; extern bool ecma_is_value_array_hole (ecma_value_t) __attr_pure___; extern bool ecma_is_value_integer_number (ecma_value_t) __attr_pure___; diff --git a/jerry-core/ecma/base/ecma-lcache.c b/jerry-core/ecma/base/ecma-lcache.c index b97874e5c..d4e38df55 100644 --- a/jerry-core/ecma/base/ecma-lcache.c +++ b/jerry-core/ecma/base/ecma-lcache.c @@ -210,8 +210,6 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */ { if (entry_p->object_cp != ECMA_NULL_POINTER && entry_p->prop_p == prop_p) { - JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_string_t, - entry_p->prop_name_cp) == prop_name_p); JERRY_ASSERT (entry_p->object_cp == object_cp); ecma_lcache_invalidate_entry (entry_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index ca4787bc9..08276b66f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -652,8 +652,8 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg) /**< this ar ECMA_TRY_CATCH (upper_value, ecma_op_object_get (obj_p, upper_str_p), ret_value); /* 6.f and 6.g */ - bool lower_exist = (ecma_op_object_get_property (obj_p, lower_str_p) != NULL); - bool upper_exist = (ecma_op_object_get_property (obj_p, upper_str_p) != NULL); + bool lower_exist = ecma_op_object_has_property (obj_p, lower_str_p); + bool upper_exist = ecma_op_object_has_property (obj_p, upper_str_p); /* 6.h */ if (lower_exist && upper_exist) @@ -759,16 +759,14 @@ ecma_builtin_array_prototype_object_shift (ecma_value_t this_arg) /**< this argu ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (k - 1); /* 7.c */ - if (ecma_op_object_get_property (obj_p, from_str_p) != NULL) - { - /* 7.d.i */ - ECMA_TRY_CATCH (curr_value, ecma_op_object_get (obj_p, from_str_p), ret_value); + ECMA_TRY_CATCH (curr_value, ecma_op_object_find (obj_p, from_str_p), ret_value); - /* 7.d.ii*/ + if (ecma_is_value_found (curr_value)) + { + /* 7.d.i, 7.d.ii */ ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, curr_value, true), ret_value); ECMA_FINALIZE (put_value); - ECMA_FINALIZE (curr_value); } else { @@ -777,6 +775,8 @@ ecma_builtin_array_prototype_object_shift (ecma_value_t this_arg) /**< this argu ECMA_FINALIZE (del_value); } + ECMA_FINALIZE (curr_value); + ecma_deref_ecma_string (to_str_p); ecma_deref_ecma_string (from_str_p); } @@ -886,11 +886,11 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (k); /* 10.c */ - if (ecma_op_object_get_property (obj_p, curr_idx_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, curr_idx_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 10.c.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, curr_idx_str_p), ret_value); - ecma_string_t *to_idx_str_p = ecma_new_ecma_string_from_uint32 (n); /* 10.c.ii */ @@ -905,10 +905,10 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar JERRY_ASSERT (ecma_is_value_true (put_comp)); ecma_deref_ecma_string (to_idx_str_p); - - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (curr_idx_str_p); } @@ -1441,12 +1441,11 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (del_item_idx); /* 9.b */ - if (ecma_op_object_get_property (obj_p, idx_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 9.c.i */ - ECMA_TRY_CATCH (get_value, - ecma_op_object_get (obj_p, idx_str_p), - ret_value); ecma_string_t *idx_str_new_p = ecma_new_ecma_string_from_uint32 (k); @@ -1462,9 +1461,10 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg JERRY_ASSERT (ecma_is_value_true (put_comp)); ecma_deref_ecma_string (idx_str_new_p); - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (idx_str_p); } @@ -1499,19 +1499,16 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to); /* 12.b.iii */ - if (ecma_op_object_get_property (obj_p, from_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 12.b.iv */ - ECMA_TRY_CATCH (get_value, - ecma_op_object_get (obj_p, from_str_p), - ret_value); - ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, get_value, true), ret_value); ECMA_FINALIZE (put_value); - ECMA_FINALIZE (get_value); } else { @@ -1523,6 +1520,8 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ECMA_FINALIZE (del_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (to_str_p); ecma_deref_ecma_string (from_str_p); } @@ -1552,19 +1551,16 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to); /* 13.b.iii */ - if (ecma_op_object_get_property (obj_p, from_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 13.b.iv */ - ECMA_TRY_CATCH (get_value, - ecma_op_object_get (obj_p, from_str_p), - ret_value); - ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, get_value, true), ret_value); ECMA_FINALIZE (put_value); - ECMA_FINALIZE (get_value); } else { @@ -1576,6 +1572,8 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ECMA_FINALIZE (del_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (to_str_p); ecma_deref_ecma_string (from_str_p); } @@ -1668,15 +1666,14 @@ ecma_builtin_array_prototype_object_unshift (ecma_value_t this_arg, /**< this ar ecma_string_t *to_str_p = ecma_new_ecma_string_from_number (new_idx); /* 6.c */ - if (ecma_op_object_get_property (obj_p, from_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { - /* 6.d.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, from_str_p), ret_value); - /* 6.d.ii */ + /* 6.d.i, 6.d.ii */ ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, get_value, true), ret_value); ECMA_FINALIZE (put_value); - ECMA_FINALIZE (get_value); } else { @@ -1685,6 +1682,8 @@ ecma_builtin_array_prototype_object_unshift (ecma_value_t this_arg, /**< this ar ECMA_FINALIZE (del_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (to_str_p); ecma_deref_ecma_string (from_str_p); } @@ -1778,20 +1777,19 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx); /* 9.a */ - if (ecma_op_object_get_property (obj_p, idx_str_p) != NULL) - { - /* 9.b.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, idx_str_p), ret_value); + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value); - /* 9.b.ii */ + if (ecma_is_value_found (get_value)) + { + /* 9.b.i, 9.b.ii */ if (ecma_op_strict_equality_compare (arg1, get_value)) { found_index = ((ecma_number_t) from_idx); } - - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (idx_str_p); } } @@ -1930,20 +1928,19 @@ ecma_builtin_array_prototype_object_last_index_of (ecma_value_t this_arg, /**< t ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx); /* 8.a */ - if (ecma_op_object_get_property (obj_p, idx_str_p) != NULL) - { - /* 8.b.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, idx_str_p), ret_value); + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value); - /* 8.b.ii */ + if (ecma_is_value_found (get_value)) + { + /* 8.b.i, 8.b.ii */ if (ecma_op_strict_equality_compare (search_element, get_value)) { num = ((ecma_number_t) from_idx); } - - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (idx_str_p); } @@ -2018,11 +2015,11 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); /* 7.c */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 7.c.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - current_index = ecma_make_uint32_value (index); ecma_value_t call_args[] = { get_value, current_index, obj_this }; @@ -2036,9 +2033,10 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu } ECMA_FINALIZE (call_value); - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (index_str_p); } @@ -2116,14 +2114,15 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); /* 7.c */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 7.c.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - current_index = ecma_make_uint32_value (index); ecma_value_t call_args[] = { get_value, current_index, obj_this }; + /* 7.c.ii */ ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); @@ -2134,9 +2133,10 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum } ECMA_FINALIZE (call_value); - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (index_str_p); } @@ -2213,11 +2213,11 @@ ecma_builtin_array_prototype_object_for_each (ecma_value_t this_arg, /**< this a ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); /* 7.b */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { /* 7.c.i */ - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - current_index = ecma_make_uint32_value (index); /* 7.c.ii */ @@ -2225,9 +2225,10 @@ ecma_builtin_array_prototype_object_for_each (ecma_value_t this_arg, /**< this a ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); ECMA_FINALIZE (call_value); - ECMA_FINALIZE (current_value); } + ECMA_FINALIZE (current_value); + ecma_deref_ecma_string (index_str_p); } @@ -2307,14 +2308,15 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume { /* 8.a */ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); + /* 8.b */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { - /* 8.c.i */ - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - /* 8.c.ii */ + /* 8.c.i, 8.c.ii */ current_index = ecma_make_uint32_value (index); - ecma_value_t call_args[] = {current_value, current_index, obj_this}; + ecma_value_t call_args[] = { current_value, current_index, obj_this }; ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); @@ -2330,9 +2332,10 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume JERRY_ASSERT (ecma_is_value_true (put_comp)); ECMA_FINALIZE (mapped_value); - ECMA_FINALIZE (current_value); } + ECMA_FINALIZE (current_value); + ecma_deref_ecma_string (index_str_p); } @@ -2421,11 +2424,11 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); /* 9.c */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (get_value)) { /* 9.c.i */ - ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - current_index = ecma_make_uint32_value (index); ecma_value_t call_args[] = { get_value, current_index, obj_this }; @@ -2452,9 +2455,10 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg } ECMA_FINALIZE (call_value); - ECMA_FINALIZE (get_value); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (index_str_p); } @@ -2545,24 +2549,34 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg { /* 8.a */ bool k_present = false; + /* 8.b */ while (!k_present && index < len && ecma_is_value_empty (ret_value)) { /* 8.b.i */ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); + k_present = true; /* 8.b.ii-iii */ - if ((k_present = (ecma_op_object_get_property (obj_p, index_str_p) != NULL))) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); accumulator = ecma_copy_value (current_value); - ECMA_FINALIZE (current_value); } + else + { + k_present = false; + } + + ECMA_FINALIZE (current_value); + /* 8.b.iv */ index++; ecma_deref_ecma_string (index_str_p); } + /* 8.c */ if (!k_present) { @@ -2576,12 +2590,13 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg { /* 9.a */ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); + /* 9.b */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { - /* 9.c.i */ - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - /* 9.c.ii */ + /* 9.c.i, 9.c.ii */ current_index = ecma_make_uint32_value (index); ecma_value_t call_args[] = {accumulator, current_value, current_index, obj_this}; @@ -2596,8 +2611,10 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg accumulator = ecma_copy_value (call_value); ECMA_FINALIZE (call_value); - ECMA_FINALIZE (current_value); } + + ECMA_FINALIZE (current_value); + ecma_deref_ecma_string (index_str_p); /* 9.d in for loop */ } @@ -2688,24 +2705,34 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th { /* 8.a */ bool k_present = false; + /* 8.b */ while (!k_present && index >= 0 && ecma_is_value_empty (ret_value)) { /* 8.b.i */ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 ((uint32_t) index); + k_present = true; /* 8.b.ii-iii */ - if ((k_present = (ecma_op_object_get_property (obj_p, index_str_p) != NULL))) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); accumulator = ecma_copy_value (current_value); - ECMA_FINALIZE (current_value); } + else + { + k_present = false; + } + + ECMA_FINALIZE (current_value); + /* 8.b.iv */ index--; ecma_deref_ecma_string (index_str_p); } + /* 8.c */ if (!k_present) { @@ -2719,12 +2746,13 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th { /* 9.a */ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 ((uint32_t) index); + /* 9.b */ - if (ecma_op_object_get_property (obj_p, index_str_p) != NULL) + ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value); + + if (ecma_is_value_found (current_value)) { - /* 9.c.i */ - ECMA_TRY_CATCH (current_value, ecma_op_object_get (obj_p, index_str_p), ret_value); - /* 9.c.ii */ + /* 9.c.i, 9.c.ii */ current_index = ecma_make_uint32_value ((uint32_t) index); ecma_value_t call_args[] = {accumulator, current_value, current_index, obj_this}; @@ -2739,8 +2767,10 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th accumulator = ecma_copy_value (call_value); ECMA_FINALIZE (call_value); - ECMA_FINALIZE (current_value); } + + ECMA_FINALIZE (current_value); + ecma_deref_ecma_string (index_str_p); /* 9.d in for loop */ } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index 3f43fdabc..8b6e80de0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -353,16 +353,15 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */ ecma_string_t *array_index_string_p = ecma_new_ecma_string_from_uint32 (array_index); /* 5.b.iii.2 */ - if (ecma_op_object_get_property (ecma_get_object_from_value (value), - array_index_string_p) != NULL) - { - ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index); + ECMA_TRY_CATCH (get_value, + ecma_op_object_find (ecma_get_object_from_value (value), + array_index_string_p), + ret_value); + if (ecma_is_value_found (get_value)) + { /* 5.b.iii.3.a */ - ECMA_TRY_CATCH (get_value, - ecma_op_object_get (ecma_get_object_from_value (value), - array_index_string_p), - ret_value); + ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index); /* 5.b.iii.3.b */ /* This will always be a simple value since 'is_throw' is false, so no need to free. */ @@ -375,11 +374,11 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */ false); /* Failure handling */ JERRY_ASSERT (ecma_is_value_true (put_comp)); - - ECMA_FINALIZE (get_value); ecma_deref_ecma_string (new_array_index_string_p); } + ECMA_FINALIZE (get_value); + ecma_deref_ecma_string (array_index_string_p); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c index 54534cc27..fb90b26c3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c @@ -151,9 +151,7 @@ ecma_builtin_object_prototype_object_has_own_property (ecma_value_t this_arg, /* ecma_object_t *obj_p = ecma_get_object_from_value (obj_val); /* 3. */ - ecma_property_t *property_p = ecma_op_object_get_own_property (obj_p, property_name_string_p); - - if (property_p != NULL) + if (ecma_op_object_has_own_property (obj_p, property_name_string_p)) { return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } @@ -161,6 +159,7 @@ ecma_builtin_object_prototype_object_has_own_property (ecma_value_t this_arg, /* { return_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } + ECMA_FINALIZE (obj_val); ECMA_FINALIZE (to_string_val); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c index 583161600..7c5663461 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -72,7 +72,6 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument } else { - ecma_string_t *pattern_string_p = NULL; uint16_t flags = 0; if (ecma_is_value_object (pattern_arg) @@ -89,39 +88,44 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument /* Get source. */ ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE); - ecma_property_t *prop_p = ecma_op_object_get_property (target_p, magic_string_p); - pattern_string_p = ecma_get_string_from_value (ecma_get_named_data_property_value (prop_p)); + ecma_value_t source_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); + ecma_string_t *pattern_string_p = ecma_get_string_from_value (source_value); /* Get flags. */ magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL); - prop_p = ecma_op_object_get_property (target_p, magic_string_p); + ecma_value_t global_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p); + ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (global_value)); + + if (ecma_is_value_true (global_value)) { flags |= RE_FLAG_GLOBAL; } - ecma_deref_ecma_string (magic_string_p); magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL); - prop_p = ecma_op_object_get_property (target_p, magic_string_p); + ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p); + ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value)); + + if (ecma_is_value_true (ignore_case_value)) { flags |= RE_FLAG_IGNORE_CASE; } - ecma_deref_ecma_string (magic_string_p); magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE); - prop_p = ecma_op_object_get_property (target_p, magic_string_p); + ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p); + ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (multiline_value)); + + if (ecma_is_value_true (multiline_value)) { flags |= RE_FLAG_MULTILINE; } - ecma_deref_ecma_string (magic_string_p); - ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value); ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this); @@ -136,6 +140,8 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument /* Should always succeed, since we're compiling from a source that has been compiled previously. */ JERRY_ASSERT (ecma_is_value_empty (bc_comp)); + ecma_deref_ecma_string (pattern_string_p); + re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t, *bc_prop_p); if (old_bc_p != NULL) @@ -155,6 +161,8 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument } else { + ecma_string_t *pattern_string_p = NULL; + /* Get source string. */ if (!ecma_is_value_undefined (pattern_arg)) { @@ -365,12 +373,13 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume /* Get RegExp source from the source property */ ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE); - ecma_property_t *source_prop_p = ecma_op_object_get_property (obj_p, magic_string_p); + ecma_value_t source_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); ecma_string_t *src_sep_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SLASH_CHAR); - ecma_string_t *source_str_p = ecma_get_string_from_value (ecma_get_named_data_property_value (source_prop_p)); + ecma_string_t *source_str_p = ecma_get_string_from_value (source_value); ecma_string_t *output_str_p = ecma_concat_ecma_strings (src_sep_str_p, source_str_p); + ecma_deref_ecma_string (source_str_p); ecma_string_t *concat_p = ecma_concat_ecma_strings (output_str_p, src_sep_str_p); ecma_deref_ecma_string (src_sep_str_p); @@ -379,10 +388,12 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume /* Check the global flag */ magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL); - ecma_property_t *global_prop_p = ecma_op_object_get_property (obj_p, magic_string_p); + ecma_value_t global_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (global_prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (global_value)); + + if (ecma_is_value_true (global_value)) { ecma_string_t *g_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_G_CHAR); concat_p = ecma_concat_ecma_strings (output_str_p, g_flag_str_p); @@ -393,10 +404,12 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume /* Check the ignoreCase flag */ magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL); - ecma_property_t *ignorecase_prop_p = ecma_op_object_get_property (obj_p, magic_string_p); + ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (ignorecase_prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value)); + + if (ecma_is_value_true (ignore_case_value)) { ecma_string_t *ic_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_I_CHAR); concat_p = ecma_concat_ecma_strings (output_str_p, ic_flag_str_p); @@ -405,12 +418,14 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume output_str_p = concat_p; } - /* Check the global flag */ + /* Check the multiline flag */ magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE); - ecma_property_t *multiline_prop_p = ecma_op_object_get_property (obj_p, magic_string_p); + ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p); ecma_deref_ecma_string (magic_string_p); - if (ecma_is_value_true (ecma_get_named_data_property_value (multiline_prop_p))) + JERRY_ASSERT (ecma_is_value_boolean (multiline_value)); + + if (ecma_is_value_true (multiline_value)) { ecma_string_t *m_flag_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_M_CHAR); concat_p = ecma_concat_ecma_strings (output_str_p, m_flag_str_p); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index dd4492a20..7d69910f7 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -622,7 +622,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id); - if (!was_instantiated || ecma_op_object_get_own_property (object_p, name_p) != NULL) + if (!was_instantiated || ecma_op_object_has_own_property (object_p, name_p)) { ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index 284eee53c..72abebab1 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -582,18 +582,18 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ // 3. ecma_string_t *enumerable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE); - if (ecma_op_object_get_property (obj_p, enumerable_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (enumerable_prop_value, - ecma_op_object_get (obj_p, enumerable_magic_string_p), - ret_value); + ECMA_TRY_CATCH (enumerable_prop_value, + ecma_op_object_find (obj_p, enumerable_magic_string_p), + ret_value); + if (ecma_is_value_found (enumerable_prop_value)) + { prop_desc.is_enumerable_defined = true; prop_desc.is_enumerable = ecma_op_to_boolean (enumerable_prop_value); - - ECMA_FINALIZE (enumerable_prop_value); } + ECMA_FINALIZE (enumerable_prop_value); + ecma_deref_ecma_string (enumerable_magic_string_p); if (!ECMA_IS_VALUE_ERROR (ret_value)) @@ -603,18 +603,18 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ // 4. ecma_string_t *configurable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE); - if (ecma_op_object_get_property (obj_p, configurable_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (configurable_prop_value, - ecma_op_object_get (obj_p, configurable_magic_string_p), - ret_value); + ECMA_TRY_CATCH (configurable_prop_value, + ecma_op_object_find (obj_p, configurable_magic_string_p), + ret_value); + if (ecma_is_value_found (configurable_prop_value)) + { prop_desc.is_configurable_defined = true; prop_desc.is_configurable = ecma_op_to_boolean (configurable_prop_value); - - ECMA_FINALIZE (configurable_prop_value); } + ECMA_FINALIZE (configurable_prop_value); + ecma_deref_ecma_string (configurable_magic_string_p); } @@ -625,18 +625,18 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ // 5. ecma_string_t *value_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_VALUE); - if (ecma_op_object_get_property (obj_p, value_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (value_prop_value, - ecma_op_object_get (obj_p, value_magic_string_p), - ret_value); + ECMA_TRY_CATCH (value_prop_value, + ecma_op_object_find (obj_p, value_magic_string_p), + ret_value); + if (ecma_is_value_found (value_prop_value)) + { prop_desc.is_value_defined = true; prop_desc.value = ecma_copy_value (value_prop_value); - - ECMA_FINALIZE (value_prop_value); } + ECMA_FINALIZE (value_prop_value); + ecma_deref_ecma_string (value_magic_string_p); } @@ -647,18 +647,18 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ // 6. ecma_string_t *writable_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE); - if (ecma_op_object_get_property (obj_p, writable_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (writable_prop_value, - ecma_op_object_get (obj_p, writable_magic_string_p), - ret_value); + ECMA_TRY_CATCH (writable_prop_value, + ecma_op_object_find (obj_p, writable_magic_string_p), + ret_value); + if (ecma_is_value_found (writable_prop_value)) + { prop_desc.is_writable_defined = true; prop_desc.is_writable = ecma_op_to_boolean (writable_prop_value); - - ECMA_FINALIZE (writable_prop_value); } + ECMA_FINALIZE (writable_prop_value); + ecma_deref_ecma_string (writable_magic_string_p); } @@ -669,12 +669,12 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ // 7. ecma_string_t *get_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GET); - if (ecma_op_object_get_property (obj_p, get_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (get_prop_value, - ecma_op_object_get (obj_p, get_magic_string_p), - ret_value); + ECMA_TRY_CATCH (get_prop_value, + ecma_op_object_find (obj_p, get_magic_string_p), + ret_value); + if (ecma_is_value_found (get_prop_value)) + { if (!ecma_op_is_callable (get_prop_value) && !ecma_is_value_undefined (get_prop_value)) { @@ -698,10 +698,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ prop_desc.get_p = get_p; } } - - ECMA_FINALIZE (get_prop_value); } + ECMA_FINALIZE (get_prop_value); + ecma_deref_ecma_string (get_magic_string_p); } @@ -713,12 +713,12 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ ecma_string_t *set_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SET); - if (ecma_op_object_get_property (obj_p, set_magic_string_p) != NULL) - { - ECMA_TRY_CATCH (set_prop_value, - ecma_op_object_get (obj_p, set_magic_string_p), - ret_value); + ECMA_TRY_CATCH (set_prop_value, + ecma_op_object_find (obj_p, set_magic_string_p), + ret_value); + if (ecma_is_value_found (set_prop_value)) + { if (!ecma_op_is_callable (set_prop_value) && !ecma_is_value_undefined (set_prop_value)) { @@ -742,10 +742,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ prop_desc.set_p = set_p; } } - - ECMA_FINALIZE (set_prop_value); } + ECMA_FINALIZE (set_prop_value); + ecma_deref_ecma_string (set_magic_string_p); } diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index d07488cb6..8461a7873 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -104,7 +104,7 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */ ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - return (ecma_op_object_get_property (binding_obj_p, name_p) != NULL); + return ecma_op_object_has_property (binding_obj_p, name_p); } } /* ecma_op_has_binding */ @@ -270,19 +270,21 @@ ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */ ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - if (ecma_op_object_get_property (binding_obj_p, name_p) == NULL) + ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p); + + if (!ecma_is_value_found (result)) { if (is_strict) { - return ecma_raise_reference_error (ECMA_ERR_MSG ("")); + result = ecma_raise_reference_error (ECMA_ERR_MSG ("")); } else { - return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } } - return ecma_op_object_get (binding_obj_p, name_p); + return result; } } /* ecma_op_get_binding_value */ diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index 6d68a97ec..f3feb6d8e 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -21,6 +21,7 @@ #include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" +#include "ecma-lcache.h" #include "ecma-lex-env.h" #include "ecma-objects.h" #include "ecma-objects-arguments.h" @@ -265,108 +266,43 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function * @return ecma value * Returned value must be freed with ecma_free_value */ -static ecma_value_t -ecma_arguments_get_mapped_arg_value (ecma_object_t *map_p, /**< [[ParametersMap]] object */ - ecma_property_t *arg_name_prop_p) /**< property of [[ParametersMap]] - corresponding to index and value - equal to mapped argument's name */ +void +ecma_arguments_update_mapped_arg_value (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p, /**< property name */ + ecma_property_t *property_p) /**< property value */ { + ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); + ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); + + ecma_value_t arg_name = ecma_op_object_find (map_p, property_name_p); + + if (!ecma_is_value_found (arg_name)) + { + return; + } + ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p); JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); - ecma_value_t arg_name_prop_value = ecma_get_named_data_property_value (arg_name_prop_p); + ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name); + ecma_value_t value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true); + ecma_deref_ecma_string (arg_name_p); - ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name_prop_value); + JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value)); - ecma_value_t completion = ecma_op_get_binding_value (lex_env_p, arg_name_p, true); - JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (completion)); + ecma_named_data_property_assign_value (object_p, property_p, value); + ecma_free_value (value); - return completion; -} /* ecma_arguments_get_mapped_arg_value */ - -/** - * [[Get]] ecma Arguments object's operation - * - * See also: - * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 - * ECMA-262 v5, 10.6 - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_op_arguments_object_get (ecma_object_t *obj_p, /**< the object */ - ecma_string_t *property_name_p) /**< property name */ -{ - // 1. - ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); - ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); - - // 2. - ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); - - // 3. - if (mapped_prop_p == NULL) + /* These properties cannot be cached. This is a temporary + * workaround until the property management is fully rewritten. */ + if (ecma_is_property_lcached (property_p)) { - /* We don't check for 'caller' (item 3.b) here, because the 'caller' property is defined - as non-configurable and it's get/set are set to [[ThrowTypeError]] object */ - - return ecma_op_general_object_get (obj_p, property_name_p); + ecma_lcache_invalidate (object_p, property_name_p, property_p); } - else - { - // 4. - return ecma_arguments_get_mapped_arg_value (map_p, mapped_prop_p); - } -} /* ecma_op_arguments_object_get */ - -/** - * [[GetOwnProperty]] ecma Arguments object's operation - * - * See also: - * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 - * ECMA-262 v5, 10.6 - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_property_t * -ecma_op_arguments_object_get_own_property (ecma_object_t *obj_p, /**< the object */ - ecma_string_t *property_name_p) /**< property name */ -{ - // 1. - ecma_property_t *desc_p = ecma_op_general_object_get_own_property (obj_p, property_name_p); - - // 2. - if (desc_p == NULL) - { - return desc_p; - } - - // 3. - ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); - ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); - - // 4. - ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); - - // 5. - if (mapped_prop_p != NULL) - { - // a. - ecma_value_t completion = ecma_arguments_get_mapped_arg_value (map_p, mapped_prop_p); - - ecma_named_data_property_assign_value (obj_p, desc_p, completion); - - ecma_free_value (completion); - } - - // 6. - return desc_p; -} /* ecma_op_arguments_object_get_own_property */ +} /* ecma_arguments_update_mapped_arg_value */ /** * [[DefineOwnProperty]] ecma Arguments object's operation @@ -389,9 +325,6 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); - // 2. - ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); - // 3. ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); @@ -403,7 +336,7 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *obj_p, /**< the obj ret_value); // 5. - if (mapped_prop_p != NULL) + if (ecma_op_object_has_own_property (map_p, property_name_p)) { // a. if (property_desc_p->is_get_defined @@ -485,9 +418,6 @@ ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */ ecma_value_t *map_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); - // 2. - ecma_property_t *mapped_prop_p = ecma_op_object_get_own_property (map_p, property_name_p); - // 3. ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); @@ -499,7 +429,7 @@ ecma_op_arguments_object_delete (ecma_object_t *obj_p, /**< the object */ if (ecma_is_value_true (delete_in_args_ret)) { - if (mapped_prop_p != NULL) + if (ecma_op_object_has_own_property (map_p, property_name_p)) { ecma_value_t delete_in_map_completion = ecma_op_object_delete (map_p, property_name_p, false); JERRY_ASSERT (ecma_is_value_true (delete_in_map_completion)); diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.h b/jerry-core/ecma/operations/ecma-objects-arguments.h index e907b262f..967f87ece 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.h +++ b/jerry-core/ecma/operations/ecma-objects-arguments.h @@ -23,10 +23,8 @@ extern void ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *, const ecma_value_t *, ecma_length_t, const ecma_compiled_code_t *); -extern ecma_value_t -ecma_op_arguments_object_get (ecma_object_t *, ecma_string_t *); -extern ecma_property_t * -ecma_op_arguments_object_get_own_property (ecma_object_t *, ecma_string_t *); +extern void +ecma_arguments_update_mapped_arg_value (ecma_object_t *, ecma_string_t *, ecma_property_t *); extern ecma_value_t ecma_op_arguments_object_delete (ecma_object_t *, ecma_string_t *, bool); extern ecma_value_t diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index c7375eaf6..5f7223e09 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -129,60 +129,6 @@ ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prot return obj_p; } /* ecma_op_create_object_object_noarg_and_set_prototype */ -/** - * [[Get]] ecma general object's operation - * - * See also: - * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 - * ECMA-262 v5, 8.12.3 - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */ - ecma_string_t *property_name_p) /**< property name */ -{ - JERRY_ASSERT (obj_p != NULL - && !ecma_is_lexical_environment (obj_p)); - JERRY_ASSERT (property_name_p != NULL); - - // 1. - const ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, property_name_p); - - // 2. - if (prop_p == NULL) - { - return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); - } - - // 3. - if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) - { - return ecma_copy_value (ecma_get_named_data_property_value (prop_p)); - } - else - { - // 4. - ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_p); - - // 5. - if (getter_p == NULL) - { - return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); - } - else - { - return ecma_op_function_call (getter_p, - ecma_make_object_value (obj_p), - NULL, - 0); - } - } - - JERRY_UNREACHABLE (); -} /* ecma_op_general_object_get */ - /** * [[GetOwnProperty]] ecma general object's operation * @@ -204,47 +150,6 @@ ecma_op_general_object_get_own_property (ecma_object_t *obj_p, /**< the object * return ecma_find_named_property (obj_p, property_name_p); } /* ecma_op_general_object_get_own_property */ -/** - * [[GetProperty]] ecma general object's operation - * - * See also: - * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 - * ECMA-262 v5, 8.12.2 - * - * @return pointer to a property - if it exists, - * NULL (i.e. ecma-undefined) - otherwise. - */ -ecma_property_t * -ecma_op_general_object_get_property (ecma_object_t *obj_p, /**< the object */ - ecma_string_t *property_name_p) /**< property name */ -{ - JERRY_ASSERT (obj_p != NULL - && !ecma_is_lexical_environment (obj_p)); - JERRY_ASSERT (property_name_p != NULL); - - // 1. - ecma_property_t *prop_p = ecma_op_object_get_own_property (obj_p, property_name_p); - - // 2. - if (prop_p != NULL) - { - return prop_p; - } - - // 3. - ecma_object_t *prototype_p = ecma_get_object_prototype (obj_p); - - // 4., 5. - if (prototype_p != NULL) - { - return ecma_op_object_get_property (prototype_p, property_name_p); - } - else - { - return NULL; - } -} /* ecma_op_general_object_get_property */ - /** * [[Put]] ecma general object's operation * diff --git a/jerry-core/ecma/operations/ecma-objects-general.h b/jerry-core/ecma/operations/ecma-objects-general.h index b4f42e883..8346a2ea0 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.h +++ b/jerry-core/ecma/operations/ecma-objects-general.h @@ -31,9 +31,7 @@ extern ecma_object_t *ecma_op_create_object_object_noarg (void); extern ecma_value_t ecma_op_create_object_object_arg (ecma_value_t); extern ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *); -extern ecma_value_t ecma_op_general_object_get (ecma_object_t *, ecma_string_t *); extern ecma_property_t *ecma_op_general_object_get_own_property (ecma_object_t *, ecma_string_t *); -extern ecma_property_t *ecma_op_general_object_get_property (ecma_object_t *, ecma_string_t *); extern ecma_value_t ecma_op_general_object_put (ecma_object_t *, ecma_string_t *, ecma_value_t, bool); extern ecma_value_t ecma_op_general_object_delete (ecma_object_t *, ecma_string_t *, bool); extern ecma_value_t ecma_op_general_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t); diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 3dd2b8a1a..02f9b2ccc 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -20,6 +20,7 @@ #include "ecma-globals.h" #include "ecma-function-object.h" #include "ecma-lcache.h" +#include "ecma-lex-env.h" #include "ecma-string-object.h" #include "ecma-objects-arguments.h" #include "ecma-objects-general.h" @@ -55,40 +56,6 @@ #define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) #endif /* !JERRY_NDEBUG */ -/** - * [[Get]] ecma object's operation - * - * See also: - * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_op_object_get (ecma_object_t *obj_p, /**< the object */ - ecma_string_t *property_name_p) /**< property name */ -{ - JERRY_ASSERT (obj_p != NULL - && !ecma_is_lexical_environment (obj_p)); - JERRY_ASSERT (property_name_p != NULL); - - const ecma_object_type_t type = ecma_get_object_type (obj_p); - - if (unlikely (type == ECMA_OBJECT_TYPE_ARGUMENTS)) - { - return ecma_op_arguments_object_get (obj_p, property_name_p); - } - - JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL - || type == ECMA_OBJECT_TYPE_FUNCTION - || type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION - || type == ECMA_OBJECT_TYPE_ARRAY - || type == ECMA_OBJECT_TYPE_STRING - || type == ECMA_OBJECT_TYPE_BOUND_FUNCTION); - - return ecma_op_general_object_get (obj_p, property_name_p); -} /* ecma_op_object_get */ - /** * Long path for ecma_op_object_get_own_property * @@ -132,8 +99,12 @@ ecma_op_object_get_own_property_longpath (ecma_object_t *obj_p, /**< the object case ECMA_OBJECT_TYPE_ARGUMENTS: { - prop_p = ecma_op_arguments_object_get_own_property (obj_p, property_name_p); + prop_p = ecma_op_general_object_get_own_property (obj_p, property_name_p); + if (prop_p != NULL) + { + ecma_arguments_update_mapped_arg_value (obj_p, property_name_p, prop_p); + } break; } @@ -178,10 +149,8 @@ ecma_op_object_get_own_property (ecma_object_t *obj_p, /**< the object */ { return prop_p; } - else - { - return ecma_op_object_get_own_property_longpath (obj_p, property_name_p); - } + + return ecma_op_object_get_own_property_longpath (obj_p, property_name_p); } /* ecma_op_object_get_own_property */ /** @@ -194,33 +163,202 @@ ecma_op_object_get_own_property (ecma_object_t *obj_p, /**< the object */ * NULL (i.e. ecma-undefined) - otherwise. */ ecma_property_t * -ecma_op_object_get_property (ecma_object_t *obj_p, /**< the object */ +ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */ ecma_string_t *property_name_p) /**< property name */ { - JERRY_ASSERT (obj_p != NULL - && !ecma_is_lexical_environment (obj_p)); + /* Circular reference is possible in JavaScript and testing it is complicated. */ + int max_depth = 128; + + do + { + ecma_property_t *property_p = ecma_op_object_get_own_property (object_p, property_name_p); + + if (property_p != NULL) + { + return property_p; + } + + if (--max_depth == 0) + { + break; + } + + object_p = ecma_get_object_prototype (object_p); + } + while (object_p != NULL); + + return NULL; +} /* ecma_op_object_get_property */ + +/** + * Checks whether an object (excluding prototypes) has a named property + * + * @return true if property is found + * false otherwise + */ +inline bool __attr_always_inline___ +ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ + return ecma_op_object_get_own_property (object_p, property_name_p) != NULL; +} /* ecma_op_object_has_own_property */ + +/** + * Checks whether an object (including prototypes) has a named property + * + * @return true if property is found + * false otherwise + */ +inline bool __attr_always_inline___ +ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ + return ecma_op_object_get_property (object_p, property_name_p) != NULL; +} /* ecma_op_object_has_property */ + +/** + * Search the value corresponding to a property name + * + * Note: search includes prototypes + * + * @return ecma value if property is found + * ECMA_SIMPLE_VALUE_NOT_FOUND if property is not found + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +ecma_op_object_find_own (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ + JERRY_ASSERT (object_p != NULL + && !ecma_is_lexical_environment (object_p)); JERRY_ASSERT (property_name_p != NULL); - JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p)); + if (unlikely (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARGUMENTS)) + { + ecma_value_t *map_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); + ecma_object_t *map_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *map_prop_p); - /* - * typedef ecma_property_t * (*get_property_ptr_t) (ecma_object_t *, ecma_string_t *); - * static const get_property_ptr_t get_property [ECMA_OBJECT_TYPE__COUNT] = - * { - * [ECMA_OBJECT_TYPE_GENERAL] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_STRING] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_get_property, - * [ECMA_OBJECT_TYPE_ARGUMENTS] = &ecma_op_general_object_get_property - * }; - * - * return get_property[type] (obj_p, property_name_p); - */ + ecma_value_t arg_name = ecma_op_object_find_own (map_p, property_name_p); - return ecma_op_general_object_get_property (obj_p, property_name_p); -} /* ecma_op_object_get_property */ + if (ecma_is_value_found (arg_name)) + { + ecma_value_t *scope_prop_p = ecma_get_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); + ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, *scope_prop_p); + + JERRY_ASSERT (lex_env_p != NULL + && ecma_is_lexical_environment (lex_env_p)); + + ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_name); + ecma_value_t result = ecma_op_get_binding_value (lex_env_p, arg_name_p, true); + ecma_deref_ecma_string (arg_name_p); + return result; + } + } + + ecma_property_t *property_p = ecma_op_object_get_own_property (object_p, property_name_p); + + if (property_p == NULL) + { + return ecma_make_simple_value (ECMA_SIMPLE_VALUE_NOT_FOUND); + } + + if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) + { + return ecma_fast_copy_value (ecma_get_named_data_property_value (property_p)); + } + + ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (property_p); + + if (getter_p == NULL) + { + return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + } + + return ecma_op_function_call (getter_p, ecma_make_object_value (object_p), NULL, 0); +} /* ecma_op_object_find_own */ + +/** + * Search the value corresponding to a property name + * + * Note: search includes prototypes + * + * @return ecma value if property is found + * ECMA_SIMPLE_VALUE_NOT_FOUND if property is not found + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +ecma_op_object_find (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ + /* Circular reference is possible in JavaScript and testing it is complicated. */ + int max_depth = 128; + + do + { + ecma_value_t value = ecma_op_object_find_own (object_p, property_name_p); + + if (ecma_is_value_found (value)) + { + return value; + } + + if (--max_depth == 0) + { + break; + } + + object_p = ecma_get_object_prototype (object_p); + } + while (object_p != NULL); + + return ecma_make_simple_value (ECMA_SIMPLE_VALUE_NOT_FOUND); +} /* ecma_op_object_find */ + +/** + * Get own property by name + * + * Note: property must be an existing data property + * + * @return ecma value + * Returned value must be freed with ecma_free_value + */ +inline ecma_value_t __attr_always_inline___ +ecma_op_object_get_own_data_prop (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ +#ifndef JERRY_NDEBUG + ecma_property_t *property_p = ecma_op_object_get_own_property (object_p, property_name_p); + + JERRY_ASSERT (property_p != NULL + && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA + && !ecma_is_property_configurable (property_p)); +#endif /* !JERRY_NDEBUG */ + + return ecma_op_object_find (object_p, property_name_p); +} /* ecma_op_object_get_own_data_prop */ + +/** + * [[Get]] ecma object's operation + * + * See also: + * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 + * + * @return ecma value + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +ecma_op_object_get (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p) /**< property name */ +{ + ecma_value_t value = ecma_op_object_find (object_p, property_name_p); + + if (!ecma_is_value_found (value)) + { + value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + } + + return value; +} /* ecma_op_object_get */ /** * [[Put]] ecma object's operation diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index 30b66b70d..af36f4bac 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -26,9 +26,14 @@ * @{ */ -extern ecma_value_t ecma_op_object_get (ecma_object_t *, ecma_string_t *); extern ecma_property_t *ecma_op_object_get_own_property (ecma_object_t *, ecma_string_t *); extern ecma_property_t *ecma_op_object_get_property (ecma_object_t *, ecma_string_t *); +extern bool ecma_op_object_has_own_property (ecma_object_t *, ecma_string_t *); +extern bool ecma_op_object_has_property (ecma_object_t *, ecma_string_t *); +extern ecma_value_t ecma_op_object_find_own (ecma_object_t *, ecma_string_t *); +extern ecma_value_t ecma_op_object_find (ecma_object_t *, ecma_string_t *); +extern ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *, ecma_string_t *); +extern ecma_value_t ecma_op_object_get (ecma_object_t *, ecma_string_t *); extern ecma_value_t ecma_op_object_put (ecma_object_t *, ecma_string_t *, ecma_value_t, bool); extern ecma_value_t ecma_op_object_delete (ecma_object_t *, ecma_string_t *, bool); extern ecma_value_t ecma_op_object_default_value (ecma_object_t *, ecma_preferred_type_hint_t); diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index 6517808a2..68db5bf7b 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -105,26 +105,11 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - ecma_property_t *property_p = ecma_op_object_get_property (binding_obj_p, name_p); + ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p); - if (likely (property_p != NULL)) + if (ecma_is_value_found (prop_value)) { - if (ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) - { - return ecma_fast_copy_value (ecma_get_named_data_property_value (property_p)); - } - - ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (property_p); - - if (getter_p == NULL) - { - return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); - } - - return ecma_op_function_call (getter_p, - ecma_make_object_value (binding_obj_p), - NULL, - 0); + return prop_value; } } diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 738e8e16c..c09bf1c08 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -1311,11 +1311,9 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */ if (input_buffer_p && (re_ctx.flags & RE_FLAG_GLOBAL)) { ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL); - ecma_property_t *lastindex_prop_p = ecma_op_object_get_property (regexp_object_p, magic_str_p); + ecma_value_t lastindex_value = ecma_op_object_get_own_data_prop (regexp_object_p, magic_str_p); - ECMA_OP_TO_NUMBER_TRY_CATCH (lastindex_num, - ecma_get_named_data_property_value (lastindex_prop_p), - ret_value) + ECMA_OP_TO_NUMBER_TRY_CATCH (lastindex_num, lastindex_value, ret_value) index = ecma_number_to_int32 (lastindex_num); @@ -1331,6 +1329,8 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */ ECMA_OP_TO_NUMBER_FINALIZE (lastindex_num); + ecma_fast_free_value (lastindex_value); + ecma_deref_ecma_string (magic_str_p); } diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index 60d452098..fef3de487 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -1084,10 +1084,10 @@ jerry_has_property (const jerry_value_t obj_val, /**< object value */ return false; } - ecma_property_t *prop_p = ecma_op_object_get_property (ecma_get_object_from_value (obj_val), - ecma_get_string_from_value (prop_name_val)); + bool has_property = ecma_op_object_has_property (ecma_get_object_from_value (obj_val), + ecma_get_string_from_value (prop_name_val)); - return ecma_make_boolean_value (prop_p != NULL); + return ecma_make_boolean_value (has_property); } /* jerry_has_property */ /** @@ -1108,10 +1108,10 @@ jerry_has_own_property (const jerry_value_t obj_val, /**< object value */ return false; } - ecma_property_t *prop_p = ecma_op_object_get_own_property (ecma_get_object_from_value (obj_val), - ecma_get_string_from_value (prop_name_val)); + bool has_property = ecma_op_object_has_own_property (ecma_get_object_from_value (obj_val), + ecma_get_string_from_value (prop_name_val)); - return ecma_make_boolean_value (prop_p != NULL); + return ecma_make_boolean_value (has_property); } /* jerry_has_own_property */ diff --git a/jerry-core/vm/opcodes-ecma-relational.c b/jerry-core/vm/opcodes-ecma-relational.c index 04112e432..8ce251790 100644 --- a/jerry-core/vm/opcodes-ecma-relational.c +++ b/jerry-core/vm/opcodes-ecma-relational.c @@ -228,7 +228,7 @@ opfunc_in (ecma_value_t left_value, /**< left value */ ecma_string_t *left_value_prop_name_p = ecma_get_string_from_value (str_left_value); ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value); - if (ecma_op_object_get_property (right_value_obj_p, left_value_prop_name_p) != NULL) + if (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index a3b30530c..28ba9a6ee 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -2169,8 +2169,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ lit_utf8_byte_t *data_ptr = chunk_p->data; ecma_string_t *prop_name_p = ecma_get_string_from_value (*(ecma_value_t *) data_ptr); - if (ecma_op_object_get_property (ecma_get_object_from_value (stack_top_p[-3]), - prop_name_p) == NULL) + if (!ecma_op_object_has_property (ecma_get_object_from_value (stack_top_p[-3]), + prop_name_p)) { stack_top_p[-2] = chunk_p->next_chunk_cp; ecma_deref_ecma_string (prop_name_p);