Skip to content

Commit 9b576ed

Browse files
committed
Implement Array.prototoype.toLocaleString()
JerryScript-DCO-1.0-Signed-off-by: Peter Gal [email protected]
1 parent d144cbf commit 9b576ed

File tree

5 files changed

+222
-0
lines changed

5 files changed

+222
-0
lines changed

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

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,105 @@ ecma_builtin_array_prototype_object_to_string (ecma_value_t this_arg) /**< this
326326
return return_value;
327327
} /* ecma_builtin_array_prototype_object_to_string */
328328

329+
330+
/**
331+
* The Array.prototype object's 'toLocaleString' routine
332+
*
333+
* See also:
334+
* ECMA-262 v5, 15.4.4.3
335+
*
336+
* @return completion value
337+
* Returned value must be freed with ecma_free_completion_value.
338+
*/
339+
static ecma_completion_value_t
340+
ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_arg) /**< this argument */
341+
{
342+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
343+
344+
/* 1. */
345+
ECMA_TRY_CATCH (obj_value,
346+
ecma_op_to_object (this_arg),
347+
ret_value);
348+
349+
ecma_object_t *obj_p = ecma_get_object_from_completion_value (obj_value);
350+
351+
ecma_string_t *length_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
352+
353+
/* 2. */
354+
ECMA_TRY_CATCH (length_value,
355+
ecma_op_object_get (obj_p, length_magic_string_p),
356+
ret_value);
357+
358+
/* 3. */
359+
ECMA_OP_TO_NUMBER_TRY_CATCH (length_number,
360+
length_value,
361+
ret_value);
362+
363+
uint32_t length = ecma_number_to_uint32 (length_number);
364+
365+
/* 4. */
366+
ecma_string_t *separator_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_COMMA_CHAR);
367+
368+
/* 5. */
369+
if (length == 0)
370+
{
371+
ecma_string_t *empty_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING__EMPTY);
372+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (empty_string_p));
373+
}
374+
else
375+
{
376+
/* 7-8. */
377+
ECMA_TRY_CATCH (first_value,
378+
ecma_op_array_get_to_locale_string_at_index (obj_p, 0),
379+
ret_value);
380+
381+
ecma_string_t *return_string_p = ecma_copy_or_ref_ecma_string (ecma_get_string_from_value (first_value));
382+
383+
/* 9-10. */
384+
for (uint32_t k = 1; ecma_is_completion_value_empty (ret_value) && (k < length); ++k)
385+
{
386+
ecma_string_t *part_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p);
387+
388+
ECMA_TRY_CATCH (next_string_value,
389+
ecma_op_array_get_to_locale_string_at_index (obj_p, k),
390+
ret_value);
391+
392+
ecma_string_t *next_string_p = ecma_get_string_from_completion_value (next_string_value);
393+
394+
ecma_deref_ecma_string (return_string_p);
395+
396+
return_string_p = ecma_concat_ecma_strings (part_string_p, next_string_p);
397+
398+
ECMA_FINALIZE (next_string_value);
399+
400+
ecma_deref_ecma_string (part_string_p);
401+
}
402+
403+
if (ecma_is_completion_value_empty (ret_value))
404+
{
405+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (return_string_p));
406+
}
407+
else
408+
{
409+
ecma_deref_ecma_string (return_string_p);
410+
}
411+
412+
ECMA_FINALIZE (first_value);
413+
}
414+
415+
ecma_deref_ecma_string (separator_string_p);
416+
417+
ECMA_OP_TO_NUMBER_FINALIZE (length_number);
418+
419+
ECMA_FINALIZE (length_value);
420+
421+
ecma_deref_ecma_string (length_magic_string_p);
422+
423+
ECMA_FINALIZE (obj_value);
424+
425+
return ret_value;
426+
} /* ecma_builtin_array_prototype_object_to_locale_string */
427+
329428
/**
330429
* The Array.prototype object's 'pop' routine
331430
*

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
@@ -61,6 +61,7 @@ NUMBER_VALUE (ECMA_MAGIC_STRING_LENGTH,
6161
ROUTINE (ECMA_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_array_prototype_object_for_each, 2, 1)
6262
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)
64+
ROUTINE (ECMA_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_array_prototype_object_to_locale_string, 0, 0)
6465
ROUTINE (ECMA_MAGIC_STRING_POP, ecma_builtin_array_prototype_object_pop, 0, 0)
6566
ROUTINE (ECMA_MAGIC_STRING_PUSH, ecma_builtin_array_prototype_object_push, NON_FIXED, 1)
6667
ROUTINE (ECMA_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_array_prototype_object_index_of, 2, 1)

jerry-core/ecma/operations/ecma-array-prototype.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,75 @@ ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /** < this object */
9595
return ret_value;
9696
} /* ecma_op_array_get_to_string_at_index */
9797

98+
/**
99+
* The Array.prototype's 'toLocaleString' single element operation routine
100+
*
101+
* See also:
102+
* ECMA-262 v5, 15.4.4.3
103+
*
104+
* @return completion value
105+
* Returned value must be freed with ecma_free_completion_value.
106+
*/
107+
ecma_completion_value_t
108+
ecma_op_array_get_to_locale_string_at_index (ecma_object_t *obj_p, /** < this object */
109+
uint32_t index) /** < array index */
110+
{
111+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
112+
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
113+
114+
ECMA_TRY_CATCH (index_value,
115+
ecma_op_object_get (obj_p, index_string_p),
116+
ret_value);
117+
118+
if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
119+
{
120+
ecma_string_t *return_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING__EMPTY);
121+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (return_string_p));
122+
}
123+
else
124+
{
125+
ECMA_TRY_CATCH (index_obj_value,
126+
ecma_op_to_object (index_value),
127+
ret_value);
128+
129+
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
130+
131+
ecma_string_t *locale_string_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_TO_LOCALE_STRING_UL);
132+
133+
ECMA_TRY_CATCH (to_locale_value,
134+
ecma_op_object_get (index_obj_p, locale_string_magic_string_p),
135+
ret_value);
136+
137+
if (ecma_op_is_callable (to_locale_value))
138+
{
139+
140+
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
141+
142+
ret_value = ecma_op_function_call (locale_func_obj_p,
143+
ecma_make_object_value (index_obj_p),
144+
NULL,
145+
0);
146+
}
147+
else
148+
{
149+
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
150+
}
151+
152+
ECMA_FINALIZE (to_locale_value);
153+
154+
ecma_deref_ecma_string (locale_string_magic_string_p);
155+
156+
ECMA_FINALIZE (index_obj_value);
157+
158+
}
159+
160+
ECMA_FINALIZE (index_value);
161+
162+
ecma_deref_ecma_string (index_string_p);
163+
164+
return ret_value;
165+
} /* ecma_op_array_get_to_locale_string_at_index */
166+
98167
/**
99168
* @}
100169
* @}

jerry-core/ecma/operations/ecma-array-prototype.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
extern ecma_completion_value_t ecma_op_array_get_separator_string (ecma_value_t separator);
3030
extern ecma_completion_value_t ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, uint32_t index);
31+
extern ecma_completion_value_t ecma_op_array_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index);
3132

3233
/**
3334
* @}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
assert ([].toLocaleString() === "");
17+
assert ([1].toLocaleString() === "1");
18+
assert ([1,2].toLocaleString() === "1,2");
19+
assert ([1,2,3].toLocaleString() === "1,2,3");
20+
21+
var test_ok = {
22+
length: 1,
23+
toLocaleString: function() { return "1"; }
24+
};
25+
26+
assert ([3, test_ok, 4, test_ok].toLocaleString() === "3,1,4,1");
27+
28+
29+
var test_fail = {
30+
toLocaleString: "FAIL"
31+
};
32+
33+
try {
34+
[test_fail].toLocaleString();
35+
assert (false);
36+
} catch (e) {
37+
assert (e instanceof TypeError);
38+
}
39+
40+
41+
var test_fail_call = {
42+
toLocaleString: function() { throw new ReferenceError("foo"); }
43+
};
44+
45+
46+
try {
47+
[1, 2, test_fail_call].toLocaleString();
48+
assert (false);
49+
} catch (e) {
50+
assert (e.message === "foo");
51+
assert (e instanceof ReferenceError);
52+
}

0 commit comments

Comments
 (0)