• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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