Add runtime option "--call-on-exit [FUNCNAME]" to main-unix.c (#3518)

With this option you can call a function after the user script and promises have ran, to be able to do assertions that are executed just before the process would exit.

JerryScript-DCO-1.0-Signed-off-by: Daniel Balla dballa@inf.u-szeged.hu
This commit is contained in:
Daniel Balla 2020-01-15 17:10:42 +01:00 committed by Robert Fancsik
parent 4a331b2edc
commit 332e216736
3 changed files with 45 additions and 7 deletions

View File

@ -325,7 +325,8 @@ typedef enum
OPT_EXEC_SNAP,
OPT_EXEC_SNAP_FUNC,
OPT_LOG_LEVEL,
OPT_NO_PROMPT
OPT_NO_PROMPT,
OPT_CALL_ON_EXIT
} main_opt_id_t;
/**
@ -365,6 +366,8 @@ static const cli_opt_t main_opts[] =
.help = "set log level (0-3)"),
CLI_OPT_DEF (.id = OPT_NO_PROMPT, .longopt = "no-prompt",
.help = "don't print prompt in REPL mode"),
CLI_OPT_DEF (.id = OPT_CALL_ON_EXIT, .longopt = "call-on-exit", .meta = "STRING",
.help = "invoke the specified function when the process is just about to exit"),
CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE",
.help = "input JS file(s) (If file is -, read standard input.)")
};
@ -488,6 +491,8 @@ main (int argc,
bool is_wait_mode = false;
bool no_prompt = false;
const char *exit_cb = NULL;
cli_state_t cli_state = cli_init (main_opts, argc - 1, argv + 1);
for (int id = cli_consume_option (&cli_state); id != CLI_OPT_END; id = cli_consume_option (&cli_state))
{
@ -530,6 +535,11 @@ main (int argc,
}
break;
}
case OPT_CALL_ON_EXIT:
{
exit_cb = cli_consume_string (&cli_state);
break;
}
case OPT_SHOW_RE_OP:
{
if (check_feature (JERRY_FEATURE_REGEXP_DUMP, cli_state.arg))
@ -935,6 +945,32 @@ main (int argc,
jerry_release_value (ret_value);
if (exit_cb != NULL)
{
jerry_value_t global = jerry_get_global_object ();
jerry_value_t fn_str = jerry_create_string ((jerry_char_t *) exit_cb);
jerry_value_t callback_fn = jerry_get_property (global, fn_str);
jerry_release_value (global);
jerry_release_value (fn_str);
if (jerry_value_is_function (callback_fn))
{
jerry_value_t ret_val = jerry_call_function (callback_fn, jerry_create_undefined (), NULL, 0);
if (jerry_value_is_error (ret_val))
{
ret_val = jerry_get_value_from_error (ret_val, true);
print_unhandled_exception (ret_val);
ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
}
jerry_release_value (ret_val);
}
jerry_release_value (callback_fn);
}
jerry_cleanup ();
#if defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
free (context_p);

View File

@ -13,8 +13,9 @@
// limitations under the License.
Object.defineProperty(Array.prototype, 0, { get : function () { throw $; } });
var asyncPassed = false;
Promise.race([ , this]).then(Error).catch(function(err) { asyncPassed = (err instanceof ReferenceError); });
new Promise(function() {
throw 5;
}).then(Error).catch(function() { assert(asyncPassed); });
var global_err = undefined;
Promise.race([ , this]).then(Error).catch(function(err) { global_err = err; });
function __checkAsync() {
assert(global_err instanceof ReferenceError);
}

View File

@ -127,7 +127,7 @@ def run_normal_tests(args, tests):
test_cmd = get_platform_cmd_prefix()
if args.runtime:
test_cmd.append(args.runtime)
test_cmd.append(args.engine)
test_cmd.extend([args.engine, '--call-on-exit', '__checkAsync'])
total = len(tests)
tested = 0
@ -161,6 +161,7 @@ def run_snapshot_tests(args, tests):
generate_snapshot_cmd.append(args.runtime)
execute_snapshot_cmd.extend([args.engine, '--exec-snapshot', 'js.snapshot'])
execute_snapshot_cmd.extend(['--call-on-exit', '__checkAsync'])
# engine: jerry[.exe] -> snapshot generator: jerry-snapshot[.exe]
engine = os.path.splitext(args.engine)