[gjs/mozjs31: 7/7] js: Don't exit immediately from System.exit()
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/mozjs31: 7/7] js: Don't exit immediately from System.exit()
- Date: Tue, 15 Nov 2016 23:17:51 +0000 (UTC)
commit aa3d22239ac6d6e872c11d8c75e329c752c40ced
Author: Philip Chimento <philip endlessm com>
Date: Mon Nov 14 16:46:17 2016 -0800
js: Don't exit immediately from System.exit()
Exiting directly will now crash the GC thread if there happens to be a GC
going on at the time exit() is called; you can force this by running e.g.
JS_GC_ZEAL=2,1 gjs -c 'imports.system.exit(0)'
on a debug build of SpiderMonkey.
This does what SpiderMonkey's shell itself does: sets a flag to tell the
interpreter that the script wants to exit, then throws an uncatchable
exception. When JS::Evaluate subsequently exits, the flag is checked and
exit() is called.
https://bugzilla.gnome.org/show_bug.cgi?id=751252
gjs/context-private.h | 8 ++++++++
gjs/context.cpp | 25 +++++++++++++++++++++++++
modules/system.cpp | 7 +++++--
3 files changed, 38 insertions(+), 2 deletions(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 10d000a..045909f 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -24,6 +24,8 @@
#ifndef __GJS_CONTEXT_PRIVATE_H__
#define __GJS_CONTEXT_PRIVATE_H__
+#include <inttypes.h>
+
#include "context.h"
G_BEGIN_DECLS
@@ -32,6 +34,12 @@ bool _gjs_context_destroying (GjsContext *js_context);
void _gjs_context_schedule_gc_if_needed (GjsContext *js_context);
+void _gjs_context_exit(GjsContext *js_context,
+ uint8_t exit_code);
+
+bool _gjs_context_should_exit(GjsContext *js_context,
+ uint8_t *exit_code_p);
+
G_END_DECLS
#endif /* __GJS_CONTEXT_PRIVATE_H__ */
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 682d00c..5c8c267 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -69,6 +69,9 @@ struct _GjsContext {
bool destroying;
+ bool should_exit;
+ uint8_t exit_code;
+
guint auto_gc_id;
jsid const_strings[GJS_STRING_LAST];
@@ -556,6 +559,24 @@ _gjs_context_schedule_gc_if_needed (GjsContext *js_context)
js_context, NULL);
}
+void
+_gjs_context_exit(GjsContext *js_context,
+ uint8_t exit_code)
+{
+ g_assert(!js_context->should_exit);
+ js_context->should_exit = true;
+ js_context->exit_code = exit_code;
+}
+
+bool
+_gjs_context_should_exit(GjsContext *js_context,
+ uint8_t *exit_code_p)
+{
+ if (exit_code_p != NULL)
+ *exit_code_p = js_context->exit_code;
+ return js_context->should_exit;
+}
+
/**
* gjs_context_maybe_gc:
* @context: a #GjsContext
@@ -649,6 +670,10 @@ gjs_context_eval(GjsContext *js_context,
JS::RootedValue retval(js_context->context);
if (!gjs_eval_with_scope(js_context->context, JS::NullPtr(), script,
script_len, filename, &retval)) {
+ uint8_t code;
+ if (_gjs_context_should_exit(js_context, &code))
+ exit(code);
+
gjs_log_exception(js_context->context);
g_set_error(error,
GJS_ERROR,
diff --git a/modules/system.cpp b/modules/system.cpp
index 4c49799..c2c1551 100644
--- a/modules/system.cpp
+++ b/modules/system.cpp
@@ -31,6 +31,7 @@
#include <gjs/context.h>
#include "gi/object.h"
+#include "gjs/context-private.h"
#include "gjs/jsapi-util-args.h"
#include "system.h"
@@ -116,8 +117,10 @@ gjs_exit(JSContext *context,
if (!gjs_parse_call_args(context, "exit", argv, "i",
"ecode", &ecode))
return false;
- exit(ecode);
- return true;
+
+ GjsContext *gjs_context = static_cast<GjsContext *>(JS_GetContextPrivate(context));
+ _gjs_context_exit(gjs_context, ecode);
+ return false; /* without gjs_throw() == "throw uncatchable exception" */
}
static bool
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]