• 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 <stdio.h>
17 
18 #include "debugger.h"
19 #include "ecma-alloc.h"
20 #include "ecma-array-object.h"
21 #include "ecma-arraybuffer-object.h"
22 #include "ecma-builtin-helpers.h"
23 #include "ecma-builtins.h"
24 #include "ecma-comparison.h"
25 #include "ecma-container-object.h"
26 #include "ecma-dataview-object.h"
27 #include "ecma-exceptions.h"
28 #include "ecma-eval.h"
29 #include "ecma-function-object.h"
30 #include "ecma-gc.h"
31 #include "ecma-helpers.h"
32 #include "ecma-init-finalize.h"
33 #include "ecma-lex-env.h"
34 #include "lit-char-helpers.h"
35 #include "ecma-literal-storage.h"
36 #include "ecma-objects.h"
37 #include "ecma-objects-general.h"
38 #include "ecma-regexp-object.h"
39 #include "ecma-promise-object.h"
40 #include "ecma-proxy-object.h"
41 #include "ecma-symbol-object.h"
42 #include "ecma-typedarray-object.h"
43 #include "opcodes.h"
44 #include "jcontext.h"
45 #include "jerryscript.h"
46 #include "jerryscript-debugger-transport.h"
47 #include "jmem.h"
48 #include "js-parser.h"
49 #include "re-compiler.h"
50 
51 #ifdef JERRY_FOR_IAR_CONFIG
52 
53 #include "config-gt.h"
54 
55 #endif
56 
57 #if defined(JERRY_REF_TRACKER)
58 #include "tracker.h"
59 #endif
60 
61 #if defined(JERRY_HEAPDUMP)
62 #include "heapdump.h"
63 #endif
64 
65 JERRY_STATIC_ASSERT (sizeof (jerry_value_t) == sizeof (ecma_value_t),
66                      size_of_jerry_value_t_must_be_equal_to_size_of_ecma_value_t);
67 
68 JERRY_STATIC_ASSERT ((int) ECMA_ERROR_NONE == (int) JERRY_ERROR_NONE
69                      && (int) ECMA_ERROR_COMMON == (int) JERRY_ERROR_COMMON
70                      && (int) ECMA_ERROR_EVAL == (int) JERRY_ERROR_EVAL
71                      && (int) ECMA_ERROR_RANGE == (int) JERRY_ERROR_RANGE
72                      && (int) ECMA_ERROR_REFERENCE == (int) JERRY_ERROR_REFERENCE
73                      && (int) ECMA_ERROR_SYNTAX == (int) JERRY_ERROR_SYNTAX
74                      && (int) ECMA_ERROR_TYPE == (int) JERRY_ERROR_TYPE
75                      && (int) ECMA_ERROR_URI == (int) JERRY_ERROR_URI,
76                      ecma_standard_error_t_must_be_equal_to_jerry_error_t);
77 
78 JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY
79                      && (int) ECMA_INIT_SHOW_OPCODES == (int) JERRY_INIT_SHOW_OPCODES
80                      && (int) ECMA_INIT_SHOW_REGEXP_OPCODES == (int) JERRY_INIT_SHOW_REGEXP_OPCODES
81                      && (int) ECMA_INIT_MEM_STATS == (int) JERRY_INIT_MEM_STATS,
82                      ecma_init_flag_t_must_be_equal_to_jerry_init_flag_t);
83 
84 #if ENABLED (JERRY_BUILTIN_REGEXP)
85 JERRY_STATIC_ASSERT ((int) RE_FLAG_GLOBAL == (int) JERRY_REGEXP_FLAG_GLOBAL
86                      && (int) RE_FLAG_MULTILINE == (int) JERRY_REGEXP_FLAG_MULTILINE
87                      && (int) RE_FLAG_IGNORE_CASE == (int) JERRY_REGEXP_FLAG_IGNORE_CASE,
88                      re_flags_t_must_be_equal_to_jerry_regexp_flags_t);
89 #endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
90 
91 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
92 /* The internal ECMA_PROMISE_STATE_* values are "one byte away" from the API values */
93 JERRY_STATIC_ASSERT ((int) ECMA_PROMISE_IS_PENDING == (int) JERRY_PROMISE_STATE_PENDING
94                      && (int) ECMA_PROMISE_IS_FULFILLED == (int) JERRY_PROMISE_STATE_FULFILLED,
95                      promise_internal_state_matches_external);
96 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
97 
98 /**
99  * Offset between internal and external arithmetic operator types
100  */
101 #define ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET (JERRY_BIN_OP_SUB - NUMBER_ARITHMETIC_SUBTRACTION)
102 
103 JERRY_STATIC_ASSERT (((NUMBER_ARITHMETIC_SUBTRACTION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_SUB)
104                      && ((NUMBER_ARITHMETIC_MULTIPLICATION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_MUL)
105                      && ((NUMBER_ARITHMETIC_DIVISION + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_DIV)
106                      && ((NUMBER_ARITHMETIC_REMAINDER + ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET) == JERRY_BIN_OP_REM),
107                      number_arithmetics_operation_type_matches_external);
108 
109 #if !ENABLED (JERRY_PARSER) && !ENABLED (JERRY_SNAPSHOT_EXEC)
110 #error "JERRY_SNAPSHOT_EXEC must be enabled if JERRY_PARSER is disabled!"
111 #endif /* !ENABLED (JERRY_PARSER) && !ENABLED (JERRY_SNAPSHOT_EXEC) */
112 
113 #if ENABLED (JERRY_ERROR_MESSAGES)
114 
115 /**
116  * Error message, if an argument is has an error flag
117  */
118 static const char * const error_value_msg_p = "argument cannot have an error flag";
119 
120 /**
121  * Error message, if types of arguments are incorrect
122  */
123 static const char * const wrong_args_msg_p = "wrong type of argument";
124 
125 #endif /* ENABLED (JERRY_ERROR_MESSAGES) */
126 
127 /** \addtogroup jerry Jerry engine interface
128  * @{
129  */
130 
131 /**
132  * Assert that it is correct to call API in current state.
133  *
134  * Note:
135  *         By convention, there are some states when API could not be invoked.
136  *
137  *         The API can be and only be invoked when the ECMA_STATUS_API_AVAILABLE
138  *         flag is set.
139  *
140  *         This procedure checks whether the API is available, and terminates
141  *         the engine if it is unavailable. Otherwise it is a no-op.
142  *
143  * Note:
144  *         The API could not be invoked in the following cases:
145  *           - before jerry_init and after jerry_cleanup
146  *           - between enter to and return from a native free callback
147  */
148 static inline void JERRY_ATTR_ALWAYS_INLINE
jerry_assert_api_available(void)149 jerry_assert_api_available (void)
150 {
151   JERRY_ASSERT (JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE);
152 } /* jerry_assert_api_available */
153 
154 /**
155  * Turn on API availability
156  */
157 static inline void JERRY_ATTR_ALWAYS_INLINE
jerry_make_api_available(void)158 jerry_make_api_available (void)
159 {
160   JERRY_CONTEXT (status_flags) |= ECMA_STATUS_API_AVAILABLE;
161 } /* jerry_make_api_available */
162 
163 /**
164  * Turn off API availability
165  */
166 static inline void JERRY_ATTR_ALWAYS_INLINE
jerry_make_api_unavailable(void)167 jerry_make_api_unavailable (void)
168 {
169   JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_API_AVAILABLE;
170 } /* jerry_make_api_unavailable */
171 
172 /**
173  * Create an API compatible return value.
174  *
175  * @return return value for Jerry API functions
176  */
177 static jerry_value_t
jerry_return(jerry_value_t value)178 jerry_return (jerry_value_t value) /**< return value */
179 {
180   if (ECMA_IS_VALUE_ERROR (value))
181   {
182     value = ecma_create_error_reference_from_context ();
183   }
184 
185   return value;
186 } /* jerry_return */
187 
188 /**
189  * Throw an API compatible return value.
190  *
191  * @return return value for Jerry API functions
192  */
193 static inline jerry_value_t JERRY_ATTR_ALWAYS_INLINE
jerry_throw(jerry_value_t value)194 jerry_throw (jerry_value_t value) /**< return value */
195 {
196   JERRY_ASSERT (ECMA_IS_VALUE_ERROR (value));
197   return ecma_create_error_reference_from_context ();
198 } /* jerry_throw */
199 
200 #ifdef JERRY_FOR_IAR_CONFIG
jerry_vla_malloc(uint32_t size)201 char* jerry_vla_malloc (uint32_t size)
202 {
203   char* ret;
204   ret = OhosMalloc (MEM_TYPE_JERRY, size);
205   if (!ret)
206   {
207     return NULL;
208   }
209   return ret;
210 }
211 
jerry_vla_free(char * p)212 void jerry_vla_free (char* p)
213 {
214   OhosFree (p);
215 }
216 #endif
217 
218 /**
219  * Jerry engine initialization
220  */
221 void
jerry_init(jerry_init_flag_t flags)222 jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */
223 {
224 #if defined(JERRY_REF_TRACKER)
225   InitTracker();
226 #endif
227   /* This function cannot be called twice unless jerry_cleanup is called. */
228   JERRY_ASSERT (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE));
229 
230   /* Zero out all non-external members. */
231   memset ((char *) &JERRY_CONTEXT_STRUCT + offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER), 0,
232           sizeof (jerry_context_t) - offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER));
233 
234   JERRY_CONTEXT (jerry_init_flags) = flags;
235 
236   jerry_make_api_available ();
237 
238   jmem_init ();
239   ecma_init ();
240 } /* jerry_init */
241 
242 /**
243  * Terminate Jerry engine
244  */
245 void
jerry_cleanup(void)246 jerry_cleanup (void)
247 {
248   ecma_gc_run();
249 
250   jerry_assert_api_available ();
251 
252 #if ENABLED (JERRY_DEBUGGER)
253   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
254   {
255     jerry_debugger_send_type (JERRY_DEBUGGER_CLOSE_CONNECTION);
256 
257     jerry_debugger_transport_close ();
258   }
259 #endif /* ENABLED (JERRY_DEBUGGER) */
260 
261   for (jerry_context_data_header_t *this_p = JERRY_CONTEXT (context_data_p);
262        this_p != NULL;
263        this_p = this_p->next_p)
264   {
265     if (this_p->manager_p->deinit_cb)
266     {
267       void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL;
268       this_p->manager_p->deinit_cb (data);
269     }
270   }
271 
272 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
273   ecma_free_all_enqueued_jobs ();
274 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
275   ecma_finalize ();
276   jerry_make_api_unavailable ();
277 
278   for (jerry_context_data_header_t *this_p = JERRY_CONTEXT (context_data_p), *next_p = NULL;
279        this_p != NULL;
280        this_p = next_p)
281   {
282     next_p = this_p->next_p;
283     if (this_p->manager_p->finalize_cb)
284     {
285       void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL;
286       this_p->manager_p->finalize_cb (data);
287     }
288     jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed);
289   }
290 
291   jmem_finalize ();
292 } /* jerry_cleanup */
293 
294 /**
295  * Retrieve a context data item, or create a new one.
296  *
297  * @param manager_p pointer to the manager whose context data item should be returned.
298  *
299  * @return a pointer to the user-provided context-specific data item for the given manager, creating such a pointer if
300  * none was found.
301  */
302 void *
jerry_get_context_data(const jerry_context_data_manager_t * manager_p)303 jerry_get_context_data (const jerry_context_data_manager_t *manager_p)
304 {
305   void *ret = NULL;
306   jerry_context_data_header_t *item_p;
307 
308   for (item_p = JERRY_CONTEXT (context_data_p); item_p != NULL; item_p = item_p->next_p)
309   {
310     if (item_p->manager_p == manager_p)
311     {
312       return (manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p) : NULL;
313     }
314   }
315 
316   item_p = jmem_heap_alloc_block (sizeof (jerry_context_data_header_t) + manager_p->bytes_needed);
317   item_p->manager_p = manager_p;
318   item_p->next_p = JERRY_CONTEXT (context_data_p);
319   JERRY_CONTEXT (context_data_p) = item_p;
320 
321   if (manager_p->bytes_needed > 0)
322   {
323     ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p);
324     memset (ret, 0, manager_p->bytes_needed);
325   }
326 
327   if (manager_p->init_cb)
328   {
329     manager_p->init_cb (ret);
330   }
331 
332   return ret;
333 } /* jerry_get_context_data */
334 
335 /**
336  * Register external magic string array
337  */
338 void
jerry_register_magic_strings(const jerry_char_t * const * ex_str_items_p,uint32_t count,const jerry_length_t * str_lengths_p)339 jerry_register_magic_strings (const jerry_char_t * const *ex_str_items_p, /**< character arrays, representing
340                                                                            *   external magic strings' contents */
341                               uint32_t count, /**< number of the strings */
342                               const jerry_length_t *str_lengths_p) /**< lengths of all strings */
343 {
344   jerry_assert_api_available ();
345 
346   lit_magic_strings_ex_set ((const lit_utf8_byte_t * const *) ex_str_items_p,
347                             count,
348                             (const lit_utf8_size_t *) str_lengths_p);
349 } /* jerry_register_magic_strings */
350 
351 /**
352  * Run garbage collection
353  */
354 void
jerry_gc(jerry_gc_mode_t mode)355 jerry_gc (jerry_gc_mode_t mode) /**< operational mode */
356 {
357   jerry_assert_api_available ();
358 
359   if (mode == JERRY_GC_PRESSURE_LOW)
360   {
361     /* Call GC directly, because 'ecma_free_unused_memory' might decide it's not yet worth it. */
362     ecma_gc_run ();
363     return;
364   }
365 
366   ecma_free_unused_memory (JMEM_PRESSURE_HIGH);
367 } /* jerry_gc */
368 
369 /**
370  * Get heap memory stats.
371  *
372  * @return true - get the heap stats successful
373  *         false - otherwise. Usually it is because the MEM_STATS feature is not enabled.
374  */
375 bool
jerry_get_memory_stats(jerry_heap_stats_t * out_stats_p)376 jerry_get_memory_stats (jerry_heap_stats_t *out_stats_p) /**< [out] heap memory stats */
377 {
378 #if ENABLED (JERRY_MEM_STATS)
379   if (out_stats_p == NULL)
380   {
381     return false;
382   }
383 
384   jmem_heap_stats_t jmem_heap_stats;
385   memset (&jmem_heap_stats, 0, sizeof (jmem_heap_stats));
386   jmem_heap_get_stats (&jmem_heap_stats);
387 
388   *out_stats_p = (jerry_heap_stats_t)
389   {
390     .version = 1,
391     .size = jmem_heap_stats.size,
392     .allocated_bytes = jmem_heap_stats.allocated_bytes,
393     .peak_allocated_bytes = jmem_heap_stats.peak_allocated_bytes
394   };
395 
396   return true;
397 #else /* !ENABLED (JERRY_MEM_STATS) */
398   JERRY_UNUSED (out_stats_p);
399   return false;
400 #endif /* ENABLED (JERRY_MEM_STATS) */
401 } /* jerry_get_memory_stats */
402 
403 /**
404  * Simple Jerry runner
405  *
406  * @return true  - if run was successful
407  *         false - otherwise
408  */
409 bool
jerry_run_simple(const jerry_char_t * script_source_p,size_t script_source_size,jerry_init_flag_t flags)410 jerry_run_simple (const jerry_char_t *script_source_p, /**< script source */
411                   size_t script_source_size, /**< script source size */
412                   jerry_init_flag_t flags) /**< combination of Jerry flags */
413 {
414   bool result = false;
415 
416   jerry_init (flags);
417 
418   jerry_value_t parse_ret_val = jerry_parse (NULL, 0, script_source_p, script_source_size, JERRY_PARSE_NO_OPTS);
419 
420   if (!ecma_is_value_error_reference (parse_ret_val))
421   {
422     jerry_value_t run_ret_val = jerry_run (parse_ret_val);
423 
424     if (!ecma_is_value_error_reference (run_ret_val))
425     {
426       result = true;
427     }
428 
429     jerry_release_value (run_ret_val);
430   }
431 
432   jerry_release_value (parse_ret_val);
433   jerry_cleanup ();
434 
435   return result;
436 } /* jerry_run_simple */
437 
438 /**
439  * Parse script and construct an EcmaScript function. The lexical
440  * environment is set to the global lexical environment.
441  *
442  * @return function object value - if script was parsed successfully,
443  *         thrown error - otherwise
444  */
445 jerry_value_t
jerry_parse(const jerry_char_t * resource_name_p,size_t resource_name_length,const jerry_char_t * source_p,size_t source_size,uint32_t parse_opts)446 jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */
447              size_t resource_name_length, /**< length of resource name */
448              const jerry_char_t *source_p, /**< script source */
449              size_t source_size, /**< script source size */
450              uint32_t parse_opts) /**< jerry_parse_opts_t option bits */
451 {
452 #if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
453   if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
454       && resource_name_length > 0)
455   {
456     jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME,
457                                 JERRY_DEBUGGER_NO_SUBTYPE,
458                                 resource_name_p,
459                                 resource_name_length);
460   }
461 #else /* !(ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)) */
462   JERRY_UNUSED (resource_name_p);
463   JERRY_UNUSED (resource_name_length);
464 #endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */
465 
466 #if ENABLED (JERRY_PARSER)
467   jerry_assert_api_available ();
468 
469 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
470   if (resource_name_length == 0)
471   {
472     JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
473   }
474   else
475   {
476     JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p,
477                                                                         (lit_utf8_size_t) resource_name_length);
478   }
479 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
480 
481   ecma_compiled_code_t *bytecode_data_p;
482   ecma_value_t parse_status;
483 
484   parse_status = parser_parse_script (NULL,
485                                       0,
486                                       source_p,
487                                       source_size,
488                                       parse_opts,
489                                       &bytecode_data_p);
490 
491   if (ECMA_IS_VALUE_ERROR (parse_status))
492   {
493     return ecma_create_error_reference_from_context ();
494   }
495 
496   ecma_free_value (parse_status);
497 
498   ecma_object_t *lex_env_p = ecma_get_global_environment ();
499   ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
500   ecma_bytecode_deref (bytecode_data_p);
501 
502   return ecma_make_object_value (func_obj_p);
503 #else /* !ENABLED (JERRY_PARSER) */
504   JERRY_UNUSED (source_p);
505   JERRY_UNUSED (source_size);
506   JERRY_UNUSED (parse_opts);
507 
508   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled.")));
509 #endif /* ENABLED (JERRY_PARSER) */
510 } /* jerry_parse */
511 
512 /**
513  * Parse function and construct an EcmaScript function. The lexical
514  * environment is set to the global lexical environment.
515  *
516  * @return function object value - if script was parsed successfully,
517  *         thrown error - otherwise
518  */
519 jerry_value_t
jerry_parse_function(const jerry_char_t * resource_name_p,size_t resource_name_length,const jerry_char_t * arg_list_p,size_t arg_list_size,const jerry_char_t * source_p,size_t source_size,uint32_t parse_opts)520 jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */
521                       size_t resource_name_length, /**< length of resource name */
522                       const jerry_char_t *arg_list_p, /**< script source */
523                       size_t arg_list_size, /**< script source size */
524                       const jerry_char_t *source_p, /**< script source */
525                       size_t source_size, /**< script source size */
526                       uint32_t parse_opts) /**< jerry_parse_opts_t option bits */
527 {
528 #if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
529   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
530   {
531     jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME,
532                                 JERRY_DEBUGGER_NO_SUBTYPE,
533                                 resource_name_p,
534                                 resource_name_length);
535   }
536 #else /* !(ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)) */
537   JERRY_UNUSED (resource_name_p);
538   JERRY_UNUSED (resource_name_length);
539 #endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */
540 
541 #if ENABLED (JERRY_PARSER)
542   jerry_assert_api_available ();
543 
544   ecma_compiled_code_t *bytecode_data_p;
545   ecma_value_t parse_status;
546 
547 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
548   if (resource_name_length == 0)
549   {
550     JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
551   }
552   else
553   {
554     JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p,
555                                                                         (lit_utf8_size_t) resource_name_length);
556   }
557 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
558 
559   if (arg_list_p == NULL)
560   {
561     /* Must not be a NULL value. */
562     arg_list_p = (const jerry_char_t *) "";
563   }
564 
565   parse_status = parser_parse_script (arg_list_p,
566                                       arg_list_size,
567                                       source_p,
568                                       source_size,
569                                       parse_opts,
570                                       &bytecode_data_p);
571 
572   if (ECMA_IS_VALUE_ERROR (parse_status))
573   {
574     return ecma_create_error_reference_from_context ();
575   }
576 
577   ecma_free_value (parse_status);
578 
579   ecma_object_t *lex_env_p = ecma_get_global_environment ();
580   ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
581   ecma_bytecode_deref (bytecode_data_p);
582 
583   return ecma_make_object_value (func_obj_p);
584 #else /* !ENABLED (JERRY_PARSER) */
585   JERRY_UNUSED (arg_list_p);
586   JERRY_UNUSED (arg_list_size);
587   JERRY_UNUSED (source_p);
588   JERRY_UNUSED (source_size);
589   JERRY_UNUSED (parse_opts);
590 
591   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled.")));
592 #endif /* ENABLED (JERRY_PARSER) */
593 } /* jerry_parse_function */
594 
595 /**
596  * Run an EcmaScript function created by jerry_parse.
597  *
598  * Note:
599  *      returned value must be freed with jerry_release_value, when it is no longer needed.
600  *
601  * @return result of bytecode - if run was successful
602  *         thrown error - otherwise
603  */
604 jerry_value_t
jerry_run(const jerry_value_t func_val)605 jerry_run (const jerry_value_t func_val) /**< function to run */
606 {
607   jerry_assert_api_available ();
608 
609   if (!ecma_is_value_object (func_val))
610   {
611     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
612   }
613 
614   ecma_object_t *func_obj_p = ecma_get_object_from_value (func_val);
615 
616   if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_FUNCTION
617       || ecma_get_object_is_builtin (func_obj_p))
618   {
619     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
620   }
621 
622   ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
623 
624   ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
625                                                                        ext_func_p->u.function.scope_cp);
626 
627   if (scope_p != ecma_get_global_environment ())
628   {
629     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
630   }
631 
632   return jerry_return (vm_run_global (ecma_op_function_get_compiled_code (ext_func_p)));
633 } /* jerry_run */
634 
635 /**
636  * Perform eval
637  *
638  * Note:
639  *      returned value must be freed with jerry_release_value, when it is no longer needed.
640  *
641  * @return result of eval, may be error value.
642  */
643 jerry_value_t
jerry_eval(const jerry_char_t * source_p,size_t source_size,uint32_t parse_opts)644 jerry_eval (const jerry_char_t *source_p, /**< source code */
645             size_t source_size, /**< length of source code */
646             uint32_t parse_opts) /**< jerry_parse_opts_t option bits */
647 {
648   jerry_assert_api_available ();
649 
650   return jerry_return (ecma_op_eval_chars_buffer ((const lit_utf8_byte_t *) source_p,
651                                                   source_size,
652                                                   parse_opts));
653 } /* jerry_eval */
654 
655 /**
656  * Run enqueued Promise jobs until the first thrown error or until all get executed.
657  *
658  * Note:
659  *      returned value must be freed with jerry_release_value, when it is no longer needed.
660  *
661  * @return result of last executed job, may be error value.
662  */
663 jerry_value_t
jerry_run_all_enqueued_jobs(void)664 jerry_run_all_enqueued_jobs (void)
665 {
666   jerry_assert_api_available ();
667 
668 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
669   return ecma_process_all_enqueued_jobs ();
670 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
671   return ECMA_VALUE_UNDEFINED;
672 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
673 } /* jerry_run_all_enqueued_jobs */
674 
675 /**
676  * Get global object
677  *
678  * Note:
679  *      returned value must be freed with jerry_release_value, when it is no longer needed.
680  *
681  * @return api value of global object
682  */
683 jerry_value_t
jerry_get_global_object(void)684 jerry_get_global_object (void)
685 {
686   jerry_assert_api_available ();
687   ecma_object_t *global_obj_p = ecma_builtin_get_global ();
688   ecma_ref_object (global_obj_p);
689   return ecma_make_object_value (global_obj_p);
690 } /* jerry_get_global_object */
691 
692 /**
693  * Check if the specified value is an abort value.
694  *
695  * @return true  - if both the error and abort values are set,
696  *         false - otherwise
697  */
698 bool
jerry_value_is_abort(const jerry_value_t value)699 jerry_value_is_abort (const jerry_value_t value) /**< api value */
700 {
701   jerry_assert_api_available ();
702 
703   if (!ecma_is_value_error_reference (value))
704   {
705     return false;
706   }
707 
708   ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
709 
710   return (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT) != 0;
711 } /* jerry_value_is_abort */
712 
713 /**
714  * Check if the specified value is an array object value.
715  *
716  * @return true  - if the specified value is an array object,
717  *         false - otherwise
718  */
719 bool
jerry_value_is_array(const jerry_value_t value)720 jerry_value_is_array (const jerry_value_t value) /**< jerry api value */
721 {
722   jerry_assert_api_available ();
723 
724   return (ecma_is_value_object (value)
725           && ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY);
726 } /* jerry_value_is_array */
727 
728 /**
729  * Check if the specified value is boolean.
730  *
731  * @return true  - if the specified value is boolean,
732  *         false - otherwise
733  */
734 bool
jerry_value_is_boolean(const jerry_value_t value)735 jerry_value_is_boolean (const jerry_value_t value) /**< api value */
736 {
737   jerry_assert_api_available ();
738 
739   return ecma_is_value_boolean (value);
740 } /* jerry_value_is_boolean */
741 
742 /**
743  * Check if the specified value is a constructor function object value.
744  *
745  * @return true - if the specified value is a function value that implements [[Construct]],
746  *         false - otherwise
747  */
748 bool
jerry_value_is_constructor(const jerry_value_t value)749 jerry_value_is_constructor (const jerry_value_t value) /**< jerry api value */
750 {
751   jerry_assert_api_available ();
752 
753   return ecma_is_constructor (value);
754 } /* jerry_value_is_constructor */
755 
756 /**
757  * Check if the specified value is an error or abort value.
758  *
759  * @return true  - if the specified value is an error value,
760  *         false - otherwise
761  */
762 bool
jerry_value_is_error(const jerry_value_t value)763 jerry_value_is_error (const jerry_value_t value) /**< api value */
764 {
765   jerry_assert_api_available ();
766 
767   return ecma_is_value_error_reference (value);
768 } /* jerry_value_is_error */
769 
770 /**
771  * Check if the specified value is a function object value.
772  *
773  * @return true - if the specified value is callable,
774  *         false - otherwise
775  */
776 bool
jerry_value_is_function(const jerry_value_t value)777 jerry_value_is_function (const jerry_value_t value) /**< api value */
778 {
779   jerry_assert_api_available ();
780 
781   return ecma_op_is_callable (value);
782 } /* jerry_value_is_function */
783 
784 /**
785  * Check if the specified value is number.
786  *
787  * @return true  - if the specified value is number,
788  *         false - otherwise
789  */
790 bool
jerry_value_is_number(const jerry_value_t value)791 jerry_value_is_number (const jerry_value_t value) /**< api value */
792 {
793   jerry_assert_api_available ();
794 
795   return ecma_is_value_number (value);
796 } /* jerry_value_is_number */
797 
798 /**
799  * Check if the specified value is null.
800  *
801  * @return true  - if the specified value is null,
802  *         false - otherwise
803  */
804 bool
jerry_value_is_null(const jerry_value_t value)805 jerry_value_is_null (const jerry_value_t value) /**< api value */
806 {
807   jerry_assert_api_available ();
808 
809   return ecma_is_value_null (value);
810 } /* jerry_value_is_null */
811 
812 /**
813  * Check if the specified value is object.
814  *
815  * @return true  - if the specified value is object,
816  *         false - otherwise
817  */
818 bool
jerry_value_is_object(const jerry_value_t value)819 jerry_value_is_object (const jerry_value_t value) /**< api value */
820 {
821   jerry_assert_api_available ();
822 
823   return ecma_is_value_object (value);
824 } /* jerry_value_is_object */
825 
826 /**
827  * Check if the specified value is promise.
828  *
829  * @return true  - if the specified value is promise,
830  *         false - otherwise
831  */
832 bool
jerry_value_is_promise(const jerry_value_t value)833 jerry_value_is_promise (const jerry_value_t value) /**< api value */
834 {
835   jerry_assert_api_available ();
836 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
837   return (ecma_is_value_object (value)
838           && ecma_is_promise (ecma_get_object_from_value (value)));
839 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
840   JERRY_UNUSED (value);
841   return false;
842 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
843 } /* jerry_value_is_promise */
844 
845 /**
846  * Check if the specified value is a proxy object.
847  *
848  * @return true  - if the specified value is a proxy object,
849  *         false - otherwise
850  */
851 bool
jerry_value_is_proxy(const jerry_value_t value)852 jerry_value_is_proxy (const jerry_value_t value) /**< api value */
853 {
854   jerry_assert_api_available ();
855 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
856   return (ecma_is_value_object (value)
857           && ECMA_OBJECT_IS_PROXY (ecma_get_object_from_value (value)));
858 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
859   JERRY_UNUSED (value);
860   return false;
861 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
862 } /* jerry_value_is_proxy */
863 
864 /**
865  * Check if the specified value is string.
866  *
867  * @return true  - if the specified value is string,
868  *         false - otherwise
869  */
870 bool
jerry_value_is_string(const jerry_value_t value)871 jerry_value_is_string (const jerry_value_t value) /**< api value */
872 {
873   jerry_assert_api_available ();
874 
875   return ecma_is_value_string (value);
876 } /* jerry_value_is_string */
877 
878 /**
879  * Check if the specified value is symbol.
880  *
881  * @return true  - if the specified value is symbol,
882  *         false - otherwise
883  */
884 bool
jerry_value_is_symbol(const jerry_value_t value)885 jerry_value_is_symbol (const jerry_value_t value) /**< api value */
886 {
887   jerry_assert_api_available ();
888 
889 #if ENABLED (JERRY_ES2015)
890   return ecma_is_value_symbol (value);
891 #else /* !ENABLED (JERRY_ES2015) */
892   JERRY_UNUSED (value);
893   return false;
894 #endif /* ENABLED (JERRY_ES2015) */
895 } /* jerry_value_is_symbol */
896 
897 /**
898  * Check if the specified value is undefined.
899  *
900  * @return true  - if the specified value is undefined,
901  *         false - otherwise
902  */
903 bool
jerry_value_is_undefined(const jerry_value_t value)904 jerry_value_is_undefined (const jerry_value_t value) /**< api value */
905 {
906   jerry_assert_api_available ();
907 
908   return ecma_is_value_undefined (value);
909 } /* jerry_value_is_undefined */
910 
911 /**
912  * Perform the base type of the JavaScript value.
913  *
914  * @return jerry_type_t value
915  */
916 jerry_type_t
jerry_value_get_type(const jerry_value_t value)917 jerry_value_get_type (const jerry_value_t value) /**< input value to check */
918 {
919   jerry_assert_api_available ();
920 
921   if (ecma_is_value_error_reference (value))
922   {
923     return JERRY_TYPE_ERROR;
924   }
925 
926   lit_magic_string_id_t lit_id = ecma_get_typeof_lit_id (value);
927 
928   JERRY_ASSERT (lit_id != LIT_MAGIC_STRING__EMPTY);
929 
930   switch (lit_id)
931   {
932     case LIT_MAGIC_STRING_UNDEFINED:
933     {
934       return JERRY_TYPE_UNDEFINED;
935     }
936     case LIT_MAGIC_STRING_BOOLEAN:
937     {
938       return JERRY_TYPE_BOOLEAN;
939     }
940     case LIT_MAGIC_STRING_NUMBER:
941     {
942       return JERRY_TYPE_NUMBER;
943     }
944     case LIT_MAGIC_STRING_STRING:
945     {
946       return JERRY_TYPE_STRING;
947     }
948 #if ENABLED (JERRY_ES2015)
949     case LIT_MAGIC_STRING_SYMBOL:
950     {
951       return JERRY_TYPE_SYMBOL;
952     }
953 #endif /* ENABLED (JERRY_ES2015) */
954     case LIT_MAGIC_STRING_FUNCTION:
955     {
956       return JERRY_TYPE_FUNCTION;
957     }
958     default:
959     {
960       JERRY_ASSERT (lit_id == LIT_MAGIC_STRING_OBJECT);
961 
962       /* Based on the ECMA 262 5.1 standard the 'null' value is an object.
963        * Thus we'll do an extra check for 'null' here.
964        */
965       return ecma_is_value_null (value) ? JERRY_TYPE_NULL : JERRY_TYPE_OBJECT;
966     }
967   }
968 } /* jerry_value_get_type */
969 
970 /**
971  * Check if the specified feature is enabled.
972  *
973  * @return true  - if the specified feature is enabled,
974  *         false - otherwise
975  */
976 bool
jerry_is_feature_enabled(const jerry_feature_t feature)977 jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check */
978 {
979   JERRY_ASSERT (feature < JERRY_FEATURE__COUNT);
980 
981   return (false
982 #if ENABLED (JERRY_CPOINTER_32_BIT)
983           || feature == JERRY_FEATURE_CPOINTER_32_BIT
984 #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
985 #if ENABLED (JERRY_ERROR_MESSAGES)
986           || feature == JERRY_FEATURE_ERROR_MESSAGES
987 #endif /* ENABLED (JERRY_ERROR_MESSAGES) */
988 #if ENABLED (JERRY_PARSER)
989           || feature == JERRY_FEATURE_JS_PARSER
990 #endif /* ENABLED (JERRY_PARSER) */
991 #if ENABLED (JERRY_MEM_STATS)
992           || feature == JERRY_FEATURE_MEM_STATS
993 #endif /* ENABLED (JERRY_MEM_STATS) */
994 #if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
995           || feature == JERRY_FEATURE_PARSER_DUMP
996 #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
997 #if ENABLED (JERRY_REGEXP_DUMP_BYTE_CODE)
998           || feature == JERRY_FEATURE_REGEXP_DUMP
999 #endif /* ENABLED (JERRY_REGEXP_DUMP_BYTE_CODE) */
1000 #if ENABLED (JERRY_SNAPSHOT_SAVE)
1001           || feature == JERRY_FEATURE_SNAPSHOT_SAVE
1002 #endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
1003 #if ENABLED (JERRY_SNAPSHOT_EXEC)
1004           || feature == JERRY_FEATURE_SNAPSHOT_EXEC
1005 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
1006 #if ENABLED (JERRY_DEBUGGER)
1007           || feature == JERRY_FEATURE_DEBUGGER
1008 #endif /* ENABLED (JERRY_DEBUGGER) */
1009 #if ENABLED (JERRY_VM_EXEC_STOP)
1010           || feature == JERRY_FEATURE_VM_EXEC_STOP
1011 #endif /* ENABLED (JERRY_VM_EXEC_STOP) */
1012 #if ENABLED (JERRY_BUILTIN_JSON)
1013           || feature == JERRY_FEATURE_JSON
1014 #endif /* ENABLED (JERRY_BUILTIN_JSON) */
1015 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
1016           || feature == JERRY_FEATURE_PROMISE
1017 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
1018 #if ENABLED (JERRY_ES2015)
1019           || feature == JERRY_FEATURE_SYMBOL
1020 #endif /* ENABLED (JERRY_ES2015) */
1021 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
1022           || feature == JERRY_FEATURE_TYPEDARRAY
1023 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
1024 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
1025           || feature == JERRY_FEATURE_DATAVIEW
1026 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
1027 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1028           || feature == JERRY_FEATURE_PROXY
1029 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1030 #if ENABLED (JERRY_BUILTIN_DATE)
1031           || feature == JERRY_FEATURE_DATE
1032 #endif /* ENABLED (JERRY_BUILTIN_DATE) */
1033 #if ENABLED (JERRY_BUILTIN_REGEXP)
1034           || feature == JERRY_FEATURE_REGEXP
1035 #endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
1036 #if ENABLED (JERRY_LINE_INFO)
1037           || feature == JERRY_FEATURE_LINE_INFO
1038 #endif /* ENABLED (JERRY_LINE_INFO) */
1039 #if ENABLED (JERRY_LOGGING)
1040           || feature == JERRY_FEATURE_LOGGING
1041 #endif /* ENABLED (JERRY_LOGGING) */
1042 #if ENABLED (JERRY_ES2015_BUILTIN_MAP)
1043           || feature == JERRY_FEATURE_MAP
1044 #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
1045 #if ENABLED (JERRY_ES2015_BUILTIN_SET)
1046           || feature == JERRY_FEATURE_SET
1047 #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
1048 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
1049           || feature == JERRY_FEATURE_WEAKMAP
1050 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */
1051 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
1052           || feature == JERRY_FEATURE_WEAKSET
1053 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
1054           );
1055 } /* jerry_is_feature_enabled */
1056 
1057 /**
1058  * Perform binary operation on the given operands (==, ===, <, >, etc.).
1059  *
1060  * @return error - if argument has an error flag or operation is unsuccessful or unsupported
1061  *         true/false - the result of the binary operation on the given operands otherwise
1062  */
1063 jerry_value_t
jerry_binary_operation(jerry_binary_operation_t op,const jerry_value_t lhs,const jerry_value_t rhs)1064 jerry_binary_operation (jerry_binary_operation_t op, /**< operation */
1065                         const jerry_value_t lhs, /**< first operand */
1066                         const jerry_value_t rhs) /**< second operand */
1067 {
1068   jerry_assert_api_available ();
1069 
1070   if (ecma_is_value_error_reference (lhs) || ecma_is_value_error_reference (rhs))
1071   {
1072     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
1073   }
1074 
1075   switch (op)
1076   {
1077     case JERRY_BIN_OP_EQUAL:
1078     {
1079       return jerry_return (ecma_op_abstract_equality_compare (lhs, rhs));
1080     }
1081     case JERRY_BIN_OP_STRICT_EQUAL:
1082     {
1083       return ecma_make_boolean_value (ecma_op_strict_equality_compare (lhs, rhs));
1084     }
1085     case JERRY_BIN_OP_LESS:
1086     {
1087       return jerry_return (opfunc_relation (lhs, rhs, true, false));
1088     }
1089     case JERRY_BIN_OP_LESS_EQUAL:
1090     {
1091       return jerry_return (opfunc_relation (lhs, rhs, false, true));
1092     }
1093     case JERRY_BIN_OP_GREATER:
1094     {
1095       return jerry_return (opfunc_relation (lhs, rhs, false, false));
1096     }
1097     case JERRY_BIN_OP_GREATER_EQUAL:
1098     {
1099       return jerry_return (opfunc_relation (lhs, rhs, true, true));
1100     }
1101     case JERRY_BIN_OP_INSTANCEOF:
1102     {
1103       if (!ecma_is_value_object (lhs)
1104           || !ecma_op_is_callable (rhs))
1105       {
1106         return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
1107       }
1108 
1109       ecma_object_t *proto_obj_p = ecma_get_object_from_value (rhs);
1110       return jerry_return (ecma_op_object_has_instance (proto_obj_p, lhs));
1111     }
1112     case JERRY_BIN_OP_ADD:
1113     {
1114       return jerry_return (opfunc_addition (lhs, rhs));
1115     }
1116     case JERRY_BIN_OP_SUB:
1117     case JERRY_BIN_OP_MUL:
1118     case JERRY_BIN_OP_DIV:
1119     case JERRY_BIN_OP_REM:
1120     {
1121       return jerry_return (do_number_arithmetic (op - ECMA_NUMBER_ARITHMETIC_OP_API_OFFSET, lhs, rhs));
1122     }
1123     default:
1124     {
1125       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Unsupported binary operation")));
1126     }
1127   }
1128 } /* jerry_binary_operation */
1129 
1130 /**
1131  * Create abort from an api value.
1132  *
1133  * Create abort value from an api value. If the second argument is true
1134  * it will release the input api value.
1135  *
1136  * @return api abort value
1137  */
1138 jerry_value_t
jerry_create_abort_from_value(jerry_value_t value,bool release)1139 jerry_create_abort_from_value (jerry_value_t value, /**< api value */
1140                                bool release) /**< release api value */
1141 {
1142   jerry_assert_api_available ();
1143 
1144   if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
1145   {
1146     /* This is a rare case so it is optimized for
1147      * binary size rather than performance. */
1148     if (jerry_value_is_abort (value))
1149     {
1150       return release ? value : jerry_acquire_value (value);
1151     }
1152 
1153     value = jerry_get_value_from_error (value, release);
1154     release = true;
1155   }
1156 
1157   if (!release)
1158   {
1159     value = ecma_copy_value (value);
1160   }
1161 
1162   return ecma_create_error_reference (value, false);
1163 } /* jerry_create_abort_from_value */
1164 
1165 /**
1166  * Create error from an api value.
1167  *
1168  * Create error value from an api value. If the second argument is true
1169  * it will release the input api value.
1170  *
1171  * @return api error value
1172  */
1173 jerry_value_t
jerry_create_error_from_value(jerry_value_t value,bool release)1174 jerry_create_error_from_value (jerry_value_t value, /**< api value */
1175                                bool release) /**< release api value */
1176 {
1177   jerry_assert_api_available ();
1178 
1179   if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
1180   {
1181     /* This is a rare case so it is optimized for
1182      * binary size rather than performance. */
1183     if (!jerry_value_is_abort (value))
1184     {
1185       return release ? value : jerry_acquire_value (value);
1186     }
1187 
1188     value = jerry_get_value_from_error (value, release);
1189     release = true;
1190   }
1191 
1192   if (!release)
1193   {
1194     value = ecma_copy_value (value);
1195   }
1196 
1197   return ecma_create_error_reference (value, true);
1198 } /* jerry_create_error_from_value */
1199 
1200 /**
1201  * Get the value from an error value.
1202  *
1203  * Extract the api value from an error. If the second argument is true
1204  * it will release the input error value.
1205  *
1206  * Note:
1207  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1208  *
1209  * @return jerry_value_t value
1210  */
1211 jerry_value_t
jerry_get_value_from_error(jerry_value_t value,bool release)1212 jerry_get_value_from_error (jerry_value_t value, /**< api value */
1213                             bool release) /**< release api value */
1214 {
1215   jerry_assert_api_available ();
1216 
1217   if (!ecma_is_value_error_reference (value))
1218   {
1219     return release ? value : ecma_copy_value (value);
1220   }
1221 
1222   jerry_value_t ret_val = jerry_acquire_value (ecma_get_error_reference_from_value (value)->value);
1223 
1224   if (release)
1225   {
1226     jerry_release_value (value);
1227   }
1228   return ret_val;
1229 } /* jerry_get_value_from_error */
1230 
1231 /**
1232  * Return the type of the Error object if possible.
1233  *
1234  * @return one of the jerry_error_t value as the type of the Error object
1235  *         JERRY_ERROR_NONE - if the input value is not an Error object
1236  */
1237 jerry_error_t
jerry_get_error_type(jerry_value_t value)1238 jerry_get_error_type (jerry_value_t value) /**< api value */
1239 {
1240   if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
1241   {
1242     value = ecma_get_error_reference_from_value (value)->value;
1243   }
1244 
1245   if (!ecma_is_value_object (value))
1246   {
1247     return JERRY_ERROR_NONE;
1248   }
1249 
1250   ecma_object_t *object_p = ecma_get_object_from_value (value);
1251   ecma_standard_error_t error_type = ecma_get_error_type (object_p);
1252 
1253   return (jerry_error_t) error_type;
1254 } /* jerry_get_error_type */
1255 
1256 /**
1257  * Get boolean from the specified value.
1258  *
1259  * @return true or false.
1260  */
1261 bool
jerry_get_boolean_value(const jerry_value_t value)1262 jerry_get_boolean_value (const jerry_value_t value) /**< api value */
1263 {
1264   jerry_assert_api_available ();
1265 
1266   return ecma_is_value_true (value);
1267 } /* jerry_get_boolean_value */
1268 
1269 /**
1270  * Get number from the specified value as a double.
1271  *
1272  * @return stored number as double
1273  */
1274 double
jerry_get_number_value(const jerry_value_t value)1275 jerry_get_number_value (const jerry_value_t value) /**< api value */
1276 {
1277   jerry_assert_api_available ();
1278 
1279   if (!ecma_is_value_number (value))
1280   {
1281     return 0;
1282   }
1283 
1284   return (double) ecma_get_number_from_value (value);
1285 } /* jerry_get_number_value */
1286 
1287 /**
1288  * Call ToBoolean operation on the api value.
1289  *
1290  * @return true  - if the logical value is true
1291  *         false - otherwise
1292  */
1293 bool
jerry_value_to_boolean(const jerry_value_t value)1294 jerry_value_to_boolean (const jerry_value_t value) /**< input value */
1295 {
1296   jerry_assert_api_available ();
1297 
1298   if (ecma_is_value_error_reference (value))
1299   {
1300     return false;
1301   }
1302 
1303   return ecma_op_to_boolean (value);
1304 } /* jerry_value_to_boolean */
1305 
1306 /**
1307  * Call ToNumber operation on the api value.
1308  *
1309  * Note:
1310  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1311  *
1312  * @return converted number value - if success
1313  *         thrown error - otherwise
1314  */
1315 jerry_value_t
jerry_value_to_number(const jerry_value_t value)1316 jerry_value_to_number (const jerry_value_t value) /**< input value */
1317 {
1318   jerry_assert_api_available ();
1319 
1320   if (ecma_is_value_error_reference (value))
1321   {
1322     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
1323   }
1324 
1325   return jerry_return (ecma_op_to_number (value));
1326 } /* jerry_value_to_number */
1327 
1328 /**
1329  * Call ToObject operation on the api value.
1330  *
1331  * Note:
1332  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1333  *
1334  * @return converted object value - if success
1335  *         thrown error - otherwise
1336  */
1337 jerry_value_t
jerry_value_to_object(const jerry_value_t value)1338 jerry_value_to_object (const jerry_value_t value) /**< input value */
1339 {
1340   jerry_assert_api_available ();
1341 
1342   if (ecma_is_value_error_reference (value))
1343   {
1344     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
1345   }
1346 
1347   return jerry_return (ecma_op_to_object (value));
1348 } /* jerry_value_to_object */
1349 
1350 /**
1351  * Call ToPrimitive operation on the api value.
1352  *
1353  * Note:
1354  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1355  *
1356  * @return converted primitive value - if success
1357  *         thrown error - otherwise
1358  */
1359 jerry_value_t
jerry_value_to_primitive(const jerry_value_t value)1360 jerry_value_to_primitive (const jerry_value_t value) /**< input value */
1361 {
1362   jerry_assert_api_available ();
1363 
1364   if (ecma_is_value_error_reference (value))
1365   {
1366     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
1367   }
1368 
1369   return jerry_return (ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NO));
1370 } /* jerry_value_to_primitive */
1371 
1372 /**
1373  * Call the ToString ecma builtin operation on the api value.
1374  *
1375  * Note:
1376  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1377  *
1378  * @return converted string value - if success
1379  *         thrown error - otherwise
1380  */
1381 jerry_value_t
jerry_value_to_string(const jerry_value_t value)1382 jerry_value_to_string (const jerry_value_t value) /**< input value */
1383 {
1384 
1385   jerry_assert_api_available ();
1386 
1387   if (ecma_is_value_error_reference (value))
1388   {
1389     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
1390   }
1391 
1392   ecma_string_t *str_p = ecma_op_to_string (value);
1393   if (JERRY_UNLIKELY (str_p == NULL))
1394   {
1395     return ecma_create_error_reference_from_context ();
1396   }
1397 
1398   return jerry_return (ecma_make_string_value (str_p));
1399 } /* jerry_value_to_string */
1400 
1401 /**
1402  * Acquire specified Jerry API value.
1403  *
1404  * Note:
1405  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1406  *
1407  * @return acquired api value
1408  */
1409 jerry_value_t
jerry_acquire_value(jerry_value_t value)1410 jerry_acquire_value (jerry_value_t value) /**< API value */
1411 {
1412   jerry_assert_api_available ();
1413 
1414   if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
1415   {
1416     ecma_ref_error_reference (ecma_get_error_reference_from_value (value));
1417     return value;
1418   }
1419 
1420   return ecma_copy_value (value);
1421 } /* jerry_acquire_value */
1422 
1423 /**
1424  * Release specified Jerry API value
1425  */
1426 void
jerry_release_value(jerry_value_t value)1427 jerry_release_value (jerry_value_t value) /**< API value */
1428 {
1429   jerry_assert_api_available ();
1430 
1431   if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
1432   {
1433     ecma_deref_error_reference (ecma_get_error_reference_from_value (value));
1434     return;
1435   }
1436 
1437   ecma_free_value (value);
1438 } /* jerry_release_value */
1439 
1440 /**
1441  * Create an array object value
1442  *
1443  * Note:
1444  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1445  *
1446  * @return value of the constructed array object
1447  */
1448 jerry_value_t
jerry_create_array(uint32_t size)1449 jerry_create_array (uint32_t size) /**< size of array */
1450 {
1451   jerry_assert_api_available ();
1452 
1453   ecma_value_t array_length = ecma_make_uint32_value (size);
1454 
1455   const jerry_length_t argument_size = 1;
1456   ecma_value_t array_value = ecma_op_create_array_object (&array_length, argument_size, true);
1457   ecma_free_value (array_length);
1458 
1459   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
1460 
1461   return array_value;
1462 } /* jerry_create_array */
1463 
1464 /**
1465  * Create a jerry_value_t representing a boolean value from the given boolean parameter.
1466  *
1467  * @return value of the created boolean
1468  */
1469 jerry_value_t
jerry_create_boolean(bool value)1470 jerry_create_boolean (bool value) /**< bool value from which a jerry_value_t will be created */
1471 {
1472   jerry_assert_api_available ();
1473 
1474   return jerry_return (ecma_make_boolean_value (value));
1475 } /* jerry_create_boolean */
1476 
1477 /**
1478  * Create an error object
1479  *
1480  * Note:
1481  *      - returned value must be freed with jerry_release_value, when it is no longer needed
1482  *      - the error flag is set for the returned value
1483  *
1484  * @return value of the constructed error object
1485  */
1486 jerry_value_t
jerry_create_error(jerry_error_t error_type,const jerry_char_t * message_p)1487 jerry_create_error (jerry_error_t error_type, /**< type of error */
1488                     const jerry_char_t *message_p) /**< value of 'message' property
1489                                                     *   of constructed error object */
1490 {
1491   return jerry_create_error_sz (error_type,
1492                                 (lit_utf8_byte_t *) message_p,
1493                                 lit_zt_utf8_string_size (message_p));
1494 } /* jerry_create_error */
1495 
1496 /**
1497  * Create an error object
1498  *
1499  * Note:
1500  *      - returned value must be freed with jerry_release_value, when it is no longer needed
1501  *      - the error flag is set for the returned value
1502  *
1503  * @return value of the constructed error object
1504  */
1505 jerry_value_t
jerry_create_error_sz(jerry_error_t error_type,const jerry_char_t * message_p,jerry_size_t message_size)1506 jerry_create_error_sz (jerry_error_t error_type, /**< type of error */
1507                        const jerry_char_t *message_p, /**< value of 'message' property
1508                                                        *   of constructed error object */
1509                        jerry_size_t message_size) /**< size of the message in bytes */
1510 {
1511   jerry_assert_api_available ();
1512 
1513   if (message_p == NULL || message_size == 0)
1514   {
1515     return ecma_create_error_object_reference (ecma_new_standard_error ((ecma_standard_error_t) error_type));
1516   }
1517   else
1518   {
1519     ecma_string_t *message_string_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) message_p,
1520                                                                       (lit_utf8_size_t) message_size);
1521 
1522     ecma_object_t *error_object_p = ecma_new_standard_error_with_message ((ecma_standard_error_t) error_type,
1523                                                                           message_string_p);
1524 
1525     ecma_deref_ecma_string (message_string_p);
1526 
1527     return ecma_create_error_object_reference (error_object_p);
1528   }
1529 } /* jerry_create_error_sz */
1530 
1531 /**
1532  * Create an external function object
1533  *
1534  * Note:
1535  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1536  *
1537  * @return value of the constructed function object
1538  */
1539 jerry_value_t
jerry_create_external_function(jerry_external_handler_t handler_p)1540 jerry_create_external_function (jerry_external_handler_t handler_p) /**< pointer to native handler
1541                                                                      *   for the function */
1542 {
1543   jerry_assert_api_available ();
1544 
1545   ecma_object_t *func_obj_p = ecma_op_create_external_function_object (handler_p);
1546   return ecma_make_object_value (func_obj_p);
1547 } /* jerry_create_external_function */
1548 
1549 /**
1550  * Creates a jerry_value_t representing a number value.
1551  *
1552  * Note:
1553  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1554  *
1555  * @return jerry_value_t created from the given double argument.
1556  */
1557 jerry_value_t
jerry_create_number(double value)1558 jerry_create_number (double value) /**< double value from which a jerry_value_t will be created */
1559 {
1560   jerry_assert_api_available ();
1561 
1562   return ecma_make_number_value ((ecma_number_t) value);
1563 } /* jerry_create_number */
1564 
1565 /**
1566  * Creates a jerry_value_t representing a positive or negative infinity value.
1567  *
1568  * Note:
1569  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1570  *
1571  * @return jerry_value_t representing an infinity value.
1572  */
1573 jerry_value_t
jerry_create_number_infinity(bool sign)1574 jerry_create_number_infinity (bool sign) /**< true for negative Infinity
1575                                           *   false for positive Infinity */
1576 {
1577   jerry_assert_api_available ();
1578 
1579   return ecma_make_number_value (ecma_number_make_infinity (sign));
1580 } /* jerry_create_number_infinity */
1581 
1582 /**
1583  * Creates a jerry_value_t representing a not-a-number value.
1584  *
1585  * Note:
1586  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1587  *
1588  * @return jerry_value_t representing a not-a-number value.
1589  */
1590 jerry_value_t
jerry_create_number_nan(void)1591 jerry_create_number_nan (void)
1592 {
1593   jerry_assert_api_available ();
1594 
1595   return ecma_make_nan_value ();
1596 } /* jerry_create_number_nan */
1597 
1598 /**
1599  * Creates a jerry_value_t representing an undefined value.
1600  *
1601  * @return value of undefined
1602  */
1603 jerry_value_t
jerry_create_undefined(void)1604 jerry_create_undefined (void)
1605 {
1606   jerry_assert_api_available ();
1607 
1608   return ECMA_VALUE_UNDEFINED;
1609 } /* jerry_create_undefined */
1610 
1611 /**
1612  * Creates and returns a jerry_value_t with type null object.
1613  *
1614  * @return jerry_value_t representing null
1615  */
1616 jerry_value_t
jerry_create_null(void)1617 jerry_create_null (void)
1618 {
1619   jerry_assert_api_available ();
1620 
1621   return ECMA_VALUE_NULL;
1622 } /* jerry_create_null */
1623 
1624 /**
1625  * Create new JavaScript object, like with new Object().
1626  *
1627  * Note:
1628  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1629  *
1630  * @return value of the created object
1631  */
1632 jerry_value_t
jerry_create_object(void)1633 jerry_create_object (void)
1634 {
1635   jerry_assert_api_available ();
1636 
1637   return ecma_make_object_value (ecma_op_create_object_object_noarg ());
1638 } /* jerry_create_object */
1639 
1640 /**
1641  * Create an empty Promise object which can be resolve/reject later
1642  * by calling jerry_resolve_or_reject_promise.
1643  *
1644  * Note:
1645  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1646  *
1647  * @return value of the created object
1648  */
1649 jerry_value_t
jerry_create_promise(void)1650 jerry_create_promise (void)
1651 {
1652   jerry_assert_api_available ();
1653 
1654 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
1655   ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1656 
1657   if (old_new_target_p == NULL)
1658   {
1659     JERRY_CONTEXT (current_new_target) = ecma_builtin_get (ECMA_BUILTIN_ID_PROMISE);
1660   }
1661 
1662   ecma_value_t promise_value = ecma_op_create_promise_object (ECMA_VALUE_EMPTY, ECMA_PROMISE_EXECUTOR_EMPTY);
1663 
1664   JERRY_CONTEXT (current_new_target) = old_new_target_p;
1665   return promise_value;
1666 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
1667   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported.")));
1668 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
1669 } /* jerry_create_promise */
1670 
1671 /**
1672  * Create a new Proxy object with the given target and handler
1673  *
1674  * Note:
1675  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1676  *
1677  * @return value of the created Proxy object
1678  */
1679 jerry_value_t
jerry_create_proxy(const jerry_value_t target,const jerry_value_t handler)1680 jerry_create_proxy (const jerry_value_t target, /**< target argument */
1681                     const jerry_value_t handler) /**< handler argument */
1682 {
1683   jerry_assert_api_available ();
1684 
1685   if (ecma_is_value_error_reference (target)
1686       || ecma_is_value_error_reference (handler))
1687   {
1688     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
1689   }
1690 
1691 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1692   ecma_object_t *proxy_p = ecma_proxy_create (target, handler);
1693   return jerry_return (proxy_p == NULL ? ECMA_VALUE_ERROR : ecma_make_object_value (proxy_p));
1694 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1695   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Proxy is not supported.")));
1696 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1697 } /* jerry_create_proxy */
1698 
1699 /**
1700  * Create string from a valid UTF-8 string
1701  *
1702  * Note:
1703  *      returned value must be freed with jerry_release_value when it is no longer needed.
1704  *
1705  * @return value of the created string
1706  */
1707 jerry_value_t
jerry_create_string_from_utf8(const jerry_char_t * str_p)1708 jerry_create_string_from_utf8 (const jerry_char_t *str_p) /**< pointer to string */
1709 {
1710   return jerry_create_string_sz_from_utf8 (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p));
1711 } /* jerry_create_string_from_utf8 */
1712 
1713 /**
1714  * Create string from a valid UTF-8 string
1715  *
1716  * Note:
1717  *      returned value must be freed with jerry_release_value when it is no longer needed.
1718  *
1719  * @return value of the created string
1720  */
1721 jerry_value_t
jerry_create_string_sz_from_utf8(const jerry_char_t * str_p,jerry_size_t str_size)1722 jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, /**< pointer to string */
1723                                   jerry_size_t str_size) /**< string size */
1724 {
1725   jerry_assert_api_available ();
1726 
1727   ecma_string_t *ecma_str_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 ((lit_utf8_byte_t *) str_p,
1728                                                                                  (lit_utf8_size_t) str_size);
1729 
1730   return ecma_make_string_value (ecma_str_p);
1731 } /* jerry_create_string_sz_from_utf8 */
1732 
1733 /**
1734  * Create string from a valid CESU-8 string
1735  *
1736  * Note:
1737  *      returned value must be freed with jerry_release_value, when it is no longer needed.
1738  *
1739  * @return value of the created string
1740  */
1741 jerry_value_t
jerry_create_string(const jerry_char_t * str_p)1742 jerry_create_string (const jerry_char_t *str_p) /**< pointer to string */
1743 {
1744   return jerry_create_string_sz (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p));
1745 } /* jerry_create_string */
1746 
1747 /**
1748  * Create string from a valid CESU-8 string
1749  *
1750  * Note:
1751  *      returned value must be freed with jerry_release_value when it is no longer needed.
1752  *
1753  * @return value of the created string
1754  */
1755 jerry_value_t
jerry_create_string_sz(const jerry_char_t * str_p,jerry_size_t str_size)1756 jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */
1757                         jerry_size_t str_size) /**< string size */
1758 {
1759   jerry_assert_api_available ();
1760 
1761   ecma_string_t *ecma_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) str_p,
1762                                                               (lit_utf8_size_t) str_size);
1763   return ecma_make_string_value (ecma_str_p);
1764 } /* jerry_create_string_sz */
1765 
1766 /**
1767  * Create symbol from an api value
1768  *
1769  * Note:
1770  *      The given argument is converted to string. This operation can throw an error.
1771  *      returned value must be freed with jerry_release_value when it is no longer needed.
1772  *
1773  * @return value of the created symbol, if success
1774  *         thrown error, otherwise
1775  */
1776 jerry_value_t
jerry_create_symbol(const jerry_value_t value)1777 jerry_create_symbol (const jerry_value_t value) /**< api value */
1778 {
1779   jerry_assert_api_available ();
1780 
1781   if (ecma_is_value_error_reference (value))
1782   {
1783     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
1784   }
1785 
1786 #if ENABLED (JERRY_ES2015)
1787   return jerry_return (ecma_op_create_symbol (&value, 1));
1788 #else /* !ENABLED (JERRY_ES2015) */
1789   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Symbol is not supported.")));
1790 #endif /* ENABLED (JERRY_ES2015) */
1791 } /* jerry_create_symbol */
1792 
1793 /**
1794  * Calculates the size of the given pattern and creates a RegExp object.
1795  *
1796  * @return value of the constructed RegExp object.
1797  */
1798 jerry_value_t
jerry_create_regexp(const jerry_char_t * pattern_p,uint16_t flags)1799 jerry_create_regexp (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */
1800                      uint16_t flags) /**< optional RegExp flags */
1801 {
1802   return jerry_create_regexp_sz (pattern_p, lit_zt_utf8_string_size (pattern_p), flags);
1803 } /* jerry_create_regexp */
1804 
1805 /**
1806  * Creates a RegExp object with the given pattern and flags.
1807  *
1808  * @return value of the constructed RegExp object.
1809  */
1810 jerry_value_t
jerry_create_regexp_sz(const jerry_char_t * pattern_p,jerry_size_t pattern_size,uint16_t flags)1811 jerry_create_regexp_sz (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */
1812                         jerry_size_t pattern_size, /**< length of the pattern */
1813                         uint16_t flags) /**< optional RegExp flags */
1814 {
1815   jerry_assert_api_available ();
1816 
1817 #if ENABLED (JERRY_BUILTIN_REGEXP)
1818   if (!lit_is_valid_utf8_string (pattern_p, pattern_size))
1819   {
1820     return jerry_throw (ecma_raise_common_error (ECMA_ERR_MSG ("Input must be a valid utf8 string")));
1821   }
1822 
1823   ecma_object_t *regexp_obj_p = ecma_op_regexp_alloc (NULL);
1824 
1825   if (JERRY_UNLIKELY (regexp_obj_p == NULL))
1826   {
1827     return ECMA_VALUE_ERROR;
1828   }
1829 
1830   ecma_string_t *ecma_pattern = ecma_new_ecma_string_from_utf8 (pattern_p, pattern_size);
1831 
1832   jerry_value_t ret_val = ecma_op_create_regexp_with_flags (regexp_obj_p,
1833                                                             ecma_make_string_value (ecma_pattern),
1834                                                             flags);
1835   ecma_deref_ecma_string (ecma_pattern);
1836 
1837   return ret_val;
1838 
1839 #else /* !ENABLED (JERRY_BUILTIN_REGEXP) */
1840   JERRY_UNUSED (pattern_p);
1841   JERRY_UNUSED (pattern_size);
1842   JERRY_UNUSED (flags);
1843 
1844   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("RegExp is not supported.")));
1845 #endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
1846 } /* jerry_create_regexp_sz */
1847 
1848 /**
1849  * Get length of an array object
1850  *
1851  * Note:
1852  *      Returns 0, if the value parameter is not an array object.
1853  *
1854  * @return length of the given array
1855  */
1856 uint32_t
jerry_get_array_length(const jerry_value_t value)1857 jerry_get_array_length (const jerry_value_t value) /**< api value */
1858 {
1859   jerry_assert_api_available ();
1860 
1861   if (!jerry_value_is_object (value))
1862   {
1863     return 0;
1864   }
1865 
1866   ecma_object_t *object_p = ecma_get_object_from_value (value);
1867 
1868   if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY))
1869   {
1870     return ecma_array_get_length (object_p);
1871   }
1872 
1873   return 0;
1874 } /* jerry_get_array_length */
1875 
1876 /**
1877  * Get size of Jerry string
1878  *
1879  * Note:
1880  *      Returns 0, if the value parameter is not a string.
1881  *
1882  * @return number of bytes in the buffer needed to represent the string
1883  */
1884 jerry_size_t
jerry_get_string_size(const jerry_value_t value)1885 jerry_get_string_size (const jerry_value_t value) /**< input string */
1886 {
1887   jerry_assert_api_available ();
1888 
1889   if (!ecma_is_value_string (value))
1890   {
1891     return 0;
1892   }
1893 
1894   return ecma_string_get_size (ecma_get_string_from_value (value));
1895 } /* jerry_get_string_size */
1896 
1897 /**
1898  * Get UTF-8 encoded string size from Jerry string
1899  *
1900  * Note:
1901  *      Returns 0, if the value parameter is not a string.
1902  *
1903  * @return number of bytes in the buffer needed to represent the UTF-8 encoded string
1904  */
1905 jerry_size_t
jerry_get_utf8_string_size(const jerry_value_t value)1906 jerry_get_utf8_string_size (const jerry_value_t value) /**< input string */
1907 {
1908   jerry_assert_api_available ();
1909 
1910   if (!ecma_is_value_string (value))
1911   {
1912     return 0;
1913   }
1914 
1915   return ecma_string_get_utf8_size (ecma_get_string_from_value (value));
1916 } /* jerry_get_utf8_string_size */
1917 
1918 /**
1919  * Get length of Jerry string
1920  *
1921  * Note:
1922  *      Returns 0, if the value parameter is not a string.
1923  *
1924  * @return number of characters in the string
1925  */
1926 jerry_length_t
jerry_get_string_length(const jerry_value_t value)1927 jerry_get_string_length (const jerry_value_t value) /**< input string */
1928 {
1929   jerry_assert_api_available ();
1930 
1931   if (!ecma_is_value_string (value))
1932   {
1933     return 0;
1934   }
1935 
1936   return ecma_string_get_length (ecma_get_string_from_value (value));
1937 } /* jerry_get_string_length */
1938 
1939 /**
1940  * Get UTF-8 string length from Jerry string
1941  *
1942  * Note:
1943  *      Returns 0, if the value parameter is not a string.
1944  *
1945  * @return number of characters in the string
1946  */
1947 jerry_length_t
jerry_get_utf8_string_length(const jerry_value_t value)1948 jerry_get_utf8_string_length (const jerry_value_t value) /**< input string */
1949 {
1950   jerry_assert_api_available ();
1951 
1952   if (!ecma_is_value_string (value))
1953   {
1954     return 0;
1955   }
1956 
1957   return ecma_string_get_utf8_length (ecma_get_string_from_value (value));
1958 } /* jerry_get_utf8_string_length */
1959 
1960 /**
1961  * Copy the characters of a string into a specified buffer.
1962  *
1963  * Note:
1964  *      The '\0' character could occur in character buffer.
1965  *      Returns 0, if the value parameter is not a string or
1966  *      the buffer is not large enough for the whole string.
1967  *
1968  * Note:
1969  *      If the size of the string in jerry value is larger than the size of the
1970  *      target buffer, the copy will fail.
1971  *      To copy substring use jerry_substring_to_char_buffer() instead.
1972  *
1973  * @return number of bytes, actually copied to the buffer.
1974  */
1975 jerry_size_t
jerry_string_to_char_buffer(const jerry_value_t value,jerry_char_t * buffer_p,jerry_size_t buffer_size)1976 jerry_string_to_char_buffer (const jerry_value_t value, /**< input string value */
1977                              jerry_char_t *buffer_p, /**< [out] output characters buffer */
1978                              jerry_size_t buffer_size) /**< size of output buffer */
1979 {
1980   jerry_assert_api_available ();
1981 
1982   if (!ecma_is_value_string (value) || buffer_p == NULL)
1983   {
1984     return 0;
1985   }
1986 
1987   ecma_string_t *str_p = ecma_get_string_from_value (value);
1988 
1989   if (ecma_string_get_size (str_p) > buffer_size)
1990   {
1991     return 0;
1992   }
1993 
1994   return ecma_string_copy_to_cesu8_buffer (str_p,
1995                                            (lit_utf8_byte_t *) buffer_p,
1996                                            buffer_size);
1997 } /* jerry_string_to_char_buffer */
1998 
1999 /**
2000  * Copy the characters of an utf-8 encoded string into a specified buffer.
2001  *
2002  * Note:
2003  *      The '\0' character could occur anywhere in the returned string
2004  *      Returns 0, if the value parameter is not a string or the buffer
2005  *      is not large enough for the whole string.
2006  *
2007  * Note:
2008  *      If the size of the string in jerry value is larger than the size of the
2009  *      target buffer, the copy will fail.
2010  *      To copy a substring use jerry_substring_to_utf8_char_buffer() instead.
2011  *
2012  * @return number of bytes copied to the buffer.
2013  */
2014 jerry_size_t
jerry_string_to_utf8_char_buffer(const jerry_value_t value,jerry_char_t * buffer_p,jerry_size_t buffer_size)2015 jerry_string_to_utf8_char_buffer (const jerry_value_t value, /**< input string value */
2016                                   jerry_char_t *buffer_p, /**< [out] output characters buffer */
2017                                   jerry_size_t buffer_size) /**< size of output buffer */
2018 {
2019   jerry_assert_api_available ();
2020 
2021   if (!ecma_is_value_string (value) || buffer_p == NULL)
2022   {
2023     return 0;
2024   }
2025 
2026   ecma_string_t *str_p = ecma_get_string_from_value (value);
2027 
2028   if (ecma_string_get_utf8_size (str_p) > buffer_size)
2029   {
2030     return 0;
2031   }
2032 
2033   return ecma_string_copy_to_utf8_buffer (str_p,
2034                                           (lit_utf8_byte_t *) buffer_p,
2035                                           buffer_size);
2036 } /* jerry_string_to_utf8_char_buffer */
2037 
2038 /**
2039  * Copy the characters of an cesu-8 encoded substring into a specified buffer.
2040  *
2041  * Note:
2042  *      The '\0' character could occur anywhere in the returned string
2043  *      Returns 0, if the value parameter is not a string.
2044  *      It will extract the substring beetween the specified start position
2045  *      and the end position (or the end of the string, whichever comes first).
2046  *
2047  * @return number of bytes copied to the buffer.
2048  */
2049 jerry_size_t
jerry_substring_to_char_buffer(const jerry_value_t value,jerry_length_t start_pos,jerry_length_t end_pos,jerry_char_t * buffer_p,jerry_size_t buffer_size)2050 jerry_substring_to_char_buffer (const jerry_value_t value, /**< input string value */
2051                                 jerry_length_t start_pos, /**< position of the first character */
2052                                 jerry_length_t end_pos, /**< position of the last character */
2053                                 jerry_char_t *buffer_p, /**< [out] output characters buffer */
2054                                 jerry_size_t buffer_size) /**< size of output buffer */
2055 {
2056   jerry_assert_api_available ();
2057 
2058   if (!ecma_is_value_string (value) || buffer_p == NULL)
2059   {
2060     return 0;
2061   }
2062 
2063   ecma_string_t *str_p = ecma_get_string_from_value (value);
2064 
2065   return ecma_substring_copy_to_cesu8_buffer (str_p,
2066                                               start_pos,
2067                                               end_pos,
2068                                               (lit_utf8_byte_t *) buffer_p,
2069                                               buffer_size);
2070 } /* jerry_substring_to_char_buffer */
2071 
2072 /**
2073  * Copy the characters of an utf-8 encoded substring into a specified buffer.
2074  *
2075  * Note:
2076  *      The '\0' character could occur anywhere in the returned string
2077  *      Returns 0, if the value parameter is not a string.
2078  *      It will extract the substring beetween the specified start position
2079  *      and the end position (or the end of the string, whichever comes first).
2080  *
2081  * @return number of bytes copied to the buffer.
2082  */
2083 jerry_size_t
jerry_substring_to_utf8_char_buffer(const jerry_value_t value,jerry_length_t start_pos,jerry_length_t end_pos,jerry_char_t * buffer_p,jerry_size_t buffer_size)2084 jerry_substring_to_utf8_char_buffer (const jerry_value_t value, /**< input string value */
2085                                      jerry_length_t start_pos, /**< position of the first character */
2086                                      jerry_length_t end_pos, /**< position of the last character */
2087                                      jerry_char_t *buffer_p, /**< [out] output characters buffer */
2088                                      jerry_size_t buffer_size) /**< size of output buffer */
2089 {
2090   jerry_assert_api_available ();
2091 
2092   if (!ecma_is_value_string (value) || buffer_p == NULL)
2093   {
2094     return 0;
2095   }
2096 
2097   ecma_string_t *str_p = ecma_get_string_from_value (value);
2098 
2099   return ecma_substring_copy_to_utf8_buffer (str_p,
2100                                              start_pos,
2101                                              end_pos,
2102                                              (lit_utf8_byte_t *) buffer_p,
2103                                              buffer_size);
2104 } /* jerry_substring_to_utf8_char_buffer */
2105 
2106 /**
2107  * Checks whether the object or it's prototype objects have the given property.
2108  *
2109  * @return raised error - if the operation fail
2110  *         true/false API value  - depend on whether the property exists
2111  */
2112 jerry_value_t
jerry_has_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2113 jerry_has_property (const jerry_value_t obj_val, /**< object value */
2114                     const jerry_value_t prop_name_val) /**< property name (string value) */
2115 {
2116   jerry_assert_api_available ();
2117 
2118   if (!ecma_is_value_object (obj_val)
2119       || !ecma_is_value_prop_name (prop_name_val))
2120   {
2121     return ECMA_VALUE_FALSE;
2122   }
2123 
2124   return ecma_op_object_has_property (ecma_get_object_from_value (obj_val),
2125                                       ecma_get_prop_name_from_value (prop_name_val));
2126 } /* jerry_has_property */
2127 
2128 /**
2129  * Checks whether the object has the given property.
2130  *
2131  * @return ECMA_VALUE_ERROR - if the operation raises error
2132  *         ECMA_VALUE_{TRUE, FALSE} - based on whether the property exists
2133  */
2134 jerry_value_t
jerry_has_own_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2135 jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
2136                         const jerry_value_t prop_name_val) /**< property name (string value) */
2137 {
2138   jerry_assert_api_available ();
2139 
2140   if (!ecma_is_value_object (obj_val)
2141       || !ecma_is_value_prop_name (prop_name_val))
2142   {
2143     return ECMA_VALUE_FALSE;
2144   }
2145 
2146   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2147   ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val);
2148 
2149 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2150   if (ECMA_OBJECT_IS_PROXY (obj_p))
2151   {
2152     ecma_property_descriptor_t prop_desc;
2153 
2154     ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
2155 
2156     if (ecma_is_value_true (status))
2157     {
2158       ecma_free_property_descriptor (&prop_desc);
2159     }
2160 
2161     return jerry_return (status);
2162   }
2163 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2164 
2165   return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
2166 } /* jerry_has_own_property */
2167 
2168 /**
2169  * Checks whether the object has the given internal property.
2170  *
2171  * @return true  - if the internal property exists
2172  *         false - otherwise
2173  */
2174 bool
jerry_has_internal_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2175 jerry_has_internal_property (const jerry_value_t obj_val, /**< object value */
2176                              const jerry_value_t prop_name_val) /**< property name value */
2177 {
2178   jerry_assert_api_available ();
2179 
2180   if (!ecma_is_value_object (obj_val)
2181       || !ecma_is_value_prop_name (prop_name_val))
2182   {
2183     return false;
2184   }
2185 
2186   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2187 
2188   ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
2189 
2190   if (ecma_op_object_is_fast_array (obj_p))
2191   {
2192     return false;
2193   }
2194 
2195   ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
2196 
2197   if (property_p == NULL)
2198   {
2199     return false;
2200   }
2201 
2202   ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
2203   property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
2204 
2205   return property_p != NULL;
2206 } /* jerry_has_internal_property */
2207 
2208 /**
2209  * Delete a property from an object.
2210  *
2211  * @return true  - if property was deleted successfully
2212  *         false - otherwise
2213  */
2214 bool
jerry_delete_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2215 jerry_delete_property (const jerry_value_t obj_val, /**< object value */
2216                        const jerry_value_t prop_name_val) /**< property name (string value) */
2217 {
2218   jerry_assert_api_available ();
2219 
2220   if (!ecma_is_value_object (obj_val)
2221       || !ecma_is_value_prop_name (prop_name_val))
2222   {
2223     return false;
2224   }
2225 
2226   ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val),
2227                                                   ecma_get_prop_name_from_value (prop_name_val),
2228                                                   false);
2229 
2230 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2231   if (ECMA_IS_VALUE_ERROR (ret_value))
2232   {
2233     // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
2234     jcontext_release_exception ();
2235   }
2236 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2237 
2238   return ecma_is_value_true (ret_value);
2239 } /* jerry_delete_property */
2240 
2241 /**
2242  * Delete indexed property from the specified object.
2243  *
2244  * @return true  - if property was deleted successfully
2245  *         false - otherwise
2246  */
2247 bool
jerry_delete_property_by_index(const jerry_value_t obj_val,uint32_t index)2248 jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value */
2249                                 uint32_t index) /**< index to be written */
2250 {
2251   jerry_assert_api_available ();
2252 
2253   if (!ecma_is_value_object (obj_val))
2254   {
2255     return false;
2256   }
2257 
2258   ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
2259   ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val),
2260                                                   str_idx_p,
2261                                                   false);
2262   ecma_deref_ecma_string (str_idx_p);
2263 
2264 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2265   if (ECMA_IS_VALUE_ERROR (ret_value))
2266   {
2267     // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
2268     jcontext_release_exception ();
2269   }
2270 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2271 
2272   return ecma_is_value_true (ret_value);
2273 } /* jerry_delete_property_by_index */
2274 
2275 /**
2276  * Delete an internal property from an object.
2277  *
2278  * @return true  - if property was deleted successfully
2279  *         false - otherwise
2280  */
2281 bool
jerry_delete_internal_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2282 jerry_delete_internal_property (const jerry_value_t obj_val, /**< object value */
2283                                 const jerry_value_t prop_name_val) /**< property name value */
2284 {
2285   jerry_assert_api_available ();
2286 
2287   if (!ecma_is_value_object (obj_val)
2288       || !ecma_is_value_prop_name (prop_name_val))
2289   {
2290     return false;
2291   }
2292 
2293   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2294 
2295   ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
2296 
2297   if (ecma_op_object_is_fast_array (obj_p))
2298   {
2299     return true;
2300   }
2301 
2302   ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
2303 
2304   if (property_p == NULL)
2305   {
2306     return true;
2307   }
2308 
2309   ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
2310   property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
2311 
2312   if (property_p == NULL)
2313   {
2314     return true;
2315   }
2316 
2317   ecma_delete_property (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
2318 
2319   return true;
2320 } /* jerry_delete_internal_property */
2321 
2322 /**
2323  * Get value of a property to the specified object with the given name.
2324  *
2325  * Note:
2326  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2327  *
2328  * @return value of the property - if success
2329  *         value marked with error flag - otherwise
2330  */
2331 jerry_value_t
jerry_get_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2332 jerry_get_property (const jerry_value_t obj_val, /**< object value */
2333                     const jerry_value_t prop_name_val) /**< property name (string value) */
2334 {
2335   jerry_assert_api_available ();
2336 
2337   if (!ecma_is_value_object (obj_val)
2338       || !ecma_is_value_prop_name (prop_name_val))
2339   {
2340     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2341   }
2342 
2343   jerry_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_val),
2344                                                 ecma_get_prop_name_from_value (prop_name_val));
2345   return jerry_return (ret_value);
2346 } /* jerry_get_property */
2347 
2348 /**
2349  * Get value by an index from the specified object.
2350  *
2351  * Note:
2352  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2353  *
2354  * @return value of the property specified by the index - if success
2355  *         value marked with error flag - otherwise
2356  */
2357 jerry_value_t
jerry_get_property_by_index(const jerry_value_t obj_val,uint32_t index)2358 jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
2359                              uint32_t index) /**< index to be written */
2360 {
2361   jerry_assert_api_available ();
2362 
2363   if (!ecma_is_value_object (obj_val))
2364   {
2365     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2366   }
2367 
2368   ecma_value_t ret_value = ecma_op_object_get_by_uint32_index (ecma_get_object_from_value (obj_val), index);
2369 
2370   return jerry_return (ret_value);
2371 } /* jerry_get_property_by_index */
2372 
2373 /**
2374  * Get value of an internal property to the specified object with the given name.
2375  *
2376  * Note:
2377  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2378  *
2379  * @return value of the internal property - if the internal property exists
2380  *         undefined value - if the internal does not property exists
2381  *         value marked with error flag - otherwise
2382  */
2383 jerry_value_t
jerry_get_internal_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val)2384 jerry_get_internal_property (const jerry_value_t obj_val, /**< object value */
2385                              const jerry_value_t prop_name_val) /**< property name value */
2386 {
2387   jerry_assert_api_available ();
2388 
2389   if (!ecma_is_value_object (obj_val)
2390       || !ecma_is_value_prop_name (prop_name_val))
2391   {
2392     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2393   }
2394 
2395   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2396 
2397   ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
2398 
2399   if (ecma_op_object_is_fast_array (obj_p))
2400   {
2401     return jerry_return (ECMA_VALUE_UNDEFINED);
2402   }
2403 
2404   ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
2405 
2406   if (property_p == NULL)
2407   {
2408     return jerry_return (ECMA_VALUE_UNDEFINED);
2409   }
2410 
2411   ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
2412   property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
2413 
2414   if (property_p == NULL)
2415   {
2416     return jerry_return (ECMA_VALUE_UNDEFINED);
2417   }
2418 
2419   return jerry_return (ecma_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value));
2420 } /* jerry_get_internal_property */
2421 
2422 /**
2423  * Set a property to the specified object with the given name.
2424  *
2425  * Note:
2426  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2427  *
2428  * @return true value - if the operation was successful
2429  *         value marked with error flag - otherwise
2430  */
2431 jerry_value_t
jerry_set_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val,const jerry_value_t value_to_set)2432 jerry_set_property (const jerry_value_t obj_val, /**< object value */
2433                     const jerry_value_t prop_name_val, /**< property name (string value) */
2434                     const jerry_value_t value_to_set) /**< value to set */
2435 {
2436   jerry_assert_api_available ();
2437 
2438   if (ecma_is_value_error_reference (value_to_set)
2439       || !ecma_is_value_object (obj_val)
2440       || !ecma_is_value_prop_name (prop_name_val))
2441   {
2442     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2443   }
2444 
2445   return jerry_return (ecma_op_object_put (ecma_get_object_from_value (obj_val),
2446                                            ecma_get_prop_name_from_value (prop_name_val),
2447                                            value_to_set,
2448                                            true));
2449 } /* jerry_set_property */
2450 
2451 /**
2452  * Set indexed value in the specified object
2453  *
2454  * Note:
2455  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2456  *
2457  * @return true value - if the operation was successful
2458  *         value marked with error flag - otherwise
2459  */
2460 jerry_value_t
jerry_set_property_by_index(const jerry_value_t obj_val,uint32_t index,const jerry_value_t value_to_set)2461 jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */
2462                              uint32_t index, /**< index to be written */
2463                              const jerry_value_t value_to_set) /**< value to set */
2464 {
2465   jerry_assert_api_available ();
2466 
2467   if (ecma_is_value_error_reference (value_to_set)
2468       || !ecma_is_value_object (obj_val))
2469   {
2470     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2471   }
2472 
2473   ecma_value_t ret_value = ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (obj_val),
2474                                                                index,
2475                                                                value_to_set,
2476                                                                true);
2477 
2478   return jerry_return (ret_value);
2479 } /* jerry_set_property_by_index */
2480 
2481 /**
2482  * Set an internal property to the specified object with the given name.
2483  *
2484  * Note:
2485  *      - the property cannot be accessed from the JavaScript context, only from the public API
2486  *      - returned value must be freed with jerry_release_value, when it is no longer needed.
2487  *
2488  * @return true value - if the operation was successful
2489  *         value marked with error flag - otherwise
2490  */
2491 bool
jerry_set_internal_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val,const jerry_value_t value_to_set)2492 jerry_set_internal_property (const jerry_value_t obj_val, /**< object value */
2493                              const jerry_value_t prop_name_val, /**< property name value */
2494                              const jerry_value_t value_to_set) /**< value to set */
2495 {
2496   jerry_assert_api_available ();
2497 
2498   if (ecma_is_value_error_reference (value_to_set)
2499       || !ecma_is_value_object (obj_val)
2500       || !ecma_is_value_prop_name (prop_name_val))
2501   {
2502     return false;
2503   }
2504 
2505   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2506 
2507   ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
2508 
2509   if (ecma_op_object_is_fast_array (obj_p))
2510   {
2511     ecma_fast_array_convert_to_normal (obj_p);
2512   }
2513 
2514   ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
2515   ecma_object_t *internal_object_p;
2516 
2517   if (property_p == NULL)
2518   {
2519     ecma_property_value_t *value_p = ecma_create_named_data_property (obj_p,
2520                                                                       internal_string_p,
2521                                                                       ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
2522                                                                       NULL);
2523 
2524     internal_object_p = ecma_create_object (NULL,
2525                                             sizeof (ecma_extended_object_t),
2526                                             ECMA_OBJECT_TYPE_CLASS);
2527     {
2528       ecma_extended_object_t *container_p = (ecma_extended_object_t *) internal_object_p;
2529       container_p->u.class_prop.class_id = LIT_INTERNAL_MAGIC_STRING_INTERNAL_OBJECT;
2530       container_p->u.class_prop.extra_info = 0;
2531       container_p->u.class_prop.u.length = 0;
2532     }
2533 
2534     value_p->value = ecma_make_object_value (internal_object_p);
2535     ecma_deref_object (internal_object_p);
2536   }
2537   else
2538   {
2539     internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
2540   }
2541 
2542   ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val);
2543   property_p = ecma_find_named_property (internal_object_p, prop_name_p);
2544 
2545   if (property_p == NULL)
2546   {
2547     ecma_property_value_t *value_p = ecma_create_named_data_property (internal_object_p,
2548                                                                       prop_name_p,
2549                                                                       ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
2550                                                                       NULL);
2551 
2552     value_p->value = ecma_copy_value_if_not_object (value_to_set);
2553   }
2554   else
2555   {
2556     ecma_named_data_property_assign_value (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value_to_set);
2557   }
2558 
2559   return true;
2560 } /* jerry_set_internal_property */
2561 
2562 /**
2563  * Initialize property descriptor.
2564  */
2565 void
jerry_init_property_descriptor_fields(jerry_property_descriptor_t * prop_desc_p)2566 jerry_init_property_descriptor_fields (jerry_property_descriptor_t *prop_desc_p) /**< [out] property descriptor */
2567 {
2568   prop_desc_p->is_value_defined = false;
2569   prop_desc_p->value = ECMA_VALUE_UNDEFINED;
2570   prop_desc_p->is_writable_defined = false;
2571   prop_desc_p->is_writable = false;
2572   prop_desc_p->is_enumerable_defined = false;
2573   prop_desc_p->is_enumerable = false;
2574   prop_desc_p->is_configurable_defined = false;
2575   prop_desc_p->is_configurable = false;
2576   prop_desc_p->is_get_defined = false;
2577   prop_desc_p->getter = ECMA_VALUE_UNDEFINED;
2578   prop_desc_p->is_set_defined = false;
2579   prop_desc_p->setter = ECMA_VALUE_UNDEFINED;
2580 } /* jerry_init_property_descriptor_fields */
2581 
2582 /**
2583  * Define a property to the specified object with the given name.
2584  *
2585  * Note:
2586  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2587  *
2588  * @return true value - if the operation was successful
2589  *         value marked with error flag - otherwise
2590  */
2591 jerry_value_t
jerry_define_own_property(const jerry_value_t obj_val,const jerry_value_t prop_name_val,const jerry_property_descriptor_t * prop_desc_p)2592 jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
2593                            const jerry_value_t prop_name_val, /**< property name (string value) */
2594                            const jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */
2595 {
2596   jerry_assert_api_available ();
2597 
2598   if (!ecma_is_value_object (obj_val)
2599       || !ecma_is_value_prop_name (prop_name_val))
2600   {
2601     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2602   }
2603 
2604   if ((prop_desc_p->is_writable_defined || prop_desc_p->is_value_defined)
2605       && (prop_desc_p->is_get_defined || prop_desc_p->is_set_defined))
2606   {
2607     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2608   }
2609 
2610   ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
2611 
2612   uint32_t flags = ECMA_PROP_NO_OPTS;
2613 
2614   if (prop_desc_p->is_enumerable_defined)
2615   {
2616     flags |= (uint32_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | (prop_desc_p->is_enumerable ? ECMA_PROP_IS_ENUMERABLE
2617                                                                                        : ECMA_PROP_NO_OPTS));
2618   }
2619 
2620   if (prop_desc_p->is_configurable_defined)
2621   {
2622     flags |= (uint32_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | (prop_desc_p->is_configurable ? ECMA_PROP_IS_CONFIGURABLE
2623                                                                                            : ECMA_PROP_NO_OPTS));
2624   }
2625 
2626   /* Copy data property info. */
2627   flags |= (prop_desc_p->is_value_defined ? ECMA_PROP_IS_VALUE_DEFINED : ECMA_PROP_NO_OPTS);
2628 
2629   if (prop_desc_p->is_value_defined)
2630   {
2631     if (ecma_is_value_error_reference (prop_desc_p->value))
2632     {
2633       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2634     }
2635 
2636     prop_desc.value = prop_desc_p->value;
2637   }
2638 
2639   if (prop_desc_p->is_writable_defined)
2640   {
2641     flags |= (uint32_t) (ECMA_PROP_IS_WRITABLE_DEFINED | (prop_desc_p->is_writable ? ECMA_PROP_IS_WRITABLE
2642                                                                                    : ECMA_PROP_NO_OPTS));
2643   }
2644 
2645   /* Copy accessor property info. */
2646   if (prop_desc_p->is_get_defined)
2647   {
2648     ecma_value_t getter = prop_desc_p->getter;
2649     flags |= ECMA_PROP_IS_GET_DEFINED;
2650 
2651     if (ecma_is_value_error_reference (getter))
2652     {
2653       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2654     }
2655 
2656     if (ecma_op_is_callable (getter))
2657     {
2658       prop_desc.get_p = ecma_get_object_from_value (getter);
2659     }
2660     else if (!ecma_is_value_null (getter))
2661     {
2662       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2663     }
2664   }
2665 
2666   if (prop_desc_p->is_set_defined)
2667   {
2668     ecma_value_t setter = prop_desc_p->setter;
2669     flags |= ECMA_PROP_IS_SET_DEFINED;
2670 
2671     if (ecma_is_value_error_reference (setter))
2672     {
2673       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2674     }
2675 
2676     if (ecma_op_is_callable (setter))
2677     {
2678       prop_desc.set_p = ecma_get_object_from_value (setter);
2679     }
2680     else if (!ecma_is_value_null (setter))
2681     {
2682       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2683     }
2684   }
2685 
2686   prop_desc.flags |= (uint16_t) (flags | ECMA_PROP_IS_THROW);
2687 
2688   return ecma_op_object_define_own_property (ecma_get_object_from_value (obj_val),
2689                                              ecma_get_prop_name_from_value (prop_name_val),
2690                                              &prop_desc);
2691 } /* jerry_define_own_property */
2692 
2693 /**
2694  * Construct property descriptor from specified property.
2695  *
2696  * @return true - if success, the prop_desc_p fields contains the property info
2697  *         false - otherwise, the prop_desc_p is unchanged
2698  */
2699 bool
jerry_get_own_property_descriptor(const jerry_value_t obj_val,const jerry_value_t prop_name_val,jerry_property_descriptor_t * prop_desc_p)2700 jerry_get_own_property_descriptor (const jerry_value_t  obj_val, /**< object value */
2701                                    const jerry_value_t prop_name_val, /**< property name (string value) */
2702                                    jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */
2703 {
2704   jerry_assert_api_available ();
2705 
2706   if (!ecma_is_value_object (obj_val)
2707       || !ecma_is_value_prop_name (prop_name_val))
2708   {
2709     return false;
2710   }
2711 
2712   ecma_property_descriptor_t prop_desc;
2713 
2714   ecma_value_t status = ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val),
2715                                                                     ecma_get_prop_name_from_value (prop_name_val),
2716                                                                     &prop_desc);
2717 
2718 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2719   if (ECMA_IS_VALUE_ERROR (status))
2720   {
2721     // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
2722     jcontext_release_exception ();
2723   }
2724 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2725 
2726   if (!ecma_is_value_true (status))
2727   {
2728     return false;
2729   }
2730 
2731   prop_desc_p->is_configurable_defined = true;
2732   prop_desc_p->is_configurable = (prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE) != 0;
2733   prop_desc_p->is_enumerable_defined = true;
2734   prop_desc_p->is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) != 0;
2735 
2736   prop_desc_p->is_writable_defined = (prop_desc.flags & ECMA_PROP_IS_WRITABLE_DEFINED) != 0;
2737   prop_desc_p->is_writable = prop_desc_p->is_writable_defined ? (prop_desc.flags & ECMA_PROP_IS_WRITABLE) != 0 : false;
2738 
2739   prop_desc_p->is_value_defined = (prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED) != 0;
2740   prop_desc_p->is_get_defined = (prop_desc.flags & ECMA_PROP_IS_GET_DEFINED) != 0;
2741   prop_desc_p->is_set_defined = (prop_desc.flags & ECMA_PROP_IS_SET_DEFINED) != 0;
2742 
2743   prop_desc_p->value = ECMA_VALUE_UNDEFINED;
2744   prop_desc_p->getter = ECMA_VALUE_UNDEFINED;
2745   prop_desc_p->setter = ECMA_VALUE_UNDEFINED;
2746 
2747   if (prop_desc_p->is_value_defined)
2748   {
2749     prop_desc_p->value = prop_desc.value;
2750   }
2751 
2752   if (prop_desc_p->is_get_defined)
2753   {
2754     if (prop_desc.get_p != NULL)
2755     {
2756       prop_desc_p->getter = ecma_make_object_value (prop_desc.get_p);
2757     }
2758     else
2759     {
2760       prop_desc_p->getter = ECMA_VALUE_NULL;
2761     }
2762   }
2763 
2764   if (prop_desc_p->is_set_defined)
2765   {
2766     if (prop_desc.set_p != NULL)
2767     {
2768       prop_desc_p->setter = ecma_make_object_value (prop_desc.set_p);
2769     }
2770     else
2771     {
2772       prop_desc_p->setter = ECMA_VALUE_NULL;
2773     }
2774   }
2775 
2776   return true;
2777 } /* jerry_get_own_property_descriptor */
2778 
2779 /**
2780  * Free fields of property descriptor (setter, getter and value).
2781  */
2782 void
jerry_free_property_descriptor_fields(const jerry_property_descriptor_t * prop_desc_p)2783 jerry_free_property_descriptor_fields (const jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */
2784 {
2785   if (prop_desc_p->is_value_defined)
2786   {
2787     jerry_release_value (prop_desc_p->value);
2788   }
2789 
2790   if (prop_desc_p->is_get_defined)
2791   {
2792     jerry_release_value (prop_desc_p->getter);
2793   }
2794 
2795   if (prop_desc_p->is_set_defined)
2796   {
2797     jerry_release_value (prop_desc_p->setter);
2798   }
2799 } /* jerry_free_property_descriptor_fields */
2800 
2801 /**
2802  * Invoke function specified by a function value
2803  *
2804  * Note:
2805  *      - returned value must be freed with jerry_release_value, when it is no longer needed.
2806  *      - If function is invoked as constructor, it should support [[Construct]] method,
2807  *        otherwise, if function is simply called - it should support [[Call]] method.
2808  *
2809  * @return returned jerry value of the invoked function
2810  */
2811 static jerry_value_t
jerry_invoke_function(bool is_invoke_as_constructor,const jerry_value_t func_obj_val,const jerry_value_t this_val,const jerry_value_t args_p[],const jerry_size_t args_count)2812 jerry_invoke_function (bool is_invoke_as_constructor, /**< true - invoke function as constructor
2813                                                        *          (this_arg_p should be NULL, as it is ignored),
2814                                                        *   false - perform function call */
2815                        const jerry_value_t func_obj_val, /**< function object to call */
2816                        const jerry_value_t this_val, /**< object value of 'this' binding */
2817                        const jerry_value_t args_p[], /**< function's call arguments */
2818                        const jerry_size_t args_count) /**< number of the arguments */
2819 {
2820   JERRY_ASSERT (args_count == 0 || args_p != NULL);
2821 
2822   if (ecma_is_value_error_reference (func_obj_val)
2823       || ecma_is_value_error_reference (this_val))
2824   {
2825     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2826   }
2827 
2828   for (uint32_t i = 0; i < args_count; i++)
2829   {
2830     if (ecma_is_value_error_reference (args_p[i]))
2831     {
2832       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2833     }
2834   }
2835 
2836   if (is_invoke_as_constructor)
2837   {
2838     JERRY_ASSERT (jerry_value_is_constructor (func_obj_val));
2839 
2840     return jerry_return (ecma_op_function_construct (ecma_get_object_from_value (func_obj_val),
2841                                                      ecma_get_object_from_value (func_obj_val),
2842                                                      args_p,
2843                                                      args_count));
2844   }
2845   else
2846   {
2847     JERRY_ASSERT (jerry_value_is_function (func_obj_val));
2848 
2849     return jerry_return (ecma_op_function_call (ecma_get_object_from_value (func_obj_val),
2850                                                 this_val,
2851                                                 args_p,
2852                                                 args_count));
2853   }
2854 } /* jerry_invoke_function */
2855 
2856 /**
2857  * Call function specified by a function value
2858  *
2859  * Note:
2860  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2861  *      error flag must not be set for any arguments of this function.
2862  *
2863  * @return returned jerry value of the called function
2864  */
2865 jerry_value_t
jerry_call_function(const jerry_value_t func_obj_val,const jerry_value_t this_val,const jerry_value_t args_p[],jerry_size_t args_count)2866 jerry_call_function (const jerry_value_t func_obj_val, /**< function object to call */
2867                      const jerry_value_t this_val, /**< object for 'this' binding */
2868                      const jerry_value_t args_p[], /**< function's call arguments */
2869                      jerry_size_t args_count) /**< number of the arguments */
2870 {
2871   jerry_assert_api_available ();
2872 
2873 #if ENABLED (JERRY_DEBUGGER)
2874   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) {
2875     if (jerry_debugger_receive (NULL)) {
2876       JERRY_DEBUG_MSG ("resume");
2877     }
2878   }
2879 #endif
2880 
2881   if (jerry_value_is_function (func_obj_val) && !ecma_is_value_error_reference (this_val))
2882   {
2883     for (jerry_size_t i = 0; i < args_count; i++)
2884     {
2885       if (ecma_is_value_error_reference (args_p[i]))
2886       {
2887         return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2888       }
2889     }
2890 
2891     return jerry_invoke_function (false, func_obj_val, this_val, args_p, args_count);
2892   }
2893 
2894   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2895 } /* jerry_call_function */
2896 
2897 /**
2898  * Construct object value invoking specified function value as a constructor
2899  *
2900  * Note:
2901  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2902  *      error flag must not be set for any arguments of this function.
2903  *
2904  * @return returned jerry value of the invoked constructor
2905  */
2906 jerry_value_t
jerry_construct_object(const jerry_value_t func_obj_val,const jerry_value_t args_p[],jerry_size_t args_count)2907 jerry_construct_object (const jerry_value_t func_obj_val, /**< function object to call */
2908                         const jerry_value_t args_p[], /**< function's call arguments
2909                                                        *   (NULL if arguments number is zero) */
2910                         jerry_size_t args_count) /**< number of the arguments */
2911 {
2912   jerry_assert_api_available ();
2913 
2914   if (jerry_value_is_constructor (func_obj_val))
2915   {
2916     for (jerry_size_t i = 0; i < args_count; i++)
2917     {
2918       if (ecma_is_value_error_reference (args_p[i]))
2919       {
2920         return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2921       }
2922     }
2923 
2924     ecma_value_t this_val = ECMA_VALUE_UNDEFINED;
2925     return jerry_invoke_function (true, func_obj_val, this_val, args_p, args_count);
2926   }
2927 
2928   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2929 } /* jerry_construct_object */
2930 
2931 /**
2932  * Get keys of the specified object value
2933  *
2934  * Note:
2935  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2936  *
2937  * @return array object value - if success
2938  *         value marked with error flag - otherwise
2939  */
2940 jerry_value_t
jerry_get_object_keys(const jerry_value_t obj_val)2941 jerry_get_object_keys (const jerry_value_t obj_val) /**< object value */
2942 {
2943   jerry_assert_api_available ();
2944 
2945   if (!ecma_is_value_object (obj_val))
2946   {
2947     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2948   }
2949 
2950   return ecma_builtin_helper_object_get_properties (ecma_get_object_from_value (obj_val),
2951                                                     ECMA_LIST_ENUMERABLE);
2952 } /* jerry_get_object_keys */
2953 
2954 /**
2955  * Get the prototype of the specified object
2956  *
2957  * Note:
2958  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2959  *
2960  * @return prototype object or null value - if success
2961  *         value marked with error flag - otherwise
2962  */
2963 jerry_value_t
jerry_get_prototype(const jerry_value_t obj_val)2964 jerry_get_prototype (const jerry_value_t obj_val) /**< object value */
2965 {
2966   jerry_assert_api_available ();
2967 
2968   if (!ecma_is_value_object (obj_val))
2969   {
2970     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2971   }
2972 
2973   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2974 
2975 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2976   if (ECMA_OBJECT_IS_PROXY (obj_p))
2977   {
2978     return jerry_return (ecma_proxy_object_get_prototype_of (obj_p));
2979   }
2980 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2981 
2982   if (obj_p->u2.prototype_cp == JMEM_CP_NULL)
2983   {
2984     return ECMA_VALUE_NULL;
2985   }
2986 
2987   ecma_object_t *proto_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp);
2988   ecma_ref_object (proto_obj_p);
2989 
2990   return ecma_make_object_value (proto_obj_p);
2991 } /* jerry_get_prototype */
2992 
2993 /**
2994  * Set the prototype of the specified object
2995  *
2996  * @return true value - if success
2997  *         value marked with error flag - otherwise
2998  */
2999 jerry_value_t
jerry_set_prototype(const jerry_value_t obj_val,const jerry_value_t proto_obj_val)3000 jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
3001                      const jerry_value_t proto_obj_val) /**< prototype object value */
3002 {
3003   jerry_assert_api_available ();
3004 
3005   if (!ecma_is_value_object (obj_val)
3006       || ecma_is_value_error_reference (proto_obj_val)
3007       || (!ecma_is_value_object (proto_obj_val) && !ecma_is_value_null (proto_obj_val)))
3008   {
3009     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3010   }
3011   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
3012 
3013 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
3014   if (ECMA_OBJECT_IS_PROXY (obj_p))
3015   {
3016     return jerry_return (ecma_proxy_object_set_prototype_of (obj_p, proto_obj_val));
3017   }
3018 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
3019 
3020   return ecma_op_ordinary_object_set_prototype_of (obj_p, proto_obj_val);
3021 } /* jerry_set_prototype */
3022 
3023 /**
3024  * Utility to check if a given object can be used for the foreach api calls.
3025  *
3026  * Some objects/classes uses extra internal objects to correctly store data.
3027  * These extre object should never be exposed externally to the API user.
3028  *
3029  * @returns true - if the user can access the object in the callback.
3030  *          false - if the object is an internal object which should no be accessed by the user.
3031  */
3032 static
jerry_object_is_valid_foreach(ecma_object_t * object_p)3033 bool jerry_object_is_valid_foreach (ecma_object_t *object_p) /**< object to test */
3034 {
3035   if (ecma_is_lexical_environment (object_p))
3036   {
3037     return false;
3038   }
3039 
3040   ecma_object_type_t object_type = ecma_get_object_type (object_p);
3041 
3042   if (object_type == ECMA_OBJECT_TYPE_CLASS)
3043   {
3044     ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
3045     switch (ext_object_p->u.class_prop.class_id)
3046     {
3047       /* An object's internal property object should not be iterable by foreach. */
3048       case LIT_INTERNAL_MAGIC_STRING_INTERNAL_OBJECT: return false;
3049     }
3050   }
3051 
3052   return true;
3053 } /* jerry_object_is_valid_foreach */
3054 
3055 /**
3056  * Traverse objects.
3057  *
3058  * @return true - traversal was interrupted by the callback.
3059  *         false - otherwise - traversal visited all objects.
3060  */
3061 bool
jerry_objects_foreach(jerry_objects_foreach_t foreach_p,void * user_data_p)3062 jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer of the iterator function */
3063                        void *user_data_p) /**< pointer to user data */
3064 {
3065   jerry_assert_api_available ();
3066 
3067   JERRY_ASSERT (foreach_p != NULL);
3068 
3069   jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
3070 
3071   while (iter_cp != JMEM_CP_NULL)
3072   {
3073     ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
3074 
3075     if (jerry_object_is_valid_foreach (iter_p)
3076         && !foreach_p (ecma_make_object_value (iter_p), user_data_p))
3077     {
3078       return true;
3079     }
3080 
3081     iter_cp = iter_p->gc_next_cp;
3082   }
3083 
3084   return false;
3085 } /* jerry_objects_foreach */
3086 
3087 /**
3088  * Traverse objects having a given native type info.
3089  *
3090  * @return true - traversal was interrupted by the callback.
3091  *         false - otherwise - traversal visited all objects.
3092  */
3093 bool
jerry_objects_foreach_by_native_info(const jerry_object_native_info_t * native_info_p,jerry_objects_foreach_by_native_info_t foreach_p,void * user_data_p)3094 jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p, /**< the type info
3095                                                                                         *   of the native pointer */
3096                                       jerry_objects_foreach_by_native_info_t foreach_p, /**< function to apply for
3097                                                                                          *   each matching object */
3098                                       void *user_data_p) /**< pointer to user data */
3099 {
3100   jerry_assert_api_available ();
3101 
3102   JERRY_ASSERT (native_info_p != NULL);
3103   JERRY_ASSERT (foreach_p != NULL);
3104 
3105   ecma_native_pointer_t *native_pointer_p;
3106 
3107   jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
3108 
3109   while (iter_cp != JMEM_CP_NULL)
3110   {
3111     ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
3112 
3113     if (jerry_object_is_valid_foreach (iter_p))
3114     {
3115       native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p);
3116       if (native_pointer_p
3117           && !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p))
3118       {
3119         return true;
3120       }
3121     }
3122 
3123     iter_cp = iter_p->gc_next_cp;
3124   }
3125 
3126   return false;
3127 } /* jerry_objects_foreach_by_native_info */
3128 
3129 /**
3130  * Get native pointer and its type information, associated with the given native type info.
3131  *
3132  * Note:
3133  *  If native pointer is present, its type information is returned in out_native_pointer_p
3134  *
3135  * @return true - if there is an associated pointer,
3136  *         false - otherwise
3137  */
3138 bool
jerry_get_object_native_pointer(const jerry_value_t obj_val,void ** out_native_pointer_p,const jerry_object_native_info_t * native_info_p)3139 jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get native pointer from */
3140                                  void **out_native_pointer_p, /**< [out] native pointer */
3141                                  const jerry_object_native_info_t *native_info_p) /**< the type info
3142                                                                                    *   of the native pointer */
3143 {
3144   jerry_assert_api_available ();
3145 
3146   if (!ecma_is_value_object (obj_val))
3147   {
3148     return false;
3149   }
3150 
3151   ecma_native_pointer_t *native_pointer_p;
3152   native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val), (void *) native_info_p);
3153 
3154   if (native_pointer_p == NULL)
3155   {
3156     return false;
3157   }
3158 
3159   if (out_native_pointer_p != NULL)
3160   {
3161     *out_native_pointer_p = native_pointer_p->data_p;
3162   }
3163 
3164   return true;
3165 } /* jerry_get_object_native_pointer */
3166 
3167 /**
3168  * Set native pointer and an optional type info for the specified object.
3169  *
3170  *
3171  * Note:
3172  *      If native pointer was already set for the object, its value is updated.
3173  *
3174  * Note:
3175  *      If a non-NULL free callback is specified in the native type info,
3176  *      it will be called by the garbage collector when the object is freed.
3177  *      Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)
3178  *      The type info always overwrites the previous value, so passing
3179  *      a NULL value deletes the current type info.
3180  */
3181 void
jerry_set_object_native_pointer(const jerry_value_t obj_val,void * native_pointer_p,const jerry_object_native_info_t * native_info_p)3182 jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set native pointer in */
3183                                  void *native_pointer_p, /**< native pointer */
3184                                  const jerry_object_native_info_t *native_info_p) /**< object's native type info */
3185 {
3186   jerry_assert_api_available ();
3187 
3188   if (ecma_is_value_object (obj_val))
3189   {
3190     ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3191 
3192     ecma_create_native_pointer_property (object_p, native_pointer_p, (void *) native_info_p);
3193   }
3194 } /* jerry_set_object_native_pointer */
3195 
3196 /**
3197  * Delete the previously set native pointer by the native type info from the specified object.
3198  *
3199  * Note:
3200  *      If the specified object has no matching native pointer for the given native type info
3201  *      the function has no effect.
3202  *
3203  * Note:
3204  *      This operation cannot throw an exception.
3205  *
3206  * @return true - if the native pointer has been deleted succesfully
3207  *         false - otherwise
3208  */
3209 bool
jerry_delete_object_native_pointer(const jerry_value_t obj_val,const jerry_object_native_info_t * native_info_p)3210 jerry_delete_object_native_pointer (const jerry_value_t obj_val, /**< object to delete native pointer from */
3211                                     const jerry_object_native_info_t *native_info_p) /**< object's native type info */
3212 {
3213   jerry_assert_api_available ();
3214 
3215   if (ecma_is_value_object (obj_val))
3216   {
3217     ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3218 
3219     return ecma_delete_native_pointer_property (object_p, (void *) native_info_p);
3220   }
3221 
3222   return false;
3223 } /* jerry_delete_object_native_pointer */
3224 
3225 /**
3226  * Applies the given function to the every property in the object.
3227  *
3228  * @return true - if object fields traversal was performed successfully, i.e.:
3229  *                - no unhandled exceptions were thrown in object fields traversal;
3230  *                - object fields traversal was stopped on callback that returned false;
3231  *         false - otherwise,
3232  *                 if getter of field threw a exception or unhandled exceptions were thrown during traversal;
3233  */
3234 bool
jerry_foreach_object_property(const jerry_value_t obj_val,jerry_object_property_foreach_t foreach_p,void * user_data_p)3235 jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
3236                                jerry_object_property_foreach_t foreach_p, /**< foreach function */
3237                                void *user_data_p) /**< user data for foreach function */
3238 {
3239   jerry_assert_api_available ();
3240 
3241   if (!ecma_is_value_object (obj_val))
3242   {
3243     return false;
3244   }
3245 
3246   ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3247   ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
3248 
3249 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
3250   if (names_p == NULL)
3251   {
3252     // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
3253     jcontext_release_exception ();
3254     return false;
3255   }
3256 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
3257 
3258   ecma_value_t *buffer_p = names_p->buffer_p;
3259 
3260   ecma_value_t property_value = ECMA_VALUE_EMPTY;
3261 
3262   bool continuous = true;
3263 
3264   for (uint32_t i = 0; continuous && (i < names_p->item_count); i++)
3265   {
3266     ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
3267 
3268     property_value = ecma_op_object_get (object_p, property_name_p);
3269 
3270     if (ECMA_IS_VALUE_ERROR (property_value))
3271     {
3272       break;
3273     }
3274 
3275     continuous = foreach_p (buffer_p[i], property_value, user_data_p);
3276     ecma_free_value (property_value);
3277   }
3278 
3279   ecma_collection_free (names_p);
3280 
3281   if (!ECMA_IS_VALUE_ERROR (property_value))
3282   {
3283     return true;
3284   }
3285 
3286   jcontext_release_exception ();
3287   return false;
3288 } /* jerry_foreach_object_property */
3289 
3290 /**
3291  * Resolve or reject the promise with an argument.
3292  *
3293  * @return undefined value - if success
3294  *         value marked with error flag - otherwise
3295  */
3296 jerry_value_t
jerry_resolve_or_reject_promise(jerry_value_t promise,jerry_value_t argument,bool is_resolve)3297 jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value */
3298                                  jerry_value_t argument, /**< the argument */
3299                                  bool is_resolve) /**< whether the promise should be resolved or rejected */
3300 {
3301   jerry_assert_api_available ();
3302 
3303 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3304   if (!ecma_is_value_object (promise) || !ecma_is_promise (ecma_get_object_from_value (promise)))
3305   {
3306     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3307   }
3308 
3309   if (ecma_is_value_error_reference (argument))
3310   {
3311     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
3312   }
3313 
3314   lit_magic_string_id_t prop_name = (is_resolve ? LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION
3315                                                 : LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
3316 
3317   ecma_value_t function = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (promise), prop_name);
3318 
3319   ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function),
3320                                             ECMA_VALUE_UNDEFINED,
3321                                             &argument,
3322                                             1);
3323 
3324   ecma_free_value (function);
3325 
3326   return ret;
3327 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3328   JERRY_UNUSED (promise);
3329   JERRY_UNUSED (argument);
3330   JERRY_UNUSED (is_resolve);
3331 
3332   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported.")));
3333 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3334 } /* jerry_resolve_or_reject_promise */
3335 
3336 /**
3337  * Get the result of a promise.
3338  *
3339  * @return - Promise result
3340  *         - Type error if the promise support was not enabled or the input was not a promise object
3341  */
3342 jerry_value_t
jerry_get_promise_result(const jerry_value_t promise)3343 jerry_get_promise_result (const jerry_value_t promise) /**< promise object to get the result from */
3344 {
3345   jerry_assert_api_available ();
3346 
3347 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3348   if (!jerry_value_is_promise (promise))
3349   {
3350     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3351   }
3352 
3353   return ecma_promise_get_result (ecma_get_object_from_value (promise));
3354 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3355   JERRY_UNUSED (promise);
3356   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported.")));
3357 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3358 } /* jerry_get_promise_result */
3359 
3360 /**
3361  * Get the state of a promise object.
3362  *
3363  * @return - the state of the promise (one of the jerry_promise_state_t enum values)
3364  *         - JERRY_PROMISE_STATE_NONE is only returned if the input is not a promise object
3365  *           or the promise support was not enabled.
3366  */
3367 jerry_promise_state_t
jerry_get_promise_state(const jerry_value_t promise)3368 jerry_get_promise_state (const jerry_value_t promise) /**< promise object to get the state from */
3369 {
3370   jerry_assert_api_available ();
3371 
3372 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3373   if (!jerry_value_is_promise (promise))
3374   {
3375     return JERRY_PROMISE_STATE_NONE;
3376   }
3377 
3378   uint16_t flags = ecma_promise_get_flags (ecma_get_object_from_value (promise));
3379   flags &= (ECMA_PROMISE_IS_PENDING | ECMA_PROMISE_IS_FULFILLED);
3380 
3381   return (flags ? flags : JERRY_PROMISE_STATE_REJECTED);
3382 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3383   JERRY_UNUSED (promise);
3384   return JERRY_PROMISE_STATE_NONE;
3385 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3386 } /* jerry_get_promise_state */
3387 
3388 /**
3389  * Call the SymbolDescriptiveString ecma builtin operation on the symbol value.
3390  *
3391  * Note:
3392  *      returned value must be freed with jerry_release_value, when it is no longer needed.
3393  *
3394  * @return string value containing the symbol's descriptive string - if success
3395  *         thrown error - otherwise
3396  */
3397 jerry_value_t
jerry_get_symbol_descriptive_string(const jerry_value_t symbol)3398 jerry_get_symbol_descriptive_string (const jerry_value_t symbol) /**< symbol value */
3399 {
3400   jerry_assert_api_available ();
3401 
3402 #if ENABLED (JERRY_ES2015)
3403   if (!ecma_is_value_symbol (symbol))
3404   {
3405     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3406   }
3407 
3408   /* Note: This operation cannot throw an error */
3409   return ecma_get_symbol_descriptive_string (symbol);
3410 #else /* !ENABLED (JERRY_ES2015) */
3411   JERRY_UNUSED (symbol);
3412 
3413   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Symbol is not supported.")));
3414 #endif /* ENABLED (JERRY_ES2015) */
3415 } /** jerry_get_symbol_descriptive_string */
3416 
3417 /**
3418  * Validate UTF-8 string
3419  *
3420  * @return true - if UTF-8 string is well-formed
3421  *         false - otherwise
3422  */
3423 bool
jerry_is_valid_utf8_string(const jerry_char_t * utf8_buf_p,jerry_size_t buf_size)3424 jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */
3425                             jerry_size_t buf_size) /**< string size */
3426 {
3427   return lit_is_valid_utf8_string ((lit_utf8_byte_t *) utf8_buf_p,
3428                                    (lit_utf8_size_t) buf_size);
3429 } /* jerry_is_valid_utf8_string */
3430 
3431 /**
3432  * Validate CESU-8 string
3433  *
3434  * @return true - if CESU-8 string is well-formed
3435  *         false - otherwise
3436  */
3437 bool
jerry_is_valid_cesu8_string(const jerry_char_t * cesu8_buf_p,jerry_size_t buf_size)3438 jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string */
3439                              jerry_size_t buf_size) /**< string size */
3440 {
3441   return lit_is_valid_cesu8_string ((lit_utf8_byte_t *) cesu8_buf_p,
3442                                     (lit_utf8_size_t) buf_size);
3443 } /* jerry_is_valid_cesu8_string */
3444 
3445 /**
3446  * Allocate memory on the engine's heap.
3447  *
3448  * Note:
3449  *      This function may take away memory from the executed JavaScript code.
3450  *      If any other dynamic memory allocation API is available (e.g., libc
3451  *      malloc), it should be used instead.
3452  *
3453  * @return allocated memory on success
3454  *         NULL otherwise
3455  */
3456 void *
jerry_heap_alloc(size_t size)3457 jerry_heap_alloc (size_t size) /**< size of the memory block */
3458 {
3459   jerry_assert_api_available ();
3460 
3461   return jmem_heap_alloc_block_null_on_error (size);
3462 } /* jerry_heap_alloc */
3463 
3464 /**
3465  * Free memory allocated on the engine's heap.
3466  */
3467 void
jerry_heap_free(void * mem_p,size_t size)3468 jerry_heap_free (void *mem_p, /**< value returned by jerry_heap_alloc */
3469                  size_t size) /**< same size as passed to jerry_heap_alloc */
3470 {
3471   jerry_assert_api_available ();
3472 
3473   jmem_heap_free_block (mem_p, size);
3474 } /* jerry_heap_free */
3475 
3476 /**
3477  * Create an external engine context.
3478  *
3479  * @return the pointer to the context.
3480  */
3481 jerry_context_t *
jerry_create_context(uint32_t heap_size,jerry_context_alloc_t alloc,void * cb_data_p)3482 jerry_create_context (uint32_t heap_size, /**< the size of heap */
3483                       jerry_context_alloc_t alloc, /**< the alloc function */
3484                       void *cb_data_p) /**< the cb_data for alloc function */
3485 {
3486   JERRY_UNUSED (heap_size);
3487 
3488 #if ENABLED (JERRY_EXTERNAL_CONTEXT)
3489 
3490   size_t total_size = sizeof (jerry_context_t) + JMEM_ALIGNMENT;
3491 
3492 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
3493   heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT);
3494 
3495   /* Minimum heap size is 1Kbyte. */
3496   if (heap_size < 1024)
3497   {
3498     return NULL;
3499   }
3500 
3501   total_size += heap_size;
3502 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
3503 
3504   total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
3505 
3506   jerry_context_t *context_p = (jerry_context_t *) alloc (total_size, cb_data_p);
3507 
3508   if (context_p == NULL)
3509   {
3510     return NULL;
3511   }
3512 
3513   memset (context_p, 0, total_size);
3514 
3515   uintptr_t context_ptr = ((uintptr_t) context_p) + sizeof (jerry_context_t);
3516   context_ptr = JERRY_ALIGNUP (context_ptr, (uintptr_t) JMEM_ALIGNMENT);
3517 
3518   uint8_t *byte_p = (uint8_t *) context_ptr;
3519 
3520 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
3521   context_p->heap_p = (jmem_heap_t *) byte_p;
3522   context_p->heap_size = heap_size;
3523   byte_p += heap_size;
3524 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
3525 
3526   JERRY_ASSERT (byte_p <= ((uint8_t *) context_p) + total_size);
3527 
3528   JERRY_UNUSED (byte_p);
3529   return context_p;
3530 
3531 #else /* !ENABLED (JERRY_EXTERNAL_CONTEXT) */
3532 
3533   JERRY_UNUSED (alloc);
3534   JERRY_UNUSED (cb_data_p);
3535 
3536   return NULL;
3537 
3538 #endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */
3539 } /* jerry_create_context */
3540 
3541 /**
3542  * If JERRY_VM_EXEC_STOP is enabled the callback passed to this function is
3543  * periodically called with the user_p argument. If frequency is greater
3544  * than 1, the callback is only called at every frequency ticks.
3545  */
3546 void
jerry_set_vm_exec_stop_callback(jerry_vm_exec_stop_callback_t stop_cb,void * user_p,uint32_t frequency)3547 jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< periodically called user function */
3548                                  void *user_p, /**< pointer passed to the function */
3549                                  uint32_t frequency) /**< frequency of the function call */
3550 {
3551 #if ENABLED (JERRY_VM_EXEC_STOP)
3552   if (frequency == 0)
3553   {
3554     frequency = 1;
3555   }
3556 
3557   JERRY_CONTEXT (vm_exec_stop_frequency) = frequency;
3558   JERRY_CONTEXT (vm_exec_stop_counter) = frequency;
3559   JERRY_CONTEXT (vm_exec_stop_user_p) = user_p;
3560   JERRY_CONTEXT (vm_exec_stop_cb) = stop_cb;
3561 #else /* !ENABLED (JERRY_VM_EXEC_STOP) */
3562   JERRY_UNUSED (stop_cb);
3563   JERRY_UNUSED (user_p);
3564   JERRY_UNUSED (frequency);
3565 #endif /* ENABLED (JERRY_VM_EXEC_STOP) */
3566 } /* jerry_set_vm_exec_stop_callback */
3567 
3568 /**
3569  * Get backtrace. The backtrace is an array of strings where
3570  * each string contains the position of the corresponding frame.
3571  * The array length is zero if the backtrace is not available.
3572  *
3573  * @return array value
3574  */
3575 jerry_value_t
jerry_get_backtrace(uint32_t max_depth)3576 jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */
3577 {
3578   return vm_get_backtrace (max_depth);
3579 } /* jerry_get_backtrace */
3580 
3581 /**
3582  * Get the resource name (usually a file name) of the currently executed script or the given function object
3583  *
3584  * Note: returned value must be freed with jerry_release_value, when it is no longer needed
3585  *
3586  * @return JS string constructed from
3587  *         - the currently executed function object's resource name, if the given value is undefined
3588  *         - resource name of the function object, if the given value is a function object
3589  *         - "<anonymous>", otherwise
3590  */
3591 jerry_value_t
jerry_get_resource_name(const jerry_value_t value)3592 jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
3593 {
3594 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3595   if (ecma_is_value_undefined (value))
3596   {
3597     if (JERRY_CONTEXT (vm_top_context_p) != NULL)
3598     {
3599       return ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->resource_name);
3600     }
3601   }
3602 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3603 #if ENABLED (JERRY_LINE_INFO)
3604   else if (ecma_is_value_object (value))
3605   {
3606     ecma_object_t *obj_p = ecma_get_object_from_value (value);
3607 
3608     if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
3609         && !ecma_get_object_is_builtin (obj_p))
3610     {
3611       ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
3612 
3613       const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
3614 
3615       return ecma_copy_value (ecma_op_resource_name (bytecode_data_p));
3616     }
3617   }
3618 #endif /* ENABLED (JERRY_LINE_INFO) */
3619 
3620   JERRY_UNUSED (value);
3621   return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
3622 } /* jerry_get_resource_name */
3623 
3624 /**
3625  * Access the "new.target" value.
3626  *
3627  * The "new.target" value depends on the current call site. That is
3628  * this method will only have a function object result if, at the call site
3629  * it was called inside a constructor method invoked with "new".
3630  *
3631  * @return "undefined" - if at the call site it was not a constructor call.
3632  *         function object - if the current call site is in a constructor call.
3633  */
3634 jerry_value_t
jerry_get_new_target(void)3635 jerry_get_new_target (void)
3636 {
3637 #if ENABLED (JERRY_ES2015)
3638   ecma_object_t *current_new_target = JERRY_CONTEXT (current_new_target);
3639 
3640   if (current_new_target == NULL)
3641   {
3642     return jerry_create_undefined ();
3643   }
3644 
3645   ecma_ref_object (current_new_target);
3646   return ecma_make_object_value (current_new_target);
3647 #else /* !ENABLED (JERRY_ES2015) */
3648   return jerry_create_undefined ();
3649 #endif /* ENABLED (JERRY_ES2015) */
3650 } /* jerry_get_new_target */
3651 
3652 /**
3653  * Check if the given value is an ArrayBuffer object.
3654  *
3655  * @return true - if it is an ArrayBuffer object
3656  *         false - otherwise
3657  */
3658 bool
jerry_value_is_arraybuffer(const jerry_value_t value)3659 jerry_value_is_arraybuffer (const jerry_value_t value) /**< value to check if it is an ArrayBuffer */
3660 {
3661   jerry_assert_api_available ();
3662 
3663 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3664   return ecma_is_arraybuffer (value);
3665 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3666   JERRY_UNUSED (value);
3667   return false;
3668 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3669 } /* jerry_value_is_arraybuffer */
3670 
3671 /**
3672  * Creates an ArrayBuffer object with the given length (size).
3673  *
3674  * Notes:
3675  *      * the length is specified in bytes.
3676  *      * returned value must be freed with jerry_release_value, when it is no longer needed.
3677  *      * if the typed arrays are disabled this will return a TypeError.
3678  *
3679  * @return value of the constructed ArrayBuffer object
3680  */
3681 jerry_value_t
jerry_create_arraybuffer(const jerry_length_t size)3682 jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffer to create */
3683 {
3684   jerry_assert_api_available ();
3685 
3686 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3687   return jerry_return (ecma_make_object_value (ecma_arraybuffer_new_object (size)));
3688 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3689   JERRY_UNUSED (size);
3690   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported.")));
3691 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3692 } /* jerry_create_arraybuffer */
3693 
3694 /**
3695  * Creates an ArrayBuffer object with user specified buffer.
3696  *
3697  * Notes:
3698  *     * the size is specified in bytes.
3699  *     * the buffer passed should be at least the specified bytes big.
3700  *     * if the typed arrays are disabled this will return a TypeError.
3701  *     * if the size is zero or buffer_p is a null pointer this will return an empty ArrayBuffer.
3702  *
3703  * @return value of the construced ArrayBuffer object
3704  */
3705 jerry_value_t
jerry_create_arraybuffer_external(const jerry_length_t size,uint8_t * buffer_p,jerry_object_native_free_callback_t free_cb)3706 jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */
3707                                    uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */
3708                                    jerry_object_native_free_callback_t free_cb) /**< buffer free callback */
3709 {
3710   jerry_assert_api_available ();
3711 
3712 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3713   ecma_object_t *arraybuffer;
3714 
3715   if (JERRY_UNLIKELY (size == 0 || buffer_p == NULL))
3716   {
3717     arraybuffer = ecma_arraybuffer_new_object_external (0, NULL, (ecma_object_native_free_callback_t) free_cb);
3718   }
3719   else
3720   {
3721     arraybuffer = ecma_arraybuffer_new_object_external (size,
3722                                                         buffer_p,
3723                                                         (ecma_object_native_free_callback_t) free_cb);
3724   }
3725 
3726   return jerry_return (ecma_make_object_value (arraybuffer));
3727 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3728   JERRY_UNUSED (size);
3729   JERRY_UNUSED (buffer_p);
3730   JERRY_UNUSED (free_cb);
3731   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported.")));
3732 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3733 } /* jerry_create_arraybuffer_external */
3734 
3735 /**
3736  * Copy bytes into the ArrayBuffer from a buffer.
3737  *
3738  * Note:
3739  *     * if the object passed is not an ArrayBuffer will return 0.
3740  *
3741  * @return number of bytes copied into the ArrayBuffer.
3742  */
3743 jerry_length_t
jerry_arraybuffer_write(const jerry_value_t value,jerry_length_t offset,const uint8_t * buf_p,jerry_length_t buf_size)3744 jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer */
3745                          jerry_length_t offset, /**< start offset of the ArrayBuffer */
3746                          const uint8_t *buf_p, /**< buffer to copy from */
3747                          jerry_length_t buf_size) /**< number of bytes to copy from the buffer */
3748 {
3749   jerry_assert_api_available ();
3750 
3751 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3752   if (!ecma_is_arraybuffer (value))
3753   {
3754     return 0;
3755   }
3756 
3757   ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3758   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
3759 
3760   if (offset >= length)
3761   {
3762     return 0;
3763   }
3764 
3765   jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
3766 
3767   if (copy_count > 0)
3768   {
3769     lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3770 
3771     memcpy ((void *) (mem_buffer_p + offset), (void *) buf_p, copy_count);
3772   }
3773 
3774   return copy_count;
3775 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3776   JERRY_UNUSED (value);
3777   JERRY_UNUSED (offset);
3778   JERRY_UNUSED (buf_p);
3779   JERRY_UNUSED (buf_size);
3780   return 0;
3781 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3782 } /* jerry_arraybuffer_write */
3783 
3784 /**
3785  * Copy bytes from a buffer into an ArrayBuffer.
3786  *
3787  * Note:
3788  *     * if the object passed is not an ArrayBuffer will return 0.
3789  *
3790  * @return number of bytes read from the ArrayBuffer.
3791  */
3792 jerry_length_t
jerry_arraybuffer_read(const jerry_value_t value,jerry_length_t offset,uint8_t * buf_p,jerry_length_t buf_size)3793 jerry_arraybuffer_read (const jerry_value_t value, /**< ArrayBuffer to read from */
3794                         jerry_length_t offset, /**< start offset of the ArrayBuffer */
3795                         uint8_t *buf_p, /**< destination buffer to copy to */
3796                         jerry_length_t buf_size) /**< number of bytes to copy into the buffer */
3797 {
3798   jerry_assert_api_available ();
3799 
3800 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3801   if (!ecma_is_arraybuffer (value))
3802   {
3803     return 0;
3804   }
3805 
3806   ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3807   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
3808 
3809   if (offset >= length)
3810   {
3811     return 0;
3812   }
3813 
3814   jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
3815 
3816   if (copy_count > 0)
3817   {
3818     lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3819 
3820     memcpy ((void *) buf_p, (void *) (mem_buffer_p + offset), copy_count);
3821   }
3822 
3823   return copy_count;
3824 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3825   JERRY_UNUSED (value);
3826   JERRY_UNUSED (offset);
3827   JERRY_UNUSED (buf_p);
3828   JERRY_UNUSED (buf_size);
3829   return 0;
3830 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3831 } /* jerry_arraybuffer_read */
3832 
3833 /**
3834  * Get the length (size) of the ArrayBuffer in bytes.
3835  *
3836  * Note:
3837  *     This is the 'byteLength' property of an ArrayBuffer.
3838  *
3839  * @return the length of the ArrayBuffer in bytes.
3840  */
3841 jerry_length_t
jerry_get_arraybuffer_byte_length(const jerry_value_t value)3842 jerry_get_arraybuffer_byte_length (const jerry_value_t value) /**< ArrayBuffer */
3843 {
3844   jerry_assert_api_available ();
3845 
3846 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3847   if (ecma_is_arraybuffer (value))
3848   {
3849     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3850     return ecma_arraybuffer_get_length (buffer_p);
3851   }
3852 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3853   JERRY_UNUSED (value);
3854 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3855   return 0;
3856 } /* jerry_get_arraybuffer_byte_length */
3857 
3858 /**
3859  * Get a pointer for the start of the ArrayBuffer.
3860  *
3861  * Note:
3862  *    * This is a high-risk operation as the bounds are not checked
3863  *      when accessing the pointer elements.
3864  *
3865  * @return pointer to the back-buffer of the ArrayBuffer.
3866  *         pointer is NULL if the parameter is not an ArrayBuffer
3867  */
3868 uint8_t *
jerry_get_arraybuffer_pointer(const jerry_value_t array_buffer)3869 jerry_get_arraybuffer_pointer (const jerry_value_t array_buffer) /**< Array Buffer to use */
3870 {
3871   jerry_assert_api_available ();
3872 
3873 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3874   if (ecma_is_value_error_reference (array_buffer)
3875       || !ecma_is_arraybuffer (array_buffer))
3876   {
3877     return NULL;
3878   }
3879 
3880   ecma_object_t *buffer_p = ecma_get_object_from_value (array_buffer);
3881   lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3882   return (uint8_t *const) mem_buffer_p;
3883 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3884   JERRY_UNUSED (array_buffer);
3885 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3886 
3887   return NULL;
3888 } /* jerry_get_arraybuffer_pointer */
3889 
3890 /**
3891  * Get if the ArrayBuffer is detachable.
3892  *
3893  * @return boolean value - if success
3894  *         value marked with error flag - otherwise
3895  */
3896 jerry_value_t
jerry_is_arraybuffer_detachable(const jerry_value_t value)3897 jerry_is_arraybuffer_detachable (const jerry_value_t value) /**< ArrayBuffer */
3898 {
3899   jerry_assert_api_available ();
3900 
3901 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3902   if (ecma_is_arraybuffer (value))
3903   {
3904     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3905     return ecma_arraybuffer_is_detachable (buffer_p) ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
3906   }
3907 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3908   JERRY_UNUSED (value);
3909 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3910   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer")));
3911 } /* jerry_is_arraybuffer_detachable */
3912 
3913 /**
3914  * Detach the underlying data block from ArrayBuffer and set its bytelength to 0.
3915  * This operation requires the ArrayBuffer to be external that created by
3916  * `jerry_create_arraybuffer_external`.
3917  *
3918  * @return null value - if success
3919  *         value marked with error flag - otherwise
3920  */
3921 jerry_value_t
jerry_detach_arraybuffer(const jerry_value_t value)3922 jerry_detach_arraybuffer (const jerry_value_t value) /**< ArrayBuffer */
3923 {
3924   jerry_assert_api_available ();
3925 
3926 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3927   if (ecma_is_arraybuffer (value))
3928   {
3929     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3930     bool detached = ecma_arraybuffer_detach (buffer_p);
3931     if (!detached)
3932     {
3933       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects a detachable ArrayBuffer.")));
3934     }
3935     return ECMA_VALUE_NULL;
3936   }
3937 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3938   JERRY_UNUSED (value);
3939 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3940   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer")));
3941 } /* jerry_detach_arraybuffer */
3942 
3943 /**
3944  * DataView related functions
3945  */
3946 
3947 /**
3948  * Creates a DataView object with the given ArrayBuffer, ByteOffset and ByteLength arguments.
3949  *
3950  * Notes:
3951  *      * returned value must be freed with jerry_release_value, when it is no longer needed.
3952  *      * if the DataView bulitin is disabled this will return a TypeError.
3953  *
3954  * @return value of the constructed DataView object - if success
3955  *         created error - otherwise
3956  */
3957 jerry_value_t
jerry_create_dataview(const jerry_value_t array_buffer,const jerry_length_t byte_offset,const jerry_length_t byte_length)3958 jerry_create_dataview (const jerry_value_t array_buffer, /**< arraybuffer to create DataView from */
3959                        const jerry_length_t byte_offset, /**< offset in bytes, to the first byte in the buffer */
3960                        const jerry_length_t byte_length) /**< number of elements in the byte array */
3961 {
3962   jerry_assert_api_available ();
3963 
3964 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
3965   if (ecma_is_value_error_reference (array_buffer))
3966   {
3967     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3968   }
3969 
3970   ecma_value_t arguments_p[3] =
3971   {
3972     array_buffer,
3973     ecma_make_uint32_value (byte_offset),
3974     ecma_make_uint32_value (byte_length)
3975   };
3976 
3977   return jerry_return (ecma_op_dataview_create (arguments_p, 3));
3978 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
3979   JERRY_UNUSED (array_buffer);
3980   JERRY_UNUSED (byte_offset);
3981   JERRY_UNUSED (byte_length);
3982   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported.")));
3983 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
3984 } /* jerry_create_dataview */
3985 
3986 /**
3987  * Check if the given value is a DataView object.
3988  *
3989  * @return true - if it is a DataView object
3990  *         false - otherwise
3991  */
3992 bool
jerry_value_is_dataview(const jerry_value_t value)3993 jerry_value_is_dataview (const jerry_value_t value) /**< value to check if it is a DataView object */
3994 {
3995   jerry_assert_api_available ();
3996 
3997 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
3998   return ecma_is_dataview (value);
3999 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
4000   JERRY_UNUSED (value);
4001   return false;
4002 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
4003 } /* jerry_value_is_dataview */
4004 
4005 /**
4006  * Get the underlying ArrayBuffer from a DataView.
4007  *
4008  * Additionally the byteLength and byteOffset properties are also returned
4009  * which were specified when the DataView was created.
4010  *
4011  * Note:
4012  *     the returned value must be freed with a jerry_release_value call
4013  *
4014  * @return ArrayBuffer of a DataView
4015  *         TypeError if the object is not a DataView.
4016  */
4017 jerry_value_t
jerry_get_dataview_buffer(const jerry_value_t value,jerry_length_t * byte_offset,jerry_length_t * byte_length)4018 jerry_get_dataview_buffer (const jerry_value_t value, /**< DataView to get the arraybuffer from */
4019                            jerry_length_t *byte_offset, /**< [out] byteOffset property */
4020                            jerry_length_t *byte_length) /**< [out] byteLength property */
4021 {
4022   jerry_assert_api_available ();
4023 
4024 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
4025   if (ecma_is_value_error_reference (value))
4026   {
4027     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
4028   }
4029 
4030   ecma_dataview_object_t *dataview_p = ecma_op_dataview_get_object (value);
4031 
4032   if (JERRY_UNLIKELY (dataview_p == NULL))
4033   {
4034     return ecma_create_error_reference_from_context ();
4035   }
4036 
4037   if (byte_offset != NULL)
4038   {
4039     *byte_offset = dataview_p->byte_offset;
4040   }
4041 
4042   if (byte_length != NULL)
4043   {
4044     *byte_length = dataview_p->header.u.class_prop.u.length;
4045   }
4046 
4047   ecma_object_t *arraybuffer_p = dataview_p->buffer_p;
4048   ecma_ref_object (arraybuffer_p);
4049 
4050   return ecma_make_object_value (arraybuffer_p);
4051 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
4052   JERRY_UNUSED (value);
4053   JERRY_UNUSED (byte_offset);
4054   JERRY_UNUSED (byte_length);
4055   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported.")));
4056 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
4057 } /* jerry_get_dataview_buffer */
4058 
4059 /**
4060  * TypedArray related functions
4061  */
4062 
4063 /**
4064  * Check if the given value is a TypedArray object.
4065  *
4066  * @return true - if it is a TypedArray object
4067  *         false - otherwise
4068  */
4069 bool
jerry_value_is_typedarray(jerry_value_t value)4070 jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a TypedArray */
4071 {
4072   jerry_assert_api_available ();
4073 
4074 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4075   return ecma_is_typedarray (value);
4076 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4077   JERRY_UNUSED (value);
4078   return false;
4079 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4080 } /* jerry_value_is_typedarray */
4081 
4082 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4083 /**
4084  * TypedArray mapping type
4085  */
4086 typedef struct
4087 {
4088   jerry_typedarray_type_t api_type; /**< api type */
4089   ecma_builtin_id_t prototype_id; /**< prototype ID */
4090   ecma_typedarray_type_t id; /**< typedArray ID */
4091   uint8_t element_size_shift; /**< element size shift */
4092 } jerry_typedarray_mapping_t;
4093 
4094 /**
4095  * List of TypedArray mappings
4096  */
4097 static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
4098 {
4099 #define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \
4100   { JERRY_TYPEDARRAY_ ## NAME, ECMA_BUILTIN_ID_ ## NAME ## ARRAY_PROTOTYPE, \
4101     ECMA_ ## LIT_NAME ## _ARRAY, SIZE_SHIFT }
4102 
4103   TYPEDARRAY_ENTRY (UINT8, UINT8, 0),
4104   TYPEDARRAY_ENTRY (UINT8CLAMPED, UINT8_CLAMPED, 0),
4105   TYPEDARRAY_ENTRY (INT8, INT8, 0),
4106   TYPEDARRAY_ENTRY (UINT16, UINT16, 1),
4107   TYPEDARRAY_ENTRY (INT16, INT16, 1),
4108   TYPEDARRAY_ENTRY (UINT32, UINT32, 2),
4109   TYPEDARRAY_ENTRY (INT32, INT32, 2),
4110   TYPEDARRAY_ENTRY (FLOAT32, FLOAT32, 2),
4111 #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
4112   TYPEDARRAY_ENTRY (FLOAT64, FLOAT64, 3),
4113 #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
4114 
4115 #undef TYPEDARRAY_ENTRY
4116 };
4117 
4118 /**
4119  * Helper function to get the TypedArray prototype, typedArray id, and element size shift
4120  * information.
4121  *
4122  * @return true - if the TypedArray information was found
4123  *         false - if there is no such TypedArray type
4124  */
4125 static bool
jerry_typedarray_find_by_type(jerry_typedarray_type_t type_name,ecma_builtin_id_t * prototype_id,ecma_typedarray_type_t * id,uint8_t * element_size_shift)4126 jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of the TypedArray */
4127                                ecma_builtin_id_t *prototype_id, /**< [out] found prototype object id */
4128                                ecma_typedarray_type_t *id, /**< [out] found typedArray id */
4129                                uint8_t *element_size_shift) /**< [out] found element size shift value */
4130 {
4131   JERRY_ASSERT (prototype_id != NULL);
4132   JERRY_ASSERT (id != NULL);
4133   JERRY_ASSERT (element_size_shift != NULL);
4134 
4135   for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
4136   {
4137     if (type_name == jerry_typedarray_mappings[i].api_type)
4138     {
4139       *prototype_id = jerry_typedarray_mappings[i].prototype_id;
4140       *id = jerry_typedarray_mappings[i].id;
4141       *element_size_shift = jerry_typedarray_mappings[i].element_size_shift;
4142       return true;
4143     }
4144   }
4145 
4146   return false;
4147 } /* jerry_typedarray_find_by_type */
4148 
4149 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4150 
4151 /**
4152  * Create a TypedArray object with a given type and length.
4153  *
4154  * Notes:
4155  *      * returns TypeError if an incorrect type (type_name) is specified.
4156  *      * byteOffset property will be set to 0.
4157  *      * byteLength property will be a multiple of the length parameter (based on the type).
4158  *
4159  * @return - new TypedArray object
4160  */
4161 jerry_value_t
jerry_create_typedarray(jerry_typedarray_type_t type_name,jerry_length_t length)4162 jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4163                          jerry_length_t length) /**< element count of the new TypedArray */
4164 {
4165   jerry_assert_api_available ();
4166 
4167 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4168   ecma_builtin_id_t prototype_id = 0;
4169   ecma_typedarray_type_t id = 0;
4170   uint8_t element_size_shift = 0;
4171 
4172   if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
4173   {
4174     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
4175   }
4176 
4177   ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
4178 
4179   ecma_value_t array_value = ecma_typedarray_create_object_with_length (length,
4180                                                                         NULL,
4181                                                                         prototype_obj_p,
4182                                                                         element_size_shift,
4183                                                                         id);
4184 
4185   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
4186 
4187   return array_value;
4188 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4189   JERRY_UNUSED (type_name);
4190   JERRY_UNUSED (length);
4191   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4192 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4193 } /* jerry_create_typedarray */
4194 
4195 /**
4196  * Create a TypedArray object using the given arraybuffer and size information.
4197  *
4198  * Notes:
4199  *      * returns TypeError if an incorrect type (type_name) is specified.
4200  *      * this is the 'new %TypedArray%(arraybuffer, byteOffset, length)' equivalent call.
4201  *
4202  * @return - new TypedArray object
4203  */
4204 jerry_value_t
jerry_create_typedarray_for_arraybuffer_sz(jerry_typedarray_type_t type_name,const jerry_value_t arraybuffer,jerry_length_t byte_offset,jerry_length_t length)4205 jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4206                                             const jerry_value_t arraybuffer, /**< ArrayBuffer to use */
4207                                             jerry_length_t byte_offset, /**< offset for the ArrayBuffer */
4208                                             jerry_length_t length) /**< number of elements to use from ArrayBuffer */
4209 {
4210   jerry_assert_api_available ();
4211 
4212 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4213   if (ecma_is_value_error_reference (arraybuffer))
4214   {
4215     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4216   }
4217 
4218   ecma_builtin_id_t prototype_id = 0;
4219   ecma_typedarray_type_t id = 0;
4220   uint8_t element_size_shift = 0;
4221 
4222   if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
4223   {
4224     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
4225   }
4226 
4227   if (!ecma_is_arraybuffer (arraybuffer))
4228   {
4229     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an ArrayBuffer")));
4230   }
4231 
4232   ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
4233   ecma_value_t arguments_p[3] =
4234   {
4235     arraybuffer,
4236     ecma_make_uint32_value (byte_offset),
4237     ecma_make_uint32_value (length)
4238   };
4239 
4240   ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, id);
4241   ecma_free_value (arguments_p[1]);
4242   ecma_free_value (arguments_p[2]);
4243 
4244   return jerry_return (array_value);
4245 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4246   JERRY_UNUSED (type_name);
4247   JERRY_UNUSED (arraybuffer);
4248   JERRY_UNUSED (byte_offset);
4249   JERRY_UNUSED (length);
4250   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4251 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4252 } /* jerry_create_typedarray_for_arraybuffer_sz */
4253 
4254 /**
4255  * Create a TypedArray object using the given arraybuffer and size information.
4256  *
4257  * Notes:
4258  *      * returns TypeError if an incorrect type (type_name) is specified.
4259  *      * this is the 'new %TypedArray%(arraybuffer)' equivalent call.
4260  *
4261  * @return - new TypedArray object
4262  */
4263 jerry_value_t
jerry_create_typedarray_for_arraybuffer(jerry_typedarray_type_t type_name,const jerry_value_t arraybuffer)4264 jerry_create_typedarray_for_arraybuffer (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4265                                          const jerry_value_t arraybuffer) /**< ArrayBuffer to use */
4266 {
4267   jerry_assert_api_available ();
4268 
4269 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4270   if (ecma_is_value_error_reference (arraybuffer))
4271   {
4272     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4273   }
4274 
4275   jerry_length_t byteLength = jerry_get_arraybuffer_byte_length (arraybuffer);
4276   return jerry_create_typedarray_for_arraybuffer_sz (type_name, arraybuffer, 0, byteLength);
4277 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4278   JERRY_UNUSED (type_name);
4279   JERRY_UNUSED (arraybuffer);
4280   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4281 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4282 } /* jerry_create_typedarray_for_arraybuffer */
4283 
4284 /**
4285  * Get the type of the TypedArray.
4286  *
4287  * @return - type of the TypedArray
4288  *         - JERRY_TYPEDARRAY_INVALID if the argument is not a TypedArray
4289  */
4290 jerry_typedarray_type_t
jerry_get_typedarray_type(jerry_value_t value)4291 jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArray type */
4292 {
4293   jerry_assert_api_available ();
4294 
4295 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4296   if (!ecma_is_typedarray (value))
4297   {
4298     return JERRY_TYPEDARRAY_INVALID;
4299   }
4300 
4301   ecma_object_t *array_p = ecma_get_object_from_value (value);
4302   ecma_typedarray_type_t class_type = ecma_get_typedarray_id (array_p);
4303 
4304   for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
4305   {
4306     if (class_type == jerry_typedarray_mappings[i].id)
4307     {
4308       return jerry_typedarray_mappings[i].api_type;
4309     }
4310   }
4311 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4312   JERRY_UNUSED (value);
4313 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4314 
4315   return JERRY_TYPEDARRAY_INVALID;
4316 } /* jerry_get_typedarray_type */
4317 
4318 /**
4319  * Get the element count of the TypedArray.
4320  *
4321  * @return length of the TypedArray.
4322  */
4323 jerry_length_t
jerry_get_typedarray_length(jerry_value_t value)4324 jerry_get_typedarray_length (jerry_value_t value) /**< TypedArray to query */
4325 {
4326   jerry_assert_api_available ();
4327 
4328 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4329   if (ecma_is_typedarray (value))
4330   {
4331     ecma_object_t *array_p = ecma_get_object_from_value (value);
4332     return ecma_typedarray_get_length (array_p);
4333   }
4334 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4335   JERRY_UNUSED (value);
4336 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4337 
4338   return 0;
4339 } /* jerry_get_typedarray_length */
4340 
4341 /**
4342  * Get the underlying ArrayBuffer from a TypedArray.
4343  *
4344  * Additionally the byteLength and byteOffset properties are also returned
4345  * which were specified when the TypedArray was created.
4346  *
4347  * Note:
4348  *     the returned value must be freed with a jerry_release_value call
4349  *
4350  * @return ArrayBuffer of a TypedArray
4351  *         TypeError if the object is not a TypedArray.
4352  */
4353 jerry_value_t
jerry_get_typedarray_buffer(jerry_value_t value,jerry_length_t * byte_offset,jerry_length_t * byte_length)4354 jerry_get_typedarray_buffer (jerry_value_t value, /**< TypedArray to get the arraybuffer from */
4355                              jerry_length_t *byte_offset, /**< [out] byteOffset property */
4356                              jerry_length_t *byte_length) /**< [out] byteLength property */
4357 {
4358   jerry_assert_api_available ();
4359 
4360 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4361   if (!ecma_is_typedarray (value))
4362   {
4363     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Object is not a TypedArray.")));
4364   }
4365 
4366   ecma_object_t *array_p = ecma_get_object_from_value (value);
4367   uint8_t shift = ecma_typedarray_get_element_size_shift (array_p);
4368 
4369   if (byte_length != NULL)
4370   {
4371     *byte_length = (jerry_length_t) (ecma_typedarray_get_length (array_p) << shift);
4372   }
4373 
4374   if (byte_offset != NULL)
4375   {
4376     *byte_offset = (jerry_length_t) ecma_typedarray_get_offset (array_p);
4377   }
4378 
4379   ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (array_p);
4380   ecma_ref_object (arraybuffer_p);
4381   return jerry_return (ecma_make_object_value (arraybuffer_p));
4382 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4383   JERRY_UNUSED (value);
4384   JERRY_UNUSED (byte_length);
4385   JERRY_UNUSED (byte_offset);
4386   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray is not supported.")));
4387 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4388 } /* jerry_get_typedarray_buffer */
4389 
4390 /**
4391  * Create an object from JSON
4392  *
4393  * Note:
4394  *      The returned value must be freed with jerry_release_value
4395  * @return jerry_value_t from json formated string or an error massage
4396  */
4397 jerry_value_t
jerry_json_parse(const jerry_char_t * string_p,jerry_size_t string_size)4398 jerry_json_parse (const jerry_char_t *string_p, /**< json string */
4399                   jerry_size_t string_size) /**< json string size */
4400 {
4401   jerry_assert_api_available ();
4402 
4403 #if ENABLED (JERRY_BUILTIN_JSON)
4404   ecma_value_t ret_value = ecma_builtin_json_parse_buffer (string_p, string_size);
4405 
4406   if (ecma_is_value_undefined (ret_value))
4407   {
4408     ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON string parse error.")));
4409   }
4410 
4411   return ret_value;
4412 #else /* !ENABLED (JERRY_BUILTIN_JSON) */
4413   JERRY_UNUSED (string_p);
4414   JERRY_UNUSED (string_size);
4415 
4416   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled.")));
4417 #endif /* ENABLED (JERRY_BUILTIN_JSON) */
4418 } /* jerry_json_parse */
4419 
4420 /**
4421  * Create a Json formated string from an object
4422  *
4423  * Note:
4424  *      The returned value must be freed with jerry_release_value
4425  * @return json formated jerry_value_t or an error massage
4426  */
4427 jerry_value_t
jerry_json_stringify(const jerry_value_t object_to_stringify)4428 jerry_json_stringify (const jerry_value_t object_to_stringify) /**< a jerry_object_t to stringify */
4429 {
4430   jerry_assert_api_available ();
4431 #if ENABLED (JERRY_BUILTIN_JSON)
4432   ecma_value_t ret_value = ecma_builtin_json_string_from_object (object_to_stringify);
4433 
4434   if (ecma_is_value_error_reference (object_to_stringify))
4435   {
4436     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4437   }
4438 
4439   if (ecma_is_value_undefined (ret_value))
4440   {
4441     ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON stringify error.")));
4442   }
4443 
4444   return ret_value;
4445 #else /* ENABLED (JERRY_BUILTIN_JSON) */
4446   JERRY_UNUSED (object_to_stringify);
4447 
4448   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled.")));
4449 #endif /* ENABLED (JERRY_BUILTIN_JSON) */
4450 } /* jerry_json_stringify */
4451 
4452 /**
4453  * Create a container type specified in jerry_container_type_t.
4454  * The container can be created with a list of arguments, which will be passed to the container constructor to be
4455  * inserted to the container.
4456  *
4457  * Note:
4458  *      The returned value must be freed with jerry_release_value
4459  * @return jerry_value_t representing a container with the given type.
4460  */
4461 jerry_value_t
jerry_create_container(jerry_container_type_t container_type,const jerry_value_t * arguments_list_p,jerry_length_t arguments_list_len)4462 jerry_create_container (jerry_container_type_t container_type, /**< Type of the container */
4463                         const jerry_value_t *arguments_list_p, /**< arguments list */
4464                         jerry_length_t arguments_list_len) /**< Length of arguments list */
4465 {
4466   jerry_assert_api_available ();
4467 
4468 #if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER)
4469   for (jerry_length_t i = 0; i < arguments_list_len; i++)
4470   {
4471     if (ecma_is_value_error_reference (arguments_list_p[i]))
4472     {
4473       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4474     }
4475   }
4476 
4477   lit_magic_string_id_t lit_id;
4478   ecma_builtin_id_t proto_id;
4479   ecma_builtin_id_t ctor_id;
4480 
4481   switch (container_type)
4482   {
4483 #if ENABLED (JERRY_ES2015_BUILTIN_MAP)
4484     case JERRY_CONTAINER_TYPE_MAP:
4485     {
4486       lit_id = LIT_MAGIC_STRING_MAP_UL;
4487       proto_id = ECMA_BUILTIN_ID_MAP_PROTOTYPE;
4488       ctor_id = ECMA_BUILTIN_ID_MAP;
4489       break;
4490     }
4491 #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
4492 #if ENABLED (JERRY_ES2015_BUILTIN_SET)
4493     case JERRY_CONTAINER_TYPE_SET:
4494     {
4495       lit_id = LIT_MAGIC_STRING_SET_UL;
4496       proto_id = ECMA_BUILTIN_ID_SET_PROTOTYPE;
4497       ctor_id = ECMA_BUILTIN_ID_SET;
4498       break;
4499     }
4500 #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
4501 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
4502     case JERRY_CONTAINER_TYPE_WEAKMAP:
4503     {
4504       lit_id = LIT_MAGIC_STRING_WEAKMAP_UL;
4505       proto_id = ECMA_BUILTIN_ID_WEAKMAP_PROTOTYPE;
4506       ctor_id = ECMA_BUILTIN_ID_WEAKMAP;
4507       break;
4508     }
4509 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */
4510 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
4511     case JERRY_CONTAINER_TYPE_WEAKSET:
4512     {
4513       lit_id = LIT_MAGIC_STRING_WEAKSET_UL;
4514       proto_id = ECMA_BUILTIN_ID_WEAKSET_PROTOTYPE;
4515       ctor_id = ECMA_BUILTIN_ID_WEAKSET;
4516       break;
4517     }
4518 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
4519     default:
4520     {
4521       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Invalid container type.")));
4522     }
4523   }
4524   ecma_object_t * old_new_target_p = JERRY_CONTEXT (current_new_target);
4525 
4526   if (old_new_target_p == NULL)
4527   {
4528     JERRY_CONTEXT (current_new_target) = ecma_builtin_get (ctor_id);
4529   }
4530 
4531   ecma_value_t container_value = ecma_op_container_create (arguments_list_p,
4532                                                            arguments_list_len,
4533                                                            lit_id,
4534                                                            proto_id);
4535 
4536   JERRY_CONTEXT (current_new_target) = old_new_target_p;
4537   return container_value;
4538 #else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4539   JERRY_UNUSED (arguments_list_p);
4540   JERRY_UNUSED (arguments_list_len);
4541   JERRY_UNUSED (container_type);
4542   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Containers are disabled.")));
4543 #endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4544 } /* jerry_create_container */
4545 
4546 /**
4547  * Get the type of the given container object.
4548  *
4549  * @return Corresponding type to the given container object.
4550  */
4551 jerry_container_type_t
jerry_get_container_type(const jerry_value_t value)4552 jerry_get_container_type (const jerry_value_t value) /**< the container object */
4553 {
4554   jerry_assert_api_available ();
4555 
4556 #if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER)
4557   if (ecma_is_value_object (value))
4558   {
4559     ecma_object_t *obj_p = ecma_get_object_from_value (value);
4560 
4561     if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS)
4562     {
4563       uint16_t type = ((ecma_extended_object_t *) obj_p)->u.class_prop.class_id;
4564 
4565       switch (type)
4566       {
4567 #if ENABLED (JERRY_ES2015_BUILTIN_MAP)
4568         case LIT_MAGIC_STRING_MAP_UL:
4569         {
4570           return JERRY_CONTAINER_TYPE_MAP;
4571         }
4572 #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
4573 #if ENABLED (JERRY_ES2015_BUILTIN_SET)
4574         case LIT_MAGIC_STRING_SET_UL:
4575         {
4576           return JERRY_CONTAINER_TYPE_SET;
4577         }
4578 #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
4579 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
4580         case LIT_MAGIC_STRING_WEAKMAP_UL:
4581         {
4582           return JERRY_CONTAINER_TYPE_WEAKMAP;
4583         }
4584 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */
4585 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
4586         case LIT_MAGIC_STRING_WEAKSET_UL:
4587         {
4588           return JERRY_CONTAINER_TYPE_WEAKSET;
4589         }
4590 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
4591         default:
4592         {
4593           return JERRY_CONTAINER_TYPE_INVALID;
4594         }
4595       }
4596     }
4597   }
4598 
4599 #else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4600   JERRY_UNUSED (value);
4601 #endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4602   return JERRY_CONTAINER_TYPE_INVALID;
4603 } /* jerry_get_container_type */
4604 
4605 #if defined(JERRY_HEAPDUMP)
JerryHeapdumpRun(const char * filepath)4606 void JerryHeapdumpRun(const char* filepath)
4607 {
4608   SetHeapdumpTraring(true);
4609   LogHeapdumpInit(filepath);
4610   LogHeapdump("[\n");
4611   DumpInfoObject(ecma_builtin_get_global(), HEAPDUMP_OBJECT_GLOBAL);
4612   DumpInfoObject(ecma_get_global_environment(), HEAPDUMP_OBJECT_GLOBAL);
4613   ecma_gc_run();
4614   LogHeapdump("{}]\n");
4615   SetHeapdumpTraring(false);
4616   LogHeapdumpClose();
4617 }
4618 #endif
4619 
4620 #if defined(JERRY_REF_TRACKER)
JerryRefTrackerStart(const char * filepath)4621 void JerryRefTrackerStart(const char* filepath)
4622 {
4623   SetRefTrackerEnabled(true);
4624   LogTrackerInit(filepath);
4625 }
4626 #endif
4627 
4628 #if defined(JERRY_REF_TRACKER)
JerryRefTrackerStop(void)4629 void JerryRefTrackerStop(void)
4630 {
4631   SetRefTrackerEnabled(false);
4632   LogTrackerClose();
4633 }
4634 #endif
4635 
4636 /**
4637  * @}
4638  */
4639