1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include <stdio.h>
17425bb815Sopenharmony_ci#include <string.h>
18425bb815Sopenharmony_ci#include <stdlib.h>
19425bb815Sopenharmony_ci
20425bb815Sopenharmony_ci#include "jerryscript.h"
21425bb815Sopenharmony_ci#include "jerryscript-ext/debugger.h"
22425bb815Sopenharmony_ci#include "jerryscript-ext/handler.h"
23425bb815Sopenharmony_ci#include "jerryscript-port.h"
24425bb815Sopenharmony_ci#include "setjmp.h"
25425bb815Sopenharmony_ci
26425bb815Sopenharmony_ci/**
27425bb815Sopenharmony_ci * Maximum command line arguments number.
28425bb815Sopenharmony_ci */
29425bb815Sopenharmony_ci#define JERRY_MAX_COMMAND_LINE_ARGS (16)
30425bb815Sopenharmony_ci
31425bb815Sopenharmony_ci/**
32425bb815Sopenharmony_ci * Standalone Jerry exit codes.
33425bb815Sopenharmony_ci */
34425bb815Sopenharmony_ci#define JERRY_STANDALONE_EXIT_CODE_OK   (0)
35425bb815Sopenharmony_ci#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
36425bb815Sopenharmony_ci
37425bb815Sopenharmony_ci/**
38425bb815Sopenharmony_ci * Context size of the SYNTAX_ERROR
39425bb815Sopenharmony_ci */
40425bb815Sopenharmony_ci#define SYNTAX_ERROR_CONTEXT_SIZE 2
41425bb815Sopenharmony_ci
42425bb815Sopenharmony_civoid set_log_level (jerry_log_level_t level);
43425bb815Sopenharmony_ci
44425bb815Sopenharmony_ci/**
45425bb815Sopenharmony_ci * Print usage and available options
46425bb815Sopenharmony_ci */
47425bb815Sopenharmony_cistatic void
48425bb815Sopenharmony_ciprint_help (char *name)
49425bb815Sopenharmony_ci{
50425bb815Sopenharmony_ci  printf ("Usage: %s [OPTION]... [FILE]...\n"
51425bb815Sopenharmony_ci          "\n"
52425bb815Sopenharmony_ci          "Options:\n"
53425bb815Sopenharmony_ci          "  --log-level [0-3]\n"
54425bb815Sopenharmony_ci          "  --mem-stats\n"
55425bb815Sopenharmony_ci          "  --mem-stats-separate\n"
56425bb815Sopenharmony_ci          "  --show-opcodes\n"
57425bb815Sopenharmony_ci          "  --start-debug-server\n"
58425bb815Sopenharmony_ci          "  --debug-server-port [port]\n"
59425bb815Sopenharmony_ci          "\n",
60425bb815Sopenharmony_ci          name);
61425bb815Sopenharmony_ci} /* print_help */
62425bb815Sopenharmony_ci
63425bb815Sopenharmony_ci/**
64425bb815Sopenharmony_ci * Read source code into buffer.
65425bb815Sopenharmony_ci *
66425bb815Sopenharmony_ci * Returned value must be freed with jmem_heap_free_block if it's not NULL.
67425bb815Sopenharmony_ci * @return NULL, if read or allocation has failed
68425bb815Sopenharmony_ci *         pointer to the allocated memory block, otherwise
69425bb815Sopenharmony_ci */
70425bb815Sopenharmony_cistatic const uint8_t *
71425bb815Sopenharmony_ciread_file (const char *file_name, /**< source code */
72425bb815Sopenharmony_ci           size_t *out_size_p) /**< [out] number of bytes successfully read from source */
73425bb815Sopenharmony_ci{
74425bb815Sopenharmony_ci  FILE *file = fopen (file_name, "r");
75425bb815Sopenharmony_ci  if (file == NULL)
76425bb815Sopenharmony_ci  {
77425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: %s\n", file_name);
78425bb815Sopenharmony_ci    return NULL;
79425bb815Sopenharmony_ci  }
80425bb815Sopenharmony_ci
81425bb815Sopenharmony_ci  int fseek_status = fseek (file, 0, SEEK_END);
82425bb815Sopenharmony_ci  if (fseek_status != 0)
83425bb815Sopenharmony_ci  {
84425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to seek (error: %d)\n", fseek_status);
85425bb815Sopenharmony_ci    fclose (file);
86425bb815Sopenharmony_ci    return NULL;
87425bb815Sopenharmony_ci  }
88425bb815Sopenharmony_ci
89425bb815Sopenharmony_ci  long script_len = ftell (file);
90425bb815Sopenharmony_ci  if (script_len < 0)
91425bb815Sopenharmony_ci  {
92425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to get the file size(error %ld)\n", script_len);
93425bb815Sopenharmony_ci    fclose (file);
94425bb815Sopenharmony_ci    return NULL;
95425bb815Sopenharmony_ci  }
96425bb815Sopenharmony_ci
97425bb815Sopenharmony_ci  rewind (file);
98425bb815Sopenharmony_ci
99425bb815Sopenharmony_ci  uint8_t *buffer = (uint8_t *) malloc (script_len);
100425bb815Sopenharmony_ci
101425bb815Sopenharmony_ci  if (buffer == NULL)
102425bb815Sopenharmony_ci  {
103425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Out of memory error\n");
104425bb815Sopenharmony_ci    fclose (file);
105425bb815Sopenharmony_ci    return NULL;
106425bb815Sopenharmony_ci  }
107425bb815Sopenharmony_ci
108425bb815Sopenharmony_ci  size_t bytes_read = fread (buffer, 1u, script_len, file);
109425bb815Sopenharmony_ci
110425bb815Sopenharmony_ci  if (!bytes_read || bytes_read != script_len)
111425bb815Sopenharmony_ci  {
112425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
113425bb815Sopenharmony_ci    free ((void*) buffer);
114425bb815Sopenharmony_ci
115425bb815Sopenharmony_ci    fclose (file);
116425bb815Sopenharmony_ci    return NULL;
117425bb815Sopenharmony_ci  }
118425bb815Sopenharmony_ci
119425bb815Sopenharmony_ci  fclose (file);
120425bb815Sopenharmony_ci
121425bb815Sopenharmony_ci  *out_size_p = bytes_read;
122425bb815Sopenharmony_ci  return (const uint8_t *) buffer;
123425bb815Sopenharmony_ci} /* read_file */
124425bb815Sopenharmony_ci
125425bb815Sopenharmony_ci/**
126425bb815Sopenharmony_ci * Convert string into unsigned integer
127425bb815Sopenharmony_ci *
128425bb815Sopenharmony_ci * @return converted number
129425bb815Sopenharmony_ci */
130425bb815Sopenharmony_cistatic uint32_t
131425bb815Sopenharmony_cistr_to_uint (const char *num_str_p, /**< string to convert */
132425bb815Sopenharmony_ci             char **out_p) /**< [out] end of the number */
133425bb815Sopenharmony_ci{
134425bb815Sopenharmony_ci  assert (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES));
135425bb815Sopenharmony_ci
136425bb815Sopenharmony_ci  uint32_t result = 0;
137425bb815Sopenharmony_ci
138425bb815Sopenharmony_ci  while (*num_str_p >= '0' && *num_str_p <= '9')
139425bb815Sopenharmony_ci  {
140425bb815Sopenharmony_ci    result *= 10;
141425bb815Sopenharmony_ci    result += (uint32_t) (*num_str_p - '0');
142425bb815Sopenharmony_ci    num_str_p++;
143425bb815Sopenharmony_ci  }
144425bb815Sopenharmony_ci
145425bb815Sopenharmony_ci  if (out_p != NULL)
146425bb815Sopenharmony_ci  {
147425bb815Sopenharmony_ci    *out_p = num_str_p;
148425bb815Sopenharmony_ci  }
149425bb815Sopenharmony_ci
150425bb815Sopenharmony_ci  return result;
151425bb815Sopenharmony_ci} /* str_to_uint */
152425bb815Sopenharmony_ci
153425bb815Sopenharmony_ci/**
154425bb815Sopenharmony_ci * Print error value
155425bb815Sopenharmony_ci */
156425bb815Sopenharmony_cistatic void
157425bb815Sopenharmony_ciprint_unhandled_exception (jerry_value_t error_value) /**< error value */
158425bb815Sopenharmony_ci{
159425bb815Sopenharmony_ci  assert (jerry_value_is_error (error_value));
160425bb815Sopenharmony_ci
161425bb815Sopenharmony_ci  error_value = jerry_get_value_from_error (error_value, false);
162425bb815Sopenharmony_ci  jerry_value_t err_str_val = jerry_value_to_string (error_value);
163425bb815Sopenharmony_ci  jerry_size_t err_str_size = jerry_get_utf8_string_size (err_str_val);
164425bb815Sopenharmony_ci  jerry_char_t err_str_buf[256];
165425bb815Sopenharmony_ci
166425bb815Sopenharmony_ci  jerry_release_value (error_value);
167425bb815Sopenharmony_ci
168425bb815Sopenharmony_ci  if (err_str_size >= 256)
169425bb815Sopenharmony_ci  {
170425bb815Sopenharmony_ci    const char msg[] = "[Error message too long]";
171425bb815Sopenharmony_ci    err_str_size = sizeof (msg) / sizeof (char) - 1;
172425bb815Sopenharmony_ci    memcpy (err_str_buf, msg, err_str_size);
173425bb815Sopenharmony_ci  }
174425bb815Sopenharmony_ci  else
175425bb815Sopenharmony_ci  {
176425bb815Sopenharmony_ci    jerry_size_t sz = jerry_string_to_utf8_char_buffer (err_str_val, err_str_buf, err_str_size);
177425bb815Sopenharmony_ci    assert (sz == err_str_size);
178425bb815Sopenharmony_ci    err_str_buf[err_str_size] = 0;
179425bb815Sopenharmony_ci
180425bb815Sopenharmony_ci    if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)
181425bb815Sopenharmony_ci        && jerry_get_error_type (error_value) == JERRY_ERROR_SYNTAX)
182425bb815Sopenharmony_ci    {
183425bb815Sopenharmony_ci      jerry_char_t *string_end_p = err_str_buf + sz;
184425bb815Sopenharmony_ci      uint32_t err_line = 0;
185425bb815Sopenharmony_ci      uint32_t err_col = 0;
186425bb815Sopenharmony_ci      char *path_str_p = NULL;
187425bb815Sopenharmony_ci      char *path_str_end_p = NULL;
188425bb815Sopenharmony_ci
189425bb815Sopenharmony_ci      /* 1. parse column and line information */
190425bb815Sopenharmony_ci      for (jerry_char_t *current_p = err_str_buf; current_p < string_end_p; current_p++)
191425bb815Sopenharmony_ci      {
192425bb815Sopenharmony_ci        if (*current_p == '[')
193425bb815Sopenharmony_ci        {
194425bb815Sopenharmony_ci          current_p++;
195425bb815Sopenharmony_ci
196425bb815Sopenharmony_ci          if (*current_p == '<')
197425bb815Sopenharmony_ci          {
198425bb815Sopenharmony_ci            break;
199425bb815Sopenharmony_ci          }
200425bb815Sopenharmony_ci
201425bb815Sopenharmony_ci          path_str_p = (char *) current_p;
202425bb815Sopenharmony_ci          while (current_p < string_end_p && *current_p != ':')
203425bb815Sopenharmony_ci          {
204425bb815Sopenharmony_ci            current_p++;
205425bb815Sopenharmony_ci          }
206425bb815Sopenharmony_ci
207425bb815Sopenharmony_ci          path_str_end_p = (char *) current_p++;
208425bb815Sopenharmony_ci
209425bb815Sopenharmony_ci          err_line = str_to_uint ((char *) current_p, (char **) &current_p);
210425bb815Sopenharmony_ci
211425bb815Sopenharmony_ci          current_p++;
212425bb815Sopenharmony_ci
213425bb815Sopenharmony_ci          err_col = str_to_uint ((char *) current_p, NULL);
214425bb815Sopenharmony_ci          break;
215425bb815Sopenharmony_ci        }
216425bb815Sopenharmony_ci      } /* for */
217425bb815Sopenharmony_ci
218425bb815Sopenharmony_ci      if (err_line != 0 && err_col != 0)
219425bb815Sopenharmony_ci      {
220425bb815Sopenharmony_ci        uint32_t curr_line = 1;
221425bb815Sopenharmony_ci
222425bb815Sopenharmony_ci        bool is_printing_context = false;
223425bb815Sopenharmony_ci        uint32_t pos = 0;
224425bb815Sopenharmony_ci
225425bb815Sopenharmony_ci        /* Temporarily modify the error message, so we can use the path. */
226425bb815Sopenharmony_ci        *path_str_end_p = '\0';
227425bb815Sopenharmony_ci
228425bb815Sopenharmony_ci        size_t source_size;
229425bb815Sopenharmony_ci        const jerry_char_t *source_p = read_file (path_str_p, &source_size);
230425bb815Sopenharmony_ci
231425bb815Sopenharmony_ci        /* Revert the error message. */
232425bb815Sopenharmony_ci        *path_str_end_p = ':';
233425bb815Sopenharmony_ci
234425bb815Sopenharmony_ci        /* 2. seek and print */
235425bb815Sopenharmony_ci        while (source_p[pos] != '\0')
236425bb815Sopenharmony_ci        {
237425bb815Sopenharmony_ci          if (source_p[pos] == '\n')
238425bb815Sopenharmony_ci          {
239425bb815Sopenharmony_ci            curr_line++;
240425bb815Sopenharmony_ci          }
241425bb815Sopenharmony_ci
242425bb815Sopenharmony_ci          if (err_line < SYNTAX_ERROR_CONTEXT_SIZE
243425bb815Sopenharmony_ci              || (err_line >= curr_line
244425bb815Sopenharmony_ci                  && (err_line - curr_line) <= SYNTAX_ERROR_CONTEXT_SIZE))
245425bb815Sopenharmony_ci          {
246425bb815Sopenharmony_ci            /* context must be printed */
247425bb815Sopenharmony_ci            is_printing_context = true;
248425bb815Sopenharmony_ci          }
249425bb815Sopenharmony_ci
250425bb815Sopenharmony_ci          if (curr_line > err_line)
251425bb815Sopenharmony_ci          {
252425bb815Sopenharmony_ci            break;
253425bb815Sopenharmony_ci          }
254425bb815Sopenharmony_ci
255425bb815Sopenharmony_ci          if (is_printing_context)
256425bb815Sopenharmony_ci          {
257425bb815Sopenharmony_ci            jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]);
258425bb815Sopenharmony_ci          }
259425bb815Sopenharmony_ci
260425bb815Sopenharmony_ci          pos++;
261425bb815Sopenharmony_ci        }
262425bb815Sopenharmony_ci
263425bb815Sopenharmony_ci        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");
264425bb815Sopenharmony_ci
265425bb815Sopenharmony_ci        while (--err_col)
266425bb815Sopenharmony_ci        {
267425bb815Sopenharmony_ci          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "~");
268425bb815Sopenharmony_ci        }
269425bb815Sopenharmony_ci
270425bb815Sopenharmony_ci        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "^\n");
271425bb815Sopenharmony_ci      }
272425bb815Sopenharmony_ci    }
273425bb815Sopenharmony_ci  }
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci  jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: %s\n", err_str_buf);
276425bb815Sopenharmony_ci  jerry_release_value (err_str_val);
277425bb815Sopenharmony_ci} /* print_unhandled_exception */
278425bb815Sopenharmony_ci
279425bb815Sopenharmony_ci/**
280425bb815Sopenharmony_ci * Register a JavaScript function in the global object.
281425bb815Sopenharmony_ci */
282425bb815Sopenharmony_cistatic void
283425bb815Sopenharmony_ciregister_js_function (const char *name_p, /**< name of the function */
284425bb815Sopenharmony_ci                      jerry_external_handler_t handler_p) /**< function callback */
285425bb815Sopenharmony_ci{
286425bb815Sopenharmony_ci  jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
287425bb815Sopenharmony_ci
288425bb815Sopenharmony_ci  if (jerry_value_is_error (result_val))
289425bb815Sopenharmony_ci  {
290425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
291425bb815Sopenharmony_ci  }
292425bb815Sopenharmony_ci
293425bb815Sopenharmony_ci  jerry_release_value (result_val);
294425bb815Sopenharmony_ci} /* register_js_function */
295425bb815Sopenharmony_ci
296425bb815Sopenharmony_ci
297425bb815Sopenharmony_ci/**
298425bb815Sopenharmony_ci * Main program.
299425bb815Sopenharmony_ci *
300425bb815Sopenharmony_ci * @return 0 if success, error code otherwise
301425bb815Sopenharmony_ci */
302425bb815Sopenharmony_ci#ifdef CONFIG_BUILD_KERNEL
303425bb815Sopenharmony_ciint main (int argc, FAR char *argv[])
304425bb815Sopenharmony_ci#else
305425bb815Sopenharmony_ciint jerry_main (int argc, char *argv[])
306425bb815Sopenharmony_ci#endif
307425bb815Sopenharmony_ci{
308425bb815Sopenharmony_ci  if (argc > JERRY_MAX_COMMAND_LINE_ARGS)
309425bb815Sopenharmony_ci  {
310425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR,
311425bb815Sopenharmony_ci                    "Too many command line arguments. Current maximum is %d\n",
312425bb815Sopenharmony_ci                    JERRY_MAX_COMMAND_LINE_ARGS);
313425bb815Sopenharmony_ci
314425bb815Sopenharmony_ci    return JERRY_STANDALONE_EXIT_CODE_FAIL;
315425bb815Sopenharmony_ci  }
316425bb815Sopenharmony_ci
317425bb815Sopenharmony_ci  const char *file_names[JERRY_MAX_COMMAND_LINE_ARGS];
318425bb815Sopenharmony_ci  int i;
319425bb815Sopenharmony_ci  int files_counter = 0;
320425bb815Sopenharmony_ci  bool start_debug_server = false;
321425bb815Sopenharmony_ci  uint16_t debug_port = 5001;
322425bb815Sopenharmony_ci
323425bb815Sopenharmony_ci  jerry_init_flag_t flags = JERRY_INIT_EMPTY;
324425bb815Sopenharmony_ci
325425bb815Sopenharmony_ci  for (i = 1; i < argc; i++)
326425bb815Sopenharmony_ci  {
327425bb815Sopenharmony_ci    if (!strcmp ("-h", argv[i]) || !strcmp ("--help", argv[i]))
328425bb815Sopenharmony_ci    {
329425bb815Sopenharmony_ci      print_help (argv[0]);
330425bb815Sopenharmony_ci      return JERRY_STANDALONE_EXIT_CODE_OK;
331425bb815Sopenharmony_ci    }
332425bb815Sopenharmony_ci    else if (!strcmp ("--mem-stats", argv[i]))
333425bb815Sopenharmony_ci    {
334425bb815Sopenharmony_ci      flags |= JERRY_INIT_MEM_STATS;
335425bb815Sopenharmony_ci      set_log_level (JERRY_LOG_LEVEL_DEBUG);
336425bb815Sopenharmony_ci    }
337425bb815Sopenharmony_ci    else if (!strcmp ("--mem-stats-separate", argv[i]))
338425bb815Sopenharmony_ci    {
339425bb815Sopenharmony_ci      flags |= JERRY_INIT_MEM_STATS_SEPARATE;
340425bb815Sopenharmony_ci      set_log_level (JERRY_LOG_LEVEL_DEBUG);
341425bb815Sopenharmony_ci    }
342425bb815Sopenharmony_ci    else if (!strcmp ("--show-opcodes", argv[i]))
343425bb815Sopenharmony_ci    {
344425bb815Sopenharmony_ci      flags |= JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES;
345425bb815Sopenharmony_ci      set_log_level (JERRY_LOG_LEVEL_DEBUG);
346425bb815Sopenharmony_ci    }
347425bb815Sopenharmony_ci    else if (!strcmp ("--log-level", argv[i]))
348425bb815Sopenharmony_ci    {
349425bb815Sopenharmony_ci      if (++i < argc && strlen (argv[i]) == 1 && argv[i][0] >='0' && argv[i][0] <= '3')
350425bb815Sopenharmony_ci      {
351425bb815Sopenharmony_ci        set_log_level (argv[i][0] - '0');
352425bb815Sopenharmony_ci      }
353425bb815Sopenharmony_ci      else
354425bb815Sopenharmony_ci      {
355425bb815Sopenharmony_ci        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n");
356425bb815Sopenharmony_ci        return JERRY_STANDALONE_EXIT_CODE_FAIL;
357425bb815Sopenharmony_ci      }
358425bb815Sopenharmony_ci    }
359425bb815Sopenharmony_ci    else if (!strcmp ("--start-debug-server", argv[i]))
360425bb815Sopenharmony_ci    {
361425bb815Sopenharmony_ci      start_debug_server = true;
362425bb815Sopenharmony_ci    }
363425bb815Sopenharmony_ci    else if (!strcmp ("--debug-server-port", argv[i]))
364425bb815Sopenharmony_ci    {
365425bb815Sopenharmony_ci      if (++i < argc)
366425bb815Sopenharmony_ci      {
367425bb815Sopenharmony_ci        debug_port = str_to_uint (argv[i], NULL);
368425bb815Sopenharmony_ci      }
369425bb815Sopenharmony_ci      else
370425bb815Sopenharmony_ci      {
371425bb815Sopenharmony_ci        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n");
372425bb815Sopenharmony_ci        return JERRY_STANDALONE_EXIT_CODE_FAIL;
373425bb815Sopenharmony_ci      }
374425bb815Sopenharmony_ci    }
375425bb815Sopenharmony_ci    else
376425bb815Sopenharmony_ci    {
377425bb815Sopenharmony_ci      file_names[files_counter++] = argv[i];
378425bb815Sopenharmony_ci    }
379425bb815Sopenharmony_ci  }
380425bb815Sopenharmony_ci
381425bb815Sopenharmony_ci  jerry_init (flags);
382425bb815Sopenharmony_ci
383425bb815Sopenharmony_ci  if (start_debug_server)
384425bb815Sopenharmony_ci  {
385425bb815Sopenharmony_ci    jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port)
386425bb815Sopenharmony_ci                                   && jerryx_debugger_ws_create ());
387425bb815Sopenharmony_ci  }
388425bb815Sopenharmony_ci
389425bb815Sopenharmony_ci  register_js_function ("assert", jerryx_handler_assert);
390425bb815Sopenharmony_ci  register_js_function ("gc", jerryx_handler_gc);
391425bb815Sopenharmony_ci  register_js_function ("print", jerryx_handler_print);
392425bb815Sopenharmony_ci
393425bb815Sopenharmony_ci  jerry_value_t ret_value = jerry_create_undefined ();
394425bb815Sopenharmony_ci
395425bb815Sopenharmony_ci  if (files_counter == 0)
396425bb815Sopenharmony_ci  {
397425bb815Sopenharmony_ci    printf ("No input files, running a hello world demo:\n");
398425bb815Sopenharmony_ci    const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript')";
399425bb815Sopenharmony_ci
400425bb815Sopenharmony_ci    ret_value = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
401425bb815Sopenharmony_ci
402425bb815Sopenharmony_ci    if (!jerry_value_is_error (ret_value))
403425bb815Sopenharmony_ci    {
404425bb815Sopenharmony_ci      ret_value = jerry_run (ret_value);
405425bb815Sopenharmony_ci    }
406425bb815Sopenharmony_ci  }
407425bb815Sopenharmony_ci  else
408425bb815Sopenharmony_ci  {
409425bb815Sopenharmony_ci    for (i = 0; i < files_counter; i++)
410425bb815Sopenharmony_ci    {
411425bb815Sopenharmony_ci      size_t source_size;
412425bb815Sopenharmony_ci      const jerry_char_t *source_p = read_file (file_names[i], &source_size);
413425bb815Sopenharmony_ci
414425bb815Sopenharmony_ci      if (source_p == NULL)
415425bb815Sopenharmony_ci      {
416425bb815Sopenharmony_ci        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Source file load error\n");
417425bb815Sopenharmony_ci        return JERRY_STANDALONE_EXIT_CODE_FAIL;
418425bb815Sopenharmony_ci      }
419425bb815Sopenharmony_ci
420425bb815Sopenharmony_ci      ret_value = jerry_parse ((jerry_char_t *) file_names[i],
421425bb815Sopenharmony_ci                               strlen (file_names[i]),
422425bb815Sopenharmony_ci                               source_p,
423425bb815Sopenharmony_ci                               source_size,
424425bb815Sopenharmony_ci                               JERRY_PARSE_NO_OPTS);
425425bb815Sopenharmony_ci      free ((void*) source_p);
426425bb815Sopenharmony_ci
427425bb815Sopenharmony_ci      if (!jerry_value_is_error (ret_value))
428425bb815Sopenharmony_ci      {
429425bb815Sopenharmony_ci        jerry_value_t func_val = ret_value;
430425bb815Sopenharmony_ci        ret_value = jerry_run (func_val);
431425bb815Sopenharmony_ci        jerry_release_value (func_val);
432425bb815Sopenharmony_ci      }
433425bb815Sopenharmony_ci
434425bb815Sopenharmony_ci      if (jerry_value_is_error (ret_value))
435425bb815Sopenharmony_ci      {
436425bb815Sopenharmony_ci        print_unhandled_exception (ret_value);
437425bb815Sopenharmony_ci        break;
438425bb815Sopenharmony_ci      }
439425bb815Sopenharmony_ci
440425bb815Sopenharmony_ci      jerry_release_value (ret_value);
441425bb815Sopenharmony_ci      ret_value = jerry_create_undefined ();
442425bb815Sopenharmony_ci    }
443425bb815Sopenharmony_ci  }
444425bb815Sopenharmony_ci
445425bb815Sopenharmony_ci  int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
446425bb815Sopenharmony_ci
447425bb815Sopenharmony_ci  if (jerry_value_is_error (ret_value))
448425bb815Sopenharmony_ci  {
449425bb815Sopenharmony_ci    ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
450425bb815Sopenharmony_ci  }
451425bb815Sopenharmony_ci
452425bb815Sopenharmony_ci  jerry_release_value (ret_value);
453425bb815Sopenharmony_ci
454425bb815Sopenharmony_ci  ret_value = jerry_run_all_enqueued_jobs ();
455425bb815Sopenharmony_ci
456425bb815Sopenharmony_ci  if (jerry_value_is_error (ret_value))
457425bb815Sopenharmony_ci  {
458425bb815Sopenharmony_ci    ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
459425bb815Sopenharmony_ci  }
460425bb815Sopenharmony_ci
461425bb815Sopenharmony_ci  jerry_release_value (ret_value);
462425bb815Sopenharmony_ci  jerry_cleanup ();
463425bb815Sopenharmony_ci
464425bb815Sopenharmony_ci  return ret_code;
465425bb815Sopenharmony_ci} /* main */
466