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

This commit is contained in:
Andreea Pavel 2018-07-30 19:35:30 +03:00
commit be1d7773cc
41 changed files with 1040 additions and 685 deletions

View File

@ -79,7 +79,7 @@ add_task(async function startup() {
},
"layout.css.prefixes.webkit": {
min: 135,
max: 150,
max: 170,
},
"browser.search.log": {
min: 100,

View File

@ -35,4 +35,8 @@ ac_add_options --disable-sandbox
# while the build otherwise identifies as "nightly" to receive its updates.
export MOZ_TELEMETRY_REPORTING=1
# Disable stack instrumentation until we can tackle bug 1477490
export CFLAGS="-mllvm -asan-stack=0"
export CXXFLAGS="-mllvm -asan-stack=0"
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -9092,10 +9092,6 @@ exports.PSEUDO_ELEMENTS = [
* exposed for testing purposes.
*/
exports.PREFERENCES = [
[
"background-blend-mode",
"layout.css.background-blend-mode.enabled"
],
[
"box-decoration-break",
"layout.css.box-decoration-break.enabled"
@ -9116,10 +9112,6 @@ exports.PREFERENCES = [
"font-optical-sizing",
"layout.css.font-variations.enabled"
],
[
"font-variation-settings",
"layout.css.font-variations.enabled"
],
[
"image-orientation",
"layout.css.image-orientation.enabled"
@ -9141,12 +9133,20 @@ exports.PREFERENCES = [
"layout.css.osx-font-smoothing.enabled"
],
[
"overflow-clip-box-block",
"layout.css.overflow-clip-box.enabled"
"scroll-behavior",
"layout.css.scroll-behavior.property-enabled"
],
[
"overflow-clip-box-inline",
"layout.css.overflow-clip-box.enabled"
"text-justify",
"layout.css.text-justify.enabled"
],
[
"touch-action",
"layout.css.touch_action.enabled"
],
[
"transform-box",
"svg.transform-box.enabled"
],
[
"overscroll-behavior-x",
@ -9156,6 +9156,26 @@ exports.PREFERENCES = [
"overscroll-behavior-y",
"layout.css.overscroll-behavior.enabled"
],
[
"scroll-snap-type-x",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type-y",
"layout.css.scroll-snap.enabled"
],
[
"shape-image-threshold",
"layout.css.shape-outside.enabled"
],
[
"background-blend-mode",
"layout.css.background-blend-mode.enabled"
],
[
"font-variation-settings",
"layout.css.font-variations.enabled"
],
[
"rotate",
"layout.css.individual-transform.enabled"
@ -9164,17 +9184,25 @@ exports.PREFERENCES = [
"scale",
"layout.css.individual-transform.enabled"
],
[
"scroll-behavior",
"layout.css.scroll-behavior.property-enabled"
],
[
"scroll-snap-coordinate",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-destination",
"layout.css.scroll-snap.enabled"
"shape-outside",
"layout.css.shape-outside.enabled"
],
[
"translate",
"layout.css.individual-transform.enabled"
],
[
"overflow-clip-box-block",
"layout.css.overflow-clip-box.enabled"
],
[
"overflow-clip-box-inline",
"layout.css.overflow-clip-box.enabled"
],
[
"scroll-snap-points-x",
@ -9185,11 +9213,7 @@ exports.PREFERENCES = [
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type-x",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-type-y",
"scroll-snap-destination",
"layout.css.scroll-snap.enabled"
],
[
@ -9200,218 +9224,38 @@ exports.PREFERENCES = [
"scrollbar-track-color",
"layout.css.scrollbar-colors.enabled"
],
[
"shape-image-threshold",
"layout.css.shape-outside.enabled"
],
[
"shape-margin",
"layout.css.shape-outside.enabled"
],
[
"shape-outside",
"layout.css.shape-outside.enabled"
],
[
"-webkit-text-fill-color",
"layout.css.prefixes.webkit"
],
[
"text-justify",
"layout.css.text-justify.enabled"
],
[
"-webkit-text-stroke-color",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-stroke-width",
"layout.css.prefixes.webkit"
],
[
"touch-action",
"layout.css.touch_action.enabled"
"-webkit-text-fill-color",
"layout.css.prefixes.webkit"
],
[
"transform-box",
"svg.transform-box.enabled"
],
[
"translate",
"layout.css.individual-transform.enabled"
"-webkit-text-stroke-color",
"layout.css.prefixes.webkit"
],
[
"overflow-clip-box",
"layout.css.overflow-clip-box.enabled"
],
[
"overscroll-behavior",
"layout.css.overscroll-behavior.enabled"
],
[
"scroll-snap-type",
"layout.css.scroll-snap.enabled"
],
[
"overscroll-behavior",
"layout.css.overscroll-behavior.enabled"
],
[
"-webkit-text-stroke",
"layout.css.prefixes.webkit"
],
[
"-moz-animation",
"layout.css.prefixes.animations"
],
[
"-moz-animation-delay",
"layout.css.prefixes.animations"
],
[
"-moz-animation-direction",
"layout.css.prefixes.animations"
],
[
"-moz-animation-duration",
"layout.css.prefixes.animations"
],
[
"-moz-animation-fill-mode",
"layout.css.prefixes.animations"
],
[
"-moz-animation-iteration-count",
"layout.css.prefixes.animations"
],
[
"-moz-animation-name",
"layout.css.prefixes.animations"
],
[
"-moz-animation-play-state",
"layout.css.prefixes.animations"
],
[
"-moz-animation-timing-function",
"layout.css.prefixes.animations"
],
[
"-moz-backface-visibility",
"layout.css.prefixes.transforms"
],
[
"-moz-border-image",
"layout.css.prefixes.border-image"
],
[
"-moz-box-sizing",
"layout.css.prefixes.box-sizing"
],
[
"-moz-column-span",
"layout.css.column-span.enabled"
],
[
"-moz-font-feature-settings",
"layout.css.prefixes.font-features"
],
[
"-moz-font-language-override",
"layout.css.prefixes.font-features"
],
[
"-moz-perspective",
"layout.css.prefixes.transforms"
],
[
"-moz-perspective-origin",
"layout.css.prefixes.transforms"
],
[
"-moz-transform",
"layout.css.prefixes.transforms"
],
[
"-moz-transform-origin",
"layout.css.prefixes.transforms"
],
[
"-moz-transform-style",
"layout.css.prefixes.transforms"
],
[
"-moz-transition",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-delay",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-duration",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-property",
"layout.css.prefixes.transitions"
],
[
"-moz-transition-timing-function",
"layout.css.prefixes.transitions"
],
[
"-webkit-align-content",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-items",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-self",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-delay",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-direction",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-duration",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-fill-mode",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-iteration-count",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-name",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-play-state",
"layout.css.prefixes.webkit"
],
[
"-webkit-animation-timing-function",
"layout.css.prefixes.webkit"
],
[
"-webkit-appearance",
"layout.css.webkit-appearance.enabled"
],
[
"-webkit-backface-visibility",
"layout.css.prefixes.webkit"
],
[
"-webkit-background-clip",
"layout.css.prefixes.webkit"
@ -9425,7 +9269,11 @@ exports.PREFERENCES = [
"layout.css.prefixes.webkit"
],
[
"-webkit-border-bottom-left-radius",
"-webkit-border-top-left-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-top-right-radius",
"layout.css.prefixes.webkit"
],
[
@ -9433,19 +9281,279 @@ exports.PREFERENCES = [
"layout.css.prefixes.webkit"
],
[
"-webkit-border-image",
"-webkit-border-bottom-left-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-radius",
"-moz-transition-duration",
"layout.css.prefixes.transitions"
],
[
"-webkit-transition-duration",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-top-left-radius",
"-moz-transition-timing-function",
"layout.css.prefixes.transitions"
],
[
"-webkit-transition-timing-function",
"layout.css.prefixes.webkit"
],
[
"-webkit-border-top-right-radius",
"-moz-transition-property",
"layout.css.prefixes.transitions"
],
[
"-webkit-transition-property",
"layout.css.prefixes.webkit"
],
[
"-moz-transition-delay",
"layout.css.prefixes.transitions"
],
[
"-webkit-transition-delay",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-name",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-name",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-duration",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-duration",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-timing-function",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-timing-function",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-iteration-count",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-iteration-count",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-direction",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-direction",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-play-state",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-play-state",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-fill-mode",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-fill-mode",
"layout.css.prefixes.webkit"
],
[
"-moz-animation-delay",
"layout.css.prefixes.animations"
],
[
"-webkit-animation-delay",
"layout.css.prefixes.webkit"
],
[
"-moz-transform",
"layout.css.prefixes.transforms"
],
[
"-webkit-transform",
"layout.css.prefixes.webkit"
],
[
"-moz-perspective",
"layout.css.prefixes.transforms"
],
[
"-webkit-perspective",
"layout.css.prefixes.webkit"
],
[
"-moz-perspective-origin",
"layout.css.prefixes.transforms"
],
[
"-webkit-perspective-origin",
"layout.css.prefixes.webkit"
],
[
"-moz-backface-visibility",
"layout.css.prefixes.transforms"
],
[
"-webkit-backface-visibility",
"layout.css.prefixes.webkit"
],
[
"-moz-transform-style",
"layout.css.prefixes.transforms"
],
[
"-webkit-transform-style",
"layout.css.prefixes.webkit"
],
[
"-moz-transform-origin",
"layout.css.prefixes.transforms"
],
[
"-webkit-transform-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-appearance",
"layout.css.webkit-appearance.enabled"
],
[
"-moz-column-span",
"layout.css.column-span.enabled"
],
[
"-webkit-box-shadow",
"layout.css.prefixes.webkit"
],
[
"-webkit-filter",
"layout.css.prefixes.webkit"
],
[
"-moz-font-feature-settings",
"layout.css.prefixes.font-features"
],
[
"-moz-font-language-override",
"layout.css.prefixes.font-features"
],
[
"-webkit-text-size-adjust",
"layout.css.prefixes.webkit"
],
[
"offset-block-start",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-block-end",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-inline-start",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-inline-end",
"layout.css.offset-logical-properties.enabled"
],
[
"-webkit-flex-direction",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-wrap",
"layout.css.prefixes.webkit"
],
[
"-webkit-justify-content",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-content",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-items",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-grow",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-shrink",
"layout.css.prefixes.webkit"
],
[
"-webkit-align-self",
"layout.css.prefixes.webkit"
],
[
"-webkit-order",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-basis",
"layout.css.prefixes.webkit"
],
[
"-moz-box-sizing",
"layout.css.prefixes.box-sizing"
],
[
"-webkit-box-sizing",
"layout.css.prefixes.webkit"
],
[
"-webkit-user-select",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-repeat",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-x",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-y",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-clip",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-size",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-composite",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-image",
"layout.css.prefixes.webkit"
],
[
@ -9460,10 +9568,6 @@ exports.PREFERENCES = [
"-webkit-box-flex",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-ordinal-group",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-orient",
"layout.css.prefixes.webkit"
@ -9473,27 +9577,35 @@ exports.PREFERENCES = [
"layout.css.prefixes.webkit"
],
[
"-webkit-box-shadow",
"-webkit-box-ordinal-group",
"layout.css.prefixes.webkit"
],
[
"-webkit-box-sizing",
"-webkit-border-radius",
"layout.css.prefixes.webkit"
],
[
"-webkit-filter",
"-moz-border-image",
"layout.css.prefixes.border-image"
],
[
"-webkit-border-image",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex",
"-moz-transition",
"layout.css.prefixes.transitions"
],
[
"-webkit-transition",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-basis",
"layout.css.prefixes.webkit"
"-moz-animation",
"layout.css.prefixes.animations"
],
[
"-webkit-flex-direction",
"-webkit-animation",
"layout.css.prefixes.webkit"
],
[
@ -9501,127 +9613,15 @@ exports.PREFERENCES = [
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-grow",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-shrink",
"layout.css.prefixes.webkit"
],
[
"-webkit-flex-wrap",
"layout.css.prefixes.webkit"
],
[
"-webkit-justify-content",
"-webkit-flex",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-clip",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-composite",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-image",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-x",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-position-y",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-repeat",
"layout.css.prefixes.webkit"
],
[
"-webkit-mask-size",
"layout.css.prefixes.webkit"
],
[
"-webkit-order",
"layout.css.prefixes.webkit"
],
[
"-webkit-perspective",
"layout.css.prefixes.webkit"
],
[
"-webkit-perspective-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-text-size-adjust",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform-origin",
"layout.css.prefixes.webkit"
],
[
"-webkit-transform-style",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-delay",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-duration",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-property",
"layout.css.prefixes.webkit"
],
[
"-webkit-transition-timing-function",
"layout.css.prefixes.webkit"
],
[
"-webkit-user-select",
"layout.css.prefixes.webkit"
],
[
"offset-block-end",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-block-start",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-inline-end",
"layout.css.offset-logical-properties.enabled"
],
[
"offset-inline-start",
"layout.css.offset-logical-properties.enabled"
]
];

View File

@ -37,7 +37,6 @@
// 2 == downgrade to session
// 3 == limit lifetime to N days
static const uint32_t ACCEPT_NORMALLY = 0;
static const uint32_t ASK_BEFORE_ACCEPT = 1;
static const uint32_t ACCEPT_SESSION = 2;
static const uint32_t ACCEPT_FOR_N_DAYS = 3;

View File

@ -509,6 +509,10 @@ Arena::arenaAllocatedDuringGC()
void
GCRuntime::setParallelAtomsAllocEnabled(bool enabled)
{
// This can only be changed on the main thread otherwise we could race.
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
MOZ_ASSERT(enabled == rt->hasHelperThreadZones());
atomsZone->arenas.setParallelAllocEnabled(enabled);
}

View File

@ -2254,7 +2254,7 @@ MarkStack::poisonUnused()
static_assert((JS_FRESH_MARK_STACK_PATTERN & TagMask) > LastTag,
"The mark stack poison pattern must not look like a valid tagged pointer");
JS_POISON(&stack()[topIndex_],
JS_POISON(stack().begin() + topIndex_,
JS_FRESH_MARK_STACK_PATTERN,
stack().capacity() - topIndex_,
MemCheckKind::MakeUndefined);

View File

@ -0,0 +1,6 @@
fullcompartmentchecks(true);
var dbg = new Debugger();
var g = newGlobal();
g.eval("function f(){}");
dbg.addDebuggee(g);
dbg.findScripts();

View File

@ -0,0 +1,22 @@
let count = 0;
function testMathyFunction(f, inputs) {
for (var j = 0; j < inputs.length; ++j)
for (var k = 0; k < inputs.length; ++k) {
let a = f(inputs[j], inputs[k]);
count += 1;
print("Number " + count + ": " + a + " (inputs "+inputs[j]+","+inputs[k]+")");
}
}
mathy0 = function(x, y) {
return (x / (y ? x : -Number.MAX_SAFE_INTEGER) > Math.fround(+y & +0x100000000) ** Math.fround(y))
}
testMathyFunction(mathy0, /*MARR*/ [
[1], , , [1],
[1], , [1], , , [1], , [1], , , [1],
[1], , [1], , , [1],
[1], , [1], , [1],
[1],
[1], , -1 / 0
])
testMathyFunction(mathy0, [, -Number.MAX_VALUE, Number.MIN_SAFE_INTEGER, 0x100000001, 0x07fffffff, -0x07fffffff, 0 / 0, Number.MIN_VALUE, -0x0ffffffff, Number.MAX_SAFE_INTEGER, 0x0ffffffff, -0x100000000, , 1 / 0, 0x080000000, -1 / 0, 0x100000000])

View File

@ -0,0 +1,6 @@
var lfRandom = 0;
var i = 0;
while (i < 1000) {
lfRunTypeId = 4 + (lfRandom % 2);
i++;
}

View File

@ -0,0 +1,16 @@
let lfPreamble = `
assertEq = function(a,b) {
try { print(a); print(b); } catch(exc) {}
}
`;
evaluate(lfPreamble, {});
var a = [1, 2, 3];
var b = [4, 5, 6];
function testFold() {
for (var i = 0; i < 10; i++) {
var x = a[i];
var z = b[i];
if (((x / x) | 0) < 3) assertEq(x !== z, true);
}
}
for (var i = 0; i < 10; i++) testFold();

View File

@ -0,0 +1,4 @@
function f(v, e) {
for (var i = 2; i < 9; i++) v %= e;
}
f(0, 1);

View File

@ -0,0 +1,7 @@
const handler = {}
function testArray(arr) {
let proxy = new Proxy(arr, handler)
proxy.sort((x, y) => 1 * x - y);
arr.sort((x, y) => 1 * x - y);
}
testArray([5, (this), 2, 99]);

View File

@ -0,0 +1,3 @@
gczeal(0);
gcparam("markStackLimit", 1);
startgc(1);

View File

@ -47,6 +47,7 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler
bool makesGCCalls_;
MOZ_MUST_USE bool callVM(MacroAssembler& masm, const VMFunction& fun);
MOZ_MUST_USE bool tailCallVM(MacroAssembler& masm, const VMFunction& fun);
MOZ_MUST_USE bool callTypeUpdateIC(Register obj, ValueOperand val, Register scratch,
LiveGeneralRegisterSet saveRegs);
@ -158,6 +159,20 @@ BaselineCacheIRCompiler::callVM(MacroAssembler& masm, const VMFunction& fun)
return true;
}
bool
BaselineCacheIRCompiler::tailCallVM(MacroAssembler& masm, const VMFunction& fun)
{
MOZ_ASSERT(!inStubFrame_);
TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(fun);
MOZ_ASSERT(fun.expectTailCall == TailCall);
MOZ_ASSERT(engine_ == ICStubEngine::Baseline);
size_t argSize = fun.explicitStackSlots() * sizeof(void*);
EmitBaselineTailCallVM(code, masm, argSize);
return true;
}
JitCode*
BaselineCacheIRCompiler::compile()
{
@ -2395,3 +2410,52 @@ ICCacheIR_Updated::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitor
stubInfo->copyStubData(&other, res);
return res;
}
typedef JSString* (*ConcatStringsFn)(JSContext*, HandleString, HandleString);
static const VMFunction ConcatStringsInfo =
FunctionInfo<ConcatStringsFn>(ConcatStrings<CanGC>, "ConcatStrings", NonTailCall);
bool
BaselineCacheIRCompiler::emitCallStringConcatResult()
{
AutoOutputRegister output(*this);
Register lhs = allocator.useRegister(masm, reader.stringOperandId());
Register rhs = allocator.useRegister(masm, reader.stringOperandId());
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
AutoStubFrame stubFrame(*this);
stubFrame.enter(masm, scratch);
masm.push(rhs);
masm.push(lhs);
if (!callVM(masm, ConcatStringsInfo))
return false;
masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg());
stubFrame.leave(masm);
return true;
}
bool
BaselineCacheIRCompiler::emitCallStringObjectConcatResult()
{
ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId());
ValueOperand rhs = allocator.useValueRegister(masm, reader.valOperandId());
allocator.discardStack(masm);
// For the expression decompiler
EmitRestoreTailCallReg(masm);
masm.pushValue(lhs);
masm.pushValue(rhs);
masm.pushValue(rhs);
masm.pushValue(lhs);
if (!tailCallVM(masm, DoConcatStringObjectInfo))
return false;
return true;
}

View File

@ -319,6 +319,79 @@ BaselineInspector::dimorphicStub(jsbytecode* pc, ICStub** pfirst, ICStub** pseco
return true;
}
// Process the type guards in the stub in order to reveal the
// underlying operation.
static void
SkipBinaryGuards(CacheIRReader& reader)
{
while (true) {
// Two skip opcodes
if (reader.matchOp(CacheOp::GuardIsInt32) ||
reader.matchOp(CacheOp::GuardType) ||
reader.matchOp(CacheOp::TruncateDoubleToUInt32) ||
reader.matchOp(CacheOp::GuardIsBoolean))
{
reader.skip(); // Skip over operandId
reader.skip(); // Skip over result/type.
continue;
}
// One skip
if (reader.matchOp(CacheOp::GuardIsNumber) ||
reader.matchOp(CacheOp::GuardIsString) ||
reader.matchOp(CacheOp::GuardIsObject))
{
reader.skip(); // Skip over operandId
continue;
}
return;
}
}
static MIRType
ParseCacheIRStub(ICStub* stub)
{
ICCacheIR_Regular* cacheirStub = stub->toCacheIR_Regular();
CacheIRReader reader(cacheirStub->stubInfo());
SkipBinaryGuards(reader);
switch (reader.readOp()) {
case CacheOp::LoadUndefinedResult:
return MIRType::Undefined;
case CacheOp::LoadBooleanResult:
return MIRType::Boolean;
case CacheOp::LoadStringResult:
case CacheOp::CallStringConcatResult:
case CacheOp::CallStringObjectConcatResult:
return MIRType::String;
case CacheOp::DoubleAddResult:
case CacheOp::DoubleSubResult:
case CacheOp::DoubleMulResult:
case CacheOp::DoubleDivResult:
case CacheOp::DoubleModResult:
case CacheOp::DoubleNegationResult:
return MIRType::Double;
case CacheOp::Int32AddResult:
case CacheOp::Int32SubResult:
case CacheOp::Int32MulResult:
case CacheOp::Int32DivResult:
case CacheOp::Int32ModResult:
case CacheOp::Int32BitOrResult:
case CacheOp::Int32BitXorResult:
case CacheOp::Int32BitAndResult:
case CacheOp::Int32LeftShiftResult:
case CacheOp::Int32RightShiftResult:
case CacheOp::Int32URightShiftResult:
case CacheOp::Int32NotResult:
case CacheOp::Int32NegationResult:
return MIRType::Int32;
case CacheOp::LoadValueResult:
return MIRType::Value;
default:
MOZ_CRASH("Unknown op");
return MIRType::None;
}
}
MIRType
BaselineInspector::expectedResultType(jsbytecode* pc)
{
@ -344,6 +417,8 @@ BaselineInspector::expectedResultType(jsbytecode* pc)
case ICStub::BinaryArith_StringConcat:
case ICStub::BinaryArith_StringObjectConcat:
return MIRType::String;
case ICStub::CacheIR_Regular:
return ParseCacheIRStub(stub);
default:
return MIRType::None;
}
@ -435,6 +510,19 @@ TryToSpecializeBinaryArithOp(ICStub** stubs,
case ICStub::BinaryArith_DoubleWithInt32:
sawDouble = true;
break;
case ICStub::CacheIR_Regular:
switch (ParseCacheIRStub(stubs[i])) {
case MIRType::Double:
sawDouble = true;
break;
case MIRType::Int32:
sawInt32 = true;
break;
default:
sawOther = true;
break;
}
break;
default:
sawOther = true;
break;

View File

@ -5104,14 +5104,25 @@ bool
BinaryArithIRGenerator::tryAttachStub()
{
// Attempt common case first
if (tryAttachInt32())
return true;
if (tryAttachDouble())
return true;
if (tryAttachDoubleWithInt32())
return true;
if (tryAttachBooleanWithInt32())
return true;
if (tryAttachDoubleWithInt32())
return true;
// This attempt must come after tryAttachDoubleWithInt32
// and tryAttachInt32, as it will attach for those cases
if (tryAttachDouble())
return true;
if (tryAttachStringConcat())
return true;
if (tryAttachStringObjectConcat())
return true;
trackAttached(IRGenerator::NotAttached);
return false;
@ -5120,14 +5131,18 @@ BinaryArithIRGenerator::tryAttachStub()
bool
BinaryArithIRGenerator::tryAttachDoubleWithInt32()
{
// ONLY bit-wise
if (op_ != JSOP_BITOR && op_ != JSOP_BITXOR && op_ != JSOP_BITAND)
return false;
if (!(lhs_.isInt32() && rhs_.isDouble()) ||
!(lhs_.isDouble() && rhs_.isInt32()) ||
!res_.isInt32())
// Check guard conditions
if ((!(lhs_.isInt32() && rhs_.isDouble()) &&
!(lhs_.isDouble() && rhs_.isInt32())))
return false;
// output always int
MOZ_ASSERT(res_.isInt32());
ValOperandId lhsId(writer.setInputOperandId(0));
ValOperandId rhsId(writer.setInputOperandId(1));
@ -5150,7 +5165,7 @@ BinaryArithIRGenerator::tryAttachDoubleWithInt32()
trackAttached("BinaryArith.Int32Double.BitAnd");
break;
default:
MOZ_CRASH("Unhandled op in tryAttachInt32");
MOZ_CRASH("Unhandled op in tryAttachDoubleWithInt32");
}
writer.returnFromIC();
@ -5160,12 +5175,14 @@ BinaryArithIRGenerator::tryAttachDoubleWithInt32()
bool
BinaryArithIRGenerator::tryAttachDouble()
{
// Check valid opcodes
if (op_ != JSOP_ADD && op_ != JSOP_SUB &&
op_ != JSOP_MUL && op_ != JSOP_DIV &&
op_ != JSOP_MOD)
return false;
if (!lhs_.isDouble() || !rhs_.isDouble() || !res_.isDouble())
// Check guard conditions
if (!lhs_.isNumber() || !rhs_.isNumber())
return false;
if (!cx_->runtime()->jitSupportsFloatingPoint)
@ -5208,7 +5225,17 @@ BinaryArithIRGenerator::tryAttachDouble()
bool
BinaryArithIRGenerator::tryAttachInt32()
{
if (!lhs_.isInt32() || !rhs_.isInt32() || op_ == JSOP_POW)
// Check guard conditions
if (!lhs_.isInt32() || !rhs_.isInt32())
return false;
// These ICs will failure() if result can't be encoded in an Int32:
// If sample result is not Int32, we should avoid IC.
if (!res_.isInt32())
return false;
// Unsupported OP
if (op_ == JSOP_POW)
return false;
ValOperandId lhsId(writer.setInputOperandId(0));
@ -5270,14 +5297,73 @@ BinaryArithIRGenerator::tryAttachInt32()
return true;
}
bool
BinaryArithIRGenerator::tryAttachStringConcat()
{
// Only Addition
if (op_ != JSOP_ADD)
return false;
// Check guards
if (!lhs_.isString() || !rhs_.isString())
return false;
ValOperandId lhsId(writer.setInputOperandId(0));
ValOperandId rhsId(writer.setInputOperandId(1));
StringOperandId lhsStrId = writer.guardIsString(lhsId);
StringOperandId rhsStrId = writer.guardIsString(rhsId);
writer.callStringConcatResult(lhsStrId, rhsStrId);
writer.returnFromIC();
trackAttached("BinaryArith.StringConcat");
return true;
}
bool
BinaryArithIRGenerator::tryAttachStringObjectConcat()
{
// Only Addition
if (op_ != JSOP_ADD)
return false;
// Check Guards
if (!(lhs_.isObject() && rhs_.isString()) &&
!(lhs_.isString() && rhs_.isObject()))
return false;
ValOperandId lhsId(writer.setInputOperandId(0));
ValOperandId rhsId(writer.setInputOperandId(1));
// This guard is actually overly tight, as the runtime
// helper can handle lhs or rhs being a string, so long
// as the other is an object.
if (lhs_.isString()) {
writer.guardIsString(lhsId);
writer.guardIsObject(rhsId);
} else {
writer.guardIsObject(lhsId);
writer.guardIsString(rhsId);
}
writer.callStringObjectConcatResult(lhsId, rhsId);
writer.returnFromIC();
trackAttached("BinaryArith.StringObjectConcat");
return true;
}
bool
BinaryArithIRGenerator::tryAttachBooleanWithInt32()
{
// Check operation
if (op_ != JSOP_ADD && op_ != JSOP_SUB &&
op_ != JSOP_BITOR && op_ != JSOP_BITAND &&
op_ != JSOP_BITXOR && op_ != JSOP_MUL && op_ != JSOP_DIV)
return false;
// Check guards
if (!(lhs_.isBoolean() && (rhs_.isBoolean() || rhs_.isInt32())) &&
!(rhs_.isBoolean() && (lhs_.isBoolean() || lhs_.isInt32())))
return false;

View File

@ -61,7 +61,7 @@ enum class BaselineCacheIRStubKind;
// An OperandId represents either a cache input or a value returned by a
// CacheIR instruction. Most code should use the ValOperandId and ObjOperandId
// classes below. The ObjOperandId class represents an operand that's known to
// be an object.
// be an object, just as StringOperandId represents a known string, etc.
class OperandId
{
protected:
@ -318,6 +318,8 @@ extern const char* CacheKindNames[];
_(LoadValueResult) \
\
_(CallStringSplitResult) \
_(CallStringConcatResult) \
_(CallStringObjectConcatResult) \
\
_(CompareStringResult) \
_(CompareObjectResult) \
@ -1230,6 +1232,14 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
writeOp(CacheOp::LoadValueResult);
addStubField(val.asRawBits(), StubField::Type::Value);
}
void callStringConcatResult(StringOperandId lhs, StringOperandId rhs) {
writeOpWithOperandId(CacheOp::CallStringConcatResult, lhs);
writeOperandId(rhs);
}
void callStringObjectConcatResult(ValOperandId lhs, ValOperandId rhs) {
writeOpWithOperandId(CacheOp::CallStringObjectConcatResult, lhs);
writeOperandId(rhs);
}
void callStringSplitResult(StringOperandId str, StringOperandId sep, ObjectGroup* group) {
writeOp(CacheOp::CallStringSplitResult);
writeOperandId(str);
@ -1880,6 +1890,8 @@ class MOZ_RAII BinaryArithIRGenerator : public IRGenerator
bool tryAttachDouble();
bool tryAttachDoubleWithInt32();
bool tryAttachBooleanWithInt32();
bool tryAttachStringConcat();
bool tryAttachStringObjectConcat();
public:
BinaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState::Mode,

View File

@ -2529,3 +2529,57 @@ IonIC::attachCacheIRStub(JSContext* cx, const CacheIRWriter& writer, CacheKind k
attachStub(newStub, code);
*attached = true;
}
typedef JSString* (*ConcatStringsFn)(JSContext*, HandleString, HandleString);
static const VMFunction ConcatStringsInfo =
FunctionInfo<ConcatStringsFn>(ConcatStrings<CanGC>, "ConcatStrings", NonTailCall);
bool
IonCacheIRCompiler::emitCallStringConcatResult()
{
AutoSaveLiveRegisters save(*this);
AutoOutputRegister output(*this);
Register lhs = allocator.useRegister(masm, reader.stringOperandId());
Register rhs = allocator.useRegister(masm, reader.stringOperandId());
allocator.discardStack(masm);
prepareVMCall(masm, save);
masm.Push(rhs);
masm.Push(lhs);
if (!callVM(masm, ConcatStringsInfo))
return false;
masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg());
return true;
}
typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue,
MutableHandleValue);
const VMFunction DoIonConcatStringObjectInfo =
FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, "DoIonConcatStringObject");
bool
IonCacheIRCompiler::emitCallStringObjectConcatResult()
{
AutoSaveLiveRegisters save(*this);
AutoOutputRegister output(*this);
ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId());
ValueOperand rhs = allocator.useValueRegister(masm, reader.valOperandId());
allocator.discardStack(masm);
prepareVMCall(masm, save);
masm.Push(rhs);
masm.Push(lhs);
if (!callVM(masm, DoIonConcatStringObjectInfo))
return false;
masm.storeCallResultValue(output);
return true;
}

View File

@ -977,60 +977,9 @@ ICBinaryArith_StringConcat::Compiler::generateStubCode(MacroAssembler& masm)
return true;
}
static JSString*
ConvertObjectToStringForConcat(JSContext* cx, HandleValue obj)
{
MOZ_ASSERT(obj.isObject());
RootedValue rootedObj(cx, obj);
if (!ToPrimitive(cx, &rootedObj))
return nullptr;
return ToString<CanGC>(cx, rootedObj);
}
static bool
DoConcatStringObject(JSContext* cx, bool lhsIsString, HandleValue lhs, HandleValue rhs,
MutableHandleValue res)
{
JSString* lstr = nullptr;
JSString* rstr = nullptr;
if (lhsIsString) {
// Convert rhs first.
MOZ_ASSERT(lhs.isString() && rhs.isObject());
rstr = ConvertObjectToStringForConcat(cx, rhs);
if (!rstr)
return false;
// lhs is already string.
lstr = lhs.toString();
} else {
MOZ_ASSERT(rhs.isString() && lhs.isObject());
// Convert lhs first.
lstr = ConvertObjectToStringForConcat(cx, lhs);
if (!lstr)
return false;
// rhs is already string.
rstr = rhs.toString();
}
JSString* str = ConcatStrings<NoGC>(cx, lstr, rstr);
if (!str) {
RootedString nlstr(cx, lstr), nrstr(cx, rstr);
str = ConcatStrings<CanGC>(cx, nlstr, nrstr);
if (!str)
return false;
}
// Technically, we need to call TypeScript::MonitorString for this PC, however
// it was called when this stub was attached so it's OK.
res.setString(str);
return true;
}
typedef bool (*DoConcatStringObjectFn)(JSContext*, bool lhsIsString, HandleValue, HandleValue,
typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoConcatStringObjectInfo =
static const VMFunction DoSharedConcatStringObjectInfo =
FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, "DoConcatStringObject", TailCall,
PopValues(2));
@ -1056,8 +1005,8 @@ ICBinaryArith_StringObjectConcat::Compiler::generateStubCode(MacroAssembler& mas
// Push arguments.
masm.pushValue(R1);
masm.pushValue(R0);
masm.push(Imm32(lhsIsString_));
if (!tailCallVM(DoConcatStringObjectInfo, masm))
if (!tailCallVM(DoSharedConcatStringObjectInfo, masm))
return false;
// Failure case - jump to next stub

View File

@ -1893,5 +1893,63 @@ typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue,
const VMFunction SetObjectElementInfo =
FunctionInfo<SetObjectElementFn>(js::SetObjectElement, "SetObjectElement");
static JSString*
ConvertObjectToStringForConcat(JSContext* cx, HandleValue obj)
{
MOZ_ASSERT(obj.isObject());
RootedValue rootedObj(cx, obj);
if (!ToPrimitive(cx, &rootedObj))
return nullptr;
return ToString<CanGC>(cx, rootedObj);
}
bool
DoConcatStringObject(JSContext* cx, HandleValue lhs, HandleValue rhs,
MutableHandleValue res)
{
JSString* lstr = nullptr;
JSString* rstr = nullptr;
if (lhs.isString()) {
// Convert rhs first.
MOZ_ASSERT(lhs.isString() && rhs.isObject());
rstr = ConvertObjectToStringForConcat(cx, rhs);
if (!rstr)
return false;
// lhs is already string.
lstr = lhs.toString();
} else {
MOZ_ASSERT(rhs.isString() && lhs.isObject());
// Convert lhs first.
lstr = ConvertObjectToStringForConcat(cx, lhs);
if (!lstr)
return false;
// rhs is already string.
rstr = rhs.toString();
}
JSString* str = ConcatStrings<NoGC>(cx, lstr, rstr);
if (!str) {
RootedString nlstr(cx, lstr), nrstr(cx, rstr);
str = ConcatStrings<CanGC>(cx, nlstr, nrstr);
if (!str)
return false;
}
// Technically, we need to call TypeScript::MonitorString for this PC, however
// it was called when this stub was attached so it's OK.
res.setString(str);
return true;
}
typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue,
MutableHandleValue);
const VMFunction DoConcatStringObjectInfo =
FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, "DoConcatStringObject", TailCall, PopValues(2));
} // namespace jit
} // namespace js

View File

@ -953,6 +953,13 @@ CloseIteratorFromIon(JSContext* cx, JSObject* obj);
extern const VMFunction SetObjectElementInfo;
bool
DoConcatStringObject(JSContext* cx, HandleValue lhs, HandleValue rhs,
MutableHandleValue res);
// This is the tailcall version of DoConcatStringObject
extern const VMFunction DoConcatStringObjectInfo;
extern const VMFunction StringsEqualInfo;
extern const VMFunction StringsNotEqualInfo;

View File

@ -2099,7 +2099,10 @@ HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
ParseTask* task = parseTask();
JSRuntime* runtime = task->parseGlobal->runtimeFromAnyThread();
#ifdef DEBUG
runtime->incOffThreadParsesRunning();
#endif
{
AutoUnlockHelperThreadState unlock(locked);
@ -2128,7 +2131,9 @@ HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
// migrate it into the correct compartment.
HelperThreadState().parseFinishedList(locked).insertBack(task);
#ifdef DEBUG
runtime->decOffThreadParsesRunning();
#endif
currentTask.reset();

View File

@ -2351,6 +2351,7 @@ class LazyScript : public gc::TenuredCell
}
JS::Compartment* compartment() const;
JS::Compartment* maybeCompartment() const { return compartment(); }
Realm* realm() const;
void initScript(JSScript* script);

View File

@ -191,6 +191,9 @@ JSRuntime::~JSRuntime()
MOZ_ASSERT(oldCount > 0);
MOZ_ASSERT(wasmInstances.lock()->empty());
MOZ_ASSERT(offThreadParsesRunning_ == 0);
MOZ_ASSERT(!offThreadParsingBlocked_);
}
bool
@ -783,16 +786,21 @@ JSRuntime::setUsedByHelperThread(Zone* zone)
MOZ_ASSERT(!zone->usedByHelperThread());
MOZ_ASSERT(!zone->wasGCStarted());
MOZ_ASSERT(!isOffThreadParsingBlocked());
zone->setUsedByHelperThread();
numActiveHelperThreadZones++;
if (numActiveHelperThreadZones++ == 0)
gc.setParallelAtomsAllocEnabled(true);
}
void
JSRuntime::clearUsedByHelperThread(Zone* zone)
{
MOZ_ASSERT(zone->usedByHelperThread());
zone->clearUsedByHelperThread();
numActiveHelperThreadZones--;
if (--numActiveHelperThreadZones == 0)
gc.setParallelAtomsAllocEnabled(false);
JSContext* cx = mainContextFromOwnThread();
if (gc.fullGCForAtomsRequested() && cx->canCollectAtoms())
gc.triggerFullGCForAtoms(cx);

View File

@ -857,8 +857,8 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
mozilla::Atomic<bool, mozilla::SequentiallyConsistent,
mozilla::recordreplay::Behavior::DontPreserve> parallelParsingEnabled_;
mozilla::Atomic<uint32_t> offThreadParsesRunning_;
#ifdef DEBUG
mozilla::Atomic<uint32_t> offThreadParsesRunning_;
mozilla::Atomic<bool> offThreadParsingBlocked_;
#endif
@ -881,22 +881,18 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
return parallelParsingEnabled_;
}
#ifdef DEBUG
void incOffThreadParsesRunning() {
MOZ_ASSERT(!isOffThreadParsingBlocked());
if (!offThreadParsesRunning_)
gc.setParallelAtomsAllocEnabled(true);
offThreadParsesRunning_++;
}
void decOffThreadParsesRunning() {
MOZ_ASSERT(isOffThreadParseRunning());
offThreadParsesRunning_--;
if (!offThreadParsesRunning_)
gc.setParallelAtomsAllocEnabled(false);
}
#ifdef DEBUG
bool isOffThreadParseRunning() const {
return offThreadParsesRunning_;
}

View File

@ -5696,7 +5696,6 @@ class BaseCompiler final : public BaseCompilerInterface
masm.bind(&skipBarrier);
}
#endif
void emitBarrieredStore(const Maybe<RegPtr>& object, RegPtr valueAddr, RegPtr value) {
emitPreBarrier(valueAddr); // Preserves valueAddr
@ -5705,6 +5704,7 @@ class BaseCompiler final : public BaseCompilerInterface
emitPostBarrier(object, otherScratch, valueAddr, value); // Consumes valueAddr
freeRef(otherScratch);
}
#endif // ENABLE_WASM_GC
////////////////////////////////////////////////////////////
//

View File

@ -2144,6 +2144,49 @@ Gecko_nsIURI_Debug(nsIURI* aURI, nsCString* aOut)
}
}
template <typename ElementLike>
void
DebugListAttributes(const ElementLike& aElement, nsCString& aOut)
{
const uint32_t kMaxAttributeLength = 40;
uint32_t i = 0;
while (BorrowedAttrInfo info = aElement.GetAttrInfoAt(i++)) {
aOut.AppendLiteral(" ");
if (nsAtom* prefix = info.mName->GetPrefix()) {
aOut.Append(NS_ConvertUTF16toUTF8(nsDependentAtomString(prefix)));
aOut.AppendLiteral(":");
}
aOut.Append(
NS_ConvertUTF16toUTF8(nsDependentAtomString(info.mName->LocalName())));
if (!info.mValue) {
continue;
}
aOut.AppendLiteral("=\"");
nsAutoString value;
info.mValue->ToString(value);
if (value.Length() > kMaxAttributeLength) {
value.Truncate(kMaxAttributeLength - 3);
value.AppendLiteral("...");
}
aOut.Append(NS_ConvertUTF16toUTF8(value));
aOut.AppendLiteral("\"");
}
}
void
Gecko_Element_DebugListAttributes(RawGeckoElementBorrowed aElement, nsCString* aOut)
{
DebugListAttributes(*aElement, *aOut);
}
void
Gecko_Snapshot_DebugListAttributes(const ServoElementSnapshot* aSnapshot,
nsCString* aOut)
{
DebugListAttributes(*aSnapshot, *aOut);
}
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);

View File

@ -139,6 +139,10 @@ struct MediumFeaturesChangedResult {
bool mUsesViewportUnits;
};
// Debugging stuff.
void Gecko_Element_DebugListAttributes(RawGeckoElementBorrowed, nsCString*);
void Gecko_Snapshot_DebugListAttributes(const ServoElementSnapshot*, nsCString*);
bool Gecko_IsSignificantChild(RawGeckoNodeBorrowed node, bool whitespace_is_significant);
RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed node);

View File

@ -40,14 +40,6 @@ class Alias(object):
return "alias"
<%!
# nsCSSPropertyID of longhands and shorthands is ordered alphabetically
# with vendor prefixes removed. Note that aliases use their alias name
# as order key directly because they may be duplicate without prefix.
def order_key(prop):
if prop.name.startswith("-"):
return prop.name[prop.name.find("-", 1) + 1:]
return prop.name
# See bug 1454823 for situation of internal flag.
def is_internal(prop):
# A property which is not controlled by pref and not enabled in
@ -161,16 +153,16 @@ def sub_properties(prop):
%>
data = [
% for prop in sorted(data.longhands, key=order_key):
% for prop in data.longhands:
Longhand("${prop.name}", "${method(prop)}", "${prop.ident}", [${flags(prop)}], ${pref(prop)}),
% endfor
% for prop in sorted(data.shorthands, key=order_key):
% for prop in data.shorthands:
Shorthand("${prop.name}", "${prop.camel_case}", "${prop.ident}", [${flags(prop)}], ${pref(prop)},
[${sub_properties(prop)}]),
% endfor
% for prop in sorted(data.all_aliases(), key=lambda x: x.name):
% for prop in data.all_aliases():
Alias("${prop.name}", "${prop.camel_case}", "${prop.ident}", "${prop.original.ident}", [], ${pref(prop)}),
% endfor
]

View File

@ -27,11 +27,6 @@ using namespace mozilla;
static nsTArray<RefPtr<nsAtom>>* sSystemMetrics = nullptr;
#ifdef XP_WIN
// Cached theme identifier for the moz-windows-theme media query.
static uint8_t sWinThemeId = LookAndFeel::eWindowsTheme_Generic;
#endif
static const nsCSSKTableEntry kOrientationKeywords[] = {
{ eCSSKeyword_portrait, StyleOrientation::Portrait },
{ eCSSKeyword_landscape, StyleOrientation::Landscape },
@ -60,23 +55,6 @@ static const nsCSSKeywordAndBoolTableEntry kPrefersReducedMotionKeywords[] = {
};
#ifdef XP_WIN
struct WindowsThemeName {
LookAndFeel::WindowsTheme mId;
nsStaticAtom** mName;
};
// Windows theme identities used in the -moz-windows-theme media query.
const WindowsThemeName kThemeStrings[] = {
{ LookAndFeel::eWindowsTheme_Aero, &nsGkAtoms::aero },
{ LookAndFeel::eWindowsTheme_AeroLite, &nsGkAtoms::aero_lite },
{ LookAndFeel::eWindowsTheme_LunaBlue, &nsGkAtoms::luna_blue },
{ LookAndFeel::eWindowsTheme_LunaOlive, &nsGkAtoms::luna_olive },
{ LookAndFeel::eWindowsTheme_LunaSilver, &nsGkAtoms::luna_silver },
{ LookAndFeel::eWindowsTheme_Royale, &nsGkAtoms::royale },
{ LookAndFeel::eWindowsTheme_Zune, &nsGkAtoms::zune },
{ LookAndFeel::eWindowsTheme_Generic, &nsGkAtoms::generic_ }
};
struct OperatingSystemVersionInfo {
LookAndFeel::OperatingSystemVersion mId;
nsStaticAtom** mName;
@ -421,15 +399,6 @@ HasSystemMetric(nsAtom* aMetric)
return sSystemMetrics->IndexOf(aMetric) != sSystemMetrics->NoIndex;
}
#ifdef XP_WIN
static uint8_t
GetWindowsThemeIdentifier()
{
nsMediaFeatures::InitSystemMetrics();
return sWinThemeId;
}
#endif
static void
GetSystemMetric(nsIDocument* aDocument, const nsMediaFeature* aFeature,
nsCSSValue& aResult)
@ -458,34 +427,6 @@ GetSystemMetric(nsIDocument* aDocument, const nsMediaFeature* aFeature,
aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer);
}
static void
GetWindowsTheme(nsIDocument* aDocument, const nsMediaFeature* aFeature,
nsCSSValue& aResult)
{
aResult.Reset();
MOZ_ASSERT(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly);
if (nsContentUtils::ShouldResistFingerprinting(aDocument)) {
return;
}
#ifdef XP_WIN
uint8_t windowsThemeId = GetWindowsThemeIdentifier();
// Classic mode should fail to match.
if (windowsThemeId == LookAndFeel::eWindowsTheme_Classic)
return;
// Look up the appropriate theme string
for (const auto& theme : kThemeStrings) {
if (windowsThemeId == theme.mId) {
aResult.SetAtomIdentValue((*theme.mName)->ToAddRefed());
break;
}
}
#endif
}
static void
GetOperatingSystemVersion(nsIDocument* aDocument, const nsMediaFeature* aFeature,
nsCSSValue& aResult)
@ -664,40 +605,6 @@ nsMediaFeatures::InitSystemMetrics()
if (metricResult) {
sSystemMetrics->AppendElement(nsGkAtoms::system_dark_theme);
}
#ifdef XP_WIN
if (NS_SUCCEEDED(
LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsThemeIdentifier,
&metricResult))) {
sWinThemeId = metricResult;
switch (metricResult) {
case LookAndFeel::eWindowsTheme_Aero:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_aero);
break;
case LookAndFeel::eWindowsTheme_AeroLite:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_aero_lite);
break;
case LookAndFeel::eWindowsTheme_LunaBlue:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_luna_blue);
break;
case LookAndFeel::eWindowsTheme_LunaOlive:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_luna_olive);
break;
case LookAndFeel::eWindowsTheme_LunaSilver:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_luna_silver);
break;
case LookAndFeel::eWindowsTheme_Royale:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_royale);
break;
case LookAndFeel::eWindowsTheme_Zune:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_zune);
break;
case LookAndFeel::eWindowsTheme_Generic:
sSystemMetrics->AppendElement(nsGkAtoms::windows_theme_generic);
break;
}
}
#endif
}
/* static */ void
@ -1012,14 +919,6 @@ nsMediaFeatures::features[] = {
{ &nsGkAtoms::menubar_drag },
GetSystemMetric
},
{
&nsGkAtoms::_moz_windows_theme,
nsMediaFeature::eMinMaxNotAllowed,
nsMediaFeature::eIdent,
nsMediaFeature::eUserAgentAndChromeOnly,
{ nullptr },
GetWindowsTheme
},
{
&nsGkAtoms::_moz_os_version,
nsMediaFeature::eMinMaxNotAllowed,

View File

@ -70,18 +70,6 @@ var windows_versions = [
"windows-win10",
];
// Possible values for '-moz-windows-theme'
var windows_themes = [
"aero",
"aero-lite",
"luna-blue",
"luna-olive",
"luna-silver",
"royale",
"generic",
"zune"
];
// Read the current OS.
var OS = SpecialPowers.Services.appinfo.OS;
@ -167,14 +155,11 @@ var generateHtmlLines = function (resisting) {
fragment.appendChild(div);
});
if (OS === "WINNT") {
let ids = ["-moz-os-version", "-moz-windows-theme"];
for (let id of ids) {
let div = document.createElement("div");
div.setAttribute("class", "windows");
div.setAttribute("id", id);
div.textContent = id;
fragment.appendChild(div);
}
let div = document.createElement("div");
div.setAttribute("class", "windows");
div.setAttribute("id", "-moz-os-version");
div.textContent = "-moz-os-version";
fragment.appendChild(div);
}
return fragment;
};
@ -236,8 +221,6 @@ var generateCSSLines = function (resisting) {
lines += ".windows { background-color: " + (resisting ? "green" : "red") + ";}\n";
lines += windows_versions.map(val => "(-moz-os-version: " + val + ")").join(", ") +
" { #-moz-os-version { background-color: " + (resisting ? "red" : "green") + ";} }\n";
lines += windows_themes.map(val => "(-moz-windows-theme: " + val + ")").join(",") +
" { #-moz-windows-theme { background-color: " + (resisting ? "red" : "green") + ";} }\n";
}
return lines;
};
@ -338,7 +321,6 @@ var test = async function(isContent) {
testToggles(resisting);
if (OS === "WINNT") {
testWindowsSpecific(resisting, "-moz-os-version", windows_versions);
testWindowsSpecific(resisting, "-moz-windows-theme", windows_themes);
}
testCSS(resisting);
if (OS === "Darwin") {

View File

@ -66,18 +66,6 @@ for (let i = 0; i < TOGGLES.length; ++i) {
testToggle(TOGGLES[i])
}
expectParseable("(-moz-windows-theme: aero)");
expectParseable("(-moz-windows-theme: aero-lite)");
expectParseable("(-moz-windows-theme: luna-blue)");
expectParseable("(-moz-windows-theme: luna-olive)");
expectParseable("(-moz-windows-theme: luna-silver)");
expectParseable("(-moz-windows-theme: royale)");
expectParseable("(-moz-windows-theme: generic)");
expectParseable("(-moz-windows-theme: zune)");
expectParseable("(-moz-windows-theme: garbage)");
expectNonParseable("(-moz-windows-theme: '')");
expectNonParseable("(-moz-windows-theme: )");
expectParseable("(-moz-os-version: windows-win7)");
expectParseable("(-moz-os-version: windows-win8)");
expectParseable("(-moz-os-version: windows-win10)");

View File

@ -779,19 +779,6 @@ function run() {
expression_should_not_be_parseable("-moz-gtk-csd-maximize-button: true");
expression_should_not_be_parseable("-moz-gtk-csd-close-button: true");
// windows theme media queries
expression_should_not_be_parseable("-moz-windows-theme: aero");
expression_should_not_be_parseable("-moz-windows-theme: aero-lite");
expression_should_not_be_parseable("-moz-windows-theme: luna-blue");
expression_should_not_be_parseable("-moz-windows-theme: luna-olive");
expression_should_not_be_parseable("-moz-windows-theme: luna-silver");
expression_should_not_be_parseable("-moz-windows-theme: royale");
expression_should_not_be_parseable("-moz-windows-theme: generic");
expression_should_not_be_parseable("-moz-windows-theme: zune");
expression_should_not_be_parseable("-moz-windows-theme: garbage");
expression_should_not_be_parseable("-moz-windows-theme: ''");
expression_should_not_be_parseable("-moz-windows-theme: ");
// os version media queries (currently windows only)
expression_should_not_be_parseable("-moz-os-version: windows-win7");
expression_should_not_be_parseable("-moz-os-version: windows-win8");

View File

@ -2235,7 +2235,7 @@ pref("network.cookie.thirdparty.nonsecureSessionOnly", false);
pref("network.cookie.leave-secure-alone", true);
pref("network.cookie.same-site.enabled", true); // Honor the SameSite cookie attribute
pref("network.cookie.ipc.sync", false);
pref("network.cookie.lifetimePolicy", 0); // 0-accept, 1-dontUse 2-acceptForSession, 3-acceptForNDays
pref("network.cookie.lifetimePolicy", 0); // 0-accept, 2-acceptForSession, 3-acceptForNDays
pref("network.cookie.prefsMigrated", false);
pref("network.cookie.lifetime.days", 90); // Ignored unless network.cookie.lifetimePolicy is 3.
// The interval in seconds to move the cookies in the child process.

View File

@ -156,6 +156,15 @@ impl GeckoElementSnapshot {
}
impl ElementSnapshot for GeckoElementSnapshot {
fn debug_list_attributes(&self) -> String {
use nsstring::nsCString;
let mut string = nsCString::new();
unsafe {
bindings::Gecko_Snapshot_DebugListAttributes(self, &mut string);
}
String::from_utf8_lossy(&*string).into_owned()
}
fn state(&self) -> Option<ElementState> {
if self.has_any(Flags::State) {
Some(ElementState::from_bits_truncate(self.mState))

View File

@ -562,28 +562,15 @@ pub struct GeckoElement<'le>(pub &'le RawGeckoElement);
impl<'le> fmt::Debug for GeckoElement<'le> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use nsstring::nsCString;
write!(f, "<{}", self.local_name())?;
if let Some(id) = self.id() {
write!(f, " id={}", id)?;
let mut attrs = nsCString::new();
unsafe {
bindings::Gecko_Element_DebugListAttributes(self.0, &mut attrs);
}
let mut first = true;
let mut any = false;
self.each_class(|c| {
if first {
first = false;
any = true;
let _ = f.write_str(" class=\"");
} else {
let _ = f.write_str(" ");
}
let _ = write!(f, "{}", c);
});
if any {
f.write_str("\"")?;
}
write!(f, "{}", attrs)?;
write!(f, "> ({:#x})", self.as_node().opaque().0)
}
}

View File

@ -43,6 +43,11 @@ pub trait ElementSnapshot: Sized {
/// If this snapshot contains attribute information.
fn has_attrs(&self) -> bool;
/// Gets the attribute information of the snapshot as a string.
///
/// Only for debugging purposes.
fn debug_list_attributes(&self) -> String { String::new() }
/// The ID attribute per this snapshot. Should only be called if
/// `has_attrs()` returns true.
fn id_attr(&self) -> Option<&WeakAtom>;

View File

@ -208,20 +208,32 @@ where
}
}
debug!("Collecting changes for: {:?}", element);
debug!(" > state: {:?}", state_changes);
debug!(
" > id changed: {:?} -> +{:?} -{:?}",
snapshot.id_changed(),
id_added,
id_removed
);
debug!(
" > class changed: {:?} -> +{:?} -{:?}",
snapshot.class_changed(),
classes_added,
classes_removed
);
if log_enabled!(::log::Level::Debug) {
debug!("Collecting changes for: {:?}", element);
if !state_changes.is_empty() {
debug!(" > state: {:?}", state_changes);
}
if snapshot.id_changed() {
debug!(
" > id changed: +{:?} -{:?}",
id_added,
id_removed
);
}
if snapshot.class_changed() {
debug!(
" > class changed: +{:?} -{:?}",
classes_added,
classes_removed
);
}
if snapshot.other_attr_changed() {
debug!(
" > attributes changed, old: {}",
snapshot.debug_list_attributes()
)
}
}
let lookup_element = if element.implemented_pseudo_element().is_some() {
element.pseudo_element_originating_element().unwrap()

View File

@ -410,17 +410,35 @@ pub mod animated_properties {
#[derive(Clone, Copy, Debug)]
pub struct NonCustomPropertyId(usize);
% if product == "gecko":
#[allow(dead_code)]
unsafe fn static_assert_nscsspropertyid() {
% for i, property in enumerate(data.longhands + data.shorthands + data.all_aliases()):
::std::mem::transmute::<[u8; ${i}], [u8; ${property.nscsspropertyid()} as usize]>([0; ${i}]); // ${property.name}
% endfor
}
% endif
impl NonCustomPropertyId {
#[cfg(feature = "gecko")]
#[inline]
fn to_nscsspropertyid(self) -> nsCSSPropertyID {
static MAP: [nsCSSPropertyID; ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())}] = [
% for property in data.longhands + data.shorthands + data.all_aliases():
${property.nscsspropertyid()},
% endfor
];
// unsafe: guaranteed by static_assert_nscsspropertyid above.
unsafe { ::std::mem::transmute(self.0 as i32) }
}
MAP[self.0]
#[cfg(feature = "gecko")]
#[inline]
fn from_nscsspropertyid(prop: nsCSSPropertyID) -> Result<Self, ()> {
let prop = prop as i32;
if prop < 0 {
return Err(());
}
if prop >= ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())} {
return Err(());
}
// unsafe: guaranteed by static_assert_nscsspropertyid above.
Ok(unsafe { ::std::mem::transmute(prop as usize) })
}
/// Get the property name.
@ -428,7 +446,7 @@ impl NonCustomPropertyId {
fn name(self) -> &'static str {
static MAP: [&'static str; ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())}] = [
% for property in data.longhands + data.shorthands + data.all_aliases():
"${property.name}",
"${property.name}",
% endfor
];
MAP[self.0]
@ -464,7 +482,7 @@ impl NonCustomPropertyId {
PREFS.get(pref).as_boolean().unwrap_or(false)
% else:
unsafe { structs::nsCSSProps_gPropertyEnabled[self.to_nscsspropertyid() as usize] }
unsafe { structs::nsCSSProps_gPropertyEnabled[self.0] }
% endif
};
@ -585,6 +603,30 @@ impl NonCustomPropertyId {
];
COLLECT_FUNCTIONS[self.0](f);
}
#[inline]
fn to_property_id(self) -> PropertyId {
use std::mem::transmute;
if self.0 < ${len(data.longhands)} {
return unsafe {
PropertyId::Longhand(transmute(self.0 as u16))
}
}
if self.0 < ${len(data.longhands) + len(data.shorthands)} {
return unsafe {
PropertyId::Shorthand(transmute((self.0 - ${len(data.longhands)}) as u16))
}
}
assert!(self.0 < ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())});
let alias_id: AliasId = unsafe {
transmute((self.0 - ${len(data.longhands) + len(data.shorthands)}) as u16)
};
match alias_id.aliased_property() {
AliasedPropertyId::Longhand(longhand) => PropertyId::LonghandAlias(longhand, alias_id),
AliasedPropertyId::Shorthand(shorthand) => PropertyId::ShorthandAlias(shorthand, alias_id),
}
}
}
impl From<LonghandId> for NonCustomPropertyId {
@ -1237,10 +1279,11 @@ where
/// An identifier for a given shorthand property.
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
#[repr(u16)]
pub enum ShorthandId {
% for property in data.shorthands:
% for i, property in enumerate(data.shorthands):
/// ${property.name}
${property.camel_case},
${property.camel_case} = ${i},
% endfor
}
@ -1767,42 +1810,11 @@ impl PropertyId {
}
/// Returns a property id from Gecko's nsCSSPropertyID.
///
/// TODO(emilio): We should be able to make this a single integer cast to
/// `NonCustomPropertyId`.
#[cfg(feature = "gecko")]
#[allow(non_upper_case_globals)]
#[inline]
pub fn from_nscsspropertyid(id: nsCSSPropertyID) -> Result<Self, ()> {
use gecko_bindings::structs::*;
match id {
% for property in data.longhands:
${property.nscsspropertyid()} => {
Ok(PropertyId::Longhand(LonghandId::${property.camel_case}))
}
% for alias in property.alias:
${alias.nscsspropertyid()} => {
Ok(PropertyId::LonghandAlias(
LonghandId::${property.camel_case},
AliasId::${alias.camel_case}
))
}
% endfor
% endfor
% for property in data.shorthands:
${property.nscsspropertyid()} => {
Ok(PropertyId::Shorthand(ShorthandId::${property.camel_case}))
}
% for alias in property.alias:
${alias.nscsspropertyid()} => {
Ok(PropertyId::ShorthandAlias(
ShorthandId::${property.camel_case},
AliasId::${alias.camel_case}
))
}
% endfor
% endfor
_ => Err(())
}
Ok(NonCustomPropertyId::from_nscsspropertyid(id)?.to_property_id())
}
/// Returns true if the property is a shorthand or shorthand alias.
@ -4230,6 +4242,7 @@ pub fn adjust_border_width(style: &mut StyleBuilder) {
/// An identifier for a given alias property.
#[derive(Clone, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[repr(u16)]
pub enum AliasId {
% for i, property in enumerate(data.all_aliases()):
/// ${property.name}
@ -4237,17 +4250,37 @@ pub enum AliasId {
% endfor
}
#[derive(Clone, Copy, Eq, PartialEq)]
enum AliasedPropertyId {
Shorthand(ShorthandId),
Longhand(LonghandId),
}
impl fmt::Debug for AliasId {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let name = match *self {
% for property in data.all_aliases():
AliasId::${property.camel_case} => "${property.camel_case}",
% endfor
};
let name = NonCustomPropertyId::from(*self).name();
formatter.write_str(name)
}
}
impl AliasId {
/// Returns the property we're aliasing, as a longhand or a shorthand.
#[inline]
fn aliased_property(self) -> AliasedPropertyId {
static MAP: [AliasedPropertyId; ${len(data.all_aliases())}] = [
% for alias in data.all_aliases():
% if alias.original.type() == "longhand":
AliasedPropertyId::Longhand(LonghandId::${alias.original.camel_case}),
% else:
<% assert alias.original.type() == "shorthand" %>
AliasedPropertyId::Shorthand(ShorthandId::${alias.original.camel_case}),
% endif
% endfor
];
MAP[self as usize]
}
}
// NOTE(emilio): Callers are responsible to deal with prefs.
#[macro_export]
macro_rules! css_properties_accessors {

View File

@ -96,6 +96,8 @@ pub trait SelectorMapEntry: Sized + Clone {
/// TODO: Tune the initial capacity of the HashMap
#[derive(Debug, MallocSizeOf)]
pub struct SelectorMap<T: 'static> {
/// Rules that have `:root` selectors.
pub root: SmallVec<[T; 1]>,
/// A hash from an ID to rules which contain that ID selector.
pub id_hash: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[T; 1]>>,
/// A hash from a class name to rules which contain that class selector.
@ -104,7 +106,7 @@ pub struct SelectorMap<T: 'static> {
pub local_name_hash: PrecomputedHashMap<LocalName, SmallVec<[T; 1]>>,
/// A hash from namespace to rules which contain that namespace selector.
pub namespace_hash: PrecomputedHashMap<Namespace, SmallVec<[T; 1]>>,
/// Rules that don't have ID, class, or element selectors.
/// All other rules.
pub other: SmallVec<[T; 1]>,
/// The number of entries in this map.
pub count: usize,
@ -124,6 +126,7 @@ impl<T: 'static> SelectorMap<T> {
/// Trivially constructs an empty `SelectorMap`.
pub fn new() -> Self {
SelectorMap {
root: SmallVec::new(),
id_hash: MaybeCaseInsensitiveHashMap::new(),
class_hash: MaybeCaseInsensitiveHashMap::new(),
local_name_hash: HashMap::default(),
@ -135,6 +138,7 @@ impl<T: 'static> SelectorMap<T> {
/// Clears the hashmap retaining storage.
pub fn clear(&mut self) {
self.root.clear();
self.id_hash.clear();
self.class_hash.clear();
self.local_name_hash.clear();
@ -181,6 +185,19 @@ impl SelectorMap<Rule> {
// At the end, we're going to sort the rules that we added, so remember
// where we began.
let init_len = matching_rules_list.len();
if rule_hash_target.is_root() {
SelectorMap::get_matching_rules(
element,
&self.root,
matching_rules_list,
context,
flags_setter,
cascade_level,
shadow_cascade_order,
);
}
if let Some(id) = rule_hash_target.id() {
if let Some(rules) = self.id_hash.get(id, quirks_mode) {
SelectorMap::get_matching_rules(
@ -287,6 +304,7 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
self.count += 1;
let vector = match find_bucket(entry.selector()) {
Bucket::Root => &mut self.root,
Bucket::ID(id) => self.id_hash
.try_entry(id.clone(), quirks_mode)?
.or_insert_with(SmallVec::new),
@ -340,6 +358,14 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
E: TElement,
F: FnMut(&'a T) -> bool,
{
if element.is_root() {
for entry in self.root.iter() {
if !f(&entry) {
return false;
}
}
}
if let Some(id) = element.id() {
if let Some(v) = self.id_hash.get(id, quirks_mode) {
for entry in v.iter() {
@ -444,6 +470,7 @@ impl<T: SelectorMapEntry> SelectorMap<T> {
}
enum Bucket<'a> {
Root,
ID(&'a Atom),
Class(&'a Atom),
LocalName {
@ -456,6 +483,7 @@ enum Bucket<'a> {
fn specific_bucket_for<'a>(component: &'a Component<SelectorImpl>) -> Bucket<'a> {
match *component {
Component::Root => Bucket::Root,
Component::ID(ref id) => Bucket::ID(id),
Component::Class(ref class) => Bucket::Class(class),
Component::LocalName(ref selector) => Bucket::LocalName {
@ -498,14 +526,19 @@ fn find_bucket<'a>(mut iter: SelectorIter<'a, SelectorImpl>) -> Bucket<'a> {
// We basically want to find the most specific bucket,
// where:
//
// id > class > local name > namespace > universal.
// root > id > class > local name > namespace > universal.
//
for ss in &mut iter {
let new_bucket = specific_bucket_for(ss);
match new_bucket {
Bucket::ID(..) => return new_bucket,
Bucket::Class(..) => {
Bucket::Root => return new_bucket,
Bucket::ID(..) => {
current_bucket = new_bucket;
}
Bucket::Class(..) => {
if !matches!(current_bucket, Bucket::ID(..)) {
current_bucket = new_bucket;
}
},
Bucket::LocalName { .. } => {
if matches!(current_bucket, Bucket::Universal | Bucket::Namespace(..)) {

View File

@ -2000,6 +2000,7 @@ GK_ATOM(windows_default_theme, "windows-default-theme")
GK_ATOM(mac_graphite_theme, "mac-graphite-theme")
GK_ATOM(mac_yosemite_theme, "mac-yosemite-theme")
GK_ATOM(windows_compositor, "windows-compositor")
GK_ATOM(windows_classic, "windows-classic")
GK_ATOM(windows_glass, "windows-glass")
GK_ATOM(touch_enabled, "touch-enabled")
GK_ATOM(menubar_drag, "menubar-drag")
@ -2010,25 +2011,7 @@ GK_ATOM(gtk_csd_maximize_button, "gtk-csd-maximize-button")
GK_ATOM(gtk_csd_close_button, "gtk-csd-close-button")
GK_ATOM(system_dark_theme, "system-dark-theme")
// windows theme selector metrics
GK_ATOM(windows_classic, "windows-classic")
GK_ATOM(windows_theme_aero, "windows-theme-aero")
GK_ATOM(windows_theme_aero_lite, "windows-theme-aero-lite")
GK_ATOM(windows_theme_luna_blue, "windows-theme-luna-blue")
GK_ATOM(windows_theme_luna_olive, "windows-theme-luna-olive")
GK_ATOM(windows_theme_luna_silver, "windows-theme-luna-silver")
GK_ATOM(windows_theme_royale, "windows-theme-royale")
GK_ATOM(windows_theme_zune, "windows-theme-zune")
GK_ATOM(windows_theme_generic, "windows-theme-generic")
// windows media query names
GK_ATOM(aero, "aero")
GK_ATOM(aero_lite, "aero-lite")
GK_ATOM(luna_blue, "luna-blue")
GK_ATOM(luna_olive, "luna-olive")
GK_ATOM(luna_silver, "luna-silver")
GK_ATOM(royale, "royale")
GK_ATOM(zune, "zune")
GK_ATOM(windows_win7, "windows-win7")
GK_ATOM(windows_win8, "windows-win8")
GK_ATOM(windows_win10, "windows-win10")
@ -2047,7 +2030,6 @@ GK_ATOM(_moz_mac_yosemite_theme, "-moz-mac-yosemite-theme")
GK_ATOM(_moz_windows_compositor, "-moz-windows-compositor")
GK_ATOM(_moz_windows_classic, "-moz-windows-classic")
GK_ATOM(_moz_windows_glass, "-moz-windows-glass")
GK_ATOM(_moz_windows_theme, "-moz-windows-theme")
GK_ATOM(_moz_os_version, "-moz-os-version")
GK_ATOM(_moz_touch_enabled, "-moz-touch-enabled")
GK_ATOM(_moz_menubar_drag, "-moz-menubar-drag")