aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Linton <jeremy.linton@arm.com>2017-04-25 16:21:09 -0500
committerDaniel Wagner <wagi@monom.org>2017-04-26 19:24:08 +0200
commitd07e2f7e5bf9d689941c023410d25789bc4b1531 (patch)
treee4d8fdddcfabca922f6a13c99365624550a2a942
parent765d8500657f295abf9a521582a3951f8f6fad66 (diff)
downloadpacrunner-d07e2f7e5bf9d689941c023410d25789bc4b1531.tar.gz
build: Pull pacrunner forward to mozjs38
Mozjs185 is getting really old and unsupported. Newer versions of the mozjs JSAPI are C++ based. So we convert the plugin to C++ and then apply necessarily API changes so that it can be built with the more recent mozjs38. For example we now need to "root" values being passed into the API in order to satisfy the JSAPI garbage collection rules. Further, a number of the APIs have been tweaked and moved into the JS namespace, so we namespace them appropriately and adjust their parameters.
-rw-r--r--Makefile.am15
-rw-r--r--configure.ac4
-rw-r--r--plugins/mozjs.cc (renamed from plugins/mozjs.c)109
3 files changed, 68 insertions, 60 deletions
diff --git a/Makefile.am b/Makefile.am
index ee84b75..65cc8c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,9 +31,10 @@ endif
if MOZJS
js_sources = src/js_funcs.c
builtin_modules += mozjs
-builtin_sources += plugins/mozjs.c
-builtin_cflags += @MOZJS_CFLAGS@
-builtin_libadd += @MOZJS_LIBS@
+builtin_libadd += plugins/libmozjsplugin.a @MOZJS_LIBS@ -lstdc++
+noinst_LIBRARIES += plugins/libmozjsplugin.a
+plugins_libmozjsplugin_a_SOURCES = plugins/mozjs.cc
+plugins_libmozjsplugin_a_CXXFLAGS = $(AM_CFLAGS) @MOZJS_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@
endif
if V8
@@ -137,16 +138,16 @@ unit_test_pacrunner_LDADD += @CURL_LIBS@
endif
if MOZJS
-unit_test_pacrunner_SOURCES += plugins/mozjs.c
-
+unit_test_pacrunner_SOURCES += plugins/mozjs.cc
+unit_test_pacrunner_CXXFLAGS = $(AM_CFLAGS) @MOZJS_CFLAGS@
unit_test_pacrunner_LDADD += @MOZJS_LIBS@ @PTHREAD_LIBS@
noinst_PROGRAMS += unit/test-mozjs
unit_test_mozjs_SOURCES = unit/test-mozjs.c src/pacrunner.h \
src/proxy.c src/manual.c src/download.c \
- src/js.c plugins/mozjs.c $(js_sources)
-
+ src/js.c plugins/mozjs.cc $(js_sources)
+unit_test_mozjs_CXXFLAGS = $(AM_CFLAGS) @MOZJS_CFLAGS@
unit_test_mozjs_LDADD = @MOZJS_LIBS@ @GLIB_LIBS@ @PTHREAD_LIBS@
endif
diff --git a/configure.ac b/configure.ac
index 888c873..bf76fbb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,8 +76,8 @@ AM_CONDITIONAL(DUKTAPE, test "${enable_duktape}" = "yes")
AC_ARG_ENABLE(mozjs, AC_HELP_STRING([--enable-mozjs],
[enable Mozilla Javascript plugin support]))
if (test "${enable_mozjs}" = "yes"); then
- PKG_CHECK_MODULES(MOZJS, mozjs185, dummy=yes,
- AC_MSG_ERROR(Mozilla Javascript >= 1.8 is required))
+ PKG_CHECK_MODULES(MOZJS, mozjs-38, dummy=yes,
+ AC_MSG_ERROR(Mozilla Javascript version 38 is required))
AC_SUBST(MOZJS_CFLAGS)
AC_SUBST(MOZJS_LIBS)
fi
diff --git a/plugins/mozjs.c b/plugins/mozjs.cc
index a923203..e10b297 100644
--- a/plugins/mozjs.c
+++ b/plugins/mozjs.cc
@@ -31,11 +31,15 @@
#include <netdb.h>
#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#include <jsapi.h>
#pragma GCC diagnostic error "-Wredundant-decls"
+#pragma GCC diagnostic error "-Winvalid-offsetof"
+extern "C" {
#include "pacrunner.h"
#include "js.h"
+}
static pthread_mutex_t mozjs_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -43,42 +47,42 @@ struct pacrunner_mozjs {
struct pacrunner_proxy *proxy;
JSContext *jsctx;
JSObject *jsobj;
+ JSAutoCompartment *jsac;
};
-static JSBool myipaddress(JSContext *jsctx, uintN argc, jsval *vp)
+static bool myipaddress(JSContext *jsctx, unsigned argc, jsval *vp)
{
- struct pacrunner_mozjs *ctx = JS_GetContextPrivate(jsctx);
+ struct pacrunner_mozjs *ctx = (pacrunner_mozjs *)JS_GetContextPrivate(jsctx);
char address[NI_MAXHOST];
DBG("");
- JS_SET_RVAL(jsctx, vp, JSVAL_NULL);
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+
+ args.rval().setNull();
if (!ctx)
- return JS_TRUE;
+ return true;
if (__pacrunner_js_getipaddr(ctx->proxy, address, sizeof(address)) < 0)
- return JS_TRUE;
+ return true;
DBG("address %s", address);
- JS_SET_RVAL(jsctx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(jsctx,
- address)));
+ args.rval().setString(JS_NewStringCopyZ(jsctx,address));
- return JS_TRUE;
+ return true;
}
-static JSBool dnsresolve(JSContext *jsctx, uintN argc, jsval *vp)
+static bool dnsresolve(JSContext *jsctx, unsigned argc, jsval *vp)
{
- struct pacrunner_mozjs *ctx = JS_GetContextPrivate(jsctx);
+ struct pacrunner_mozjs *ctx = (pacrunner_mozjs *)JS_GetContextPrivate(jsctx);
char address[NI_MAXHOST];
- jsval *argv = JS_ARGV(jsctx, vp);
- char *host = JS_EncodeString(jsctx, JS_ValueToString(jsctx, argv[0]));
+ JS::CallArgs args = JS::CallArgsFromVp(argc,vp);
+ char * host = JS_EncodeString(jsctx, args[0].toString());
DBG("host %s", host);
- JS_SET_RVAL(jsctx, vp, JSVAL_NULL);
-
if (!ctx)
goto out;
@@ -87,20 +91,16 @@ static JSBool dnsresolve(JSContext *jsctx, uintN argc, jsval *vp)
DBG("address %s", address);
- JS_SET_RVAL(jsctx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(jsctx, address)));
+ args.rval().setString(JS_NewStringCopyZ(jsctx,address));
out:
JS_free(jsctx, host);
- return JS_TRUE;
+ return true;
}
static JSClass jscls = {
"global", JSCLASS_GLOBAL_FLAGS,
- JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static JSRuntime *jsrun;
@@ -109,13 +109,12 @@ static int create_object(struct pacrunner_proxy *proxy)
{
struct pacrunner_mozjs *ctx;
const char *script;
- jsval rval;
script = pacrunner_proxy_get_script(proxy);
if (!script)
return 0;
- ctx = g_malloc0(sizeof(struct pacrunner_mozjs));
+ ctx = (pacrunner_mozjs *)g_malloc0(sizeof(struct pacrunner_mozjs));
ctx->proxy = proxy;
ctx->jsctx = JS_NewContext(jsrun, 8 * 1024);
@@ -126,41 +125,48 @@ static int create_object(struct pacrunner_proxy *proxy)
JS_SetContextPrivate(ctx->jsctx, ctx);
__pacrunner_proxy_set_jsctx(proxy, ctx);
-#if JS_VERSION >= 185
- ctx->jsobj = JS_NewCompartmentAndGlobalObject(ctx->jsctx, &jscls,
- NULL);
-#else
- ctx->jsobj = JS_NewObject(ctx->jsctx, &jscls, NULL, NULL);
-#endif
+ JS::CompartmentOptions compart_opts;
+ compart_opts.setVersion(JSVERSION_LATEST);
+ ctx->jsobj = JS_NewGlobalObject(ctx->jsctx, &jscls, nullptr,
+ JS::DontFireOnNewGlobalHook, compart_opts);
+ JS::RootedObject jsobj(ctx->jsctx,ctx->jsobj);
+
+ ctx->jsac = new JSAutoCompartment(ctx->jsctx, jsobj);
- if (!JS_InitStandardClasses(ctx->jsctx, ctx->jsobj))
+ if (!JS_InitStandardClasses(ctx->jsctx, jsobj))
pacrunner_error("Failed to init JS standard classes");
- JS_DefineFunction(ctx->jsctx, ctx->jsobj, "myIpAddress",
- myipaddress, 0, 0);
- JS_DefineFunction(ctx->jsctx, ctx->jsobj,
- "dnsResolve", dnsresolve, 1, 0);
+ JS_DefineFunction(ctx->jsctx, jsobj, "myIpAddress", myipaddress, 0, 0);
+ JS_DefineFunction(ctx->jsctx, jsobj, "dnsResolve", dnsresolve, 1, 0);
+
+ JS::RootedValue rval(ctx->jsctx);
+ JS::CompileOptions opts(ctx->jsctx);
+ opts.setIntroductionType("pacrunner")
+ .setUTF8(true)
+ .setCompileAndGo(true);
- JS_EvaluateScript(ctx->jsctx, ctx->jsobj, __pacrunner_js_routines,
- strlen(__pacrunner_js_routines), NULL, 0, &rval);
+ JS::Evaluate(ctx->jsctx, JS::HandleObject(jsobj), opts,
+ __pacrunner_js_routines, strlen(__pacrunner_js_routines)
+ , &rval);
- JS_EvaluateScript(ctx->jsctx, ctx->jsobj, script, strlen(script),
- "wpad.dat", 0, &rval);
+ JS::Evaluate(ctx->jsctx, jsobj, opts, script, strlen(script), &rval);
return 0;
}
static int mozjs_clear_proxy(struct pacrunner_proxy *proxy)
{
- struct pacrunner_mozjs *ctx = __pacrunner_proxy_get_jsctx(proxy);
+ struct pacrunner_mozjs *ctx = (pacrunner_mozjs *)__pacrunner_proxy_get_jsctx(proxy);
DBG("proxy %p ctx %p", proxy, ctx);
if (!ctx)
return -EINVAL;
+ delete ctx->jsac;
JS_DestroyContext(ctx->jsctx);
__pacrunner_proxy_set_jsctx(proxy, NULL);
+ g_free(ctx);
return 0;
}
@@ -168,7 +174,6 @@ static int mozjs_clear_proxy(struct pacrunner_proxy *proxy)
static int mozjs_set_proxy(struct pacrunner_proxy *proxy)
{
DBG("proxy %p", proxy);
-
if (!proxy)
return 0;
@@ -180,11 +185,9 @@ static int mozjs_set_proxy(struct pacrunner_proxy *proxy)
static char * mozjs_execute(struct pacrunner_proxy *proxy, const char *url,
const char *host)
{
- struct pacrunner_mozjs *ctx = __pacrunner_proxy_get_jsctx(proxy);
- JSBool result;
- jsval rval, args[2];
+ struct pacrunner_mozjs *ctx = (pacrunner_mozjs *)__pacrunner_proxy_get_jsctx(proxy);
+ bool result;
char *answer, *g_answer;
-
DBG("proxy %p ctx %p url %s host %s", proxy, ctx, url, host);
if (!ctx)
@@ -193,12 +196,16 @@ static char * mozjs_execute(struct pacrunner_proxy *proxy, const char *url,
pthread_mutex_lock(&mozjs_mutex);
JS_BeginRequest(ctx->jsctx);
+ JS::RootedValue rval(ctx->jsctx);
+ JS::AutoValueArray<2> args(ctx->jsctx);
+
+ args[0].setString(JS_NewStringCopyZ(ctx->jsctx, url));
+ args[1].setString(JS_NewStringCopyZ(ctx->jsctx, host));
- args[0] = STRING_TO_JSVAL(JS_NewStringCopyZ(ctx->jsctx, url));
- args[1] = STRING_TO_JSVAL(JS_NewStringCopyZ(ctx->jsctx, host));
- result = JS_CallFunctionName(ctx->jsctx, ctx->jsobj,
- "FindProxyForURL", 2, args, &rval);
+ JS::RootedObject jsobj(ctx->jsctx,ctx->jsobj);
+
+ result = JS_CallFunctionName(ctx->jsctx, jsobj, "FindProxyForURL", args , &rval);
JS_EndRequest(ctx->jsctx);
@@ -207,8 +214,7 @@ static char * mozjs_execute(struct pacrunner_proxy *proxy, const char *url,
pthread_mutex_unlock(&mozjs_mutex);
if (result) {
- answer = JS_EncodeString(ctx->jsctx,
- JS_ValueToString(ctx->jsctx, rval));
+ answer = JS_EncodeString(ctx->jsctx, rval.toString());
g_answer = g_strdup(answer);
JS_free(ctx->jsctx, answer);
return g_answer;
@@ -228,8 +234,8 @@ static struct pacrunner_js_driver mozjs_driver = {
static int mozjs_init(void)
{
DBG("");
-
- jsrun = JS_NewRuntime(8 * 1024 * 1024);
+ JS_Init();
+ jsrun = JS_NewRuntime(JS::DefaultHeapMaxBytes, 8 * 1024 * 1024 );
return pacrunner_js_driver_register(&mozjs_driver);
}
@@ -241,6 +247,7 @@ static void mozjs_exit(void)
pacrunner_js_driver_unregister(&mozjs_driver);
JS_DestroyRuntime(jsrun);
+ JS_ShutDown();
}
PACRUNNER_PLUGIN_DEFINE(mozjs, mozjs_init, mozjs_exit)