|
21 | 21 | #include "ecma-conversion.h" |
22 | 22 | #include "ecma-function-object.h" |
23 | 23 | #include "ecma-exceptions.h" |
| 24 | +#include "ecma-gc.h" |
24 | 25 | #include "ecma-helpers.h" |
| 26 | +#include "jmem.h" |
25 | 27 | #include "ecma-objects.h" |
26 | 28 | #include "ecma-try-catch-macro.h" |
27 | 29 | #include "lit-magic-strings.h" |
|
33 | 35 | * @{ |
34 | 36 | */ |
35 | 37 |
|
| 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 | + |
36 | 101 | /** |
37 | 102 | * Common implementation of the Object.prototype.toString routine |
38 | 103 | * |
@@ -75,7 +140,25 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg |
75 | 140 |
|
76 | 141 | type_string = ecma_object_get_class_name (obj_p); |
77 | 142 |
|
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); |
79 | 162 | } |
80 | 163 |
|
81 | 164 | ecma_string_t *ret_string_p; |
|
0 commit comments