diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp index 8e247a29c919..40980f5010f6 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -305,10 +305,10 @@ Version(JSContext *cx, JS::Value *vp) { JS::Value *argv = JS_ARGV(cx, vp); + JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx))); if (argc > 0 && JSVAL_IS_INT(argv[0])) - JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0]))))); - else - JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx))); + JS_SetVersionForCompartment(js::GetContextCompartment(cx), + JSVersion(JSVAL_TO_INT(argv[0]))); return JS_TRUE; } diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e381474a8bca..8571b44c2a39 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1362,6 +1362,12 @@ JS_SetVersion(JSContext *cx, JSVersion newVersion) return oldVersionNumber; } +JS_PUBLIC_API(void) +JS_SetVersionForCompartment(JSCompartment *compartment, JSVersion version) +{ + compartment->options().setVersion(version); +} + static struct v2smap { JSVersion version; const char *string; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 91f02cb56e9e..261591109ad3 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1898,6 +1898,15 @@ JS_GetVersion(JSContext *cx); extern JS_PUBLIC_API(JSVersion) JS_SetVersion(JSContext *cx, JSVersion version); +// Mutate the version on the compartment. This is generally discouraged, but +// necessary to support the version mutation in the js and xpc shell command +// set. +// +// It would be nice to put this in jsfriendapi, but the linkage requirements +// of the shells make that impossible. +JS_PUBLIC_API(void) +JS_SetVersionForCompartment(JSCompartment *compartment, JSVersion version); + extern JS_PUBLIC_API(const char *) JS_VersionToString(JSVersion version); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 8cfb382b2c26..924b4ff4dc56 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -625,9 +625,10 @@ static JSBool Version(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); + JSVersion origVersion = JS_GetVersion(cx); if (args.length() == 0 || JSVAL_IS_VOID(args[0])) { /* Get version. */ - args.rval().setInt32(JS_GetVersion(cx)); + args.rval().setInt32(origVersion); } else { /* Set version. */ int32_t v = -1; @@ -642,7 +643,8 @@ Version(JSContext *cx, unsigned argc, jsval *vp) JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "version"); return false; } - args.rval().setInt32(JS_SetVersion(cx, JSVersion(v))); + JS_SetVersionForCompartment(js::GetContextCompartment(cx), JSVersion(v)); + args.rval().setInt32(origVersion); } return true; } diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp index 5500d7a0db3c..ad39a77c170d 100644 --- a/js/xpconnect/shell/xpcshell.cpp +++ b/js/xpconnect/shell/xpcshell.cpp @@ -491,10 +491,11 @@ Load(JSContext *cx, unsigned argc, jsval *vp) static JSBool Version(JSContext *cx, unsigned argc, jsval *vp) { + JSVersion origVersion = JS_GetVersion(cx); + JS_SET_RVAL(cx, vp, INT_TO_JSVAL(origVersion)); if (argc > 0 && JSVAL_IS_INT(JS_ARGV(cx, vp)[0])) - JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(JS_ARGV(cx, vp)[0]))))); - else - JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx))); + JS_SetVersionForCompartment(js::GetContextCompartment(cx), + JSVersion(JSVAL_TO_INT(JS_ARGV(cx, vp)[0]))); return true; } @@ -1318,7 +1319,8 @@ ProcessArgs(JSContext *cx, JS::Handle obj, char **argv, int argc, XPC if (++i == argc) { return usage(); } - JS_SetVersion(cx, JSVersion(atoi(argv[i]))); + JS_SetVersionForCompartment(js::GetContextCompartment(cx), + JSVersion(atoi(argv[i]))); break; case 'W': reportWarnings = false;