1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "jcontext.h"
17425bb815Sopenharmony_ci#include "lit-magic-strings.h"
18425bb815Sopenharmony_ci#include "lit-strings.h"
19425bb815Sopenharmony_ci
20425bb815Sopenharmony_ci/**
21425bb815Sopenharmony_ci * Maximum number of external magic strings that can be registered.
22425bb815Sopenharmony_ci */
23425bb815Sopenharmony_ci#define LIT_EXTERNAL_MAGIC_STRING_LIMIT (UINT32_MAX / 2)
24425bb815Sopenharmony_ci
25425bb815Sopenharmony_ci/**
26425bb815Sopenharmony_ci * Get number of external magic strings
27425bb815Sopenharmony_ci *
28425bb815Sopenharmony_ci * @return number of the strings, if there were registered,
29425bb815Sopenharmony_ci *         zero - otherwise.
30425bb815Sopenharmony_ci */
31425bb815Sopenharmony_ciinline uint32_t JERRY_ATTR_ALWAYS_INLINE
32425bb815Sopenharmony_cilit_get_magic_string_ex_count (void)
33425bb815Sopenharmony_ci{
34425bb815Sopenharmony_ci  return JERRY_CONTEXT (lit_magic_string_ex_count);
35425bb815Sopenharmony_ci} /* lit_get_magic_string_ex_count */
36425bb815Sopenharmony_ci
37425bb815Sopenharmony_ci/**
38425bb815Sopenharmony_ci * Get specified magic string as zero-terminated string
39425bb815Sopenharmony_ci *
40425bb815Sopenharmony_ci * @return pointer to zero-terminated magic string
41425bb815Sopenharmony_ci */
42425bb815Sopenharmony_ciconst lit_utf8_byte_t *
43425bb815Sopenharmony_cilit_get_magic_string_utf8 (uint32_t id) /**< magic string id */
44425bb815Sopenharmony_ci{
45425bb815Sopenharmony_ci  static const lit_utf8_byte_t * const lit_magic_strings[] JERRY_ATTR_CONST_DATA =
46425bb815Sopenharmony_ci  {
47425bb815Sopenharmony_ci/** @cond doxygen_suppress */
48425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id)
49425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_DEF(id, utf8_string) \
50425bb815Sopenharmony_ci    (const lit_utf8_byte_t *) utf8_string,
51425bb815Sopenharmony_ci#include "lit-magic-strings.inc.h"
52425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_DEF
53425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
54425bb815Sopenharmony_ci/** @endcond */
55425bb815Sopenharmony_ci  };
56425bb815Sopenharmony_ci
57425bb815Sopenharmony_ci  JERRY_ASSERT (id < LIT_NON_INTERNAL_MAGIC_STRING__COUNT);
58425bb815Sopenharmony_ci
59425bb815Sopenharmony_ci  return lit_magic_strings[id];
60425bb815Sopenharmony_ci} /* lit_get_magic_string_utf8 */
61425bb815Sopenharmony_ci
62425bb815Sopenharmony_ci/**
63425bb815Sopenharmony_ci * Get size of specified magic string
64425bb815Sopenharmony_ci *
65425bb815Sopenharmony_ci * @return size in bytes
66425bb815Sopenharmony_ci */
67425bb815Sopenharmony_cilit_utf8_size_t
68425bb815Sopenharmony_cilit_get_magic_string_size (uint32_t id) /**< magic string id */
69425bb815Sopenharmony_ci{
70425bb815Sopenharmony_ci  static const lit_magic_size_t lit_magic_string_sizes[] JERRY_ATTR_CONST_DATA =
71425bb815Sopenharmony_ci  {
72425bb815Sopenharmony_ci/** @cond doxygen_suppress */
73425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id)
74425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_DEF(id, utf8_string) \
75425bb815Sopenharmony_ci    sizeof(utf8_string) - 1,
76425bb815Sopenharmony_ci#include "lit-magic-strings.inc.h"
77425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_DEF
78425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
79425bb815Sopenharmony_ci/** @endcond */
80425bb815Sopenharmony_ci  };
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  JERRY_ASSERT (id < LIT_NON_INTERNAL_MAGIC_STRING__COUNT);
83425bb815Sopenharmony_ci
84425bb815Sopenharmony_ci  return lit_magic_string_sizes[id];
85425bb815Sopenharmony_ci} /* lit_get_magic_string_size */
86425bb815Sopenharmony_ci
87425bb815Sopenharmony_ci/**
88425bb815Sopenharmony_ci * Get the block start element with the given size from
89425bb815Sopenharmony_ci * the list of ECMA and implementation-defined magic string constants
90425bb815Sopenharmony_ci *
91425bb815Sopenharmony_ci * @return magic string id
92425bb815Sopenharmony_ci */
93425bb815Sopenharmony_cistatic lit_magic_string_id_t
94425bb815Sopenharmony_cilit_get_magic_string_size_block_start (lit_utf8_size_t size) /**< magic string size */
95425bb815Sopenharmony_ci{
96425bb815Sopenharmony_ci  static const lit_magic_string_id_t lit_magic_string_size_block_starts[] JERRY_ATTR_CONST_DATA =
97425bb815Sopenharmony_ci  {
98425bb815Sopenharmony_ci/** @cond doxygen_suppress */
99425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_DEF(id, utf8_string)
100425bb815Sopenharmony_ci#define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id) \
101425bb815Sopenharmony_ci    id,
102425bb815Sopenharmony_ci#include "lit-magic-strings.inc.h"
103425bb815Sopenharmony_ci    LIT_NON_INTERNAL_MAGIC_STRING__COUNT
104425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_DEF
105425bb815Sopenharmony_ci#undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
106425bb815Sopenharmony_ci/** @endcond */
107425bb815Sopenharmony_ci  };
108425bb815Sopenharmony_ci
109425bb815Sopenharmony_ci  JERRY_ASSERT (size <= (sizeof (lit_magic_string_size_block_starts) / sizeof (lit_magic_string_id_t)));
110425bb815Sopenharmony_ci
111425bb815Sopenharmony_ci  return lit_magic_string_size_block_starts[size];
112425bb815Sopenharmony_ci} /* lit_get_magic_string_size_block_start */
113425bb815Sopenharmony_ci
114425bb815Sopenharmony_ci/**
115425bb815Sopenharmony_ci * Get specified magic string as zero-terminated string from external table
116425bb815Sopenharmony_ci *
117425bb815Sopenharmony_ci * @return pointer to zero-terminated magic string
118425bb815Sopenharmony_ci */
119425bb815Sopenharmony_ciconst lit_utf8_byte_t *
120425bb815Sopenharmony_cilit_get_magic_string_ex_utf8 (uint32_t id) /**< extern magic string id */
121425bb815Sopenharmony_ci{
122425bb815Sopenharmony_ci  JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_array) && id < JERRY_CONTEXT (lit_magic_string_ex_count));
123425bb815Sopenharmony_ci
124425bb815Sopenharmony_ci  return JERRY_CONTEXT (lit_magic_string_ex_array)[id];
125425bb815Sopenharmony_ci} /* lit_get_magic_string_ex_utf8 */
126425bb815Sopenharmony_ci
127425bb815Sopenharmony_ci/**
128425bb815Sopenharmony_ci * Get size of specified external magic string
129425bb815Sopenharmony_ci *
130425bb815Sopenharmony_ci * @return size in bytes
131425bb815Sopenharmony_ci */
132425bb815Sopenharmony_cilit_utf8_size_t
133425bb815Sopenharmony_cilit_get_magic_string_ex_size (uint32_t id) /**< external magic string id */
134425bb815Sopenharmony_ci{
135425bb815Sopenharmony_ci  return JERRY_CONTEXT (lit_magic_string_ex_sizes)[id];
136425bb815Sopenharmony_ci} /* lit_get_magic_string_ex_size */
137425bb815Sopenharmony_ci
138425bb815Sopenharmony_ci/**
139425bb815Sopenharmony_ci * Register external magic strings
140425bb815Sopenharmony_ci */
141425bb815Sopenharmony_civoid
142425bb815Sopenharmony_cilit_magic_strings_ex_set (const lit_utf8_byte_t * const *ex_str_items, /**< character arrays, representing
143425bb815Sopenharmony_ci                                                                        *   external magic strings' contents */
144425bb815Sopenharmony_ci                          uint32_t count,                       /**< number of the strings */
145425bb815Sopenharmony_ci                          const lit_utf8_size_t *ex_str_sizes)  /**< sizes of the strings */
146425bb815Sopenharmony_ci{
147425bb815Sopenharmony_ci  JERRY_ASSERT (ex_str_items != NULL);
148425bb815Sopenharmony_ci  JERRY_ASSERT (count > 0);
149425bb815Sopenharmony_ci  JERRY_ASSERT (ex_str_sizes != NULL);
150425bb815Sopenharmony_ci
151425bb815Sopenharmony_ci  JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_array) == NULL);
152425bb815Sopenharmony_ci  JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_count) == 0);
153425bb815Sopenharmony_ci  JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_sizes) == NULL);
154425bb815Sopenharmony_ci
155425bb815Sopenharmony_ci  /* Limit the number of external magic strings */
156425bb815Sopenharmony_ci  if (count > LIT_EXTERNAL_MAGIC_STRING_LIMIT)
157425bb815Sopenharmony_ci  {
158425bb815Sopenharmony_ci    count = LIT_EXTERNAL_MAGIC_STRING_LIMIT;
159425bb815Sopenharmony_ci  }
160425bb815Sopenharmony_ci
161425bb815Sopenharmony_ci  /* Set external magic strings information */
162425bb815Sopenharmony_ci  JERRY_CONTEXT (lit_magic_string_ex_array) = ex_str_items;
163425bb815Sopenharmony_ci  JERRY_CONTEXT (lit_magic_string_ex_count) = count;
164425bb815Sopenharmony_ci  JERRY_CONTEXT (lit_magic_string_ex_sizes) = ex_str_sizes;
165425bb815Sopenharmony_ci
166425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG
167425bb815Sopenharmony_ci  for (lit_magic_string_ex_id_t id = (lit_magic_string_ex_id_t) 0;
168425bb815Sopenharmony_ci       id < JERRY_CONTEXT (lit_magic_string_ex_count);
169425bb815Sopenharmony_ci       id = (lit_magic_string_ex_id_t) (id + 1))
170425bb815Sopenharmony_ci  {
171425bb815Sopenharmony_ci    lit_utf8_size_t string_size = JERRY_CONTEXT (lit_magic_string_ex_sizes)[id];
172425bb815Sopenharmony_ci
173425bb815Sopenharmony_ci    /**
174425bb815Sopenharmony_ci     * Check whether the strings are sorted by size and lexicographically,
175425bb815Sopenharmony_ci     * e.g., "Bb" < "aa" < "aaa" < "xyz0".
176425bb815Sopenharmony_ci     */
177425bb815Sopenharmony_ci    if (id > 0)
178425bb815Sopenharmony_ci    {
179425bb815Sopenharmony_ci      const lit_magic_string_ex_id_t prev_id = id - 1;
180425bb815Sopenharmony_ci      const lit_utf8_size_t prev_string_size = lit_get_magic_string_ex_size (prev_id);
181425bb815Sopenharmony_ci      JERRY_ASSERT (lit_is_valid_cesu8_string (lit_get_magic_string_ex_utf8 (id),
182425bb815Sopenharmony_ci                                               string_size));
183425bb815Sopenharmony_ci      JERRY_ASSERT (prev_string_size <= string_size);
184425bb815Sopenharmony_ci
185425bb815Sopenharmony_ci      if (prev_string_size == string_size)
186425bb815Sopenharmony_ci      {
187425bb815Sopenharmony_ci        const lit_utf8_byte_t *prev_ex_string_p = lit_get_magic_string_ex_utf8 (prev_id);
188425bb815Sopenharmony_ci        const lit_utf8_byte_t *curr_ex_string_p = lit_get_magic_string_ex_utf8 (id);
189425bb815Sopenharmony_ci        JERRY_ASSERT (memcmp (prev_ex_string_p, curr_ex_string_p, string_size) < 0);
190425bb815Sopenharmony_ci      }
191425bb815Sopenharmony_ci    }
192425bb815Sopenharmony_ci  }
193425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */
194425bb815Sopenharmony_ci} /* lit_magic_strings_ex_set */
195425bb815Sopenharmony_ci
196425bb815Sopenharmony_ci/**
197425bb815Sopenharmony_ci * Returns the magic string id of the argument string if it is available.
198425bb815Sopenharmony_ci *
199425bb815Sopenharmony_ci * @return id - if magic string id is found,
200425bb815Sopenharmony_ci *         LIT_MAGIC_STRING__COUNT - otherwise.
201425bb815Sopenharmony_ci */
202425bb815Sopenharmony_cilit_magic_string_id_t
203425bb815Sopenharmony_cilit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
204425bb815Sopenharmony_ci                          lit_utf8_size_t string_size) /**< string size in bytes */
205425bb815Sopenharmony_ci{
206425bb815Sopenharmony_ci  if (string_size > lit_get_magic_string_size (LIT_NON_INTERNAL_MAGIC_STRING__COUNT - 1))
207425bb815Sopenharmony_ci  {
208425bb815Sopenharmony_ci    return LIT_MAGIC_STRING__COUNT;
209425bb815Sopenharmony_ci  }
210425bb815Sopenharmony_ci
211425bb815Sopenharmony_ci  /**< The string must be in this id range. */
212425bb815Sopenharmony_ci  lit_utf8_size_t first = lit_get_magic_string_size_block_start (string_size);
213425bb815Sopenharmony_ci  lit_utf8_size_t last = lit_get_magic_string_size_block_start (string_size + 1);
214425bb815Sopenharmony_ci
215425bb815Sopenharmony_ci  while (first < last)
216425bb815Sopenharmony_ci  {
217425bb815Sopenharmony_ci    lit_utf8_size_t middle = ((first + last) / 2); /**< mid point of search */
218425bb815Sopenharmony_ci    int compare = memcmp (lit_get_magic_string_utf8 ((lit_magic_string_id_t) middle), string_p, string_size);
219425bb815Sopenharmony_ci
220425bb815Sopenharmony_ci    if (compare == 0)
221425bb815Sopenharmony_ci    {
222425bb815Sopenharmony_ci      return (lit_magic_string_id_t) middle;
223425bb815Sopenharmony_ci    }
224425bb815Sopenharmony_ci    else if (compare > 0)
225425bb815Sopenharmony_ci    {
226425bb815Sopenharmony_ci      last = middle;
227425bb815Sopenharmony_ci    }
228425bb815Sopenharmony_ci    else
229425bb815Sopenharmony_ci    {
230425bb815Sopenharmony_ci      first = middle + 1;
231425bb815Sopenharmony_ci    }
232425bb815Sopenharmony_ci  }
233425bb815Sopenharmony_ci
234425bb815Sopenharmony_ci  return LIT_MAGIC_STRING__COUNT;
235425bb815Sopenharmony_ci} /* lit_is_utf8_string_magic */
236425bb815Sopenharmony_ci
237425bb815Sopenharmony_ci/**
238425bb815Sopenharmony_ci * Returns the magic string id of the argument string pair if it is available.
239425bb815Sopenharmony_ci *
240425bb815Sopenharmony_ci * @return id - if magic string id is found,
241425bb815Sopenharmony_ci *         LIT_MAGIC_STRING__COUNT - otherwise.
242425bb815Sopenharmony_ci */
243425bb815Sopenharmony_cilit_magic_string_id_t
244425bb815Sopenharmony_cilit_is_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first utf-8 string */
245425bb815Sopenharmony_ci                               lit_utf8_size_t string1_size, /**< first string size in bytes */
246425bb815Sopenharmony_ci                               const lit_utf8_byte_t *string2_p, /**< second utf-8 string */
247425bb815Sopenharmony_ci                               lit_utf8_size_t string2_size) /**< second string size in bytes */
248425bb815Sopenharmony_ci{
249425bb815Sopenharmony_ci  lit_utf8_size_t total_string_size = string1_size + string2_size;
250425bb815Sopenharmony_ci
251425bb815Sopenharmony_ci  if (total_string_size > lit_get_magic_string_size (LIT_NON_INTERNAL_MAGIC_STRING__COUNT - 1))
252425bb815Sopenharmony_ci  {
253425bb815Sopenharmony_ci    return LIT_MAGIC_STRING__COUNT;
254425bb815Sopenharmony_ci  }
255425bb815Sopenharmony_ci
256425bb815Sopenharmony_ci  /**< The string must be in this id range. */
257425bb815Sopenharmony_ci  lit_utf8_size_t first = lit_get_magic_string_size_block_start (total_string_size);
258425bb815Sopenharmony_ci  lit_utf8_size_t last = lit_get_magic_string_size_block_start (total_string_size + 1);
259425bb815Sopenharmony_ci
260425bb815Sopenharmony_ci  while (first < last)
261425bb815Sopenharmony_ci  {
262425bb815Sopenharmony_ci    lit_utf8_size_t middle = ((first + last) / 2); /**< mid point of search */
263425bb815Sopenharmony_ci    const lit_utf8_byte_t *middle_string_p = lit_get_magic_string_utf8 ((lit_magic_string_id_t) middle);
264425bb815Sopenharmony_ci
265425bb815Sopenharmony_ci    int compare = memcmp (middle_string_p, string1_p, string1_size);
266425bb815Sopenharmony_ci
267425bb815Sopenharmony_ci    if (compare == 0)
268425bb815Sopenharmony_ci    {
269425bb815Sopenharmony_ci      compare = memcmp (middle_string_p + string1_size, string2_p, string2_size);
270425bb815Sopenharmony_ci    }
271425bb815Sopenharmony_ci
272425bb815Sopenharmony_ci    if (compare == 0)
273425bb815Sopenharmony_ci    {
274425bb815Sopenharmony_ci      return (lit_magic_string_id_t) middle;
275425bb815Sopenharmony_ci    }
276425bb815Sopenharmony_ci    else if (compare > 0)
277425bb815Sopenharmony_ci    {
278425bb815Sopenharmony_ci      last = middle;
279425bb815Sopenharmony_ci    }
280425bb815Sopenharmony_ci    else
281425bb815Sopenharmony_ci    {
282425bb815Sopenharmony_ci      first = middle + 1;
283425bb815Sopenharmony_ci    }
284425bb815Sopenharmony_ci  }
285425bb815Sopenharmony_ci
286425bb815Sopenharmony_ci  return LIT_MAGIC_STRING__COUNT;
287425bb815Sopenharmony_ci} /* lit_is_utf8_string_pair_magic */
288425bb815Sopenharmony_ci
289425bb815Sopenharmony_ci/**
290425bb815Sopenharmony_ci * Returns the ex magic string id of the argument string if it is available.
291425bb815Sopenharmony_ci *
292425bb815Sopenharmony_ci * @return id - if magic string id is found,
293425bb815Sopenharmony_ci *         lit_get_magic_string_ex_count () - otherwise.
294425bb815Sopenharmony_ci */
295425bb815Sopenharmony_cilit_magic_string_ex_id_t
296425bb815Sopenharmony_cilit_is_ex_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
297425bb815Sopenharmony_ci                             lit_utf8_size_t string_size) /**< string size in bytes */
298425bb815Sopenharmony_ci{
299425bb815Sopenharmony_ci  const uint32_t magic_string_ex_count = lit_get_magic_string_ex_count ();
300425bb815Sopenharmony_ci
301425bb815Sopenharmony_ci  if (magic_string_ex_count == 0
302425bb815Sopenharmony_ci      || string_size > lit_get_magic_string_ex_size (magic_string_ex_count - 1))
303425bb815Sopenharmony_ci  {
304425bb815Sopenharmony_ci    return (lit_magic_string_ex_id_t) magic_string_ex_count;
305425bb815Sopenharmony_ci  }
306425bb815Sopenharmony_ci
307425bb815Sopenharmony_ci  lit_magic_string_ex_id_t first = 0;
308425bb815Sopenharmony_ci  lit_magic_string_ex_id_t last = (lit_magic_string_ex_id_t) magic_string_ex_count;
309425bb815Sopenharmony_ci
310425bb815Sopenharmony_ci  while (first < last)
311425bb815Sopenharmony_ci  {
312425bb815Sopenharmony_ci    const lit_magic_string_ex_id_t middle = (first + last) / 2;
313425bb815Sopenharmony_ci    const lit_utf8_byte_t *ext_string_p = lit_get_magic_string_ex_utf8 (middle);
314425bb815Sopenharmony_ci    const lit_utf8_size_t ext_string_size = lit_get_magic_string_ex_size (middle);
315425bb815Sopenharmony_ci
316425bb815Sopenharmony_ci    if (string_size == ext_string_size)
317425bb815Sopenharmony_ci    {
318425bb815Sopenharmony_ci      const int string_compare = memcmp (ext_string_p, string_p, string_size);
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci      if (string_compare == 0)
321425bb815Sopenharmony_ci      {
322425bb815Sopenharmony_ci        return middle;
323425bb815Sopenharmony_ci      }
324425bb815Sopenharmony_ci      else if (string_compare < 0)
325425bb815Sopenharmony_ci      {
326425bb815Sopenharmony_ci        first = middle + 1;
327425bb815Sopenharmony_ci      }
328425bb815Sopenharmony_ci      else
329425bb815Sopenharmony_ci      {
330425bb815Sopenharmony_ci        last = middle;
331425bb815Sopenharmony_ci      }
332425bb815Sopenharmony_ci    }
333425bb815Sopenharmony_ci    else if (string_size > ext_string_size)
334425bb815Sopenharmony_ci    {
335425bb815Sopenharmony_ci      first = middle + 1;
336425bb815Sopenharmony_ci    }
337425bb815Sopenharmony_ci    else
338425bb815Sopenharmony_ci    {
339425bb815Sopenharmony_ci      last = middle;
340425bb815Sopenharmony_ci    }
341425bb815Sopenharmony_ci  }
342425bb815Sopenharmony_ci
343425bb815Sopenharmony_ci  return (lit_magic_string_ex_id_t) magic_string_ex_count;
344425bb815Sopenharmony_ci} /* lit_is_ex_utf8_string_magic */
345425bb815Sopenharmony_ci
346425bb815Sopenharmony_ci/**
347425bb815Sopenharmony_ci * Returns the ex magic string id of the argument string pair if it is available.
348425bb815Sopenharmony_ci *
349425bb815Sopenharmony_ci * @return id - if magic string id is found,
350425bb815Sopenharmony_ci *         lit_get_magic_string_ex_count () - otherwise.
351425bb815Sopenharmony_ci */
352425bb815Sopenharmony_cilit_magic_string_ex_id_t
353425bb815Sopenharmony_cilit_is_ex_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first utf-8 string */
354425bb815Sopenharmony_ci                                  lit_utf8_size_t string1_size, /**< first string size in bytes */
355425bb815Sopenharmony_ci                                  const lit_utf8_byte_t *string2_p, /**< second utf-8 string */
356425bb815Sopenharmony_ci                                  lit_utf8_size_t string2_size) /**< second string size in bytes */
357425bb815Sopenharmony_ci{
358425bb815Sopenharmony_ci  const uint32_t magic_string_ex_count = lit_get_magic_string_ex_count ();
359425bb815Sopenharmony_ci  const lit_utf8_size_t total_string_size = string1_size + string2_size;
360425bb815Sopenharmony_ci
361425bb815Sopenharmony_ci  if (magic_string_ex_count == 0
362425bb815Sopenharmony_ci      || total_string_size > lit_get_magic_string_ex_size (magic_string_ex_count - 1))
363425bb815Sopenharmony_ci  {
364425bb815Sopenharmony_ci    return (lit_magic_string_ex_id_t) magic_string_ex_count;
365425bb815Sopenharmony_ci  }
366425bb815Sopenharmony_ci
367425bb815Sopenharmony_ci  lit_magic_string_ex_id_t first = 0;
368425bb815Sopenharmony_ci  lit_magic_string_ex_id_t last = (lit_magic_string_ex_id_t) magic_string_ex_count;
369425bb815Sopenharmony_ci
370425bb815Sopenharmony_ci  while (first < last)
371425bb815Sopenharmony_ci  {
372425bb815Sopenharmony_ci    const lit_magic_string_ex_id_t middle = (first + last) / 2;
373425bb815Sopenharmony_ci    const lit_utf8_byte_t *ext_string_p = lit_get_magic_string_ex_utf8 (middle);
374425bb815Sopenharmony_ci    const lit_utf8_size_t ext_string_size = lit_get_magic_string_ex_size (middle);
375425bb815Sopenharmony_ci
376425bb815Sopenharmony_ci    if (total_string_size == ext_string_size)
377425bb815Sopenharmony_ci    {
378425bb815Sopenharmony_ci      int string_compare = memcmp (ext_string_p, string1_p, string1_size);
379425bb815Sopenharmony_ci
380425bb815Sopenharmony_ci      if (string_compare == 0)
381425bb815Sopenharmony_ci      {
382425bb815Sopenharmony_ci        string_compare = memcmp (ext_string_p + string1_size, string2_p, string2_size);
383425bb815Sopenharmony_ci      }
384425bb815Sopenharmony_ci
385425bb815Sopenharmony_ci      if (string_compare == 0)
386425bb815Sopenharmony_ci      {
387425bb815Sopenharmony_ci        return middle;
388425bb815Sopenharmony_ci      }
389425bb815Sopenharmony_ci      else if (string_compare < 0)
390425bb815Sopenharmony_ci      {
391425bb815Sopenharmony_ci        first = middle + 1;
392425bb815Sopenharmony_ci      }
393425bb815Sopenharmony_ci      else
394425bb815Sopenharmony_ci      {
395425bb815Sopenharmony_ci        last = middle;
396425bb815Sopenharmony_ci      }
397425bb815Sopenharmony_ci    }
398425bb815Sopenharmony_ci    else if (total_string_size > ext_string_size)
399425bb815Sopenharmony_ci    {
400425bb815Sopenharmony_ci      first = middle + 1;
401425bb815Sopenharmony_ci    }
402425bb815Sopenharmony_ci    else
403425bb815Sopenharmony_ci    {
404425bb815Sopenharmony_ci      last = middle;
405425bb815Sopenharmony_ci    }
406425bb815Sopenharmony_ci  }
407425bb815Sopenharmony_ci
408425bb815Sopenharmony_ci  return (lit_magic_string_ex_id_t) magic_string_ex_count;
409425bb815Sopenharmony_ci} /* lit_is_ex_utf8_string_pair_magic */
410425bb815Sopenharmony_ci
411425bb815Sopenharmony_ci/**
412425bb815Sopenharmony_ci * Copy magic string to buffer
413425bb815Sopenharmony_ci *
414425bb815Sopenharmony_ci * Warning:
415425bb815Sopenharmony_ci *         the routine requires that buffer size is enough
416425bb815Sopenharmony_ci *
417425bb815Sopenharmony_ci * @return pointer to the byte next to the last copied in the buffer
418425bb815Sopenharmony_ci */
419425bb815Sopenharmony_cilit_utf8_byte_t *
420425bb815Sopenharmony_cilit_copy_magic_string_to_buffer (lit_magic_string_id_t id, /**< magic string id */
421425bb815Sopenharmony_ci                                 lit_utf8_byte_t *buffer_p, /**< destination buffer */
422425bb815Sopenharmony_ci                                 lit_utf8_size_t buffer_size) /**< size of buffer */
423425bb815Sopenharmony_ci{
424425bb815Sopenharmony_ci  const lit_utf8_byte_t *magic_string_bytes_p = lit_get_magic_string_utf8 (id);
425425bb815Sopenharmony_ci  lit_utf8_size_t magic_string_bytes_count = lit_get_magic_string_size (id);
426425bb815Sopenharmony_ci
427425bb815Sopenharmony_ci  const lit_utf8_byte_t *str_iter_p = magic_string_bytes_p;
428425bb815Sopenharmony_ci  lit_utf8_byte_t *buf_iter_p = buffer_p;
429425bb815Sopenharmony_ci  lit_utf8_size_t bytes_copied = 0;
430425bb815Sopenharmony_ci
431425bb815Sopenharmony_ci  while (magic_string_bytes_count--)
432425bb815Sopenharmony_ci  {
433425bb815Sopenharmony_ci    bytes_copied ++;
434425bb815Sopenharmony_ci    JERRY_ASSERT (bytes_copied <= buffer_size);
435425bb815Sopenharmony_ci
436425bb815Sopenharmony_ci    *buf_iter_p++ = *str_iter_p++;
437425bb815Sopenharmony_ci  }
438425bb815Sopenharmony_ci
439425bb815Sopenharmony_ci  return buf_iter_p;
440425bb815Sopenharmony_ci} /* lit_copy_magic_string_to_buffer */
441