Skip to content

Commit 0ef0b0d

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

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

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

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,103 @@ ecma_builtin_array_prototype_object_push (ecma_value_t this_arg, /**< this argum
506506
return ret_value;
507507
} /* ecma_builtin_array_prototype_object_push */
508508

509+
/**
510+
* The Array.prototype object's 'reverse' routine
511+
*
512+
* See also:
513+
* ECMA-262 v5, 15.4.4.8
514+
*
515+
* @return completion value
516+
* Returned value must be freed with ecma_free_completion_value.
517+
*/
518+
static ecma_completion_value_t
519+
ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg) /**< this argument */
520+
{
521+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
522+
523+
/* 1. */
524+
ECMA_TRY_CATCH (obj_this,
525+
ecma_op_to_object (this_arg),
526+
ret_value);
527+
528+
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
529+
ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
530+
531+
/* 2. */
532+
ECMA_TRY_CATCH (len_value,
533+
ecma_op_object_get (obj_p, magic_string_length_p),
534+
ret_value);
535+
536+
ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
537+
538+
/* 3. */
539+
uint32_t len = ecma_number_to_uint32 (len_number);
540+
541+
/* 4. */
542+
uint32_t middle = len / 2;
543+
544+
/* 5. and 6. */
545+
for (uint32_t lower = 0; lower < middle && ecma_is_completion_value_empty (ret_value); lower++)
546+
{
547+
/* 6.a */
548+
uint32_t upper = len - lower - 1;
549+
/* 6.b and 6.c */
550+
ecma_string_t *upper_str_p = ecma_new_ecma_string_from_uint32 (upper);
551+
ecma_string_t *lower_str_p = ecma_new_ecma_string_from_uint32 (lower);
552+
553+
/* 6.d and 6.e */
554+
ECMA_TRY_CATCH (lower_value, ecma_op_object_get (obj_p, lower_str_p), ret_value);
555+
ECMA_TRY_CATCH (upper_value, ecma_op_object_get (obj_p, upper_str_p), ret_value);
556+
557+
/* 6.f and 6.g */
558+
bool lower_exist = (ecma_op_object_get_property (obj_p, lower_str_p) != NULL);
559+
bool upper_exist = (ecma_op_object_get_property (obj_p, upper_str_p) != NULL);
560+
561+
/* 6.h */
562+
if (lower_exist && upper_exist)
563+
{
564+
ECMA_TRY_CATCH (outer_put_value, ecma_op_object_put (obj_p, lower_str_p, upper_value, true), ret_value);
565+
ECMA_TRY_CATCH (inner_put_value, ecma_op_object_put (obj_p, upper_str_p, lower_value, true), ret_value);
566+
ECMA_FINALIZE (inner_put_value);
567+
ECMA_FINALIZE (outer_put_value);
568+
}
569+
/* 6.i */
570+
else if (!lower_exist && upper_exist)
571+
{
572+
ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, lower_str_p, upper_value, true), ret_value);
573+
ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, upper_str_p, true), ret_value);
574+
ECMA_FINALIZE (del_value);
575+
ECMA_FINALIZE (put_value);
576+
}
577+
/* 6.j */
578+
else if (lower_exist && !upper_exist)
579+
{
580+
ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, lower_str_p, true), ret_value);
581+
ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, upper_str_p, lower_value, true), ret_value);
582+
ECMA_FINALIZE (put_value);
583+
ECMA_FINALIZE (del_value);
584+
}
585+
586+
ECMA_FINALIZE (upper_value);
587+
ECMA_FINALIZE (lower_value);
588+
ecma_deref_ecma_string (lower_str_p);
589+
ecma_deref_ecma_string (upper_str_p);
590+
}
591+
592+
if (ecma_is_completion_value_empty (ret_value))
593+
{
594+
/* 7. */
595+
ret_value = ecma_make_normal_completion_value (ecma_copy_value (obj_this, true));
596+
}
597+
598+
ECMA_OP_TO_NUMBER_FINALIZE (len_number);
599+
ECMA_FINALIZE (len_value);
600+
ecma_deref_ecma_string (magic_string_length_p);
601+
ECMA_FINALIZE (obj_this);
602+
603+
return ret_value;
604+
} /* ecma_builtin_array_prototype_object_reverse */
605+
509606
/**
510607
* The Array.prototype object's 'indexOf' routine
511608
*

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
@@ -63,6 +63,7 @@ ROUTINE (ECMA_MAGIC_STRING_JOIN, ecma_builtin_array_prototype_join, 1, 1)
6363
ROUTINE (ECMA_MAGIC_STRING_TO_STRING_UL, ecma_builtin_array_prototype_object_to_string, 0, 0)
6464
ROUTINE (ECMA_MAGIC_STRING_POP, ecma_builtin_array_prototype_object_pop, 0, 0)
6565
ROUTINE (ECMA_MAGIC_STRING_PUSH, ecma_builtin_array_prototype_object_push, NON_FIXED, 1)
66+
ROUTINE (ECMA_MAGIC_STRING_REVERSE, ecma_builtin_array_prototype_object_reverse, 0, 0)
6667
ROUTINE (ECMA_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_array_prototype_object_index_of, 2, 1)
6768
ROUTINE (ECMA_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_array_prototype_object_last_index_of, 2, 1)
6869
ROUTINE (ECMA_MAGIC_STRING_SHIFT, ecma_builtin_array_prototype_object_shift, 0, 0)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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 = [4, 3, 2, 1, 0]
17+
18+
array.reverse();
19+
20+
for (i = 0; i < array.length; i++) {
21+
assert(array[i] === i);
22+
}
23+
24+
// Checking behavior when unable to get length
25+
var obj = { reverse : Array.prototype.reverse };
26+
Object.defineProperty(obj, 'length', { 'get' : function () {throw new ReferenceError ("foo"); } });
27+
28+
try {
29+
obj.reverse();
30+
assert(false);
31+
} catch (e) {
32+
assert(e.message === "foo");
33+
assert(e instanceof ReferenceError);
34+
}
35+
36+
// Checking behavior when unable to get element
37+
var obj = { reverse : Array.prototype.reverse, length : 3 };
38+
Object.defineProperty(obj, '0', { 'get' : function () {throw new ReferenceError ("foo"); } });
39+
40+
try {
41+
obj.reverse();
42+
assert(false);
43+
} catch (e) {
44+
assert(e.message === "foo");
45+
assert(e instanceof ReferenceError);
46+
}

0 commit comments

Comments
 (0)