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 <assert.h> 17425bb815Sopenharmony_ci#include <stdlib.h> 18425bb815Sopenharmony_ci#include <string.h> 19425bb815Sopenharmony_ci 20425bb815Sopenharmony_ci#include "jerryscript.h" 21425bb815Sopenharmony_ci#include "jerryscript-port.h" 22425bb815Sopenharmony_ci#include "jerryscript-port-default.h" 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_ci#include "cli.h" 25425bb815Sopenharmony_ci 26425bb815Sopenharmony_ci/** 27425bb815Sopenharmony_ci * Maximum size for loaded snapshots 28425bb815Sopenharmony_ci */ 29425bb815Sopenharmony_ci#define JERRY_BUFFER_SIZE (1048576) 30425bb815Sopenharmony_ci 31425bb815Sopenharmony_ci/** 32425bb815Sopenharmony_ci * Maximum number of loaded literals 33425bb815Sopenharmony_ci */ 34425bb815Sopenharmony_ci#define JERRY_LITERAL_LENGTH (4096) 35425bb815Sopenharmony_ci 36425bb815Sopenharmony_ci/** 37425bb815Sopenharmony_ci * Standalone Jerry exit codes 38425bb815Sopenharmony_ci */ 39425bb815Sopenharmony_ci#define JERRY_STANDALONE_EXIT_CODE_OK (0) 40425bb815Sopenharmony_ci#define JERRY_STANDALONE_EXIT_CODE_FAIL (1) 41425bb815Sopenharmony_ci 42425bb815Sopenharmony_ci#ifdef _WIN32 43425bb815Sopenharmony_ci# ifdef _WIN64 44425bb815Sopenharmony_ci# define PRI_SIZET "lu" 45425bb815Sopenharmony_ci# define SIZE_T_TYPE unsigned long 46425bb815Sopenharmony_ci# else 47425bb815Sopenharmony_ci# define PRI_SIZET "zu" 48425bb815Sopenharmony_ci# define SIZE_T_TYPE size_t 49425bb815Sopenharmony_ci# endif 50425bb815Sopenharmony_ci#else 51425bb815Sopenharmony_ci# define PRI_SIZET "zu" 52425bb815Sopenharmony_ci# define SIZE_T_TYPE size_t 53425bb815Sopenharmony_ci#endif 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_cistatic uint8_t input_buffer[JERRY_BUFFER_SIZE]; 56425bb815Sopenharmony_cistatic uint32_t output_buffer[JERRY_BUFFER_SIZE / 4]; 57425bb815Sopenharmony_cistatic jerry_char_t literal_buffer[JERRY_BUFFER_SIZE]; 58425bb815Sopenharmony_cistatic const char *output_file_name_p = "js.snapshot"; 59425bb815Sopenharmony_cistatic jerry_length_t magic_string_lengths[JERRY_LITERAL_LENGTH]; 60425bb815Sopenharmony_cistatic const jerry_char_t *magic_string_items[JERRY_LITERAL_LENGTH]; 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci#if defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) 63425bb815Sopenharmony_ci/** 64425bb815Sopenharmony_ci * The alloc function passed to jerry_create_context 65425bb815Sopenharmony_ci */ 66425bb815Sopenharmony_cistatic void * 67425bb815Sopenharmony_cicontext_alloc (size_t size, 68425bb815Sopenharmony_ci void *cb_data_p) 69425bb815Sopenharmony_ci{ 70425bb815Sopenharmony_ci (void) cb_data_p; /* unused */ 71425bb815Sopenharmony_ci return malloc (size); 72425bb815Sopenharmony_ci} /* context_alloc */ 73425bb815Sopenharmony_ci 74425bb815Sopenharmony_ci/** 75425bb815Sopenharmony_ci * Create and set the default external context. 76425bb815Sopenharmony_ci */ 77425bb815Sopenharmony_cistatic void 78425bb815Sopenharmony_cicontext_init (void) 79425bb815Sopenharmony_ci{ 80425bb815Sopenharmony_ci jerry_context_t *context_p = jerry_create_context (JERRY_GLOBAL_HEAP_SIZE * 1024, context_alloc, NULL); 81425bb815Sopenharmony_ci jerry_port_default_set_current_context (context_p); 82425bb815Sopenharmony_ci} /* context_init */ 83425bb815Sopenharmony_ci 84425bb815Sopenharmony_ci#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */ 85425bb815Sopenharmony_ci 86425bb815Sopenharmony_ci/** 87425bb815Sopenharmony_ci * Check whether JerryScript has a requested feature enabled or not. If not, 88425bb815Sopenharmony_ci * print a warning message. 89425bb815Sopenharmony_ci * 90425bb815Sopenharmony_ci * @return the status of the feature. 91425bb815Sopenharmony_ci */ 92425bb815Sopenharmony_cistatic bool 93425bb815Sopenharmony_cicheck_feature (jerry_feature_t feature, /**< feature to check */ 94425bb815Sopenharmony_ci const char *option) /**< command line option that triggered this check */ 95425bb815Sopenharmony_ci{ 96425bb815Sopenharmony_ci if (!jerry_is_feature_enabled (feature)) 97425bb815Sopenharmony_ci { 98425bb815Sopenharmony_ci jerry_port_default_set_log_level (JERRY_LOG_LEVEL_WARNING); 99425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option); 100425bb815Sopenharmony_ci return false; 101425bb815Sopenharmony_ci } 102425bb815Sopenharmony_ci return true; 103425bb815Sopenharmony_ci} /* check_feature */ 104425bb815Sopenharmony_ci 105425bb815Sopenharmony_ci/** 106425bb815Sopenharmony_ci * Utility method to check and print error in the given cli state. 107425bb815Sopenharmony_ci * 108425bb815Sopenharmony_ci * @return true - if any error is detected 109425bb815Sopenharmony_ci * false - if there is no error in the cli state 110425bb815Sopenharmony_ci */ 111425bb815Sopenharmony_cistatic bool 112425bb815Sopenharmony_cicheck_cli_error (const cli_state_t *const cli_state_p) 113425bb815Sopenharmony_ci{ 114425bb815Sopenharmony_ci if (cli_state_p->error != NULL) 115425bb815Sopenharmony_ci { 116425bb815Sopenharmony_ci if (cli_state_p->arg != NULL) 117425bb815Sopenharmony_ci { 118425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg); 119425bb815Sopenharmony_ci } 120425bb815Sopenharmony_ci else 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error); 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci 125425bb815Sopenharmony_ci return true; 126425bb815Sopenharmony_ci } 127425bb815Sopenharmony_ci 128425bb815Sopenharmony_ci return false; 129425bb815Sopenharmony_ci} /* check_cli_error */ 130425bb815Sopenharmony_ci 131425bb815Sopenharmony_ci/** 132425bb815Sopenharmony_ci * Loading a single file into the memory. 133425bb815Sopenharmony_ci * 134425bb815Sopenharmony_ci * @return size of file - if loading is successful 135425bb815Sopenharmony_ci * 0 - otherwise 136425bb815Sopenharmony_ci */ 137425bb815Sopenharmony_cistatic size_t 138425bb815Sopenharmony_ciread_file (uint8_t *input_pos_p, /**< next position in the input buffer */ 139425bb815Sopenharmony_ci const char *file_name) /**< file name */ 140425bb815Sopenharmony_ci{ 141425bb815Sopenharmony_ci FILE *file = fopen (file_name, "rb"); 142425bb815Sopenharmony_ci 143425bb815Sopenharmony_ci if (file == NULL) 144425bb815Sopenharmony_ci { 145425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name); 146425bb815Sopenharmony_ci return 0; 147425bb815Sopenharmony_ci } 148425bb815Sopenharmony_ci 149425bb815Sopenharmony_ci size_t max_size = (size_t) (input_buffer + JERRY_BUFFER_SIZE - input_pos_p); 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci size_t bytes_read = fread (input_pos_p, 1u, max_size, file); 152425bb815Sopenharmony_ci fclose (file); 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci if (bytes_read == 0) 155425bb815Sopenharmony_ci { 156425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name); 157425bb815Sopenharmony_ci return 0; 158425bb815Sopenharmony_ci } 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_ci if (bytes_read == max_size) 161425bb815Sopenharmony_ci { 162425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: file too large: %s\n", file_name); 163425bb815Sopenharmony_ci return 0; 164425bb815Sopenharmony_ci } 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci printf ("Input file '%s' (%"PRI_SIZET" bytes) loaded.\n", file_name, (SIZE_T_TYPE)bytes_read); 167425bb815Sopenharmony_ci return bytes_read; 168425bb815Sopenharmony_ci} /* read_file */ 169425bb815Sopenharmony_ci 170425bb815Sopenharmony_ci/** 171425bb815Sopenharmony_ci * Print error value 172425bb815Sopenharmony_ci */ 173425bb815Sopenharmony_cistatic void 174425bb815Sopenharmony_ciprint_unhandled_exception (jerry_value_t error_value) /**< error value */ 175425bb815Sopenharmony_ci{ 176425bb815Sopenharmony_ci assert (!jerry_value_is_error (error_value)); 177425bb815Sopenharmony_ci 178425bb815Sopenharmony_ci jerry_value_t err_str_val = jerry_value_to_string (error_value); 179425bb815Sopenharmony_ci 180425bb815Sopenharmony_ci if (jerry_value_is_error (err_str_val)) 181425bb815Sopenharmony_ci { 182425bb815Sopenharmony_ci /* Avoid recursive error throws. */ 183425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n"); 184425bb815Sopenharmony_ci jerry_release_value (err_str_val); 185425bb815Sopenharmony_ci return; 186425bb815Sopenharmony_ci } 187425bb815Sopenharmony_ci 188425bb815Sopenharmony_ci jerry_size_t err_str_size = jerry_get_utf8_string_size (err_str_val); 189425bb815Sopenharmony_ci 190425bb815Sopenharmony_ci if (err_str_size >= 256) 191425bb815Sopenharmony_ci { 192425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n"); 193425bb815Sopenharmony_ci jerry_release_value (err_str_val); 194425bb815Sopenharmony_ci return; 195425bb815Sopenharmony_ci } 196425bb815Sopenharmony_ci 197425bb815Sopenharmony_ci jerry_char_t err_str_buf[256]; 198425bb815Sopenharmony_ci jerry_size_t string_end = jerry_string_to_utf8_char_buffer (err_str_val, err_str_buf, err_str_size); 199425bb815Sopenharmony_ci assert (string_end == err_str_size); 200425bb815Sopenharmony_ci err_str_buf[string_end] = 0; 201425bb815Sopenharmony_ci 202425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: %s\n", (char *) err_str_buf); 203425bb815Sopenharmony_ci jerry_release_value (err_str_val); 204425bb815Sopenharmony_ci} /* print_unhandled_exception */ 205425bb815Sopenharmony_ci 206425bb815Sopenharmony_ci/** 207425bb815Sopenharmony_ci * Generate command line option IDs 208425bb815Sopenharmony_ci */ 209425bb815Sopenharmony_citypedef enum 210425bb815Sopenharmony_ci{ 211425bb815Sopenharmony_ci OPT_GENERATE_HELP, 212425bb815Sopenharmony_ci OPT_GENERATE_STATIC, 213425bb815Sopenharmony_ci OPT_GENERATE_SHOW_OP, 214425bb815Sopenharmony_ci OPT_GENERATE_FUNCTION, 215425bb815Sopenharmony_ci OPT_GENERATE_OUT, 216425bb815Sopenharmony_ci OPT_IMPORT_LITERAL_LIST 217425bb815Sopenharmony_ci} generate_opt_id_t; 218425bb815Sopenharmony_ci 219425bb815Sopenharmony_ci/** 220425bb815Sopenharmony_ci * Generate command line options 221425bb815Sopenharmony_ci */ 222425bb815Sopenharmony_cistatic const cli_opt_t generate_opts[] = 223425bb815Sopenharmony_ci{ 224425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_GENERATE_HELP, .opt = "h", .longopt = "help", 225425bb815Sopenharmony_ci .help = "print this help and exit"), 226425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_GENERATE_STATIC, .opt = "s", .longopt = "static", 227425bb815Sopenharmony_ci .help = "generate static snapshot"), 228425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_GENERATE_FUNCTION, .opt = "f", .longopt = "generate-function-snapshot", 229425bb815Sopenharmony_ci .meta = "ARGUMENTS", 230425bb815Sopenharmony_ci .help = "generate function snapshot with given arguments"), 231425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_IMPORT_LITERAL_LIST, .longopt = "load-literals-list-format", 232425bb815Sopenharmony_ci .meta = "FILE", 233425bb815Sopenharmony_ci .help = "import literals from list format (for static snapshots)"), 234425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_GENERATE_SHOW_OP, .longopt = "show-opcodes", 235425bb815Sopenharmony_ci .help = "print generated opcodes"), 236425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_GENERATE_OUT, .opt = "o", .meta="FILE", 237425bb815Sopenharmony_ci .help = "specify output file name (default: js.snapshot)"), 238425bb815Sopenharmony_ci CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE", 239425bb815Sopenharmony_ci .help = "input source file") 240425bb815Sopenharmony_ci}; 241425bb815Sopenharmony_ci 242425bb815Sopenharmony_ci/** 243425bb815Sopenharmony_ci * Process 'generate' command. 244425bb815Sopenharmony_ci * 245425bb815Sopenharmony_ci * @return error code (0 - no error) 246425bb815Sopenharmony_ci */ 247425bb815Sopenharmony_cistatic int 248425bb815Sopenharmony_ciprocess_generate (cli_state_t *cli_state_p, /**< cli state */ 249425bb815Sopenharmony_ci int argc, /**< number of arguments */ 250425bb815Sopenharmony_ci char *prog_name_p) /**< program name */ 251425bb815Sopenharmony_ci{ 252425bb815Sopenharmony_ci (void) argc; 253425bb815Sopenharmony_ci 254425bb815Sopenharmony_ci uint32_t snapshot_flags = 0; 255425bb815Sopenharmony_ci jerry_init_flag_t flags = JERRY_INIT_EMPTY; 256425bb815Sopenharmony_ci 257425bb815Sopenharmony_ci const char *file_name_p = NULL; 258425bb815Sopenharmony_ci uint8_t *source_p = input_buffer; 259425bb815Sopenharmony_ci size_t source_length = 0; 260425bb815Sopenharmony_ci const char *literals_file_name_p = NULL; 261425bb815Sopenharmony_ci const char *function_args_p = NULL; 262425bb815Sopenharmony_ci 263425bb815Sopenharmony_ci cli_change_opts (cli_state_p, generate_opts); 264425bb815Sopenharmony_ci 265425bb815Sopenharmony_ci for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p)) 266425bb815Sopenharmony_ci { 267425bb815Sopenharmony_ci switch (id) 268425bb815Sopenharmony_ci { 269425bb815Sopenharmony_ci case OPT_GENERATE_HELP: 270425bb815Sopenharmony_ci { 271425bb815Sopenharmony_ci cli_help (prog_name_p, "generate", generate_opts); 272425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 273425bb815Sopenharmony_ci } 274425bb815Sopenharmony_ci case OPT_GENERATE_STATIC: 275425bb815Sopenharmony_ci { 276425bb815Sopenharmony_ci snapshot_flags |= JERRY_SNAPSHOT_SAVE_STATIC; 277425bb815Sopenharmony_ci break; 278425bb815Sopenharmony_ci } 279425bb815Sopenharmony_ci case OPT_GENERATE_FUNCTION: 280425bb815Sopenharmony_ci { 281425bb815Sopenharmony_ci function_args_p = cli_consume_string (cli_state_p); 282425bb815Sopenharmony_ci break; 283425bb815Sopenharmony_ci } 284425bb815Sopenharmony_ci case OPT_IMPORT_LITERAL_LIST: 285425bb815Sopenharmony_ci { 286425bb815Sopenharmony_ci literals_file_name_p = cli_consume_string (cli_state_p); 287425bb815Sopenharmony_ci break; 288425bb815Sopenharmony_ci } 289425bb815Sopenharmony_ci case OPT_GENERATE_SHOW_OP: 290425bb815Sopenharmony_ci { 291425bb815Sopenharmony_ci if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state_p->arg)) 292425bb815Sopenharmony_ci { 293425bb815Sopenharmony_ci jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG); 294425bb815Sopenharmony_ci flags |= JERRY_INIT_SHOW_OPCODES; 295425bb815Sopenharmony_ci } 296425bb815Sopenharmony_ci break; 297425bb815Sopenharmony_ci } 298425bb815Sopenharmony_ci case OPT_GENERATE_OUT: 299425bb815Sopenharmony_ci { 300425bb815Sopenharmony_ci output_file_name_p = cli_consume_string (cli_state_p); 301425bb815Sopenharmony_ci break; 302425bb815Sopenharmony_ci } 303425bb815Sopenharmony_ci case CLI_OPT_DEFAULT: 304425bb815Sopenharmony_ci { 305425bb815Sopenharmony_ci if (file_name_p != NULL) 306425bb815Sopenharmony_ci { 307425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n"); 308425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 309425bb815Sopenharmony_ci } 310425bb815Sopenharmony_ci 311425bb815Sopenharmony_ci file_name_p = cli_consume_string (cli_state_p); 312425bb815Sopenharmony_ci 313425bb815Sopenharmony_ci if (cli_state_p->error == NULL) 314425bb815Sopenharmony_ci { 315425bb815Sopenharmony_ci source_length = read_file (source_p, file_name_p); 316425bb815Sopenharmony_ci 317425bb815Sopenharmony_ci if (source_length == 0) 318425bb815Sopenharmony_ci { 319425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n"); 320425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 321425bb815Sopenharmony_ci } 322425bb815Sopenharmony_ci } 323425bb815Sopenharmony_ci break; 324425bb815Sopenharmony_ci } 325425bb815Sopenharmony_ci default: 326425bb815Sopenharmony_ci { 327425bb815Sopenharmony_ci cli_state_p->error = "Internal error"; 328425bb815Sopenharmony_ci break; 329425bb815Sopenharmony_ci } 330425bb815Sopenharmony_ci } 331425bb815Sopenharmony_ci } 332425bb815Sopenharmony_ci 333425bb815Sopenharmony_ci if (check_cli_error (cli_state_p)) 334425bb815Sopenharmony_ci { 335425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 336425bb815Sopenharmony_ci } 337425bb815Sopenharmony_ci 338425bb815Sopenharmony_ci if (file_name_p == NULL) 339425bb815Sopenharmony_ci { 340425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n"); 341425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 342425bb815Sopenharmony_ci } 343425bb815Sopenharmony_ci 344425bb815Sopenharmony_ci#if defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) 345425bb815Sopenharmony_ci context_init (); 346425bb815Sopenharmony_ci#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */ 347425bb815Sopenharmony_ci 348425bb815Sopenharmony_ci jerry_init (flags); 349425bb815Sopenharmony_ci 350425bb815Sopenharmony_ci if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_length)) 351425bb815Sopenharmony_ci { 352425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n"); 353425bb815Sopenharmony_ci jerry_cleanup (); 354425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 355425bb815Sopenharmony_ci } 356425bb815Sopenharmony_ci 357425bb815Sopenharmony_ci if (literals_file_name_p != NULL) 358425bb815Sopenharmony_ci { 359425bb815Sopenharmony_ci /* Import literal list */ 360425bb815Sopenharmony_ci uint8_t *sp_buffer_start_p = source_p + source_length + 1; 361425bb815Sopenharmony_ci size_t sp_buffer_size = read_file (sp_buffer_start_p, literals_file_name_p); 362425bb815Sopenharmony_ci 363425bb815Sopenharmony_ci if (sp_buffer_size > 0) 364425bb815Sopenharmony_ci { 365425bb815Sopenharmony_ci const char *sp_buffer_p = (const char *) sp_buffer_start_p; 366425bb815Sopenharmony_ci uint32_t num_of_lit = 0; 367425bb815Sopenharmony_ci 368425bb815Sopenharmony_ci do 369425bb815Sopenharmony_ci { 370425bb815Sopenharmony_ci char *sp_buffer_end_p = NULL; 371425bb815Sopenharmony_ci jerry_length_t mstr_size = (jerry_length_t) strtol (sp_buffer_p, &sp_buffer_end_p, 10); 372425bb815Sopenharmony_ci if (mstr_size > 0) 373425bb815Sopenharmony_ci { 374425bb815Sopenharmony_ci magic_string_items[num_of_lit] = (jerry_char_t *) (sp_buffer_end_p + 1); 375425bb815Sopenharmony_ci magic_string_lengths[num_of_lit] = mstr_size; 376425bb815Sopenharmony_ci num_of_lit++; 377425bb815Sopenharmony_ci } 378425bb815Sopenharmony_ci sp_buffer_p = sp_buffer_end_p + mstr_size + 1; 379425bb815Sopenharmony_ci } 380425bb815Sopenharmony_ci while ((size_t) (sp_buffer_p - (char *) sp_buffer_start_p) < sp_buffer_size); 381425bb815Sopenharmony_ci 382425bb815Sopenharmony_ci if (num_of_lit > 0) 383425bb815Sopenharmony_ci { 384425bb815Sopenharmony_ci jerry_register_magic_strings (magic_string_items, num_of_lit, 385425bb815Sopenharmony_ci magic_string_lengths); 386425bb815Sopenharmony_ci } 387425bb815Sopenharmony_ci } 388425bb815Sopenharmony_ci } 389425bb815Sopenharmony_ci 390425bb815Sopenharmony_ci jerry_value_t snapshot_result; 391425bb815Sopenharmony_ci 392425bb815Sopenharmony_ci if (function_args_p != NULL) 393425bb815Sopenharmony_ci { 394425bb815Sopenharmony_ci snapshot_result = jerry_generate_function_snapshot ((jerry_char_t *) file_name_p, 395425bb815Sopenharmony_ci (size_t) strlen (file_name_p), 396425bb815Sopenharmony_ci (jerry_char_t *) source_p, 397425bb815Sopenharmony_ci source_length, 398425bb815Sopenharmony_ci (const jerry_char_t *) function_args_p, 399425bb815Sopenharmony_ci strlen (function_args_p), 400425bb815Sopenharmony_ci snapshot_flags, 401425bb815Sopenharmony_ci output_buffer, 402425bb815Sopenharmony_ci sizeof (output_buffer) / sizeof (uint32_t)); 403425bb815Sopenharmony_ci } 404425bb815Sopenharmony_ci else 405425bb815Sopenharmony_ci { 406425bb815Sopenharmony_ci snapshot_result = jerry_generate_snapshot ((jerry_char_t *) file_name_p, 407425bb815Sopenharmony_ci (size_t) strlen (file_name_p), 408425bb815Sopenharmony_ci (jerry_char_t *) source_p, 409425bb815Sopenharmony_ci source_length, 410425bb815Sopenharmony_ci snapshot_flags, 411425bb815Sopenharmony_ci output_buffer, 412425bb815Sopenharmony_ci sizeof (output_buffer) / sizeof (uint32_t)); 413425bb815Sopenharmony_ci } 414425bb815Sopenharmony_ci 415425bb815Sopenharmony_ci if (jerry_value_is_error (snapshot_result)) 416425bb815Sopenharmony_ci { 417425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n"); 418425bb815Sopenharmony_ci 419425bb815Sopenharmony_ci snapshot_result = jerry_get_value_from_error (snapshot_result, true); 420425bb815Sopenharmony_ci 421425bb815Sopenharmony_ci print_unhandled_exception (snapshot_result); 422425bb815Sopenharmony_ci 423425bb815Sopenharmony_ci jerry_release_value (snapshot_result); 424425bb815Sopenharmony_ci jerry_cleanup (); 425425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 426425bb815Sopenharmony_ci } 427425bb815Sopenharmony_ci 428425bb815Sopenharmony_ci size_t snapshot_size = (size_t) jerry_get_number_value (snapshot_result); 429425bb815Sopenharmony_ci jerry_release_value (snapshot_result); 430425bb815Sopenharmony_ci 431425bb815Sopenharmony_ci FILE *snapshot_file_p = fopen (output_file_name_p, "wb"); 432425bb815Sopenharmony_ci if (snapshot_file_p == NULL) 433425bb815Sopenharmony_ci { 434425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p); 435425bb815Sopenharmony_ci jerry_cleanup (); 436425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 437425bb815Sopenharmony_ci } 438425bb815Sopenharmony_ci 439425bb815Sopenharmony_ci fwrite (output_buffer, sizeof (uint8_t), snapshot_size, snapshot_file_p); 440425bb815Sopenharmony_ci fclose (snapshot_file_p); 441425bb815Sopenharmony_ci 442425bb815Sopenharmony_ci printf ("Created snapshot file: '%s' (%zu bytes)\n", output_file_name_p, snapshot_size); 443425bb815Sopenharmony_ci 444425bb815Sopenharmony_ci jerry_cleanup (); 445425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 446425bb815Sopenharmony_ci} /* process_generate */ 447425bb815Sopenharmony_ci 448425bb815Sopenharmony_ci/** 449425bb815Sopenharmony_ci * Literal dump command line option IDs 450425bb815Sopenharmony_ci */ 451425bb815Sopenharmony_citypedef enum 452425bb815Sopenharmony_ci{ 453425bb815Sopenharmony_ci OPT_LITERAL_DUMP_HELP, 454425bb815Sopenharmony_ci OPT_LITERAL_DUMP_FORMAT, 455425bb815Sopenharmony_ci OPT_LITERAL_DUMP_OUT, 456425bb815Sopenharmony_ci} literal_dump_opt_id_t; 457425bb815Sopenharmony_ci 458425bb815Sopenharmony_ci/** 459425bb815Sopenharmony_ci * Literal dump command line options 460425bb815Sopenharmony_ci */ 461425bb815Sopenharmony_cistatic const cli_opt_t literal_dump_opts[] = 462425bb815Sopenharmony_ci{ 463425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_HELP, .opt = "h", .longopt = "help", 464425bb815Sopenharmony_ci .help = "print this help and exit"), 465425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_FORMAT, .longopt = "format", 466425bb815Sopenharmony_ci .meta = "[c|list]", 467425bb815Sopenharmony_ci .help = "specify output format (default: list)"), 468425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_OUT, .opt = "o", 469425bb815Sopenharmony_ci .help = "specify output file name (default: literals.[h|list])"), 470425bb815Sopenharmony_ci CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE(S)", 471425bb815Sopenharmony_ci .help = "input snapshot files") 472425bb815Sopenharmony_ci}; 473425bb815Sopenharmony_ci 474425bb815Sopenharmony_ci/** 475425bb815Sopenharmony_ci * Process 'litdump' command. 476425bb815Sopenharmony_ci * 477425bb815Sopenharmony_ci * @return error code (0 - no error) 478425bb815Sopenharmony_ci */ 479425bb815Sopenharmony_cistatic int 480425bb815Sopenharmony_ciprocess_literal_dump (cli_state_t *cli_state_p, /**< cli state */ 481425bb815Sopenharmony_ci int argc, /**< number of arguments */ 482425bb815Sopenharmony_ci char *prog_name_p) /**< program name */ 483425bb815Sopenharmony_ci{ 484425bb815Sopenharmony_ci uint8_t *input_pos_p = input_buffer; 485425bb815Sopenharmony_ci 486425bb815Sopenharmony_ci cli_change_opts (cli_state_p, literal_dump_opts); 487425bb815Sopenharmony_ci 488425bb815Sopenharmony_ci JERRY_VLA (const uint32_t *, snapshot_buffers, argc); 489425bb815Sopenharmony_ci JERRY_VLA (size_t, snapshot_buffer_sizes, argc); 490425bb815Sopenharmony_ci uint32_t number_of_files = 0; 491425bb815Sopenharmony_ci const char *literals_file_name_p = NULL; 492425bb815Sopenharmony_ci bool is_c_format = false; 493425bb815Sopenharmony_ci 494425bb815Sopenharmony_ci for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p)) 495425bb815Sopenharmony_ci { 496425bb815Sopenharmony_ci switch (id) 497425bb815Sopenharmony_ci { 498425bb815Sopenharmony_ci case OPT_LITERAL_DUMP_HELP: 499425bb815Sopenharmony_ci { 500425bb815Sopenharmony_ci cli_help (prog_name_p, "litdump", literal_dump_opts); 501425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 502425bb815Sopenharmony_ci } 503425bb815Sopenharmony_ci case OPT_LITERAL_DUMP_FORMAT: 504425bb815Sopenharmony_ci { 505425bb815Sopenharmony_ci const char *fromat_str_p = cli_consume_string (cli_state_p); 506425bb815Sopenharmony_ci if (!strcmp ("c", fromat_str_p)) 507425bb815Sopenharmony_ci { 508425bb815Sopenharmony_ci is_c_format = true; 509425bb815Sopenharmony_ci } 510425bb815Sopenharmony_ci else if (!strcmp ("list", fromat_str_p)) 511425bb815Sopenharmony_ci { 512425bb815Sopenharmony_ci is_c_format = false; 513425bb815Sopenharmony_ci } 514425bb815Sopenharmony_ci else 515425bb815Sopenharmony_ci { 516425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unsupported literal dump format."); 517425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 518425bb815Sopenharmony_ci } 519425bb815Sopenharmony_ci break; 520425bb815Sopenharmony_ci } 521425bb815Sopenharmony_ci case OPT_LITERAL_DUMP_OUT: 522425bb815Sopenharmony_ci { 523425bb815Sopenharmony_ci literals_file_name_p = cli_consume_string (cli_state_p); 524425bb815Sopenharmony_ci break; 525425bb815Sopenharmony_ci } 526425bb815Sopenharmony_ci case CLI_OPT_DEFAULT: 527425bb815Sopenharmony_ci { 528425bb815Sopenharmony_ci const char *file_name_p = cli_consume_string (cli_state_p); 529425bb815Sopenharmony_ci 530425bb815Sopenharmony_ci if (cli_state_p->error == NULL) 531425bb815Sopenharmony_ci { 532425bb815Sopenharmony_ci size_t size = read_file (input_pos_p, file_name_p); 533425bb815Sopenharmony_ci 534425bb815Sopenharmony_ci if (size == 0) 535425bb815Sopenharmony_ci { 536425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 537425bb815Sopenharmony_ci } 538425bb815Sopenharmony_ci 539425bb815Sopenharmony_ci snapshot_buffers[number_of_files] = (const uint32_t *) input_pos_p; 540425bb815Sopenharmony_ci snapshot_buffer_sizes[number_of_files] = size; 541425bb815Sopenharmony_ci 542425bb815Sopenharmony_ci number_of_files++; 543425bb815Sopenharmony_ci const uintptr_t mask = sizeof (uint32_t) - 1; 544425bb815Sopenharmony_ci input_pos_p = (uint8_t *) ((((uintptr_t) input_pos_p) + size + mask) & ~mask); 545425bb815Sopenharmony_ci } 546425bb815Sopenharmony_ci break; 547425bb815Sopenharmony_ci } 548425bb815Sopenharmony_ci default: 549425bb815Sopenharmony_ci { 550425bb815Sopenharmony_ci cli_state_p->error = "Internal error"; 551425bb815Sopenharmony_ci break; 552425bb815Sopenharmony_ci } 553425bb815Sopenharmony_ci } 554425bb815Sopenharmony_ci } 555425bb815Sopenharmony_ci 556425bb815Sopenharmony_ci if (check_cli_error (cli_state_p)) 557425bb815Sopenharmony_ci { 558425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 559425bb815Sopenharmony_ci } 560425bb815Sopenharmony_ci 561425bb815Sopenharmony_ci if (number_of_files < 1) 562425bb815Sopenharmony_ci { 563425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least one input file must be specified.\n"); 564425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 565425bb815Sopenharmony_ci } 566425bb815Sopenharmony_ci 567425bb815Sopenharmony_ci#if defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) 568425bb815Sopenharmony_ci context_init (); 569425bb815Sopenharmony_ci#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */ 570425bb815Sopenharmony_ci 571425bb815Sopenharmony_ci jerry_init (JERRY_INIT_EMPTY); 572425bb815Sopenharmony_ci 573425bb815Sopenharmony_ci size_t lit_buf_sz = 0; 574425bb815Sopenharmony_ci if (number_of_files == 1) 575425bb815Sopenharmony_ci { 576425bb815Sopenharmony_ci lit_buf_sz = jerry_get_literals_from_snapshot (snapshot_buffers[0], 577425bb815Sopenharmony_ci snapshot_buffer_sizes[0], 578425bb815Sopenharmony_ci literal_buffer, 579425bb815Sopenharmony_ci JERRY_BUFFER_SIZE, 580425bb815Sopenharmony_ci is_c_format); 581425bb815Sopenharmony_ci } 582425bb815Sopenharmony_ci else 583425bb815Sopenharmony_ci { 584425bb815Sopenharmony_ci /* The input contains more than one input snapshot file, so we must merge them first. */ 585425bb815Sopenharmony_ci const char *error_p = NULL; 586425bb815Sopenharmony_ci size_t merged_snapshot_size = jerry_merge_snapshots (snapshot_buffers, 587425bb815Sopenharmony_ci snapshot_buffer_sizes, 588425bb815Sopenharmony_ci number_of_files, 589425bb815Sopenharmony_ci output_buffer, 590425bb815Sopenharmony_ci JERRY_BUFFER_SIZE, 591425bb815Sopenharmony_ci &error_p); 592425bb815Sopenharmony_ci 593425bb815Sopenharmony_ci if (merged_snapshot_size == 0) 594425bb815Sopenharmony_ci { 595425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p); 596425bb815Sopenharmony_ci jerry_cleanup (); 597425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 598425bb815Sopenharmony_ci } 599425bb815Sopenharmony_ci 600425bb815Sopenharmony_ci printf ("Successfully merged the input snapshots (%"PRI_SIZET" bytes).\n", (SIZE_T_TYPE)merged_snapshot_size); 601425bb815Sopenharmony_ci 602425bb815Sopenharmony_ci lit_buf_sz = jerry_get_literals_from_snapshot (output_buffer, 603425bb815Sopenharmony_ci merged_snapshot_size, 604425bb815Sopenharmony_ci literal_buffer, 605425bb815Sopenharmony_ci JERRY_BUFFER_SIZE, 606425bb815Sopenharmony_ci is_c_format); 607425bb815Sopenharmony_ci } 608425bb815Sopenharmony_ci 609425bb815Sopenharmony_ci if (lit_buf_sz == 0) 610425bb815Sopenharmony_ci { 611425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, 612425bb815Sopenharmony_ci "Error: Literal saving failed! No literals were found in the input snapshot(s).\n"); 613425bb815Sopenharmony_ci jerry_cleanup (); 614425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 615425bb815Sopenharmony_ci } 616425bb815Sopenharmony_ci 617425bb815Sopenharmony_ci if (literals_file_name_p == NULL) 618425bb815Sopenharmony_ci { 619425bb815Sopenharmony_ci literals_file_name_p = is_c_format ? "literals.h" : "literals.list"; 620425bb815Sopenharmony_ci } 621425bb815Sopenharmony_ci 622425bb815Sopenharmony_ci FILE *file_p = fopen (literals_file_name_p, "wb"); 623425bb815Sopenharmony_ci 624425bb815Sopenharmony_ci if (file_p == NULL) 625425bb815Sopenharmony_ci { 626425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", literals_file_name_p); 627425bb815Sopenharmony_ci jerry_cleanup (); 628425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 629425bb815Sopenharmony_ci } 630425bb815Sopenharmony_ci 631425bb815Sopenharmony_ci fwrite (literal_buffer, sizeof (uint8_t), lit_buf_sz, file_p); 632425bb815Sopenharmony_ci fclose (file_p); 633425bb815Sopenharmony_ci 634425bb815Sopenharmony_ci printf ("Literals are saved into '%s' (%"PRI_SIZET" bytes).\n", literals_file_name_p, (SIZE_T_TYPE)lit_buf_sz); 635425bb815Sopenharmony_ci 636425bb815Sopenharmony_ci jerry_cleanup (); 637425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 638425bb815Sopenharmony_ci} /* process_literal_dump */ 639425bb815Sopenharmony_ci 640425bb815Sopenharmony_ci/** 641425bb815Sopenharmony_ci * Merge command line option IDs 642425bb815Sopenharmony_ci */ 643425bb815Sopenharmony_citypedef enum 644425bb815Sopenharmony_ci{ 645425bb815Sopenharmony_ci OPT_MERGE_HELP, 646425bb815Sopenharmony_ci OPT_MERGE_OUT, 647425bb815Sopenharmony_ci} merge_opt_id_t; 648425bb815Sopenharmony_ci 649425bb815Sopenharmony_ci/** 650425bb815Sopenharmony_ci * Merge command line options 651425bb815Sopenharmony_ci */ 652425bb815Sopenharmony_cistatic const cli_opt_t merge_opts[] = 653425bb815Sopenharmony_ci{ 654425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_MERGE_HELP, .opt = "h", .longopt = "help", 655425bb815Sopenharmony_ci .help = "print this help and exit"), 656425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_MERGE_OUT, .opt = "o", 657425bb815Sopenharmony_ci .help = "specify output file name (default: js.snapshot)"), 658425bb815Sopenharmony_ci CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE", 659425bb815Sopenharmony_ci .help = "input snapshot files, minimum two") 660425bb815Sopenharmony_ci}; 661425bb815Sopenharmony_ci 662425bb815Sopenharmony_ci/** 663425bb815Sopenharmony_ci * Process 'merge' command. 664425bb815Sopenharmony_ci * 665425bb815Sopenharmony_ci * @return error code (0 - no error) 666425bb815Sopenharmony_ci */ 667425bb815Sopenharmony_cistatic int 668425bb815Sopenharmony_ciprocess_merge (cli_state_t *cli_state_p, /**< cli state */ 669425bb815Sopenharmony_ci int argc, /**< number of arguments */ 670425bb815Sopenharmony_ci char *prog_name_p) /**< program name */ 671425bb815Sopenharmony_ci{ 672425bb815Sopenharmony_ci uint8_t *input_pos_p = input_buffer; 673425bb815Sopenharmony_ci 674425bb815Sopenharmony_ci cli_change_opts (cli_state_p, merge_opts); 675425bb815Sopenharmony_ci 676425bb815Sopenharmony_ci JERRY_VLA (const uint32_t *, merge_buffers, argc); 677425bb815Sopenharmony_ci JERRY_VLA (size_t, merge_buffer_sizes, argc); 678425bb815Sopenharmony_ci uint32_t number_of_files = 0; 679425bb815Sopenharmony_ci 680425bb815Sopenharmony_ci for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p)) 681425bb815Sopenharmony_ci { 682425bb815Sopenharmony_ci switch (id) 683425bb815Sopenharmony_ci { 684425bb815Sopenharmony_ci case OPT_MERGE_HELP: 685425bb815Sopenharmony_ci { 686425bb815Sopenharmony_ci cli_help (prog_name_p, "merge", merge_opts); 687425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 688425bb815Sopenharmony_ci } 689425bb815Sopenharmony_ci case OPT_MERGE_OUT: 690425bb815Sopenharmony_ci { 691425bb815Sopenharmony_ci output_file_name_p = cli_consume_string (cli_state_p); 692425bb815Sopenharmony_ci break; 693425bb815Sopenharmony_ci } 694425bb815Sopenharmony_ci case CLI_OPT_DEFAULT: 695425bb815Sopenharmony_ci { 696425bb815Sopenharmony_ci const char *file_name_p = cli_consume_string (cli_state_p); 697425bb815Sopenharmony_ci 698425bb815Sopenharmony_ci if (cli_state_p->error == NULL) 699425bb815Sopenharmony_ci { 700425bb815Sopenharmony_ci size_t size = read_file (input_pos_p, file_name_p); 701425bb815Sopenharmony_ci 702425bb815Sopenharmony_ci if (size == 0) 703425bb815Sopenharmony_ci { 704425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 705425bb815Sopenharmony_ci } 706425bb815Sopenharmony_ci 707425bb815Sopenharmony_ci merge_buffers[number_of_files] = (const uint32_t *) input_pos_p; 708425bb815Sopenharmony_ci merge_buffer_sizes[number_of_files] = size; 709425bb815Sopenharmony_ci 710425bb815Sopenharmony_ci number_of_files++; 711425bb815Sopenharmony_ci const uintptr_t mask = sizeof (uint32_t) - 1; 712425bb815Sopenharmony_ci input_pos_p = (uint8_t *) ((((uintptr_t) input_pos_p) + size + mask) & ~mask); 713425bb815Sopenharmony_ci } 714425bb815Sopenharmony_ci break; 715425bb815Sopenharmony_ci } 716425bb815Sopenharmony_ci default: 717425bb815Sopenharmony_ci { 718425bb815Sopenharmony_ci cli_state_p->error = "Internal error"; 719425bb815Sopenharmony_ci break; 720425bb815Sopenharmony_ci } 721425bb815Sopenharmony_ci } 722425bb815Sopenharmony_ci } 723425bb815Sopenharmony_ci 724425bb815Sopenharmony_ci if (check_cli_error (cli_state_p)) 725425bb815Sopenharmony_ci { 726425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 727425bb815Sopenharmony_ci } 728425bb815Sopenharmony_ci 729425bb815Sopenharmony_ci if (number_of_files < 2) 730425bb815Sopenharmony_ci { 731425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least two input files must be passed.\n"); 732425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 733425bb815Sopenharmony_ci } 734425bb815Sopenharmony_ci 735425bb815Sopenharmony_ci#if defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) 736425bb815Sopenharmony_ci context_init (); 737425bb815Sopenharmony_ci#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */ 738425bb815Sopenharmony_ci 739425bb815Sopenharmony_ci jerry_init (JERRY_INIT_EMPTY); 740425bb815Sopenharmony_ci 741425bb815Sopenharmony_ci const char *error_p = NULL; 742425bb815Sopenharmony_ci size_t merged_snapshot_size = jerry_merge_snapshots (merge_buffers, 743425bb815Sopenharmony_ci merge_buffer_sizes, 744425bb815Sopenharmony_ci number_of_files, 745425bb815Sopenharmony_ci output_buffer, 746425bb815Sopenharmony_ci JERRY_BUFFER_SIZE, 747425bb815Sopenharmony_ci &error_p); 748425bb815Sopenharmony_ci 749425bb815Sopenharmony_ci if (merged_snapshot_size == 0) 750425bb815Sopenharmony_ci { 751425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p); 752425bb815Sopenharmony_ci jerry_cleanup (); 753425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 754425bb815Sopenharmony_ci } 755425bb815Sopenharmony_ci 756425bb815Sopenharmony_ci FILE *file_p = fopen (output_file_name_p, "wb"); 757425bb815Sopenharmony_ci 758425bb815Sopenharmony_ci if (file_p == NULL) 759425bb815Sopenharmony_ci { 760425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", output_file_name_p); 761425bb815Sopenharmony_ci jerry_cleanup (); 762425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 763425bb815Sopenharmony_ci } 764425bb815Sopenharmony_ci 765425bb815Sopenharmony_ci fwrite (output_buffer, 1u, merged_snapshot_size, file_p); 766425bb815Sopenharmony_ci fclose (file_p); 767425bb815Sopenharmony_ci 768425bb815Sopenharmony_ci printf ("Merge is completed. Merged snapshot is saved into '%s' (%"PRI_SIZET" bytes).\n", 769425bb815Sopenharmony_ci output_file_name_p, 770425bb815Sopenharmony_ci (SIZE_T_TYPE)merged_snapshot_size); 771425bb815Sopenharmony_ci 772425bb815Sopenharmony_ci jerry_cleanup (); 773425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 774425bb815Sopenharmony_ci} /* process_merge */ 775425bb815Sopenharmony_ci 776425bb815Sopenharmony_ci/** 777425bb815Sopenharmony_ci * Command line option IDs 778425bb815Sopenharmony_ci */ 779425bb815Sopenharmony_citypedef enum 780425bb815Sopenharmony_ci{ 781425bb815Sopenharmony_ci OPT_HELP, 782425bb815Sopenharmony_ci} main_opt_id_t; 783425bb815Sopenharmony_ci 784425bb815Sopenharmony_ci/** 785425bb815Sopenharmony_ci * Command line options 786425bb815Sopenharmony_ci */ 787425bb815Sopenharmony_cistatic const cli_opt_t main_opts[] = 788425bb815Sopenharmony_ci{ 789425bb815Sopenharmony_ci CLI_OPT_DEF (.id = OPT_HELP, .opt = "h", .longopt = "help", 790425bb815Sopenharmony_ci .help = "print this help and exit"), 791425bb815Sopenharmony_ci CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "COMMAND", 792425bb815Sopenharmony_ci .help = "specify the command") 793425bb815Sopenharmony_ci}; 794425bb815Sopenharmony_ci 795425bb815Sopenharmony_ci/** 796425bb815Sopenharmony_ci * Print available commands. 797425bb815Sopenharmony_ci */ 798425bb815Sopenharmony_cistatic void 799425bb815Sopenharmony_ciprint_commands (char *prog_name_p) /**< program name */ 800425bb815Sopenharmony_ci{ 801425bb815Sopenharmony_ci cli_help (prog_name_p, NULL, main_opts); 802425bb815Sopenharmony_ci 803425bb815Sopenharmony_ci printf ("\nAvailable commands:\n" 804425bb815Sopenharmony_ci " generate\n" 805425bb815Sopenharmony_ci " litdump\n" 806425bb815Sopenharmony_ci " merge\n" 807425bb815Sopenharmony_ci "\nPassing -h or --help after a command displays its help.\n"); 808425bb815Sopenharmony_ci} /* print_commands */ 809425bb815Sopenharmony_ci 810425bb815Sopenharmony_ci/** 811425bb815Sopenharmony_ci * Main function. 812425bb815Sopenharmony_ci * 813425bb815Sopenharmony_ci * @return error code (0 - no error) 814425bb815Sopenharmony_ci */ 815425bb815Sopenharmony_ciint 816425bb815Sopenharmony_cimain (int argc, /**< number of arguments */ 817425bb815Sopenharmony_ci char **argv) /**< argument list */ 818425bb815Sopenharmony_ci{ 819425bb815Sopenharmony_ci cli_state_t cli_state = cli_init (main_opts, argc - 1, argv + 1); 820425bb815Sopenharmony_ci 821425bb815Sopenharmony_ci for (int id = cli_consume_option (&cli_state); id != CLI_OPT_END; id = cli_consume_option (&cli_state)) 822425bb815Sopenharmony_ci { 823425bb815Sopenharmony_ci switch (id) 824425bb815Sopenharmony_ci { 825425bb815Sopenharmony_ci case OPT_MERGE_HELP: 826425bb815Sopenharmony_ci { 827425bb815Sopenharmony_ci /* Help is always printed if no command is provided. */ 828425bb815Sopenharmony_ci break; 829425bb815Sopenharmony_ci } 830425bb815Sopenharmony_ci case CLI_OPT_DEFAULT: 831425bb815Sopenharmony_ci { 832425bb815Sopenharmony_ci const char *command_p = cli_consume_string (&cli_state); 833425bb815Sopenharmony_ci 834425bb815Sopenharmony_ci if (cli_state.error != NULL) 835425bb815Sopenharmony_ci { 836425bb815Sopenharmony_ci break; 837425bb815Sopenharmony_ci } 838425bb815Sopenharmony_ci 839425bb815Sopenharmony_ci if (!strcmp ("merge", command_p)) 840425bb815Sopenharmony_ci { 841425bb815Sopenharmony_ci return process_merge (&cli_state, argc, argv[0]); 842425bb815Sopenharmony_ci } 843425bb815Sopenharmony_ci else if (!strcmp ("litdump", command_p)) 844425bb815Sopenharmony_ci { 845425bb815Sopenharmony_ci return process_literal_dump (&cli_state, argc, argv[0]); 846425bb815Sopenharmony_ci } 847425bb815Sopenharmony_ci else if (!strcmp ("generate", command_p)) 848425bb815Sopenharmony_ci { 849425bb815Sopenharmony_ci return process_generate (&cli_state, argc, argv[0]); 850425bb815Sopenharmony_ci } 851425bb815Sopenharmony_ci 852425bb815Sopenharmony_ci jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: unknown command: %s\n\n", command_p); 853425bb815Sopenharmony_ci print_commands (argv[0]); 854425bb815Sopenharmony_ci 855425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 856425bb815Sopenharmony_ci } 857425bb815Sopenharmony_ci default: 858425bb815Sopenharmony_ci { 859425bb815Sopenharmony_ci cli_state.error = "Internal error"; 860425bb815Sopenharmony_ci break; 861425bb815Sopenharmony_ci } 862425bb815Sopenharmony_ci } 863425bb815Sopenharmony_ci } 864425bb815Sopenharmony_ci 865425bb815Sopenharmony_ci if (check_cli_error (&cli_state)) 866425bb815Sopenharmony_ci { 867425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_FAIL; 868425bb815Sopenharmony_ci } 869425bb815Sopenharmony_ci 870425bb815Sopenharmony_ci print_commands (argv[0]); 871425bb815Sopenharmony_ci return JERRY_STANDALONE_EXIT_CODE_OK; 872425bb815Sopenharmony_ci} /* main */ 873