Skip to content

Commit 5c1a4f1

Browse files
rerobikaLaszloLango
authored andcommitted
Implement @@toStringTag well-known symbol related features (#2739)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent ca8442c commit 5c1a4f1

11 files changed

+277
-1
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
3333
ecma_builtin_arraybuffer_prototype_bytelength_getter,
3434
ECMA_PROPERTY_FIXED)
3535

36+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
37+
/* ECMA-262 v6, 24.1.4.4 */
38+
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
39+
LIT_MAGIC_STRING_ARRAY_BUFFER_UL,
40+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
41+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
42+
3643
/* Routine properties:
3744
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
3845
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_arraybuffer_prototype_object_slice, 2, 2)

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

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
#include "ecma-conversion.h"
2222
#include "ecma-function-object.h"
2323
#include "ecma-exceptions.h"
24+
#include "ecma-gc.h"
2425
#include "ecma-helpers.h"
26+
#include "jmem.h"
2527
#include "ecma-objects.h"
2628
#include "ecma-try-catch-macro.h"
2729
#include "lit-magic-strings.h"
@@ -33,6 +35,69 @@
3335
* @{
3436
*/
3537

38+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
39+
/**
40+
* Helper function for Object.prototype.toString routine when
41+
* the @@toStringTag property is present
42+
*
43+
* See also:
44+
* ECMA-262 v6, 19.1.3.6
45+
*
46+
* @return ecma value
47+
* Returned value must be freed with ecma_free_value.
48+
*/
49+
static ecma_value_t
50+
ecma_builtin_helper_object_to_string_tag_helper (ecma_value_t tag_value) /**< string tag */
51+
{
52+
JERRY_ASSERT (ecma_is_value_string (tag_value));
53+
54+
ecma_string_t *tag_str_p = ecma_get_string_from_value (tag_value);
55+
ecma_string_t *ret_string_p;
56+
57+
/* Building string "[object #@@toStringTag#]"
58+
The string size will be size("[object ") + size(#@@toStringTag#) + size ("]"). */
59+
const lit_utf8_size_t buffer_size = 9 + ecma_string_get_size (tag_str_p);
60+
JMEM_DEFINE_LOCAL_ARRAY (str_buffer, buffer_size, lit_utf8_byte_t);
61+
62+
lit_utf8_byte_t *buffer_ptr = str_buffer;
63+
64+
const lit_magic_string_id_t magic_string_ids[] =
65+
{
66+
LIT_MAGIC_STRING_LEFT_SQUARE_CHAR,
67+
LIT_MAGIC_STRING_OBJECT,
68+
LIT_MAGIC_STRING_SPACE_CHAR,
69+
};
70+
71+
/* Copy to buffer the "[object " string */
72+
for (uint32_t i = 0; i < sizeof (magic_string_ids) / sizeof (lit_magic_string_id_t); ++i)
73+
{
74+
buffer_ptr = lit_copy_magic_string_to_buffer (magic_string_ids[i], buffer_ptr,
75+
(lit_utf8_size_t) ((str_buffer + buffer_size) - buffer_ptr));
76+
77+
JERRY_ASSERT (buffer_ptr <= str_buffer + buffer_size);
78+
}
79+
80+
/* Copy to buffer the #@@toStringTag# string */
81+
buffer_ptr += ecma_string_copy_to_utf8_buffer (tag_str_p, buffer_ptr,
82+
(lit_utf8_size_t) ((str_buffer + buffer_size) - buffer_ptr));
83+
84+
JERRY_ASSERT (buffer_ptr <= str_buffer + buffer_size);
85+
86+
/* Copy to buffer the "]" string */
87+
buffer_ptr = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR, buffer_ptr,
88+
(lit_utf8_size_t) ((str_buffer + buffer_size) - buffer_ptr));
89+
90+
JERRY_ASSERT (buffer_ptr <= str_buffer + buffer_size);
91+
92+
ret_string_p = ecma_new_ecma_string_from_utf8 (str_buffer, (lit_utf8_size_t) (buffer_ptr - str_buffer));
93+
94+
JMEM_FINALIZE_LOCAL_ARRAY (str_buffer);
95+
ecma_deref_ecma_string (tag_str_p);
96+
97+
return ecma_make_string_value (ret_string_p);
98+
} /* ecma_builtin_helper_object_to_string_tag_helper */
99+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
100+
36101
/**
37102
* Common implementation of the Object.prototype.toString routine
38103
*
@@ -75,7 +140,25 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
75140

76141
type_string = ecma_object_get_class_name (obj_p);
77142

78-
ecma_free_value (obj_this);
143+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
144+
ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_TO_STRING_TAG);
145+
146+
if (ECMA_IS_VALUE_ERROR (tag_value))
147+
{
148+
ecma_deref_object (obj_p);
149+
return tag_value;
150+
}
151+
152+
if (ecma_is_value_string (tag_value))
153+
{
154+
ecma_deref_object (obj_p);
155+
return ecma_builtin_helper_object_to_string_tag_helper (tag_value);
156+
}
157+
158+
ecma_free_value (tag_value);
159+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
160+
161+
ecma_deref_object (obj_p);
79162
}
80163

81164
ecma_string_t *ret_string_p;

jerry-core/ecma/builtin-objects/ecma-builtin-json.inc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121

2222
#ifndef CONFIG_DISABLE_JSON_BUILTIN
2323

24+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
25+
/* ECMA-262 v6, 24.3.3 */
26+
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
27+
LIT_MAGIC_STRING_JSON_U,
28+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
29+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
30+
2431
/* Routine properties:
2532
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
2633
ROUTINE (LIT_MAGIC_STRING_PARSE, ecma_builtin_json_parse, 2, 2)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
2929
ECMA_BUILTIN_ID_MAP,
3030
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
3131

32+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
33+
/* ECMA-262 v6, 23.1.3.13 */
34+
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
35+
LIT_MAGIC_STRING_MAP_UL,
36+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
37+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
38+
3239
/* Routine properties:
3340
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
3441
ROUTINE (LIT_MAGIC_STRING_CLEAR, ecma_builtin_map_prototype_object_clear, 0, 0)

jerry-core/ecma/builtin-objects/ecma-builtin-math.inc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ NUMBER_VALUE (LIT_MAGIC_STRING_SQRT2_U,
6464
ECMA_BUILTIN_NUMBER_SQRT2,
6565
ECMA_PROPERTY_FIXED)
6666

67+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
68+
/* ECMA-262 v6, 20.2.1.9 */
69+
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
70+
LIT_MAGIC_STRING_MATH_UL,
71+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
72+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
73+
6774
/* Routine properties:
6875
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
6976
ROUTINE (LIT_MAGIC_STRING_ABS, ECMA_MATH_OBJECT_ABS, 1, 1)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
2828
1,
2929
ECMA_PROPERTY_FLAG_WRITABLE)
3030

31+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
32+
/* ECMA-262 v6, 25.4.5.4 */
33+
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
34+
LIT_MAGIC_STRING_PROMISE_UL,
35+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
36+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
37+
3138
ROUTINE (LIT_MAGIC_STRING_THEN, ecma_builtin_promise_prototype_then, 2, 2)
3239
ROUTINE (LIT_MAGIC_STRING_CATCH, ecma_builtin_promise_prototype_catch, 1, 1)
3340

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,28 @@ ecma_builtin_typedarray_prototype_length_getter (ecma_value_t this_arg) /**< thi
140140
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
141141
} /* ecma_builtin_typedarray_prototype_length_getter */
142142

143+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
144+
/**
145+
* The %TypedArray%.prototype[Symbol.toStringTag] accessor
146+
*
147+
* See also:
148+
* ES2015, 22.2.3.31
149+
*
150+
* @return ecma value
151+
* Returned value must be freed with ecma_free_value.
152+
*/
153+
static ecma_value_t
154+
ecma_builtin_typedarray_prototype_to_string_tag_getter (ecma_value_t this_arg) /**< this argument */
155+
{
156+
if (!ecma_is_typedarray (this_arg))
157+
{
158+
return ECMA_VALUE_UNDEFINED;
159+
}
160+
161+
return ecma_make_magic_string_value (ecma_object_get_class_name (ecma_get_object_from_value (this_arg)));
162+
} /* ecma_builtin_typedarray_prototype_to_string_tag_getter */
163+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
164+
143165
/**
144166
* Type of routine.
145167
*/

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_LENGTH,
4545
ecma_builtin_typedarray_prototype_length_getter,
4646
ECMA_PROPERTY_FIXED)
4747

48+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
49+
/* ECMA-262 v6, 23.1.3.13 */
50+
ACCESSOR_READ_ONLY (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
51+
ecma_builtin_typedarray_prototype_to_string_tag_getter,
52+
ECMA_PROPERTY_FLAG_CONFIGURABLE)
53+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
54+
4855
/* Routine properties:
4956
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
5057
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_typedarray_prototype_object_to_string, 0, 0)

jerry-core/ecma/operations/ecma-objects.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,30 @@ ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */
734734
return ecma_op_object_get (object_p, ecma_get_magic_string (property_id));
735735
} /* ecma_op_object_get_by_magic_id */
736736

737+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
738+
/**
739+
* [[Get]] operation of ecma object where the property is a well-known symbol
740+
*
741+
* @return ecma value
742+
* Returned value must be freed with ecma_free_value
743+
*/
744+
ecma_value_t
745+
ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, /**< the object */
746+
lit_magic_string_id_t property_id) /**< property symbol id */
747+
{
748+
ecma_value_t symbol_value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_SYMBOL),
749+
property_id);
750+
JERRY_ASSERT (ecma_is_value_symbol (symbol_value));
751+
752+
ecma_string_t *symbol_p = ecma_get_symbol_from_value (symbol_value);
753+
ecma_value_t ret_value = ecma_op_object_get (object_p, symbol_p);
754+
755+
ecma_deref_ecma_string (symbol_p);
756+
757+
return ret_value;
758+
} /* ecma_op_object_get_by_symbol_id */
759+
#endif /* !CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
760+
737761
/**
738762
* [[Put]] ecma general object's operation
739763
*

jerry-core/ecma/operations/ecma-objects.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *proper
3535
ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *object_p, ecma_string_t *property_name_p);
3636
ecma_value_t ecma_op_object_get (ecma_object_t *object_p, ecma_string_t *property_name_p);
3737
ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
38+
#ifndef CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN
39+
ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
40+
#endif /* CONFIG_DISABLE_ES2015_SYMBOL_BUILTIN */
3841
ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value,
3942
bool is_throw);
4043
ecma_value_t ecma_op_object_delete (ecma_object_t *obj_p, ecma_string_t *property_name_p, bool is_throw);

0 commit comments

Comments
 (0)