[gjs/wip/xulrunner-1.9.3-rebase6: 1/8] Drop load and call contexts
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/xulrunner-1.9.3-rebase6: 1/8] Drop load and call contexts
- Date: Thu, 23 Sep 2010 20:44:25 +0000 (UTC)
commit b024ed5b255c4e12633c625767eadaeed40f1753
Author: Colin Walters <walters verbum org>
Date: Wed Sep 22 16:11:23 2010 -0400
Drop load and call contexts
Apparently for XULRunner embedding reasons, multiple different
contexts were added to gjs. We're using these in a way not really
intended by Spidermonkey. The default intended design is that there's
one (active) JSContext * per thread.
In particular, stacking JS_BeginRequest(context_a);
JS_BeginRequest(context_b) is "dubious" in current Spidermonkey.
For the load context: If we want to e.g. avoid having modules loaded
multiple times even if run from a non-default context (and thus a
non-default global object), the obvious implementation technique is to
just hook them off the GjsRuntime default global object.
For the callback context: We need to assume that we have a standard
context provided by Gjs, which is the thread default one. Actually,
one possibility here is to root the global object for a given
callback.
https://bugzilla.gnome.org/show_bug.cgi?id=622896
Makefile.am | 1 -
gi/closure.c | 31 +-----
gi/function.c | 14 +--
gi/keep-alive.c | 5 +-
gi/keep-alive.h | 2 +-
gi/ns.c | 44 +++-----
gi/object.c | 9 +-
gi/repo.c | 58 +++++------
gjs/byteArray.c | 7 +-
gjs/context-jsapi.h | 37 -------
gjs/context.c | 138 ++++++++-----------------
gjs/importer.c | 34 +++----
gjs/importer.h | 4 +-
gjs/jsapi-private.cpp | 1 -
gjs/jsapi-util.c | 268 +++---------------------------------------------
gjs/jsapi-util.h | 16 +---
gjs/stack.c | 2 +-
modules/dbus-exports.c | 9 +-
18 files changed, 138 insertions(+), 542 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index f12fd70..c0d0e71 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,7 +29,6 @@ nobase_gjsinclude_HEADERS = \
noinst_HEADERS += \
gjs/compat.h \
- gjs/context-jsapi.h \
gjs/jsapi-private.h \
gjs/profiler.h \
gjs/unit-test-utils.h \
diff --git a/gi/closure.c b/gi/closure.c
index 3eb5a33..56de829 100644
--- a/gi/closure.c
+++ b/gi/closure.c
@@ -40,30 +40,7 @@ typedef struct {
} Closure;
/*
- * Memory management of closures is "interesting" because we're keeping around
- * a JSContext* and then trying to use it spontaneously from the main loop.
- * I don't think that's really quite kosher, and perhaps the problem is that
- * (in xulrunner) we just need to save a different context.
- *
- * Or maybe the right fix is to create our own context just for this?
- *
- * But for the moment, we save the context that was used to create the closure.
- *
- * Here's the problem: this context can be destroyed. AFTER the
- * context is destroyed, or at least potentially after, the objects in
- * the context's global object may be garbage collected. Remember that
- * JSObject* belong to a runtime, not a context.
- *
- * There is apparently no robust way to track context destruction in
- * SpiderMonkey, because the context can be destroyed without running
- * the garbage collector, and xulrunner takes over the JS_SetContextCallback()
- * callback. So there's no callback for us.
- *
- * So, when we go to use our context, we iterate the contexts in the runtime
- * and see if ours is still in the valid list, and decide to invalidate
- * the closure if it isn't.
- *
- * The closure can thus be destroyed in several cases:
+ * The closure can be destroyed in several cases:
* - invalidation by unref, e.g. when a signal is disconnected, closure is unref'd
* - invalidation because we were invoked while the context was dead
* - invalidation through finalization (we were garbage collected)
@@ -356,11 +333,7 @@ gjs_closure_new(JSContext *context,
c = (Closure*) g_closure_new_simple(sizeof(Closure), NULL);
c->runtime = JS_GetRuntime(context);
- /* Closure are executed in our special "load-context" (one per runtime).
- * This ensures that the context is still alive when the closure
- * is invoked (as long as the runtime lives)
- */
- c->context = gjs_runtime_get_load_context(c->runtime);
+ c->context = context;
JS_BeginRequest(c->context);
c->obj = callable;
diff --git a/gi/function.c b/gi/function.c
index b8aa2a0..80c051a 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -1036,16 +1036,12 @@ gjs_define_function(JSContext *context,
GIFunctionInfo *info)
{
JSObject *function;
- JSContext *load_context;
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
+ JS_BeginRequest(context);
- function = function_new(load_context, info);
+ function = function_new(context, info);
if (function == NULL) {
- gjs_move_exception(load_context, context);
-
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return NULL;
}
@@ -1056,11 +1052,11 @@ gjs_define_function(JSContext *context,
GJS_MODULE_PROP_FLAGS)) {
gjs_debug(GJS_DEBUG_GFUNCTION, "Failed to define function");
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return NULL;
}
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return function;
}
diff --git a/gi/keep-alive.c b/gi/keep-alive.c
index 8e2c4ab..8d903f7 100644
--- a/gi/keep-alive.c
+++ b/gi/keep-alive.c
@@ -446,13 +446,10 @@ gjs_keep_alive_remove_global_child(JSContext *context,
}
JSObject*
-gjs_keep_alive_get_for_load_context(JSRuntime *runtime)
+gjs_keep_alive_get_for_context(JSContext *context)
{
- JSContext *context;
JSObject *keep_alive;
- context = gjs_runtime_get_load_context(runtime);
-
g_assert(context != NULL);
JS_BeginRequest(context);
diff --git a/gi/keep-alive.h b/gi/keep-alive.h
index 7c4d0c2..4f81459 100644
--- a/gi/keep-alive.h
+++ b/gi/keep-alive.h
@@ -73,7 +73,7 @@ void gjs_keep_alive_remove_global_child (JSContext *context,
GjsUnrootedFunc notify,
JSObject *child,
void *data);
-JSObject* gjs_keep_alive_get_for_load_context (JSRuntime *runtime);
+JSObject* gjs_keep_alive_get_for_context (JSContext *context);
diff --git a/gi/ns.c b/gi/ns.c
index 85652dd..6d85241 100644
--- a/gi/ns.c
+++ b/gi/ns.c
@@ -70,7 +70,7 @@ ns_new_resolve(JSContext *context,
const char *name;
GIRepository *repo;
GIBaseInfo *info;
- JSContext *load_context;
+ JSBool retval = JS_FALSE;
*objp = NULL;
@@ -88,8 +88,7 @@ ns_new_resolve(JSContext *context,
if (priv == NULL)
return JS_TRUE; /* we are the prototype, or have the wrong class */
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
+ JS_BeginRequest(context);
repo = g_irepository_get_default();
@@ -98,23 +97,17 @@ ns_new_resolve(JSContext *context,
/* Special-case fallback hack for GParamSpec */
if (strcmp(name, "ParamSpec") == 0 &&
strcmp(priv->namespace, "GLib") == 0) {
- gjs_define_param_class(load_context,
- obj,
- NULL);
- if (gjs_move_exception(load_context, context)) {
- JS_EndRequest(load_context);
- return JS_FALSE;
- } else {
- *objp = obj; /* we defined the property in this object */
- JS_EndRequest(load_context);
- return JS_TRUE;
- }
+ if (!gjs_define_param_class(context,
+ obj,
+ NULL))
+ goto out;
+ *objp = obj; /* we defined the property in this object */
+ retval = JS_TRUE;
} else {
gjs_throw(context,
"No symbol '%s' in namespace '%s'",
name, priv->namespace);
- JS_EndRequest(load_context);
- return JS_FALSE;
+ goto out;
}
}
@@ -124,27 +117,22 @@ ns_new_resolve(JSContext *context,
g_base_info_get_name(info),
g_base_info_get_namespace(info));
- if (gjs_define_info(load_context, obj, info)) {
+ if (gjs_define_info(context, obj, info)) {
g_base_info_unref(info);
*objp = obj; /* we defined the property in this object */
- JS_EndRequest(load_context);
- return JS_TRUE;
} else {
gjs_debug(GJS_DEBUG_GNAMESPACE,
"Failed to define info '%s'",
g_base_info_get_name(info));
g_base_info_unref(info);
-
- if (!gjs_move_exception(load_context, context)) {
- /* set an exception if none was set */
- gjs_throw(context,
- "Defining info failed but no exception set");
- }
-
- JS_EndRequest(load_context);
- return JS_FALSE;
+ goto out;
}
+
+ retval = JS_TRUE;
+ out:
+ JS_EndRequest(context);
+ return retval;
}
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
diff --git a/gi/object.c b/gi/object.c
index caacce5..fadc780 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -566,7 +566,10 @@ wrapped_gobj_toggle_notify(gpointer data,
* Or if !is_last_ref, we do not want to convert to a strong
* ref since we want everything collected on runtime destroy.
*/
- context = gjs_runtime_peek_load_context(runtime);
+ {
+ context = NULL;
+ JS_ContextIterator(runtime, &context);
+ }
if (!context)
return;
@@ -598,7 +601,7 @@ wrapped_gobj_toggle_notify(gpointer data,
*/
if (priv->keep_alive == NULL) {
gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Adding object to keep alive");
- priv->keep_alive = gjs_keep_alive_get_for_load_context(runtime);
+ priv->keep_alive = gjs_keep_alive_get_for_context(context);
gjs_keep_alive_add_child(context, priv->keep_alive,
gobj_no_longer_kept_alive_func,
obj,
@@ -746,7 +749,7 @@ object_instance_constructor(JSContext *context,
* the wrapper to be garbage collected (and thus unref the
* wrappee).
*/
- priv->keep_alive = gjs_keep_alive_get_for_load_context(JS_GetRuntime(context));
+ priv->keep_alive = gjs_keep_alive_get_for_context(context);
gjs_keep_alive_add_child(context,
priv->keep_alive,
gobj_no_longer_kept_alive_func,
diff --git a/gi/repo.c b/gi/repo.c
index cff1b24..3dd8166 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -59,28 +59,26 @@ resolve_namespace_object(JSContext *context,
{
GIRepository *repo;
GError *error;
- JSContext *load_context;
jsval versions_val;
JSObject *versions;
jsval version_val;
const char *version;
JSObject *result;
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
+ JS_BeginRequest(context);
- if (!gjs_object_require_property(load_context, repo_obj, "GI repository object", "versions", &versions_val) ||
+ if (!gjs_object_require_property(context, repo_obj, "GI repository object", "versions", &versions_val) ||
!JSVAL_IS_OBJECT(versions_val)) {
gjs_throw(context, "No 'versions' property in GI repository object");
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return NULL;
}
versions = JSVAL_TO_OBJECT(versions_val);
version = NULL;
- if (JS_GetProperty(load_context, versions, ns_name, &version_val) &&
+ if (JS_GetProperty(context, versions, ns_name, &version_val) &&
JSVAL_IS_STRING(version_val)) {
version = gjs_string_get_ascii(version_val);
}
@@ -94,7 +92,7 @@ resolve_namespace_object(JSContext *context,
"Requiring %s, version %s: %s",
ns_name, version?version:"none", error->message);
g_error_free(error);
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return JS_FALSE;
}
@@ -103,7 +101,7 @@ resolve_namespace_object(JSContext *context,
* in the repo.
*/
result = gjs_define_ns(context, repo_obj, ns_name, repo);
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return result;
}
@@ -129,7 +127,7 @@ repo_new_resolve(JSContext *context,
{
Repo *priv;
const char *name;
- JSContext *load_context;
+ JSBool retval = JS_FALSE;
*objp = NULL;
@@ -147,17 +145,17 @@ repo_new_resolve(JSContext *context,
if (priv == NULL)
return JS_TRUE; /* we are the prototype, or have the wrong class */
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
- resolve_namespace_object(load_context, obj, name);
- if (gjs_move_exception(load_context, context)) {
- JS_EndRequest(load_context);
- return JS_FALSE;
- } else {
- *objp = obj; /* store the object we defined the prop in */
- JS_EndRequest(load_context);
- return JS_TRUE;
- }
+ JS_BeginRequest(context);
+
+ if (!resolve_namespace_object(context, obj, name))
+ goto out;
+
+ retval = JS_TRUE;
+ *objp = obj; /* store the object we defined the prop in */
+
+ out:
+ JS_EndRequest(context);
+ return retval;
}
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
@@ -505,7 +503,6 @@ JSObject*
gjs_lookup_namespace_object_by_name(JSContext *context,
const char *ns)
{
- JSContext *load_context;
JSObject *global;
JSObject *repo_obj;
jsval importer;
@@ -517,23 +514,22 @@ gjs_lookup_namespace_object_by_name(JSContext *context,
* in the load context.
*/
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
- global = JS_GetGlobalObject(load_context);
+ JS_BeginRequest(context);
+ global = JS_GetGlobalObject(context);
importer = JSVAL_VOID;
- if (!gjs_object_require_property(load_context, global, "global object", "imports", &importer) ||
+ if (!gjs_object_require_property(context, global, "global object", "imports", &importer) ||
!JSVAL_IS_OBJECT(importer)) {
- gjs_log_exception(load_context, NULL);
+ gjs_log_exception(context, NULL);
gjs_throw(context, "No imports property in global object");
goto fail;
}
girepository = JSVAL_VOID;
- if (!gjs_object_require_property(load_context, JSVAL_TO_OBJECT(importer), "importer",
- "gi", &girepository) ||
+ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(importer), "importer",
+ "gi", &girepository) ||
!JSVAL_IS_OBJECT(girepository)) {
- gjs_log_exception(load_context, NULL);
+ gjs_log_exception(context, NULL);
gjs_throw(context, "No gi property in importer");
goto fail;
}
@@ -549,11 +545,11 @@ gjs_lookup_namespace_object_by_name(JSContext *context,
goto fail;
}
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return JSVAL_TO_OBJECT(ns_obj);
fail:
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return NULL;
}
diff --git a/gjs/byteArray.c b/gjs/byteArray.c
index d0157e9..8a5993b 100644
--- a/gjs/byteArray.c
+++ b/gjs/byteArray.c
@@ -843,9 +843,8 @@ JSBool
gjs_define_byte_array_stuff(JSContext *context,
JSObject *in_object)
{
- JSContext *load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
JSObject *global = JS_GetGlobalObject(context);
- gjs_byte_array_prototype = JS_InitClass(load_context, global,
+ gjs_byte_array_prototype = JS_InitClass(context, global,
NULL,
&gjs_byte_array_class,
byte_array_constructor,
@@ -857,14 +856,12 @@ gjs_define_byte_array_stuff(JSContext *context,
jsval rval;
if (gjs_byte_array_prototype == NULL) {
- gjs_move_exception(load_context, context);
return JS_FALSE;
}
if (!gjs_object_require_property(
- load_context, global, NULL,
+ context, global, NULL,
"ByteArray", &rval)) {
- gjs_move_exception(load_context, context);
return JS_FALSE;
}
diff --git a/gjs/context.c b/gjs/context.c
index 28f1c8c..9c20266 100644
--- a/gjs/context.c
+++ b/gjs/context.c
@@ -24,7 +24,6 @@
#include <config.h>
#include "context.h"
-#include "context-jsapi.h"
#include "importer.h"
#include "jsapi-util.h"
#include "profiler.h"
@@ -62,9 +61,6 @@ struct _GjsContext {
GjsProfiler *profiler;
char **search_path;
-
- unsigned int we_own_runtime : 1;
- unsigned int is_load_context : 1;
};
struct _GjsContextClass {
@@ -83,9 +79,7 @@ static int signals[LAST_SIGNAL];
enum {
PROP_0,
- PROP_SEARCH_PATH,
- PROP_RUNTIME,
- PROP_IS_LOAD_CONTEXT
+ PROP_SEARCH_PATH
};
@@ -316,25 +310,6 @@ gjs_context_class_init(GjsContextClass *klass)
PROP_SEARCH_PATH,
pspec);
- pspec = g_param_spec_pointer("runtime",
- "JSRuntime",
- "A runtime to use instead of creating our own",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property(object_class,
- PROP_RUNTIME,
- pspec);
-
- pspec = g_param_spec_boolean("is-load-context",
- "IsLoadContext",
- "Whether this is the load context",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
- g_object_class_install_property(object_class,
- PROP_IS_LOAD_CONTEXT,
- pspec);
-
gjs_register_native_module("byteArray", gjs_define_byte_array_stuff, 0);
}
@@ -358,42 +333,34 @@ gjs_context_dispose(GObject *object)
}
if (js_context->context != NULL) {
-
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Destroying JS context%s",
- js_context->is_load_context ? " (load context)" : "");
+ gjs_debug(GJS_DEBUG_CONTEXT, "Destroying JS context");
JS_DestroyContext(js_context->context);
js_context->context = NULL;
}
if (js_context->runtime != NULL) {
- if (js_context->we_own_runtime) {
- /* Avoid keeping JSContext with a dangling pointer to the
- * runtime.
- */
- gjs_runtime_clear_call_context(js_context->runtime);
- gjs_runtime_clear_load_context(js_context->runtime);
-
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Destroying JS runtime");
+ /* Avoid keeping JSContext with a dangling pointer to the
+ * runtime.
+ */
+ gjs_debug(GJS_DEBUG_CONTEXT,
+ "Destroying JS runtime");
- JS_DestroyRuntime(js_context->runtime);
+ JS_DestroyRuntime(js_context->runtime);
- /* finalize the dataset from jsapi-util.c ... for
- * "foreign" runtimes this just never happens for
- * now... we do this after the runtime itself is destroyed
- * because we might have finalizers run by
- * JS_DestroyRuntime() that rely on data we've set on the
- * runtime, such as the dynamic class structs.
- */
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Destroying any remaining dataset items on runtime");
+ /* finalize the dataset from jsapi-util.c ... for
+ * "foreign" runtimes this just never happens for
+ * now... we do this after the runtime itself is destroyed
+ * because we might have finalizers run by
+ * JS_DestroyRuntime() that rely on data we've set on the
+ * runtime, such as the dynamic class structs.
+ */
+ gjs_debug(GJS_DEBUG_CONTEXT,
+ "Destroying any remaining dataset items on runtime");
- g_dataset_destroy(js_context->runtime);
- }
- js_context->runtime = NULL;
+ g_dataset_destroy(js_context->runtime);
}
+ js_context->runtime = NULL;
G_OBJECT_CLASS(gjs_context_parent_class)->dispose(object);
}
@@ -553,7 +520,6 @@ gjs_context_constructor (GType type,
if (js_context->runtime == NULL)
gjs_fatal("Failed to create javascript runtime");
JS_SetGCParameter(js_context->runtime, JSGC_MAX_BYTES, 0xffffffff);
- js_context->we_own_runtime = TRUE;
}
js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */);
@@ -648,34 +614,26 @@ gjs_context_constructor (GType type,
4, GJS_MODULE_PROP_FLAGS))
gjs_fatal("Failed to define printerr function");
- /* If we created the root importer in the load context,
- * there would be infinite recursion since the load context
- * is a GjsContext
+ /* We create the global-to-runtime root importer with the
+ * passed-in search path. If someone else already created
+ * the root importer, this is a no-op.
*/
- if (!js_context->is_load_context) {
- /* We create the global-to-runtime root importer with the
- * passed-in search path. If someone else already created
- * the root importer, this is a no-op.
- */
- if (!gjs_create_root_importer(js_context->runtime,
- js_context->search_path ?
- (const char**) js_context->search_path :
- NULL,
- TRUE))
- gjs_fatal("Failed to create root importer");
-
- /* Now copy the global root importer (which we just created,
- * if it didn't exist) to our global object
- */
- if (!gjs_define_root_importer(js_context->context,
- js_context->global,
- "imports"))
- gjs_fatal("Failed to point 'imports' property at root importer");
- }
+ if (!gjs_create_root_importer(js_context,
+ js_context->search_path ?
+ (const char**) js_context->search_path :
+ NULL,
+ TRUE))
+ gjs_fatal("Failed to create root importer");
+
+ /* Now copy the global root importer (which we just created,
+ * if it didn't exist) to our global object
+ */
+ if (!gjs_define_root_importer(js_context,
+ js_context->global,
+ "imports"))
+ gjs_fatal("Failed to point 'imports' property at root importer");
- if (js_context->we_own_runtime) {
- js_context->profiler = gjs_profiler_new(js_context->runtime);
- }
+ js_context->profiler = gjs_profiler_new(js_context->runtime);
JS_EndRequest(js_context->context);
@@ -697,8 +655,8 @@ gjs_context_get_property (GObject *object,
js_context = GJS_CONTEXT (object);
switch (prop_id) {
- case PROP_IS_LOAD_CONTEXT:
- g_value_set_boolean(value, js_context->is_load_context);
+ case PROP_SEARCH_PATH:
+ g_value_set_boxed(value, js_context->search_path);
break;
default:
@@ -721,12 +679,6 @@ gjs_context_set_property (GObject *object,
case PROP_SEARCH_PATH:
js_context->search_path = g_strdupv(g_value_get_pointer(value));
break;
- case PROP_RUNTIME:
- js_context->runtime = g_value_get_pointer(value);
- break;
- case PROP_IS_LOAD_CONTEXT:
- js_context->is_load_context = g_value_get_boolean(value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -784,12 +736,6 @@ gjs_context_get_native_context (GjsContext *js_context)
}
gboolean
-gjs_context_is_load_context(GjsContext *js_context)
-{
- return js_context->is_load_context;
-}
-
-gboolean
gjs_context_eval(GjsContext *js_context,
const char *script,
gssize script_len,
diff --git a/gjs/importer.c b/gjs/importer.c
index f2d1bd1..d0c347a 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -913,7 +913,6 @@ importer_new_resolve(JSContext *context,
{
Importer *priv;
const char *name;
- JSContext *load_context;
*objp = NULL;
@@ -932,20 +931,13 @@ importer_new_resolve(JSContext *context,
return JS_TRUE; /* we are the prototype, or have the wrong class */
/* We always import in the special load context. */
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
- if (do_import(load_context, obj, priv, name)) {
+ JS_BeginRequest(context);
+ if (do_import(context, obj, priv, name)) {
*objp = obj;
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return JS_TRUE;
} else {
- /* Move the exception to the calling context from load context.
- */
- if (!gjs_move_exception(load_context, context)) {
- /* set an exception since none was set */
- gjs_throw(context, "No exception was set, but import failed somehow");
- }
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return JS_FALSE;
}
}
@@ -1185,13 +1177,13 @@ gjs_define_importer(JSContext *context,
* we just ignore all calls after the first and hope the args are the same.
*/
JSBool
-gjs_create_root_importer(JSRuntime *runtime,
+gjs_create_root_importer(GjsContext *gjs_context,
const char **initial_search_path,
gboolean add_standard_search_path)
{
JSContext *context;
- context = gjs_runtime_get_load_context(runtime);
+ context = gjs_context_get_native_context(gjs_context);
JS_BeginRequest(context);
@@ -1216,20 +1208,20 @@ gjs_create_root_importer(JSRuntime *runtime,
}
JSBool
-gjs_define_root_importer(JSContext *context,
+gjs_define_root_importer(GjsContext *gjs_context,
JSObject *in_object,
const char *importer_name)
{
- JSContext *load_context;
+ JSContext *context;
jsval value;
JSBool success;
success = JS_FALSE;
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
+ context = gjs_context_get_native_context(gjs_context);
+ JS_BeginRequest(context);
- if (!gjs_object_require_property(load_context,
- JS_GetGlobalObject(load_context), "global object",
+ if (!gjs_object_require_property(context,
+ JS_GetGlobalObject(context), "global object",
"imports", &value) ||
!JSVAL_IS_OBJECT(value)) {
gjs_debug(GJS_DEBUG_IMPORTER, "Root importer did not exist, couldn't get from load context; must create it");
@@ -1247,6 +1239,6 @@ gjs_define_root_importer(JSContext *context,
success = JS_TRUE;
fail:
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return success;
}
diff --git a/gjs/importer.h b/gjs/importer.h
index 2bd99e0..50e7753 100644
--- a/gjs/importer.h
+++ b/gjs/importer.h
@@ -34,10 +34,10 @@
G_BEGIN_DECLS
-JSBool gjs_create_root_importer (JSRuntime *runtime,
+JSBool gjs_create_root_importer (GjsContext *context,
const char **initial_search_path,
gboolean add_standard_search_path);
-JSBool gjs_define_root_importer (JSContext *context,
+JSBool gjs_define_root_importer (GjsContext *context,
JSObject *in_object,
const char *importer_name);
JSObject* gjs_define_importer (JSContext *context,
diff --git a/gjs/jsapi-private.cpp b/gjs/jsapi-private.cpp
index b27935a..ad47065 100644
--- a/gjs/jsapi-private.cpp
+++ b/gjs/jsapi-private.cpp
@@ -29,7 +29,6 @@
#include "jsapi-util.h"
#include "jsapi-private.h"
-#include "context-jsapi.h"
#include <string.h>
#include <jscntxt.h>
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index e2f7f14..3dc9178 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -29,7 +29,6 @@
#include <util/misc.h>
#include "jsapi-util.h"
-#include "context-jsapi.h"
#include "jsapi-private.h"
#include <string.h>
@@ -65,112 +64,6 @@ gjs_runtime_set_data(JSRuntime *runtime,
g_dataset_set_data_full(runtime, name, data, dnotify);
}
-/* The "load context" is the one we use for loading
- * modules and initializing classes.
- */
-JSContext*
-gjs_runtime_get_load_context(JSRuntime *runtime)
-{
- GjsContext *context;
-
- context = gjs_runtime_get_data(runtime, "gjs-load-context");
- if (context == NULL) {
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Creating load context for runtime %p",
- runtime);
- context = g_object_new(GJS_TYPE_CONTEXT,
- "runtime", runtime,
- "is-load-context", TRUE,
- NULL);
- gjs_runtime_set_data(runtime,
- "gjs-load-context",
- context,
- g_object_unref);
- }
-
- return (JSContext*)gjs_context_get_native_context(context);
-}
-
-JSContext*
-gjs_runtime_peek_load_context(JSRuntime *runtime)
-{
- GjsContext *context;
-
- context = gjs_runtime_get_data(runtime, "gjs-load-context");
- if (context == NULL) {
- return NULL;
- } else {
- return (JSContext*)gjs_context_get_native_context(context);
- }
-}
-
-void
-gjs_runtime_clear_load_context(JSRuntime *runtime)
-{
- gjs_debug(GJS_DEBUG_CONTEXT, "Clearing load context");
- gjs_runtime_set_data(runtime,
- "gjs-load-context",
- NULL,
- NULL);
- gjs_debug(GJS_DEBUG_CONTEXT, "Load context cleared");
-}
-
-/* The call context exists because when we call a closure, the scope
- * chain on the context is set to the original scope chain of the
- * closure. We want to avoid using any existing context (especially
- * the load context) because the closure "messes up" the scope chain
- * on the context.
- *
- * Unlike the load context, which is expected to be an eternal
- * singleton, we only cache the call context for efficiency. It would
- * be just as workable to recreate it for each call.
- */
-JSContext*
-gjs_runtime_get_call_context(JSRuntime *runtime)
-{
- GjsContext *context;
-
- context = gjs_runtime_get_data(runtime, "gjs-call-context");
- if (context == NULL) {
- gjs_debug(GJS_DEBUG_CONTEXT,
- "Creating call context for runtime %p",
- runtime);
- context = g_object_new(GJS_TYPE_CONTEXT,
- "runtime", runtime,
- NULL);
- gjs_runtime_set_data(runtime,
- "gjs-call-context",
- context,
- g_object_unref);
- }
-
- return (JSContext*)gjs_context_get_native_context(context);
-}
-
-static JSContext*
-gjs_runtime_peek_call_context(JSRuntime *runtime)
-{
- GjsContext *context;
-
- context = gjs_runtime_get_data(runtime, "gjs-call-context");
- if (context == NULL) {
- return NULL;
- } else {
- return (JSContext*)gjs_context_get_native_context(context);
- }
-}
-
-void
-gjs_runtime_clear_call_context(JSRuntime *runtime)
-{
- gjs_debug(GJS_DEBUG_CONTEXT, "Clearing call context");
- gjs_runtime_set_data(runtime,
- "gjs-call-context",
- NULL,
- NULL);
- gjs_debug(GJS_DEBUG_CONTEXT, "Call context cleared");
-}
-
static void
runtime_data_destroy_notify(void *data)
{
@@ -320,7 +213,6 @@ gjs_init_class_dynamic(JSContext *context,
jsval value;
char *private_name;
JSObject *prototype;
- JSContext *load_context;
if (clasp->name != NULL) {
g_warning("Dynamic class should not have a name in the JSClass struct");
@@ -329,15 +221,6 @@ gjs_init_class_dynamic(JSContext *context,
JS_BeginRequest(context);
- /* We replace the passed-in context and global object with our
- * runtime-global permanent load context. Otherwise, in a
- * process with multiple contexts, we'd arbitrarily define
- * the class in whatever global object initialized the
- * class first, which is not desirable.
- */
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
-
/* JS_InitClass() wants to define the constructor in the global object, so
* we give it a private and namespaced name... passing in the namespace
* object instead of global object seems to break JS_ConstructObject()
@@ -347,17 +230,17 @@ gjs_init_class_dynamic(JSContext *context,
private_name = g_strdup_printf("_private_%s_%s", ns_name, class_name);
prototype = NULL;
- if (gjs_object_get_property(load_context, JS_GetGlobalObject(load_context),
+ if (gjs_object_get_property(context, JS_GetGlobalObject(context),
private_name, &value) &&
JSVAL_IS_OBJECT(value)) {
jsval proto_val;
g_free(private_name); /* don't need it anymore */
- if (!gjs_object_require_property(load_context, JSVAL_TO_OBJECT(value), NULL,
+ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(value), NULL,
"prototype", &proto_val) ||
!JSVAL_IS_OBJECT(proto_val)) {
- gjs_throw(load_context, "prototype was not defined or not an object?");
+ gjs_throw(context, "prototype was not defined or not an object?");
goto error;
}
prototype = JSVAL_TO_OBJECT(proto_val);
@@ -365,7 +248,7 @@ gjs_init_class_dynamic(JSContext *context,
DynamicJSClass *class_copy;
RuntimeData *rd;
- rd = get_data_from_context(load_context);
+ rd = get_data_from_context(context);
class_copy = g_slice_new0(DynamicJSClass);
class_copy->base = *clasp;
@@ -383,7 +266,7 @@ gjs_init_class_dynamic(JSContext *context,
"Initializing dynamic class %s %p",
class_name, class_copy);
- prototype = JS_InitClass(load_context, JS_GetGlobalObject(load_context),
+ prototype = JS_InitClass(context, JS_GetGlobalObject(context),
parent_proto, &class_copy->base,
constructor, nargs,
ps, fs,
@@ -392,7 +275,7 @@ gjs_init_class_dynamic(JSContext *context,
/* Retrieve the property again so we can define it in
* in_object
*/
- if (!gjs_object_require_property(load_context, JS_GetGlobalObject(load_context), NULL,
+ if (!gjs_object_require_property(context, JS_GetGlobalObject(context), NULL,
class_copy->base.name, &value))
goto error;
}
@@ -402,26 +285,17 @@ gjs_init_class_dynamic(JSContext *context,
/* Now manually define our constructor with a sane name, in the
* namespace object.
*/
- if (!JS_DefineProperty(load_context, in_object,
+ if (!JS_DefineProperty(context, in_object,
class_name,
value,
NULL, NULL,
GJS_MODULE_PROP_FLAGS))
goto error;
- JS_EndRequest(load_context);
JS_EndRequest(context);
return prototype;
error:
- /* Move the exception to the calling context from load context.
- */
- if (!gjs_move_exception(load_context, context)) {
- /* set an exception since none was set */
- gjs_throw(context, "No exception was set, but class initialize failed somehow");
- }
-
- JS_EndRequest(load_context);
JS_EndRequest(context);
return NULL;
}
@@ -532,26 +406,17 @@ gjs_construct_object_dynamic(JSContext *context,
{
RuntimeData *rd;
JSClass *proto_class;
- JSContext *load_context;
JSObject *result;
JS_BeginRequest(context);
- /* We replace the passed-in context and global object with our
- * runtime-global permanent load context. Otherwise, JS_ConstructObject
- * can't find the constructor in whatever random global object is set
- * on the passed-in context.
- */
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
-
- proto_class = JS_GET_CLASS(load_context, proto);
+ proto_class = JS_GET_CLASS(context, proto);
- rd = get_data_from_context(load_context);
+ rd = get_data_from_context(context);
/* Check that it's safe to cast to DynamicJSClass */
if (g_hash_table_lookup(rd->dynamic_classes, proto_class) == NULL) {
- gjs_throw(load_context, "Prototype is not for a dynamically-registered class");
+ gjs_throw(context, "Prototype is not for a dynamically-registered class");
goto error;
}
@@ -560,26 +425,18 @@ gjs_construct_object_dynamic(JSContext *context,
proto_class->name, proto_class, proto);
if (argc > 0)
- result = JS_ConstructObjectWithArguments(load_context, proto_class, proto, NULL, argc, argv);
+ result = JS_ConstructObjectWithArguments(context, proto_class, proto, NULL, argc, argv);
else
- result = JS_ConstructObject(load_context, proto_class, proto, NULL);
+ result = JS_ConstructObject(context, proto_class, proto, NULL);
if (!result)
goto error;
- JS_EndRequest(load_context);
JS_EndRequest(context);
return result;
error:
- /* Move the exception to the calling context from load context.
- */
- if (!gjs_move_exception(load_context, context)) {
- /* set an exception since none was set */
- gjs_throw(context, "No exception was set, but object construction failed somehow");
- }
- JS_EndRequest(load_context);
JS_EndRequest(context);
return NULL;
}
@@ -733,8 +590,6 @@ void
gjs_explain_scope(JSContext *context,
const char *title)
{
- JSContext *load_context;
- JSContext *call_context;
JSObject *global;
JSObject *parent;
GString *chain;
@@ -743,21 +598,11 @@ gjs_explain_scope(JSContext *context,
"=== %s ===",
title);
- load_context = gjs_runtime_peek_load_context(JS_GetRuntime(context));
- call_context = gjs_runtime_peek_call_context(JS_GetRuntime(context));
-
JS_BeginRequest(context);
- JS_BeginRequest(load_context);
- JS_BeginRequest(call_context);
JS_EnterLocalRootScope(context);
- gjs_debug(GJS_DEBUG_SCOPE,
- " Context: %p %s",
- context,
- context == load_context ? "(LOAD CONTEXT)" :
- context == call_context ? "(CALL CONTEXT)" :
- "");
+ gjs_debug(GJS_DEBUG_SCOPE, " Context: %p", context);
global = JS_GetGlobalObject(context);
gjs_debug(GJS_DEBUG_SCOPE,
@@ -784,8 +629,6 @@ gjs_explain_scope(JSContext *context,
JS_LeaveLocalRootScope(context);
- JS_EndRequest(call_context);
- JS_EndRequest(load_context);
JS_EndRequest(context);
}
@@ -911,82 +754,6 @@ gjs_log_and_keep_exception(JSContext *context,
return log_and_maybe_keep_exception(context, message_p, TRUE);
}
-static void
-try_to_chain_stack_trace(JSContext *src_context, JSContext *dst_context,
- jsval src_exc) {
- /* append current stack of dst_context to stack trace for src_exc.
- * we bail if anything goes wrong, just using the src_exc unmodified
- * in that case. */
- jsval chained, src_stack, dst_stack, new_stack;
- JSString *new_stack_str;
-
- JS_BeginRequest(src_context);
- JS_BeginRequest(dst_context);
-
- if (!JSVAL_IS_OBJECT(src_exc))
- goto out; // src_exc doesn't have a stack trace
-
- /* create a new exception in dst_context to get a stack trace */
- gjs_throw_literal(dst_context, "Chained exception");
- if (!(JS_GetPendingException(dst_context, &chained) &&
- JSVAL_IS_OBJECT(chained)))
- goto out; // gjs_throw_literal didn't work?!
- JS_ClearPendingException(dst_context);
-
- /* get stack trace for src_exc and chained */
- if (!(gjs_object_get_property(dst_context, JSVAL_TO_OBJECT(chained),
- "stack", &dst_stack) &&
- JSVAL_IS_STRING(dst_stack)))
- goto out; // couldn't get chained stack
- if (!(gjs_object_get_property(src_context, JSVAL_TO_OBJECT(src_exc),
- "stack", &src_stack) &&
- JSVAL_IS_STRING(src_stack)))
- goto out; // couldn't get source stack
-
- /* add chained exception's stack trace to src_exc */
- new_stack_str = JS_ConcatStrings
- (dst_context, JSVAL_TO_STRING(src_stack), JSVAL_TO_STRING(dst_stack));
- if (new_stack_str==NULL)
- goto out; // couldn't concatenate src and dst stacks?!
- new_stack = STRING_TO_JSVAL(new_stack_str);
- JS_SetProperty(dst_context, JSVAL_TO_OBJECT(src_exc), "stack", &new_stack);
-
- out:
- JS_EndRequest(dst_context);
- JS_EndRequest(src_context);
-}
-
-JSBool
-gjs_move_exception(JSContext *src_context,
- JSContext *dest_context)
-{
- JSBool success;
-
- JS_BeginRequest(src_context);
- JS_BeginRequest(dest_context);
-
- /* NOTE: src and dest could be the same. */
- jsval exc;
- if (JS_GetPendingException(src_context, &exc)) {
- if (src_context != dest_context) {
- /* try to add the current stack of dest_context to the
- * stack trace of exc */
- try_to_chain_stack_trace(src_context, dest_context, exc);
- /* move the exception to dest_context */
- JS_SetPendingException(dest_context, exc);
- JS_ClearPendingException(src_context);
- }
- success = JS_TRUE;
- } else {
- success = JS_FALSE;
- }
-
- JS_EndRequest(dest_context);
- JS_EndRequest(src_context);
-
- return success;
-}
-
JSBool
gjs_call_function_value(JSContext *context,
JSObject *obj,
@@ -996,18 +763,11 @@ gjs_call_function_value(JSContext *context,
jsval *rval)
{
JSBool result;
- JSContext *call_context;
JS_BeginRequest(context);
-
- call_context = gjs_runtime_get_call_context(JS_GetRuntime(context));
- JS_BeginRequest(call_context);
-
- result = JS_CallFunctionValue(call_context, obj, fval,
+ result = JS_CallFunctionValue(context, obj, fval,
argc, argv, rval);
- gjs_move_exception(call_context, context);
- JS_EndRequest(call_context);
JS_EndRequest(context);
return result;
}
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 9921805..51db961 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -164,11 +164,10 @@ static struct JSClass cname##_class = { \
jsval cname##_create_proto(JSContext *context, JSObject *module, const char *proto_name, JSObject *parent) \
{ \
jsval rval; \
- JSContext *load_context = gjs_runtime_get_load_context(JS_GetRuntime(context)); \
JSObject *global = JS_GetGlobalObject(context); \
- if (!gjs_object_has_property(load_context, global, \
+ if (!gjs_object_has_property(context, global, \
cname##_class.name)) { \
- JSObject *prototype = JS_InitClass(load_context, global, \
+ JSObject *prototype = JS_InitClass(context, global, \
parent, \
&cname##_class, \
ctor, \
@@ -178,13 +177,11 @@ jsval cname##_create_proto(JSContext *context, JSObject *module, const char *pro
NULL, \
NULL); \
if (prototype == NULL) { \
- gjs_move_exception(load_context, context); \
return JSVAL_NULL; \
} \
if (!gjs_object_require_property( \
- load_context, global, NULL, \
+ context, global, NULL, \
cname##_class.name, &rval)) { \
- gjs_move_exception(load_context, context); \
return JSVAL_NULL; \
} \
} \
@@ -201,11 +198,6 @@ void gjs_runtime_set_data (JSRuntime *runtime,
const char *name,
void *data,
GDestroyNotify dnotify);
-JSContext* gjs_runtime_get_load_context (JSRuntime *runtime);
-JSContext* gjs_runtime_peek_load_context (JSRuntime *runtime);
-void gjs_runtime_clear_load_context (JSRuntime *runtime);
-JSContext* gjs_runtime_get_call_context (JSRuntime *runtime);
-void gjs_runtime_clear_call_context (JSRuntime *runtime);
gboolean gjs_object_has_property (JSContext *context,
JSObject *obj,
const char *property_name);
@@ -262,8 +254,6 @@ JSBool gjs_log_exception (JSContext *context,
char **message_p);
JSBool gjs_log_and_keep_exception (JSContext *context,
char **message_p);
-JSBool gjs_move_exception (JSContext *src_context,
- JSContext *dest_context);
void gjs_log_exception_props (JSContext *context,
jsval exc);
#ifdef __GJS_UTIL_LOG_H__
diff --git a/gjs/stack.c b/gjs/stack.c
index 410fc24..8e0e5ac 100644
--- a/gjs/stack.c
+++ b/gjs/stack.c
@@ -41,10 +41,10 @@
* ***** END LICENSE BLOCK ***** */
#include <config.h>
-#include "context-jsapi.h"
#include <glib.h>
#include <string.h>
#include <jsdbgapi.h>
+#include "context.h"
static const char*
jsvalue_to_string(JSContext* cx, jsval val, gboolean* is_string)
diff --git a/modules/dbus-exports.c b/modules/dbus-exports.c
index 99259a0..87889f9 100644
--- a/modules/dbus-exports.c
+++ b/modules/dbus-exports.c
@@ -1860,16 +1860,13 @@ gjs_js_define_dbus_exports(JSContext *context,
DBusBusType which_bus)
{
JSObject *exports;
- JSContext *load_context;
JSBool success;
success = JS_FALSE;
- load_context = gjs_runtime_get_load_context(JS_GetRuntime(context));
- JS_BeginRequest(load_context);
+ JS_BeginRequest(context);
- exports = exports_new(load_context, which_bus);
+ exports = exports_new(context, which_bus);
if (exports == NULL) {
- gjs_move_exception(load_context, context);
goto fail;
}
@@ -1885,6 +1882,6 @@ gjs_js_define_dbus_exports(JSContext *context,
success = JS_TRUE;
fail:
- JS_EndRequest(load_context);
+ JS_EndRequest(context);
return success;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]