diff options
author | Péter Gál <pgal.u-szeged@partner.samsung.com> | 2017-11-05 18:37:27 +0100 |
---|---|---|
committer | Akos Kiss <akiss@inf.u-szeged.hu> | 2017-11-05 18:37:27 +0100 |
commit | 8ae659227e02ecbb5241c95c20b0e750c319150e (patch) | |
tree | 0b41bf3d5663e9e42670c7c3e0f78ab4e7839e1d /jerry-main | |
parent | ee24965bcf256fef8b7b850e8ce543dd99979fab (diff) |
Move snapshot generation function to the snapshot tool (#2057)
Now there is a snapshot tool which can merge snapshots
but was unable to generate snapshots by itself.
This change moves the snapshot generation utilities
to the snapshot tool.
JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
Diffstat (limited to 'jerry-main')
-rw-r--r-- | jerry-main/main-unix-snapshot.c | 298 | ||||
-rw-r--r-- | jerry-main/main-unix.c | 122 |
2 files changed, 285 insertions, 135 deletions
diff --git a/jerry-main/main-unix-snapshot.c b/jerry-main/main-unix-snapshot.c index b4c12888..e5faaf5b 100644 --- a/jerry-main/main-unix-snapshot.c +++ b/jerry-main/main-unix-snapshot.c @@ -17,6 +17,7 @@ #include "jerryscript.h" #include "jerryscript-port.h" +#include "jerryscript-port-default.h" #include "cli.h" @@ -33,6 +34,52 @@ static uint8_t input_buffer[ JERRY_BUFFER_SIZE ]; static uint32_t output_buffer[ JERRY_BUFFER_SIZE / 4 ]; +static const char *output_file_name_p = "js.snapshot"; + +/** + * Check whether JerryScript has a requested feature enabled or not. If not, + * print a warning message. + * + * @return the status of the feature. + */ +static bool +check_feature (jerry_feature_t feature, /**< feature to check */ + const char *option) /**< command line option that triggered this check */ +{ + if (!jerry_is_feature_enabled (feature)) + { + jerry_port_default_set_log_level (JERRY_LOG_LEVEL_WARNING); + jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option); + return false; + } + return true; +} /* check_feature */ + +/** + * Utility method to check and print error in the given cli state. + * + * @return true - if any error is detected + * false - if there is no error in the cli state + */ +static bool +check_cli_error (const cli_state_t *const cli_state_p) +{ + if (cli_state_p->error != NULL) + { + if (cli_state_p->arg != NULL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg); + } + else + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error); + } + + return true; + } + + return false; +} /* check_cli_error */ /** * Loading a single file into the memory. @@ -74,6 +121,227 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */ } /* read_file */ /** + * Generate command line option IDs + */ +typedef enum +{ + OPT_GENERATE_HELP, + OPT_GENERATE_CONTEXT, + OPT_GENERATE_SHOW_OP, + OPT_GENERATE_LITERAL_LIST, + OPT_GENERATE_LITERAL_C, + OPT_GENERATE_OUT, +} generate_opt_id_t; + +/** + * Generate command line options + */ +static const cli_opt_t generate_opts[] = +{ + CLI_OPT_DEF (.id = OPT_GENERATE_HELP, .opt = "h", .longopt = "help", + .help = "print this help and exit"), + CLI_OPT_DEF (.id = OPT_GENERATE_SHOW_OP, .longopt = "show-opcodes", + .help = "print generated opcodes"), + CLI_OPT_DEF (.id = OPT_GENERATE_CONTEXT, .opt = "c", .longopt = "context", + .meta = "MODE", + .help = "specify the execution context of the snapshot: " + "global or eval (default: global)."), + CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_LIST, .longopt = "save-literals-list-format", + .meta = "FILE", + .help = "export literals found in parsed JS input (in list format)"), + CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_C, .longopt = "save-literals-c-format", + .meta = "FILE", + .help = "export literals found in parsed JS input (in C source format)"), + CLI_OPT_DEF (.id = OPT_GENERATE_OUT, .opt = "o", .meta="FILE", + .help = "specify output file name (default: js.snapshot)"), + CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE", + .help = "input snapshot file") +}; + +/** + * Process 'generate' command. + * + * @return error code (0 - no error) + */ +static int +process_generate (cli_state_t *cli_state_p, /**< cli state */ + int argc, /**< number of arguments */ + char *prog_name_p) /**< program name */ +{ + (void) argc; + + bool is_save_literals_mode_in_c_format = false; + bool is_snapshot_mode_for_global = true; + jerry_init_flag_t flags = JERRY_INIT_EMPTY; + + uint32_t number_of_files = 0; + uint8_t *source_p = input_buffer; + size_t source_length = 0; + const char *save_literals_file_name_p = NULL; + + cli_change_opts (cli_state_p, generate_opts); + + for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p)) + { + switch (id) + { + case OPT_GENERATE_HELP: + { + cli_help (prog_name_p, "generate", generate_opts); + return JERRY_STANDALONE_EXIT_CODE_OK; + } + case OPT_GENERATE_OUT: + { + output_file_name_p = cli_consume_string (cli_state_p); + break; + } + case OPT_GENERATE_LITERAL_LIST: + case OPT_GENERATE_LITERAL_C: + { + if (save_literals_file_name_p != NULL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: literal file name already specified"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + is_save_literals_mode_in_c_format = (id == OPT_GENERATE_LITERAL_C); + save_literals_file_name_p = cli_consume_string (cli_state_p); + break; + } + case OPT_GENERATE_SHOW_OP: + { + if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state_p->arg)) + { + jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG); + flags |= JERRY_INIT_SHOW_OPCODES; + } + break; + } + case OPT_GENERATE_CONTEXT: + { + const char *mode_str_p = cli_consume_string (cli_state_p); + + if (cli_state_p->error != NULL) + { + break; + } + + if (!strcmp ("global", mode_str_p)) + { + is_snapshot_mode_for_global = true; + } + else if (!strcmp ("eval", mode_str_p)) + { + is_snapshot_mode_for_global = false; + } + else + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Incorrect argument for context mode: %s\n", mode_str_p); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + break; + } + case CLI_OPT_DEFAULT: + { + const char *file_name_p = cli_consume_string (cli_state_p); + + if (cli_state_p->error == NULL) + { + source_length = read_file (source_p, file_name_p); + + if (source_length == 0) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + number_of_files++; + } + break; + } + default: + { + cli_state_p->error = "Internal error"; + break; + } + } + } + + if (check_cli_error (cli_state_p)) + { + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + if (number_of_files != 1) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: No input file specified!\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + jerry_init (flags); + + if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_length)) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + size_t snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) source_p, + source_length, + is_snapshot_mode_for_global, + false, + output_buffer, + sizeof (output_buffer) / sizeof (uint32_t)); + if (snapshot_size == 0) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + FILE *snapshot_file_p = fopen (output_file_name_p, "w"); + if (snapshot_file_p == NULL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + fwrite (output_buffer, sizeof (uint8_t), snapshot_size, snapshot_file_p); + fclose (snapshot_file_p); + + printf ("Created snapshot file: '%s' (%lu bytes)\n", output_file_name_p, (unsigned long) snapshot_size); + + if (save_literals_file_name_p != NULL) + { + const size_t literal_buffer_size = jerry_parse_and_save_literals ((jerry_char_t *) source_p, + source_length, + false, + output_buffer, + sizeof (output_buffer) / sizeof (uint32_t), + is_save_literals_mode_in_c_format); + if (literal_buffer_size == 0) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Literal saving failed!\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + FILE *literal_file_p = fopen (save_literals_file_name_p, "w"); + + if (literal_file_p == NULL) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write literal file: '%s'\n", save_literals_file_name_p); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + fwrite (output_buffer, sizeof (uint8_t), literal_buffer_size, literal_file_p); + fclose (literal_file_p); + + printf ("Created literal file: '%s' (%lu bytes)\n", save_literals_file_name_p, (unsigned long) literal_buffer_size); + } + + return 0; +} /* process_generate */ + +/** * Merge command line option IDs */ typedef enum @@ -90,7 +358,7 @@ static const cli_opt_t merge_opts[] = CLI_OPT_DEF (.id = OPT_MERGE_HELP, .opt = "h", .longopt = "help", .help = "print this help and exit"), CLI_OPT_DEF (.id = OPT_MERGE_OUT, .opt = "o", - .help = "specify output file name (default: merged.snapshot)"), + .help = "specify output file name (default: js.snapshot)"), CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE", .help = "input snapshot files, minimum two") }; @@ -111,7 +379,6 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */ cli_change_opts (cli_state_p, merge_opts); - const char *output_file_name_p = "merged.snapshot"; const uint32_t *merge_buffers[argc]; size_t merge_buffer_sizes[argc]; uint32_t number_of_files = 0; @@ -160,17 +427,8 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */ } } - if (cli_state_p->error != NULL) + if (check_cli_error (cli_state_p)) { - if (cli_state_p->arg != NULL) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg); - } - else - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error); - } - return JERRY_STANDALONE_EXIT_CODE_FAIL; } @@ -238,6 +496,7 @@ print_commands (char *prog_name_p) /**< program name */ cli_help (prog_name_p, NULL, main_opts); printf ("\nAvailable commands:\n" + " generate\n" " merge\n" "\nPassing -h or --help after a command displays its help.\n"); } /* print_commands */ @@ -275,6 +534,10 @@ main (int argc, /**< number of arguments */ { return process_merge (&cli_state, argc, argv[0]); } + else if (!strcmp ("generate", command_p)) + { + return process_generate (&cli_state, argc, argv[0]); + } jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: unknown command: %s\n\n", command_p); print_commands (argv[0]); @@ -289,17 +552,8 @@ main (int argc, /**< number of arguments */ } } - if (cli_state.error != NULL) + if (check_cli_error (&cli_state)) { - if (cli_state.arg != NULL) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state.error, cli_state.arg); - } - else - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state.error); - } - return JERRY_STANDALONE_EXIT_CODE_FAIL; } diff --git a/jerry-main/main-unix.c b/jerry-main/main-unix.c index 0bfaaccc..6e8a47fb 100644 --- a/jerry-main/main-unix.c +++ b/jerry-main/main-unix.c @@ -314,10 +314,6 @@ typedef enum OPT_DEBUG_SERVER, OPT_DEBUG_PORT, OPT_DEBUGGER_WAIT_SOURCE, - OPT_SAVE_SNAP_GLOBAL, - OPT_SAVE_SNAP_EVAL, - OPT_SAVE_LIT_LIST, - OPT_SAVE_LIT_C, OPT_EXEC_SNAP, OPT_EXEC_SNAP_FUNC, OPT_LOG_LEVEL, @@ -348,14 +344,6 @@ static const cli_opt_t main_opts[] = .help = "debug server port (default: 5001)"), CLI_OPT_DEF (.id = OPT_DEBUGGER_WAIT_SOURCE, .longopt = "debugger-wait-source", .help = "wait for an executable source from the client"), - CLI_OPT_DEF (.id = OPT_SAVE_SNAP_GLOBAL, .longopt = "save-snapshot-for-global", .meta = "FILE", - .help = "save binary snapshot of parsed JS input (for execution in global context)"), - CLI_OPT_DEF (.id = OPT_SAVE_SNAP_EVAL, .longopt = "save-snapshot-for-eval", .meta = "FILE", - .help = "save binary snapshot of parsed JS input (for execution in local context by eval)"), - CLI_OPT_DEF (.id = OPT_SAVE_LIT_LIST, .longopt = "save-literals-list-format", .meta = "FILE", - .help = "export literals found in parsed JS input (in list format)"), - CLI_OPT_DEF (.id = OPT_SAVE_LIT_C, .longopt = "save-literals-c-format", .meta = "FILE", - .help = "export literals found in parsed JS input (in C source format)"), CLI_OPT_DEF (.id = OPT_EXEC_SNAP, .longopt = "exec-snapshot", .meta = "FILE", .help = "execute input snapshot file(s)"), CLI_OPT_DEF (.id = OPT_EXEC_SNAP_FUNC, .longopt = "exec-snapshot-func", .meta = "FILE NUM", @@ -435,13 +423,6 @@ main (int argc, int exec_snapshots_count = 0; bool is_parse_only = false; - bool is_save_snapshot_mode = false; - bool is_save_snapshot_mode_for_global_or_eval = false; - const char *save_snapshot_file_name_p = NULL; - - bool is_save_literals_mode = false; - bool is_save_literals_mode_in_c_format_or_list = false; - const char *save_literals_file_name_p = NULL; bool start_debug_server = false; uint16_t debug_port = 5001; @@ -521,30 +502,6 @@ main (int argc, } break; } - case OPT_SAVE_SNAP_GLOBAL: - case OPT_SAVE_SNAP_EVAL: - { - check_usage (save_snapshot_file_name_p == NULL, argv[0], "Error: snapshot file name already specified", NULL); - if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, cli_state.arg)) - { - is_save_snapshot_mode = true; - is_save_snapshot_mode_for_global_or_eval = (id == OPT_SAVE_SNAP_GLOBAL); - } - save_snapshot_file_name_p = cli_consume_string (&cli_state); - break; - } - case OPT_SAVE_LIT_LIST: - case OPT_SAVE_LIT_C: - { - check_usage (save_literals_file_name_p == NULL, argv[0], "Error: literal file name already specified", NULL); - if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, cli_state.arg)) - { - is_save_literals_mode = true; - is_save_literals_mode_in_c_format_or_list = (id == OPT_SAVE_LIT_C); - } - save_literals_file_name_p = cli_consume_string (&cli_state); - break; - } case OPT_EXEC_SNAP: { if (check_feature (JERRY_FEATURE_SNAPSHOT_EXEC, cli_state.arg)) @@ -617,20 +574,6 @@ main (int argc, return JERRY_STANDALONE_EXIT_CODE_FAIL; } - if (is_save_snapshot_mode) - { - check_usage (files_counter == 1, - argv[0], "Error: --save-snapshot-* options work with exactly one script", NULL); - check_usage (exec_snapshots_count == 0, - argv[0], "Error: --save-snapshot-* and --exec-snapshot options can't be passed simultaneously", NULL); - } - - if (is_save_literals_mode) - { - check_usage (files_counter == 1, - argv[0], "Error: --save-literals-* options work with exactly one script", NULL); - } - if (files_counter == 0 && exec_snapshots_count == 0) { @@ -701,64 +644,17 @@ main (int argc, break; } - if (is_save_snapshot_mode || is_save_literals_mode) - { - static uint32_t snapshot_save_buffer[ JERRY_SNAPSHOT_BUFFER_SIZE ]; - - if (is_save_snapshot_mode) - { - size_t snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) source_p, - source_size, - is_save_snapshot_mode_for_global_or_eval, - false, - snapshot_save_buffer, - JERRY_SNAPSHOT_BUFFER_SIZE); - if (snapshot_size == 0) - { - ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "Snapshot saving failed!"); - } - else - { - FILE *snapshot_file_p = fopen (save_snapshot_file_name_p, "w"); - fwrite (snapshot_save_buffer, sizeof (uint8_t), snapshot_size, snapshot_file_p); - fclose (snapshot_file_p); - } - } + ret_value = jerry_parse_named_resource ((jerry_char_t *) file_names[i], + strlen (file_names[i]), + source_p, + source_size, + false); - if (!jerry_value_has_error_flag (ret_value) && is_save_literals_mode) - { - const size_t literal_buffer_size = jerry_parse_and_save_literals ((jerry_char_t *) source_p, - source_size, - false, - snapshot_save_buffer, - JERRY_SNAPSHOT_BUFFER_SIZE, - is_save_literals_mode_in_c_format_or_list); - if (literal_buffer_size == 0) - { - ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "Literal saving failed!"); - } - else - { - FILE *literal_file_p = fopen (save_literals_file_name_p, "w"); - fwrite (snapshot_save_buffer, sizeof (uint8_t), literal_buffer_size, literal_file_p); - fclose (literal_file_p); - } - } - } - else + if (!jerry_value_has_error_flag (ret_value) && !is_parse_only) { - ret_value = jerry_parse_named_resource ((jerry_char_t *) file_names[i], - strlen (file_names[i]), - source_p, - source_size, - false); - - if (!jerry_value_has_error_flag (ret_value) && !is_parse_only) - { - jerry_value_t func_val = ret_value; - ret_value = jerry_run (func_val); - jerry_release_value (func_val); - } + jerry_value_t func_val = ret_value; + ret_value = jerry_run (func_val); + jerry_release_value (func_val); } if (jerry_value_has_error_flag (ret_value)) |