• 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   /**
2875    * Clear flag JERRY_DEBUGGER_VM_STOP and set debugger_stop_context Null everytime jerry's debugger call a function.
2876    * This could solve the problem that jerry's debugger stops at an unexpected line when re-entering a function after a
2877    * step-operation.
2878    */
2879   JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
2880   JERRY_CONTEXT (debugger_stop_context) = NULL;
2881 
2882   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) {
2883     if (jerry_debugger_receive (NULL)) {
2884       JERRY_DEBUG_MSG ("resume");
2885     }
2886   }
2887 #endif
2888 
2889   if (jerry_value_is_function (func_obj_val) && !ecma_is_value_error_reference (this_val))
2890   {
2891     for (jerry_size_t i = 0; i < args_count; i++)
2892     {
2893       if (ecma_is_value_error_reference (args_p[i]))
2894       {
2895         return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2896       }
2897     }
2898 
2899     return jerry_invoke_function (false, func_obj_val, this_val, args_p, args_count);
2900   }
2901 
2902   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2903 } /* jerry_call_function */
2904 
2905 /**
2906  * Construct object value invoking specified function value as a constructor
2907  *
2908  * Note:
2909  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2910  *      error flag must not be set for any arguments of this function.
2911  *
2912  * @return returned jerry value of the invoked constructor
2913  */
2914 jerry_value_t
jerry_construct_object(const jerry_value_t func_obj_val,const jerry_value_t args_p[],jerry_size_t args_count)2915 jerry_construct_object (const jerry_value_t func_obj_val, /**< function object to call */
2916                         const jerry_value_t args_p[], /**< function's call arguments
2917                                                        *   (NULL if arguments number is zero) */
2918                         jerry_size_t args_count) /**< number of the arguments */
2919 {
2920   jerry_assert_api_available ();
2921 
2922   if (jerry_value_is_constructor (func_obj_val))
2923   {
2924     for (jerry_size_t i = 0; i < args_count; i++)
2925     {
2926       if (ecma_is_value_error_reference (args_p[i]))
2927       {
2928         return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
2929       }
2930     }
2931 
2932     ecma_value_t this_val = ECMA_VALUE_UNDEFINED;
2933     return jerry_invoke_function (true, func_obj_val, this_val, args_p, args_count);
2934   }
2935 
2936   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2937 } /* jerry_construct_object */
2938 
2939 /**
2940  * Get keys of the specified object value
2941  *
2942  * Note:
2943  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2944  *
2945  * @return array object value - if success
2946  *         value marked with error flag - otherwise
2947  */
2948 jerry_value_t
jerry_get_object_keys(const jerry_value_t obj_val)2949 jerry_get_object_keys (const jerry_value_t obj_val) /**< object value */
2950 {
2951   jerry_assert_api_available ();
2952 
2953   if (!ecma_is_value_object (obj_val))
2954   {
2955     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2956   }
2957 
2958   return ecma_builtin_helper_object_get_properties (ecma_get_object_from_value (obj_val),
2959                                                     ECMA_LIST_ENUMERABLE);
2960 } /* jerry_get_object_keys */
2961 
2962 /**
2963  * Get the prototype of the specified object
2964  *
2965  * Note:
2966  *      returned value must be freed with jerry_release_value, when it is no longer needed.
2967  *
2968  * @return prototype object or null value - if success
2969  *         value marked with error flag - otherwise
2970  */
2971 jerry_value_t
jerry_get_prototype(const jerry_value_t obj_val)2972 jerry_get_prototype (const jerry_value_t obj_val) /**< object value */
2973 {
2974   jerry_assert_api_available ();
2975 
2976   if (!ecma_is_value_object (obj_val))
2977   {
2978     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
2979   }
2980 
2981   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
2982 
2983 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
2984   if (ECMA_OBJECT_IS_PROXY (obj_p))
2985   {
2986     return jerry_return (ecma_proxy_object_get_prototype_of (obj_p));
2987   }
2988 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
2989 
2990   if (obj_p->u2.prototype_cp == JMEM_CP_NULL)
2991   {
2992     return ECMA_VALUE_NULL;
2993   }
2994 
2995   ecma_object_t *proto_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp);
2996   ecma_ref_object (proto_obj_p);
2997 
2998   return ecma_make_object_value (proto_obj_p);
2999 } /* jerry_get_prototype */
3000 
3001 /**
3002  * Set the prototype of the specified object
3003  *
3004  * @return true value - if success
3005  *         value marked with error flag - otherwise
3006  */
3007 jerry_value_t
jerry_set_prototype(const jerry_value_t obj_val,const jerry_value_t proto_obj_val)3008 jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
3009                      const jerry_value_t proto_obj_val) /**< prototype object value */
3010 {
3011   jerry_assert_api_available ();
3012 
3013   if (!ecma_is_value_object (obj_val)
3014       || ecma_is_value_error_reference (proto_obj_val)
3015       || (!ecma_is_value_object (proto_obj_val) && !ecma_is_value_null (proto_obj_val)))
3016   {
3017     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3018   }
3019   ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
3020 
3021 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
3022   if (ECMA_OBJECT_IS_PROXY (obj_p))
3023   {
3024     return jerry_return (ecma_proxy_object_set_prototype_of (obj_p, proto_obj_val));
3025   }
3026 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
3027 
3028   return ecma_op_ordinary_object_set_prototype_of (obj_p, proto_obj_val);
3029 } /* jerry_set_prototype */
3030 
3031 /**
3032  * Utility to check if a given object can be used for the foreach api calls.
3033  *
3034  * Some objects/classes uses extra internal objects to correctly store data.
3035  * These extre object should never be exposed externally to the API user.
3036  *
3037  * @returns true - if the user can access the object in the callback.
3038  *          false - if the object is an internal object which should no be accessed by the user.
3039  */
3040 static
jerry_object_is_valid_foreach(ecma_object_t * object_p)3041 bool jerry_object_is_valid_foreach (ecma_object_t *object_p) /**< object to test */
3042 {
3043   if (ecma_is_lexical_environment (object_p))
3044   {
3045     return false;
3046   }
3047 
3048   ecma_object_type_t object_type = ecma_get_object_type (object_p);
3049 
3050   if (object_type == ECMA_OBJECT_TYPE_CLASS)
3051   {
3052     ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
3053     switch (ext_object_p->u.class_prop.class_id)
3054     {
3055       /* An object's internal property object should not be iterable by foreach. */
3056       case LIT_INTERNAL_MAGIC_STRING_INTERNAL_OBJECT: return false;
3057     }
3058   }
3059 
3060   return true;
3061 } /* jerry_object_is_valid_foreach */
3062 
3063 /**
3064  * Traverse objects.
3065  *
3066  * @return true - traversal was interrupted by the callback.
3067  *         false - otherwise - traversal visited all objects.
3068  */
3069 bool
jerry_objects_foreach(jerry_objects_foreach_t foreach_p,void * user_data_p)3070 jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer of the iterator function */
3071                        void *user_data_p) /**< pointer to user data */
3072 {
3073   jerry_assert_api_available ();
3074 
3075   JERRY_ASSERT (foreach_p != NULL);
3076 
3077   jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
3078 
3079   while (iter_cp != JMEM_CP_NULL)
3080   {
3081     ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
3082 
3083     if (jerry_object_is_valid_foreach (iter_p)
3084         && !foreach_p (ecma_make_object_value (iter_p), user_data_p))
3085     {
3086       return true;
3087     }
3088 
3089     iter_cp = iter_p->gc_next_cp;
3090   }
3091 
3092   return false;
3093 } /* jerry_objects_foreach */
3094 
3095 /**
3096  * Traverse objects having a given native type info.
3097  *
3098  * @return true - traversal was interrupted by the callback.
3099  *         false - otherwise - traversal visited all objects.
3100  */
3101 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)3102 jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p, /**< the type info
3103                                                                                         *   of the native pointer */
3104                                       jerry_objects_foreach_by_native_info_t foreach_p, /**< function to apply for
3105                                                                                          *   each matching object */
3106                                       void *user_data_p) /**< pointer to user data */
3107 {
3108   jerry_assert_api_available ();
3109 
3110   JERRY_ASSERT (native_info_p != NULL);
3111   JERRY_ASSERT (foreach_p != NULL);
3112 
3113   ecma_native_pointer_t *native_pointer_p;
3114 
3115   jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
3116 
3117   while (iter_cp != JMEM_CP_NULL)
3118   {
3119     ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
3120 
3121     if (jerry_object_is_valid_foreach (iter_p))
3122     {
3123       native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p);
3124       if (native_pointer_p
3125           && !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p))
3126       {
3127         return true;
3128       }
3129     }
3130 
3131     iter_cp = iter_p->gc_next_cp;
3132   }
3133 
3134   return false;
3135 } /* jerry_objects_foreach_by_native_info */
3136 
3137 /**
3138  * Get native pointer and its type information, associated with the given native type info.
3139  *
3140  * Note:
3141  *  If native pointer is present, its type information is returned in out_native_pointer_p
3142  *
3143  * @return true - if there is an associated pointer,
3144  *         false - otherwise
3145  */
3146 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)3147 jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get native pointer from */
3148                                  void **out_native_pointer_p, /**< [out] native pointer */
3149                                  const jerry_object_native_info_t *native_info_p) /**< the type info
3150                                                                                    *   of the native pointer */
3151 {
3152   jerry_assert_api_available ();
3153 
3154   if (!ecma_is_value_object (obj_val))
3155   {
3156     return false;
3157   }
3158 
3159   ecma_native_pointer_t *native_pointer_p;
3160   native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val), (void *) native_info_p);
3161 
3162   if (native_pointer_p == NULL)
3163   {
3164     return false;
3165   }
3166 
3167   if (out_native_pointer_p != NULL)
3168   {
3169     *out_native_pointer_p = native_pointer_p->data_p;
3170   }
3171 
3172   return true;
3173 } /* jerry_get_object_native_pointer */
3174 
3175 /**
3176  * Set native pointer and an optional type info for the specified object.
3177  *
3178  *
3179  * Note:
3180  *      If native pointer was already set for the object, its value is updated.
3181  *
3182  * Note:
3183  *      If a non-NULL free callback is specified in the native type info,
3184  *      it will be called by the garbage collector when the object is freed.
3185  *      Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)
3186  *      The type info always overwrites the previous value, so passing
3187  *      a NULL value deletes the current type info.
3188  */
3189 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)3190 jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set native pointer in */
3191                                  void *native_pointer_p, /**< native pointer */
3192                                  const jerry_object_native_info_t *native_info_p) /**< object's native type info */
3193 {
3194   jerry_assert_api_available ();
3195 
3196   if (ecma_is_value_object (obj_val))
3197   {
3198     ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3199 
3200     ecma_create_native_pointer_property (object_p, native_pointer_p, (void *) native_info_p);
3201   }
3202 } /* jerry_set_object_native_pointer */
3203 
3204 /**
3205  * Delete the previously set native pointer by the native type info from the specified object.
3206  *
3207  * Note:
3208  *      If the specified object has no matching native pointer for the given native type info
3209  *      the function has no effect.
3210  *
3211  * Note:
3212  *      This operation cannot throw an exception.
3213  *
3214  * @return true - if the native pointer has been deleted succesfully
3215  *         false - otherwise
3216  */
3217 bool
jerry_delete_object_native_pointer(const jerry_value_t obj_val,const jerry_object_native_info_t * native_info_p)3218 jerry_delete_object_native_pointer (const jerry_value_t obj_val, /**< object to delete native pointer from */
3219                                     const jerry_object_native_info_t *native_info_p) /**< object's native type info */
3220 {
3221   jerry_assert_api_available ();
3222 
3223   if (ecma_is_value_object (obj_val))
3224   {
3225     ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3226 
3227     return ecma_delete_native_pointer_property (object_p, (void *) native_info_p);
3228   }
3229 
3230   return false;
3231 } /* jerry_delete_object_native_pointer */
3232 
3233 /**
3234  * Applies the given function to the every property in the object.
3235  *
3236  * @return true - if object fields traversal was performed successfully, i.e.:
3237  *                - no unhandled exceptions were thrown in object fields traversal;
3238  *                - object fields traversal was stopped on callback that returned false;
3239  *         false - otherwise,
3240  *                 if getter of field threw a exception or unhandled exceptions were thrown during traversal;
3241  */
3242 bool
jerry_foreach_object_property(const jerry_value_t obj_val,jerry_object_property_foreach_t foreach_p,void * user_data_p)3243 jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
3244                                jerry_object_property_foreach_t foreach_p, /**< foreach function */
3245                                void *user_data_p) /**< user data for foreach function */
3246 {
3247   jerry_assert_api_available ();
3248 
3249   if (!ecma_is_value_object (obj_val))
3250   {
3251     return false;
3252   }
3253 
3254   ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
3255   ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
3256 
3257 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
3258   if (names_p == NULL)
3259   {
3260     // TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
3261     jcontext_release_exception ();
3262     return false;
3263   }
3264 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
3265 
3266   ecma_value_t *buffer_p = names_p->buffer_p;
3267 
3268   ecma_value_t property_value = ECMA_VALUE_EMPTY;
3269 
3270   bool continuous = true;
3271 
3272   for (uint32_t i = 0; continuous && (i < names_p->item_count); i++)
3273   {
3274     ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
3275 
3276     property_value = ecma_op_object_get (object_p, property_name_p);
3277 
3278     if (ECMA_IS_VALUE_ERROR (property_value))
3279     {
3280       break;
3281     }
3282 
3283     continuous = foreach_p (buffer_p[i], property_value, user_data_p);
3284     ecma_free_value (property_value);
3285   }
3286 
3287   ecma_collection_free (names_p);
3288 
3289   if (!ECMA_IS_VALUE_ERROR (property_value))
3290   {
3291     return true;
3292   }
3293 
3294   jcontext_release_exception ();
3295   return false;
3296 } /* jerry_foreach_object_property */
3297 
3298 /**
3299  * Resolve or reject the promise with an argument.
3300  *
3301  * @return undefined value - if success
3302  *         value marked with error flag - otherwise
3303  */
3304 jerry_value_t
jerry_resolve_or_reject_promise(jerry_value_t promise,jerry_value_t argument,bool is_resolve)3305 jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value */
3306                                  jerry_value_t argument, /**< the argument */
3307                                  bool is_resolve) /**< whether the promise should be resolved or rejected */
3308 {
3309   jerry_assert_api_available ();
3310 
3311 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3312   if (!ecma_is_value_object (promise) || !ecma_is_promise (ecma_get_object_from_value (promise)))
3313   {
3314     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3315   }
3316 
3317   if (ecma_is_value_error_reference (argument))
3318   {
3319     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
3320   }
3321 
3322   lit_magic_string_id_t prop_name = (is_resolve ? LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION
3323                                                 : LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
3324 
3325   ecma_value_t function = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (promise), prop_name);
3326 
3327   ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function),
3328                                             ECMA_VALUE_UNDEFINED,
3329                                             &argument,
3330                                             1);
3331 
3332   ecma_free_value (function);
3333 
3334   return ret;
3335 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3336   JERRY_UNUSED (promise);
3337   JERRY_UNUSED (argument);
3338   JERRY_UNUSED (is_resolve);
3339 
3340   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported.")));
3341 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3342 } /* jerry_resolve_or_reject_promise */
3343 
3344 /**
3345  * Get the result of a promise.
3346  *
3347  * @return - Promise result
3348  *         - Type error if the promise support was not enabled or the input was not a promise object
3349  */
3350 jerry_value_t
jerry_get_promise_result(const jerry_value_t promise)3351 jerry_get_promise_result (const jerry_value_t promise) /**< promise object to get the result from */
3352 {
3353   jerry_assert_api_available ();
3354 
3355 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3356   if (!jerry_value_is_promise (promise))
3357   {
3358     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3359   }
3360 
3361   return ecma_promise_get_result (ecma_get_object_from_value (promise));
3362 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3363   JERRY_UNUSED (promise);
3364   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Promise not supported.")));
3365 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3366 } /* jerry_get_promise_result */
3367 
3368 /**
3369  * Get the state of a promise object.
3370  *
3371  * @return - the state of the promise (one of the jerry_promise_state_t enum values)
3372  *         - JERRY_PROMISE_STATE_NONE is only returned if the input is not a promise object
3373  *           or the promise support was not enabled.
3374  */
3375 jerry_promise_state_t
jerry_get_promise_state(const jerry_value_t promise)3376 jerry_get_promise_state (const jerry_value_t promise) /**< promise object to get the state from */
3377 {
3378   jerry_assert_api_available ();
3379 
3380 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
3381   if (!jerry_value_is_promise (promise))
3382   {
3383     return JERRY_PROMISE_STATE_NONE;
3384   }
3385 
3386   uint16_t flags = ecma_promise_get_flags (ecma_get_object_from_value (promise));
3387   flags &= (ECMA_PROMISE_IS_PENDING | ECMA_PROMISE_IS_FULFILLED);
3388 
3389   return (flags ? flags : JERRY_PROMISE_STATE_REJECTED);
3390 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3391   JERRY_UNUSED (promise);
3392   return JERRY_PROMISE_STATE_NONE;
3393 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
3394 } /* jerry_get_promise_state */
3395 
3396 /**
3397  * Call the SymbolDescriptiveString ecma builtin operation on the symbol value.
3398  *
3399  * Note:
3400  *      returned value must be freed with jerry_release_value, when it is no longer needed.
3401  *
3402  * @return string value containing the symbol's descriptive string - if success
3403  *         thrown error - otherwise
3404  */
3405 jerry_value_t
jerry_get_symbol_descriptive_string(const jerry_value_t symbol)3406 jerry_get_symbol_descriptive_string (const jerry_value_t symbol) /**< symbol value */
3407 {
3408   jerry_assert_api_available ();
3409 
3410 #if ENABLED (JERRY_ES2015)
3411   if (!ecma_is_value_symbol (symbol))
3412   {
3413     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3414   }
3415 
3416   /* Note: This operation cannot throw an error */
3417   return ecma_get_symbol_descriptive_string (symbol);
3418 #else /* !ENABLED (JERRY_ES2015) */
3419   JERRY_UNUSED (symbol);
3420 
3421   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Symbol is not supported.")));
3422 #endif /* ENABLED (JERRY_ES2015) */
3423 } /** jerry_get_symbol_descriptive_string */
3424 
3425 /**
3426  * Validate UTF-8 string
3427  *
3428  * @return true - if UTF-8 string is well-formed
3429  *         false - otherwise
3430  */
3431 bool
jerry_is_valid_utf8_string(const jerry_char_t * utf8_buf_p,jerry_size_t buf_size)3432 jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */
3433                             jerry_size_t buf_size) /**< string size */
3434 {
3435   return lit_is_valid_utf8_string ((lit_utf8_byte_t *) utf8_buf_p,
3436                                    (lit_utf8_size_t) buf_size);
3437 } /* jerry_is_valid_utf8_string */
3438 
3439 /**
3440  * Validate CESU-8 string
3441  *
3442  * @return true - if CESU-8 string is well-formed
3443  *         false - otherwise
3444  */
3445 bool
jerry_is_valid_cesu8_string(const jerry_char_t * cesu8_buf_p,jerry_size_t buf_size)3446 jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string */
3447                              jerry_size_t buf_size) /**< string size */
3448 {
3449   return lit_is_valid_cesu8_string ((lit_utf8_byte_t *) cesu8_buf_p,
3450                                     (lit_utf8_size_t) buf_size);
3451 } /* jerry_is_valid_cesu8_string */
3452 
3453 /**
3454  * Allocate memory on the engine's heap.
3455  *
3456  * Note:
3457  *      This function may take away memory from the executed JavaScript code.
3458  *      If any other dynamic memory allocation API is available (e.g., libc
3459  *      malloc), it should be used instead.
3460  *
3461  * @return allocated memory on success
3462  *         NULL otherwise
3463  */
3464 void *
jerry_heap_alloc(size_t size)3465 jerry_heap_alloc (size_t size) /**< size of the memory block */
3466 {
3467   jerry_assert_api_available ();
3468 
3469   return jmem_heap_alloc_block_null_on_error (size);
3470 } /* jerry_heap_alloc */
3471 
3472 /**
3473  * Free memory allocated on the engine's heap.
3474  */
3475 void
jerry_heap_free(void * mem_p,size_t size)3476 jerry_heap_free (void *mem_p, /**< value returned by jerry_heap_alloc */
3477                  size_t size) /**< same size as passed to jerry_heap_alloc */
3478 {
3479   jerry_assert_api_available ();
3480 
3481   jmem_heap_free_block (mem_p, size);
3482 } /* jerry_heap_free */
3483 
3484 /**
3485  * Create an external engine context.
3486  *
3487  * @return the pointer to the context.
3488  */
3489 jerry_context_t *
jerry_create_context(uint32_t heap_size,jerry_context_alloc_t alloc,void * cb_data_p)3490 jerry_create_context (uint32_t heap_size, /**< the size of heap */
3491                       jerry_context_alloc_t alloc, /**< the alloc function */
3492                       void *cb_data_p) /**< the cb_data for alloc function */
3493 {
3494   JERRY_UNUSED (heap_size);
3495 
3496 #if ENABLED (JERRY_EXTERNAL_CONTEXT)
3497 
3498   size_t total_size = sizeof (jerry_context_t) + JMEM_ALIGNMENT;
3499 
3500 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
3501   heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT);
3502 
3503   /* Minimum heap size is 1Kbyte. */
3504   if (heap_size < 1024)
3505   {
3506     return NULL;
3507   }
3508 
3509   total_size += heap_size;
3510 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
3511 
3512   total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
3513 
3514   jerry_context_t *context_p = (jerry_context_t *) alloc (total_size, cb_data_p);
3515 
3516   if (context_p == NULL)
3517   {
3518     return NULL;
3519   }
3520 
3521   memset (context_p, 0, total_size);
3522 
3523   uintptr_t context_ptr = ((uintptr_t) context_p) + sizeof (jerry_context_t);
3524   context_ptr = JERRY_ALIGNUP (context_ptr, (uintptr_t) JMEM_ALIGNMENT);
3525 
3526   uint8_t *byte_p = (uint8_t *) context_ptr;
3527 
3528 #if !ENABLED (JERRY_SYSTEM_ALLOCATOR)
3529   context_p->heap_p = (jmem_heap_t *) byte_p;
3530   context_p->heap_size = heap_size;
3531   byte_p += heap_size;
3532 #endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */
3533 
3534   JERRY_ASSERT (byte_p <= ((uint8_t *) context_p) + total_size);
3535 
3536   JERRY_UNUSED (byte_p);
3537   return context_p;
3538 
3539 #else /* !ENABLED (JERRY_EXTERNAL_CONTEXT) */
3540 
3541   JERRY_UNUSED (alloc);
3542   JERRY_UNUSED (cb_data_p);
3543 
3544   return NULL;
3545 
3546 #endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */
3547 } /* jerry_create_context */
3548 
3549 /**
3550  * If JERRY_VM_EXEC_STOP is enabled the callback passed to this function is
3551  * periodically called with the user_p argument. If frequency is greater
3552  * than 1, the callback is only called at every frequency ticks.
3553  */
3554 void
jerry_set_vm_exec_stop_callback(jerry_vm_exec_stop_callback_t stop_cb,void * user_p,uint32_t frequency)3555 jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< periodically called user function */
3556                                  void *user_p, /**< pointer passed to the function */
3557                                  uint32_t frequency) /**< frequency of the function call */
3558 {
3559 #if ENABLED (JERRY_VM_EXEC_STOP)
3560   if (frequency == 0)
3561   {
3562     frequency = 1;
3563   }
3564 
3565   JERRY_CONTEXT (vm_exec_stop_frequency) = frequency;
3566   JERRY_CONTEXT (vm_exec_stop_counter) = frequency;
3567   JERRY_CONTEXT (vm_exec_stop_user_p) = user_p;
3568   JERRY_CONTEXT (vm_exec_stop_cb) = stop_cb;
3569 #else /* !ENABLED (JERRY_VM_EXEC_STOP) */
3570   JERRY_UNUSED (stop_cb);
3571   JERRY_UNUSED (user_p);
3572   JERRY_UNUSED (frequency);
3573 #endif /* ENABLED (JERRY_VM_EXEC_STOP) */
3574 } /* jerry_set_vm_exec_stop_callback */
3575 
3576 /**
3577  * Get backtrace. The backtrace is an array of strings where
3578  * each string contains the position of the corresponding frame.
3579  * The array length is zero if the backtrace is not available.
3580  *
3581  * @return array value
3582  */
3583 jerry_value_t
jerry_get_backtrace(uint32_t max_depth)3584 jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */
3585 {
3586   return vm_get_backtrace (max_depth);
3587 } /* jerry_get_backtrace */
3588 
3589 /**
3590  * Get the resource name (usually a file name) of the currently executed script or the given function object
3591  *
3592  * Note: returned value must be freed with jerry_release_value, when it is no longer needed
3593  *
3594  * @return JS string constructed from
3595  *         - the currently executed function object's resource name, if the given value is undefined
3596  *         - resource name of the function object, if the given value is a function object
3597  *         - "<anonymous>", otherwise
3598  */
3599 jerry_value_t
jerry_get_resource_name(const jerry_value_t value)3600 jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
3601 {
3602 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3603   if (ecma_is_value_undefined (value))
3604   {
3605     if (JERRY_CONTEXT (vm_top_context_p) != NULL)
3606     {
3607       return ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->resource_name);
3608     }
3609   }
3610 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3611 #if ENABLED (JERRY_LINE_INFO)
3612   else if (ecma_is_value_object (value))
3613   {
3614     ecma_object_t *obj_p = ecma_get_object_from_value (value);
3615 
3616     if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
3617         && !ecma_get_object_is_builtin (obj_p))
3618     {
3619       ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
3620 
3621       const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
3622 
3623       return ecma_copy_value (ecma_op_resource_name (bytecode_data_p));
3624     }
3625   }
3626 #endif /* ENABLED (JERRY_LINE_INFO) */
3627 
3628   JERRY_UNUSED (value);
3629   return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
3630 } /* jerry_get_resource_name */
3631 
3632 /**
3633  * Access the "new.target" value.
3634  *
3635  * The "new.target" value depends on the current call site. That is
3636  * this method will only have a function object result if, at the call site
3637  * it was called inside a constructor method invoked with "new".
3638  *
3639  * @return "undefined" - if at the call site it was not a constructor call.
3640  *         function object - if the current call site is in a constructor call.
3641  */
3642 jerry_value_t
jerry_get_new_target(void)3643 jerry_get_new_target (void)
3644 {
3645 #if ENABLED (JERRY_ES2015)
3646   ecma_object_t *current_new_target = JERRY_CONTEXT (current_new_target);
3647 
3648   if (current_new_target == NULL)
3649   {
3650     return jerry_create_undefined ();
3651   }
3652 
3653   ecma_ref_object (current_new_target);
3654   return ecma_make_object_value (current_new_target);
3655 #else /* !ENABLED (JERRY_ES2015) */
3656   return jerry_create_undefined ();
3657 #endif /* ENABLED (JERRY_ES2015) */
3658 } /* jerry_get_new_target */
3659 
3660 /**
3661  * Check if the given value is an ArrayBuffer object.
3662  *
3663  * @return true - if it is an ArrayBuffer object
3664  *         false - otherwise
3665  */
3666 bool
jerry_value_is_arraybuffer(const jerry_value_t value)3667 jerry_value_is_arraybuffer (const jerry_value_t value) /**< value to check if it is an ArrayBuffer */
3668 {
3669   jerry_assert_api_available ();
3670 
3671 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3672   return ecma_is_arraybuffer (value);
3673 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3674   JERRY_UNUSED (value);
3675   return false;
3676 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3677 } /* jerry_value_is_arraybuffer */
3678 
3679 /**
3680  * Creates an ArrayBuffer object with the given length (size).
3681  *
3682  * Notes:
3683  *      * the length is specified in bytes.
3684  *      * returned value must be freed with jerry_release_value, when it is no longer needed.
3685  *      * if the typed arrays are disabled this will return a TypeError.
3686  *
3687  * @return value of the constructed ArrayBuffer object
3688  */
3689 jerry_value_t
jerry_create_arraybuffer(const jerry_length_t size)3690 jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffer to create */
3691 {
3692   jerry_assert_api_available ();
3693 
3694 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3695   return jerry_return (ecma_make_object_value (ecma_arraybuffer_new_object (size)));
3696 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3697   JERRY_UNUSED (size);
3698   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported.")));
3699 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3700 } /* jerry_create_arraybuffer */
3701 
3702 /**
3703  * Creates an ArrayBuffer object with user specified buffer.
3704  *
3705  * Notes:
3706  *     * the size is specified in bytes.
3707  *     * the buffer passed should be at least the specified bytes big.
3708  *     * if the typed arrays are disabled this will return a TypeError.
3709  *     * if the size is zero or buffer_p is a null pointer this will return an empty ArrayBuffer.
3710  *
3711  * @return value of the construced ArrayBuffer object
3712  */
3713 jerry_value_t
jerry_create_arraybuffer_external(const jerry_length_t size,uint8_t * buffer_p,jerry_object_native_free_callback_t free_cb)3714 jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */
3715                                    uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */
3716                                    jerry_object_native_free_callback_t free_cb) /**< buffer free callback */
3717 {
3718   jerry_assert_api_available ();
3719 
3720 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3721   ecma_object_t *arraybuffer;
3722 
3723   if (JERRY_UNLIKELY (size == 0 || buffer_p == NULL))
3724   {
3725     arraybuffer = ecma_arraybuffer_new_object_external (0, NULL, (ecma_object_native_free_callback_t) free_cb);
3726   }
3727   else
3728   {
3729     arraybuffer = ecma_arraybuffer_new_object_external (size,
3730                                                         buffer_p,
3731                                                         (ecma_object_native_free_callback_t) free_cb);
3732   }
3733 
3734   return jerry_return (ecma_make_object_value (arraybuffer));
3735 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3736   JERRY_UNUSED (size);
3737   JERRY_UNUSED (buffer_p);
3738   JERRY_UNUSED (free_cb);
3739   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported.")));
3740 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3741 } /* jerry_create_arraybuffer_external */
3742 
3743 /**
3744  * Copy bytes into the ArrayBuffer from a buffer.
3745  *
3746  * Note:
3747  *     * if the object passed is not an ArrayBuffer will return 0.
3748  *
3749  * @return number of bytes copied into the ArrayBuffer.
3750  */
3751 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)3752 jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer */
3753                          jerry_length_t offset, /**< start offset of the ArrayBuffer */
3754                          const uint8_t *buf_p, /**< buffer to copy from */
3755                          jerry_length_t buf_size) /**< number of bytes to copy from the buffer */
3756 {
3757   jerry_assert_api_available ();
3758 
3759 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3760   if (!ecma_is_arraybuffer (value))
3761   {
3762     return 0;
3763   }
3764 
3765   ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3766   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
3767 
3768   if (offset >= length)
3769   {
3770     return 0;
3771   }
3772 
3773   jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
3774 
3775   if (copy_count > 0)
3776   {
3777     lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3778 
3779     memcpy ((void *) (mem_buffer_p + offset), (void *) buf_p, copy_count);
3780   }
3781 
3782   return copy_count;
3783 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3784   JERRY_UNUSED (value);
3785   JERRY_UNUSED (offset);
3786   JERRY_UNUSED (buf_p);
3787   JERRY_UNUSED (buf_size);
3788   return 0;
3789 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3790 } /* jerry_arraybuffer_write */
3791 
3792 /**
3793  * Copy bytes from a buffer into an ArrayBuffer.
3794  *
3795  * Note:
3796  *     * if the object passed is not an ArrayBuffer will return 0.
3797  *
3798  * @return number of bytes read from the ArrayBuffer.
3799  */
3800 jerry_length_t
jerry_arraybuffer_read(const jerry_value_t value,jerry_length_t offset,uint8_t * buf_p,jerry_length_t buf_size)3801 jerry_arraybuffer_read (const jerry_value_t value, /**< ArrayBuffer to read from */
3802                         jerry_length_t offset, /**< start offset of the ArrayBuffer */
3803                         uint8_t *buf_p, /**< destination buffer to copy to */
3804                         jerry_length_t buf_size) /**< number of bytes to copy into the buffer */
3805 {
3806   jerry_assert_api_available ();
3807 
3808 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3809   if (!ecma_is_arraybuffer (value))
3810   {
3811     return 0;
3812   }
3813 
3814   ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3815   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
3816 
3817   if (offset >= length)
3818   {
3819     return 0;
3820   }
3821 
3822   jerry_length_t copy_count = JERRY_MIN (length - offset, buf_size);
3823 
3824   if (copy_count > 0)
3825   {
3826     lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3827 
3828     memcpy ((void *) buf_p, (void *) (mem_buffer_p + offset), copy_count);
3829   }
3830 
3831   return copy_count;
3832 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3833   JERRY_UNUSED (value);
3834   JERRY_UNUSED (offset);
3835   JERRY_UNUSED (buf_p);
3836   JERRY_UNUSED (buf_size);
3837   return 0;
3838 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3839 } /* jerry_arraybuffer_read */
3840 
3841 /**
3842  * Get the length (size) of the ArrayBuffer in bytes.
3843  *
3844  * Note:
3845  *     This is the 'byteLength' property of an ArrayBuffer.
3846  *
3847  * @return the length of the ArrayBuffer in bytes.
3848  */
3849 jerry_length_t
jerry_get_arraybuffer_byte_length(const jerry_value_t value)3850 jerry_get_arraybuffer_byte_length (const jerry_value_t value) /**< ArrayBuffer */
3851 {
3852   jerry_assert_api_available ();
3853 
3854 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3855   if (ecma_is_arraybuffer (value))
3856   {
3857     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3858     return ecma_arraybuffer_get_length (buffer_p);
3859   }
3860 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3861   JERRY_UNUSED (value);
3862 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3863   return 0;
3864 } /* jerry_get_arraybuffer_byte_length */
3865 
3866 /**
3867  * Get a pointer for the start of the ArrayBuffer.
3868  *
3869  * Note:
3870  *    * This is a high-risk operation as the bounds are not checked
3871  *      when accessing the pointer elements.
3872  *
3873  * @return pointer to the back-buffer of the ArrayBuffer.
3874  *         pointer is NULL if the parameter is not an ArrayBuffer
3875  */
3876 uint8_t *
jerry_get_arraybuffer_pointer(const jerry_value_t array_buffer)3877 jerry_get_arraybuffer_pointer (const jerry_value_t array_buffer) /**< Array Buffer to use */
3878 {
3879   jerry_assert_api_available ();
3880 
3881 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3882   if (ecma_is_value_error_reference (array_buffer)
3883       || !ecma_is_arraybuffer (array_buffer))
3884   {
3885     return NULL;
3886   }
3887 
3888   ecma_object_t *buffer_p = ecma_get_object_from_value (array_buffer);
3889   lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
3890   return (uint8_t *const) mem_buffer_p;
3891 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3892   JERRY_UNUSED (array_buffer);
3893 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3894 
3895   return NULL;
3896 } /* jerry_get_arraybuffer_pointer */
3897 
3898 /**
3899  * Get if the ArrayBuffer is detachable.
3900  *
3901  * @return boolean value - if success
3902  *         value marked with error flag - otherwise
3903  */
3904 jerry_value_t
jerry_is_arraybuffer_detachable(const jerry_value_t value)3905 jerry_is_arraybuffer_detachable (const jerry_value_t value) /**< ArrayBuffer */
3906 {
3907   jerry_assert_api_available ();
3908 
3909 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3910   if (ecma_is_arraybuffer (value))
3911   {
3912     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3913     return ecma_arraybuffer_is_detachable (buffer_p) ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
3914   }
3915 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3916   JERRY_UNUSED (value);
3917 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3918   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer")));
3919 } /* jerry_is_arraybuffer_detachable */
3920 
3921 /**
3922  * Detach the underlying data block from ArrayBuffer and set its bytelength to 0.
3923  * This operation requires the ArrayBuffer to be external that created by
3924  * `jerry_create_arraybuffer_external`.
3925  *
3926  * @return null value - if success
3927  *         value marked with error flag - otherwise
3928  */
3929 jerry_value_t
jerry_detach_arraybuffer(const jerry_value_t value)3930 jerry_detach_arraybuffer (const jerry_value_t value) /**< ArrayBuffer */
3931 {
3932   jerry_assert_api_available ();
3933 
3934 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
3935   if (ecma_is_arraybuffer (value))
3936   {
3937     ecma_object_t *buffer_p = ecma_get_object_from_value (value);
3938     bool detached = ecma_arraybuffer_detach (buffer_p);
3939     if (!detached)
3940     {
3941       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects a detachable ArrayBuffer.")));
3942     }
3943     return ECMA_VALUE_NULL;
3944   }
3945 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3946   JERRY_UNUSED (value);
3947 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
3948   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expects an ArrayBuffer")));
3949 } /* jerry_detach_arraybuffer */
3950 
3951 /**
3952  * DataView related functions
3953  */
3954 
3955 /**
3956  * Creates a DataView object with the given ArrayBuffer, ByteOffset and ByteLength arguments.
3957  *
3958  * Notes:
3959  *      * returned value must be freed with jerry_release_value, when it is no longer needed.
3960  *      * if the DataView bulitin is disabled this will return a TypeError.
3961  *
3962  * @return value of the constructed DataView object - if success
3963  *         created error - otherwise
3964  */
3965 jerry_value_t
jerry_create_dataview(const jerry_value_t array_buffer,const jerry_length_t byte_offset,const jerry_length_t byte_length)3966 jerry_create_dataview (const jerry_value_t array_buffer, /**< arraybuffer to create DataView from */
3967                        const jerry_length_t byte_offset, /**< offset in bytes, to the first byte in the buffer */
3968                        const jerry_length_t byte_length) /**< number of elements in the byte array */
3969 {
3970   jerry_assert_api_available ();
3971 
3972 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
3973   if (ecma_is_value_error_reference (array_buffer))
3974   {
3975     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
3976   }
3977 
3978   ecma_value_t arguments_p[3] =
3979   {
3980     array_buffer,
3981     ecma_make_uint32_value (byte_offset),
3982     ecma_make_uint32_value (byte_length)
3983   };
3984 
3985   return jerry_return (ecma_op_dataview_create (arguments_p, 3));
3986 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
3987   JERRY_UNUSED (array_buffer);
3988   JERRY_UNUSED (byte_offset);
3989   JERRY_UNUSED (byte_length);
3990   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported.")));
3991 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
3992 } /* jerry_create_dataview */
3993 
3994 /**
3995  * Check if the given value is a DataView object.
3996  *
3997  * @return true - if it is a DataView object
3998  *         false - otherwise
3999  */
4000 bool
jerry_value_is_dataview(const jerry_value_t value)4001 jerry_value_is_dataview (const jerry_value_t value) /**< value to check if it is a DataView object */
4002 {
4003   jerry_assert_api_available ();
4004 
4005 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
4006   return ecma_is_dataview (value);
4007 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
4008   JERRY_UNUSED (value);
4009   return false;
4010 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
4011 } /* jerry_value_is_dataview */
4012 
4013 /**
4014  * Get the underlying ArrayBuffer from a DataView.
4015  *
4016  * Additionally the byteLength and byteOffset properties are also returned
4017  * which were specified when the DataView was created.
4018  *
4019  * Note:
4020  *     the returned value must be freed with a jerry_release_value call
4021  *
4022  * @return ArrayBuffer of a DataView
4023  *         TypeError if the object is not a DataView.
4024  */
4025 jerry_value_t
jerry_get_dataview_buffer(const jerry_value_t value,jerry_length_t * byte_offset,jerry_length_t * byte_length)4026 jerry_get_dataview_buffer (const jerry_value_t value, /**< DataView to get the arraybuffer from */
4027                            jerry_length_t *byte_offset, /**< [out] byteOffset property */
4028                            jerry_length_t *byte_length) /**< [out] byteLength property */
4029 {
4030   jerry_assert_api_available ();
4031 
4032 #if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
4033   if (ecma_is_value_error_reference (value))
4034   {
4035     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
4036   }
4037 
4038   ecma_dataview_object_t *dataview_p = ecma_op_dataview_get_object (value);
4039 
4040   if (JERRY_UNLIKELY (dataview_p == NULL))
4041   {
4042     return ecma_create_error_reference_from_context ();
4043   }
4044 
4045   if (byte_offset != NULL)
4046   {
4047     *byte_offset = dataview_p->byte_offset;
4048   }
4049 
4050   if (byte_length != NULL)
4051   {
4052     *byte_length = dataview_p->header.u.class_prop.u.length;
4053   }
4054 
4055   ecma_object_t *arraybuffer_p = dataview_p->buffer_p;
4056   ecma_ref_object (arraybuffer_p);
4057 
4058   return ecma_make_object_value (arraybuffer_p);
4059 #else /* !ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
4060   JERRY_UNUSED (value);
4061   JERRY_UNUSED (byte_offset);
4062   JERRY_UNUSED (byte_length);
4063   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("DataView is not supported.")));
4064 #endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
4065 } /* jerry_get_dataview_buffer */
4066 
4067 /**
4068  * TypedArray related functions
4069  */
4070 
4071 /**
4072  * Check if the given value is a TypedArray object.
4073  *
4074  * @return true - if it is a TypedArray object
4075  *         false - otherwise
4076  */
4077 bool
jerry_value_is_typedarray(jerry_value_t value)4078 jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a TypedArray */
4079 {
4080   jerry_assert_api_available ();
4081 
4082 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4083   return ecma_is_typedarray (value);
4084 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4085   JERRY_UNUSED (value);
4086   return false;
4087 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4088 } /* jerry_value_is_typedarray */
4089 
4090 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4091 /**
4092  * TypedArray mapping type
4093  */
4094 typedef struct
4095 {
4096   jerry_typedarray_type_t api_type; /**< api type */
4097   ecma_builtin_id_t prototype_id; /**< prototype ID */
4098   ecma_typedarray_type_t id; /**< typedArray ID */
4099   uint8_t element_size_shift; /**< element size shift */
4100 } jerry_typedarray_mapping_t;
4101 
4102 /**
4103  * List of TypedArray mappings
4104  */
4105 static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
4106 {
4107 #define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \
4108   { JERRY_TYPEDARRAY_ ## NAME, ECMA_BUILTIN_ID_ ## NAME ## ARRAY_PROTOTYPE, \
4109     ECMA_ ## LIT_NAME ## _ARRAY, SIZE_SHIFT }
4110 
4111   TYPEDARRAY_ENTRY (UINT8, UINT8, 0),
4112   TYPEDARRAY_ENTRY (UINT8CLAMPED, UINT8_CLAMPED, 0),
4113   TYPEDARRAY_ENTRY (INT8, INT8, 0),
4114   TYPEDARRAY_ENTRY (UINT16, UINT16, 1),
4115   TYPEDARRAY_ENTRY (INT16, INT16, 1),
4116   TYPEDARRAY_ENTRY (UINT32, UINT32, 2),
4117   TYPEDARRAY_ENTRY (INT32, INT32, 2),
4118   TYPEDARRAY_ENTRY (FLOAT32, FLOAT32, 2),
4119 #if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
4120   TYPEDARRAY_ENTRY (FLOAT64, FLOAT64, 3),
4121 #endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
4122 
4123 #undef TYPEDARRAY_ENTRY
4124 };
4125 
4126 /**
4127  * Helper function to get the TypedArray prototype, typedArray id, and element size shift
4128  * information.
4129  *
4130  * @return true - if the TypedArray information was found
4131  *         false - if there is no such TypedArray type
4132  */
4133 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)4134 jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of the TypedArray */
4135                                ecma_builtin_id_t *prototype_id, /**< [out] found prototype object id */
4136                                ecma_typedarray_type_t *id, /**< [out] found typedArray id */
4137                                uint8_t *element_size_shift) /**< [out] found element size shift value */
4138 {
4139   JERRY_ASSERT (prototype_id != NULL);
4140   JERRY_ASSERT (id != NULL);
4141   JERRY_ASSERT (element_size_shift != NULL);
4142 
4143   for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
4144   {
4145     if (type_name == jerry_typedarray_mappings[i].api_type)
4146     {
4147       *prototype_id = jerry_typedarray_mappings[i].prototype_id;
4148       *id = jerry_typedarray_mappings[i].id;
4149       *element_size_shift = jerry_typedarray_mappings[i].element_size_shift;
4150       return true;
4151     }
4152   }
4153 
4154   return false;
4155 } /* jerry_typedarray_find_by_type */
4156 
4157 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4158 
4159 /**
4160  * Create a TypedArray object with a given type and length.
4161  *
4162  * Notes:
4163  *      * returns TypeError if an incorrect type (type_name) is specified.
4164  *      * byteOffset property will be set to 0.
4165  *      * byteLength property will be a multiple of the length parameter (based on the type).
4166  *
4167  * @return - new TypedArray object
4168  */
4169 jerry_value_t
jerry_create_typedarray(jerry_typedarray_type_t type_name,jerry_length_t length)4170 jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4171                          jerry_length_t length) /**< element count of the new TypedArray */
4172 {
4173   jerry_assert_api_available ();
4174 
4175 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4176   ecma_builtin_id_t prototype_id = 0;
4177   ecma_typedarray_type_t id = 0;
4178   uint8_t element_size_shift = 0;
4179 
4180   if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
4181   {
4182     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
4183   }
4184 
4185   ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
4186 
4187   ecma_value_t array_value = ecma_typedarray_create_object_with_length (length,
4188                                                                         NULL,
4189                                                                         prototype_obj_p,
4190                                                                         element_size_shift,
4191                                                                         id);
4192 
4193   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
4194 
4195   return array_value;
4196 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4197   JERRY_UNUSED (type_name);
4198   JERRY_UNUSED (length);
4199   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4200 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4201 } /* jerry_create_typedarray */
4202 
4203 /**
4204  * Create a TypedArray object using the given arraybuffer and size information.
4205  *
4206  * Notes:
4207  *      * returns TypeError if an incorrect type (type_name) is specified.
4208  *      * this is the 'new %TypedArray%(arraybuffer, byteOffset, length)' equivalent call.
4209  *
4210  * @return - new TypedArray object
4211  */
4212 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)4213 jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4214                                             const jerry_value_t arraybuffer, /**< ArrayBuffer to use */
4215                                             jerry_length_t byte_offset, /**< offset for the ArrayBuffer */
4216                                             jerry_length_t length) /**< number of elements to use from ArrayBuffer */
4217 {
4218   jerry_assert_api_available ();
4219 
4220 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4221   if (ecma_is_value_error_reference (arraybuffer))
4222   {
4223     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4224   }
4225 
4226   ecma_builtin_id_t prototype_id = 0;
4227   ecma_typedarray_type_t id = 0;
4228   uint8_t element_size_shift = 0;
4229 
4230   if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
4231   {
4232     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
4233   }
4234 
4235   if (!ecma_is_arraybuffer (arraybuffer))
4236   {
4237     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an ArrayBuffer")));
4238   }
4239 
4240   ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id);
4241   ecma_value_t arguments_p[3] =
4242   {
4243     arraybuffer,
4244     ecma_make_uint32_value (byte_offset),
4245     ecma_make_uint32_value (length)
4246   };
4247 
4248   ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, id);
4249   ecma_free_value (arguments_p[1]);
4250   ecma_free_value (arguments_p[2]);
4251 
4252   return jerry_return (array_value);
4253 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4254   JERRY_UNUSED (type_name);
4255   JERRY_UNUSED (arraybuffer);
4256   JERRY_UNUSED (byte_offset);
4257   JERRY_UNUSED (length);
4258   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4259 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4260 } /* jerry_create_typedarray_for_arraybuffer_sz */
4261 
4262 /**
4263  * Create a TypedArray object using the given arraybuffer and size information.
4264  *
4265  * Notes:
4266  *      * returns TypeError if an incorrect type (type_name) is specified.
4267  *      * this is the 'new %TypedArray%(arraybuffer)' equivalent call.
4268  *
4269  * @return - new TypedArray object
4270  */
4271 jerry_value_t
jerry_create_typedarray_for_arraybuffer(jerry_typedarray_type_t type_name,const jerry_value_t arraybuffer)4272 jerry_create_typedarray_for_arraybuffer (jerry_typedarray_type_t type_name, /**< type of TypedArray to create */
4273                                          const jerry_value_t arraybuffer) /**< ArrayBuffer to use */
4274 {
4275   jerry_assert_api_available ();
4276 
4277 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4278   if (ecma_is_value_error_reference (arraybuffer))
4279   {
4280     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4281   }
4282 
4283   jerry_length_t byteLength = jerry_get_arraybuffer_byte_length (arraybuffer);
4284   return jerry_create_typedarray_for_arraybuffer_sz (type_name, arraybuffer, 0, byteLength);
4285 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4286   JERRY_UNUSED (type_name);
4287   JERRY_UNUSED (arraybuffer);
4288   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
4289 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4290 } /* jerry_create_typedarray_for_arraybuffer */
4291 
4292 /**
4293  * Get the type of the TypedArray.
4294  *
4295  * @return - type of the TypedArray
4296  *         - JERRY_TYPEDARRAY_INVALID if the argument is not a TypedArray
4297  */
4298 jerry_typedarray_type_t
jerry_get_typedarray_type(jerry_value_t value)4299 jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArray type */
4300 {
4301   jerry_assert_api_available ();
4302 
4303 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4304   if (!ecma_is_typedarray (value))
4305   {
4306     return JERRY_TYPEDARRAY_INVALID;
4307   }
4308 
4309   ecma_object_t *array_p = ecma_get_object_from_value (value);
4310   ecma_typedarray_type_t class_type = ecma_get_typedarray_id (array_p);
4311 
4312   for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
4313   {
4314     if (class_type == jerry_typedarray_mappings[i].id)
4315     {
4316       return jerry_typedarray_mappings[i].api_type;
4317     }
4318   }
4319 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4320   JERRY_UNUSED (value);
4321 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4322 
4323   return JERRY_TYPEDARRAY_INVALID;
4324 } /* jerry_get_typedarray_type */
4325 
4326 /**
4327  * Get the element count of the TypedArray.
4328  *
4329  * @return length of the TypedArray.
4330  */
4331 jerry_length_t
jerry_get_typedarray_length(jerry_value_t value)4332 jerry_get_typedarray_length (jerry_value_t value) /**< TypedArray to query */
4333 {
4334   jerry_assert_api_available ();
4335 
4336 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4337   if (ecma_is_typedarray (value))
4338   {
4339     ecma_object_t *array_p = ecma_get_object_from_value (value);
4340     return ecma_typedarray_get_length (array_p);
4341   }
4342 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4343   JERRY_UNUSED (value);
4344 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4345 
4346   return 0;
4347 } /* jerry_get_typedarray_length */
4348 
4349 /**
4350  * Get the underlying ArrayBuffer from a TypedArray.
4351  *
4352  * Additionally the byteLength and byteOffset properties are also returned
4353  * which were specified when the TypedArray was created.
4354  *
4355  * Note:
4356  *     the returned value must be freed with a jerry_release_value call
4357  *
4358  * @return ArrayBuffer of a TypedArray
4359  *         TypeError if the object is not a TypedArray.
4360  */
4361 jerry_value_t
jerry_get_typedarray_buffer(jerry_value_t value,jerry_length_t * byte_offset,jerry_length_t * byte_length)4362 jerry_get_typedarray_buffer (jerry_value_t value, /**< TypedArray to get the arraybuffer from */
4363                              jerry_length_t *byte_offset, /**< [out] byteOffset property */
4364                              jerry_length_t *byte_length) /**< [out] byteLength property */
4365 {
4366   jerry_assert_api_available ();
4367 
4368 #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
4369   if (!ecma_is_typedarray (value))
4370   {
4371     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Object is not a TypedArray.")));
4372   }
4373 
4374   ecma_object_t *array_p = ecma_get_object_from_value (value);
4375   uint8_t shift = ecma_typedarray_get_element_size_shift (array_p);
4376 
4377   if (byte_length != NULL)
4378   {
4379     *byte_length = (jerry_length_t) (ecma_typedarray_get_length (array_p) << shift);
4380   }
4381 
4382   if (byte_offset != NULL)
4383   {
4384     *byte_offset = (jerry_length_t) ecma_typedarray_get_offset (array_p);
4385   }
4386 
4387   ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (array_p);
4388   ecma_ref_object (arraybuffer_p);
4389   return jerry_return (ecma_make_object_value (arraybuffer_p));
4390 #else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4391   JERRY_UNUSED (value);
4392   JERRY_UNUSED (byte_length);
4393   JERRY_UNUSED (byte_offset);
4394   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray is not supported.")));
4395 #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
4396 } /* jerry_get_typedarray_buffer */
4397 
4398 /**
4399  * Create an object from JSON
4400  *
4401  * Note:
4402  *      The returned value must be freed with jerry_release_value
4403  * @return jerry_value_t from json formated string or an error massage
4404  */
4405 jerry_value_t
jerry_json_parse(const jerry_char_t * string_p,jerry_size_t string_size)4406 jerry_json_parse (const jerry_char_t *string_p, /**< json string */
4407                   jerry_size_t string_size) /**< json string size */
4408 {
4409   jerry_assert_api_available ();
4410 
4411 #if ENABLED (JERRY_BUILTIN_JSON)
4412   ecma_value_t ret_value = ecma_builtin_json_parse_buffer (string_p, string_size);
4413 
4414   if (ecma_is_value_undefined (ret_value))
4415   {
4416     ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON string parse error.")));
4417   }
4418 
4419   return ret_value;
4420 #else /* !ENABLED (JERRY_BUILTIN_JSON) */
4421   JERRY_UNUSED (string_p);
4422   JERRY_UNUSED (string_size);
4423 
4424   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled.")));
4425 #endif /* ENABLED (JERRY_BUILTIN_JSON) */
4426 } /* jerry_json_parse */
4427 
4428 /**
4429  * Create a Json formated string from an object
4430  *
4431  * Note:
4432  *      The returned value must be freed with jerry_release_value
4433  * @return json formated jerry_value_t or an error massage
4434  */
4435 jerry_value_t
jerry_json_stringify(const jerry_value_t object_to_stringify)4436 jerry_json_stringify (const jerry_value_t object_to_stringify) /**< a jerry_object_t to stringify */
4437 {
4438   jerry_assert_api_available ();
4439 #if ENABLED (JERRY_BUILTIN_JSON)
4440   ecma_value_t ret_value = ecma_builtin_json_string_from_object (object_to_stringify);
4441 
4442   if (ecma_is_value_error_reference (object_to_stringify))
4443   {
4444     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4445   }
4446 
4447   if (ecma_is_value_undefined (ret_value))
4448   {
4449     ret_value = jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("JSON stringify error.")));
4450   }
4451 
4452   return ret_value;
4453 #else /* ENABLED (JERRY_BUILTIN_JSON) */
4454   JERRY_UNUSED (object_to_stringify);
4455 
4456   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled.")));
4457 #endif /* ENABLED (JERRY_BUILTIN_JSON) */
4458 } /* jerry_json_stringify */
4459 
4460 /**
4461  * Create a container type specified in jerry_container_type_t.
4462  * The container can be created with a list of arguments, which will be passed to the container constructor to be
4463  * inserted to the container.
4464  *
4465  * Note:
4466  *      The returned value must be freed with jerry_release_value
4467  * @return jerry_value_t representing a container with the given type.
4468  */
4469 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)4470 jerry_create_container (jerry_container_type_t container_type, /**< Type of the container */
4471                         const jerry_value_t *arguments_list_p, /**< arguments list */
4472                         jerry_length_t arguments_list_len) /**< Length of arguments list */
4473 {
4474   jerry_assert_api_available ();
4475 
4476 #if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER)
4477   for (jerry_length_t i = 0; i < arguments_list_len; i++)
4478   {
4479     if (ecma_is_value_error_reference (arguments_list_p[i]))
4480     {
4481       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
4482     }
4483   }
4484 
4485   lit_magic_string_id_t lit_id;
4486   ecma_builtin_id_t proto_id;
4487   ecma_builtin_id_t ctor_id;
4488 
4489   switch (container_type)
4490   {
4491 #if ENABLED (JERRY_ES2015_BUILTIN_MAP)
4492     case JERRY_CONTAINER_TYPE_MAP:
4493     {
4494       lit_id = LIT_MAGIC_STRING_MAP_UL;
4495       proto_id = ECMA_BUILTIN_ID_MAP_PROTOTYPE;
4496       ctor_id = ECMA_BUILTIN_ID_MAP;
4497       break;
4498     }
4499 #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
4500 #if ENABLED (JERRY_ES2015_BUILTIN_SET)
4501     case JERRY_CONTAINER_TYPE_SET:
4502     {
4503       lit_id = LIT_MAGIC_STRING_SET_UL;
4504       proto_id = ECMA_BUILTIN_ID_SET_PROTOTYPE;
4505       ctor_id = ECMA_BUILTIN_ID_SET;
4506       break;
4507     }
4508 #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
4509 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
4510     case JERRY_CONTAINER_TYPE_WEAKMAP:
4511     {
4512       lit_id = LIT_MAGIC_STRING_WEAKMAP_UL;
4513       proto_id = ECMA_BUILTIN_ID_WEAKMAP_PROTOTYPE;
4514       ctor_id = ECMA_BUILTIN_ID_WEAKMAP;
4515       break;
4516     }
4517 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */
4518 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
4519     case JERRY_CONTAINER_TYPE_WEAKSET:
4520     {
4521       lit_id = LIT_MAGIC_STRING_WEAKSET_UL;
4522       proto_id = ECMA_BUILTIN_ID_WEAKSET_PROTOTYPE;
4523       ctor_id = ECMA_BUILTIN_ID_WEAKSET;
4524       break;
4525     }
4526 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
4527     default:
4528     {
4529       return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Invalid container type.")));
4530     }
4531   }
4532   ecma_object_t * old_new_target_p = JERRY_CONTEXT (current_new_target);
4533 
4534   if (old_new_target_p == NULL)
4535   {
4536     JERRY_CONTEXT (current_new_target) = ecma_builtin_get (ctor_id);
4537   }
4538 
4539   ecma_value_t container_value = ecma_op_container_create (arguments_list_p,
4540                                                            arguments_list_len,
4541                                                            lit_id,
4542                                                            proto_id);
4543 
4544   JERRY_CONTEXT (current_new_target) = old_new_target_p;
4545   return container_value;
4546 #else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4547   JERRY_UNUSED (arguments_list_p);
4548   JERRY_UNUSED (arguments_list_len);
4549   JERRY_UNUSED (container_type);
4550   return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Containers are disabled.")));
4551 #endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4552 } /* jerry_create_container */
4553 
4554 /**
4555  * Get the type of the given container object.
4556  *
4557  * @return Corresponding type to the given container object.
4558  */
4559 jerry_container_type_t
jerry_get_container_type(const jerry_value_t value)4560 jerry_get_container_type (const jerry_value_t value) /**< the container object */
4561 {
4562   jerry_assert_api_available ();
4563 
4564 #if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER)
4565   if (ecma_is_value_object (value))
4566   {
4567     ecma_object_t *obj_p = ecma_get_object_from_value (value);
4568 
4569     if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS)
4570     {
4571       uint16_t type = ((ecma_extended_object_t *) obj_p)->u.class_prop.class_id;
4572 
4573       switch (type)
4574       {
4575 #if ENABLED (JERRY_ES2015_BUILTIN_MAP)
4576         case LIT_MAGIC_STRING_MAP_UL:
4577         {
4578           return JERRY_CONTAINER_TYPE_MAP;
4579         }
4580 #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
4581 #if ENABLED (JERRY_ES2015_BUILTIN_SET)
4582         case LIT_MAGIC_STRING_SET_UL:
4583         {
4584           return JERRY_CONTAINER_TYPE_SET;
4585         }
4586 #endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
4587 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
4588         case LIT_MAGIC_STRING_WEAKMAP_UL:
4589         {
4590           return JERRY_CONTAINER_TYPE_WEAKMAP;
4591         }
4592 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */
4593 #if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
4594         case LIT_MAGIC_STRING_WEAKSET_UL:
4595         {
4596           return JERRY_CONTAINER_TYPE_WEAKSET;
4597         }
4598 #endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
4599         default:
4600         {
4601           return JERRY_CONTAINER_TYPE_INVALID;
4602         }
4603       }
4604     }
4605   }
4606 
4607 #else /* !ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4608   JERRY_UNUSED (value);
4609 #endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
4610   return JERRY_CONTAINER_TYPE_INVALID;
4611 } /* jerry_get_container_type */
4612 
4613 #if defined(JERRY_HEAPDUMP)
JerryHeapdumpRun(const char * filepath)4614 void JerryHeapdumpRun(const char* filepath)
4615 {
4616   SetHeapdumpTraring(true);
4617   LogHeapdumpInit(filepath);
4618   LogHeapdump("[\n");
4619   DumpInfoObject(ecma_builtin_get_global(), HEAPDUMP_OBJECT_GLOBAL);
4620   DumpInfoObject(ecma_get_global_environment(), HEAPDUMP_OBJECT_GLOBAL);
4621   ecma_gc_run();
4622   LogHeapdump("{}]\n");
4623   SetHeapdumpTraring(false);
4624   LogHeapdumpClose();
4625 }
4626 #endif
4627 
4628 #if defined(JERRY_REF_TRACKER)
JerryRefTrackerStart(const char * filepath)4629 void JerryRefTrackerStart(const char* filepath)
4630 {
4631   SetRefTrackerEnabled(true);
4632   LogTrackerInit(filepath);
4633 }
4634 #endif
4635 
4636 #if defined(JERRY_REF_TRACKER)
JerryRefTrackerStop(void)4637 void JerryRefTrackerStop(void)
4638 {
4639   SetRefTrackerEnabled(false);
4640   LogTrackerClose();
4641 }
4642 #endif
4643 
4644 /**
4645  * @}
4646  */
4647