aboutsummaryrefslogtreecommitdiff
path: root/jerry-main
diff options
context:
space:
mode:
authorPéter Gál <pgal.u-szeged@partner.samsung.com>2017-11-05 18:37:27 +0100
committerAkos Kiss <akiss@inf.u-szeged.hu>2017-11-05 18:37:27 +0100
commit8ae659227e02ecbb5241c95c20b0e750c319150e (patch)
tree0b41bf3d5663e9e42670c7c3e0f78ab4e7839e1d /jerry-main
parentee24965bcf256fef8b7b850e8ce543dd99979fab (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.c298
-rw-r--r--jerry-main/main-unix.c122
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))