Skip to content

Commit 3939c7b

Browse files
committed
Move snapshot generation function to the snapshot tool
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
1 parent 6dae815 commit 3939c7b

File tree

4 files changed

+301
-132
lines changed

4 files changed

+301
-132
lines changed

jerry-main/main-unix-snapshot.c

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "jerryscript.h"
1919
#include "jerryscript-port.h"
20+
#include "jerryscript-port-default.h"
2021

2122
#include "cli.h"
2223

@@ -34,6 +35,25 @@
3435
static uint8_t input_buffer[ JERRY_BUFFER_SIZE ];
3536
static uint32_t output_buffer[ JERRY_BUFFER_SIZE / 4 ];
3637

38+
/**
39+
* Check whether JerryScript has a requested feature enabled or not. If not,
40+
* print a warning message.
41+
*
42+
* @return the status of the feature.
43+
*/
44+
static bool
45+
check_feature (jerry_feature_t feature, /**< feature to check */
46+
const char *option) /**< command line option that triggered this check */
47+
{
48+
if (!jerry_is_feature_enabled (feature))
49+
{
50+
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_WARNING);
51+
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option);
52+
return false;
53+
}
54+
return true;
55+
} /* check_feature */
56+
3757
/**
3858
* Loading a single file into the memory.
3959
*
@@ -73,6 +93,237 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
7393
return bytes_read;
7494
} /* read_file */
7595

96+
/** Generate command line option IDs
97+
*
98+
*/
99+
typedef enum
100+
{
101+
OPT_GENERATE_HELP,
102+
OPT_GENERATE_CONTEXT,
103+
OPT_GENERATE_SHOW_OP,
104+
OPT_GENERATE_LITERAL_LIST,
105+
OPT_GENERATE_LITERAL_C,
106+
OPT_GENERATE_OUT,
107+
} generate_opt_id_t;
108+
109+
/**
110+
* Generate command line options
111+
*/
112+
static const cli_opt_t generate_opts[] =
113+
{
114+
CLI_OPT_DEF (.id = OPT_GENERATE_HELP, .opt = "h", .longopt = "help",
115+
.help = "print this help and exit"),
116+
CLI_OPT_DEF (.id = OPT_GENERATE_SHOW_OP, .longopt = "show-opcodes",
117+
.help = "print generated opcodes"),
118+
CLI_OPT_DEF (.id = OPT_GENERATE_CONTEXT, .opt = "c", .longopt = "context",
119+
.help = "specify the execution context of the snapshot: "
120+
"global or eval (default: global).", .meta = "MODE"),
121+
CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_LIST, .longopt = "save-literals-list-format",
122+
.meta = "FILE",
123+
.help = "export literals found in parsed JS input (in list format)"),
124+
CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_C, .longopt = "save-literals-c-format",
125+
.meta = "FILE",
126+
.help = "export literals found in parsed JS input (in C source format)"),
127+
CLI_OPT_DEF (.id = OPT_GENERATE_OUT, .opt = "o",
128+
.help = "specify output file name (default: js.snapshot)"),
129+
CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE",
130+
.help = "input snapshot file")
131+
};
132+
133+
/**
134+
* Process 'generate' command.
135+
*
136+
* @return error code (0 - no error)
137+
*/
138+
static int
139+
process_generate (cli_state_t *cli_state_p, /**< cli state */
140+
int argc, /**< number of arguments */
141+
char *prog_name_p) /**< program name */
142+
{
143+
(void) argc;
144+
145+
bool is_save_literals_mode_in_c_format = false;
146+
bool is_snapshot_mode_for_global = true;
147+
jerry_init_flag_t flags = JERRY_INIT_EMPTY;
148+
149+
uint32_t number_of_files = 0;
150+
uint8_t *source_p = input_buffer;
151+
size_t source_length = 0;
152+
const char *output_file_name_p = "js.snapshot";
153+
const char *save_literals_file_name_p = NULL;
154+
155+
cli_change_opts (cli_state_p, generate_opts);
156+
157+
for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p))
158+
{
159+
switch (id)
160+
{
161+
case OPT_GENERATE_HELP:
162+
{
163+
cli_help (prog_name_p, "generate", generate_opts);
164+
return JERRY_STANDALONE_EXIT_CODE_OK;
165+
}
166+
case OPT_GENERATE_OUT:
167+
{
168+
output_file_name_p = cli_consume_string (cli_state_p);
169+
break;
170+
}
171+
case OPT_GENERATE_LITERAL_LIST:
172+
case OPT_GENERATE_LITERAL_C:
173+
{
174+
if (save_literals_file_name_p != NULL)
175+
{
176+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: literal file name already specified");
177+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
178+
}
179+
180+
is_save_literals_mode_in_c_format = (id == OPT_GENERATE_LITERAL_C);
181+
save_literals_file_name_p = cli_consume_string (cli_state_p);
182+
break;
183+
}
184+
case OPT_GENERATE_SHOW_OP:
185+
{
186+
if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state_p->arg))
187+
{
188+
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
189+
flags |= JERRY_INIT_SHOW_OPCODES;
190+
}
191+
break;
192+
}
193+
case OPT_GENERATE_CONTEXT:
194+
{
195+
const char *mode_str_p = cli_consume_string (cli_state_p);
196+
197+
if (cli_state_p->error != NULL)
198+
{
199+
break;
200+
}
201+
202+
if (!strcmp ("global", mode_str_p))
203+
{
204+
is_snapshot_mode_for_global = true;
205+
}
206+
else if (!strcmp ("eval", mode_str_p))
207+
{
208+
is_snapshot_mode_for_global = false;
209+
}
210+
else
211+
{
212+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Incorrect argument for context mode: %s\n", mode_str_p);
213+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
214+
}
215+
break;
216+
}
217+
case CLI_OPT_DEFAULT:
218+
{
219+
const char *file_name_p = cli_consume_string (cli_state_p);
220+
221+
if (cli_state_p->error == NULL)
222+
{
223+
source_length = read_file (source_p, file_name_p);
224+
225+
if (source_length == 0)
226+
{
227+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n");
228+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
229+
}
230+
231+
number_of_files++;
232+
}
233+
break;
234+
}
235+
default:
236+
{
237+
cli_state_p->error = "Internal error";
238+
break;
239+
}
240+
}
241+
}
242+
243+
if (cli_state_p->error != NULL)
244+
{
245+
if (cli_state_p->arg != NULL)
246+
{
247+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg);
248+
}
249+
else
250+
{
251+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error);
252+
}
253+
254+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
255+
}
256+
257+
if (number_of_files != 1)
258+
{
259+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: No input file specified!\n");
260+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
261+
}
262+
263+
jerry_init (flags);
264+
265+
if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_length))
266+
{
267+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
268+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
269+
}
270+
271+
272+
size_t snapshot_size = jerry_parse_and_save_snapshot ((jerry_char_t *) source_p,
273+
source_length,
274+
is_snapshot_mode_for_global,
275+
false,
276+
output_buffer,
277+
sizeof (output_buffer) / sizeof (uint32_t));
278+
if (snapshot_size == 0)
279+
{
280+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");
281+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
282+
}
283+
284+
FILE *snapshot_file_p = fopen (output_file_name_p, "w");
285+
if (snapshot_file_p == NULL)
286+
{
287+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p);
288+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
289+
}
290+
291+
fwrite (output_buffer, sizeof (uint8_t), snapshot_size, snapshot_file_p);
292+
fclose (snapshot_file_p);
293+
294+
printf ("Created snapshot file: '%s' (%lu bytes)\n", output_file_name_p, (unsigned long) snapshot_size);
295+
296+
if (save_literals_file_name_p != NULL)
297+
{
298+
const size_t literal_buffer_size = jerry_parse_and_save_literals ((jerry_char_t *) source_p,
299+
source_length,
300+
false,
301+
output_buffer,
302+
sizeof (output_buffer) / sizeof (uint32_t),
303+
is_save_literals_mode_in_c_format);
304+
if (literal_buffer_size == 0)
305+
{
306+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Literal saving failed!\n");
307+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
308+
}
309+
310+
FILE *literal_file_p = fopen (save_literals_file_name_p, "w");
311+
312+
if (literal_file_p == NULL)
313+
{
314+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write literal file: '%s'\n", save_literals_file_name_p);
315+
return JERRY_STANDALONE_EXIT_CODE_FAIL;
316+
}
317+
318+
fwrite (output_buffer, sizeof (uint8_t), literal_buffer_size, literal_file_p);
319+
fclose (literal_file_p);
320+
321+
printf ("Created literal file: '%s' (%lu bytes)\n", save_literals_file_name_p, (unsigned long) literal_buffer_size);
322+
}
323+
324+
return 0;
325+
} /* process_generate */
326+
76327
/**
77328
* Merge command line option IDs
78329
*/
@@ -238,6 +489,7 @@ print_commands (char *prog_name_p) /**< program name */
238489
cli_help (prog_name_p, NULL, main_opts);
239490

240491
printf ("\nAvailable commands:\n"
492+
" generate \n"
241493
" merge\n"
242494
"\nPassing -h or --help after a command displays its help.\n");
243495
} /* print_commands */
@@ -275,6 +527,10 @@ main (int argc, /**< number of arguments */
275527
{
276528
return process_merge (&cli_state, argc, argv[0]);
277529
}
530+
else if (!strcmp ("generate", command_p))
531+
{
532+
return process_generate (&cli_state, argc, argv[0]);
533+
}
278534

279535
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: unknown command: %s\n\n", command_p);
280536
print_commands (argv[0]);

0 commit comments

Comments
 (0)