This commit is contained in:
Ryan VanderMeulen 2014-02-19 15:37:55 -05:00
Родитель 09bca92c44 0cdf10592f
Коммит 9e4f57bee6
163 изменённых файлов: 2059 добавлений и 3336 удалений

Просмотреть файл

@ -137,13 +137,16 @@ var parseStack = iced(function parseStack(stack) {
if (line) {
let atIndex = line.indexOf("@");
let columnIndex = line.lastIndexOf(":");
let fileName = sourceURI(line.slice(atIndex + 1, columnIndex));
let lineNumber = parseInt(line.slice(columnIndex + 1));
let lineIndex = line.lastIndexOf(":", columnIndex - 1);
let fileName = sourceURI(line.slice(atIndex + 1, lineIndex));
let lineNumber = parseInt(line.slice(lineIndex + 1, columnIndex));
let columnNumber = parseInt(line.slice(columnIndex + 1));
let name = line.slice(0, atIndex).split("(").shift();
frames.unshift({
fileName: fileName,
name: name,
lineNumber: lineNumber
lineNumber: lineNumber,
columnNumber: columnNumber
});
}
return frames;
@ -155,7 +158,8 @@ var serializeStack = iced(function serializeStack(frames) {
return frames.reduce(function(stack, frame) {
return frame.name + "@" +
frame.fileName + ":" +
frame.lineNumber + "\n" +
frame.lineNumber + ":" +
frame.columnNumber + "\n" +
stack;
}, "");
})

Просмотреть файл

@ -684,7 +684,7 @@ var gPluginHandler = {
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_SHOWN")
.add(!this.options.primaryPlugin);
// Histograms always start at 0, even though our data starts at 1
let histogramCount = this.options.centerActions.size - 1;
let histogramCount = this.options.pluginData.size - 1;
if (histogramCount > 4) {
histogramCount = 4;
}
@ -844,12 +844,12 @@ var gPluginHandler = {
plugins = [aPlugin];
}
// If this is a new notification, create a centerActions map, otherwise append
let centerActions;
// If this is a new notification, create a pluginData map, otherwise append
let pluginData;
if (notification) {
centerActions = notification.options.centerActions;
pluginData = notification.options.pluginData;
} else {
centerActions = new Map();
pluginData = new Map();
}
let principal = aBrowser.contentDocument.nodePrincipal;
@ -861,7 +861,7 @@ var gPluginHandler = {
Cu.reportError("No permission string for active plugin.");
continue;
}
if (centerActions.has(pluginInfo.permissionString)) {
if (pluginData.has(pluginInfo.permissionString)) {
continue;
}
@ -888,8 +888,8 @@ var gPluginHandler = {
url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "clicktoplay";
}
pluginInfo.detailsLink = url;
centerActions.set(pluginInfo.permissionString, pluginInfo);
pluginData.set(pluginInfo.permissionString, pluginInfo);
}
let primaryPluginPermission = null;
@ -912,7 +912,7 @@ var gPluginHandler = {
dismissed: !aShowNow,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission,
centerActions: centerActions
pluginData: pluginData
};
PopupNotifications.show(aBrowser, "click-to-play-plugins",
"", "plugins-notification-icon",
@ -934,7 +934,7 @@ var gPluginHandler = {
// outdated plugins.
let haveInsecure = false;
let actions = new Map();
for (let action of notification.options.centerActions.values()) {
for (let action of notification.options.pluginData.values()) {
switch (action.fallbackType) {
// haveInsecure will trigger the red flashing icon and the infobar
// styling below

Просмотреть файл

@ -115,10 +115,10 @@ function test2b() {
// Simulate choosing "Allow now" for the test plugin
notification.reshow();
is(notification.options.centerActions.size, 2, "Test 2b, Should have two types of plugin in the notification");
is(notification.options.pluginData.size, 2, "Test 2b, Should have two types of plugin in the notification");
var centerAction = null;
for (var action of notification.options.centerActions.values()) {
for (var action of notification.options.pluginData.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;

Просмотреть файл

@ -76,7 +76,7 @@ function test1a() {
ok(notification, "Test 1a, Should have a click-to-play notification");
notification.reshow();
is(notification.options.centerActions.size, 2,
is(notification.options.pluginData.size, 2,
"Test 1a, Should have two types of plugin in the notification");
let pluginItem = null;

Просмотреть файл

@ -40,7 +40,7 @@ function pluginBindingAttached() {
ok(notification, "should have popup notification");
// We don't set up the action list until the notification is shown
notification.reshow();
is(notification.options.centerActions.size, 1, "should be 1 type of plugin in the popup notification");
is(notification.options.pluginData.size, 1, "should be 1 type of plugin in the popup notification");
XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addSecondPlugin();
} else if (gNumPluginBindingsAttached == 2) {
var doc = gTestBrowser.contentDocument;
@ -51,7 +51,7 @@ function pluginBindingAttached() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have popup notification");
notification.reshow();
is(notification.options.centerActions.size, 2, "should be 2 types of plugin in the popup notification");
is(notification.options.pluginData.size, 2, "should be 2 types of plugin in the popup notification");
finish();
} else {
ok(false, "if we've gotten here, something is quite wrong");

Просмотреть файл

@ -179,7 +179,7 @@ function test5() {
ok(notification.dismissed, "Test 5: The plugin notification should be dismissed by default");
notification.reshow();
is(notification.options.centerActions.size, 1, "Test 5: Only the blocked plugin should be present in the notification");
is(notification.options.pluginData.size, 1, "Test 5: Only the blocked plugin should be present in the notification");
ok(PopupNotifications.panel.firstChild._buttonContainer.hidden, "Part 5: The blocked plugins notification should not have any buttons visible.");
ok(!gTestBrowser.missingPlugins, "Test 5, Should not be a missing plugin list");
@ -604,10 +604,10 @@ function test21a() {
// we have to actually show the panel to get the bindings to instantiate
notification.reshow();
is(notification.options.centerActions.size, 2, "Test 21a, Should have two types of plugin in the notification");
is(notification.options.pluginData.size, 2, "Test 21a, Should have two types of plugin in the notification");
var centerAction = null;
for (var action of notification.options.centerActions.values()) {
for (var action of notification.options.pluginData.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;
@ -641,7 +641,7 @@ function test21c() {
ok(notification, "Test 21c, Should have a click-to-play notification");
notification.reshow();
ok(notification.options.centerActions.size == 2, "Test 21c, Should have one type of plugin in the notification");
ok(notification.options.pluginData.size == 2, "Test 21c, Should have one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
@ -662,7 +662,7 @@ function test21c() {
}
var centerAction = null;
for (var action of notification.options.centerActions.values()) {
for (var action of notification.options.pluginData.values()) {
if (action.pluginName == "Second Test") {
centerAction = action;
break;

Просмотреть файл

@ -68,7 +68,7 @@ function testActivateAddSameTypePart2() {
function testActivateAddSameTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
let centerAction = null;
for (let action of popupNotification.options.centerActions.values()) {
for (let action of popupNotification.options.pluginData.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;
@ -142,7 +142,7 @@ function testActivateAddDifferentTypePart2() {
function testActivateAddDifferentTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
is(popupNotification.options.centerActions.size, 1, "Should be one plugin action");
is(popupNotification.options.pluginData.size, 1, "Should be one plugin action");
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
ok(!plugin.activated, "testActivateAddDifferentTypePart3: plugin should not be activated");

Просмотреть файл

@ -85,7 +85,7 @@ let observer = {
reflow: function (start, end) {
// Gather information about the current code path.
let path = (new Error().stack).split("\n").slice(1).map(line => {
return line.replace(/:\d+$/, "");
return line.replace(/:\d+:\d+$/, "");
}).join("|");
let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");

Просмотреть файл

@ -75,7 +75,7 @@ let observer = {
// Gather information about the current code path.
let stack = new Error().stack;
let path = stack.split("\n").slice(1).map(line => {
return line.replace(/:\d+$/, "");
return line.replace(/:\d+:\d+$/, "");
}).join("|");
let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");

Просмотреть файл

@ -1564,7 +1564,7 @@
<constructor><![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let sortedActions = [];
for (let action of this.notification.options.centerActions.values()) {
for (let action of this.notification.options.pluginData.values()) {
sortedActions.push(action);
}
sortedActions.sort((a, b) => a.pluginName.localeCompare(b.pluginName));

Просмотреть файл

@ -4,10 +4,12 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['tests']
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']

Просмотреть файл

@ -9,9 +9,3 @@ pp_mochitest_browser_files := \
pp_mochitest_browser_files_PATH := $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
PP_TARGETS += pp_mochitest_browser_files
endif # ENABLE_TESTS
ifdef MOZ_SERVICES_HEALTHREPORT
MOCHITEST_BROWSER_FILES += \
browser_healthreport.js \
$(NULL)
endif

Просмотреть файл

@ -7,6 +7,8 @@ support-files =
[browser_bug410900.js]
[browser_bug731866.js]
[browser_connection.js]
[browser_healthreport.js]
skip-if = (!healthreport) || (os == 'linux' && debug)
[browser_privacypane_1.js]
[browser_privacypane_3.js]
[browser_privacypane_5.js]

Просмотреть файл

@ -3,18 +3,3 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include('../src/objs.mozbuild')
UNIFIED_SOURCES += modules_profiledirservice_src_csrcs
LIBRARY_NAME = 'profdirserviceprovidersa_s'
FORCE_STATIC_LIB = True
DEFINES['XPCOM_GLUE'] = 1
LOCAL_INCLUDES += [
'../src',
]

Просмотреть файл

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
PARALLEL_DIRS += ['in-content']
TEST_DIRS += ['tests']
BROWSER_CHROME_MANIFESTS += [
'in-content/tests/browser.ini',
@ -17,4 +18,4 @@ for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn']
JAR_MANIFESTS += ['jar.mn']

Просмотреть файл

@ -9,7 +9,3 @@ pp_mochitest_browser_files := \
pp_mochitest_browser_files_PATH := $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
PP_TARGETS += pp_mochitest_browser_files
endif # ENABLE_TESTS
ifdef MOZ_SERVICES_HEALTHREPORT
MOCHITEST_BROWSER_FILES += browser_healthreport.js
endif

Просмотреть файл

@ -7,6 +7,8 @@ support-files =
[browser_bug410900.js]
[browser_bug705422.js]
[browser_chunk_permissions.js]
[browser_healthreport.js]
skip-if = (!healthreport) || (os == 'linux' && debug)
[browser_permissions.js]
[browser_privacypane_1.js]
[browser_privacypane_3.js]

Просмотреть файл

@ -0,0 +1,5 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -41,7 +41,7 @@ function runTests()
method: "display",
code: error1,
result: error1 + openComment +
"Exception: Ouch!\n@" + scratchpad.uniqueName + ":1" + closeComment,
"Exception: Ouch!\n@" + scratchpad.uniqueName + ":1:1" + closeComment,
label: "error display output"
},
{
@ -78,7 +78,7 @@ function runTests()
method: "run",
code: error1,
result: error1 + openComment +
"Exception: Ouch!\n@" + scratchpad.uniqueName + ":1" + closeComment,
"Exception: Ouch!\n@" + scratchpad.uniqueName + ":1:1" + closeComment,
label: "error run output"
},
{

Просмотреть файл

@ -37,7 +37,7 @@ function runTests()
method: "display",
code: error,
result: error + openComment + "Exception: Ouch!\n@" +
scratchpad.uniqueName + ":1" + closeComment,
scratchpad.uniqueName + ":1:1" + closeComment,
label: "error display output",
},
{
@ -57,7 +57,7 @@ function runTests()
method: "run",
code: error,
result: error + openComment + "Exception: Ouch!\n@" +
scratchpad.uniqueName + ":1" + closeComment,
scratchpad.uniqueName + ":1:1" + closeComment,
label: "error run output",
},
{

Просмотреть файл

@ -3224,16 +3224,20 @@ WebGLContext::CompileShader(WebGLShader *shader)
#else
if (!ShCompile(compiler, &s, 1, compileOptions)) {
#endif
size_t len = 0;
ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &len);
size_t lenWithNull = 0;
ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &lenWithNull);
if (len) {
nsAutoCString info;
info.SetLength(len);
ShGetInfoLog(compiler, info.BeginWriting());
shader->SetTranslationFailure(info);
} else {
if (!lenWithNull) {
// Error in ShGetInfo.
shader->SetTranslationFailure(NS_LITERAL_CSTRING("Internal error: failed to get shader info log"));
} else {
size_t len = lenWithNull - 1;
nsAutoCString info;
info.SetLength(len); // Allocates len+1, for the null-term.
ShGetInfoLog(compiler, info.BeginWriting());
shader->SetTranslationFailure(info);
}
ShDestruct(compiler);
shader->SetCompileStatus(false);

Просмотреть файл

@ -83,18 +83,15 @@ public:
JS::Handle<JS::Value> aContextOptions,
ErrorResult& aRv);
void ToDataURL(JSContext* aCx, const nsAString& aType,
const Optional<JS::Handle<JS::Value> >& aParams,
JS::Handle<JS::Value> aParams,
nsAString& aDataURL, ErrorResult& aRv)
{
JS::Handle<JS::Value> params = aParams.WasPassed()
? aParams.Value()
: JS::UndefinedHandleValue;
aRv = ToDataURL(aType, params, aCx, aDataURL);
aRv = ToDataURL(aType, aParams, aCx, aDataURL);
}
void ToBlob(JSContext* aCx,
FileCallback& aCallback,
const nsAString& aType,
const Optional<JS::Handle<JS::Value> >& aParams,
JS::Handle<JS::Value> aParams,
ErrorResult& aRv);
bool MozOpaque() const

Просмотреть файл

@ -487,7 +487,7 @@ void
HTMLCanvasElement::ToBlob(JSContext* aCx,
FileCallback& aCallback,
const nsAString& aType,
const Optional<JS::Handle<JS::Value> >& aParams,
JS::Handle<JS::Value> aParams,
ErrorResult& aRv)
{
// do a trust check if this is a write-only canvas
@ -502,13 +502,9 @@ HTMLCanvasElement::ToBlob(JSContext* aCx,
return;
}
JS::Value encoderOptions = aParams.WasPassed()
? aParams.Value()
: JS::UndefinedValue();
nsAutoString params;
bool usingCustomParseOptions;
aRv = ParseParams(aCx, type, encoderOptions, params, &usingCustomParseOptions);
aRv = ParseParams(aCx, type, aParams, params, &usingCustomParseOptions);
if (aRv.Failed()) {
return;
}

Просмотреть файл

@ -226,6 +226,15 @@ void GStreamerReader::PlayBinSourceSetup(GstAppSrc* aSource)
gst_app_src_set_callbacks(mSource, &mSrcCallbacks, (gpointer) this, nullptr);
MediaResource* resource = mDecoder->GetResource();
/* do a short read to trigger a network request so that GetLength() below
* returns something meaningful and not -1
*/
char buf[512];
unsigned int size = 0;
resource->Read(buf, sizeof(buf), &size);
resource->Seek(SEEK_SET, 0);
/* now we should have a length */
int64_t resourceLength = resource->GetLength();
gst_app_src_set_size(mSource, resourceLength);
if (resource->IsDataCachedToEndOfResource(0) ||
@ -372,27 +381,6 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,
/* we couldn't get this to play */
return ret;
/* FIXME: workaround for a bug in matroskademux. This seek makes matroskademux
* parse the index */
LOG(PR_LOG_DEBUG, ("doing matroskademux seek hack"));
if (gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH, 0)) {
/* after a seek we need to wait again for ASYNC_DONE */
message = gst_bus_timed_pop_filtered(mBus, 5 * GST_SECOND,
(GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));
if (message == NULL || GST_MESSAGE_TYPE(message) != GST_MESSAGE_ASYNC_DONE) {
LOG(PR_LOG_DEBUG, ("matroskademux seek hack failed: %p", message));
gst_element_set_state(mPlayBin, GST_STATE_NULL);
if (message) {
gst_message_unref(message);
}
return NS_ERROR_FAILURE;
}
LOG(PR_LOG_DEBUG, ("matroskademux seek hack completed"));
} else {
LOG(PR_LOG_DEBUG, ("matroskademux seek hack failed (non fatal)"));
}
bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
if (isMP3) {
ParseMP3Headers();

Просмотреть файл

@ -8807,18 +8807,14 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
JS::Value
nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
const Optional<JS::Handle<JS::Value> >& aArgument,
JS::Handle<JS::Value> aArgument,
const nsAString& aOptions,
ErrorResult& aError)
{
nsCOMPtr<nsIVariant> args;
if (aArgument.WasPassed()) {
aError = nsContentUtils::XPConnect()->JSToVariant(aCx,
aArgument.Value(),
getter_AddRefs(args));
} else {
args = CreateVoidVariant();
}
aError = nsContentUtils::XPConnect()->JSToVariant(aCx,
aArgument,
getter_AddRefs(args));
nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError);
if (aError.Failed()) {
@ -11430,7 +11426,9 @@ nsGlobalWindow::SetTimeout(JSContext* aCx, Function& aFunction,
int32_t
nsGlobalWindow::SetTimeout(JSContext* aCx, const nsAString& aHandler,
int32_t aTimeout, ErrorResult& aError)
int32_t aTimeout,
const Sequence<JS::Value>& /* unused */,
ErrorResult& aError)
{
return SetTimeoutOrInterval(aCx, aHandler, aTimeout, false, aError);
}
@ -11464,6 +11462,7 @@ nsGlobalWindow::SetInterval(JSContext* aCx, Function& aFunction,
int32_t
nsGlobalWindow::SetInterval(JSContext* aCx, const nsAString& aHandler,
const Optional<int32_t>& aTimeout,
const Sequence<JS::Value>& /* unused */,
ErrorResult& aError)
{
int32_t timeout;

Просмотреть файл

@ -824,7 +824,7 @@ public:
void Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsAString& aReturn, mozilla::ErrorResult& aError);
void Print(mozilla::ErrorResult& aError);
JS::Value ShowModalDialog(JSContext* aCx, const nsAString& aUrl, const mozilla::dom::Optional<JS::Handle<JS::Value> >& aArgument, const nsAString& aOptions, mozilla::ErrorResult& aError);
JS::Value ShowModalDialog(JSContext* aCx, const nsAString& aUrl, JS::Handle<JS::Value> aArgument, const nsAString& aOptions, mozilla::ErrorResult& aError);
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const nsAString& aTargetOrigin,
const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
@ -834,7 +834,9 @@ public:
const mozilla::dom::Sequence<JS::Value>& aArguments,
mozilla::ErrorResult& aError);
int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
int32_t aTimeout, mozilla::ErrorResult& aError);
int32_t aTimeout,
const mozilla::dom::Sequence<JS::Value>& /* unused */,
mozilla::ErrorResult& aError);
void ClearTimeout(int32_t aHandle, mozilla::ErrorResult& aError);
int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
const mozilla::dom::Optional<int32_t>& aTimeout,
@ -842,6 +844,7 @@ public:
mozilla::ErrorResult& aError);
int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
const mozilla::dom::Optional<int32_t>& aTimeout,
const mozilla::dom::Sequence<JS::Value>& /* unused */,
mozilla::ErrorResult& aError);
void ClearInterval(int32_t aHandle, mozilla::ErrorResult& aError);
void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData,

Просмотреть файл

@ -36,6 +36,7 @@ support-files =
[test_openDialogChromeOnly.html]
[test_postMessage_solidus.html]
[test_screen_orientation.html]
[test_settimeout_extra_arguments.html]
[test_settimeout_inner.html]
[test_setting_opener.html]
[test_url.html]

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for setTimeout with a string argument and more than 2 arguments</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
t1 = async_test("setTimeout with more than 2 arguments, first argument a string, should work");
t2 = async_test("setInterval with more than 2 arguments, first argument a string, should work");
setTimeout("t1.done()", 0, {});
var interval = setInterval("clearInterval(interval); t2.done()", 0, {});
</script>

Просмотреть файл

@ -241,32 +241,14 @@ public:
}
};
// A specialization of Optional for JS::Value to make sure that when someone
// calls Construct() on it we will pre-initialized the JS::Value to
// JS::UndefinedValue() so it can be traced safely.
// A specialization of Optional for JS::Value to make sure no one ever uses it.
template<>
class Optional<JS::Value> : public Optional_base<JS::Value, JS::Value>
class Optional<JS::Value>
{
public:
Optional() :
Optional_base<JS::Value, JS::Value>()
{}
private:
Optional() MOZ_DELETE;
explicit Optional(JS::Value aValue) :
Optional_base<JS::Value, JS::Value>(aValue)
{}
// Don't allow us to have an uninitialized JS::Value
void Construct()
{
Optional_base<JS::Value, JS::Value>::Construct(JS::UndefinedValue());
}
template <class T1>
void Construct(const T1& t1)
{
Optional_base<JS::Value, JS::Value>::Construct(t1);
}
explicit Optional(JS::Value aValue) MOZ_DELETE;
};
// A specialization of Optional for NonNull that lets us get a T& from Value()

Просмотреть файл

@ -1523,7 +1523,6 @@ DOMInterfaces = {
# from ChromeWindow.
'hasXPConnectImpls': True,
'register': False,
'implicitJSContext': [ 'setInterval', 'setTimeout' ],
'binaryNames': {
'postMessage': 'postMessageMoz',
},

Просмотреть файл

@ -11,7 +11,7 @@ import string
import math
import itertools
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
AUTOGENERATED_WARNING_COMMENT = \
@ -3844,21 +3844,22 @@ for (uint32_t i = 0; i < length; ++i) {
declType = "JS::Value"
else:
assert not isMember
if isOptional:
# We have a specialization of Optional that will use a
# Rooted for the storage here.
declType = "JS::Handle<JS::Value>"
else:
declType = "JS::Rooted<JS::Value>"
declType = "JS::Rooted<JS::Value>"
declArgs = "cx"
assert not isOptional
templateBody = "${declName} = ${val};"
nullHandling = "${declName} = JS::NullValue()"
templateBody = handleDefaultNull(templateBody, nullHandling)
# We may not have a default value if we're being converted for
# a setter, say.
if defaultValue:
if isinstance(defaultValue, IDLNullValue):
defaultHandling = "${declName} = JS::NullValue()"
else:
assert isinstance(defaultValue, IDLUndefinedValue)
defaultHandling = "${declName} = JS::UndefinedValue()"
templateBody = handleDefault(templateBody, defaultHandling)
return JSToNativeConversionInfo(templateBody,
declType=CGGeneric(declType),
dealWithOptional=isOptional,
declArgs=declArgs)
if type.isObject():
@ -4142,6 +4143,8 @@ def instantiateJSToNativeConversion(info, replacements, checkForValue=False):
def convertConstIDLValueToJSVal(value):
if isinstance(value, IDLNullValue):
return "JS::NullValue()"
if isinstance(value, IDLUndefinedValue):
return "JS::UndefinedValue()"
tag = value.type.tag()
if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16,
IDLType.Tags.uint16, IDLType.Tags.int32]:

Просмотреть файл

@ -2531,7 +2531,24 @@ class IDLNullValue(IDLObject):
def _getDependentObjects(self):
return set()
class IDLUndefinedValue(IDLObject):
def __init__(self, location):
IDLObject.__init__(self, location)
self.type = None
self.value = None
def coerceToType(self, type, location):
if not type.isAny():
raise WebIDLError("Cannot coerce undefined value to type %s." % type,
[location])
undefinedValue = IDLUndefinedValue(self.location)
undefinedValue.type = type
return undefinedValue
def _getDependentObjects(self):
return set()
class IDLInterfaceMember(IDLObjectWithIdentifier):
@ -2909,6 +2926,22 @@ class IDLArgument(IDLObjectWithIdentifier):
# Default optional dictionaries to null, for simplicity,
# so the codegen doesn't have to special-case this.
self.defaultValue = IDLNullValue(self.location)
elif self.type.isAny():
assert (self.defaultValue is None or
isinstance(self.defaultValue, IDLNullValue))
if (self.optional and not self.variadic and
not self.dictionaryMember and not self.defaultValue):
raise WebIDLError("Arguments of type 'any' are always optional "
"and shouldn't have the 'optional' keyword "
"unless they're being given a default value "
"of 'null'",
[self.location])
# 'any' values are always optional.
self.optional = True
if not self.defaultValue and not self.variadic:
# Set the default value to undefined, for simplicity, so the
# codegen doesn't have to special-case this.
self.defaultValue = IDLUndefinedValue(self.location)
# Now do the coercing thing; this needs to happen after the
# above creation of a default value.
@ -4288,6 +4321,10 @@ class Parser(Tokenizer):
raise WebIDLError("Mandatory arguments can't have a default value.",
[self.getLocation(p, 6)])
# We can't test t.isAny() here and force optional to true, since at this
# point t is not a fully resolved type yet (e.g. it might be a typedef).
# We'll handle the 'any' case in IDLArgument.complete.
if variadic:
if optional:
raise WebIDLError("Variadic arguments should not be marked optional.",

Просмотреть файл

@ -112,7 +112,7 @@ def WebIDLTest(parser, harness):
checkMethod(methods[11], "::TestMethods::setAny",
"setAny",
[("Void",
[("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
[("::TestMethods::setAny::arg1", "arg1", "Any", True, False)])])
checkMethod(methods[12], "::TestMethods::doFloats",
"doFloats",
[("Float",

Просмотреть файл

@ -146,11 +146,11 @@ public:
already_AddRefed<TestInterface> Test2(const GlobalObject&,
JSContext*,
const DictForConstructor&,
JS::Value,
JS::Handle<JS::Value>,
JS::Handle<JSObject*>,
JS::Handle<JSObject*>,
const Sequence<Dict>&,
const Optional<JS::Handle<JS::Value> >&,
JS::Handle<JS::Value>,
const Optional<JS::Handle<JSObject*> >&,
const Optional<JS::Handle<JSObject*> >&,
ErrorResult&);
@ -466,7 +466,6 @@ public:
// Any types
void PassAny(JSContext*, JS::Handle<JS::Value>);
void PassVariadicAny(JSContext*, const Sequence<JS::Value>&);
void PassOptionalAny(JSContext*, const Optional<JS::Handle<JS::Value> >&);
void PassAnyDefaultNull(JSContext*, JS::Handle<JS::Value>);
void PassSequenceOfAny(JSContext*, const Sequence<JS::Value>&);
void PassNullableSequenceOfAny(JSContext*, const Nullable<Sequence<JS::Value> >&);

Просмотреть файл

@ -110,7 +110,8 @@ interface OnlyForUseInConstructor {
NamedConstructor=Test,
NamedConstructor=Test(DOMString str),
NamedConstructor=Test2(DictForConstructor dict, any any1, object obj1,
object? obj2, sequence<Dict> seq, optional any any2,
object? obj2, sequence<Dict> seq,
optional any any2 = null,
optional object obj3, optional object? obj4)
]
interface TestInterface {
@ -428,7 +429,6 @@ interface TestInterface {
// Any types
void passAny(any arg);
void passVariadicAny(any... arg);
void passOptionalAny(optional any arg);
void passAnyDefaultNull(optional any arg = null);
void passSequenceOfAny(sequence<any> arg);
void passNullableSequenceOfAny(sequence<any>? arg);

Просмотреть файл

@ -12,7 +12,8 @@
NamedConstructor=Example,
NamedConstructor=Example(DOMString str),
NamedConstructor=Example2(DictForConstructor dict, any any1, object obj1,
object? obj2, sequence<Dict> seq, optional any any2,
object? obj2, sequence<Dict> seq,
optional any any2 = null,
optional object obj3, optional object? obj4)
]
interface TestExampleInterface {
@ -321,7 +322,6 @@ interface TestExampleInterface {
// Any types
void passAny(any arg);
void passVariadicAny(any... arg);
void passOptionalAny(optional any arg);
void passAnyDefaultNull(optional any arg = null);
void passSequenceOfAny(sequence<any> arg);
void passNullableSequenceOfAny(sequence<any>? arg);

Просмотреть файл

@ -23,7 +23,7 @@ enum MyTestEnum {
TestInterface? iface, long arg1,
DictForConstructor dict, any any1,
object obj1,
object? obj2, sequence<Dict> seq, optional any any2,
object? obj2, sequence<Dict> seq, optional any any2 = null,
optional object obj3,
optional object? obj4),
JSImplementation="@mozilla.org/test-js-impl-interface;1"]
@ -344,7 +344,6 @@ interface TestJSImplInterface {
// Any types
void passAny(any arg);
void passVariadicAny(any... arg);
void passOptionalAny(optional any arg);
void passAnyDefaultNull(optional any arg = null);
void passSequenceOfAny(sequence<any> arg);
void passNullableSequenceOfAny(sequence<any>? arg);

Просмотреть файл

@ -130,9 +130,7 @@ nsDOMMessageEvent::Constructor(const mozilla::dom::GlobalObject& aGlobal,
bool trusted = event->Init(t);
event->SetTrusted(trusted);
if (aParam.mData.WasPassed()) {
event->mData = aParam.mData.Value();
}
event->mData = aParam.mData;
mozilla::HoldJSObjects(event.get());

Просмотреть файл

@ -79,7 +79,7 @@ dictionary EventInit {
interface CustomEvent : Event {
readonly attribute any detail;
void initCustomEvent(DOMString type, boolean bubbles, boolean cancelable, any details);
void initCustomEvent(DOMString type, boolean bubbles, boolean cancelable, optional any details);
};
dictionary CustomEventInit : EventInit {

Просмотреть файл

@ -697,16 +697,14 @@ IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
void
IDBCursor::Continue(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aKey,
JS::Handle<JS::Value> aKey,
ErrorResult &aRv)
{
MOZ_ASSERT(NS_IsMainThread());
Key key;
if (aKey.WasPassed()) {
aRv = key.SetFromJSVal(aCx, aKey.Value());
ENSURE_SUCCESS_VOID(aRv);
}
aRv = key.SetFromJSVal(aCx, aKey);
ENSURE_SUCCESS_VOID(aRv);
if (!key.IsUnset()) {
switch (mDirection) {
@ -809,9 +807,7 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
return nullptr;
}
JS::Rooted<JS::Value> value(aCx, aValue);
Optional<JS::Handle<JS::Value> > keyValue(aCx);
request = mObjectStore->Put(aCx, value, keyValue, aRv);
request = mObjectStore->Put(aCx, aValue, JS::UndefinedHandleValue, aRv);
if (aRv.Failed()) {
return nullptr;
}
@ -821,9 +817,7 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
aRv = objectKey.ToJSVal(aCx, &keyVal);
ENSURE_SUCCESS(aRv, nullptr);
JS::Rooted<JS::Value> value(aCx, aValue);
Optional<JS::Handle<JS::Value> > keyValue(aCx, keyVal);
request = mObjectStore->Put(aCx, value, keyValue, aRv);
request = mObjectStore->Put(aCx, aValue, keyVal, aRv);
if (aRv.Failed()) {
return nullptr;
}

Просмотреть файл

@ -197,8 +197,7 @@ public:
Advance(uint32_t aCount, ErrorResult& aRv);
void
Continue(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
ErrorResult& aRv);
Continue(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
already_AddRefed<IDBRequest>
Delete(JSContext* aCx, ErrorResult& aRv);

Просмотреть файл

@ -896,7 +896,7 @@ IDBIndex::GetKey(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv)
}
already_AddRefed<IDBRequest>
IDBIndex::GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
IDBIndex::GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -908,10 +908,8 @@ IDBIndex::GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
uint32_t limit = UINT32_MAX;
if (aLimit.WasPassed() && aLimit.Value() > 0) {
@ -923,7 +921,7 @@ IDBIndex::GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
already_AddRefed<IDBRequest>
IDBIndex::GetAllKeys(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aKey,
JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -935,10 +933,8 @@ IDBIndex::GetAllKeys(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
uint32_t limit = UINT32_MAX;
if (aLimit.WasPassed() && aLimit.Value() > 0) {
@ -950,7 +946,7 @@ IDBIndex::GetAllKeys(JSContext* aCx,
already_AddRefed<IDBRequest>
IDBIndex::OpenCursor(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aRange,
JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -962,10 +958,8 @@ IDBIndex::OpenCursor(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aRange.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aRange.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);
@ -991,7 +985,7 @@ IDBIndex::OpenCursor(JSContext* aCx,
already_AddRefed<IDBRequest>
IDBIndex::OpenKeyCursor(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aRange,
JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -1003,10 +997,8 @@ IDBIndex::OpenKeyCursor(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aRange.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aRange.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);
@ -1014,7 +1006,7 @@ IDBIndex::OpenKeyCursor(JSContext* aCx,
}
already_AddRefed<IDBRequest>
IDBIndex::Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
IDBIndex::Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
ErrorResult& aRv)
{
IDBTransaction* transaction = mObjectStore->Transaction();
@ -1024,10 +1016,8 @@ IDBIndex::Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
return CountInternal(keyRange, aRv);
}

Просмотреть файл

@ -194,11 +194,11 @@ public:
}
already_AddRefed<IDBRequest>
OpenCursor(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aRange,
OpenCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv);
already_AddRefed<IDBRequest>
OpenKeyCursor(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aRange,
OpenKeyCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv);
already_AddRefed<IDBRequest>
@ -208,7 +208,7 @@ public:
GetKey(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
already_AddRefed<IDBRequest>
Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
ErrorResult& aRv);
void
@ -219,11 +219,11 @@ public:
}
already_AddRefed<IDBRequest>
GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
already_AddRefed<IDBRequest>
GetAllKeys(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
private:

Просмотреть файл

@ -1907,7 +1907,7 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
already_AddRefed<IDBRequest>
IDBObjectStore::AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
const Optional<JS::Handle<JS::Value> >& aKey,
JS::Handle<JS::Value> aKey,
bool aOverwrite, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -1922,15 +1922,12 @@ IDBObjectStore::AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
return nullptr;
}
JS::Rooted<JS::Value> keyval(aCx, aKey.WasPassed() ? aKey.Value()
: JSVAL_VOID);
StructuredCloneWriteInfo cloneWriteInfo;
Key key;
nsTArray<IndexUpdateInfo> updateInfo;
JS::Rooted<JS::Value> value(aCx, aValue);
aRv = GetAddInfo(aCx, value, keyval, cloneWriteInfo, key, updateInfo);
aRv = GetAddInfo(aCx, value, aKey, cloneWriteInfo, key, updateInfo);
if (aRv.Failed()) {
return nullptr;
}
@ -2700,7 +2697,7 @@ IDBObjectStore::Get(JSContext* aCx, JS::Handle<JS::Value> aKey,
already_AddRefed<IDBRequest>
IDBObjectStore::GetAll(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aKey,
JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -2711,10 +2708,8 @@ IDBObjectStore::GetAll(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
uint32_t limit = UINT32_MAX;
if (aLimit.WasPassed() && aLimit.Value() != 0) {
@ -2755,7 +2750,7 @@ IDBObjectStore::Delete(JSContext* aCx, JS::Handle<JS::Value> aKey,
already_AddRefed<IDBRequest>
IDBObjectStore::OpenCursor(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aRange,
JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -2766,10 +2761,8 @@ IDBObjectStore::OpenCursor(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aRange.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aRange.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);
size_t argDirection = static_cast<size_t>(direction);
@ -2941,7 +2934,7 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
already_AddRefed<IDBRequest>
IDBObjectStore::Count(JSContext* aCx,
const Optional<JS::Handle<JS::Value> >& aKey,
JS::Handle<JS::Value> aKey,
ErrorResult& aRv)
{
if (!mTransaction->IsOpen()) {
@ -2950,17 +2943,15 @@ IDBObjectStore::Count(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
return CountInternal(keyRange, aRv);
}
already_AddRefed<IDBRequest>
IDBObjectStore::GetAllKeys(JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aKey,
JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
@ -2971,10 +2962,8 @@ IDBObjectStore::GetAllKeys(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aKey.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
uint32_t limit = UINT32_MAX;
if (aLimit.WasPassed() && aLimit.Value() != 0) {
@ -2986,7 +2975,7 @@ IDBObjectStore::GetAllKeys(JSContext* aCx,
already_AddRefed<IDBRequest>
IDBObjectStore::OpenKeyCursor(JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aRange,
JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
@ -2997,10 +2986,8 @@ IDBObjectStore::OpenKeyCursor(JSContext* aCx,
}
nsRefPtr<IDBKeyRange> keyRange;
if (aRange.WasPassed()) {
aRv = IDBKeyRange::FromJSVal(aCx, aRange.Value(), getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
}
aRv = IDBKeyRange::FromJSVal(aCx, aRange, getter_AddRefs(keyRange));
ENSURE_SUCCESS(aRv, nullptr);
IDBCursor::Direction direction = IDBCursor::ConvertDirection(aDirection);

Просмотреть файл

@ -304,7 +304,7 @@ public:
already_AddRefed<IDBRequest>
Put(JSContext* aCx, JS::Handle<JS::Value> aValue,
const Optional<JS::Handle<JS::Value> >& aKey, ErrorResult& aRv)
JS::Handle<JS::Value> aKey, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return AddOrPut(aCx, aValue, aKey, true, aRv);
@ -312,7 +312,7 @@ public:
already_AddRefed<IDBRequest>
Add(JSContext* aCx, JS::Handle<JS::Value> aValue,
const Optional<JS::Handle<JS::Value> >& aKey, ErrorResult& aRv)
JS::Handle<JS::Value> aKey, ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return AddOrPut(aCx, aValue, aKey, false, aRv);
@ -328,7 +328,7 @@ public:
Clear(ErrorResult& aRv);
already_AddRefed<IDBRequest>
OpenCursor(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aRange,
OpenCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv);
already_AddRefed<IDBIndex>
@ -347,19 +347,19 @@ public:
DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
already_AddRefed<IDBRequest>
Count(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
ErrorResult& aRv);
already_AddRefed<IDBRequest>
GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
already_AddRefed<IDBRequest>
GetAllKeys(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aKey,
GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey,
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
already_AddRefed<IDBRequest>
OpenKeyCursor(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aRange,
OpenKeyCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
IDBCursorDirection aDirection, ErrorResult& aRv);
protected:
@ -375,7 +375,7 @@ protected:
already_AddRefed<IDBRequest>
AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
const Optional<JS::Handle<JS::Value> >& aKey, bool aOverwrite,
JS::Handle<JS::Value> aKey, bool aOverwrite,
ErrorResult& aRv);
already_AddRefed<IDBIndex>

Просмотреть файл

@ -172,7 +172,7 @@ TabContext::SetTabContextForAppFrame(mozIApplication* aOwnApp,
uint32_t containingAppId = NO_APP_ID;
if (aAppFrameOwnerApp) {
nsresult rv = aOwnApp->GetLocalId(&containingAppId);
nsresult rv = aAppFrameOwnerApp->GetLocalId(&containingAppId);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
}

Просмотреть файл

@ -500,13 +500,11 @@ Promise::Constructor(const GlobalObject& aGlobal,
/* static */ already_AddRefed<Promise>
Promise::Resolve(const GlobalObject& aGlobal, JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aValue, ErrorResult& aRv)
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
// If a Promise was passed, just return it.
JS::Rooted<JS::Value> value(aCx, aValue.WasPassed() ? aValue.Value() :
JS::UndefinedValue());
if (value.isObject()) {
JS::Rooted<JSObject*> valueObj(aCx, &value.toObject());
if (aValue.isObject()) {
JS::Rooted<JSObject*> valueObj(aCx, &aValue.toObject());
Promise* nextPromise;
nsresult rv = UNWRAP_OBJECT(Promise, valueObj, nextPromise);
@ -525,7 +523,7 @@ Promise::Resolve(const GlobalObject& aGlobal, JSContext* aCx,
}
}
return Resolve(window, aCx, value, aRv);
return Resolve(window, aCx, aValue, aRv);
}
/* static */ already_AddRefed<Promise>
@ -541,7 +539,7 @@ Promise::Resolve(nsPIDOMWindow* aWindow, JSContext* aCx,
/* static */ already_AddRefed<Promise>
Promise::Reject(const GlobalObject& aGlobal, JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aValue, ErrorResult& aRv)
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window;
if (MOZ_LIKELY(NS_IsMainThread())) {
@ -552,9 +550,7 @@ Promise::Reject(const GlobalObject& aGlobal, JSContext* aCx,
}
}
return Reject(window, aCx,
aValue.WasPassed() ? aValue.Value() : JS::UndefinedHandleValue,
aRv);
return Reject(window, aCx, aValue, aRv);
}
/* static */ already_AddRefed<Promise>
@ -736,8 +732,8 @@ Promise::All(const GlobalObject& aGlobal, JSContext* aCx,
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
Optional<JS::Handle<JS::Value>> optValue(aCx, JS::ObjectValue(*empty));
return Promise::Resolve(aGlobal, aCx, optValue, aRv);
JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*empty));
return Promise::Resolve(aGlobal, aCx, value, aRv);
}
nsRefPtr<Promise> promise = new Promise(window);
@ -747,8 +743,8 @@ Promise::All(const GlobalObject& aGlobal, JSContext* aCx,
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise);
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
Optional<JS::Handle<JS::Value>> optValue(aCx, aIterable.ElementAt(i));
nsRefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aCx, optValue, aRv);
JS::Rooted<JS::Value> value(aCx, aIterable.ElementAt(i));
nsRefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aCx, value, aRv);
MOZ_ASSERT(!aRv.Failed());
@ -783,8 +779,8 @@ Promise::Race(const GlobalObject& aGlobal, JSContext* aCx,
nsRefPtr<PromiseCallback> rejectCb = new RejectPromiseCallback(promise);
for (uint32_t i = 0; i < aIterable.Length(); ++i) {
Optional<JS::Handle<JS::Value>> optValue(aCx, aIterable.ElementAt(i));
nsRefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aCx, optValue, aRv);
JS::Rooted<JS::Value> value(aCx, aIterable.ElementAt(i));
nsRefPtr<Promise> nextPromise = Promise::Resolve(aGlobal, aCx, value, aRv);
// According to spec, Resolve can throw, but our implementation never does.
// Well it does when window isn't passed on the main thread, but that is an
// implementation detail which should never be reached since we are checking

Просмотреть файл

@ -66,7 +66,7 @@ public:
static already_AddRefed<Promise>
Resolve(const GlobalObject& aGlobal, JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aValue, ErrorResult& aRv);
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
Resolve(nsPIDOMWindow* aWindow, JSContext* aCx,
@ -74,7 +74,7 @@ public:
static already_AddRefed<Promise>
Reject(const GlobalObject& aGlobal, JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aValue, ErrorResult& aRv);
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
static already_AddRefed<Promise>
Reject(nsPIDOMWindow* aWindow, JSContext* aCx,

Просмотреть файл

@ -26,11 +26,11 @@ interface HTMLCanvasElement : HTMLElement {
[Throws]
DOMString toDataURL(optional DOMString type = "",
optional any encoderOptions);
any encoderOptions);
[Throws]
void toBlob(FileCallback _callback,
optional DOMString type = "",
optional any encoderOptions);
any encoderOptions);
};
// Mozilla specific bits

Просмотреть файл

@ -32,7 +32,7 @@ interface IDBCursor {
void advance ([EnforceRange] unsigned long count);
[Throws]
void continue (optional any key);
void continue (any key);
[Throws]
IDBRequest delete ();

Просмотреть файл

@ -23,10 +23,10 @@ interface IDBIndex {
readonly attribute boolean unique;
[Throws]
IDBRequest openCursor (optional any range, optional IDBCursorDirection direction = "next");
IDBRequest openCursor (any range, optional IDBCursorDirection direction = "next");
[Throws]
IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
IDBRequest openKeyCursor (any range, optional IDBCursorDirection direction = "next");
[Throws]
IDBRequest get (any key);
@ -35,15 +35,15 @@ interface IDBIndex {
IDBRequest getKey (any key);
[Throws]
IDBRequest count (optional any key);
IDBRequest count (any key);
};
partial interface IDBIndex {
readonly attribute DOMString storeName;
[Throws]
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
IDBRequest mozGetAll (any key, optional unsigned long limit);
[Throws]
IDBRequest mozGetAllKeys (optional any key, optional unsigned long limit);
IDBRequest mozGetAllKeys (any key, optional unsigned long limit);
};

Просмотреть файл

@ -25,10 +25,10 @@ interface IDBObjectStore {
readonly attribute boolean autoIncrement;
[Throws]
IDBRequest put (any value, optional any key);
IDBRequest put (any value, any key);
[Throws]
IDBRequest add (any value, optional any key);
IDBRequest add (any value, any key);
[Throws]
IDBRequest delete (any key);
@ -40,7 +40,7 @@ interface IDBObjectStore {
IDBRequest clear ();
[Throws]
IDBRequest openCursor (optional any range, optional IDBCursorDirection direction = "next");
IDBRequest openCursor (any range, optional IDBCursorDirection direction = "next");
// Bug 899972
// IDBIndex createIndex (DOMString name, (DOMString or sequence<DOMString>) keyPath, optional IDBIndexParameters optionalParameters);
@ -58,20 +58,20 @@ interface IDBObjectStore {
void deleteIndex (DOMString indexName);
[Throws]
IDBRequest count (optional any key);
IDBRequest count (any key);
};
partial interface IDBObjectStore {
// Success fires IDBTransactionEvent, result == array of values for given keys
[Throws]
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
IDBRequest mozGetAll (any key, optional unsigned long limit);
[Pref="dom.indexedDB.experimental", Throws]
IDBRequest getAll (optional any key, optional unsigned long limit);
IDBRequest getAll (any key, optional unsigned long limit);
[Pref="dom.indexedDB.experimental", Throws]
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
IDBRequest getAllKeys (any key, optional unsigned long limit);
[Pref="dom.indexedDB.experimental", Throws]
IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
IDBRequest openKeyCursor (any range, optional IDBCursorDirection direction = "next");
};

Просмотреть файл

@ -26,9 +26,9 @@ interface Promise {
// Promise object in this scope without having resolved the interface object
// first.
[NewObject, Throws]
static Promise resolve(optional any value);
static Promise resolve(any value);
[NewObject, Throws]
static Promise reject(optional any value);
static Promise reject(any value);
// The [TreatNonCallableAsNull] annotation is required since then() should do
// nothing instead of throwing errors when non-callable arguments are passed.

Просмотреть файл

@ -146,7 +146,7 @@ dictionary RTCStatsReportInternal {
interface RTCStatsReport {
[ChromeOnly]
readonly attribute DOMString mozPcid;
void forEach(RTCStatsReportCallback callbackFn, optional any thisArg);
void forEach(RTCStatsReportCallback callbackFn, any thisArg);
object get(DOMString key);
boolean has(DOMString key);
};

Просмотреть файл

@ -6,7 +6,7 @@
[JSImplementation="@mozilla.org/dom/test-interface-js;1",
Pref="dom.expose_test_interfaces",
Constructor(optional any anyArg, optional object objectArg)]
Constructor(any anyArg, optional object objectArg)]
interface TestInterfaceJS {
readonly attribute any anyArg;
readonly attribute object objectArg;

Просмотреть файл

@ -74,7 +74,7 @@ typedef any Transferable;
[Throws] DOMString? prompt(optional DOMString message = "", optional DOMString default = "");
[Throws] void print();
//[Throws] any showModalDialog(DOMString url, optional any argument);
[Throws] any showModalDialog(DOMString url, optional any argument, optional DOMString options = "");
[Throws] any showModalDialog(DOMString url, any argument, optional DOMString options = "");
[Throws, CrossOriginCallable] void postMessage(any message, DOMString targetOrigin, optional sequence<Transferable> transfer);
@ -87,10 +87,10 @@ Window implements WindowEventHandlers;
[NoInterfaceObject]
interface WindowTimers {
[Throws] long setTimeout(Function handler, optional long timeout = 0, any... arguments);
[Throws] long setTimeout(DOMString handler, optional long timeout = 0);
[Throws] long setTimeout(DOMString handler, optional long timeout = 0, any... unused);
[Throws] void clearTimeout(long handle);
[Throws] long setInterval(Function handler, optional long timeout, any... arguments);
[Throws] long setInterval(DOMString handler, optional long timeout);
[Throws] long setInterval(DOMString handler, optional long timeout, any... unused);
[Throws] void clearInterval(long handle);
};
Window implements WindowTimers;

Просмотреть файл

@ -12,12 +12,12 @@ interface WorkerConsole {
void _exception(any... data);
void debug(any... data);
void trace();
void dir(optional any data);
void dir(any data);
void group(any... data);
void groupCollapsed(any... data);
void groupEnd(any... data);
void time(optional any time);
void timeEnd(optional any time);
void time(any time);
void timeEnd(any time);
void profile(any... data);
void profileEnd(any... data);
void assert(boolean condition, any... data);

Просмотреть файл

@ -341,10 +341,10 @@ private:
nsTArray<nsString> mStrings;
};
class TeardownRunnable : public nsRunnable
class TeardownConsoleRunnable : public nsRunnable
{
public:
TeardownRunnable(ConsoleProxy* aProxy)
TeardownConsoleRunnable(ConsoleProxy* aProxy)
: mProxy(aProxy)
{
}
@ -392,7 +392,8 @@ WorkerConsole::~WorkerConsole()
MOZ_COUNT_DTOR(WorkerConsole);
if (mProxy) {
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mProxy);
nsRefPtr<TeardownConsoleRunnable> runnable =
new TeardownConsoleRunnable(mProxy);
mProxy = nullptr;
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
@ -491,14 +492,13 @@ WorkerConsole::Trace(JSContext* aCx)
}
void
WorkerConsole::Dir(JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aValue)
WorkerConsole::Dir(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
if (aValue.WasPassed()) {
data.AppendElement(aValue.Value());
if (!aValue.isUndefined()) {
data.AppendElement(aValue);
}
Method(aCx, "dir", data, 1);
@ -509,14 +509,13 @@ METHOD(GroupCollapsed, "groupCollapsed")
METHOD(GroupEnd, "groupEnd")
void
WorkerConsole::Time(JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aTimer)
WorkerConsole::Time(JSContext* aCx, JS::Handle<JS::Value> aTimer)
{
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
if (aTimer.WasPassed()) {
data.AppendElement(aTimer.Value());
if (!aTimer.isUndefined()) {
data.AppendElement(aTimer);
}
Method(aCx, "time", data, 1);
@ -524,13 +523,13 @@ WorkerConsole::Time(JSContext* aCx,
void
WorkerConsole::TimeEnd(JSContext* aCx,
const Optional<JS::Handle<JS::Value>>& aTimer)
JS::Handle<JS::Value> aTimer)
{
Sequence<JS::Value> data;
SequenceRooter<JS::Value> rooter(aCx, &data);
if (aTimer.WasPassed()) {
data.AppendElement(aTimer.Value());
if (!aTimer.isUndefined()) {
data.AppendElement(aTimer);
}
Method(aCx, "timeEnd", data, 1);

Просмотреть файл

@ -70,7 +70,7 @@ public:
Trace(JSContext* aCx);
void
Dir(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aValue);
Dir(JSContext* aCx, JS::Handle<JS::Value> aValue);
void
Group(JSContext* aCx, const Sequence<JS::Value>& aData);
@ -82,10 +82,10 @@ public:
GroupEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
void
Time(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aTimer);
Time(JSContext* aCx, JS::Handle<JS::Value> aTimer);
void
TimeEnd(JSContext* aCx, const Optional<JS::Handle<JS::Value>>& aTimer);
TimeEnd(JSContext* aCx, JS::Handle<JS::Value> aTimer);
void
Profile(JSContext* aCx, const Sequence<JS::Value>& aData);

Просмотреть файл

@ -843,11 +843,13 @@ class WorkerJSRuntime : public mozilla::CycleCollectedJSRuntime
public:
// The heap size passed here doesn't matter, we will change it later in the
// call to JS_SetGCParameter inside CreateJSContextForWorker.
WorkerJSRuntime(WorkerPrivate* aWorkerPrivate)
: CycleCollectedJSRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE,
JS_NO_HELPER_THREADS),
WorkerJSRuntime(JSRuntime* aParentRuntime, WorkerPrivate* aWorkerPrivate)
: CycleCollectedJSRuntime(aParentRuntime,
WORKER_DEFAULT_RUNTIME_HEAPSIZE,
JS_NO_HELPER_THREADS),
mWorkerPrivate(aWorkerPrivate)
{ }
{
}
~WorkerJSRuntime()
{
@ -912,6 +914,7 @@ class WorkerThreadPrimaryRunnable MOZ_FINAL : public nsRunnable
{
WorkerPrivate* mWorkerPrivate;
nsRefPtr<RuntimeService::WorkerThread> mThread;
JSRuntime* mParentRuntime;
class FinishedRunnable MOZ_FINAL : public nsRunnable
{
@ -935,8 +938,9 @@ class WorkerThreadPrimaryRunnable MOZ_FINAL : public nsRunnable
public:
WorkerThreadPrimaryRunnable(WorkerPrivate* aWorkerPrivate,
RuntimeService::WorkerThread* aThread)
: mWorkerPrivate(aWorkerPrivate), mThread(aThread)
RuntimeService::WorkerThread* aThread,
JSRuntime* aParentRuntime)
: mWorkerPrivate(aWorkerPrivate), mThread(aThread), mParentRuntime(aParentRuntime)
{
MOZ_ASSERT(aWorkerPrivate);
MOZ_ASSERT(aThread);
@ -1529,7 +1533,7 @@ RuntimeService::ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
}
nsCOMPtr<nsIRunnable> runnable =
new WorkerThreadPrimaryRunnable(aWorkerPrivate, thread);
new WorkerThreadPrimaryRunnable(aWorkerPrivate, thread, JS_GetParentRuntime(aCx));
if (NS_FAILED(thread->Dispatch(runnable, NS_DISPATCH_NORMAL))) {
UnregisterWorker(aCx, aWorkerPrivate);
JS_ReportError(aCx, "Could not dispatch to thread!");
@ -2535,7 +2539,7 @@ WorkerThreadPrimaryRunnable::Run()
{
nsCycleCollector_startup();
WorkerJSRuntime runtime(mWorkerPrivate);
WorkerJSRuntime runtime(mParentRuntime, mWorkerPrivate);
JSRuntime* rt = runtime.Runtime();
JSContext* cx = CreateJSContextForWorker(mWorkerPrivate, rt);

Просмотреть файл

@ -312,10 +312,10 @@ public:
}
};
class TeardownRunnable : public nsRunnable
class TeardownURLRunnable : public nsRunnable
{
public:
TeardownRunnable(URLProxy* aURLProxy)
TeardownURLRunnable(URLProxy* aURLProxy)
: mURLProxy(aURLProxy)
{
}
@ -576,7 +576,8 @@ URL::~URL()
MOZ_COUNT_DTOR(workers::URL);
if (mURLProxy) {
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mURLProxy);
nsRefPtr<TeardownURLRunnable> runnable =
new TeardownURLRunnable(mURLProxy);
mURLProxy = nullptr;
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {

Просмотреть файл

@ -180,8 +180,10 @@ WorkerGlobalScope::SetTimeout(JSContext* aCx,
}
int32_t
WorkerGlobalScope::SetTimeout(const nsAString& aHandler,
WorkerGlobalScope::SetTimeout(JSContext* /* unused */,
const nsAString& aHandler,
const int32_t aTimeout,
const Sequence<JS::Value>& /* unused */,
ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
@ -213,8 +215,10 @@ WorkerGlobalScope::SetInterval(JSContext* aCx,
}
int32_t
WorkerGlobalScope::SetInterval(const nsAString& aHandler,
WorkerGlobalScope::SetInterval(JSContext* /* unused */,
const nsAString& aHandler,
const Optional<int32_t>& aTimeout,
const Sequence<JS::Value>& /* unused */,
ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();

Просмотреть файл

@ -88,7 +88,8 @@ public:
SetTimeout(JSContext* aCx, Function& aHandler, const int32_t aTimeout,
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
int32_t
SetTimeout(const nsAString& aHandler, const int32_t aTimeout,
SetTimeout(JSContext* /* unused */, const nsAString& aHandler,
const int32_t aTimeout, const Sequence<JS::Value>& /* unused */,
ErrorResult& aRv);
void
ClearTimeout(int32_t aHandle, ErrorResult& aRv);
@ -97,8 +98,9 @@ public:
const Optional<int32_t>& aTimeout,
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
int32_t
SetInterval(const nsAString& aHandler, const Optional<int32_t>& aTimeout,
ErrorResult& aRv);
SetInterval(JSContext* /* unused */, const nsAString& aHandler,
const Optional<int32_t>& aTimeout,
const Sequence<JS::Value>& /* unused */, ErrorResult& aRv);
void
ClearInterval(int32_t aHandle, ErrorResult& aRv);

Просмотреть файл

@ -28,7 +28,7 @@
# ***** END LICENSE BLOCK *****
LIBS = \
$(DEPTH)/profile/dirserviceprovider/standalone/$(LIB_PREFIX)profdirserviceprovidersa_s.$(LIB_SUFFIX) \
$(DEPTH)/profile/dirserviceprovider/src/$(LIB_PREFIX)profdirserviceprovidersa_s.$(LIB_SUFFIX) \
$(XPCOM_STANDALONE_GLUE_LDOPTS) \
$(NULL)

Просмотреть файл

@ -9481,141 +9481,144 @@
> provender/M
39564a45391
> quinoa
40036a45864
39873a45701,45702
> rasterization/M
> rasterize/SGDR
40036a45866
> recency
40140a45969
40140a45971
> recurse/DGSV
40141a45971
40141a45973
> recuse/DGS
40208a46039
40208a46041
> refactor/SMDG
40244d46074
40244d46076
< reflexion/SM
40659d46488
40659d46490
< resizing
40829c46658
40829c46660
< reverie/M
---
> reverie/MS
41415a47245
41415a47247
> sabre/MS
41914c47744
41914c47746
< schnaps's
---
> schnaps/M
41949c47779
41949c47781
< schrod's
---
> schrod/SM
41998a47829
41998a47831
> scot-free
42883,42885c48714
42883,42885c48716
< shit's
< shit/S!
< shite/S!
---
> shit/MS!
42887,42888c48716,48717
42887,42888c48718,48719
< shithead/S!
< shitload/!
---
> shithead/MS!
> shitload/MS!
42891c48720
42891c48722
< shitty/RT!
---
> shitty/TR!
42976a48806
42976a48808
> should've
43008c48838
43008c48840
< showtime
---
> showtime/MS
43328c49158
43328c49160
< size/MGBDRS
---
> size/AMGBDRS
43724,43726c49554
43724,43726c49556
< smoulder's
< smouldered
< smoulders
---
> smoulder/GSMD
44062c49890
44062c49892
< sonofabitch
---
> sonofabitch/!
44346a50175
44346a50177
> spelled
44348a50178
44348a50180
> spelt
44371a50202
44371a50204
> spick/S!
44383c50214
44383c50216
< spik/S
---
> spik/S!
46106a51938
46106a51940
> syllabi
46160c51992
46160c51994
< synch/GMD
---
> synch/GMDS
46167d51998
46167d52000
< synchs
46203,46204c52034,52035
46203,46204c52036,52037
< sysadmin/S
< sysop/S
---
> sysadmin/MS
> sysop/MS
46752a52584
46752a52586
> terabit/MS
46753a52586,52587
46753a52588,52589
> terahertz/M
> terapixel/MS
46817a52652
46817a52654
> testcase/MS
46831a52667
46831a52669
> testsuite/MS
46925a52762
46925a52764
> theremin/MS
47455c53292
47455c53294
< toolbar
---
> toolbar/MS
47755a53593
47755a53595
> transfect/DSMG
47774a53613,53614
47774a53615,53616
> transgenderism
> transgene/MS
47951c53791
47951c53793
< triage/M
---
> triage/MG
48869a54710
48869a54712
> unlikeable
49211c55052
49211c55054
< vagina/M
---
> vagina/MS
49368,49369c55209
49368,49369c55211
< velour's
< velours's
---
> velour/MS
49478a55319
49478a55321
> vertices
50148a55990
50148a55992
> weaponize/DSG
50260,50261d56101
50260,50261d56103
< werwolf/M
< werwolves
50728c56568
50728c56570
< women
---
> women/M
50794c56634
50794c56636
< wop/S!
---
> wop/MS!

Просмотреть файл

@ -1,4 +1,4 @@
57456
57458
0/nm
0th/pt
1/n1
@ -46024,6 +46024,8 @@ rasp/GMDRS
raspberry/SM
raspy/RT
raster
rasterization/M
rasterize/SGDR
rat/SM
ratatouille/M
ratbag/S

Просмотреть файл

@ -338,6 +338,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
newTarget = new DrawTargetSkia();
newTarget->Init(aData, aSize, aStride, aFormat);
retVal = newTarget;
break;
}
#endif
#ifdef XP_MACOSX

Просмотреть файл

@ -76,12 +76,16 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
return;
}
RefPtr<DrawTarget> drawTarget =
mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
if (drawTarget) {
aLayer->UpdateTarget(drawTarget);
bool updated = false;
{
// Restrict drawTarget to a scope so that terminates before Unlock.
RefPtr<DrawTarget> drawTarget =
mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget();
if (drawTarget) {
aLayer->UpdateTarget(drawTarget);
updated = true;
}
}
mBuffer->Unlock();
if (bufferCreated && !AddTextureClient(mBuffer)) {
@ -89,7 +93,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
return;
}
if (drawTarget) {
if (updated) {
GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
GetForwarder()->UseTexture(this, mBuffer);
}

Просмотреть файл

@ -550,6 +550,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
switch (aEffectChain.mPrimaryEffect->mType) {
case EFFECT_SOLID_COLOR: {
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, SurfaceFormat::UNKNOWN);
Color color =
static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
mPSConstants.layerColor[0] = color.r * color.a * aOpacity;
@ -564,8 +566,6 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
TexturedEffect* texturedEffect =
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, texturedEffect->mTexture->GetFormat());
mVSConstants.textureCoords = texturedEffect->mTextureCoords;
TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11();
@ -575,6 +575,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
return;
}
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, texturedEffect->mTexture->GetFormat());
RefPtr<ID3D11ShaderResourceView> view;
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
@ -593,7 +595,6 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
EffectYCbCr* ycbcrEffect =
static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get());
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, ycbcrEffect->mTexture->GetFormat());
SetSamplerForFilter(Filter::LINEAR);
mVSConstants.textureCoords = ycbcrEffect->mTextureCoords;
@ -606,6 +607,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
return;
}
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, ycbcrEffect->mTexture->GetFormat());
if (!source->GetSubSource(Y) || !source->GetSubSource(Cb) || !source->GetSubSource(Cr)) {
// This can happen if we failed to upload the textures, most likely
// because of unsupported dimensions (we don't tile YCbCr textures).
@ -635,7 +638,6 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
EffectComponentAlpha* effectComponentAlpha =
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, effectComponentAlpha->mTexture->GetFormat());
TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11();
TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11();
@ -644,6 +646,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
return;
}
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, effectComponentAlpha->mOnWhite->GetFormat());
SetSamplerForFilter(effectComponentAlpha->mFilter);
mVSConstants.textureCoords = effectComponentAlpha->mTextureCoords;

Просмотреть файл

@ -291,6 +291,16 @@ GrallocBufferActor::Create(const gfx::IntSize& aSize,
return actor;
}
// If the requested size is too big (i.e. exceeds the commonly used max GL texture size)
// then we risk OOMing the parent process. It's better to just deny the allocation and
// kill the child process, which is what the following code does.
// TODO: actually use GL_MAX_TEXTURE_SIZE instead of hardcoding 4096
if (aSize.width > 4096 || aSize.height > 4096) {
printf_stderr("GrallocBufferActor::Create -- requested gralloc buffer is too big. Killing child instead.");
delete actor;
return nullptr;
}
sp<GraphicBuffer> buffer(new GraphicBuffer(aSize.width, aSize.height, format, usage));
if (buffer->initCheck() != OK)
return actor;

Просмотреть файл

@ -109,12 +109,15 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
}
MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
if (!mTextureClient->Lock(OPEN_WRITE_ONLY)) {
MOZ_ASSERT(false, "Failed to lock the texture.");
return;
}
TextureClientAutoUnlock unlock(mTextureClient);
if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
return;
}
// do not set mBuffer like in PlanarYCbCrImage because the later
// will try to manage this memory without knowing it belongs to a
// shmem.

Просмотреть файл

@ -108,13 +108,13 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
client->AllocateForSurface(ToIntSize(surface->GetSize()));
ASSERT_TRUE(texture->IsAllocated());
ASSERT_TRUE(texture->Lock(OPEN_READ_WRITE));
// client painting
client->UpdateSurface(surface);
nsRefPtr<gfxASurface> aSurface = client->GetAsSurface();
nsRefPtr<gfxImageSurface> clientSurface = aSurface->GetAsImageSurface();
ASSERT_TRUE(texture->Lock(OPEN_READ_ONLY));
AssertSurfacesEqual(surface, clientSurface);
texture->Unlock();
@ -155,10 +155,9 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
ycbcrData.mStereoMode);
ASSERT_TRUE(client->IsAllocated());
ASSERT_TRUE(client->Lock(OPEN_READ_WRITE));
// client painting
texture->UpdateYCbCr(ycbcrData);
ASSERT_TRUE(client->Lock(OPEN_READ_ONLY));
client->Unlock();
// client serialization
@ -176,13 +175,11 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
ASSERT_TRUE(host.get() != nullptr);
ASSERT_EQ(host->GetFlags(), client->GetFlags());
// This will work iff the compositor is not BasicCompositor
ASSERT_EQ(host->GetFormat(), mozilla::gfx::SurfaceFormat::YUV);
// host read
ASSERT_TRUE(host->Lock());
ASSERT_TRUE(host->GetFormat() == mozilla::gfx::SurfaceFormat::YUV);
// This will work iff the compositor is not BasicCompositor
ASSERT_EQ(host->GetFormat(), mozilla::gfx::SurfaceFormat::YUV);
YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer());
ASSERT_TRUE(yuvDeserializer.IsValid());

Просмотреть файл

@ -19,10 +19,10 @@ using namespace js::types;
using mozilla::ArrayLength;
bool
js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *chars, size_t length,
MatchPairs &matches, MutableHandleValue rval)
js::CreateRegExpMatchResult(JSContext *cx, HandleString input, const MatchPairs &matches,
MutableHandleValue rval)
{
RootedString input(cx, input_);
JS_ASSERT(input);
/*
* Create the (slow) result array for a match.
@ -33,79 +33,58 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *ch
* input: input string
* index: start index for the match
*/
if (!input) {
input = js_NewStringCopyN<CanGC>(cx, chars, length);
if (!input)
return false;
}
size_t numPairs = matches.length();
JS_ASSERT(numPairs > 0);
AutoValueVector elements(cx);
if (!elements.reserve(numPairs))
return false;
/* Accumulate a Value for each pair, in a rooted vector. */
for (size_t i = 0; i < numPairs; ++i) {
const MatchPair &pair = matches[i];
if (pair.isUndefined()) {
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
elements.infallibleAppend(UndefinedHandleValue);
} else {
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
if (!str)
return false;
elements.infallibleAppend(StringValue(str));
}
}
/* Get the templateObject that defines the shape and type of the output object */
JSObject *templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
if (!templateObject)
return false;
/* Copy the rooted vector into the array object. */
RootedObject arr(cx, NewDenseCopiedArrayWithTemplate(cx, elements.length(), elements.begin(),
templateObject));
size_t numPairs = matches.length();
JS_ASSERT(numPairs > 0);
RootedObject arr(cx, NewDenseAllocatedArrayWithTemplate(cx, numPairs, templateObject));
if (!arr)
return false;
/* Store a Value for each pair. */
for (size_t i = 0; i < numPairs; i++) {
const MatchPair &pair = matches[i];
if (pair.isUndefined()) {
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
arr->setDenseInitializedLength(i + 1);
arr->initDenseElement(i, UndefinedValue());
} else {
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
if (!str)
return false;
arr->setDenseInitializedLength(i + 1);
arr->initDenseElement(i, StringValue(str));
}
}
/* Set the |index| property. (TemplateObject positions it in slot 0) */
RootedValue index(cx, Int32Value(matches[0].start));
arr->nativeSetSlot(0, index);
arr->nativeSetSlot(0, Int32Value(matches[0].start));
/* Set the |input| property. (TemplateObject positions it in slot 1) */
RootedValue inputVal(cx, StringValue(input));
arr->nativeSetSlot(1, inputVal);
arr->nativeSetSlot(1, StringValue(input));
#ifdef DEBUG
RootedValue test(cx);
RootedId id(cx, NameToId(cx->names().index));
if (!baseops::GetProperty(cx, arr, id, &test))
return false;
JS_ASSERT(test == index);
JS_ASSERT(test == arr->nativeGetSlot(0));
id = NameToId(cx->names().input);
if (!baseops::GetProperty(cx, arr, id, &test))
return false;
JS_ASSERT(test == inputVal);
JS_ASSERT(test == arr->nativeGetSlot(1));
#endif
rval.setObject(*arr);
return true;
}
bool
js::CreateRegExpMatchResult(JSContext *cx, HandleString string, MatchPairs &matches,
MutableHandleValue rval)
{
Rooted<JSLinearString*> input(cx, string->ensureLinear(cx));
if (!input)
return false;
return CreateRegExpMatchResult(cx, input, input->chars(), input->length(), matches, rval);
}
static RegExpRunStatus
ExecuteRegExpImpl(JSContext *cx, RegExpStatics *res, RegExpShared &re,
Handle<JSLinearString*> input, const jschar *chars, size_t length,
@ -133,7 +112,7 @@ ExecuteRegExpImpl(JSContext *cx, RegExpStatics *res, RegExpShared &re,
/* Legacy ExecuteRegExp behavior is baked into the JSAPI. */
bool
js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
Handle<JSLinearString*> input, const jschar *chars, size_t length,
Handle<JSLinearString*> input_, const jschar *chars, size_t length,
size_t *lastIndex, bool test, MutableHandleValue rval)
{
RegExpGuard shared(cx);
@ -144,7 +123,7 @@ js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
MatchConduit conduit(&matches);
RegExpRunStatus status =
ExecuteRegExpImpl(cx, res, *shared, input, chars, length, lastIndex, conduit);
ExecuteRegExpImpl(cx, res, *shared, input_, chars, length, lastIndex, conduit);
if (status == RegExpRunStatus_Error)
return false;
@ -161,7 +140,14 @@ js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
return true;
}
return CreateRegExpMatchResult(cx, input, chars, length, matches, rval);
RootedString input(cx, input_);
if (!input) {
input = js_NewStringCopyN<CanGC>(cx, chars, length);
if (!input)
return false;
}
return CreateRegExpMatchResult(cx, input, matches, rval);
}
/* Note: returns the original if no escaping need be performed. */

Просмотреть файл

@ -41,13 +41,9 @@ ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
/* Translation from MatchPairs to a JS array in regexp_exec()'s output format. */
bool
CreateRegExpMatchResult(JSContext *cx, HandleString string, MatchPairs &matches,
CreateRegExpMatchResult(JSContext *cx, HandleString input, const MatchPairs &matches,
MutableHandleValue rval);
bool
CreateRegExpMatchResult(JSContext *cx, HandleString input, const jschar *chars, size_t length,
MatchPairs &matches, MutableHandleValue rval);
extern bool
regexp_exec_raw(JSContext *cx, HandleObject regexp, HandleString input, Value *vp);

Просмотреть файл

@ -2069,9 +2069,9 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbo
size_t numInnerFunctions = pc->innerFunctions.length();
RootedFunction fun(context, funbox->function());
LazyScript *lazy = LazyScript::Create(context, fun, numFreeVariables, numInnerFunctions, versionNumber(),
funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
LazyScript *lazy = LazyScript::CreateRaw(context, fun, numFreeVariables, numInnerFunctions,
versionNumber(), funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
if (!lazy)
return false;

Просмотреть файл

@ -57,4 +57,10 @@ RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone *shadowZone)
}
#endif // DEBUG
bool
StringIsPermanentAtom(JSString *str)
{
return str->isPermanentAtom();
}
} // namespace js

Просмотреть файл

@ -605,6 +605,9 @@ struct EncapsulatedPtrHasher
template <class T>
struct DefaultHasher< EncapsulatedPtr<T> > : EncapsulatedPtrHasher<T> { };
bool
StringIsPermanentAtom(JSString *str);
/*
* Base class for barriered value types.
*/
@ -657,6 +660,8 @@ class BarrieredValue : public ValueOperations<BarrieredValue>
static void writeBarrierPre(Zone *zone, const Value &v) {
#ifdef JSGC_INCREMENTAL
if (v.isString() && StringIsPermanentAtom(v.toString()))
return;
JS::shadow::Zone *shadowZone = JS::shadow::Zone::asShadowZone(zone);
if (shadowZone->needsBarrier()) {
JS_ASSERT_IF(v.isMarkable(), shadowRuntimeFromMainThread(v)->needsBarrier());

Просмотреть файл

@ -118,6 +118,13 @@ AsGCMarker(JSTracer *trc)
return static_cast<GCMarker *>(trc);
}
template <typename T> bool ThingIsPermanentAtom(T *thing) { return false; }
template <> bool ThingIsPermanentAtom<JSString>(JSString *str) { return str->isPermanentAtom(); }
template <> bool ThingIsPermanentAtom<JSFlatString>(JSFlatString *str) { return str->isPermanentAtom(); }
template <> bool ThingIsPermanentAtom<JSLinearString>(JSLinearString *str) { return str->isPermanentAtom(); }
template <> bool ThingIsPermanentAtom<JSAtom>(JSAtom *atom) { return atom->isPermanent(); }
template <> bool ThingIsPermanentAtom<PropertyName>(PropertyName *name) { return name->isPermanent(); }
template<typename T>
static inline void
CheckMarkedThing(JSTracer *trc, T *thing)
@ -130,6 +137,13 @@ CheckMarkedThing(JSTracer *trc, T *thing)
if (IsInsideNursery(trc->runtime, thing))
return;
/*
* Permanent atoms are not associated with this runtime, but will be ignored
* during marking.
*/
if (ThingIsPermanentAtom(thing))
return;
JS_ASSERT(thing->zone());
JS_ASSERT(thing->zone()->runtimeFromMainThread() == trc->runtime);
JS_ASSERT(trc->debugPrinter || trc->debugPrintArg);
@ -187,6 +201,14 @@ MarkInternal(JSTracer *trc, T **thingp)
if (IsInsideNursery(trc->runtime, thing))
return;
/*
* Don't mark permanent atoms, as they may be associated with another
* runtime. Note that PushMarkStack() also checks this, but the tests
* and maybeAlive write below should only be done on the main thread.
*/
if (ThingIsPermanentAtom(thing))
return;
/*
* Don't mark things outside a compartment if we are in a
* per-compartment GC.
@ -229,6 +251,30 @@ Mark(JSTracer *trc, BarrieredPtr<T> *thing, const char *name)
MarkInternal(trc, thing->unsafeGet());
}
void
MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name)
{
JS_SET_TRACING_NAME(trc, name);
JS_ASSERT(atom->isPermanent());
CheckMarkedThing(trc, atom);
if (!trc->callback) {
// Atoms do not refer to other GC things so don't need to go on the mark stack.
// Additionally, PushMarkStack will ignore permanent atoms.
atom->markIfUnmarked();
} else {
void *thing = atom;
trc->callback(trc, &thing, JSTRACE_STRING);
JS_ASSERT(thing == atom);
JS_UNSET_TRACING_LOCATION(trc);
}
trc->debugPrinter = nullptr;
trc->debugPrintArg = nullptr;
}
} /* namespace gc */
} /* namespace js */
@ -293,6 +339,13 @@ IsAboutToBeFinalized(T **thingp)
JS_ASSERT(thingp);
JS_ASSERT(*thingp);
/* Permanent atoms are never finalized by non-owning runtimes. */
if (ThingIsPermanentAtom(*thingp) &&
!TlsPerThreadData.get()->associatedWith((*thingp)->runtimeFromAnyThread()))
{
return false;
}
#ifdef JSGC_GENERATIONAL
Nursery &nursery = (*thingp)->runtimeFromMainThread()->gcNursery;
if (nursery.isInside(*thingp))
@ -940,6 +993,8 @@ ScanLinearString(GCMarker *gcmarker, JSLinearString *str)
while (str->hasBase()) {
str = str->base();
JS_ASSERT(str->JSString::isLinear());
if (str->isPermanentAtom())
break;
JS_COMPARTMENT_ASSERT_STR(gcmarker->runtime, str);
if (!str->markIfUnmarked())
break;
@ -968,7 +1023,7 @@ ScanRope(GCMarker *gcmarker, JSRope *rope)
JSRope *next = nullptr;
JSString *right = rope->rightChild();
if (right->markIfUnmarked()) {
if (!right->isPermanentAtom() && right->markIfUnmarked()) {
if (right->isLinear())
ScanLinearString(gcmarker, &right->asLinear());
else
@ -976,7 +1031,7 @@ ScanRope(GCMarker *gcmarker, JSRope *rope)
}
JSString *left = rope->leftChild();
if (left->markIfUnmarked()) {
if (!left->isPermanentAtom() && left->markIfUnmarked()) {
if (left->isLinear()) {
ScanLinearString(gcmarker, &left->asLinear());
} else {
@ -1013,6 +1068,10 @@ ScanString(GCMarker *gcmarker, JSString *str)
static inline void
PushMarkStack(GCMarker *gcmarker, JSString *str)
{
// Permanent atoms might not be associated with this runtime.
if (str->isPermanentAtom())
return;
JS_COMPARTMENT_ASSERT_STR(gcmarker->runtime, str);
/*
@ -1398,10 +1457,12 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
const Value &v = *vp++;
if (v.isString()) {
JSString *str = v.toString();
JS_COMPARTMENT_ASSERT_STR(runtime, str);
JS_ASSERT(runtime->isAtomsZone(str->zone()) || str->zone() == obj->zone());
if (str->markIfUnmarked())
ScanString(this, str);
if (!str->isPermanentAtom()) {
JS_COMPARTMENT_ASSERT_STR(runtime, str);
JS_ASSERT(runtime->isAtomsZone(str->zone()) || str->zone() == obj->zone());
if (str->markIfUnmarked())
ScanString(this, str);
}
} else if (v.isObject()) {
JSObject *obj2 = &v.toObject();
JS_COMPARTMENT_ASSERT(runtime, obj2);

Просмотреть файл

@ -114,6 +114,9 @@ DeclMarker(TypeObject, types::TypeObject)
#undef DeclMarker
void
MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name);
/* Return true if the pointer is nullptr, or if it is a tagged pointer to
* nullptr.
*/

Просмотреть файл

@ -736,8 +736,8 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
if (!rt->isBeingDestroyed() && !trc->runtime->isHeapMinorCollecting()) {
if (!IS_GC_MARKING_TRACER(trc) || rt->atomsCompartment()->zone()->isCollecting()) {
MarkPermanentAtoms(trc);
MarkAtoms(trc);
rt->staticStrings.trace(trc);
#ifdef JS_ION
jit::JitRuntime::Mark(trc);
#endif

Просмотреть файл

@ -582,6 +582,10 @@ AssertMarkedOrAllocated(const EdgeValue &edge)
if (!edge.thing || IsMarkedOrAllocated(static_cast<Cell *>(edge.thing)))
return;
// Permanent atoms aren't marked during graph traversal.
if (edge.kind == JSTRACE_STRING && static_cast<JSString *>(edge.thing)->isPermanentAtom())
return;
char msgbuf[1024];
const char *label = edge.label ? edge.label : "<unknown>";

Просмотреть файл

@ -7,11 +7,11 @@ function f() {
}
f();
assertEq(stack,
"h@@evaluate:2\n" +
"@@evaluate:4\n");
"h@@evaluate:2:1\n" +
"@@evaluate:4:2\n");
function k() {
evaluate("stack = Error().stack", {newContext: true});
}
k();
assertEq(stack, "@@evaluate:1\n");
assertEq(stack, "@@evaluate:1:1\n");

Просмотреть файл

@ -0,0 +1,19 @@
// |jit-test| slow
gcslice(10);
evalInWorker("print('helo world');");
for (i = 0; i < 100000; i++) {}
evalInWorker("\
for (var i = 0; i < 10; i++) { \
var o = {}; \
for (var j = 0; j < 100; j++) \
o['a' + j] = j; \
JSON.stringify(o); \
o = null; \
gc(); \
}");
for (var i = 0; i < 10; i++) {
gc();
for (var j = 0; j < 100000; j++) {}
}

Просмотреть файл

@ -1,11 +1,11 @@
// Test offThreadCompileScript option handling.
offThreadCompileScript('Error()');
assertEq(!!runOffThreadScript().stack.match(/^@<string>:1\n/), true);
assertEq(!!runOffThreadScript().stack.match(/^@<string>:1:1\n/), true);
offThreadCompileScript('Error()',
{ fileName: "candelabra", lineNumber: 6502 });
assertEq(!!runOffThreadScript().stack.match(/^@candelabra:6502\n/), true);
assertEq(!!runOffThreadScript().stack.match(/^@candelabra:6502:1\n/), true);
var element = {};
offThreadCompileScript('Error()', { element: element }); // shouldn't crash

Просмотреть файл

@ -5684,6 +5684,8 @@ CheckFunctionsParallel(ModuleCompiler &m)
if (!ParallelCompilationEnabled(m.cx()) || !g.claim())
return CheckFunctionsSequential(m);
IonSpew(IonSpew_Logs, "Can't log asm.js script. (Compiled on background thread.)");
// Saturate all worker threads plus the main thread.
size_t numParallelJobs = WorkerThreadState().threadCount + 1;

Просмотреть файл

@ -4440,7 +4440,7 @@ ICGetElem_String::Compiler::generateStubCode(MacroAssembler &masm)
&failure);
// Load static string.
masm.movePtr(ImmPtr(&cx->runtime()->staticStrings.unitStaticTable), str);
masm.movePtr(ImmPtr(&cx->staticStrings().unitStaticTable), str);
masm.loadPtr(BaseIndex(str, scratchReg, ScalePointer), str);
// Return.
@ -9387,7 +9387,7 @@ DoTypeOfFallback(JSContext *cx, BaselineFrame *frame, ICTypeOf_Fallback *stub, H
{
FallbackICSpew(cx, stub, "TypeOf");
JSType type = js::TypeOfValue(val);
RootedString string(cx, TypeName(type, cx->runtime()->atomState));
RootedString string(cx, TypeName(type, cx->names()));
res.setString(string);

Просмотреть файл

@ -112,13 +112,13 @@ CompileRuntime::hadOutOfMemory()
const JSAtomState &
CompileRuntime::names()
{
return runtime()->atomState;
return *runtime()->commonNames;
}
const StaticStrings &
CompileRuntime::staticStrings()
{
return runtime()->staticStrings;
return *runtime()->staticStrings;
}
const Value &

Просмотреть файл

@ -459,7 +459,7 @@ StringFromCharCode(JSContext *cx, int32_t code)
jschar c = jschar(code);
if (StaticStrings::hasUnit(c))
return cx->runtime()->staticStrings.getUnit(c);
return cx->staticStrings().getUnit(c);
return js_NewStringCopyN<CanGC>(cx, &c, 1);
}
@ -1040,6 +1040,12 @@ AssertValidObjectPtr(JSContext *cx, JSObject *obj)
void
AssertValidStringPtr(JSContext *cx, JSString *str)
{
// We can't closely inspect strings from another runtime.
if (str->runtimeFromAnyThread() != cx->runtime()) {
JS_ASSERT(str->isPermanentAtom());
return;
}
if (str->isAtom())
JS_ASSERT(cx->runtime()->isAtomsZone(str->tenuredZone()));
else

Просмотреть файл

@ -788,14 +788,20 @@ CodeGeneratorX86Shared::visitReturnZero(ReturnZero *ool)
bool
CodeGeneratorX86Shared::visitUDivOrMod(LUDivOrMod *ins)
{
JS_ASSERT(ToRegister(ins->lhs()) == eax);
Register lhs = ToRegister(ins->lhs());
Register rhs = ToRegister(ins->rhs());
Register output = ToRegister(ins->output());
JS_ASSERT_IF(lhs != rhs, rhs != eax);
JS_ASSERT(rhs != edx);
JS_ASSERT_IF(output == eax, ToRegister(ins->remainder()) == edx);
ReturnZero *ool = nullptr;
// Put the lhs in eax.
if (lhs != eax)
masm.mov(lhs, eax);
// Prevent divide by zero.
if (ins->canBeDivideByZero()) {
masm.testl(rhs, rhs);
@ -809,6 +815,7 @@ CodeGeneratorX86Shared::visitUDivOrMod(LUDivOrMod *ins)
}
}
// Zero extend the lhs into edx to make (edx:eax), since udiv is 64-bit.
masm.mov(ImmWord(0), edx);
masm.udiv(rhs);
@ -892,28 +899,6 @@ CodeGeneratorX86Shared::visitDivPowTwoI(LDivPowTwoI *ins)
return true;
}
bool
CodeGeneratorX86Shared::visitDivSelfI(LDivSelfI *ins)
{
Register op = ToRegister(ins->op());
Register output = ToRegister(ins->output());
MDiv *mir = ins->mir();
// If we can't divide by zero, lowering should have just used a constant one.
JS_ASSERT(mir->canBeDivideByZero());
masm.testl(op, op);
if (mir->isTruncated()) {
masm.emitSet(Assembler::NonZero, output);
} else {
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
masm.mov(ImmWord(1), output);
}
return true;
}
bool
CodeGeneratorX86Shared::visitDivI(LDivI *ins)
{
@ -924,13 +909,19 @@ CodeGeneratorX86Shared::visitDivI(LDivI *ins)
MDiv *mir = ins->mir();
JS_ASSERT_IF(lhs != rhs, rhs != eax);
JS_ASSERT(rhs != edx);
JS_ASSERT(remainder == edx);
JS_ASSERT(lhs == eax);
JS_ASSERT(output == eax);
Label done;
ReturnZero *ool = nullptr;
// Put the lhs in eax, for either the negative overflow case or the regular
// divide case.
if (lhs != eax)
masm.mov(lhs, eax);
// Handle divide by zero.
if (mir->canBeDivideByZero()) {
masm.testl(rhs, rhs);
@ -975,7 +966,9 @@ CodeGeneratorX86Shared::visitDivI(LDivI *ins)
masm.bind(&nonzero);
}
// Sign extend eax into edx to make (edx:eax), since idiv is 64-bit.
// Sign extend the lhs into edx to make (edx:eax), since idiv is 64-bit.
if (lhs != eax)
masm.mov(lhs, eax);
masm.cdq();
masm.idiv(rhs);
@ -997,39 +990,6 @@ CodeGeneratorX86Shared::visitDivI(LDivI *ins)
return true;
}
bool
CodeGeneratorX86Shared::visitModSelfI(LModSelfI *ins)
{
Register op = ToRegister(ins->op());
Register output = ToRegister(ins->output());
MMod *mir = ins->mir();
// If we're not fallible, lowering should have just used a constant zero.
JS_ASSERT(mir->fallible());
JS_ASSERT(mir->canBeDivideByZero() || (!mir->isUnsigned() && mir->canBeNegativeDividend()));
masm.testl(op, op);
// For a negative operand, we need to return negative zero. We can't
// represent that as an int32, so bail if that happens.
if (!mir->isUnsigned() && mir->canBeNegativeDividend()) {
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
}
// For a zero operand, we need to return NaN. We can't
// represent that as an int32, so bail if that happens.
if (mir->canBeDivideByZero()) {
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
}
// For any other value, return 0.
masm.mov(ImmWord(0), output);
return true;
}
bool
CodeGeneratorX86Shared::visitModPowTwoI(LModPowTwoI *ins)
{
@ -1114,7 +1074,8 @@ CodeGeneratorX86Shared::visitModI(LModI *ins)
Register rhs = ToRegister(ins->rhs());
// Required to use idiv.
JS_ASSERT(lhs == eax);
JS_ASSERT_IF(lhs != rhs, rhs != eax);
JS_ASSERT(rhs != edx);
JS_ASSERT(remainder == edx);
JS_ASSERT(ToRegister(ins->getTemp(0)) == eax);
@ -1122,6 +1083,10 @@ CodeGeneratorX86Shared::visitModI(LModI *ins)
ReturnZero *ool = nullptr;
ModOverflowCheck *overflow = nullptr;
// Set up eax in preparation for doing a div.
if (lhs != eax)
masm.mov(lhs, eax);
// Prevent divide by zero.
if (ins->mir()->canBeDivideByZero()) {
masm.testl(rhs, rhs);

Просмотреть файл

@ -91,10 +91,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
virtual bool visitMulI(LMulI *ins);
virtual bool visitDivI(LDivI *ins);
virtual bool visitDivPowTwoI(LDivPowTwoI *ins);
virtual bool visitDivSelfI(LDivSelfI *ins);
virtual bool visitModI(LModI *ins);
virtual bool visitModPowTwoI(LModPowTwoI *ins);
virtual bool visitModSelfI(LModSelfI *ins);
virtual bool visitBitNotI(LBitNotI *ins);
virtual bool visitBitOpI(LBitOpI *ins);
virtual bool visitShiftI(LShiftI *ins);

Просмотреть файл

@ -72,25 +72,6 @@ class LDivPowTwoI : public LBinaryMath<0>
}
};
// Division of a number by itself. Returns 1 unless the number is zero.
class LDivSelfI : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(DivSelfI)
LDivSelfI(const LAllocation &op) {
setOperand(0, op);
}
const LAllocation *op() {
return getOperand(0);
}
MDiv *mir() const {
return mir_->toDiv();
}
};
class LModI : public LBinaryMath<1>
{
public:
@ -114,25 +95,6 @@ class LModI : public LBinaryMath<1>
}
};
// Modulo of a number by itself. Returns 0 unless the number is zero.
class LModSelfI : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(ModSelfI)
LModSelfI(const LAllocation &op) {
setOperand(0, op);
}
const LAllocation *op() {
return getOperand(0);
}
MMod *mir() const {
return mir_->toMod();
}
};
// This class performs a simple x86 'div', yielding either a quotient or remainder depending on
// whether this instruction is defined to output eax (quotient) or edx (remainder).
class LUDivOrMod : public LBinaryMath<1>

Просмотреть файл

@ -160,24 +160,8 @@ LIRGeneratorX86Shared::lowerDivI(MDiv *div)
}
}
// Optimize x/x. This is quaint, but it also protects the LDivI code below.
// Since LDivI requires lhs to be in %eax, and since the register allocator
// can't put a virtual register in two physical registers at the same time,
// this puts rhs in %eax too, and since rhs isn't marked usedAtStart, it
// would conflict with the %eax output register. (rhs could be marked
// usedAtStart but for the fact that LDivI clobbers %edx early and rhs could
// happen to be in %edx).
if (div->lhs() == div->rhs()) {
if (!div->canBeDivideByZero())
return define(new(alloc()) LInteger(1), div);
LDivSelfI *lir = new(alloc()) LDivSelfI(useRegisterAtStart(div->lhs()));
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
return false;
return define(lir, div);
}
LDivI *lir = new(alloc()) LDivI(useFixed(div->lhs(), eax), useRegister(div->rhs()), tempFixed(edx));
LDivI *lir = new(alloc()) LDivI(useRegister(div->lhs()), useRegister(div->rhs()),
tempFixed(edx));
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
return false;
return defineFixed(lir, div, LAllocation(AnyRegister(eax)));
@ -200,20 +184,7 @@ LIRGeneratorX86Shared::lowerModI(MMod *mod)
}
}
// Optimize x%x. The comments in lowerDivI apply here as well, except
// that we return 0 for all cases except when x is 0 and we're not
// truncated.
if (mod->rhs() == mod->lhs()) {
if (mod->isTruncated())
return define(new(alloc()) LInteger(0), mod);
LModSelfI *lir = new(alloc()) LModSelfI(useRegisterAtStart(mod->lhs()));
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
return false;
return define(lir, mod);
}
LModI *lir = new(alloc()) LModI(useFixedAtStart(mod->lhs(), eax),
LModI *lir = new(alloc()) LModI(useRegister(mod->lhs()),
useRegister(mod->rhs()),
tempFixed(eax));
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
@ -237,18 +208,7 @@ LIRGeneratorX86Shared::visitAsmJSNeg(MAsmJSNeg *ins)
bool
LIRGeneratorX86Shared::lowerUDiv(MDiv *div)
{
// Optimize x/x. The comments in lowerDivI apply here as well.
if (div->lhs() == div->rhs()) {
if (!div->canBeDivideByZero())
return define(new(alloc()) LInteger(1), div);
LDivSelfI *lir = new(alloc()) LDivSelfI(useRegisterAtStart(div->lhs()));
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
return false;
return define(lir, div);
}
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useFixedAtStart(div->lhs(), eax),
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useRegister(div->lhs()),
useRegister(div->rhs()),
tempFixed(edx));
if (div->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
@ -259,18 +219,7 @@ LIRGeneratorX86Shared::lowerUDiv(MDiv *div)
bool
LIRGeneratorX86Shared::lowerUMod(MMod *mod)
{
// Optimize x%x. The comments in lowerModI apply here as well.
if (mod->lhs() == mod->rhs()) {
if (mod->isTruncated() || (mod->isUnsigned() && !mod->canBeDivideByZero()))
return define(new(alloc()) LInteger(0), mod);
LModSelfI *lir = new(alloc()) LModSelfI(useRegisterAtStart(mod->lhs()));
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))
return false;
return define(lir, mod);
}
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useFixedAtStart(mod->lhs(), eax),
LUDivOrMod *lir = new(alloc()) LUDivOrMod(useRegister(mod->lhs()),
useRegister(mod->rhs()),
tempFixed(eax));
if (mod->fallible() && !assignSnapshot(lir, Bailout_BaselineInfo))

Просмотреть файл

@ -13,10 +13,8 @@
_(UnboxFloatingPoint) \
_(DivI) \
_(DivPowTwoI) \
_(DivSelfI) \
_(ModI) \
_(ModPowTwoI) \
_(ModSelfI) \
_(PowHalfD) \
_(AsmJSUInt32ToDouble) \
_(AsmJSUInt32ToFloat32) \

Просмотреть файл

@ -14,10 +14,8 @@
_(BoxFloatingPoint) \
_(DivI) \
_(DivPowTwoI) \
_(DivSelfI) \
_(ModI) \
_(ModPowTwoI) \
_(ModSelfI) \
_(PowHalfD) \
_(AsmJSUInt32ToDouble) \
_(AsmJSUInt32ToFloat32) \

Просмотреть файл

@ -636,12 +636,18 @@ JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
#endif
JS_PUBLIC_API(JSRuntime *)
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads)
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads, JSRuntime *parentRuntime)
{
MOZ_ASSERT(jsInitState == Running,
"must call JS_Init prior to creating any JSRuntimes");
JSRuntime *rt = js_new<JSRuntime>(useHelperThreads);
// Any parent runtime should be the topmost parent. This assert
// isn't required for correctness, but ensuring that the parent
// runtime is not destroyed before this one is more easily done
// for the main runtime in the process.
JS_ASSERT_IF(parentRuntime, !parentRuntime->parentRuntime);
JSRuntime *rt = js_new<JSRuntime>(parentRuntime, useHelperThreads);
if (!rt)
return nullptr;
@ -807,6 +813,13 @@ JS_GetRuntime(JSContext *cx)
return cx->runtime();
}
JS_PUBLIC_API(JSRuntime *)
JS_GetParentRuntime(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
return rt->parentRuntime ? rt->parentRuntime : nullptr;
}
JS_PUBLIC_API(JSContext *)
JS_ContextIterator(JSRuntime *rt, JSContext **iterp)
{
@ -1160,7 +1173,7 @@ LookupStdName(JSRuntime *rt, HandleString name, const JSStdName *table)
for (unsigned i = 0; !table[i].isSentinel(); i++) {
if (table[i].isDummy())
continue;
JSAtom *atom = AtomStateOffsetToName(rt->atomState, table[i].atomOffset);
JSAtom *atom = AtomStateOffsetToName(*rt->commonNames, table[i].atomOffset);
MOZ_ASSERT(atom);
if (name == atom)
return &table[i];
@ -1265,7 +1278,7 @@ JS_ResolveStandardClass(JSContext *cx, HandleObject obj, HandleId id, bool *reso
RootedString idstr(cx, JSID_TO_STRING(id));
/* Check whether we're resolving 'undefined', and define it if so. */
JSAtom *undefinedAtom = rt->atomState.undefined;
JSAtom *undefinedAtom = cx->names().undefined;
if (idstr == undefinedAtom) {
*resolved = true;
return JSObject::defineProperty(cx, obj, undefinedAtom->asPropertyName(),

Просмотреть файл

@ -1289,7 +1289,8 @@ extern JS_PUBLIC_API(void)
JS_ShutDown(void);
extern JS_PUBLIC_API(JSRuntime *)
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads);
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads,
JSRuntime *parentRuntime = nullptr);
extern JS_PUBLIC_API(void)
JS_DestroyRuntime(JSRuntime *rt);
@ -1312,6 +1313,9 @@ JS_GetRuntimePrivate(JSRuntime *rt);
extern JS_PUBLIC_API(JSRuntime *)
JS_GetRuntime(JSContext *cx);
extern JS_PUBLIC_API(JSRuntime *)
JS_GetParentRuntime(JSContext *cx);
JS_PUBLIC_API(void)
JS_SetRuntimePrivate(JSRuntime *rt, void *data);

Просмотреть файл

@ -3277,8 +3277,7 @@ js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values,
}
ArrayObject *
js::NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
JSObject *templateObject)
js::NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject)
{
gc::AllocKind allocKind = GuessArrayGCKind(length);
JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
@ -3300,9 +3299,6 @@ js::NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value
if (!EnsureNewArrayElements(cx, arr, length))
return nullptr;
arr->setDenseInitializedLength(length);
arr->initDenseElements(0, values, length);
probes::CreateObject(cx, arr);
return arr;

Просмотреть файл

@ -70,13 +70,10 @@ extern ArrayObject *
NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, JSObject *proto = nullptr,
NewObjectKind newKind = GenericObject);
/*
* Create a dense array based on templateObject from the given array values,
* which must be rooted.
*/
/* Create a dense array based on templateObject with the given length. */
extern ArrayObject *
NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
JSObject *templateObject);
NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject);
/*
* Determines whether a write to the given element on |obj| should fail because
* |obj| is an Array with a non-writable length, and writing that element would

Просмотреть файл

@ -104,37 +104,9 @@ const char js_void_str[] = "void";
const char js_while_str[] = "while";
const char js_with_str[] = "with";
/*
* For a browser build from 2007-08-09 after the browser starts up there are
* just 55 double atoms, but over 15000 string atoms. Not to penalize more
* economical embeddings allocating too much memory initially we initialize
* atomized strings with just 1K entries.
*/
#define JS_STRING_HASH_COUNT 1024
bool
js::InitAtoms(JSRuntime *rt)
{
AutoLockForExclusiveAccess lock(rt);
return rt->atoms().init(JS_STRING_HASH_COUNT);
}
void
js::FinishAtoms(JSRuntime *rt)
{
AtomSet &atoms = rt->atoms();
if (!atoms.initialized()) {
/*
* We are called with uninitialized state when JS_NewRuntime fails and
* calls JS_DestroyRuntime on a partially initialized runtime.
*/
return;
}
FreeOp fop(rt, false);
for (AtomSet::Range r = atoms.all(); !r.empty(); r.popFront())
r.front().asPtr()->finalize(&fop);
}
// Use a low initial capacity for atom hash tables to avoid penalizing runtimes
// which create a small number of atoms.
static const uint32_t JS_STRING_HASH_COUNT = 64;
struct CommonNameInfo
{
@ -143,8 +115,28 @@ struct CommonNameInfo
};
bool
js::InitCommonNames(JSContext *cx)
JSRuntime::initializeAtoms(JSContext *cx)
{
atoms_ = cx->new_<AtomSet>();
if (!atoms_ || !atoms_->init(JS_STRING_HASH_COUNT))
return false;
if (parentRuntime) {
staticStrings = parentRuntime->staticStrings;
commonNames = parentRuntime->commonNames;
emptyString = parentRuntime->emptyString;
permanentAtoms = parentRuntime->permanentAtoms;
return true;
}
permanentAtoms = cx->new_<AtomSet>();
if (!permanentAtoms || !permanentAtoms->init(JS_STRING_HASH_COUNT))
return false;
staticStrings = cx->new_<StaticStrings>();
if (!staticStrings || !staticStrings->init(cx))
return false;
static const CommonNameInfo cachedNames[] = {
#define COMMON_NAME_INFO(idpart, id, text) { js_##idpart##_str, sizeof(text) - 1 },
FOR_EACH_COMMON_PROPERTYNAME(COMMON_NAME_INFO)
@ -154,26 +146,45 @@ js::InitCommonNames(JSContext *cx)
#undef COMMON_NAME_INFO
};
FixedHeapPtr<PropertyName> *names = &cx->runtime()->firstCachedName;
commonNames = cx->new_<JSAtomState>();
if (!commonNames)
return false;
FixedHeapPtr<PropertyName> *names = reinterpret_cast<FixedHeapPtr<PropertyName> *>(commonNames);
for (size_t i = 0; i < ArrayLength(cachedNames); i++, names++) {
JSAtom *atom = Atomize(cx, cachedNames[i].str, cachedNames[i].length, InternAtom);
if (!atom)
return false;
names->init(atom->asPropertyName());
}
JS_ASSERT(uintptr_t(names) == uintptr_t(&cx->runtime()->atomState + 1));
JS_ASSERT(uintptr_t(names) == uintptr_t(commonNames + 1));
cx->runtime()->emptyString = cx->names().empty;
emptyString = commonNames->empty;
return true;
}
void
js::FinishCommonNames(JSRuntime *rt)
JSRuntime::finishAtoms()
{
rt->emptyString = nullptr;
#ifdef DEBUG
memset(&rt->atomState, JS_FREE_PATTERN, sizeof(JSAtomState));
#endif
if (atoms_)
js_delete(atoms_);
if (!parentRuntime) {
if (staticStrings)
js_delete(staticStrings);
if (commonNames)
js_delete(commonNames);
if (permanentAtoms)
js_delete(permanentAtoms);
}
atoms_ = nullptr;
staticStrings = nullptr;
commonNames = nullptr;
permanentAtoms = nullptr;
emptyString = nullptr;
}
void
@ -194,21 +205,70 @@ js::MarkAtoms(JSTracer *trc)
}
void
js::SweepAtoms(JSRuntime *rt)
js::MarkPermanentAtoms(JSTracer *trc)
{
for (AtomSet::Enum e(rt->atoms()); !e.empty(); e.popFront()) {
JSRuntime *rt = trc->runtime;
// Permanent atoms only need to be marked in the runtime which owns them.
if (rt->parentRuntime)
return;
// Static strings are not included in the permanent atoms table.
if (rt->staticStrings)
rt->staticStrings->trace(trc);
if (rt->permanentAtoms) {
for (AtomSet::Enum e(*rt->permanentAtoms); !e.empty(); e.popFront()) {
const AtomStateEntry &entry = e.front();
JSAtom *atom = entry.asPtr();
MarkPermanentAtom(trc, atom, "permanent_table");
}
}
}
void
JSRuntime::sweepAtoms()
{
if (!atoms_)
return;
for (AtomSet::Enum e(*atoms_); !e.empty(); e.popFront()) {
AtomStateEntry entry = e.front();
JSAtom *atom = entry.asPtr();
bool isDying = IsStringAboutToBeFinalized(&atom);
/* Pinned or interned key cannot be finalized. */
JS_ASSERT_IF(rt->hasContexts() && entry.isTagged(), !isDying);
JS_ASSERT_IF(hasContexts() && entry.isTagged(), !isDying);
if (isDying)
e.removeFront();
}
}
bool
JSRuntime::transformToPermanentAtoms()
{
JS_ASSERT(!parentRuntime);
// All static strings were created as permanent atoms, now move the contents
// of the atoms table into permanentAtoms and mark each as permanent.
JS_ASSERT(permanentAtoms && permanentAtoms->empty());
AtomSet *temp = atoms_;
atoms_ = permanentAtoms;
permanentAtoms = temp;
for (AtomSet::Enum e(*permanentAtoms); !e.empty(); e.popFront()) {
AtomStateEntry entry = e.front();
JSAtom *atom = entry.asPtr();
atom->morphIntoPermanentAtom();
}
return true;
}
bool
AtomIsInterned(JSContext *cx, JSAtom *atom)
{
@ -216,9 +276,16 @@ AtomIsInterned(JSContext *cx, JSAtom *atom)
if (StaticStrings::isStatic(atom))
return true;
AtomHasher::Lookup lookup(atom);
/* Likewise, permanent strings are considered to be interned. */
AtomSet::Ptr p = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
if (p)
return true;
AutoLockForExclusiveAccess lock(cx);
AtomSet::Ptr p = cx->runtime()->atoms().lookup(atom);
p = cx->runtime()->atoms().lookup(lookup);
if (!p)
return false;
@ -241,6 +308,14 @@ AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, In
return s;
}
AtomHasher::Lookup lookup(tbchars, length);
AtomSet::Ptr pp = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
if (pp) {
js_free(tbchars);
return pp->asPtr();
}
AutoLockForExclusiveAccess lock(cx);
/*
@ -250,7 +325,7 @@ AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, In
* GC will potentially free some table entries.
*/
AtomSet& atoms = cx->atoms();
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(tbchars, length));
AtomSet::AddPtr p = atoms.lookupForAdd(lookup);
SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */
if (p) {
JSAtom *atom = p->asPtr();
@ -270,8 +345,7 @@ AtomizeAndTakeOwnership(ExclusiveContext *cx, jschar *tbchars, size_t length, In
JSAtom *atom = flat->morphAtomizedStringIntoAtom();
if (!atoms.relookupOrAdd(p, AtomHasher::Lookup(tbchars, length),
AtomStateEntry(atom, bool(ib)))) {
if (!atoms.relookupOrAdd(p, lookup, AtomStateEntry(atom, bool(ib)))) {
js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
return nullptr;
}
@ -287,6 +361,12 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length,
if (JSAtom *s = cx->staticStrings().lookup(tbchars, length))
return s;
AtomHasher::Lookup lookup(tbchars, length);
AtomSet::Ptr pp = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
if (pp)
return pp->asPtr();
/*
* If a GC occurs at js_NewStringCopy then |p| will still have the correct
* hash, allowing us to avoid rehashing it. Even though the hash is
@ -297,7 +377,7 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length,
AutoLockForExclusiveAccess lock(cx);
AtomSet& atoms = cx->atoms();
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(tbchars, length));
AtomSet::AddPtr p = atoms.lookupForAdd(lookup);
SkipRoot skipHash(cx, &p); /* Prevent the hash from being poisoned. */
if (p) {
JSAtom *atom = p->asPtr();
@ -315,8 +395,7 @@ AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length,
JSAtom *atom = flat->morphAtomizedStringIntoAtom();
if (!atoms.relookupOrAdd(p, AtomHasher::Lookup(tbchars, length),
AtomStateEntry(atom, bool(ib)))) {
if (!atoms.relookupOrAdd(p, lookup, AtomStateEntry(atom, bool(ib)))) {
js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
return nullptr;
}
@ -334,9 +413,16 @@ js::AtomizeString(ExclusiveContext *cx, JSString *str,
if (ib != InternAtom || js::StaticStrings::isStatic(&atom))
return &atom;
AtomHasher::Lookup lookup(&atom);
/* Likewise, permanent atoms are always interned. */
AtomSet::Ptr p = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
if (p)
return &atom;
AutoLockForExclusiveAccess lock(cx);
AtomSet::Ptr p = cx->atoms().lookup(AtomHasher::Lookup(&atom));
p = cx->atoms().lookup(lookup);
JS_ASSERT(p); /* Non-static atom must exist in atom state set. */
JS_ASSERT(p->asPtr() == &atom);
JS_ASSERT(ib == InternAtom);

Просмотреть файл

@ -89,11 +89,17 @@ struct AtomHasher
size_t length;
const JSAtom *atom; /* Optional. */
Lookup(const jschar *chars, size_t length) : chars(chars), length(length), atom(nullptr) {}
HashNumber hash;
Lookup(const jschar *chars, size_t length)
: chars(chars), length(length), atom(nullptr)
{
hash = mozilla::HashString(chars, length);
}
inline Lookup(const JSAtom *atom);
};
static HashNumber hash(const Lookup &l) { return mozilla::HashString(l.chars, l.length); }
static HashNumber hash(const Lookup &l) { return l.hash; }
static inline bool match(const AtomStateEntry &entry, const Lookup &lookup);
static void rekey(AtomStateEntry &k, const AtomStateEntry& newKey) { k = newKey; }
};
@ -162,21 +168,6 @@ namespace js {
extern const char * const TypeStrings[];
/*
* Initialize atom state. Return true on success, false on failure to allocate
* memory. The caller must zero rt->atomState before calling this function and
* only call it after js_InitGC successfully returns.
*/
extern bool
InitAtoms(JSRuntime *rt);
/*
* Free and clear atom state including any interned string atoms. This
* function must be called before js_FinishGC.
*/
extern void
FinishAtoms(JSRuntime *rt);
/*
* Atom tracing and garbage collection hooks.
*/
@ -184,13 +175,7 @@ extern void
MarkAtoms(JSTracer *trc);
extern void
SweepAtoms(JSRuntime *rt);
extern bool
InitCommonNames(JSContext *cx);
extern void
FinishCommonNames(JSRuntime *rt);
MarkPermanentAtoms(JSTracer *trc);
/* N.B. must correspond to boolean tagging behavior. */
enum InternBehavior

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше