mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Use [[DefineOwnProperty]] in Array builtins where necessary.
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
This commit is contained in:
parent
8cd1ade515
commit
1193de88cc
@ -895,15 +895,18 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar
|
||||
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
|
||||
* Using [[Put]] is equivalent to using [[DefineOwnProperty]] as specified the standard,
|
||||
* so we use [[Put]] instead for simplicity. No need for a try-catch block since it is called
|
||||
* with is_throw = false.
|
||||
*/
|
||||
ecma_completion_value_t put_comp_value = ecma_op_object_put (new_array_p, to_idx_str_p, get_value, false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (put_comp_value));
|
||||
ecma_free_completion_value (put_comp_value);
|
||||
|
||||
/* 10.c.ii */
|
||||
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
|
||||
ecma_completion_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
to_idx_str_p,
|
||||
get_value,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));
|
||||
|
||||
ecma_deref_ecma_string (to_idx_str_p);
|
||||
|
||||
ECMA_FINALIZE (get_value);
|
||||
@ -1477,16 +1480,17 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg
|
||||
|
||||
ecma_string_t *idx_str_new_p = ecma_new_ecma_string_from_uint32 (k);
|
||||
|
||||
/* 9.c.ii
|
||||
* Using [[Put]] is equivalent to using [[DefineOwnProperty]] as specified the standard,
|
||||
* so we use [[Put]] instead for simplicity. No need for a try-catch block since it is called
|
||||
* with is_throw = false.
|
||||
*/
|
||||
ECMA_TRY_CATCH (put_value,
|
||||
ecma_op_object_put (new_array_p, idx_str_new_p, get_value, false),
|
||||
ret_value);
|
||||
/* 9.c.ii */
|
||||
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
|
||||
ecma_completion_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
idx_str_new_p,
|
||||
get_value,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));
|
||||
|
||||
ECMA_FINALIZE (put_value);
|
||||
ecma_deref_ecma_string (idx_str_new_p);
|
||||
ECMA_FINALIZE (get_value);
|
||||
}
|
||||
@ -2365,15 +2369,16 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume
|
||||
|
||||
ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);
|
||||
|
||||
/* 8.c.iii
|
||||
* By definition we should use [[DefineOwnProperty]] here, but since [[Put]] will create the
|
||||
* same property that we need, we can use it for simplicity. No need for a try-catch block
|
||||
* since it is called with is_throw = false.
|
||||
* ecma_op_to_boolean always returns a simple value, so no need to free.
|
||||
*/
|
||||
ecma_completion_value_t put_comp_value = ecma_op_object_put (new_array_p, index_str_p, mapped_value, false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp_value));
|
||||
ecma_free_completion_value (put_comp_value);
|
||||
/* 8.c.iii */
|
||||
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
|
||||
ecma_completion_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
index_str_p,
|
||||
mapped_value,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));
|
||||
|
||||
ECMA_FINALIZE (mapped_value);
|
||||
ECMA_FINALIZE (current_value);
|
||||
@ -2486,17 +2491,16 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
|
||||
if (ecma_is_completion_value_normal_true (ecma_op_to_boolean (call_value)))
|
||||
{
|
||||
ecma_string_t *to_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);
|
||||
/*
|
||||
* By definition we should use [[DefineOwnProperty]] here, but since [[Put]] will create the
|
||||
* same property that we need, we can use it for simplicity. No need for a try-catch block
|
||||
* since it is called with is_throw = false.
|
||||
*/
|
||||
ecma_completion_value_t put_comp_value = ecma_op_object_put (new_array_p,
|
||||
to_index_string_p,
|
||||
get_value,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp_value));
|
||||
ecma_free_completion_value (put_comp_value);
|
||||
|
||||
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
|
||||
ecma_completion_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
to_index_string_p,
|
||||
get_value,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp));
|
||||
|
||||
ecma_deref_ecma_string (to_index_string_p);
|
||||
new_array_index++;
|
||||
|
||||
@ -505,6 +505,54 @@ ecma_builtin_helper_string_index_normalize (ecma_number_t index, /**< index */
|
||||
return norm_index;
|
||||
} /* ecma_builtin_helper_string_index_normalize */
|
||||
|
||||
/**
|
||||
* Helper function for using [[DefineOwnProperty]].
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.12.9
|
||||
* ECMA-262 v5, 15.4.5.1
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
|
||||
ecma_string_t *index_p, /**< index string */
|
||||
ecma_value_t value, /**< value */
|
||||
bool writable, /**< writable */
|
||||
bool enumerable, /**< enumerable */
|
||||
bool configurable, /**< configurable */
|
||||
bool is_throw) /**< is_throw */
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = value;
|
||||
|
||||
if (writable)
|
||||
{
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = true;
|
||||
}
|
||||
|
||||
if (enumerable)
|
||||
{
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = true;
|
||||
}
|
||||
|
||||
if (configurable)
|
||||
{
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
}
|
||||
|
||||
return ecma_op_object_define_own_property (obj_p,
|
||||
index_p,
|
||||
&prop_desc,
|
||||
is_throw);
|
||||
} /* ecma_builtin_helper_def_prop */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -35,6 +35,13 @@ extern ecma_completion_value_t ecma_builtin_helper_array_concat_value (ecma_obje
|
||||
ecma_value_t);
|
||||
extern uint32_t ecma_builtin_helper_array_index_normalize (ecma_number_t index, uint32_t length);
|
||||
extern uint32_t ecma_builtin_helper_string_index_normalize (ecma_number_t index, uint32_t length);
|
||||
extern ecma_completion_value_t ecma_builtin_helper_def_prop (ecma_object_t *obj_p,
|
||||
ecma_string_t *index_p,
|
||||
ecma_value_t value,
|
||||
bool writable,
|
||||
bool enumerable,
|
||||
bool configurable,
|
||||
bool is_throw);
|
||||
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN
|
||||
|
||||
|
||||
@ -44,6 +44,13 @@ assert(filtered[1] === 3);
|
||||
assert(filtered[2] === 5);
|
||||
assert(filtered[3] === 7);
|
||||
|
||||
var arr = [1,2];
|
||||
Array.prototype[0] = 3;
|
||||
var newArr = arr.filter(function() { return true; });
|
||||
delete Array.prototype[0];
|
||||
assert(newArr.hasOwnProperty("0"));
|
||||
assert(newArr[0] === 1);
|
||||
|
||||
// Checking behavior when unable to get length
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, 'length', { 'get' : function () {throw new ReferenceError ("foo"); } });
|
||||
|
||||
@ -62,6 +62,13 @@ assert (long_array.map(func).equals([0,2]));
|
||||
long_array[100] = 1;
|
||||
assert (long_array.map(func).equals([0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,101]));
|
||||
|
||||
var arr = [1,2];
|
||||
Array.prototype[0] = 3;
|
||||
var newArr = arr.map(function(value) { return value; });
|
||||
delete Array.prototype[0];
|
||||
assert(newArr.hasOwnProperty("0"));
|
||||
assert(newArr[0] === 1);
|
||||
|
||||
// check behavior when unable to get length
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, 'length', { 'get' : function () {throw new ReferenceError ("foo"); } });
|
||||
|
||||
@ -79,6 +79,13 @@ array[4294967293] = "bar";
|
||||
var result = array.slice(-4294967297, -4294967296);
|
||||
assert(result.length === 0);
|
||||
|
||||
var arr = [1,2];
|
||||
Array.prototype[0] = 3;
|
||||
var newArr = arr.slice(0, 1);
|
||||
delete Array.prototype[0];
|
||||
assert(newArr.hasOwnProperty("0"));
|
||||
assert(newArr[0] === 1);
|
||||
|
||||
// Checking behavior when unable to get length
|
||||
var obj = { slice : Array.prototype.slice };
|
||||
Object.defineProperty(obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });
|
||||
|
||||
@ -144,6 +144,13 @@ assert(result.length === 1)
|
||||
assert(result[0] === "bar")
|
||||
assert(array[0] === "y")
|
||||
|
||||
var arr = [1,2];
|
||||
Array.prototype[0] = 3;
|
||||
var newArr = arr.splice(0, 1);
|
||||
delete Array.prototype[0];
|
||||
assert(newArr.hasOwnProperty("0"));
|
||||
assert(newArr[0] === 1);
|
||||
|
||||
// Checking behavior when unable to get length
|
||||
var obj = {splice : Array.prototype.splice};
|
||||
Object.defineProperty(obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user