[gjs/wip/require: 5/11] runtime: Have a thread-specific JSRuntime
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/require: 5/11] runtime: Have a thread-specific JSRuntime
- Date: Wed, 15 Jan 2014 16:58:28 +0000 (UTC)
commit bde55facecff15778459987519de3294cedf8e95
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Jan 15 10:57:18 2014 -0500
runtime: Have a thread-specific JSRuntime
JSRuntime needs to match 1:1 to a thread, so if we have more than
one runtime in a thread, like we did in the test suite before, we
would blow up.
gjs/context.cpp | 133 +----------------------------------------------
gjs/runtime.cpp | 158 ++++++++++++++++++++++++++++++++++++++++++++++---------
gjs/runtime.h | 4 +-
3 files changed, 135 insertions(+), 160 deletions(-)
---
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 591a25d..afa8a38 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -346,13 +346,6 @@ gjs_context_dispose(GObject *object)
JS_DestroyContext(js_context->context);
js_context->context = NULL;
- }
-
- if (js_context->runtime != NULL) {
- gjs_runtime_deinit(js_context->runtime);
-
- /* Cleans up data as well as destroying the runtime. */
- JS_DestroyRuntime(js_context->runtime);
js_context->runtime = NULL;
}
@@ -386,122 +379,6 @@ gjs_context_finalize(GObject *object)
G_OBJECT_CLASS(gjs_context_parent_class)->finalize(object);
}
-/* Implementations of locale-specific operations; these are used
- * in the implementation of String.localeCompare(), Date.toLocaleDateString(),
- * and so forth. We take the straight-forward approach of converting
- * to UTF-8, using the appropriate GLib functions, and converting
- * back if necessary.
- */
-static JSBool
-gjs_locale_to_upper_case (JSContext *context,
- JS::HandleString src,
- JS::MutableHandleValue retval)
-{
- JSBool success = JS_FALSE;
- char *utf8 = NULL;
- char *upper_case_utf8 = NULL;
-
- if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src), &utf8))
- goto out;
-
- upper_case_utf8 = g_utf8_strup (utf8, -1);
-
- if (!gjs_string_from_utf8(context, upper_case_utf8, -1, retval.address()))
- goto out;
-
- success = JS_TRUE;
-
-out:
- g_free(utf8);
- g_free(upper_case_utf8);
-
- return success;
-}
-
-static JSBool
-gjs_locale_to_lower_case (JSContext *context,
- JS::HandleString src,
- JS::MutableHandleValue retval)
-{
- JSBool success = JS_FALSE;
- char *utf8 = NULL;
- char *lower_case_utf8 = NULL;
-
- if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src), &utf8))
- goto out;
-
- lower_case_utf8 = g_utf8_strdown (utf8, -1);
-
- if (!gjs_string_from_utf8(context, lower_case_utf8, -1, retval.address()))
- goto out;
-
- success = JS_TRUE;
-
-out:
- g_free(utf8);
- g_free(lower_case_utf8);
-
- return success;
-}
-
-static JSBool
-gjs_locale_compare (JSContext *context,
- JS::HandleString src_1,
- JS::HandleString src_2,
- JS::MutableHandleValue retval)
-{
- JSBool success = JS_FALSE;
- char *utf8_1 = NULL, *utf8_2 = NULL;
- int result;
-
- if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src_1), &utf8_1) ||
- !gjs_string_to_utf8(context, STRING_TO_JSVAL(src_2), &utf8_2))
- goto out;
-
- result = g_utf8_collate (utf8_1, utf8_2);
- retval.set(INT_TO_JSVAL(result));
-
- success = JS_TRUE;
-
-out:
- g_free(utf8_1);
- g_free(utf8_2);
-
- return success;
-}
-
-static JSBool
-gjs_locale_to_unicode (JSContext *context,
- const char *src,
- JS::MutableHandleValue retval)
-{
- JSBool success;
- char *utf8;
- GError *error = NULL;
-
- utf8 = g_locale_to_utf8(src, -1, NULL, NULL, &error);
- if (!utf8) {
- gjs_throw(context,
- "Failed to convert locale string to UTF8: %s",
- error->message);
- g_error_free(error);
- return JS_FALSE;
- }
-
- success = gjs_string_from_utf8(context, utf8, -1, retval.address());
- g_free (utf8);
-
- return success;
-}
-
-static JSLocaleCallbacks gjs_locale_callbacks =
-{
- gjs_locale_to_upper_case,
- gjs_locale_to_lower_case,
- gjs_locale_compare,
- gjs_locale_to_unicode
-};
-
static void
gjs_context_constructed(GObject *object)
{
@@ -511,18 +388,12 @@ gjs_context_constructed(GObject *object)
G_OBJECT_CLASS(gjs_context_parent_class)->constructed(object);
- js_context->runtime = JS_NewRuntime(32*1024*1024 /* max bytes */, JS_USE_HELPER_THREADS);
- JS_SetNativeStackQuota(js_context->runtime, 1024*1024);
- if (js_context->runtime == NULL)
- g_error("Failed to create javascript runtime");
- JS_SetGCParameter(js_context->runtime, JSGC_MAX_BYTES, 0xffffffff);
+ js_context->runtime = gjs_runtime_for_current_thread();
js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */);
if (js_context->context == NULL)
g_error("Failed to create javascript context");
- gjs_runtime_init_for_context(js_context->runtime, js_context->context);
-
for (i = 0; i < GJS_STRING_LAST; i++)
js_context->const_strings[i] = gjs_intern_string_to_id(js_context->context, const_strings[i]);
@@ -544,8 +415,6 @@ gjs_context_constructed(GObject *object)
JS_SetOptions(js_context->context,
JS_GetOptions(js_context->context) | options_flags);
- JS_SetLocaleCallbacks(js_context->runtime, &gjs_locale_callbacks);
-
JS_SetErrorReporter(js_context->context, gjs_error_reporter);
/* set ourselves as the private data */
diff --git a/gjs/runtime.cpp b/gjs/runtime.cpp
index c9acebd..68a2cc8 100644
--- a/gjs/runtime.cpp
+++ b/gjs/runtime.cpp
@@ -23,41 +23,149 @@
#include <config.h>
-#include <util/log.h>
-#include <util/glib.h>
-#include <util/misc.h>
-
-#include "jsapi-util.h"
#include "compat.h"
-#include "jsapi-private.h"
-#include "runtime.h"
-#include <string.h>
-#include <math.h>
+/* Implementations of locale-specific operations; these are used
+ * in the implementation of String.localeCompare(), Date.toLocaleDateString(),
+ * and so forth. We take the straight-forward approach of converting
+ * to UTF-8, using the appropriate GLib functions, and converting
+ * back if necessary.
+ */
+static JSBool
+gjs_locale_to_upper_case (JSContext *context,
+ JS::HandleString src,
+ JS::MutableHandleValue retval)
+{
+ JSBool success = JS_FALSE;
+ char *utf8 = NULL;
+ char *upper_case_utf8 = NULL;
+
+ if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src), &utf8))
+ goto out;
+
+ upper_case_utf8 = g_utf8_strup (utf8, -1);
-typedef struct {
- JSContext *context;
-} GjsRuntimeData;
+ if (!gjs_string_from_utf8(context, upper_case_utf8, -1, retval.address()))
+ goto out;
+
+ success = JS_TRUE;
+
+out:
+ g_free(utf8);
+ g_free(upper_case_utf8);
+
+ return success;
+}
-static inline GjsRuntimeData *
-get_data(JSRuntime *runtime)
+static JSBool
+gjs_locale_to_lower_case (JSContext *context,
+ JS::HandleString src,
+ JS::MutableHandleValue retval)
{
- return (GjsRuntimeData*) JS_GetRuntimePrivate(runtime);
+ JSBool success = JS_FALSE;
+ char *utf8 = NULL;
+ char *lower_case_utf8 = NULL;
+
+ if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src), &utf8))
+ goto out;
+
+ lower_case_utf8 = g_utf8_strdown (utf8, -1);
+
+ if (!gjs_string_from_utf8(context, lower_case_utf8, -1, retval.address()))
+ goto out;
+
+ success = JS_TRUE;
+
+out:
+ g_free(utf8);
+ g_free(lower_case_utf8);
+
+ return success;
}
-void
-gjs_runtime_init_for_context(JSRuntime *runtime,
- JSContext *context)
+static JSBool
+gjs_locale_compare (JSContext *context,
+ JS::HandleString src_1,
+ JS::HandleString src_2,
+ JS::MutableHandleValue retval)
{
- GjsRuntimeData *data;
+ JSBool success = JS_FALSE;
+ char *utf8_1 = NULL, *utf8_2 = NULL;
+ int result;
+
+ if (!gjs_string_to_utf8(context, STRING_TO_JSVAL(src_1), &utf8_1) ||
+ !gjs_string_to_utf8(context, STRING_TO_JSVAL(src_2), &utf8_2))
+ goto out;
+
+ result = g_utf8_collate (utf8_1, utf8_2);
+ retval.set(INT_TO_JSVAL(result));
+
+ success = JS_TRUE;
- data = g_new(GjsRuntimeData, 1);
- data->context = context;
- JS_SetRuntimePrivate(runtime, data);
+out:
+ g_free(utf8_1);
+ g_free(utf8_2);
+
+ return success;
}
-void
-gjs_runtime_deinit(JSRuntime *runtime)
+static JSBool
+gjs_locale_to_unicode (JSContext *context,
+ const char *src,
+ JS::MutableHandleValue retval)
{
- g_free(get_data(runtime));
+ JSBool success;
+ char *utf8;
+ GError *error = NULL;
+
+ utf8 = g_locale_to_utf8(src, -1, NULL, NULL, &error);
+ if (!utf8) {
+ gjs_throw(context,
+ "Failed to convert locale string to UTF8: %s",
+ error->message);
+ g_error_free(error);
+ return JS_FALSE;
+ }
+
+ success = gjs_string_from_utf8(context, utf8, -1, retval.address());
+ g_free (utf8);
+
+ return success;
+}
+
+static void
+destroy_runtime(gpointer data)
+{
+ JSRuntime *runtime = (JSRuntime *) data;
+ JS_DestroyRuntime(runtime);
+}
+
+static GPrivate thread_runtime = G_PRIVATE_INIT(destroy_runtime);
+
+static JSLocaleCallbacks gjs_locale_callbacks =
+{
+ gjs_locale_to_upper_case,
+ gjs_locale_to_lower_case,
+ gjs_locale_compare,
+ gjs_locale_to_unicode
+};
+
+JSRuntime *
+gjs_runtime_for_current_thread(void)
+{
+ JSRuntime *runtime = (JSRuntime *) g_private_get(&thread_runtime);
+
+ if (!runtime) {
+ runtime = JS_NewRuntime(32*1024*1024 /* max bytes */, JS_USE_HELPER_THREADS);
+ if (runtime == NULL)
+ g_error("Failed to create javascript runtime");
+
+ JS_SetNativeStackQuota(runtime, 1024*1024);
+ JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff);
+ JS_SetLocaleCallbacks(runtime, &gjs_locale_callbacks);
+
+ g_private_set(&thread_runtime, runtime);
+ }
+
+ return runtime;
}
diff --git a/gjs/runtime.h b/gjs/runtime.h
index 17e4364..90233b0 100644
--- a/gjs/runtime.h
+++ b/gjs/runtime.h
@@ -24,8 +24,6 @@
#ifndef __GJS_RUNTIME_H__
#define __GJS_RUNTIME_H__
-void gjs_runtime_init_for_context (JSRuntime *runtime,
- JSContext *context);
-void gjs_runtime_deinit (JSRuntime *runtime);
+JSRuntime * gjs_runtime_for_current_thread (void);
#endif /* __GJS_RUNTIME_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]