Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Gurzau Raul 2019-03-11 18:56:50 +02:00
commit 682327e500
94 changed files with 1155 additions and 498 deletions

View File

@ -158,3 +158,4 @@ c44fbdd5173548c9035256dda8fd3512f67118a8 FIREFOX_NIGHTLY_64_END
3386ff76878d83496bb822d09115c77472808b53 FIREFOX_NIGHTLY_65_END
254bd88c107271f3d1c2ca9969acc0ed507f0a8d FIREFOX_BETA_66_BASE
5d9c5aa981a5b824e6132c923c2f201b3fa49397 FIREFOX_NIGHTLY_66_END
f4c23517cec8626038a915bfe3bc7c0e1f6af55d FIREFOX_BETA_67_BASE

View File

@ -489,11 +489,11 @@ pref("browser.tabs.remote.separatePrivilegedContentProcess", true);
// Turn on HTTP response process selection.
pref("browser.tabs.remote.useHTTPResponseProcessSelection", true);
// Unload tabs on low-memory on nightly.
#ifdef RELEASE_OR_BETA
pref("browser.tabs.unloadOnLowMemory", false);
#else
// Unload tabs on low-memory on nightly and beta.
#ifdef EARLY_BETA_OR_EARLIER
pref("browser.tabs.unloadOnLowMemory", true);
#else
pref("browser.tabs.unloadOnLowMemory", false);
#endif
pref("browser.ctrlTab.recentlyUsedOrder", true);

View File

@ -11,6 +11,10 @@
const PERMISSIONS_PAGE = "https://example.com/browser/browser/base/content/test/permissions/permissions.html";
// The DevEdition has the DevTools button in the toolbar by default. Remove it
// to prevent branch-specific rules what button should be focused.
CustomizableUI.removeWidgetFromArea("developer-button");
async function expectFocusAfterKey(aKey, aFocus, aAncestorOk = false) {
let res = aKey.match(/^(Shift\+)?(?:(.)|(.+))$/);
let shift = Boolean(res[1]);
@ -230,3 +234,7 @@ add_task(async function testArrowsOverflowButton() {
await expectFocusAfterKey("ArrowLeft", "sidebar-button");
});
});
registerCleanupFunction(async function resetToolbar() {
await CustomizableUI.reset();
});

View File

@ -18,7 +18,7 @@ pref("app.update.url.manual", "https://www.mozilla.org/firefox/aurora/");
// supplied in the "An update is available" page of the update wizard.
pref("app.update.url.details", "https://www.mozilla.org/firefox/aurora/");
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%beta/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
// The number of days a binary is permitted to be old
// without checking for an update. This assumes that

View File

@ -17,12 +17,12 @@ pref("app.update.promptWaitTime", 691200);
#if MOZ_UPDATE_CHANNEL == beta
pref("app.update.url.manual", "https://www.mozilla.org/firefox/beta");
pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/beta/notes");
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%beta/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
#else
pref("app.update.url.manual", "https://www.mozilla.org/firefox/");
pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes");
#endif
pref("app.releaseNotesURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/releasenotes/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=whatsnew");
#endif
// The number of days a binary is permitted to be old
// without checking for an update. This assumes that

View File

@ -921,9 +921,8 @@ class UrlbarInput {
}
}
// TODO This should probably be handed via input.
// Ensure the start of the URL is visible for usability reasons.
// this.selectionStart = this.selectionEnd = 0;
this.selectionStart = this.selectionEnd = 0;
this.closePopup();
}

View File

@ -50,6 +50,7 @@ subsuite = clipboard
[browser_privateBrowsingWindowChange.js]
skip-if = debug # Bug 1532034 - Leaks in debug mode.
[browser_raceWithTabs.js]
skip-if = os == "linux" # Bug 1533807
[browser_redirect_error.js]
support-files = redirect_error.sjs
[browser_remotetab.js]

View File

@ -73,6 +73,7 @@ subsuite = clipboard
[../browser/browser_populateAfterPushState.js]
[../browser/browser_privateBrowsingWindowChange.js]
[../browser/browser_raceWithTabs.js]
skip-if = os == "linux" # Bug 1533807
[../browser/browser_redirect_error.js]
support-files = ../browser/redirect_error.sjs
[../browser/browser_remotetab.js]

View File

@ -50,6 +50,7 @@ class App extends Component {
currentReverseSearchEntry: PropTypes.string,
reverseSearchInputVisible: PropTypes.bool,
reverseSearchInitialValue: PropTypes.string,
editorMode: PropTypes.bool,
};
}
@ -200,12 +201,16 @@ class App extends Component {
closeSplitConsole,
jstermCodeMirror,
reverseSearchInitialValue,
editorMode,
} = this.props;
const classNames = ["webconsole-app"];
if (jstermCodeMirror) {
classNames.push("jsterm-cm");
}
if (editorMode) {
classNames.push("jsterm-editor");
}
// Render the entire Console panel. The panel consists
// from the following parts:
@ -242,6 +247,7 @@ class App extends Component {
serviceContainer,
onPaste: this.onPaste,
codeMirrorEnabled: jstermCodeMirror,
editorMode,
}),
ReverseSearchInput({
setInputValue: serviceContainer.setInputValue,
@ -267,6 +273,7 @@ const mapStateToProps = state => ({
notifications: getAllNotifications(state),
reverseSearchInputVisible: state.ui.reverseSearchInputVisible,
reverseSearchInitialValue: state.ui.reverseSearchInitialValue,
editorMode: state.ui.editor,
});
const mapDispatchToProps = dispatch => ({

View File

@ -79,6 +79,8 @@ class JSTerm extends Component {
autocompleteUpdate: PropTypes.func.isRequired,
// Data to be displayed in the autocomplete popup.
autocompleteData: PropTypes.object.isRequired,
// Is the input in editor mode.
editorMode: PropTypes.bool,
};
}
@ -592,7 +594,11 @@ class JSTerm extends Component {
this.props.appendToHistory(executeString);
WebConsoleUtils.usageCount++;
this._setValue("");
if (!this.props.editorMode) {
this._setValue("");
}
this.clearCompletion();
let selectedNodeActor = null;

View File

@ -65,6 +65,8 @@ const prefs = {
PERSIST: "devtools.webconsole.persistlog",
// Max number of entries in history list.
INPUT_HISTORY_COUNT: "devtools.webconsole.inputHistoryCount",
// Is editor mode enabled.
EDITOR: "devtools.webconsole.input.editor",
},
FEATURES: {
// We use the same pref to enable the sidebar on webconsole and browser console.

View File

@ -31,6 +31,7 @@ const UiState = (overrides) => Object.freeze(Object.assign({
closeButtonVisible: false,
reverseSearchInputVisible: false,
reverseSearchInitialValue: "",
editor: false,
}, overrides));
function ui(state = UiState(), action) {

View File

@ -71,6 +71,7 @@ function configureStore(webConsoleUI, options = {}) {
ui: UiState({
networkMessageActiveTabId: "headers",
persistLogs: getBoolPref(PREFS.UI.PERSIST),
editor: getBoolPref(PREFS.UI.EDITOR),
}),
};

View File

@ -197,6 +197,7 @@ skip-if = verify
[browser_jsterm_ctrl_key_nav.js]
skip-if = os != 'mac' # The tested ctrl+key shortcuts are OSX only
[browser_jsterm_document_no_xray.js]
[browser_jsterm_editor_execute.js]
[browser_jsterm_error_docs.js]
[browser_jsterm_error_outside_valid_range.js]
[browser_jsterm_focus_reload.js]

View File

@ -0,0 +1,30 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that user input is not cleared when 'devtools.webconsole.input.editor'
// is set to true.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1519313
"use strict";
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 1519313";
add_task(async function() {
await pushPref("devtools.webconsole.input.editor", true);
// Run test with legacy JsTerm
await pushPref("devtools.webconsole.jsterm.codeMirror", false);
await performTests();
// And then run it with the CodeMirror-powered one.
await pushPref("devtools.webconsole.jsterm.codeMirror", true);
await performTests();
});
async function performTests() {
const hud = await openNewTabAndConsole(TEST_URI);
const {jsterm} = hud;
const expression = `x = 10`;
setInputValue(hud, expression);
await jsterm.execute();
is(getInputValue(hud), expression, "input line is not cleared after submit");
}

View File

@ -345,39 +345,41 @@ void MediaEngineTabVideoSource::Draw() {
return;
}
layers::TextureClientAutoLock autoLock(texture,
layers::OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
NS_WARNING("Failed to lock TextureClient");
return;
}
{
layers::TextureClientAutoLock autoLock(texture,
layers::OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
NS_WARNING("Failed to lock TextureClient");
return;
}
RefPtr<gfx::DrawTarget> dt = texture->BorrowDrawTarget();
if (!dt || !dt->IsValid()) {
NS_WARNING("Failed to borrow DrawTarget");
return;
}
RefPtr<gfx::DrawTarget> dt = texture->BorrowDrawTarget();
if (!dt || !dt->IsValid()) {
NS_WARNING("Failed to borrow DrawTarget");
return;
}
if (mWindow) {
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
MOZ_ASSERT(context); // already checked the draw target above
context->SetMatrix(context->CurrentMatrix().PreScale(
(((float)size.width) / mViewportWidth),
(((float)size.height) / mViewportHeight)));
if (mWindow) {
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
MOZ_ASSERT(context); // already checked the draw target above
context->SetMatrix(context->CurrentMatrix().PreScale(
(((float)size.width) / mViewportWidth),
(((float)size.height) / mViewportHeight)));
nscolor bgColor = NS_RGB(255, 255, 255);
uint32_t renderDocFlags =
mScrollWithPage ? 0
: (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
nsIPresShell::RENDER_DOCUMENT_RELATIVE);
nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
NS_ENSURE_SUCCESS_VOID(
presShell->RenderDocument(r, renderDocFlags, bgColor, context));
} else {
dt->ClearRect(Rect(0, 0, size.width, size.height));
nscolor bgColor = NS_RGB(255, 255, 255);
uint32_t renderDocFlags =
mScrollWithPage ? 0
: (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
nsIPresShell::RENDER_DOCUMENT_RELATIVE);
nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
NS_ENSURE_SUCCESS_VOID(
presShell->RenderDocument(r, renderDocFlags, bgColor, context));
} else {
dt->ClearRect(Rect(0, 0, size.width, size.height));
}
}
MutexAutoLock lock(mMutex);

View File

@ -203,6 +203,7 @@ namespace JS {
_(CantInlineBigCaller) \
_(CantInlineBigCallee) \
_(CantInlineBigCalleeInlinedBytecodeLength) \
_(CantInlineCrossRealm) \
_(CantInlineNotHot) \
_(CantInlineNotInDispatch) \
_(CantInlineUnreachable) \

View File

@ -10,6 +10,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Maybe.h"
#include "mozilla/TextUtils.h"
#include <algorithm>
@ -57,6 +58,7 @@ using mozilla::CeilingLog2;
using mozilla::CheckedInt;
using mozilla::DebugOnly;
using mozilla::IsAsciiDigit;
using mozilla::Maybe;
using JS::AutoCheckCannotGC;
using JS::IsArrayAnswer;
@ -3869,6 +3871,14 @@ bool js::array_construct(JSContext* cx, unsigned argc, Value* vp) {
ArrayObject* js::ArrayConstructorOneArg(JSContext* cx, HandleObjectGroup group,
int32_t lengthInt) {
// Ion can call this with a group from a different realm when calling
// another realm's Array constructor.
Maybe<AutoRealm> ar;
if (cx->realm() != group->realm()) {
MOZ_ASSERT(cx->compartment() == group->compartment());
ar.emplace(cx, group);
}
if (lengthInt < 0) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_BAD_ARRAY_LENGTH);
@ -3876,7 +3886,9 @@ ArrayObject* js::ArrayConstructorOneArg(JSContext* cx, HandleObjectGroup group,
}
uint32_t length = uint32_t(lengthInt);
return NewPartlyAllocatedArrayTryUseGroup(cx, group, length);
ArrayObject* res = NewPartlyAllocatedArrayTryUseGroup(cx, group, length);
MOZ_ASSERT_IF(res, res->realm() == group->realm());
return res;
}
static JSObject* CreateArrayPrototype(JSContext* cx, JSProtoKey key) {
@ -4064,7 +4076,7 @@ static MOZ_ALWAYS_INLINE ArrayObject* NewArray(
AutoSetNewObjectMetadata metadata(cx);
RootedArrayObject arr(
cx, ArrayObject::createArray(
cx, allocKind, GetInitialHeap(newKind, group),
cx, allocKind, GetInitialHeap(newKind, &ArrayObject::class_),
shape, group, length, metadata));
if (!arr) {
return nullptr;
@ -4153,7 +4165,7 @@ ArrayObject* js::NewDenseFullyAllocatedArrayWithTemplate(
RootedObjectGroup group(cx, templateObject->group());
RootedShape shape(cx, templateObject->as<ArrayObject>().lastProperty());
gc::InitialHeap heap = GetInitialHeap(GenericObject, group);
gc::InitialHeap heap = GetInitialHeap(GenericObject, &ArrayObject::class_);
Rooted<ArrayObject*> arr(
cx, ArrayObject::createArray(cx, allocKind, heap, shape, group, length,
metadata));
@ -4171,11 +4183,10 @@ ArrayObject* js::NewDenseFullyAllocatedArrayWithTemplate(
}
ArrayObject* js::NewDenseCopyOnWriteArray(JSContext* cx,
HandleArrayObject templateObject) {
HandleArrayObject templateObject,
gc::InitialHeap heap) {
MOZ_ASSERT(!gc::IsInsideNursery(templateObject));
gc::InitialHeap heap = GetInitialHeap(GenericObject, templateObject->group());
ArrayObject* arr =
ArrayObject::createCopyOnWriteArray(cx, heap, templateObject);
if (!arr) {
@ -4328,13 +4339,23 @@ ArrayObject* js::NewCopiedArrayForCallingAllocationSite(
ArrayObject* js::NewArrayWithGroup(JSContext* cx, uint32_t length,
HandleObjectGroup group,
bool convertDoubleElements) {
// Ion can call this with a group from a different realm when calling
// another realm's Array constructor.
Maybe<AutoRealm> ar;
if (cx->realm() != group->realm()) {
MOZ_ASSERT(cx->compartment() == group->compartment());
ar.emplace(cx, group);
}
ArrayObject* res = NewFullyAllocatedArrayTryUseGroup(cx, group, length);
if (!res) {
return nullptr;
}
if (convertDoubleElements) {
res->setShouldConvertDoubleElements();
}
return res;
}

View File

@ -79,7 +79,8 @@ extern ArrayObject* NewDenseFullyAllocatedArrayWithTemplate(
// Create a dense array with the same copy-on-write elements as another object.
extern ArrayObject* NewDenseCopyOnWriteArray(JSContext* cx,
HandleArrayObject templateObject);
HandleArrayObject templateObject,
gc::InitialHeap heap);
extern ArrayObject* NewFullyAllocatedArrayTryUseGroup(
JSContext* cx, HandleObjectGroup group, size_t length,

View File

@ -1553,7 +1553,7 @@ static MOZ_MUST_USE JSObject* ReadableStreamCreateReadResult(
NativeObject* obj;
JS_TRY_VAR_OR_RETURN_NULL(
cx, obj,
NativeObject::createWithTemplate(cx, templateObject));
NativeObject::createWithTemplate(cx, gc::DefaultHeap, templateObject));
// Step 5: Perform CreateDataProperty(obj, "value", value).
obj->setSlot(Realm::IterResultObjectValueSlot, value);

View File

@ -2317,7 +2317,7 @@ bool TypedObject::construct(JSContext* cx, unsigned int argc, Value* vp) {
MOZ_ASSERT(::IsTypedObjectClass(clasp));
JSObject* obj =
js::Allocate<JSObject>(cx, kind, /* nDynamicSlots = */ 0, heap, clasp);
js::AllocateObject(cx, kind, /* nDynamicSlots = */ 0, heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}

View File

@ -25,11 +25,9 @@
using namespace js;
using namespace gc;
template <typename T, AllowGC allowGC /* = CanGC */>
JSObject* js::Allocate(JSContext* cx, AllocKind kind, size_t nDynamicSlots,
InitialHeap heap, const Class* clasp) {
static_assert(mozilla::IsConvertible<T*, JSObject*>::value,
"must be JSObject derived");
template <AllowGC allowGC /* = CanGC */>
JSObject* js::AllocateObject(JSContext* cx, AllocKind kind, size_t nDynamicSlots,
InitialHeap heap, const Class* clasp) {
MOZ_ASSERT(IsObjectAllocKind(kind));
size_t thingSize = Arena::thingSize(kind);
@ -77,16 +75,16 @@ JSObject* js::Allocate(JSContext* cx, AllocKind kind, size_t nDynamicSlots,
return GCRuntime::tryNewTenuredObject<allowGC>(cx, kind, thingSize,
nDynamicSlots);
}
template JSObject* js::Allocate<JSObject, NoGC>(JSContext* cx,
gc::AllocKind kind,
size_t nDynamicSlots,
gc::InitialHeap heap,
const Class* clasp);
template JSObject* js::Allocate<JSObject, CanGC>(JSContext* cx,
gc::AllocKind kind,
size_t nDynamicSlots,
gc::InitialHeap heap,
const Class* clasp);
template JSObject* js::AllocateObject<NoGC>(JSContext* cx,
gc::AllocKind kind,
size_t nDynamicSlots,
gc::InitialHeap heap,
const Class* clasp);
template JSObject* js::AllocateObject<CanGC>(JSContext* cx,
gc::AllocKind kind,
size_t nDynamicSlots,
gc::InitialHeap heap,
const Class* clasp);
// Attempt to allocate a new JSObject out of the nursery. If there is not
// enough room in the nursery or there is an OOM, this method will return
@ -177,7 +175,7 @@ JSString* GCRuntime::tryNewNurseryString(JSContext* cx, size_t thingSize,
}
template <typename StringAllocT, AllowGC allowGC /* = CanGC */>
StringAllocT* js::AllocateString(JSContext* cx, InitialHeap heap) {
StringAllocT* js::AllocateStringImpl(JSContext* cx, InitialHeap heap) {
static_assert(mozilla::IsConvertible<StringAllocT*, JSString*>::value,
"must be JSString derived");
@ -224,10 +222,10 @@ StringAllocT* js::AllocateString(JSContext* cx, InitialHeap heap) {
#define DECL_ALLOCATOR_INSTANCES(allocKind, traceKind, type, sizedType, \
bgfinal, nursery, compact) \
template type* js::AllocateString<type, NoGC>(JSContext * cx, \
InitialHeap heap); \
template type* js::AllocateString<type, CanGC>(JSContext * cx, \
InitialHeap heap);
template type* js::AllocateStringImpl<type, NoGC>(JSContext * cx, \
InitialHeap heap); \
template type* js::AllocateStringImpl<type, CanGC>(JSContext * cx, \
InitialHeap heap);
FOR_EACH_NURSERY_STRING_ALLOCKIND(DECL_ALLOCATOR_INSTANCES)
#undef DECL_ALLOCATOR_INSTANCES

View File

@ -17,47 +17,52 @@ namespace js {
struct Class;
// Allocate a new GC thing. After a successful allocation the caller must
// fully initialize the thing before calling any function that can potentially
// trigger GC. This will ensure that GC tracing never sees junk values stored
// in the partially initialized thing.
// Allocate a new GC thing that's not a JSObject or a string.
//
// After a successful allocation the caller must fully initialize the thing
// before calling any function that can potentially trigger GC. This will ensure
// that GC tracing never sees junk values stored in the partially initialized
// thing.
template <typename T, AllowGC allowGC = CanGC>
T* Allocate(JSContext* cx);
// Use for JSObject. A longer signature that includes additional information in
// support of various optimizations. If dynamic slots are requested they will be
// allocated and the pointer stored directly in |NativeObject::slots_|.
template <typename, AllowGC allowGC = CanGC>
JSObject* Allocate(JSContext* cx, gc::AllocKind kind, size_t nDynamicSlots,
gc::InitialHeap heap, const Class* clasp);
// Allocate a JSObject.
//
// A longer signature that includes additional information in support of various
// optimizations. If dynamic slots are requested they will be allocated and the
// pointer stored directly in |NativeObject::slots_|.
template <AllowGC allowGC = CanGC>
JSObject* AllocateObject(JSContext* cx, gc::AllocKind kind, size_t nDynamicSlots,
gc::InitialHeap heap, const Class* clasp);
// Internal function used for nursery-allocatable strings.
template <typename StringAllocT, AllowGC allowGC = CanGC>
StringAllocT* AllocateString(JSContext* cx, gc::InitialHeap heap);
StringAllocT* AllocateStringImpl(JSContext* cx, gc::InitialHeap heap);
// Allocate a string.
//
// Use for nursery-allocatable strings. Returns a value cast to the correct
// type.
template <typename StringT, AllowGC allowGC = CanGC>
StringT* Allocate(JSContext* cx, gc::InitialHeap heap) {
return static_cast<StringT*>(js::AllocateString<JSString, allowGC>(cx, heap));
StringT* AllocateString(JSContext* cx, gc::InitialHeap heap) {
return static_cast<StringT*>(AllocateStringImpl<JSString, allowGC>(cx, heap));
}
// Specialization for JSFatInlineString that must use a different allocation
// type. Note that we have to explicitly specialize for both values of AllowGC
// because partial function specialization is not allowed.
template <>
inline JSFatInlineString* Allocate<JSFatInlineString, CanGC>(
inline JSFatInlineString* AllocateString<JSFatInlineString, CanGC>(
JSContext* cx, gc::InitialHeap heap) {
return static_cast<JSFatInlineString*>(
js::AllocateString<JSFatInlineString, CanGC>(cx, heap));
js::AllocateStringImpl<JSFatInlineString, CanGC>(cx, heap));
}
template <>
inline JSFatInlineString* Allocate<JSFatInlineString, NoGC>(
inline JSFatInlineString* AllocateString<JSFatInlineString, NoGC>(
JSContext* cx, gc::InitialHeap heap) {
return static_cast<JSFatInlineString*>(
js::AllocateString<JSFatInlineString, NoGC>(cx, heap));
js::AllocateStringImpl<JSFatInlineString, NoGC>(cx, heap));
}
} // namespace js

View File

@ -2575,9 +2575,10 @@ bool BaselineCompilerCodeGen::emit_JSOP_NEWARRAY_COPYONWRITE() {
prepareVMCall();
pushArg(Imm32(gc::DefaultHeap));
pushArg(ImmGCPtr(obj));
using Fn = ArrayObject* (*)(JSContext*, HandleArrayObject);
using Fn = ArrayObject* (*)(JSContext*, HandleArrayObject, gc::InitialHeap);
if (!callVM<Fn, js::NewDenseCopyOnWriteArray>()) {
return false;
}

View File

@ -3668,8 +3668,9 @@ static bool TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub,
bool isCrossRealm = cx->realm() != fun->realm();
RootedObject templateObject(cx);
if (MOZ_LIKELY(!isSpread && !isSuper && !isCrossRealm)) {
if (MOZ_LIKELY(!isSpread && !isSuper)) {
CallArgs args = CallArgsFromVp(argc, vp);
AutoRealm ar(cx, fun);
if (!GetTemplateObjectForNative(cx, fun, args, &templateObject)) {
return false;
}

View File

@ -2402,12 +2402,12 @@ void CreateDependentString::generate(MacroAssembler& masm,
static void* AllocateString(JSContext* cx) {
AutoUnsafeCallWithABI unsafe;
return js::Allocate<JSString, NoGC>(cx, js::gc::TenuredHeap);
return js::AllocateString<JSString, NoGC>(cx, js::gc::TenuredHeap);
}
static void* AllocateFatInlineString(JSContext* cx) {
AutoUnsafeCallWithABI unsafe;
return js::Allocate<JSFatInlineString, NoGC>(cx, js::gc::TenuredHeap);
return js::AllocateString<JSFatInlineString, NoGC>(cx, js::gc::TenuredHeap);
}
void CreateDependentString::generateFallback(MacroAssembler& masm) {
@ -2443,8 +2443,8 @@ void CreateDependentString::generateFallback(MacroAssembler& masm) {
static void* CreateMatchResultFallbackFunc(JSContext* cx, gc::AllocKind kind,
size_t nDynamicSlots) {
AutoUnsafeCallWithABI unsafe;
return js::Allocate<JSObject, NoGC>(cx, kind, nDynamicSlots, gc::DefaultHeap,
&ArrayObject::class_);
return js::AllocateObject<NoGC>(cx, kind, nDynamicSlots, gc::DefaultHeap,
&ArrayObject::class_);
}
static void CreateMatchResultFallback(MacroAssembler& masm, Register object,
@ -6538,7 +6538,8 @@ void CodeGenerator::visitOutOfLineNewArray(OutOfLineNewArray* ool) {
masm.jump(ool->rejoin());
}
typedef ArrayObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject);
typedef ArrayObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject,
gc::InitialHeap);
static const VMFunction NewArrayCopyOnWriteInfo =
FunctionInfo<NewArrayCopyOnWriteFn>(js::NewDenseCopyOnWriteArray,
"NewDenseCopyOnWriteArray");
@ -6552,7 +6553,7 @@ void CodeGenerator::visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir) {
// If we have a template object, we can inline call object creation.
OutOfLineCode* ool =
oolCallVM(NewArrayCopyOnWriteInfo, lir,
ArgList(ImmGCPtr(templateObject)),
ArgList(ImmGCPtr(templateObject), Imm32(initialHeap)),
StoreRegisterTo(objReg));
TemplateObject templateObj(templateObject);

View File

@ -410,6 +410,12 @@ IonBuilder::InliningDecision IonBuilder::canInlineTarget(JSFunction* target,
return DontInline(nullptr, "Non-interpreted target");
}
// Never inline scripted cross-realm calls.
if (target->realm() != script()->realm()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineCrossRealm);
return DontInline(nullptr, "Cross-realm call");
}
if (info().analysisMode() != Analysis_DefiniteProperties) {
// If |this| or an argument has an empty resultTypeSet, don't bother
// inlining, as the call is currently unreachable due to incomplete type
@ -4265,12 +4271,6 @@ IonBuilder::InliningDecision IonBuilder::makeInliningDecision(
return InliningDecision_DontInline;
}
// Don't inline (native or scripted) cross-realm calls.
Realm* targetRealm = JS::GetObjectRealmOrNull(targetArg);
if (!targetRealm || targetRealm != script()->realm()) {
return InliningDecision_DontInline;
}
// Inlining non-function targets is handled by inlineNonFunctionCall().
if (!targetArg->is<JSFunction>()) {
return InliningDecision_Inline;

View File

@ -712,7 +712,7 @@ class IonBuilder : public MIRGenerator,
MIRType getInlineReturnType();
// Array natives.
InliningResult inlineArray(CallInfo& callInfo);
InliningResult inlineArray(CallInfo& callInfo, Realm* targetRealm);
InliningResult inlineArrayIsArray(CallInfo& callInfo);
InliningResult inlineArrayPopShift(CallInfo& callInfo,
MArrayPopShift::Mode mode);

View File

@ -49,6 +49,172 @@ using JS::TrackedOutcome;
namespace js {
namespace jit {
// Returns true if |native| can be inlined cross-realm. Especially inlined
// natives that can allocate objects or throw exceptions shouldn't be inlined
// cross-realm without a careful analysis because we might use the wrong realm!
//
// Note that self-hosting intrinsics are never called cross-realm. See the
// MOZ_CRASH below.
//
// If you are adding a new inlinable native, the safe thing is to |return false|
// here.
static bool CanInlineCrossRealm(InlinableNative native) {
switch (native) {
case InlinableNative::MathAbs:
case InlinableNative::MathFloor:
case InlinableNative::MathCeil:
case InlinableNative::MathRound:
case InlinableNative::MathClz32:
case InlinableNative::MathSqrt:
case InlinableNative::MathATan2:
case InlinableNative::MathHypot:
case InlinableNative::MathMax:
case InlinableNative::MathMin:
case InlinableNative::MathPow:
case InlinableNative::MathImul:
case InlinableNative::MathFRound:
case InlinableNative::MathTrunc:
case InlinableNative::MathSign:
case InlinableNative::MathSin:
case InlinableNative::MathTan:
case InlinableNative::MathCos:
case InlinableNative::MathExp:
case InlinableNative::MathLog:
case InlinableNative::MathASin:
case InlinableNative::MathATan:
case InlinableNative::MathACos:
case InlinableNative::MathLog10:
case InlinableNative::MathLog2:
case InlinableNative::MathLog1P:
case InlinableNative::MathExpM1:
case InlinableNative::MathCosH:
case InlinableNative::MathSinH:
case InlinableNative::MathTanH:
case InlinableNative::MathACosH:
case InlinableNative::MathASinH:
case InlinableNative::MathATanH:
case InlinableNative::MathCbrt:
case InlinableNative::Boolean:
return true;
case InlinableNative::Array:
// Cross-realm case handled by inlineArray.
return true;
case InlinableNative::MathRandom:
// RNG state is per-realm.
return false;
case InlinableNative::IntlGuardToCollator:
case InlinableNative::IntlGuardToDateTimeFormat:
case InlinableNative::IntlGuardToNumberFormat:
case InlinableNative::IntlGuardToPluralRules:
case InlinableNative::IntlGuardToRelativeTimeFormat:
case InlinableNative::IsRegExpObject:
case InlinableNative::RegExpMatcher:
case InlinableNative::RegExpSearcher:
case InlinableNative::RegExpTester:
case InlinableNative::RegExpPrototypeOptimizable:
case InlinableNative::RegExpInstanceOptimizable:
case InlinableNative::GetFirstDollarIndex:
case InlinableNative::IntrinsicNewArrayIterator:
case InlinableNative::IntrinsicNewStringIterator:
case InlinableNative::IntrinsicNewRegExpStringIterator:
case InlinableNative::IntrinsicStringReplaceString:
case InlinableNative::IntrinsicStringSplitString:
case InlinableNative::IntrinsicUnsafeSetReservedSlot:
case InlinableNative::IntrinsicUnsafeGetReservedSlot:
case InlinableNative::IntrinsicUnsafeGetObjectFromReservedSlot:
case InlinableNative::IntrinsicUnsafeGetInt32FromReservedSlot:
case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot:
case InlinableNative::IntrinsicUnsafeGetBooleanFromReservedSlot:
case InlinableNative::IntrinsicIsCallable:
case InlinableNative::IntrinsicIsConstructor:
case InlinableNative::IntrinsicToObject:
case InlinableNative::IntrinsicIsObject:
case InlinableNative::IntrinsicIsCrossRealmArrayConstructor:
case InlinableNative::IntrinsicToInteger:
case InlinableNative::IntrinsicToString:
case InlinableNative::IntrinsicIsConstructing:
case InlinableNative::IntrinsicSubstringKernel:
case InlinableNative::IntrinsicGuardToArrayIterator:
case InlinableNative::IntrinsicGuardToMapIterator:
case InlinableNative::IntrinsicGuardToSetIterator:
case InlinableNative::IntrinsicGuardToStringIterator:
case InlinableNative::IntrinsicGuardToRegExpStringIterator:
case InlinableNative::IntrinsicObjectHasPrototype:
case InlinableNative::IntrinsicFinishBoundFunctionInit:
case InlinableNative::IntrinsicIsPackedArray:
case InlinableNative::IntrinsicGuardToMapObject:
case InlinableNative::IntrinsicGetNextMapEntryForIterator:
case InlinableNative::IntrinsicGuardToSetObject:
case InlinableNative::IntrinsicGetNextSetEntryForIterator:
case InlinableNative::IntrinsicGuardToArrayBuffer:
case InlinableNative::IntrinsicArrayBufferByteLength:
case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength:
case InlinableNative::IntrinsicGuardToSharedArrayBuffer:
case InlinableNative::IntrinsicIsTypedArrayConstructor:
case InlinableNative::IntrinsicIsTypedArray:
case InlinableNative::IntrinsicIsPossiblyWrappedTypedArray:
case InlinableNative::IntrinsicPossiblyWrappedTypedArrayLength:
case InlinableNative::IntrinsicTypedArrayLength:
case InlinableNative::IntrinsicTypedArrayByteOffset:
case InlinableNative::IntrinsicTypedArrayElementShift:
case InlinableNative::IntrinsicSetDisjointTypedElements:
case InlinableNative::IntrinsicObjectIsTypedObject:
case InlinableNative::IntrinsicObjectIsTransparentTypedObject:
case InlinableNative::IntrinsicObjectIsOpaqueTypedObject:
case InlinableNative::IntrinsicObjectIsTypeDescr:
case InlinableNative::IntrinsicTypeDescrIsSimpleType:
case InlinableNative::IntrinsicTypeDescrIsArrayType:
case InlinableNative::IntrinsicSetTypedObjectOffset:
case InlinableNative::IntrinsicArrayIteratorPrototypeOptimizable:
MOZ_CRASH("Unexpected cross-realm intrinsic call");
case InlinableNative::TestBailout:
case InlinableNative::TestAssertFloat32:
case InlinableNative::TestAssertRecoveredOnBailout:
// Testing functions, not worth inlining cross-realm.
return false;
case InlinableNative::ArrayIsArray:
case InlinableNative::ArrayJoin:
case InlinableNative::ArrayPop:
case InlinableNative::ArrayShift:
case InlinableNative::ArrayPush:
case InlinableNative::ArraySlice:
case InlinableNative::AtomicsCompareExchange:
case InlinableNative::AtomicsExchange:
case InlinableNative::AtomicsLoad:
case InlinableNative::AtomicsStore:
case InlinableNative::AtomicsAdd:
case InlinableNative::AtomicsSub:
case InlinableNative::AtomicsAnd:
case InlinableNative::AtomicsOr:
case InlinableNative::AtomicsXor:
case InlinableNative::AtomicsIsLockFree:
case InlinableNative::ReflectGetPrototypeOf:
case InlinableNative::String:
case InlinableNative::StringCharCodeAt:
case InlinableNative::StringFromCharCode:
case InlinableNative::StringFromCodePoint:
case InlinableNative::StringCharAt:
case InlinableNative::StringToLowerCase:
case InlinableNative::StringToUpperCase:
case InlinableNative::Object:
case InlinableNative::ObjectCreate:
case InlinableNative::ObjectIs:
case InlinableNative::ObjectToString:
case InlinableNative::TypedArrayConstructor:
// Default to false for most natives.
return false;
case InlinableNative::Limit:
break;
}
MOZ_CRASH("Unknown native");
}
IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo,
JSFunction* target) {
MOZ_ASSERT(target->isNative());
@ -91,10 +257,17 @@ IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo,
return inlineWasmCall(callInfo, target);
}
switch (InlinableNative inlNative = target->jitInfo()->inlinableNative) {
InlinableNative inlNative = target->jitInfo()->inlinableNative;
if (target->realm() != script()->realm() && !CanInlineCrossRealm(inlNative)) {
trackOptimizationOutcome(TrackedOutcome::CantInlineCrossRealm);
return InliningStatus_NotInlined;
}
switch (inlNative) {
// Array natives.
case InlinableNative::Array:
return inlineArray(callInfo);
return inlineArray(callInfo, target->realm());
case InlinableNative::ArrayIsArray:
return inlineArrayIsArray(callInfo);
case InlinableNative::ArrayJoin:
@ -425,6 +598,8 @@ IonBuilder::InliningResult IonBuilder::inlineNativeGetter(CallInfo& callInfo,
return InliningStatus_NotInlined;
}
// Note: target might be a cross-realm native!
// Try to optimize typed array lengths.
if (TypedArrayObject::isOriginalLengthGetter(native)) {
if (thisTypes->forAllClasses(constraints(), IsTypedArrayClass) !=
@ -480,8 +655,6 @@ IonBuilder::InliningResult IonBuilder::inlineNonFunctionCall(CallInfo& callInfo,
// Inline a call to a non-function object, invoking the object's call or
// construct hook.
MOZ_ASSERT(target->nonCCWRealm() == script()->realm());
// Don't inline if we're constructing and new.target != callee. This can
// happen with Reflect.construct or derived class constructors.
if (callInfo.constructing() && callInfo.getNewTarget() != callInfo.fun()) {
@ -489,6 +662,12 @@ IonBuilder::InliningResult IonBuilder::inlineNonFunctionCall(CallInfo& callInfo,
return InliningStatus_NotInlined;
}
Realm* targetRealm = JS::GetObjectRealmOrNull(target);
if (!targetRealm || targetRealm != script()->realm()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineCrossRealm);
return InliningStatus_NotInlined;
}
if (callInfo.constructing() &&
target->constructHook() == TypedObject::construct) {
return inlineConstructTypedObject(callInfo, &target->as<TypeDescr>());
@ -533,7 +712,8 @@ IonBuilder::InliningResult IonBuilder::inlineMathFunction(
return InliningStatus_Inlined;
}
IonBuilder::InliningResult IonBuilder::inlineArray(CallInfo& callInfo) {
IonBuilder::InliningResult IonBuilder::inlineArray(CallInfo& callInfo,
Realm* targetRealm) {
uint32_t initLength = 0;
JSObject* templateObject =
@ -548,6 +728,11 @@ IonBuilder::InliningResult IonBuilder::inlineArray(CallInfo& callInfo) {
return InliningStatus_NotInlined;
}
if (templateObject->nonCCWRealm() != targetRealm) {
trackOptimizationOutcome(TrackedOutcome::CantInlineCrossRealm);
return InliningStatus_NotInlined;
}
// Multiple arguments imply array initialization, not just construction.
if (callInfo.argc() >= 2) {
initLength = callInfo.argc();
@ -4140,7 +4325,6 @@ IonBuilder::InliningResult IonBuilder::inlineConstructTypedObject(
IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo,
JSFunction* target) {
MOZ_ASSERT(target->isWasmOptimized());
MOZ_ASSERT(target->realm() == script()->realm());
// Don't inline wasm constructors.
if (callInfo.constructing()) {
@ -4148,6 +4332,11 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo,
return InliningStatus_NotInlined;
}
if (target->realm() != script()->realm()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineCrossRealm);
return InliningStatus_NotInlined;
}
wasm::Instance& inst = wasm::ExportedFunctionToInstance(target);
uint32_t funcIndex = inst.code().getFuncIndex(target);

View File

@ -1254,10 +1254,12 @@ bool RNewArray::recover(JSContext* cx, SnapshotIterator& iter) const {
bool MNewArrayCopyOnWrite::writeRecoverData(CompactBufferWriter& writer) const {
MOZ_ASSERT(canRecoverOnBailout());
writer.writeUnsigned(uint32_t(RInstruction::Recover_NewArrayCopyOnWrite));
writer.writeByte(initialHeap());
return true;
}
RNewArrayCopyOnWrite::RNewArrayCopyOnWrite(CompactBufferReader& reader) {
initialHeap_ = gc::InitialHeap(reader.readByte());
}
bool RNewArrayCopyOnWrite::recover(JSContext* cx,
@ -1267,7 +1269,7 @@ bool RNewArrayCopyOnWrite::recover(JSContext* cx,
RootedValue result(cx);
ArrayObject* resultObject =
NewDenseCopyOnWriteArray(cx, templateObject);
NewDenseCopyOnWriteArray(cx, templateObject, initialHeap_);
if (!resultObject) {
return false;
}

View File

@ -617,6 +617,9 @@ class RNewArray final : public RInstruction {
};
class RNewArrayCopyOnWrite final : public RInstruction {
private:
gc::InitialHeap initialHeap_;
public:
RINSTRUCTION_HEADER_NUM_OP_(NewArrayCopyOnWrite, 1)

View File

@ -8,5 +8,11 @@ name = "jsrust"
crate-type = ["staticlib"]
path = "lib.rs"
[features]
cranelift_x86 = ['jsrust_shared/cranelift_x86']
cranelift_arm32 = ['jsrust_shared/cranelift_arm32']
cranelift_arm64 = ['jsrust_shared/cranelift_arm64']
cranelift_none = ['jsrust_shared/cranelift_none']
[dependencies]
jsrust_shared = { path = "./shared" }

View File

@ -4,7 +4,18 @@
# 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/.
RustLibrary('jsrust')
features = []
if CONFIG['JS_CODEGEN_X64'] or CONFIG['JS_CODEGEN_X86']:
features += ['cranelift_x86']
elif CONFIG['JS_CODEGEN_ARM']:
features += ['cranelift_arm32']
elif CONFIG['JS_CODEGEN_ARM64']:
features += ['cranelift_arm64']
else:
features += ['cranelift_none']
RustLibrary('jsrust', features)
CONFIGURE_SUBST_FILES += ['extra-bindgen-flags']

View File

@ -12,6 +12,12 @@ path = "lib.rs"
baldrdash = { path = "../../wasm/cranelift" }
mozilla-central-workspace-hack = { path = "../../../../build/workspace-hack" }
[features]
cranelift_x86 = ['baldrdash/cranelift_x86']
cranelift_arm32 = ['baldrdash/cranelift_arm32']
cranelift_arm64 = ['baldrdash/cranelift_arm64']
cranelift_none = ['baldrdash/cranelift_none']
# Uncomment this to enable perf support in release mode.
#[profile.release]
#debug = true

View File

@ -42,15 +42,13 @@ inline void ArrayObject::setLength(JSContext* cx, uint32_t length) {
MOZ_ASSERT_IF(clasp->hasFinalize(), heap == gc::TenuredHeap);
MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),
heap == js::gc::TenuredHeap);
MOZ_ASSERT_IF(group->shouldPreTenureDontCheckGeneration(),
heap == gc::TenuredHeap);
// Arrays can use their fixed slots to store elements, so can't have shapes
// which allow named properties to be stored in the fixed slots.
MOZ_ASSERT(shape->numFixedSlots() == 0);
size_t nDynamicSlots = dynamicSlotsCount(0, shape->slotSpan(), clasp);
JSObject* obj = js::Allocate<JSObject>(cx, kind, nDynamicSlots, heap, clasp);
JSObject* obj = js::AllocateObject(cx, kind, nDynamicSlots, heap, clasp);
if (!obj) {
return nullptr;
}

View File

@ -73,8 +73,8 @@ inline NativeObject* NewObjectCache::newObjectFromHit(JSContext* cx,
}
NativeObject* obj = static_cast<NativeObject*>(
Allocate<JSObject, NoGC>(cx, entry->kind,
/* nDynamicSlots = */ 0, heap, group->clasp()));
AllocateObject<NoGC>(cx, entry->kind, /* nDynamicSlots = */ 0,
heap, group->clasp()));
if (!obj) {
return nullptr;
}

View File

@ -79,11 +79,9 @@ CallObject* CallObject::create(JSContext* cx, HandleShape shape,
MOZ_ASSERT(CanBeFinalizedInBackground(kind, &CallObject::class_));
kind = gc::GetBackgroundAllocKind(kind);
gc::InitialHeap heap = GetInitialHeap(GenericObject, group);
JSObject* obj;
JS_TRY_VAR_OR_RETURN_NULL(
cx, obj, NativeObject::create(cx, kind, heap, shape, group));
cx, obj, NativeObject::create(cx, kind, gc::DefaultHeap, shape, group));
return &obj->as<CallObject>();
}
@ -110,10 +108,6 @@ CallObject* CallObject::createTemplateObject(JSContext* cx, HandleScript script,
MOZ_ASSERT(CanBeFinalizedInBackground(kind, &class_));
kind = gc::GetBackgroundAllocKind(kind);
if (group->shouldPreTenureDontCheckGeneration()) {
heap = gc::TenuredHeap;
}
JSObject* obj;
JS_TRY_VAR_OR_RETURN_NULL(cx, obj,
NativeObject::create(cx, kind, heap, shape, group));
@ -893,10 +887,6 @@ LexicalEnvironmentObject* LexicalEnvironmentObject::createTemplateObject(
return nullptr;
}
if (group->shouldPreTenureDontCheckGeneration()) {
heap = gc::TenuredHeap;
}
gc::AllocKind allocKind = gc::GetGCObjectKind(shape->numFixedSlots());
MOZ_ASSERT(
CanBeFinalizedInBackground(allocKind, &LexicalEnvironmentObject::class_));

View File

@ -5237,6 +5237,7 @@ JSObject* js::CreateThisWithTemplate(JSContext* cx,
JSObject* js::NewArrayOperation(JSContext* cx, HandleScript script,
jsbytecode* pc, uint32_t length,
NewObjectKind newKind /* = GenericObject */) {
MOZ_ASSERT(*pc == JSOP_NEWARRAY);
MOZ_ASSERT(newKind != SingletonObject);
RootedObjectGroup group(cx);
@ -5302,7 +5303,7 @@ ArrayObject* js::NewArrayCopyOnWriteOperation(JSContext* cx,
return nullptr;
}
return NewDenseCopyOnWriteArray(cx, baseobj);
return NewDenseCopyOnWriteArray(cx, baseobj, gc::DefaultHeap);
}
void js::ReportRuntimeLexicalError(JSContext* cx, unsigned errorNumber,

View File

@ -619,7 +619,7 @@ static PropertyIteratorObject* NewPropertyIteratorObject(JSContext* cx) {
JS_TRY_VAR_OR_RETURN_NULL(
cx, obj,
NativeObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, group), shape, group));
GetInitialHeap(GenericObject, clasp), shape, group));
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
@ -996,7 +996,7 @@ JSObject* js::CreateIterResultObject(JSContext* cx, HandleValue value,
NativeObject* resultObj;
JS_TRY_VAR_OR_RETURN_NULL(
cx, resultObj,
NativeObject::createWithTemplate(cx, templateObject));
NativeObject::createWithTemplate(cx, gc::DefaultHeap, templateObject));
// Step 3.
resultObj->setSlot(Realm::IterResultObjectValueSlot, value);

View File

@ -113,8 +113,7 @@ inline JSFunction* CloneFunctionObjectIfNotSingleton(
MOZ_ASSERT(dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(),
clasp) == NumDynamicSlots);
JSObject* obj =
js::Allocate<JSObject>(cx, kind, NumDynamicSlots, heap, clasp);
JSObject* obj = js::AllocateObject(cx, kind, NumDynamicSlots, heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}

View File

@ -399,32 +399,6 @@ inline bool IsInternalFunctionObject(JSObject& funobj) {
return fun.isInterpreted() && !fun.environment();
}
inline gc::InitialHeap GetInitialHeap(NewObjectKind newKind,
const Class* clasp) {
if (newKind == NurseryAllocatedProxy) {
MOZ_ASSERT(clasp->isProxy());
MOZ_ASSERT(clasp->hasFinalize());
MOZ_ASSERT(!CanNurseryAllocateFinalizedClass(clasp));
return gc::DefaultHeap;
}
if (newKind != GenericObject) {
return gc::TenuredHeap;
}
if (clasp->hasFinalize() && !CanNurseryAllocateFinalizedClass(clasp)) {
return gc::TenuredHeap;
}
return gc::DefaultHeap;
}
inline gc::InitialHeap GetInitialHeap(NewObjectKind newKind,
ObjectGroup* group) {
if (group->shouldPreTenureDontCheckGeneration()) {
return gc::TenuredHeap;
}
return GetInitialHeap(newKind, group->clasp());
}
/*
* Make an object with the specified prototype. If parent is null, it will
* default to the prototype's global if the prototype is non-null.

View File

@ -792,7 +792,7 @@ static inline JSObject* NewObject(JSContext* cx, HandleObjectGroup group,
return nullptr;
}
gc::InitialHeap heap = GetInitialHeap(newKind, group);
gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
JSObject* obj;
if (clasp->isJSFunction()) {
@ -975,7 +975,7 @@ JSObject* js::NewObjectWithGroupCommon(JSContext* cx, HandleObjectGroup group,
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGroup(group, allocKind, &entry)) {
JSObject* obj = cache.newObjectFromHit(
cx, entry, GetInitialHeap(newKind, group));
cx, entry, GetInitialHeap(newKind, group->clasp()));
if (obj) {
return obj;
}
@ -4296,8 +4296,6 @@ void JSObject::debugCheckNewObject(ObjectGroup* group, Shape* shape,
clasp->isProxy());
MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(),
heap == gc::TenuredHeap);
MOZ_ASSERT_IF(group->shouldPreTenureDontCheckGeneration(),
heap == gc::TenuredHeap);
MOZ_ASSERT(!group->realm()->hasObjectPendingMetadata());

View File

@ -802,6 +802,23 @@ using ClassInitializerOp = JSObject* (*)(JSContext* cx,
namespace js {
inline gc::InitialHeap GetInitialHeap(NewObjectKind newKind,
const Class* clasp) {
if (newKind == NurseryAllocatedProxy) {
MOZ_ASSERT(clasp->isProxy());
MOZ_ASSERT(clasp->hasFinalize());
MOZ_ASSERT(!CanNurseryAllocateFinalizedClass(clasp));
return gc::DefaultHeap;
}
if (newKind != GenericObject) {
return gc::TenuredHeap;
}
if (clasp->hasFinalize() && !CanNurseryAllocateFinalizedClass(clasp)) {
return gc::TenuredHeap;
}
return gc::DefaultHeap;
}
bool NewObjectWithTaggedProtoIsCachable(JSContext* cx,
Handle<TaggedProto> proto,
NewObjectKind newKind,

View File

@ -488,7 +488,7 @@ inline bool NativeObject::isInWholeCellBuffer() const {
size_t nDynamicSlots =
dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp);
JSObject* obj = js::Allocate<JSObject>(cx, kind, nDynamicSlots, heap, clasp);
JSObject* obj = js::AllocateObject(cx, kind, nDynamicSlots, heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}
@ -522,11 +522,9 @@ inline bool NativeObject::isInWholeCellBuffer() const {
}
/* static */ inline JS::Result<NativeObject*, JS::OOM&>
NativeObject::createWithTemplate(JSContext* cx, HandleObject templateObject) {
NativeObject::createWithTemplate(JSContext* cx, js::gc::InitialHeap heap,
HandleObject templateObject) {
RootedObjectGroup group(cx, templateObject->group());
gc::InitialHeap heap = GetInitialHeap(GenericObject, group);
RootedShape shape(cx, templateObject->as<NativeObject>().lastProperty());
gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());

View File

@ -565,7 +565,7 @@ class NativeObject : public ShapedObject {
js::HandleShape shape, js::HandleObjectGroup group);
static inline JS::Result<NativeObject*, JS::OOM&> createWithTemplate(
JSContext* cx, HandleObject templateObject);
JSContext* cx, js::gc::InitialHeap heap, HandleObject templateObject);
#ifdef DEBUG
static void enableShapeConsistencyChecks();

View File

@ -54,13 +54,8 @@ inline bool ObjectGroup::unknownProperties(const AutoSweepObjectGroup& sweep) {
}
inline bool ObjectGroup::shouldPreTenure(const AutoSweepObjectGroup& sweep) {
MOZ_ASSERT(sweep.group() == this);
return shouldPreTenureDontCheckGeneration();
}
inline bool ObjectGroup::shouldPreTenureDontCheckGeneration() {
return hasAnyFlagsDontCheckGeneration(OBJECT_FLAG_PRE_TENURE) &&
!unknownPropertiesDontCheckGeneration();
return hasAnyFlags(sweep, OBJECT_FLAG_PRE_TENURE) &&
!unknownProperties(sweep);
}
inline bool ObjectGroup::canPreTenure(const AutoSweepObjectGroup& sweep) {

View File

@ -404,10 +404,6 @@ class ObjectGroup : public gc::TenuredCell {
inline bool hasAllFlags(const AutoSweepObjectGroup& sweep,
ObjectGroupFlags flags);
bool hasAnyFlagsDontCheckGeneration(ObjectGroupFlags flags) {
MOZ_ASSERT((flags & OBJECT_FLAG_DYNAMIC_MASK) == flags);
return !!(this->flagsDontCheckGeneration() & flags);
}
bool hasAllFlagsDontCheckGeneration(ObjectGroupFlags flags) {
MOZ_ASSERT((flags & OBJECT_FLAG_DYNAMIC_MASK) == flags);
return (this->flagsDontCheckGeneration() & flags) == flags;
@ -422,7 +418,6 @@ class ObjectGroup : public gc::TenuredCell {
}
inline bool shouldPreTenure(const AutoSweepObjectGroup& sweep);
inline bool shouldPreTenureDontCheckGeneration();
gc::InitialHeap initialHeap(CompilerConstraintList* constraints);

View File

@ -184,11 +184,11 @@ void ProxyObject::nuke() {
realm->newProxyCache.add(group, shape);
}
gc::InitialHeap heap = GetInitialHeap(newKind, group);
gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
debugCheckNewObject(group, shape, allocKind, heap);
JSObject* obj = js::Allocate<JSObject>(cx, allocKind, /* nDynamicSlots = */ 0,
heap, clasp);
JSObject* obj = js::AllocateObject(cx, allocKind, /* nDynamicSlots = */ 0,
heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}

View File

@ -159,7 +159,7 @@ MOZ_ALWAYS_INLINE JSRope* JSRope::new_(
if (!validateLength(cx, length)) {
return nullptr;
}
JSRope* str = js::Allocate<JSRope, allowGC>(cx, heap);
JSRope* str = js::AllocateString<JSRope, allowGC>(cx, heap);
if (!str) {
return nullptr;
}
@ -220,7 +220,7 @@ MOZ_ALWAYS_INLINE JSLinearString* JSDependentString::new_(
}
JSDependentString* str =
js::Allocate<JSDependentString, js::NoGC>(cx, js::gc::DefaultHeap);
js::AllocateString<JSDependentString, js::NoGC>(cx, js::gc::DefaultHeap);
if (str) {
str->init(cx, baseArg, start, length);
return str;
@ -228,7 +228,7 @@ MOZ_ALWAYS_INLINE JSLinearString* JSDependentString::new_(
js::RootedLinearString base(cx, baseArg);
str = js::Allocate<JSDependentString>(cx, js::gc::DefaultHeap);
str = js::AllocateString<JSDependentString>(cx, js::gc::DefaultHeap);
if (!str) {
return nullptr;
}
@ -262,7 +262,7 @@ MOZ_ALWAYS_INLINE JSFlatString* JSFlatString::new_(JSContext* cx,
if (cx->zone()->isAtomsZone()) {
str = js::Allocate<js::NormalAtom, allowGC>(cx);
} else {
str = js::Allocate<JSFlatString, allowGC>(cx, js::gc::DefaultHeap);
str = js::AllocateString<JSFlatString, allowGC>(cx, js::gc::DefaultHeap);
}
if (!str) {
return nullptr;
@ -308,7 +308,7 @@ MOZ_ALWAYS_INLINE JSThinInlineString* JSThinInlineString::new_(JSContext* cx) {
return (JSThinInlineString*)(js::Allocate<js::NormalAtom, allowGC>(cx));
}
return js::Allocate<JSThinInlineString, allowGC>(cx, js::gc::DefaultHeap);
return js::AllocateString<JSThinInlineString, allowGC>(cx, js::gc::DefaultHeap);
}
template <js::AllowGC allowGC>
@ -317,7 +317,7 @@ MOZ_ALWAYS_INLINE JSFatInlineString* JSFatInlineString::new_(JSContext* cx) {
return (JSFatInlineString*)(js::Allocate<js::FatInlineAtom, allowGC>(cx));
}
return js::Allocate<JSFatInlineString, allowGC>(cx, js::gc::DefaultHeap);
return js::AllocateString<JSFatInlineString, allowGC>(cx, js::gc::DefaultHeap);
}
template <>

View File

@ -846,7 +846,7 @@ NativeObject* UnboxedPlainObject::convertToNative(JSContext* cx,
debugCheckNewObject(group, /* shape = */ nullptr, kind, heap);
JSObject* obj =
js::Allocate<JSObject>(cx, kind, /* nDynamicSlots = */ 0, heap, clasp);
js::AllocateObject(cx, kind, /* nDynamicSlots = */ 0, heap, clasp);
if (!obj) {
return cx->alreadyReportedOOM();
}
@ -875,7 +875,7 @@ UnboxedPlainObject* UnboxedPlainObject::create(JSContext* cx,
AutoSweepObjectGroup sweep(group);
allocKind = group->unboxedLayout(sweep).getAllocKind();
}
gc::InitialHeap heap = GetInitialHeap(newKind, group);
gc::InitialHeap heap = GetInitialHeap(newKind, &class_);
MOZ_ASSERT(newKind != SingletonObject);

View File

@ -8,7 +8,7 @@ crate-type = ["rlib"]
name = "baldrdash"
[dependencies]
cranelift-codegen = "0.29.0"
cranelift-codegen = { version = "0.29.0", default-features = false }
cranelift-wasm = "0.29.0"
target-lexicon = "0.2.0"
log = { version = "0.4.6", default-features = false, features = ["release_max_level_info"] }
@ -17,6 +17,16 @@ env_logger = "0.5.6"
[build-dependencies]
bindgen = {version = "0.43", default-features = false} # disable `logging` to reduce code size
[features]
default = ['cranelift-codegen/std']
cranelift_x86 = ['cranelift-codegen/x86']
cranelift_arm32 = ['cranelift-codegen/arm32']
cranelift_arm64 = ['cranelift-codegen/arm64']
# The "none" support is a lie (so far): Cranelift has to include support for
# one ISA at the moment, so request to include support for a small one: riscv.
cranelift_none = ['cranelift-codegen/riscv']
# Uncomment this to enable perf support in release mode.
#[profile.release]
#debug = true

View File

@ -242,11 +242,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
gPrototypeProperties['RegExp'] =
["constructor", "toSource", "toString", "compile", "exec", "test",
Symbol.match, Symbol.replace, Symbol.search, Symbol.split,
Symbol.match, Symbol.matchAll, Symbol.replace, Symbol.search, Symbol.split,
"flags", "global", "ignoreCase", "multiline", "source", "sticky", "unicode"];
if (isNightlyBuild) {
gPrototypeProperties['RegExp'].push(Symbol.matchAll);
}
gConstructorProperties['RegExp'] =
constructorProps(["input", "lastMatch", "lastParen",
"leftContext", "rightContext", "$1", "$2", "$3", "$4",

View File

@ -7760,62 +7760,64 @@ nsresult PresShell::EventHandler::DispatchEvent(
nsresult rv = aEventStateManager->PreHandleEvent(
GetPresContext(), aEvent, mPresShell->mCurrentEventFrame,
mPresShell->mCurrentEventContent, aEventStatus, aOverrideClickTarget);
if (NS_FAILED(rv)) {
return rv;
}
// 2. Give event to the DOM for third party and JS use.
if (NS_SUCCEEDED(rv)) {
bool wasHandlingKeyBoardEvent = nsContentUtils::IsHandlingKeyBoardEvent();
if (aEvent->mClass == eKeyboardEventClass) {
nsContentUtils::SetIsHandlingKeyBoardEvent(true);
}
// If EventStateManager or something wants reply from remote process and
// needs to win any other event listeners in chrome, the event is both
// stopped its propagation and marked as "waiting reply from remote
// process". In this case, PresShell shouldn't dispatch the event into
// the DOM tree because they don't have a chance to stop propagation in
// the system event group. On the other hand, if its propagation is not
// stopped, that means that the event may be reserved by chrome. If it's
// reserved by chrome, the event shouldn't be sent to any remote
// processes. In this case, PresShell needs to dispatch the event to
// the DOM tree for checking if it's reserved.
if (aEvent->IsAllowedToDispatchDOMEvent() &&
!(aEvent->PropagationStopped() &&
aEvent->IsWaitingReplyFromRemoteProcess())) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
"Somebody changed aEvent to cause a DOM event!");
nsPresShellEventCB eventCB(mPresShell);
if (nsIFrame* target = mPresShell->GetCurrentEventFrame()) {
if (target->OnlySystemGroupDispatch(aEvent->mMessage)) {
aEvent->StopPropagation();
}
}
if (aEvent->mClass == eTouchEventClass) {
DispatchTouchEventToDOM(aEvent, aEventStatus, &eventCB, aTouchIsNew);
} else {
DispatchEventToDOM(aEvent, aEventStatus, &eventCB);
bool wasHandlingKeyBoardEvent = nsContentUtils::IsHandlingKeyBoardEvent();
if (aEvent->mClass == eKeyboardEventClass) {
nsContentUtils::SetIsHandlingKeyBoardEvent(true);
}
// If EventStateManager or something wants reply from remote process and
// needs to win any other event listeners in chrome, the event is both
// stopped its propagation and marked as "waiting reply from remote
// process". In this case, PresShell shouldn't dispatch the event into
// the DOM tree because they don't have a chance to stop propagation in
// the system event group. On the other hand, if its propagation is not
// stopped, that means that the event may be reserved by chrome. If it's
// reserved by chrome, the event shouldn't be sent to any remote
// processes. In this case, PresShell needs to dispatch the event to
// the DOM tree for checking if it's reserved.
if (aEvent->IsAllowedToDispatchDOMEvent() &&
!(aEvent->PropagationStopped() &&
aEvent->IsWaitingReplyFromRemoteProcess())) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
"Somebody changed aEvent to cause a DOM event!");
nsPresShellEventCB eventCB(mPresShell);
if (nsIFrame* target = mPresShell->GetCurrentEventFrame()) {
if (target->OnlySystemGroupDispatch(aEvent->mMessage)) {
aEvent->StopPropagation();
}
}
nsContentUtils::SetIsHandlingKeyBoardEvent(wasHandlingKeyBoardEvent);
if (aEvent->mMessage == ePointerUp || aEvent->mMessage == ePointerCancel) {
// Implicitly releasing capture for given pointer.
// ePointerLostCapture should be send after ePointerUp or
// ePointerCancel.
WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
MOZ_ASSERT(pointerEvent);
PointerEventHandler::ReleasePointerCaptureById(pointerEvent->pointerId);
PointerEventHandler::CheckPointerCaptureState(pointerEvent);
}
// 3. Give event to event manager for post event state changes and
// generation of synthetic events.
if (!mPresShell->IsDestroying() && NS_SUCCEEDED(rv)) {
rv = aEventStateManager->PostHandleEvent(
GetPresContext(), aEvent, mPresShell->GetCurrentEventFrame(),
aEventStatus, aOverrideClickTarget);
if (aEvent->mClass == eTouchEventClass) {
DispatchTouchEventToDOM(aEvent, aEventStatus, &eventCB, aTouchIsNew);
} else {
DispatchEventToDOM(aEvent, aEventStatus, &eventCB);
}
}
return rv;
nsContentUtils::SetIsHandlingKeyBoardEvent(wasHandlingKeyBoardEvent);
if (aEvent->mMessage == ePointerUp || aEvent->mMessage == ePointerCancel) {
// Implicitly releasing capture for given pointer.
// ePointerLostCapture should be send after ePointerUp or
// ePointerCancel.
WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
MOZ_ASSERT(pointerEvent);
PointerEventHandler::ReleasePointerCaptureById(pointerEvent->pointerId);
PointerEventHandler::CheckPointerCaptureState(pointerEvent);
}
if (mPresShell->IsDestroying()) {
return NS_OK;
}
// 3. Give event to event manager for post event state changes and
// generation of synthetic events.
return aEventStateManager->PostHandleEvent(
GetPresContext(), aEvent, mPresShell->GetCurrentEventFrame(),
aEventStatus, aOverrideClickTarget);
}
bool PresShell::EventHandler::PrepareToDispatchEvent(WidgetEvent* aEvent) {

View File

@ -2755,21 +2755,17 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(
MaybeSetupTransactionIdAllocator(layerManager, presContext);
// Store the existing layer builder to reinstate it on return.
FrameLayerBuilder* oldBuilder = layerManager->GetLayerBuilder();
FrameLayerBuilder* layerBuilder = nullptr;
bool sent = false;
if (aFlags & PAINT_IDENTICAL_DISPLAY_LIST) {
sent = layerManager->EndEmptyTransaction(flags);
}
if (!sent) {
layerBuilder =
FrameLayerBuilder* layerBuilder =
BuildLayers(aBuilder, layerManager, aFlags, widgetTransaction);
if (!layerBuilder) {
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
layerManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
return nullptr;
}
@ -2837,7 +2833,7 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(
}
}
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
layerManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
return layerManager.forget();
}

View File

@ -12,8 +12,7 @@
android:minResizeWidth="64dp"
android:minResizeHeight="40dp"
android:previewImage="@drawable/search_widget_preview"
android:resizeMode="horizontal"
android:updatePeriodMillis="300000">
android:resizeMode="horizontal">
</appwidget-provider>

View File

@ -12,6 +12,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsIntent;
@ -230,7 +231,7 @@ public class LauncherActivity extends Activity {
}
break;
case LINK_SEARCH_WIDGET:
if (AppConstants.Versions.feature26Plus) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AppWidgetManager appWidgetManager = getApplicationContext().getSystemService(AppWidgetManager.class);
ComponentName componentName = new ComponentName(this, SearchWidgetProvider.class);

View File

@ -330,10 +330,6 @@ AddrInfo::AddrInfo(const AddrInfo *src) {
}
AddrInfo::~AddrInfo() {
NetAddrElement *addrElement;
while ((addrElement = mAddresses.popLast())) {
delete addrElement;
}
}
void AddrInfo::AddAddress(NetAddrElement *address) {

View File

@ -12,6 +12,7 @@
#include "prio.h"
#include "prnetdb.h"
#include "plstr.h"
#include "nsISupportsImpl.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
@ -123,6 +124,8 @@ class NetAddrElement : public LinkedListElement<NetAddrElement> {
};
class AddrInfo {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AddrInfo)
public:
// Creates an AddrInfo object.
explicit AddrInfo(const nsACString &host, const PRAddrInfo *prAddrInfo,
@ -136,7 +139,6 @@ class AddrInfo {
// Creates a basic AddrInfo object (initialize only the host and TRR status).
explicit AddrInfo(const nsACString &host, unsigned int TRRType);
~AddrInfo();
explicit AddrInfo(const AddrInfo *src); // copy
@ -149,10 +151,11 @@ class AddrInfo {
uint32_t ttl;
static const uint32_t NO_TTL_DATA = (uint32_t)-1;
LinkedList<NetAddrElement> mAddresses;
AutoCleanLinkedList<NetAddrElement> mAddresses;
unsigned int IsTRR() { return mFromTRR; }
private:
~AddrInfo();
unsigned int mFromTRR;
};

View File

@ -277,14 +277,14 @@ _GetAddrInfo_Portable(const nsACString& aCanonHost, uint16_t aAddressFamily,
bool filterNameCollision =
!(aFlags & nsHostResolver::RES_ALLOW_NAME_COLLISION);
nsAutoPtr<AddrInfo> ai(new AddrInfo(aCanonHost, prai, disableIPv4,
RefPtr<AddrInfo> ai(new AddrInfo(aCanonHost, prai, disableIPv4,
filterNameCollision, canonName));
PR_FreeAddrInfo(prai);
if (ai->mAddresses.isEmpty()) {
return NS_ERROR_UNKNOWN_HOST;
}
*aAddrInfo = ai.forget();
ai.forget(aAddrInfo);
return NS_OK;
}

View File

@ -876,7 +876,7 @@ nsresult TRR::DohDecode(nsCString &aHost) {
nsresult TRR::ReturnData() {
if (mType != TRRTYPE_TXT) {
// create and populate an AddrInfo instance to pass on
nsAutoPtr<AddrInfo> ai(new AddrInfo(mHost, mType));
RefPtr<AddrInfo> ai(new AddrInfo(mHost, mType));
DOHaddr *item;
uint32_t ttl = AddrInfo::NO_TTL_DATA;
while ((item = static_cast<DOHaddr *>(mDNS.mAddresses.popFirst()))) {
@ -895,7 +895,7 @@ nsresult TRR::ReturnData() {
if (!mHostResolver) {
return NS_ERROR_FAILURE;
}
(void)mHostResolver->CompleteLookup(mRec, NS_OK, ai.forget(), mPB,
(void)mHostResolver->CompleteLookup(mRec, NS_OK, ai, mPB,
mOriginSuffix);
mHostResolver = nullptr;
mRec = nullptr;
@ -915,7 +915,7 @@ nsresult TRR::FailData(nsresult error) {
} else {
// create and populate an TRR AddrInfo instance to pass on to signal that
// this comes from TRR
AddrInfo *ai = new AddrInfo(mHost, mType);
RefPtr<AddrInfo> ai = new AddrInfo(mHost, mType);
(void)mHostResolver->CompleteLookup(mRec, error, ai, mPB, mOriginSuffix);
}

View File

@ -612,7 +612,7 @@ AHostResolver::LookupStatus TRRService::CompleteLookup(
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!rec);
nsAutoPtr<AddrInfo> newRRSet(aNewRRSet);
RefPtr<AddrInfo> newRRSet(aNewRRSet);
MOZ_ASSERT(newRRSet && newRRSet->IsTRR() == TRRTYPE_NS);
#ifdef DEBUG

View File

@ -297,7 +297,6 @@ AddrHostRecord::AddrHostRecord(const nsHostKey &key)
AddrHostRecord::~AddrHostRecord() {
mCallbacks.clear();
Telemetry::Accumulate(Telemetry::DNS_BLACKLIST_COUNT, mBlacklistedCount);
delete addr_info;
}
bool AddrHostRecord::Blacklisted(NetAddr *aQuery) {
@ -1009,9 +1008,6 @@ nsresult nsHostResolver::ResolveHost(const nsACString &aHost, uint16_t type,
// addr_info.
MutexAutoLock lock(addrRec->addr_info_lock);
// XXX: note that this actually leaks addr_info.
// For some reason, freeing the memory causes a crash in
// nsDNSRecord::GetNextAddr - see bug 1422173
addrRec->addr_info = nullptr;
if (unspecRec->negative) {
rec->negative = unspecRec->negative;
@ -1691,9 +1687,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
RefPtr<AddrHostRecord> addrRec = do_QueryObject(rec);
MOZ_ASSERT(addrRec);
// newRRSet needs to be taken into the hostrecord (which will then own it)
// or deleted on early return.
nsAutoPtr<AddrInfo> newRRSet(aNewRRSet);
RefPtr<AddrInfo> newRRSet(aNewRRSet);
bool trrResult = newRRSet && newRRSet->IsTRR();
@ -1748,7 +1742,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
// There's another TRR complete pending. Wait for it and keep
// this RRset around until then.
MOZ_ASSERT(!addrRec->mFirstTRR && newRRSet);
addrRec->mFirstTRR = newRRSet; // autoPtr.swap()
addrRec->mFirstTRR.swap(newRRSet); // autoPtr.swap()
MOZ_ASSERT(addrRec->mFirstTRR && !newRRSet);
if (addrRec->mDidCallbacks || addrRec->mResolverMode == MODE_SHADOW) {
@ -1774,7 +1768,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
if (NS_SUCCEEDED(status)) {
merge_rrset(newRRSet, addrRec->mFirstTRR);
} else {
newRRSet = addrRec->mFirstTRR; // transfers
newRRSet.swap(addrRec->mFirstTRR); // transfers
}
addrRec->mFirstTRR = nullptr;
}
@ -1823,7 +1817,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
// note that we don't update the addr_info if this is trr shadow results
if (!mShutdown && !(trrResult && addrRec->mResolverMode == MODE_SHADOW)) {
MutexAutoLock lock(addrRec->addr_info_lock);
nsAutoPtr<AddrInfo> old_addr_info;
RefPtr<AddrInfo> old_addr_info;
if (different_rrset(addrRec->addr_info, newRRSet)) {
LOG(("nsHostResolver record %p new gencnt\n", addrRec.get()));
old_addr_info = addrRec->addr_info;
@ -2038,7 +2032,7 @@ void nsHostResolver::ThreadFunc() {
nsResState rs;
#endif
RefPtr<AddrHostRecord> rec;
AddrInfo *ai = nullptr;
RefPtr<AddrInfo> ai;
do {
if (!rec) {
@ -2059,10 +2053,10 @@ void nsHostResolver::ThreadFunc() {
TimeDuration inQueue = startTime - rec->mNativeStart;
uint32_t ms = static_cast<uint32_t>(inQueue.ToMilliseconds());
Telemetry::Accumulate(Telemetry::DNS_NATIVE_QUEUING, ms);
nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, &ai, getTtl);
nsresult status = GetAddrInfo(rec->host, rec->af, rec->flags, getter_AddRefs(ai), getTtl);
#if defined(RES_RETRY_ON_FAILURE)
if (NS_FAILED(status) && rs.Reset()) {
status = GetAddrInfo(rec->host, rec->af, rec->flags, &ai, getTtl);
status = GetAddrInfo(rec->host, rec->af, rec->flags, getter_AddRefs(ai), getTtl);
}
#endif

View File

@ -181,7 +181,7 @@ class AddrHostRecord final : public nsHostRecord {
*/
Mutex addr_info_lock;
int addr_info_gencnt; /* generation count of |addr_info| */
mozilla::net::AddrInfo *addr_info;
RefPtr<mozilla::net::AddrInfo> addr_info;
mozilla::UniquePtr<mozilla::net::NetAddr> addr;
// hold addr_info_lock when calling the blacklist functions
@ -222,7 +222,7 @@ class AddrHostRecord final : public nsHostRecord {
mozilla::TimeDuration mTrrDuration;
mozilla::TimeDuration mNativeDuration;
nsAutoPtr<mozilla::net::AddrInfo> mFirstTRR; // partial TRR storage
RefPtr<mozilla::net::AddrInfo> mFirstTRR; // partial TRR storage
nsresult mFirstTRRresult;
uint8_t mTRRSuccess; // number of successful TRR responses

View File

@ -18,9 +18,29 @@ class Connection {
this.transport = transport;
this.transport.hooks = this;
this.onmessage = () => {};
this.transport.ready();
this.defaultSession = null;
this.sessions = new Map();
}
/**
* Register a new Session to forward the messages to.
* Session without any `id` attribute will be considered to be the
* default one, to which messages without `sessionId` attribute are
* forwarded to. Only one such session can be registered.
*
* @param Session session
*/
registerSession(session) {
if (!session.id) {
if (this.defaultSession) {
throw new Error("Default session is already set on Connection," +
"can't register another one.");
}
this.defaultSession = session;
}
this.sessions.set(session.id, session);
}
send(message) {
@ -51,7 +71,19 @@ class Connection {
let message = {id: null};
try {
message = this.deserialize(packet);
this.onmessage.call(null, message);
const { sessionId } = packet;
if (!sessionId) {
if (!this.defaultSession) {
throw new Error(`Connection is missing a default Session.`);
}
this.defaultSession.onMessage(message);
} else {
const session = this.sessions.get(sessionId);
if (!session) {
throw new Error(`Session '${sessionId}' doesn't exists.`);
}
session.onMessage(message);
}
} catch (e) {
log.warn(e);
this.error(message.id, e);
@ -60,6 +92,7 @@ class Connection {
close() {
this.transport.close();
this.sessions.clear();
}
onClosed(status) {}

View File

@ -5,6 +5,7 @@
"use strict";
var EXPORTED_SYMBOLS = [
"TabManager",
"TabObserver",
"WindowObserver",
];
@ -143,3 +144,15 @@ class TabObserver {
// TODO(ato): Is TabClose fired when the window closes?
}
}
var TabManager = {
addTab() {
const window = Services.wm.getMostRecentWindow("navigator:browser");
const { gBrowser } = window;
const tab = gBrowser.addTab("about:blank", {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
gBrowser.selectedTab = tab;
return tab;
},
};

View File

@ -11,6 +11,11 @@ const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm")
const ContentProcessDomains = {};
XPCOMUtils.defineLazyModuleGetters(ContentProcessDomains, {
Emulation: "chrome://remote/content/domains/content/Emulation.jsm",
Log: "chrome://remote/content/domains/content/Log.jsm",
Network: "chrome://remote/content/domains/content/Network.jsm",
Page: "chrome://remote/content/domains/content/Page.jsm",
Performance: "chrome://remote/content/domains/content/Performance.jsm",
Runtime: "chrome://remote/content/domains/content/Runtime.jsm",
Security: "chrome://remote/content/domains/content/Security.jsm",
});

View File

@ -0,0 +1,16 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["Emulation"];
const {ContentProcessDomain} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomain.jsm");
class Emulation extends ContentProcessDomain {
// commands
setDeviceMetricsOverride() {}
setTouchEmulationEnabled() {}
}

View File

@ -0,0 +1,34 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["Network"];
const {ContentProcessDomain} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomain.jsm");
class Network extends ContentProcessDomain {
constructor(session) {
super(session);
this.enabled = false;
}
destructor() {
this.disable();
}
// commands
async enable() {
if (!this.enabled) {
this.enabled = true;
}
}
disable() {
if (this.enabled) {
this.enabled = false;
}
}
}

View File

@ -67,6 +67,21 @@ class Page extends ContentProcessDomain {
return {frameId: "42"};
}
getFrameTree() {
return {
frameTree: {
frame: {
// id, parentId
},
childFrames: [],
},
};
}
setLifecycleEventsEnabled() {}
addScriptToEvaluateOnNewDocument() {}
createIsolatedWorld() {}
url() {
return this.content.location.href;
}
@ -81,6 +96,9 @@ class Page extends ContentProcessDomain {
case "pageshow":
this.emit("Page.loadEventFired", {timestamp});
// XXX this should most likely be sent differently
this.emit("Page.navigatedWithinDocument", {timestamp});
this.emit("Page.frameStoppedLoading", {timestamp});
break;
}
}

View File

@ -0,0 +1,34 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["Performance"];
const {ContentProcessDomain} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomain.jsm");
class Performance extends ContentProcessDomain {
constructor(session) {
super(session);
this.enabled = false;
}
destructor() {
this.disable();
}
// commands
async enable() {
if (!this.enabled) {
this.enabled = true;
}
}
disable() {
if (this.enabled) {
this.enabled = false;
}
}
}

View File

@ -0,0 +1,34 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["Runtime"];
const {ContentProcessDomain} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomain.jsm");
class Runtime extends ContentProcessDomain {
constructor(session) {
super(session);
this.enabled = false;
}
destructor() {
this.disable();
}
// commands
async enable() {
if (!this.enabled) {
this.enabled = true;
}
}
disable() {
if (this.enabled) {
this.enabled = false;
}
}
}

View File

@ -0,0 +1,34 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["Security"];
const {ContentProcessDomain} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomain.jsm");
class Security extends ContentProcessDomain {
constructor(session) {
super(session);
this.enabled = false;
}
destructor() {
this.disable();
}
// commands
async enable() {
if (!this.enabled) {
this.enabled = true;
}
}
disable() {
if (this.enabled) {
this.enabled = false;
}
}
}

View File

@ -7,8 +7,18 @@
var EXPORTED_SYMBOLS = ["Target"];
const {Domain} = ChromeUtils.import("chrome://remote/content/domains/Domain.jsm");
const {TabManager} = ChromeUtils.import("chrome://remote/content/WindowManager.jsm");
const {TabSession} = ChromeUtils.import("chrome://remote/content/sessions/TabSession.jsm");
let sessionIds = 1;
class Target extends Domain {
constructor(session) {
super(session);
this.onTargetCreated = this.onTargetCreated.bind(this);
}
getBrowserContexts() {
return {
browserContextIds: [],
@ -16,5 +26,64 @@ class Target extends Domain {
}
setDiscoverTargets({ discover }) {
const { targets } = this.session.target;
if (discover) {
targets.on("connect", this.onTargetCreated);
} else {
targets.off("connect", this.onTargetCreated);
}
}
onTargetCreated(eventName, target) {
this.emit("Target.targetCreated", {
targetInfo: {
browserContextId: target.id,
targetId: target.id,
type: "page",
},
});
}
async createTarget(a, b) {
const tab = TabManager.addTab();
const browser = tab.linkedBrowser;
// Wait for the related target to be created
const target = await new Promise(resolve => {
const { targets } = this.session.target;
const listener = (eventName, target) => {
if (target.browser == browser) {
targets.off("connect", listener);
resolve(target);
}
};
targets.on("connect", listener);
});
return {
targetId: target.id,
};
}
attachToTarget({ targetId }) {
const { targets } = this.session.target;
const target = targets.getById(targetId);
if (!target) {
return new Error(`Unable to find target with id '${targetId}'`);
}
const session = new TabSession(this.session.connection, target, sessionIds++);
this.emit("Target.attachedToTarget", {
targetInfo: {
type: "page",
},
sessionId: session.id,
});
return {
sessionId: session.id,
};
}
setAutoAttach() {}
}

View File

@ -31,8 +31,13 @@ remote.jar:
content/domains/ContentProcessDomain.jsm (domains/ContentProcessDomain.jsm)
content/domains/ContentProcessDomains.jsm (domains/ContentProcessDomains.jsm)
content/domains/ParentProcessDomains.jsm (domains/ParentProcessDomains.jsm)
content/domains/content/Emulation.jsm (domains/content/Emulation.jsm)
content/domains/content/Log.jsm (domains/content/Log.jsm)
content/domains/content/Network.jsm (domains/content/Network.jsm)
content/domains/content/Page.jsm (domains/content/Page.jsm)
content/domains/content/Performance.jsm (domains/content/Performance.jsm)
content/domains/content/Runtime.jsm (domains/content/Runtime.jsm)
content/domains/content/Security.jsm (domains/content/Security.jsm)
content/domains/parent/Browser.jsm (domains/parent/Browser.jsm)
content/domains/parent/Target.jsm (domains/parent/Target.jsm)

View File

@ -26,7 +26,7 @@ class Session {
this.destructor = this.destructor.bind(this);
this.connection.onmessage = this.onMessage.bind(this);
this.connection.registerSession(this);
this.connection.transport.on("close", this.destructor);
this.domains = new Domains(this, ParentProcessDomains);

View File

@ -64,6 +64,15 @@ class Targets {
return this._targets.size;
}
/**
* Get Target instance by target id
*
* @param int id Target id
*/
getById(id) {
return this._targets.get(id);
}
/**
* Get the Target instance for the main process.
* This target is a singleton and only exposes a subset of domains.

View File

@ -16,5 +16,9 @@ console.log("Calling puppeteer.connect");
puppeteer.connect({ browserURL: "http://localhost:9000"}).then(async browser => {
console.log("Connect success!");
const page = await browser.newPage();
console.log("page", !!page);
await page.goto("https://www.mozilla.org/");
return browser.close();
});

View File

@ -5,7 +5,12 @@
const {Session} = ChromeUtils.import("chrome://remote/content/sessions/Session.jsm");
const connection = {onmessage: () => {}};
const connection = {
registerSession: () => {},
transport: {
on: () => {},
},
};
class MockTarget {
constructor() {

View File

@ -1151,4 +1151,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1560431526439000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1560774076545000);

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,8 @@ const DB_NAME = "remote-settings";
const TELEMETRY_COMPONENT = "remotesettings";
const INVALID_SIGNATURE = "Invalid content signature";
const MISSING_SIGNATURE = "Missing signature";
const INVALID_SIGNATURE_MSG = "Invalid content signature";
const MISSING_SIGNATURE_MSG = "Missing signature";
XPCOMUtils.defineLazyPreferenceGetter(this, "gServerURL",
"services.settings.server");
@ -85,7 +85,7 @@ async function fetchCollectionSignature(bucket, collection, expectedTimestamp) {
.collection(collection)
.getData({ query: { _expected: expectedTimestamp } });
if (!signaturePayload) {
throw new Error(MISSING_SIGNATURE);
throw new Error(MISSING_SIGNATURE_MSG);
}
const { x5u, signature } = signaturePayload;
const certChainResponse = await fetch(x5u);
@ -268,7 +268,7 @@ class RemoteSettingsClient extends EventEmitter {
// According to API, there will be one only (fail if not).
const [{ last_modified: expectedTimestamp }] = changes;
return this.maybeSync(expectedTimestamp, options);
return this.maybeSync(expectedTimestamp, { ...options, trigger: "forced" });
}
/**
@ -279,16 +279,17 @@ class RemoteSettingsClient extends EventEmitter {
* cache busting if local data is out of date.
* @param {Object} options additional advanced options.
* @param {bool} options.loadDump load initial dump from disk on first sync (default: true)
* @param {string} options.trigger label to identify what triggered this sync (eg. ``"timer"``, default: `"manual"`)
* @return {Promise} which rejects on sync or process failure.
*/
async maybeSync(expectedTimestamp, options = { loadDump: true }) {
async maybeSync(expectedTimestamp, options = { loadDump: true, trigger: "manual" }) {
const { loadDump, trigger } = options;
let reportStatus = null;
try {
const collection = await this.openCollection();
// Synchronize remote data into a local Sqlite DB.
let collectionLastModified = await collection.db.getLastModified();
// Synchronize remote data into a local DB using Kinto.
const kintoCollection = await this.openCollection();
let collectionLastModified = await kintoCollection.db.getLastModified();
// If there is no data currently in the collection, attempt to import
// initial data from the application defaults.
@ -297,7 +298,7 @@ class RemoteSettingsClient extends EventEmitter {
if (!collectionLastModified && loadDump) {
try {
await RemoteSettingsWorker.importJSONDump(this.bucketName, this.collectionName);
collectionLastModified = await collection.db.getLastModified();
collectionLastModified = await kintoCollection.db.getLastModified();
} catch (e) {
// Report but go-on.
Cu.reportError(e);
@ -311,10 +312,10 @@ class RemoteSettingsClient extends EventEmitter {
return;
}
// If there is a `signerName` and collection signing is enforced, add a
// hook for incoming changes that validates the signature.
// If signature verification is enabled, then add a synchronization hook
// for incoming changes that validates the signature.
if (this.signerName && gVerifySignature) {
collection.hooks["incoming-changes"] = [async (payload, collection) => {
kintoCollection.hooks["incoming-changes"] = [async (payload, collection) => {
await this._validateCollectionSignature(payload.changes,
payload.lastModified,
collection,
@ -324,19 +325,17 @@ class RemoteSettingsClient extends EventEmitter {
}];
}
// Fetch changes from server.
let syncResult;
try {
// Server changes have priority during synchronization.
// Fetch changes from server, and make sure we overwrite local data.
const strategy = Kinto.syncStrategy.SERVER_WINS;
syncResult = await collection.sync({ remote: gServerURL, strategy, expectedTimestamp });
const { ok } = syncResult;
if (!ok) {
syncResult = await kintoCollection.sync({ remote: gServerURL, strategy, expectedTimestamp });
if (!syncResult.ok) {
// With SERVER_WINS, there cannot be any conflicts, but don't silent it anyway.
throw new Error("Synced failed");
}
} catch (e) {
if (e.message.includes(INVALID_SIGNATURE)) {
if (e.message.includes(INVALID_SIGNATURE_MSG)) {
// Signature verification failed during synchronization.
reportStatus = UptakeTelemetry.STATUS.SIGNATURE_ERROR;
// If sync fails with a signature error, it's likely that our
@ -344,7 +343,7 @@ class RemoteSettingsClient extends EventEmitter {
// We will attempt to fix this by retrieving the whole
// remote collection.
try {
syncResult = await this._retrySyncFromScratch(collection, expectedTimestamp);
syncResult = await this._retrySyncFromScratch(kintoCollection, expectedTimestamp);
} catch (e) {
// If the signature fails again, or if an error occured during wiping out the
// local data, then we report it as a *signature retry* error.
@ -353,7 +352,7 @@ class RemoteSettingsClient extends EventEmitter {
}
} else {
// The sync has thrown, it can be related to metadata, network or a general error.
if (e.message == MISSING_SIGNATURE) {
if (e.message == MISSING_SIGNATURE_MSG) {
// Collection metadata has no signature info, no need to retry.
reportStatus = UptakeTelemetry.STATUS.SIGNATURE_ERROR;
} else if (/unparseable/.test(e.message)) {
@ -372,8 +371,8 @@ class RemoteSettingsClient extends EventEmitter {
throw e;
}
}
const filteredSyncResult = await this._filterSyncResult(collection, syncResult);
// Filter the synchronization results using `filterFunc` (ie. JEXL).
const filteredSyncResult = await this._filterSyncResult(kintoCollection, syncResult);
// If every changed entry is filtered, we don't even fire the event.
if (filteredSyncResult) {
try {
@ -439,7 +438,7 @@ class RemoteSettingsClient extends EventEmitter {
"p384ecdsa=" + signature,
certChain,
this.signerName)) {
throw new Error(INVALID_SIGNATURE + ` (${bucket}/${collection})`);
throw new Error(`${INVALID_SIGNATURE_MSG} (${bucket}/${collection})`);
}
}

View File

@ -19,7 +19,7 @@ RemoteSettingsTimer.prototype = {
// By default, this timer fires once every 24 hours. See the "services.settings.poll_interval" pref.
notify(timer) {
RemoteSettings.pollChanges()
RemoteSettings.pollChanges({ trigger: "timer" })
.catch(e => Cu.reportError(e));
},
};

View File

@ -153,10 +153,10 @@ function remoteSettingsFunction() {
*
* @param {Object} options
. * @param {Object} options.expectedTimestamp (optional) The expected timestamp to be received used by servers for cache busting.
* @param {string} options.trigger (optional) label to identify what triggered this sync (eg. ``"timer"``, default: `"manual"`)
* @returns {Promise} or throws error if something goes wrong.
*/
remoteSettings.pollChanges = async ({ expectedTimestamp } = {}) => {
const trigger = expectedTimestamp ? "broadcast" : "timer";
remoteSettings.pollChanges = async ({ expectedTimestamp, trigger = "manual" } = {}) => {
const telemetryArgs = {
source: TELEMETRY_SOURCE,
trigger,
@ -224,7 +224,7 @@ function remoteSettingsFunction() {
const checkedServerTimeInSeconds = Math.round(serverTimeMillis / 1000);
gPrefs.setIntPref(PREF_SETTINGS_LAST_UPDATE, checkedServerTimeInSeconds);
// Should the clients try to load JSON dump? (mainly disabled in tests)
const loadDump = gPrefs.getBoolPref(PREF_SETTINGS_LOAD_DUMP, true);
// Iterate through the collections version info and initiate a synchronization
@ -326,6 +326,6 @@ var RemoteSettings = remoteSettingsFunction();
var remoteSettingsBroadcastHandler = {
async receivedBroadcastMessage(data, broadcastID) {
return RemoteSettings.pollChanges({ expectedTimestamp: data });
return RemoteSettings.pollChanges({ expectedTimestamp: data, trigger: "broadcast" });
},
};

View File

@ -9,3 +9,4 @@ redo = "*"
requests = "*"
scriptworker = "*"
sh = "*"
awscli = "*"

View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "f584ed9df8ff32e7bbc95a3e15a5222b17a3a8ce87d2a3f6a70b93dec6fa3ca8"
"sha256": "8ae855f2ef3d4d9dcaa6dd796ee176980724e8215eea64494710ef603cadd3c5"
},
"pipfile-spec": 6,
"requires": {
@ -72,18 +72,33 @@
],
"version": "==19.1.0"
},
"awscli": {
"hashes": [
"sha256:06f97a0eb6811d01d635fdee4f7cb78a49a43b92a71a4497c5f9e4ff83ca1af6",
"sha256:23e74b3f9afca7f7fdd27f889109d0069901136bdf34ca84a82de8910668c328"
],
"index": "pypi",
"version": "==1.16.121"
},
"backports.lzma": {
"hashes": [
"sha256:50829db66f0445442f6c796bba0ca62d1f87f54760c4682b6d1489e729a43744"
],
"version": "==0.0.13"
},
"botocore": {
"hashes": [
"sha256:6af473c52d5e3e7ff82de5334e9fee96b2d5ec2df5d78bc00cd9937e2573a7a8",
"sha256:9f5123c7be704b17aeacae99b5842ab17bda1f799dd29134de8c70e0a50a45d7"
],
"version": "==1.12.111"
},
"certifi": {
"hashes": [
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
"sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
"sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
],
"version": "==2018.11.29"
"version": "==2019.3.9"
},
"cffi": {
"hashes": [
@ -132,6 +147,13 @@
],
"version": "==7.0"
},
"colorama": {
"hashes": [
"sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda",
"sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1"
],
"version": "==0.3.9"
},
"construct": {
"hashes": [
"sha256:2271a0efd0798679dea825ff47e22a4c550456a5db0ba8baa82f7eae0af0118c"
@ -164,10 +186,11 @@
},
"datadog": {
"hashes": [
"sha256:cbaa6b4b2b88fd552605e6730f60d5437017bb76d6b701432eaafbc983735b79"
"sha256:9487480fd4b5898b665384f95eeb0cbca4ec998bb58224b7bb60fff3978191ad",
"sha256:d28251dd28f51f27e942bb23fe15349e5223aef75246a94ff7233fb174b74bb9"
],
"index": "pypi",
"version": "==0.26.0"
"version": "==0.27.0"
},
"decorator": {
"hashes": [
@ -190,6 +213,14 @@
],
"version": "==0.7.2"
},
"docutils": {
"hashes": [
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
],
"version": "==0.14"
},
"frozendict": {
"hashes": [
"sha256:774179f22db2ef8a106e9c38d4d1f8503864603db08de2e33be5b778230f6e45"
@ -217,6 +248,13 @@
"markers": "python_version < '3.7'",
"version": "==1.1.0"
},
"jmespath": {
"hashes": [
"sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6",
"sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c"
],
"version": "==0.9.4"
},
"json-e": {
"hashes": [
"sha256:d2914f785d93ecc4f0b2ad6e3f2791f33327eaa740a3c4917d68a9a485dd282d"
@ -247,10 +285,10 @@
},
"mohawk": {
"hashes": [
"sha256:b3f85ffa93a5c7d2f9cc591246ef9f8ac4a9fa716bfd5bae0377699a2d89d78c",
"sha256:e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3"
"sha256:aa57e6626a6ea323ab714779f23734de1d1feca8cb6fc00b65e65ce115c1696a",
"sha256:fca4e34d8f5492f1c33141c98b96e168a089e5692ce65fb747e4bb613f5fe552"
],
"version": "==0.3.4"
"version": "==1.0.0"
},
"multidict": {
"hashes": [
@ -300,6 +338,24 @@
],
"version": "==0.6.0"
},
"pyasn1": {
"hashes": [
"sha256:061442c60842f6d11051d4fdae9bc197b64bd41573a12234a753a0cb80b4f30b",
"sha256:0ee2449bf4c4e535823acc25624c45a8b454f328d59d3f3eeb82d3567100b9bd",
"sha256:5f9fb05c33e53b9a6ee3b1ed1d292043f83df465852bec876e93b47fd2df7eed",
"sha256:65201d28e081f690a32401e6253cca4449ccacc8f3988e811fae66bd822910ee",
"sha256:79b336b073a52fa3c3d8728e78fa56b7d03138ef59f44084de5f39650265b5ff",
"sha256:8ec20f61483764de281e0b4aba7d12716189700debcfa9e7935780850bf527f3",
"sha256:9458d0273f95d035de4c0d5e0643f25daba330582cc71bb554fe6969c015042a",
"sha256:98d97a1833a29ca61cd04a60414def8f02f406d732f9f0bcb49f769faff1b699",
"sha256:b00d7bfb6603517e189d1ad76967c7e805139f63e43096e5f871d1277f50aea5",
"sha256:b06c0cfd708b806ea025426aace45551f91ea7f557e0c2d4fbd9a4b346873ce0",
"sha256:d14d05984581770333731690f5453efd4b82e1e5d824a1d7976b868a2e5c38e8",
"sha256:da2420fe13a9452d8ae97a0e478adde1dee153b11ba832a95b223a2ba01c10f7",
"sha256:da6b43a8c9ae93bc80e2739efb38cc776ba74a886e3e9318d65fe81a8b8a2c6e"
],
"version": "==0.4.5"
},
"pycparser": {
"hashes": [
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
@ -317,6 +373,7 @@
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
],
"markers": "python_version >= '2.7'",
"version": "==2.8.0"
},
"python-gnupg": {
@ -344,11 +401,11 @@
},
"redo": {
"hashes": [
"sha256:29159a717454e1f276c7c509b81357e167a0b9218c68adf8ca8b0499363877ad",
"sha256:703603d61b4ae7fa14a9dce3db22d8789284e99be997f558137612e847ead3cb"
"sha256:36784bf8ae766e14f9db0e377ccfa02835d648321d2007b6ae0bf4fd612c0f94",
"sha256:71161cb0e928d824092a5f16203939bbc0867ce4c4685db263cf22c3ae7634a8"
],
"index": "pypi",
"version": "==2.0.2"
"version": "==2.0.3"
},
"requests": {
"hashes": [
@ -358,13 +415,27 @@
"index": "pypi",
"version": "==2.21.0"
},
"rsa": {
"hashes": [
"sha256:25df4e10c263fb88b5ace923dd84bf9aa7f5019687b5e55382ffcdb8bede9db5",
"sha256:43f682fea81c452c98d09fc316aae12de6d30c4b5c84226642cf8f8fd1c93abd"
],
"version": "==3.4.2"
},
"s3transfer": {
"hashes": [
"sha256:7b9ad3213bff7d357f888e0fab5101b56fa1a0548ee77d121c3a3dbfbef4cb2e",
"sha256:f23d5cb7d862b104401d9021fc82e5fa0e0cf57b7660a1331425aab0c691d021"
],
"version": "==0.2.0"
},
"scriptworker": {
"hashes": [
"sha256:7b3db12bf468473b1549c05b5cc78effd8c89d7721dcb889ca45e971ba21252a",
"sha256:a23b02e86f4ee10e293cc2c5e4b7becd25c5e075286daab0a28d14dc945a810a"
"sha256:9ee316ec0c7540149e53b175634736cd1900c4c14c0d461eb32ce832c77d44f1",
"sha256:d16e7a08d5b00687242252a00e59007babab62e00057a0f16654a3105867db33"
],
"index": "pypi",
"version": "==20.0.1"
"version": "==22.0.0"
},
"sh": {
"hashes": [
@ -383,17 +454,17 @@
},
"slugid": {
"hashes": [
"sha256:6dab3c7eef0bb423fb54cb7752e0f466ddd0ee495b78b763be60e8a27f69e779"
"sha256:a950d98b72691178bdd4d6c52743c4a2aa039207cf7a97d71060a111ff9ba297",
"sha256:aec8b0e01c4ad32e38e12d609eab3ec912fd129aaf6b2ded0199b56a5f8fd67c"
],
"version": "==1.0.7"
"version": "==2.0.0"
},
"taskcluster": {
"hashes": [
"sha256:48ecd4898c7928deddfb34cb1cfe2b2505c68416e6c503f8a7f3dd0572425e96",
"sha256:6d5cf7bdbc09dc48b2d376b418b95c1c157a2d359c4b6b231c1fb14a323c0cc5",
"sha256:e409fce7a72808e4f87dc7baca7a79d8b64d5c5045264b9e197c120cc40e219b"
"sha256:979beeeaa9d24d99a91a05d86c81b5b2bd43defe8fe9d4a775960004bb144314",
"sha256:e8f8e311e071cd0d2f36af136003cb87b09e87fde4a4bea98467334d6f2d5590"
],
"version": "==6.0.0"
"version": "==7.0.0"
},
"taskcluster-urls": {
"hashes": [
@ -425,6 +496,7 @@
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
"sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
],
"markers": "python_version >= '3.4'",
"version": "==1.24.1"
},
"yarl": {

View File

@ -25,6 +25,8 @@ else
METRIC_CMD="echo"
fi
METRIC_PARAMS="--type gauge --no_host"
S3_CACHE_HITS=0
S3_CACHE_MISSES=0
if [ -n "${BRANCH}" ]
then
@ -116,6 +118,7 @@ get_patch(){
if [ -n "${AWS_BUCKET_NAME}" ]; then
BUCKET_PATH="s3://${AWS_BUCKET_NAME}${sha_from}/${sha_to}/${s3_filename}"
if aws s3 ls "${BUCKET_PATH}"; then
((S3_CACHE_HITS++))
# shellcheck disable=SC2086,SC2090
${METRIC_CMD} metric post "${NAMESPACE}.s3_cache.hit" "${S3_CACHE_HITS}" ${METRIC_PARAMS} ${TAGS}
echo "s3 cache hits now ${S3_CACHE_HITS}"
@ -128,6 +131,7 @@ get_patch(){
fi
# Not found, fall through to default error
else
((S3_CACHE_MISSES++))
# shellcheck disable=SC2086,SC2090
${METRIC_CMD} metric post "${NAMESPACE}.s3_cache.miss" "${S3_CACHE_MISSES}" ${METRIC_PARAMS} ${TAGS}
fi

View File

@ -122,6 +122,25 @@ var AboutReader = function(mm, win, articlePromise) {
}
this._loadArticle();
let dropdown = this._toolbarElement;
let elemL10nMap = {
".minus-button": "minus",
".plus-button": "plus",
".content-width-minus-button": "contentwidthminus",
".content-width-plus-button": "contentwidthplus",
".line-height-minus-button": "lineheightminus",
".line-height-plus-button": "lineheightplus",
".light-button": "colorschemelight",
".dark-button": "colorschemedark",
".sepia-button": "colorschemesepia",
};
for (let [selector, stringID] of Object.entries(elemL10nMap)) {
dropdown.querySelector(selector).setAttribute("title",
gStrings.GetStringFromName("aboutReader.toolbar." + stringID));
}
};
AboutReader.prototype = {

View File

@ -1011,7 +1011,7 @@ uptake.remotecontent.result:
settings collection name, ...).
trigger: >
A label to distinguish what triggered the polling/fetching of remote content (eg. "broadcast",
"timer")
"timer", "forced", "manual")
bug_numbers:
- 1517469
record_in_processes: ["main"]

View File

@ -84,7 +84,7 @@ Additional Event Info
The Event API allows to report additional information. We support the following optional fields:
- ``trigger``: A label to distinguish what triggered the polling/fetching of remote content (eg. ``"broadcast"``, ``"timer"``)
- ``trigger``: A label to distinguish what triggered the polling/fetching of remote content (eg. ``"broadcast"``, ``"timer"``, ``"forced"``, ``"manual"``)
.. code-block:: js

View File

@ -15,6 +15,10 @@ gecko_debug = ["gkrust-shared/gecko_debug"]
simd-accel = ["gkrust-shared/simd-accel"]
moz_memory = ["gkrust-shared/moz_memory"]
spidermonkey_rust = ["gkrust-shared/spidermonkey_rust"]
cranelift_x86 = ["gkrust-shared/cranelift_x86"]
cranelift_arm32 = ["gkrust-shared/cranelift_arm32"]
cranelift_arm64 = ["gkrust-shared/cranelift_arm64"]
cranelift_none = ["gkrust-shared/cranelift_none"]
gecko_profiler = ["gkrust-shared/gecko_profiler"]
gecko_profiler_parse_elf = ["gkrust-shared/gecko_profiler_parse_elf"]

View File

@ -15,6 +15,10 @@ gecko_debug = ["gkrust-shared/gecko_debug"]
simd-accel = ["gkrust-shared/simd-accel"]
moz_memory = ["gkrust-shared/moz_memory"]
spidermonkey_rust = ["gkrust-shared/spidermonkey_rust"]
cranelift_x86 = ["gkrust-shared/cranelift_x86"]
cranelift_arm32 = ["gkrust-shared/cranelift_arm32"]
cranelift_arm64 = ["gkrust-shared/cranelift_arm64"]
cranelift_none = ["gkrust-shared/cranelift_none"]
gecko_profiler = ["gkrust-shared/gecko_profiler"]
gecko_profiler_parse_elf = ["gkrust-shared/gecko_profiler_parse_elf"]

View File

@ -28,6 +28,14 @@ if CONFIG['MOZ_MEMORY']:
if CONFIG['ENABLE_WASM_CRANELIFT']:
gkrust_features += ['spidermonkey_rust']
if CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
gkrust_features += ['cranelift_x86']
elif CONFIG['JS_CODEGEN_ARM']:
gkrust_features += ['cranelift_arm32']
elif CONFIG['JS_CODEGEN_ARM64']:
gkrust_features += ['cranelift_arm64']
else:
gkrust_features += ['cranelift_none']
if CONFIG['MOZ_GECKO_PROFILER']:
gkrust_features += ['gecko_profiler']

View File

@ -47,6 +47,10 @@ gecko_debug = ["geckoservo/gecko_debug", "nsstring/gecko_debug"]
simd-accel = ["encoding_c/simd-accel", "encoding_glue/simd-accel"]
moz_memory = ["mp4parse_capi/mp4parse_fallible"]
spidermonkey_rust = ["jsrust_shared"]
cranelift_x86 = ["jsrust_shared/cranelift_x86"]
cranelift_arm32 = ["jsrust_shared/cranelift_arm32"]
cranelift_arm64 = ["jsrust_shared/cranelift_arm64"]
cranelift_none = ["jsrust_shared/cranelift_none"]
gecko_profiler = ["profiler_helper"]
gecko_profiler_parse_elf = ["profiler_helper/parse_elf"]

View File

@ -46,3 +46,14 @@ readerView.enter=Enter Reader View
readerView.enter.accesskey=R
readerView.close=Close Reader View
readerView.close.accesskey=R
# These are used as tooltips in Type Control
aboutReader.toolbar.minus = Decrease Font Size
aboutReader.toolbar.plus = Increase Font Size
aboutReader.toolbar.contentwidthminus = Decrease Content Width
aboutReader.toolbar.contentwidthplus = Increase Content Width
aboutReader.toolbar.lineheightminus = Decrease Line Height
aboutReader.toolbar.lineheightplus = Increase Line Height
aboutReader.toolbar.colorschemelight = Color Scheme Light
aboutReader.toolbar.colorschemedark = Color Scheme Dark
aboutReader.toolbar.colorschemesepia = Color Scheme Sepia