mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 487070 - a pref for enabling the lastest version of JS in Web Workers, r=baku, r=bent
This commit is contained in:
parent
df02daef15
commit
2d0f4a55fe
@ -132,6 +132,14 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
#define PREF_JIT_HARDENING "jit_hardening"
|
||||
#define PREF_GCZEAL "gcZeal"
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_PROMISE_ENABLED "dom.promise.enabled"
|
||||
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kNoIndex = uint32_t(-1);
|
||||
@ -175,13 +183,6 @@ const char* gStringChars[] = {
|
||||
static_assert(NS_ARRAY_LENGTH(gStringChars) == ID_COUNT,
|
||||
"gStringChars should have the right length.");
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_PROMISE_ENABLED "dom.promise.enabled"
|
||||
|
||||
class LiteralRebindingCString : public nsDependentCString
|
||||
{
|
||||
public:
|
||||
@ -875,9 +876,9 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||
|
||||
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
|
||||
|
||||
JS::ContextOptionsRef(workerCx) = aWorkerPrivate->IsChromeWorker()
|
||||
? settings.chrome.options
|
||||
: settings.content.options;
|
||||
JS::ContextOptionsRef(workerCx) =
|
||||
aWorkerPrivate->IsChromeWorker() ? settings.chrome.contextOptions
|
||||
: settings.content.contextOptions;
|
||||
|
||||
JS_SetJitHardening(aRuntime, settings.jitHardening);
|
||||
|
||||
@ -1593,9 +1594,10 @@ RuntimeService::Init()
|
||||
|
||||
// Initialize JSSettings.
|
||||
if (!sDefaultJSSettings.gcSettings[0].IsSet()) {
|
||||
sDefaultJSSettings.chrome.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.contextOptions = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.maxScriptRuntime = -1;
|
||||
sDefaultJSSettings.content.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST);
|
||||
sDefaultJSSettings.content.contextOptions = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC;
|
||||
#ifdef JS_GC_ZEAL
|
||||
sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ;
|
||||
@ -1670,21 +1672,25 @@ RuntimeService::Init()
|
||||
#endif
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr))) {
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr))) {
|
||||
NS_WARNING("Failed to register pref callbacks!");
|
||||
}
|
||||
|
||||
@ -1834,19 +1840,24 @@ RuntimeService::Cleanup()
|
||||
NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!");
|
||||
|
||||
if (mObserved) {
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
#ifdef JS_GC_ZEAL
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
@ -2224,8 +2235,8 @@ void
|
||||
RuntimeService::UpdateAllWorkerJSContextOptions()
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateJSContextOptions,
|
||||
sDefaultJSSettings.content.options,
|
||||
sDefaultJSSettings.chrome.options);
|
||||
sDefaultJSSettings.content.contextOptions,
|
||||
sDefaultJSSettings.chrome.contextOptions);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2333,3 +2344,13 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
||||
rts->UpdateAllWorkerPreference(key, sDefaultPreferences[key]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
bool useLatest = Preferences::GetBool(PREF_WORKERS_LATEST_JS_VERSION, false);
|
||||
JS::CompartmentOptions& options = sDefaultJSSettings.content.compartmentOptions;
|
||||
options.setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ public:
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
sDefaultJSSettings.content.options = aContentOptions;
|
||||
sDefaultJSSettings.chrome.options = aChromeOptions;
|
||||
sDefaultJSSettings.content.contextOptions = aContentOptions;
|
||||
sDefaultJSSettings.chrome.contextOptions = aChromeOptions;
|
||||
}
|
||||
|
||||
void
|
||||
@ -295,6 +295,9 @@ private:
|
||||
|
||||
static void
|
||||
WorkerPrefChanged(const char* aPrefName, void* aClosure);
|
||||
|
||||
static void
|
||||
JSVersionChanged(const char* aPrefName, void* aClosure);
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
@ -2816,16 +2816,17 @@ WorkerPrivateParent<Derived>::GetInnerWindowId()
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateJSContextOptions(JSContext* aCx,
|
||||
const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
WorkerPrivateParent<Derived>::UpdateJSContextOptions(
|
||||
JSContext* aCx,
|
||||
const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mJSSettings.content.options = aContentOptions;
|
||||
mJSSettings.chrome.options = aChromeOptions;
|
||||
mJSSettings.content.contextOptions = aContentOptions;
|
||||
mJSSettings.chrome.contextOptions = aChromeOptions;
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateJSContextOptionsRunnable> runnable =
|
||||
@ -5449,14 +5450,7 @@ WorkerPrivate::CreateGlobalScope(JSContext* aCx)
|
||||
globalScope = new DedicatedWorkerGlobalScope(this);
|
||||
}
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
if (IsChromeWorker()) {
|
||||
options.setVersion(JSVERSION_LATEST);
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx,
|
||||
globalScope->WrapGlobalObject(aCx, options,
|
||||
GetWorkerPrincipal()));
|
||||
JS::Rooted<JSObject*> global(aCx, globalScope->WrapGlobalObject(aCx));
|
||||
NS_ENSURE_TRUE(global, nullptr);
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
@ -377,7 +377,6 @@ private:
|
||||
ErrorResult& aRv);
|
||||
|
||||
public:
|
||||
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
@ -696,6 +695,14 @@ public:
|
||||
aSettings = mJSSettings;
|
||||
}
|
||||
|
||||
void
|
||||
CopyJSCompartmentOptions(JS::CompartmentOptions& aOptions)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
aOptions = IsChromeWorker() ? mJSSettings.chrome.compartmentOptions
|
||||
: mJSSettings.content.compartmentOptions;
|
||||
}
|
||||
|
||||
// The ability to be a chrome worker is orthogonal to the type of
|
||||
// worker [Dedicated|Shared].
|
||||
bool
|
||||
|
@ -6,11 +6,6 @@
|
||||
|
||||
#include "WorkerScope.h"
|
||||
|
||||
#include "Location.h"
|
||||
#include "Navigator.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
|
||||
@ -20,7 +15,12 @@
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#include "RuntimeService.h" // For WorkersDumpEnabled().
|
||||
#include "Location.h"
|
||||
#include "Navigator.h"
|
||||
#include "Principal.h"
|
||||
#include "RuntimeService.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#define UNWRAP_WORKER_OBJECT(Interface, obj, value) \
|
||||
UnwrapObject<prototypes::id::Interface##_workers, \
|
||||
@ -261,19 +261,20 @@ DedicatedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
|
||||
}
|
||||
|
||||
JSObject*
|
||||
DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||
JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal)
|
||||
DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
mWorkerPrivate->CopyJSCompartmentOptions(options);
|
||||
|
||||
// We're wrapping the global, so the scope is undefined.
|
||||
JS::Rooted<JSObject*> scope(aCx);
|
||||
|
||||
return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, scope, this,
|
||||
this, aOptions,
|
||||
aPrincipal);
|
||||
this, options,
|
||||
GetWorkerPrincipal());
|
||||
}
|
||||
|
||||
void
|
||||
@ -301,18 +302,20 @@ SharedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
|
||||
}
|
||||
|
||||
JSObject*
|
||||
SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||
JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal)
|
||||
SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
mWorkerPrivate->CopyJSCompartmentOptions(options);
|
||||
|
||||
// We're wrapping the global, so the scope is undefined.
|
||||
JS::Rooted<JSObject*> scope(aCx);
|
||||
|
||||
return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, scope, this, this,
|
||||
aOptions, aPrincipal);
|
||||
options,
|
||||
GetWorkerPrincipal());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -40,8 +40,7 @@ public:
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) = 0;
|
||||
WrapGlobalObject(JSContext* aCx) = 0;
|
||||
|
||||
virtual JSObject*
|
||||
GetGlobalJSObject(void) MOZ_OVERRIDE
|
||||
@ -115,8 +114,7 @@ public:
|
||||
Visible(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) MOZ_OVERRIDE;
|
||||
WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void
|
||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
@ -139,8 +137,7 @@ public:
|
||||
Visible(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) MOZ_OVERRIDE;
|
||||
WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetName(DOMString& aName) const {
|
||||
aName.AsAString() = mName;
|
||||
|
@ -95,11 +95,12 @@ struct JSSettings
|
||||
// Settings that change based on chrome/content context.
|
||||
struct JSContentChromeSettings
|
||||
{
|
||||
JS::ContextOptions options;
|
||||
JS::ContextOptions contextOptions;
|
||||
JS::CompartmentOptions compartmentOptions;
|
||||
int32_t maxScriptRuntime;
|
||||
|
||||
JSContentChromeSettings()
|
||||
: options(), maxScriptRuntime(0)
|
||||
: contextOptions(), compartmentOptions(), maxScriptRuntime(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
14
dom/workers/test/jsversion_worker.js
Normal file
14
dom/workers/test/jsversion_worker.js
Normal file
@ -0,0 +1,14 @@
|
||||
onmessage = function(evt) {
|
||||
if (evt.data != 0) {
|
||||
var worker = new Worker('jsversion_worker.js');
|
||||
worker.onmessage = function(evt) {
|
||||
postMessage(evt.data);
|
||||
}
|
||||
|
||||
worker.postMessage(evt.data - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
let foo = 'bar';
|
||||
postMessage(true);
|
||||
}
|
@ -56,6 +56,7 @@ support-files =
|
||||
xhr_implicit_cancel_worker.js
|
||||
xhr_worker.js
|
||||
url_exceptions_worker.js
|
||||
jsversion_worker.js
|
||||
|
||||
[test_404.html]
|
||||
[test_atob.html]
|
||||
@ -113,3 +114,4 @@ support-files =
|
||||
[test_xhr_system.html]
|
||||
[test_xhr_system.js]
|
||||
[test_url_exceptions.html]
|
||||
[test_jsversion.html]
|
||||
|
68
dom/workers/test/test_jsversion.html
Normal file
68
dom/workers/test/test_jsversion.html
Normal file
@ -0,0 +1,68 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for JSVersion in workers - Bug 487070</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" language="javascript">
|
||||
|
||||
var gExpectedError = false;
|
||||
|
||||
onerror = function(evt) {
|
||||
ok(gExpectedError, "Error expected!");
|
||||
runTest();
|
||||
}
|
||||
|
||||
function doMagic() {
|
||||
var worker = new Worker('jsversion_worker.js');
|
||||
worker.onmessage = function(evt) {
|
||||
ok(evt.data, 'All the tests passed');
|
||||
runTest();
|
||||
}
|
||||
worker.postMessage(1);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// No custom version
|
||||
function() {
|
||||
gExpectedError = true;
|
||||
SpecialPowers.pushPrefEnv({"set":[['dom.workers.latestJSVersion', false]]},
|
||||
function() { doMagic(true); });
|
||||
},
|
||||
|
||||
// Enable latest JS Version
|
||||
function() {
|
||||
gExpectedError = false;
|
||||
SpecialPowers.pushPrefEnv({"set":[['dom.workers.latestJSVersion', true]]},
|
||||
function() { doMagic(false); });
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user