1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "js-parser-tagged-template-literal.h"
17 #include "js-lexer.h"
18 #include "ecma-array-object.h"
19 #include "ecma-builtin-helpers.h"
20 #include "ecma-gc.h"
21 #include "ecma-helpers.h"
22 #include "ecma-objects.h"
23
24 /* \addtogroup parser Parser
25 * @{
26 *
27 * \addtogroup jsparser JavaScript
28 * @{
29 *
30 * \addtogroup jsparser_tagged_template_literal Tagged template literal
31 * @{
32 */
33
34 #if ENABLED (JERRY_ES2015)
35 /**
36 * Append the cooked and raw string to the corresponding array
37 */
38 void
parser_tagged_template_literal_append_strings(parser_context_t * context_p,ecma_object_t * template_obj_p,ecma_object_t * raw_strings_p,uint32_t prop_idx)39 parser_tagged_template_literal_append_strings (parser_context_t *context_p, /**< parser context */
40 ecma_object_t *template_obj_p, /**< template object */
41 ecma_object_t *raw_strings_p, /**< raw strings object */
42 uint32_t prop_idx) /**< property index to set the values */
43 {
44 lexer_lit_location_t *lit_loc_p = &context_p->token.lit_location;
45
46 if (lit_loc_p->length == 0 && !lit_loc_p->has_escape)
47 {
48 ecma_builtin_helper_def_prop_by_index (template_obj_p,
49 prop_idx,
50 ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY),
51 ECMA_PROPERTY_FLAG_ENUMERABLE);
52
53 ecma_builtin_helper_def_prop_by_index (raw_strings_p,
54 prop_idx,
55 ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY),
56 ECMA_PROPERTY_FLAG_ENUMERABLE);
57 return;
58 }
59
60 uint8_t local_byte_array[LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE];
61 const uint8_t *source_p = lexer_convert_literal_to_chars (context_p,
62 &context_p->token.lit_location,
63 local_byte_array,
64 LEXER_STRING_NO_OPTS);
65
66 ecma_string_t *raw_str_p;
67 ecma_string_t *cooked_str_p = ecma_new_ecma_string_from_utf8 (source_p, lit_loc_p->length);
68 parser_free_allocated_buffer (context_p);
69
70 if (lit_loc_p->has_escape)
71 {
72 context_p->source_p = context_p->token.lit_location.char_p - 1;
73 lexer_parse_string (context_p, LEXER_STRING_RAW);
74 source_p = lexer_convert_literal_to_chars (context_p,
75 &context_p->token.lit_location,
76 local_byte_array,
77 LEXER_STRING_RAW);
78
79 raw_str_p = ecma_new_ecma_string_from_utf8 (source_p, lit_loc_p->length);
80 parser_free_allocated_buffer (context_p);
81 }
82 else
83 {
84 ecma_ref_ecma_string (cooked_str_p);
85 raw_str_p = cooked_str_p;
86 }
87
88 ecma_builtin_helper_def_prop_by_index (template_obj_p,
89 prop_idx,
90 ecma_make_string_value (cooked_str_p),
91 ECMA_PROPERTY_FLAG_ENUMERABLE);
92
93 ecma_builtin_helper_def_prop_by_index (raw_strings_p,
94 prop_idx,
95 ecma_make_string_value (raw_str_p),
96 ECMA_PROPERTY_FLAG_ENUMERABLE);
97
98 ecma_deref_ecma_string (cooked_str_p);
99 ecma_deref_ecma_string (raw_str_p);
100 } /* parser_tagged_template_literal_append_strings */
101
102 /**
103 * Create new tagged template literal object
104 *
105 * @return pointer to the allocated object
106 */
107 ecma_object_t *
parser_new_tagged_template_literal(ecma_object_t ** raw_strings_p)108 parser_new_tagged_template_literal (ecma_object_t **raw_strings_p) /**< [out] raw strings object */
109 {
110 ecma_object_t *template_obj_p = ecma_op_new_array_object (0);
111 *raw_strings_p = ecma_op_new_array_object (0);
112
113 ecma_builtin_helper_def_prop (template_obj_p,
114 ecma_get_magic_string (LIT_MAGIC_STRING_RAW),
115 ecma_make_object_value (*raw_strings_p),
116 ECMA_PROPERTY_FIXED);
117 ecma_deref_object (*raw_strings_p);
118
119 return template_obj_p;
120 } /* parser_new_tagged_template_literal */
121
122 /**
123 * Set integrity level of the given template array object to "frozen"
124 */
125 static void
parser_tagged_template_literal_freeze_array(ecma_object_t * obj_p)126 parser_tagged_template_literal_freeze_array (ecma_object_t *obj_p)
127 {
128 JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
129
130 ecma_op_ordinary_object_prevent_extensions (obj_p);
131 ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
132 uint8_t new_prop_value = (uint8_t) (ext_obj_p->u.array.u.length_prop & ~ECMA_PROPERTY_FLAG_WRITABLE);
133 ext_obj_p->u.array.u.length_prop = new_prop_value;
134 } /* parser_tagged_template_literal_freeze_array */
135
136 /**
137 * Finalize the tagged template object
138 */
139 void
parser_tagged_template_literal_finalize(ecma_object_t * template_obj_p,ecma_object_t * raw_strings_p)140 parser_tagged_template_literal_finalize (ecma_object_t *template_obj_p, /**< template object */
141 ecma_object_t *raw_strings_p) /**< raw strings object */
142 {
143 parser_tagged_template_literal_freeze_array (template_obj_p);
144 parser_tagged_template_literal_freeze_array (raw_strings_p);
145 } /* parser_tagged_template_literal_finalize */
146 #endif /* ENABLED (JERRY_ES2015) */
147
148 /**
149 * @}
150 * @}
151 * @}
152 */
153