Skip to content

Commit b049998

Browse files
committed
Implemented Array.prototype.every()
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
1 parent 677a0a4 commit b049998

File tree

3 files changed

+164
-0
lines changed

3 files changed

+164
-0
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,107 @@ ecma_builtin_array_prototype_object_unshift (ecma_value_t this_arg, /**< this ar
980980
return ret_value;
981981
} /* ecma_builtin_array_prototype_object_unshift */
982982

983+
/**
984+
* The Array.prototype object's 'every' routine
985+
*
986+
* See also:
987+
* ECMA-262 v5, 15.4.4.16
988+
*
989+
* @return completion value
990+
* Returned value must be freed with ecma_free_completion_value.
991+
*/
992+
static ecma_completion_value_t
993+
ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argument */
994+
ecma_value_t arg1, /**< callbackfn */
995+
ecma_value_t arg2) /**< thisArg */
996+
{
997+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
998+
999+
/* 1. */
1000+
ECMA_TRY_CATCH (obj_this,
1001+
ecma_op_to_object (this_arg),
1002+
ret_value);
1003+
1004+
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
1005+
ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
1006+
1007+
/* 2. */
1008+
ECMA_TRY_CATCH (len_value,
1009+
ecma_op_object_get (obj_p, magic_string_length_p),
1010+
ret_value);
1011+
1012+
ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
1013+
1014+
/* 3. */
1015+
uint32_t len = ecma_number_to_uint32 (len_number);
1016+
1017+
/* 4. */
1018+
if (!ecma_op_is_callable (arg1))
1019+
{
1020+
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
1021+
}
1022+
else
1023+
{
1024+
ecma_value_t current_index;
1025+
ecma_number_t *num_p = ecma_alloc_number ();
1026+
ecma_object_t *func_object_p;
1027+
1028+
/* We already checked that arg1 is callable, so it will always coerce to an object. */
1029+
ecma_completion_value_t to_object_comp = ecma_op_to_object (arg1);
1030+
JERRY_ASSERT (ecma_is_completion_value_normal (to_object_comp));
1031+
1032+
func_object_p = ecma_get_object_from_completion_value (to_object_comp);
1033+
1034+
/* 7. */
1035+
for (uint32_t index = 0; index < len && ecma_is_completion_value_empty (ret_value); index++)
1036+
{
1037+
/* 7.a */
1038+
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
1039+
1040+
/* 7.c */
1041+
if (ecma_op_object_get_property (obj_p, index_str_p) != NULL)
1042+
{
1043+
/* 7.c.i */
1044+
ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_str_p), ret_value);
1045+
1046+
*num_p = ecma_uint32_to_number (index);
1047+
current_index = ecma_make_number_value (num_p);
1048+
1049+
ecma_value_t call_args[] = { get_value, current_index, obj_this };
1050+
/* 7.c.ii */
1051+
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);
1052+
1053+
/* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */
1054+
if (!ecma_is_value_true (ecma_op_to_boolean (call_value)))
1055+
{
1056+
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_FALSE);
1057+
}
1058+
1059+
ECMA_FINALIZE (call_value);
1060+
ECMA_FINALIZE (get_value);
1061+
}
1062+
1063+
ecma_deref_ecma_string (index_str_p);
1064+
}
1065+
1066+
ecma_free_completion_value (to_object_comp);
1067+
ecma_dealloc_number (num_p);
1068+
1069+
if (ecma_is_completion_value_empty (ret_value))
1070+
{
1071+
/* 8. */
1072+
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE);
1073+
}
1074+
}
1075+
1076+
ECMA_OP_TO_NUMBER_FINALIZE (len_number);
1077+
ECMA_FINALIZE (len_value);
1078+
ecma_deref_ecma_string (magic_string_length_p);
1079+
ECMA_FINALIZE (obj_this);
1080+
1081+
return ret_value;
1082+
} /* ecma_builtin_array_prototype_object_every */
1083+
9831084
/**
9841085
* The Array.prototype object's 'some' routine
9851086
*

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ ROUTINE (ECMA_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_array_prototype_object_inde
6767
ROUTINE (ECMA_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_array_prototype_object_last_index_of, 2, 1)
6868
ROUTINE (ECMA_MAGIC_STRING_SHIFT, ecma_builtin_array_prototype_object_shift, 0, 0)
6969
ROUTINE (ECMA_MAGIC_STRING_UNSHIFT, ecma_builtin_array_prototype_object_unshift, NON_FIXED, 1)
70+
ROUTINE (ECMA_MAGIC_STRING_EVERY, ecma_builtin_array_prototype_object_every, 2, 1)
7071
ROUTINE (ECMA_MAGIC_STRING_SOME, ecma_builtin_array_prototype_object_some, 2, 1)
7172
ROUTINE (ECMA_MAGIC_STRING_SLICE, ecma_builtin_array_prototype_object_slice, 2, 2)
7273

tests/jerry/array_prototype_every.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2015 Samsung Electronics Co., Ltd.
2+
// Copyright 2015 University of Szeged.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
var array = ["foo", [], Infinity, 4];
17+
18+
function f(arg1, arg2, arg3) {
19+
assert(arg1 === array[arg2]);
20+
assert(arg3 === array);
21+
return true;
22+
}
23+
24+
assert(array.every(f) === true);
25+
26+
function g(arg1, arg2, arg3) {
27+
if (arg1 === 1) {
28+
return true;
29+
} else {
30+
return false;
31+
}
32+
}
33+
34+
var arr1 = [1, 1, 1, 1, 1, 2];
35+
assert(arr1.every(g) === false);
36+
37+
var arr2 = [1, 1, 1, 1, 1, 1];
38+
assert(arr2.every(g) === true);
39+
40+
// Checking behavior when unable to get length
41+
var obj = { every : Array.prototype.every };
42+
Object.defineProperty(obj, 'length', { 'get' : function () {throw new ReferenceError ("foo"); } });
43+
44+
try {
45+
obj.every(f);
46+
assert(false);
47+
} catch (e) {
48+
assert(e.message === "foo");
49+
assert(e instanceof ReferenceError);
50+
}
51+
52+
// Checking behavior when unable to get element
53+
var obj = { every : Array.prototype.every, length : 1};
54+
Object.defineProperty(obj, '0', { 'get' : function () {throw new ReferenceError ("foo"); } });
55+
56+
try {
57+
obj.every(f);
58+
assert(false);
59+
} catch (e) {
60+
assert(e.message === "foo");
61+
assert(e instanceof ReferenceError);
62+
}

0 commit comments

Comments
 (0)