Skip to content

Commit 08561f2

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

File tree

5 files changed

+220
-0
lines changed

5 files changed

+220
-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. Implementation-defined: set the separator to a single comma character */
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_builtin_helper_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_builtin_helper_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_REVERSE, ecma_builtin_array_prototype_object_reverse, 0, 0)

jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
#include "ecma-builtins.h"
2020
#include "ecma-conversion.h"
21+
#include "ecma-function-object.h"
2122
#include "ecma-exceptions.h"
2223
#include "ecma-helpers.h"
2324
#include "ecma-objects.h"
25+
#include "ecma-try-catch-macro.h"
2426

2527
/** \addtogroup ecma ECMA
2628
* @{
@@ -122,6 +124,71 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
122124
return ecma_make_normal_completion_value (ecma_make_string_value (ret_string_p));
123125
} /* ecma_builtin_helper_object_to_string */
124126

127+
/**
128+
* The Array.prototype's 'toLocaleString' single element operation routine
129+
*
130+
* See also:
131+
* ECMA-262 v5, 15.4.4.3 steps 6-8 and 10.b-d
132+
*
133+
* @return completion value
134+
* Returned value must be freed with ecma_free_completion_value.
135+
*/
136+
ecma_completion_value_t
137+
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /** < this object */
138+
uint32_t index) /** < array index */
139+
{
140+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
141+
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
142+
143+
ECMA_TRY_CATCH (index_value,
144+
ecma_op_object_get (obj_p, index_string_p),
145+
ret_value);
146+
147+
if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
148+
{
149+
ecma_string_t *return_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING__EMPTY);
150+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (return_string_p));
151+
}
152+
else
153+
{
154+
ECMA_TRY_CATCH (index_obj_value,
155+
ecma_op_to_object (index_value),
156+
ret_value);
157+
158+
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
159+
ecma_string_t *locale_string_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_TO_LOCALE_STRING_UL);
160+
161+
ECMA_TRY_CATCH (to_locale_value,
162+
ecma_op_object_get (index_obj_p, locale_string_magic_string_p),
163+
ret_value);
164+
165+
if (ecma_op_is_callable (to_locale_value))
166+
{
167+
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
168+
ret_value = ecma_op_function_call (locale_func_obj_p,
169+
ecma_make_object_value (index_obj_p),
170+
NULL,
171+
0);
172+
}
173+
else
174+
{
175+
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
176+
}
177+
178+
ECMA_FINALIZE (to_locale_value);
179+
180+
ecma_deref_ecma_string (locale_string_magic_string_p);
181+
182+
ECMA_FINALIZE (index_obj_value);
183+
}
184+
185+
ECMA_FINALIZE (index_value);
186+
187+
ecma_deref_ecma_string (index_string_p);
188+
189+
return ret_value;
190+
} /* ecma_builtin_helper_get_to_locale_string_at_index */
191+
125192
/**
126193
* @}
127194
* @}

jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h

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

2929
extern ecma_completion_value_t ecma_builtin_helper_object_to_string (const ecma_value_t this_arg);
30+
extern ecma_completion_value_t ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index);
3031

3132
/**
3233
* @}
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)