Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 42 additions & 38 deletions jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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++;
Expand Down
48 changes: 48 additions & 0 deletions jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/**
* @}
* @}
Expand Down
7 changes: 7 additions & 0 deletions jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions tests/jerry/array-prototype-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"); } });
Expand Down
7 changes: 7 additions & 0 deletions tests/jerry/array-prototype-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"); } });
Expand Down
7 changes: 7 additions & 0 deletions tests/jerry/array-prototype-slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"); } });
Expand Down
7 changes: 7 additions & 0 deletions tests/jerry/array-prototype-splice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"); } });
Expand Down