merge mozilla-central to autoland. r=merge a=merge

This commit is contained in:
Sebastian Hengst 2017-09-10 10:08:32 +02:00
Родитель a4b102b6d9 d71460b2ca
Коммит 0714f6271f
64 изменённых файлов: 1109 добавлений и 807 удалений

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

@ -149,76 +149,68 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
JSObject* realCallback = js::UncheckedUnwrap(wrappedCallback);
nsIGlobalObject* globalObject = nullptr;
JSContext* cx;
{
// Bug 955660: we cannot do "proper" rooting here because we need the
// global to get a context. Everything here is simple getters that cannot
// GC, so just paper over the necessary dataflow inversion.
JS::AutoSuppressGCAnalysis nogc;
// Now get the global for this callback. Note that for the case of
// JS-implemented WebIDL we never have a window here.
nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL
? xpc::WindowGlobalOrNull(realCallback)
: nullptr;
if (win) {
MOZ_ASSERT(win->IsInnerWindow());
// We don't want to run script in windows that have been navigated away
// from.
if (!win->AsInner()->HasActiveDocument()) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Refusing to execute function from window "
"whose document is no longer active."));
return;
}
globalObject = win;
} else {
// No DOM Window. Store the global.
JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
globalObject = xpc::NativeGlobal(global);
MOZ_ASSERT(globalObject);
}
// Bail out if there's no useful global. This seems to happen intermittently
// on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
// null in some kind of teardown state.
if (!globalObject->GetGlobalJSObject()) {
// Now get the global for this callback. Note that for the case of
// JS-implemented WebIDL we never have a window here.
nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL
? xpc::WindowGlobalOrNull(realCallback)
: nullptr;
if (win) {
MOZ_ASSERT(win->IsInnerWindow());
// We don't want to run script in windows that have been navigated away
// from.
if (!win->AsInner()->HasActiveDocument()) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Refusing to execute function from global which is "
"being torn down."));
NS_LITERAL_CSTRING("Refusing to execute function from window "
"whose document is no longer active."));
return;
}
globalObject = win;
} else {
// No DOM Window. Store the global.
JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback);
globalObject = xpc::NativeGlobal(global);
MOZ_ASSERT(globalObject);
}
mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread);
mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
if (incumbent) {
// The callback object traces its incumbent JS global, so in general it
// should be alive here. However, it's possible that we could run afoul
// of the same IPC global weirdness described above, wherein the
// nsIGlobalObject has severed its reference to the JS global. Let's just
// be safe here, so that nobody has to waste a day debugging gaia-ui tests.
if (!incumbent->GetGlobalJSObject()) {
// Bail out if there's no useful global. This seems to happen intermittently
// on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
// null in some kind of teardown state.
if (!globalObject->GetGlobalJSObject()) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Refusing to execute function from global which is "
"being torn down."));
return;
}
mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread);
mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
if (incumbent) {
// The callback object traces its incumbent JS global, so in general it
// should be alive here. However, it's possible that we could run afoul
// of the same IPC global weirdness described above, wherein the
// nsIGlobalObject has severed its reference to the JS global. Let's just
// be safe here, so that nobody has to waste a day debugging gaia-ui tests.
if (!incumbent->GetGlobalJSObject()) {
aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("Refusing to execute function because our "
"incumbent global is being torn down."));
return;
}
mAutoIncumbentScript.emplace(incumbent);
return;
}
cx = mAutoEntryScript->cx();
// Unmark the callable (by invoking CallbackOrNull() and not the
// CallbackPreserveColor() variant), and stick it in a Rooted before it can
// go gray again.
// Nothing before us in this function can trigger a CC, so it's safe to wait
// until here it do the unmark. This allows us to construct mRootedCallable
// with the cx from mAutoEntryScript, avoiding the cost of finding another
// JSContext. (Rooted<> does not care about requests or compartments.)
mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
mAutoIncumbentScript.emplace(incumbent);
}
JSContext* cx = mAutoEntryScript->cx();
// Unmark the callable (by invoking CallbackOrNull() and not the
// CallbackPreserveColor() variant), and stick it in a Rooted before it can
// go gray again.
// Nothing before us in this function can trigger a CC, so it's safe to wait
// until here it do the unmark. This allows us to construct mRootedCallable
// with the cx from mAutoEntryScript, avoiding the cost of finding another
// JSContext. (Rooted<> does not care about requests or compartments.)
mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
// JS-implemented WebIDL is always OK to run, since it runs with Chrome
// privileges anyway.
if (mIsMainThread && !aIsJSImplementedWebIDL) {

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

@ -327,6 +327,10 @@ HTMLEditor::ShowGrabberOnElement(nsIDOMElement* aElement)
nsCOMPtr<Element> element = do_QueryInterface(aElement);
NS_ENSURE_ARG_POINTER(element);
if (NS_WARN_IF(!IsDescendantOfEditorRoot(element))) {
return NS_ERROR_UNEXPECTED;
}
if (mGrabber) {
NS_ERROR("call HideGrabber first");
return NS_ERROR_UNEXPECTED;

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

@ -304,6 +304,10 @@ HTMLEditor::ShowResizersInner(Element& aResizedElement)
return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(!IsDescendantOfEditorRoot(&aResizedElement))) {
return NS_ERROR_UNEXPECTED;
}
mResizedObject = &aResizedElement;
// The resizers and the shadow will be anonymous siblings of the element.

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

@ -48,10 +48,15 @@ HTMLEditor::ShowInlineTableEditingUI(nsIDOMElement* aCell)
NS_ENSURE_ARG_POINTER(aCell);
// do nothing if aCell is not a table cell...
if (!HTMLEditUtils::IsTableCell(aCell)) {
nsCOMPtr<Element> cell = do_QueryInterface(aCell);
if (!cell || !HTMLEditUtils::IsTableCell(cell)) {
return NS_OK;
}
if (NS_WARN_IF(!IsDescendantOfEditorRoot(cell))) {
return NS_ERROR_UNEXPECTED;
}
if (mInlineEditedCell) {
NS_ERROR("call HideInlineTableEditingUI first");
return NS_ERROR_UNEXPECTED;

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

@ -571,17 +571,20 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
if (!geometry || !invalidRegion.IsEmpty() || fallbackData->IsInvalid()) {
if (gfxPrefs::WebRenderBlobImages()) {
bool snapped;
bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
// TODO: should use 'format' to replace gfx::SurfaceFormat::B8G8R8X8. Currently blob image doesn't support A8 format.
// TODO: should use 'format' to replace gfx::SurfaceFormat::B8G8R8A8. Currently blob image doesn't support A8 format.
RefPtr<gfx::DrawTarget> dummyDt =
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8);
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
recorder->Finish();
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
wr::ImageKey key = WrBridge()->GetNextImageKey();
wr::ImageDescriptor descriptor(imageSize.ToUnknownSize(), 0, dt->GetFormat());
wr::ImageDescriptor descriptor(imageSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
aBuilder.Resources().AddBlobImage(key, descriptor, bytes);
fallbackData->SetKey(key);
} else {

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

@ -112,6 +112,16 @@ struct ImageDescriptor: public wr::WrImageDescriptor {
stride = aByteStride;
is_opaque = gfx::IsOpaqueFormat(aFormat);
}
ImageDescriptor(const gfx::IntSize& aSize, uint32_t aByteStride, gfx::SurfaceFormat aFormat, bool opaque)
{
format = wr::SurfaceFormatToImageFormat(aFormat).value();
width = aSize.width;
height = aSize.height;
stride = aByteStride;
is_opaque = opaque;
}
};
// Whenever possible, use wr::WindowId instead of manipulating uint64_t.

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

@ -2341,7 +2341,18 @@ PromiseObject::unforgeableResolve(JSContext* cx, HandleValue value)
return CommonStaticResolveRejectImpl(cx, cVal, value, ResolveMode);
}
// ES2016, 25.4.4.6, implemented in Promise.js.
/**
* ES2016, 25.4.4.6 get Promise [ @@species ]
*/
static bool
Promise_static_species(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
// Step 1: Return the this value.
args.rval().set(args.thisv());
return true;
}
// ES2016, 25.4.5.1, implemented in Promise.js.
@ -2373,6 +2384,12 @@ NewReactionRecord(JSContext* cx, HandleObject resultPromise, HandleValue onFulfi
return reaction;
}
static bool
IsPromiseSpecies(JSContext* cx, JSFunction* species)
{
return species->maybeNative() == Promise_static_species;
}
// ES2016, 25.4.5.3., steps 3-5.
MOZ_MUST_USE bool
js::OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
@ -2391,10 +2408,9 @@ js::OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
if (createDependent) {
// Step 3.
RootedValue ctorVal(cx);
if (!SpeciesConstructor(cx, promiseObj, JSProto_Promise, &ctorVal))
RootedObject C(cx, SpeciesConstructor(cx, promiseObj, JSProto_Promise, IsPromiseSpecies));
if (!C)
return false;
RootedObject C(cx, &ctorVal.toObject());
// Step 4.
if (!NewPromiseCapability(cx, C, &resultPromise, &resolve, &reject, true))
@ -3039,11 +3055,10 @@ BlockOnPromise(JSContext* cx, HandleValue promiseVal, HandleObject blockedPromis
RootedObject PromiseCtor(cx);
if (!GetBuiltinConstructor(cx, JSProto_Promise, &PromiseCtor))
return false;
RootedValue PromiseCtorVal(cx, ObjectValue(*PromiseCtor));
RootedValue CVal(cx);
if (!SpeciesConstructor(cx, promiseObj, PromiseCtorVal, &CVal))
RootedObject C(cx, SpeciesConstructor(cx, PromiseCtor, JSProto_Promise, IsPromiseSpecies));
if (!C)
return false;
RootedObject C(cx, &CVal.toObject());
RootedObject resultPromise(cx, blockedPromise_);
RootedObject resolveFun(cx);
@ -3617,7 +3632,7 @@ static const JSFunctionSpec promise_static_methods[] = {
};
static const JSPropertySpec promise_static_properties[] = {
JS_SELF_HOSTED_SYM_GET(species, "Promise_static_get_species", 0),
JS_SYM_GET(species, Promise_static_species, 0),
JS_PS_END
};

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

@ -2,13 +2,6 @@
* 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/. */
// ES6, 25.4.4.6.
function Promise_static_get_species() {
// Step 1.
return this;
}
_SetCanonicalName(Promise_static_get_species, "get [Symbol.species]");
// ES6, 25.4.5.1.
function Promise_catch(onRejected) {
// Steps 1-2.

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

@ -92,11 +92,6 @@ CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun,
JS::SourceBufferHolder& srcBuf,
const mozilla::Maybe<uint32_t>& parameterListEnd);
MOZ_MUST_USE bool
CompileAsyncFunctionBody(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf);
ScriptSourceObject*
CreateScriptSourceObject(JSContext* cx, const ReadOnlyCompileOptions& options,
const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing());

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

@ -3665,22 +3665,6 @@ BytecodeEmitter::reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...)
return result;
}
bool
BytecodeEmitter::reportStrictModeError(ParseNode* pn, unsigned errorNumber, ...)
{
TokenPos pos = pn ? pn->pn_pos : tokenStream().currentToken().pos;
va_list args;
va_start(args, errorNumber);
// FIXME: parser.tokenStream() should be a TokenStreamAnyChars for bug 1351107,
// but caused problems, cf. bug 1363116.
bool result = parser.tokenStream()
.reportStrictModeErrorNumberVA(nullptr, pos.begin, sc->strict(),
errorNumber, args);
va_end(args);
return result;
}
bool
BytecodeEmitter::emitNewInit(JSProtoKey key)
{
@ -3710,8 +3694,8 @@ BytecodeEmitter::iteratorResultShape(unsigned* shape)
if (!obj)
return false;
Rooted<jsid> value_id(cx, AtomToId(cx->names().value));
Rooted<jsid> done_id(cx, AtomToId(cx->names().done));
Rooted<jsid> value_id(cx, NameToId(cx->names().value));
Rooted<jsid> done_id(cx, NameToId(cx->names().done));
if (!NativeDefineProperty(cx, obj, value_id, UndefinedHandleValue, nullptr, nullptr,
JSPROP_ENUMERATE))
{
@ -3760,18 +3744,6 @@ BytecodeEmitter::emitFinishIteratorResult(bool done)
return true;
}
bool
BytecodeEmitter::emitToIteratorResult(bool done)
{
if (!emitPrepareIteratorResult()) // VALUE OBJ
return false;
if (!emit1(JSOP_SWAP)) // OBJ VALUE
return false;
if (!emitFinishIteratorResult(done)) // RESULT
return false;
return true;
}
bool
BytecodeEmitter::emitGetNameAtLocation(JSAtom* name, const NameLocation& loc, bool callContext)
{

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

@ -417,7 +417,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter
void reportError(ParseNode* pn, unsigned errorNumber, ...);
bool reportExtraWarning(ParseNode* pn, unsigned errorNumber, ...);
bool reportStrictModeError(ParseNode* pn, unsigned errorNumber, ...);
// If pn contains a useful expression, return true with *answer set to true.
// If pn contains a useless expression, return true with *answer set to
@ -632,7 +631,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitPrepareIteratorResult();
MOZ_MUST_USE bool emitFinishIteratorResult(bool done);
MOZ_MUST_USE bool iteratorResultShape(unsigned* shape);
MOZ_MUST_USE bool emitToIteratorResult(bool done);
MOZ_MUST_USE bool emitGetDotGenerator();

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

@ -9479,68 +9479,97 @@ Parser<SyntaxParseHandler, char16_t>::newRegExp()
return handler.newRegExp(SyntaxParseHandler::NodeGeneric, pos(), *this);
}
// |exprPossibleError| is the PossibleError state within |expr|,
// |possibleError| is the surrounding PossibleError state.
template <class ParseHandler, typename CharT>
void
bool
Parser<ParseHandler, CharT>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
PossibleError* exprPossibleError,
PossibleError* possibleError,
TargetBehavior behavior)
{
// Report any pending expression error if we're definitely not in a
// destructuring context or the possible destructuring target is a
// property accessor.
if (!possibleError || handler.isPropertyAccess(expr))
return exprPossibleError->checkForExpressionError();
// |expr| may end up as a destructuring assignment target, so we need to
// validate it's either a name or can be parsed as a nested destructuring
// pattern. Property accessors are also valid assignment targets, but
// those are already handled above.
exprPossibleError->transferErrorsTo(possibleError);
// Return early if a pending destructuring error is already present.
if (possibleError->hasPendingDestructuringError())
return true;
if (handler.isNameAnyParentheses(expr)) {
checkDestructuringAssignmentName(expr, exprPos, possibleError);
return true;
}
if (handler.isUnparenthesizedDestructuringPattern(expr)) {
if (behavior == TargetBehavior::ForbidAssignmentPattern)
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
return true;
}
// Parentheses are forbidden around destructuring *patterns* (but allowed
// around names). Use our nicer error message for parenthesized, nested
// patterns if nested destructuring patterns are allowed.
if (handler.isParenthesizedDestructuringPattern(expr) &&
behavior != TargetBehavior::ForbidAssignmentPattern)
{
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_PARENS);
} else {
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
}
return true;
}
template <class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::checkDestructuringAssignmentName(Node name, TokenPos namePos,
PossibleError* possibleError)
{
MOZ_ASSERT(handler.isNameAnyParentheses(name));
// Return early if a pending destructuring error is already present.
if (possibleError->hasPendingDestructuringError())
return;
if (pc->sc()->needStrictChecks()) {
if (handler.isArgumentsAnyParentheses(expr, context)) {
if (handler.isArgumentsAnyParentheses(name, context)) {
if (pc->sc()->strict()) {
possibleError->setPendingDestructuringErrorAt(exprPos,
possibleError->setPendingDestructuringErrorAt(namePos,
JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
} else {
possibleError->setPendingDestructuringWarningAt(exprPos,
possibleError->setPendingDestructuringWarningAt(namePos,
JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
}
return;
}
if (handler.isEvalAnyParentheses(expr, context)) {
if (handler.isEvalAnyParentheses(name, context)) {
if (pc->sc()->strict()) {
possibleError->setPendingDestructuringErrorAt(exprPos,
possibleError->setPendingDestructuringErrorAt(namePos,
JSMSG_BAD_STRICT_ASSIGN_EVAL);
} else {
possibleError->setPendingDestructuringWarningAt(exprPos,
possibleError->setPendingDestructuringWarningAt(namePos,
JSMSG_BAD_STRICT_ASSIGN_EVAL);
}
return;
}
}
if (behavior == TargetBehavior::ForbidAssignmentPattern) {
if (handler.isUnparenthesizedDestructuringPattern(expr) ||
handler.isParenthesizedDestructuringPattern(expr))
{
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
return;
}
}
// The expression must be either a simple assignment target, i.e. a name
// or a property accessor, or a nested destructuring pattern.
if (!handler.isUnparenthesizedDestructuringPattern(expr) &&
!handler.isNameAnyParentheses(expr) &&
!handler.isPropertyAccess(expr))
{
// Parentheses are forbidden around destructuring *patterns* (but
// allowed around names). Use our nicer error message for
// parenthesized, nested patterns.
if (handler.isParenthesizedDestructuringPattern(expr))
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_PARENS);
else
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
}
}
template <class ParseHandler, typename CharT>
void
bool
Parser<ParseHandler, CharT>::checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
PossibleError* exprPossibleError,
PossibleError* possibleError)
{
// ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
@ -9553,8 +9582,16 @@ Parser<ParseHandler, CharT>::checkDestructuringAssignmentElement(Node expr, Toke
// If |expr| is an assignment element with an initializer expression, its
// destructuring assignment target was already validated in assignExpr().
// Otherwise we need to check that |expr| is a valid destructuring target.
if (!handler.isUnparenthesizedAssignment(expr))
checkDestructuringAssignmentTarget(expr, exprPos, possibleError);
if (handler.isUnparenthesizedAssignment(expr)) {
// Report any pending expression error if we're definitely not in a
// destructuring context.
if (!possibleError)
return exprPossibleError->checkForExpressionError();
exprPossibleError->transferErrorsTo(possibleError);
return true;
}
return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError, possibleError);
}
template <class ParseHandler, typename CharT>
@ -9612,12 +9649,17 @@ Parser<ParseHandler, CharT>::arrayInitializer(YieldHandling yieldHandling,
if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
return null();
PossibleError possibleErrorInner(*this);
Node inner = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
&possibleErrorInner);
if (!inner)
return null();
if (possibleError)
checkDestructuringAssignmentTarget(inner, innerPos, possibleError);
if (!checkDestructuringAssignmentTarget(inner, innerPos, &possibleErrorInner,
possibleError))
{
return null();
}
if (!handler.addSpreadElement(literal, begin, inner))
return null();
} else {
@ -9625,12 +9667,16 @@ Parser<ParseHandler, CharT>::arrayInitializer(YieldHandling yieldHandling,
if (!tokenStream.peekTokenPos(&elementPos, TokenStream::Operand))
return null();
PossibleError possibleErrorInner(*this);
Node element = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
&possibleErrorInner);
if (!element)
return null();
if (possibleError)
checkDestructuringAssignmentElement(element, elementPos, possibleError);
if (!checkDestructuringAssignmentElement(element, elementPos, &possibleErrorInner,
possibleError))
{
return null();
}
if (foldConstants && !FoldConstants(context, &element, this))
return null();
handler.addArrayElement(literal, element);
@ -9913,13 +9959,16 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
return null();
PossibleError possibleErrorInner(*this);
Node inner = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
&possibleErrorInner);
if (!inner)
return null();
if (possibleError) {
checkDestructuringAssignmentTarget(inner, innerPos, possibleError,
TargetBehavior::ForbidAssignmentPattern);
if (!checkDestructuringAssignmentTarget(inner, innerPos, &possibleErrorInner,
possibleError,
TargetBehavior::ForbidAssignmentPattern))
{
return null();
}
if (!handler.addSpreadProperty(literal, begin, inner))
return null();
@ -9936,23 +9985,27 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
if (!tokenStream.peekTokenPos(&exprPos, TokenStream::Operand))
return null();
PossibleError possibleErrorInner(*this);
Node propExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
&possibleErrorInner);
if (!propExpr)
return null();
handler.checkAndSetIsDirectRHSAnonFunction(propExpr);
if (possibleError)
checkDestructuringAssignmentElement(propExpr, exprPos, possibleError);
if (!checkDestructuringAssignmentElement(propExpr, exprPos, &possibleErrorInner,
possibleError))
{
return null();
}
if (foldConstants && !FoldConstants(context, &propExpr, this))
return null();
if (propAtom == context->names().proto) {
if (seenPrototypeMutation) {
// Directly report the error when we're not in a
// destructuring context.
// Directly report the error when we're definitely not
// in a destructuring context.
if (!possibleError) {
errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
return null();
@ -9993,7 +10046,7 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
return null();
if (possibleError)
checkDestructuringAssignmentTarget(nameExpr, namePos, possibleError);
checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
if (!handler.addShorthand(literal, propName, nameExpr))
return null();

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

@ -928,10 +928,14 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
PermitAssignmentPattern,
ForbidAssignmentPattern
};
void checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
bool checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
PossibleError* exprPossibleError,
PossibleError* possibleError,
TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
void checkDestructuringAssignmentName(Node name, TokenPos namePos,
PossibleError* possibleError);
bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
PossibleError* exprPossibleError,
PossibleError* possibleError);
Node newNumber(const Token& tok) {

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

@ -1059,10 +1059,8 @@ IonBuilder::inlineBoolean(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineNewIterator(CallInfo& callInfo, MNewIterator::Type type)
{
if (callInfo.argc() != 0 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 0);
JSObject* templateObject = nullptr;
switch (type) {
@ -1698,10 +1696,8 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineStringSplitString(CallInfo& callInfo)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* strArg = callInfo.getArg(0);
MDefinition* sepArg = callInfo.getArg(1);
@ -1748,10 +1744,8 @@ IonBuilder::inlineStringSplitString(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineObjectHasPrototype(CallInfo& callInfo)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* objArg = callInfo.getArg(0);
MDefinition* protoArg = callInfo.getArg(1);
@ -2070,10 +2064,8 @@ IonBuilder::inlineRegExpMatcher(CallInfo& callInfo)
// This is called from Self-hosted JS, after testing each argument,
// most of following tests should be passed.
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
MDefinition* rxArg = callInfo.getArg(0);
MDefinition* strArg = callInfo.getArg(1);
@ -2087,7 +2079,7 @@ IonBuilder::inlineRegExpMatcher(CallInfo& callInfo)
if (clasp != &RegExpObject::class_)
return InliningStatus_NotInlined;
if (strArg->mightBeType(MIRType::Object))
if (strArg->type() != MIRType::String && strArg->type() != MIRType::Value)
return InliningStatus_NotInlined;
if (lastIndexArg->type() != MIRType::Int32)
@ -2116,10 +2108,8 @@ IonBuilder::inlineRegExpSearcher(CallInfo& callInfo)
// This is called from Self-hosted JS, after testing each argument,
// most of following tests should be passed.
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
MDefinition* rxArg = callInfo.getArg(0);
MDefinition* strArg = callInfo.getArg(1);
@ -2133,7 +2123,7 @@ IonBuilder::inlineRegExpSearcher(CallInfo& callInfo)
if (clasp != &RegExpObject::class_)
return InliningStatus_NotInlined;
if (strArg->mightBeType(MIRType::Object))
if (strArg->type() != MIRType::String && strArg->type() != MIRType::Value)
return InliningStatus_NotInlined;
if (lastIndexArg->type() != MIRType::Int32)
@ -2162,10 +2152,8 @@ IonBuilder::inlineRegExpTester(CallInfo& callInfo)
// This is called from Self-hosted JS, after testing each argument,
// most of following tests should be passed.
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
MDefinition* rxArg = callInfo.getArg(0);
MDefinition* strArg = callInfo.getArg(1);
@ -2179,7 +2167,7 @@ IonBuilder::inlineRegExpTester(CallInfo& callInfo)
if (clasp != &RegExpObject::class_)
return InliningStatus_NotInlined;
if (strArg->mightBeType(MIRType::Object))
if (strArg->type() != MIRType::String && strArg->type() != MIRType::Value)
return InliningStatus_NotInlined;
if (lastIndexArg->type() != MIRType::Int32)
@ -2204,32 +2192,39 @@ IonBuilder::inlineRegExpTester(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineIsRegExpObject(CallInfo& callInfo)
{
if (callInfo.constructing() || callInfo.argc() != 1) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::Boolean)
return InliningStatus_NotInlined;
MDefinition* arg = callInfo.getArg(0);
bool isRegExpObject;
if (!arg->mightBeType(MIRType::Object)) {
isRegExpObject = false;
} else {
if (arg->type() != MIRType::Object)
return InliningStatus_NotInlined;
bool isRegExpObjectKnown = false;
bool isRegExpObjectConstant;
if (arg->type() == MIRType::Object) {
TemporaryTypeSet* types = arg->resultTypeSet();
const Class* clasp = types ? types->getKnownClass(constraints()) : nullptr;
if (!clasp || clasp->isProxy())
return InliningStatus_NotInlined;
isRegExpObject = (clasp == &RegExpObject::class_);
if (clasp) {
isRegExpObjectKnown = true;
isRegExpObjectConstant = (clasp == &RegExpObject::class_);
}
} else if (!arg->mightBeType(MIRType::Object)) {
// NB: This case only happens when Phi-nodes flow into IsRegExpObject.
// IsRegExpObject itself will never be called with a non-Object value.
isRegExpObjectKnown = true;
isRegExpObjectConstant = false;
} else if (arg->type() != MIRType::Value) {
return InliningStatus_NotInlined;
}
pushConstant(BooleanValue(isRegExpObject));
if (isRegExpObjectKnown) {
pushConstant(BooleanValue(isRegExpObjectConstant));
} else {
MHasClass* hasClass = MHasClass::New(alloc(), arg, &RegExpObject::class_);
current->add(hasClass);
current->push(hasClass);
}
callInfo.setImplicitlyUsedUnchecked();
return InliningStatus_Inlined;
@ -2238,10 +2233,8 @@ IonBuilder::inlineIsRegExpObject(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineRegExpPrototypeOptimizable(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
MDefinition* protoArg = callInfo.getArg(0);
@ -2263,15 +2256,13 @@ IonBuilder::inlineRegExpPrototypeOptimizable(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineRegExpInstanceOptimizable(CallInfo& callInfo)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* rxArg = callInfo.getArg(0);
MDefinition* protoArg = callInfo.getArg(1);
if (rxArg->type() != MIRType::Object)
if (rxArg->type() != MIRType::Object && rxArg->type() != MIRType::Value)
return InliningStatus_NotInlined;
if (protoArg->type() != MIRType::Object)
@ -2292,10 +2283,8 @@ IonBuilder::inlineRegExpInstanceOptimizable(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineGetFirstDollarIndex(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
MDefinition* strArg = callInfo.getArg(0);
@ -2317,10 +2306,8 @@ IonBuilder::inlineGetFirstDollarIndex(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineStringReplaceString(CallInfo& callInfo)
{
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
if (getInlineReturnType() != MIRType::String)
return InliningStatus_NotInlined;
@ -2351,8 +2338,8 @@ IonBuilder::inlineStringReplaceString(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineSubstringKernel(CallInfo& callInfo)
{
MOZ_ASSERT(callInfo.argc() == 3);
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
// Return: String.
if (getInlineReturnType() != MIRType::String)
@ -2499,10 +2486,8 @@ IonBuilder::inlineHasClass(CallInfo& callInfo,
const Class* clasp1, const Class* clasp2,
const Class* clasp3, const Class* clasp4)
{
if (callInfo.constructing() || callInfo.argc() != 1) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (callInfo.getArg(0)->type() != MIRType::Object)
return InliningStatus_NotInlined;
@ -2546,10 +2531,8 @@ IonBuilder::inlineHasClass(CallInfo& callInfo,
IonBuilder::InliningResult
IonBuilder::inlineGetNextEntryForIterator(CallInfo& callInfo, MGetNextEntryForIterator::Mode mode)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* iterArg = callInfo.getArg(0);
MDefinition* resultArg = callInfo.getArg(1);
@ -2875,10 +2858,8 @@ IonBuilder::inlineSetDisjointTypedElements(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineObjectIsTypeDescr(CallInfo& callInfo)
{
if (callInfo.constructing() || callInfo.argc() != 1) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (callInfo.getArg(0)->type() != MIRType::Object)
return InliningStatus_NotInlined;
@ -2914,10 +2895,8 @@ IonBuilder::inlineObjectIsTypeDescr(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineSetTypedObjectOffset(CallInfo& callInfo)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* typedObj = callInfo.getArg(0);
MDefinition* offset = callInfo.getArg(1);
@ -2958,10 +2937,9 @@ IonBuilder::inlineSetTypedObjectOffset(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineUnsafeSetReservedSlot(CallInfo& callInfo)
{
if (callInfo.argc() != 3 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 3);
if (getInlineReturnType() != MIRType::Undefined)
return InliningStatus_NotInlined;
@ -2998,10 +2976,8 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineUnsafeGetReservedSlot(CallInfo& callInfo, MIRType knownValueType)
{
if (callInfo.argc() != 2 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 2);
MDefinition* obj = callInfo.getArg(0);
if (obj->type() != MIRType::Object && obj->type() != MIRType::Value)
@ -3045,10 +3021,8 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo& callInfo, MIRType knownValueTy
IonBuilder::InliningResult
IonBuilder::inlineIsCallable(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::Boolean)
return InliningStatus_NotInlined;
@ -3113,10 +3087,9 @@ IonBuilder::inlineIsConstructor(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineIsObject(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::Boolean)
return InliningStatus_NotInlined;
@ -3134,10 +3107,8 @@ IonBuilder::inlineIsObject(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineToObject(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::Object)
return InliningStatus_NotInlined;
@ -3165,10 +3136,8 @@ IonBuilder::inlineToObject(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineIsWrappedArrayConstructor(CallInfo& callInfo)
{
if (callInfo.constructing() || callInfo.argc() != 1) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::Boolean)
return InliningStatus_NotInlined;
@ -3196,10 +3165,8 @@ IonBuilder::inlineIsWrappedArrayConstructor(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineToInteger(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
MDefinition* input = callInfo.getArg(0);
@ -3231,8 +3198,8 @@ IonBuilder::inlineToInteger(CallInfo& callInfo)
IonBuilder::InliningResult
IonBuilder::inlineToString(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing())
return InliningStatus_NotInlined;
MOZ_ASSERT(!callInfo.constructing());
MOZ_ASSERT(callInfo.argc() == 1);
if (getInlineReturnType() != MIRType::String)
return InliningStatus_NotInlined;

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

@ -13644,7 +13644,8 @@ class MHasClass
: MUnaryInstruction(classOpcode, object)
, class_(clasp)
{
MOZ_ASSERT(object->type() == MIRType::Object);
MOZ_ASSERT(object->type() == MIRType::Object ||
(object->type() == MIRType::Value && object->mightBeType(MIRType::Object)));
setResultType(MIRType::Boolean);
setMovable();
}

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

@ -2278,6 +2278,9 @@ inline int CheckIsSetterOp(JSSetterOp op);
#define JS_PSGS(name, getter, setter, flags) \
JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
JSPROP_SHARED)
#define JS_SYM_GET(symbol, getter, flags) \
JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, JSPROP_SHARED)
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
JSPROP_SHARED | JSPROP_GETTER)

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

@ -635,11 +635,13 @@ static bool
array_length_setter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
ObjectOpResult& result)
{
MOZ_ASSERT(id == NameToId(cx->names().length));
if (!obj->is<ArrayObject>()) {
// This array .length property was found on the prototype
// chain. Ideally the setter should not have been called, but since
// we're here, do an impression of SetPropertyByDefining.
return DefineDataProperty(cx, obj, cx->names().length, vp, JSPROP_ENUMERATE, result);
return DefineDataProperty(cx, obj, id, vp, JSPROP_ENUMERATE, result);
}
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());

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

@ -47,6 +47,10 @@ AtomToId(JSAtom* atom)
return JSID_FROM_BITS(size_t(atom));
}
// Use the NameToId method instead!
inline jsid
AtomToId(PropertyName* name) = delete;
inline bool
ValueToIdPure(const Value& v, jsid* id)
{

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

@ -749,9 +749,6 @@ DefineFunction(JSContext* cx, HandleObject obj, HandleId id, JSNative native,
unsigned nargs, unsigned flags,
gc::AllocKind allocKind = gc::AllocKind::FUNCTION);
bool
FunctionHasResolveHook(const JSAtomState& atomState, jsid id);
extern bool
fun_toString(JSContext* cx, unsigned argc, Value* vp);

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

@ -94,9 +94,6 @@ GenerateRandomSeed();
extern void
GenerateXorShift128PlusSeed(mozilla::Array<uint64_t, 2>& seed);
extern uint64_t
random_next(uint64_t* rngState, int bits);
extern double
math_random_impl(JSContext* cx);

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

@ -1440,14 +1440,6 @@ js::NumberToAtom(JSContext* cx, double d)
return atom;
}
JSFlatString*
js::NumberToString(JSContext* cx, double d)
{
if (JSString* str = NumberToStringWithBase<CanGC>(cx, d, 10))
return &str->asFlat();
return nullptr;
}
JSFlatString*
js::IndexToString(JSContext* cx, uint32_t index)
{

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

@ -92,10 +92,6 @@ IsInteger(const Value& val);
extern MOZ_MUST_USE bool JS_FASTCALL
NumberValueToStringBuffer(JSContext* cx, const Value& v, StringBuffer& sb);
/* Same as js_NumberToString, different signature. */
extern JSFlatString*
NumberToString(JSContext* cx, double d);
extern JSFlatString*
IndexToString(JSContext* cx, uint32_t index);

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

@ -265,29 +265,13 @@ js::Throw(JSContext* cx, jsid id, unsigned errorNumber, const char* details)
if (details) {
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr(),
details);
}
else {
} else {
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr());
}
return false;
}
bool
js::Throw(JSContext* cx, JSObject* obj, unsigned errorNumber)
{
if (js_ErrorFormatString[errorNumber].argCount == 1) {
RootedValue val(cx, ObjectValue(*obj));
ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,
JSDVG_IGNORE_STACK, val, nullptr,
nullptr, nullptr);
} else {
MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount == 0);
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, errorNumber);
}
return false;
}
/*** PropertyDescriptor operations and DefineProperties ******************************************/
@ -1949,9 +1933,9 @@ JSObject::fixupAfterMovingGC()
}
}
bool
js::SetClassAndProto(JSContext* cx, HandleObject obj,
const Class* clasp, Handle<js::TaggedProto> proto)
static bool
SetClassAndProto(JSContext* cx, HandleObject obj,
const Class* clasp, Handle<js::TaggedProto> proto)
{
// Regenerate the object's shape. If the object is a proto (isDelegate()),
// we also need to regenerate shapes for all of the objects along the old
@ -4056,34 +4040,77 @@ JSObject::maybeConstructorDisplayAtom() const
return displayAtomFromObjectGroup(*group());
}
bool
js::SpeciesConstructor(JSContext* cx, HandleObject obj, HandleValue defaultCtor, MutableHandleValue pctor)
// ES 2016 7.3.20.
MOZ_MUST_USE JSObject*
js::SpeciesConstructor(JSContext* cx, HandleObject obj, HandleObject defaultCtor,
bool (*isDefaultSpecies)(JSContext*, JSFunction*))
{
HandlePropertyName shName = cx->names().SpeciesConstructor;
RootedValue func(cx);
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, shName, 2, &func))
return false;
// Step 1 (implicit).
FixedInvokeArgs<2> args(cx);
// Fast-path for steps 2 - 8. Applies if all of the following conditions
// are met:
// - obj.constructor can be retrieved without side-effects.
// - obj.constructor[[@@species]] can be retrieved without side-effects.
// - obj.constructor[[@@species]] is the builtin's original @@species
// getter.
RootedValue ctor(cx);
bool ctorGetSucceeded = GetPropertyPure(cx, obj, NameToId(cx->names().constructor),
ctor.address());
if (ctorGetSucceeded && ctor.isObject() && &ctor.toObject() == defaultCtor) {
RootedObject ctorObj(cx, &ctor.toObject());
RootedId speciesId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().species));
JSFunction* getter;
if (GetGetterPure(cx, ctorObj, speciesId, &getter) && getter &&
isDefaultSpecies(cx, getter))
{
return defaultCtor;
}
}
args[0].setObject(*obj);
args[1].set(defaultCtor);
// Step 2.
if (!ctorGetSucceeded && !GetProperty(cx, obj, obj, cx->names().constructor, &ctor))
return nullptr;
if (!Call(cx, func, UndefinedHandleValue, args, pctor))
return false;
// Step 3.
if (ctor.isUndefined())
return defaultCtor;
pctor.set(args.rval());
return true;
// Step 4.
if (!ctor.isObject()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
"object's 'constructor' property");
return nullptr;
}
// Step 5.
RootedObject ctorObj(cx, &ctor.toObject());
RootedValue s(cx);
RootedId speciesId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().species));
if (!GetProperty(cx, ctorObj, ctor, speciesId, &s))
return nullptr;
// Step 6.
if (s.isNullOrUndefined())
return defaultCtor;
// Step 7.
if (IsConstructor(s))
return &s.toObject();
// Step 8.
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_CONSTRUCTOR,
"[Symbol.species] property of object's constructor");
return nullptr;
}
bool
MOZ_MUST_USE JSObject*
js::SpeciesConstructor(JSContext* cx, HandleObject obj, JSProtoKey ctorKey,
MutableHandleValue pctor)
bool (*isDefaultSpecies)(JSContext*, JSFunction*))
{
if (!GlobalObject::ensureConstructor(cx, cx->global(), ctorKey))
return false;
RootedValue defaultCtor(cx, cx->global()->getConstructor(ctorKey));
return SpeciesConstructor(cx, obj, defaultCtor, pctor);
return nullptr;
RootedObject defaultCtor(cx, &cx->global()->getConstructor(ctorKey).toObject());
return SpeciesConstructor(cx, obj, defaultCtor, isDefaultSpecies);
}
bool

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

@ -42,30 +42,6 @@ namespace gc {
class RelocationOverlay;
} // namespace gc
inline JSObject*
CastAsObject(GetterOp op)
{
return JS_FUNC_TO_DATA_PTR(JSObject*, op);
}
inline JSObject*
CastAsObject(SetterOp op)
{
return JS_FUNC_TO_DATA_PTR(JSObject*, op);
}
inline Value
CastAsObjectJsval(GetterOp op)
{
return ObjectOrNullValue(CastAsObject(op));
}
inline Value
CastAsObjectJsval(SetterOp op)
{
return ObjectOrNullValue(CastAsObject(op));
}
/******************************************************************************/
extern const Class IntlClass;
@ -884,30 +860,15 @@ GetElement(JSContext* cx, HandleObject obj, HandleObject receiver, uint32_t inde
inline bool
GetPropertyNoGC(JSContext* cx, JSObject* obj, const Value& receiver, jsid id, Value* vp);
inline bool
GetPropertyNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, jsid id, Value* vp)
{
return GetPropertyNoGC(cx, obj, ObjectValue(*receiver), id, vp);
}
inline bool
GetPropertyNoGC(JSContext* cx, JSObject* obj, const Value& receiver, PropertyName* name, Value* vp)
{
return GetPropertyNoGC(cx, obj, receiver, NameToId(name), vp);
}
inline bool
GetPropertyNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, PropertyName* name, Value* vp)
{
return GetPropertyNoGC(cx, obj, ObjectValue(*receiver), name, vp);
}
inline bool
GetElementNoGC(JSContext* cx, JSObject* obj, const Value& receiver, uint32_t index, Value* vp);
inline bool
GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t index, Value* vp);
// Returns whether |obj| or an object on its proto chain may have an interesting
// symbol property (see JSObject::hasInterestingSymbolProperty). If it returns
// true, *holder is set to the object that may have this property.
@ -1124,31 +1085,11 @@ GetBuiltinPrototype(JSContext* cx, JSProtoKey key, MutableHandleObject objp);
JSObject*
GetBuiltinPrototypePure(GlobalObject* global, JSProtoKey protoKey);
extern bool
SetClassAndProto(JSContext* cx, HandleObject obj,
const Class* clasp, Handle<TaggedProto> proto);
extern bool
IsStandardPrototype(JSObject* obj, JSProtoKey key);
} /* namespace js */
/*
* Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
*/
extern const char js_watch_str[];
extern const char js_unwatch_str[];
extern const char js_hasOwnProperty_str[];
extern const char js_isPrototypeOf_str[];
extern const char js_propertyIsEnumerable_str[];
#ifdef JS_OLD_GETTER_SETTER_METHODS
extern const char js_defineGetter_str[];
extern const char js_defineSetter_str[];
extern const char js_lookupGetter_str[];
extern const char js_lookupSetter_str[];
#endif
namespace js {
inline gc::InitialHeap
@ -1284,9 +1225,6 @@ LookupNameUnqualified(JSContext* cx, HandlePropertyName name, HandleObject scope
namespace js {
extern JSObject*
FindVariableScope(JSContext* cx, JSFunction** funp);
bool
LookupPropertyPure(JSContext* cx, JSObject* obj, jsid id, JSObject** objp,
PropertyResult* propp);
@ -1314,9 +1252,6 @@ bool
GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
MutableHandle<JS::PropertyDescriptor> desc);
bool
GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
/*
* Like JS::FromPropertyDescriptor, but ignore desc.object() and always set vp
* to an object on success.
@ -1412,13 +1347,10 @@ extern bool
GetFirstArgumentAsObject(JSContext* cx, const CallArgs& args, const char* method,
MutableHandleObject objp);
/* Helpers for throwing. These always return false. */
/* Helper for throwing, always returns false. */
extern bool
Throw(JSContext* cx, jsid id, unsigned errorNumber, const char* details = nullptr);
extern bool
Throw(JSContext* cx, JSObject* obj, unsigned errorNumber);
/*
* ES6 rev 29 (6 Dec 2014) 7.3.13. Mark obj as non-extensible, and adjust each
* of obj's own properties' attributes appropriately: each property becomes
@ -1441,11 +1373,13 @@ FreezeObject(JSContext* cx, HandleObject obj)
extern bool
TestIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level, bool* resultp);
extern bool
SpeciesConstructor(JSContext* cx, HandleObject obj, HandleValue defaultCtor, MutableHandleValue pctor);
extern MOZ_MUST_USE JSObject*
SpeciesConstructor(JSContext* cx, HandleObject obj, HandleObject defaultCtor,
bool (*isDefaultSpecies)(JSContext*, JSFunction*));
extern bool
SpeciesConstructor(JSContext* cx, HandleObject obj, JSProtoKey ctorKey, MutableHandleValue pctor);
extern MOZ_MUST_USE JSObject*
SpeciesConstructor(JSContext* cx, HandleObject obj, JSProtoKey ctorKey,
bool (*isDefaultSpecies)(JSContext*, JSFunction*));
extern bool
GetObjectFromIncumbentGlobal(JSContext* cx, MutableHandleObject obj);

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

@ -251,12 +251,6 @@ js::GetElementNoGC(JSContext* cx, JSObject* obj, const Value& receiver, uint32_t
return GetPropertyNoGC(cx, obj, receiver, INT_TO_JSID(index), vp);
}
inline bool
js::GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t index, Value* vp)
{
return GetElementNoGC(cx, obj, ObjectValue(*receiver), index, vp);
}
inline bool
js::DeleteProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result)
{

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

@ -86,14 +86,11 @@ enum JSProtoKey {
/* Struct forward declarations. */
struct JSClass;
struct JSCompartment;
struct JSCrossCompartmentCall;
class JSErrorReport;
struct JSExceptionState;
struct JSFunctionSpec;
struct JSLocaleCallbacks;
struct JSObjectMap;
struct JSPrincipals;
struct JSPropertyName;
struct JSPropertySpec;
struct JSRuntime;
struct JSSecurityCallbacks;

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

@ -1867,15 +1867,6 @@ StringMatch(JSLinearString* text, JSLinearString* pat, uint32_t start = 0)
static const size_t sRopeMatchThresholdRatioLog2 = 4;
bool
js::StringHasPattern(JSLinearString* text, const char16_t* pat, uint32_t patLen)
{
AutoCheckCannotGC nogc;
return text->hasLatin1Chars()
? StringMatch(text->latin1Chars(nogc), text->length(), pat, patLen) != -1
: StringMatch(text->twoByteChars(nogc), text->length(), pat, patLen) != -1;
}
int
js::StringFindPattern(JSLinearString* text, JSLinearString* pat, size_t start)
{

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

@ -234,10 +234,6 @@ CompareAtoms(JSAtom* atom1, JSAtom* atom2);
extern bool
StringEqualsAscii(JSLinearString* str, const char* asciiBytes);
/* Return true if the string contains a pattern anywhere inside it. */
extern bool
StringHasPattern(JSLinearString* text, const char16_t* pat, uint32_t patlen);
extern int
StringFindPattern(JSLinearString* text, JSLinearString* pat, size_t start);

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

@ -47,44 +47,6 @@ js_memcpy(void* dst_, const void* src_, size_t len)
namespace js {
template <class T>
class AlignedPtrAndFlag
{
uintptr_t bits;
public:
AlignedPtrAndFlag(T* t, bool aFlag) {
MOZ_ASSERT((uintptr_t(t) & 1) == 0);
bits = uintptr_t(t) | uintptr_t(aFlag);
}
T* ptr() const {
return (T*)(bits & ~uintptr_t(1));
}
bool flag() const {
return (bits & 1) != 0;
}
void setPtr(T* t) {
MOZ_ASSERT((uintptr_t(t) & 1) == 0);
bits = uintptr_t(t) | uintptr_t(flag());
}
void setFlag() {
bits |= 1;
}
void unsetFlag() {
bits &= ~uintptr_t(1);
}
void set(T* t, bool aFlag) {
MOZ_ASSERT((uintptr_t(t) & 1) == 0);
bits = uintptr_t(t) | aFlag;
}
};
template <class T>
static inline void
Reverse(T* beg, T* end)
@ -183,22 +145,6 @@ Max(T t1, T t2)
return t1 > t2 ? t1 : t2;
}
/* Allows a const variable to be initialized after its declaration. */
template <class T>
static T&
InitConst(const T& t)
{
return const_cast<T&>(t);
}
template <class T, class U>
MOZ_ALWAYS_INLINE T&
ImplicitCast(U& u)
{
T& t = u;
return t;
}
template<typename T>
class MOZ_RAII AutoScopedAssign
{

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

@ -1409,7 +1409,7 @@ js::proxy_revocable(JSContext* cx, unsigned argc, Value* vp)
MOZ_ASSERT(proxyVal.toObject().is<ProxyObject>());
RootedObject revoker(cx, NewFunctionByIdWithReserved(cx, RevokeProxy, 0, 0,
AtomToId(cx->names().revoke)));
NameToId(cx->names().revoke)));
if (!revoker)
return false;

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

@ -0,0 +1,44 @@
// Ensure array or object literals with trailing property accessors are not
// treated as nested destructuring patterns in assignment destructuring
// contexts.
// Array destructuring with normal element.
[{a: 0}.x] = [];
[[0].x] = [];
// Array destructuring with spread element.
[...{a: 0}.x] = [];
[...[0].x] = [];
// Object destructuring with normal property.
({a: {b: 0}.x} = {});
({a: [0].x} = {});
// Object destructuring with spread property.
({...{b: 0}.x} = {});
({...[0].x} = {});
// Object literal with initializer shorthand in destructuring context.
assertThrowsInstanceOf(() => Function(`[{a = 0}.x] = [];`), SyntaxError);
assertThrowsInstanceOf(() => Function(`[...{a = 0}.x] = [];`), SyntaxError);
assertThrowsInstanceOf(() => Function(`({a: {b = 0}.x} = {});`), SyntaxError);
assertThrowsInstanceOf(() => Function(`({...{b = 0}.x} = {});`), SyntaxError);
// Object destructuring with "eval" or "arguments" shorthand in strict mode.
(function() {
"use strict";
// Ensure "eval" resp. "arguments" is not treated as an assignment.
[{eval}.x] = [];
[...{eval}.x] = [];
({a: {eval}.x} = {});
({...{eval}.x} = {});
[{arguments}.x] = [];
[...{arguments}.x] = [];
({a: {arguments}.x} = {});
({...{arguments}.x} = {});
})();
if (typeof reportCompare === "function")
reportCompare(0, 0);

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

@ -6761,10 +6761,10 @@ DebuggerScript_getOffsetsCoverage(JSContext* cx, unsigned argc, Value* vp)
if (!result)
return false;
RootedId offsetId(cx, AtomToId(cx->names().offset));
RootedId lineNumberId(cx, AtomToId(cx->names().lineNumber));
RootedId columnNumberId(cx, AtomToId(cx->names().columnNumber));
RootedId countId(cx, AtomToId(cx->names().count));
RootedId offsetId(cx, NameToId(cx->names().offset));
RootedId lineNumberId(cx, NameToId(cx->names().lineNumber));
RootedId columnNumberId(cx, NameToId(cx->names().columnNumber));
RootedId countId(cx, NameToId(cx->names().count));
RootedObject item(cx);
RootedValue offsetValue(cx);

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

@ -1858,34 +1858,6 @@ js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
return NativeDefineProperty(cx, obj, id, desc, result);
}
bool
js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
ObjectOpResult& result)
{
RootedId id(cx, NameToId(name));
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
}
bool
js::NativeDefineElement(JSContext* cx, HandleNativeObject obj, uint32_t index,
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
ObjectOpResult& result)
{
RootedId id(cx);
if (index <= JSID_INT_MAX) {
id = INT_TO_JSID(index);
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
}
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
if (!IndexToId(cx, index, &id))
return false;
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
}
bool
js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
HandleValue value, JSGetterOp getter, JSSetterOp setter,

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

@ -1397,16 +1397,6 @@ NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleV
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result);
extern bool
NativeDefineProperty(JSContext* cx, HandleNativeObject obj, PropertyName* name,
HandleValue value, GetterOp getter, SetterOp setter,
unsigned attrs, ObjectOpResult& result);
extern bool
NativeDefineElement(JSContext* cx, HandleNativeObject obj, uint32_t index, HandleValue value,
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
ObjectOpResult& result);
/* If the result out-param is omitted, throw on failure. */
extern bool
NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,

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

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

@ -186,13 +186,12 @@ intrinsic_IsConstructor(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 1);
RootedValue val(cx, args[0]);
if (!IsConstructor(val)) {
if (!IsConstructor(args[0])) {
args.rval().setBoolean(false);
return true;
}
RootedObject obj(cx, &val.toObject());
JSObject* obj = &args[0].toObject();
if (!IsWrapper(obj)) {
args.rval().setBoolean(true);
return true;

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

@ -1067,70 +1067,28 @@ TypedArrayObjectTemplate<T>::AllocateArrayBuffer(JSContext* cx, HandleValue ctor
}
static bool
IsArrayBufferConstructor(const Value& v)
IsArrayBufferSpecies(JSContext* cx, JSFunction* species)
{
return v.isObject() &&
v.toObject().is<JSFunction>() &&
v.toObject().as<JSFunction>().isNative() &&
v.toObject().as<JSFunction>().native() == ArrayBufferObject::class_constructor;
return IsSelfHostedFunctionWithName(species, cx->names().ArrayBufferSpecies);
}
static bool
IsArrayBufferSpecies(JSContext* cx, HandleObject origBuffer)
{
RootedValue ctor(cx);
if (!GetPropertyPure(cx, origBuffer, NameToId(cx->names().constructor), ctor.address()))
return false;
if (!IsArrayBufferConstructor(ctor))
return false;
RootedObject ctorObj(cx, &ctor.toObject());
RootedId speciesId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().species));
JSFunction* getter;
if (!GetGetterPure(cx, ctorObj, speciesId, &getter))
return false;
if (!getter)
return false;
return IsSelfHostedFunctionWithName(getter, cx->names().ArrayBufferSpecies);
}
static bool
static JSObject*
GetSpeciesConstructor(JSContext* cx, HandleObject obj, bool isWrapped,
SpeciesConstructorOverride override, MutableHandleValue ctor)
SpeciesConstructorOverride override)
{
if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_ArrayBuffer))
return false;
RootedValue defaultCtor(cx, cx->global()->getConstructor(JSProto_ArrayBuffer));
return nullptr;
RootedObject defaultCtor(cx, &cx->global()->getConstructor(JSProto_ArrayBuffer).toObject());
// Use the current global's ArrayBuffer if the override is set.
if (override == SpeciesConstructorOverride::ArrayBuffer) {
ctor.set(defaultCtor);
return true;
}
if (!isWrapped) {
// As an optimization, avoid calling into self-hosted code if |obj|'s
// constructor is the built-in ArrayBuffer and the constructor's
// species property is the original ArrayBuffer[@@species] function.
if (IsArrayBufferSpecies(cx, obj))
ctor.set(defaultCtor);
else if (!SpeciesConstructor(cx, obj, defaultCtor, ctor))
return false;
return true;
}
if (override == SpeciesConstructorOverride::ArrayBuffer)
return defaultCtor;
RootedObject wrappedObj(cx, obj);
if (!cx->compartment()->wrap(cx, &wrappedObj))
return false;
if (isWrapped && !cx->compartment()->wrap(cx, &wrappedObj))
return nullptr;
if (!SpeciesConstructor(cx, wrappedObj, defaultCtor, ctor))
return false;
return true;
return SpeciesConstructor(cx, wrappedObj, defaultCtor, IsArrayBufferSpecies);
}
// ES 2017 draft rev 8633ffd9394b203b8876bb23cb79aff13eb07310 24.1.1.4.
@ -1146,9 +1104,10 @@ TypedArrayObjectTemplate<T>::CloneArrayBufferNoCopy(JSContext* cx,
// Step 1 (skipped).
// Step 2.a.
RootedValue cloneCtor(cx);
if (!GetSpeciesConstructor(cx, srcBuffer, isWrapped, override, &cloneCtor))
JSObject* ctorObj = GetSpeciesConstructor(cx, srcBuffer, isWrapped, override);
if (!ctorObj)
return false;
RootedValue cloneCtor(cx, ObjectValue(*ctorObj));
// Step 2.b.
if (srcBuffer->isDetached()) {
@ -1266,9 +1225,10 @@ TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, b
}
} else {
// Steps 17.a-b.
RootedValue bufferCtor(cx);
if (!GetSpeciesConstructor(cx, srcData, isWrapped, override, &bufferCtor))
JSObject* ctorObj = GetSpeciesConstructor(cx, srcData, isWrapped, override);
if (!ctorObj)
return nullptr;
RootedValue bufferCtor(cx, ObjectValue(*ctorObj));
// Steps 14-15, 17.c.
if (!AllocateArrayBuffer(cx, bufferCtor, elementLength, BYTES_PER_ELEMENT, &buffer))

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

@ -1765,7 +1765,7 @@ static bool
CombineArrayObjectElements(JSContext* cx, ArrayObject* obj, JSValueType* elementType)
{
if (obj->inDictionaryMode() ||
obj->lastProperty()->propid() != AtomToId(cx->names().length) ||
obj->lastProperty()->propid() != NameToId(cx->names().length) ||
!obj->lastProperty()->previous()->isEmptyShape())
{
// Only use an unboxed representation if the object has no properties.

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

@ -60,7 +60,8 @@ using namespace xpc;
using namespace JS;
static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
static const char kJSCachePrefix[] = "jsloader";
#define JS_CACHE_PREFIX(aType) "jsloader/" aType
/**
* Buffer sizes for serialization and deserialization of scripts.
@ -303,7 +304,16 @@ mozJSComponentLoader::ReallyInit()
{
MOZ_ASSERT(!mInitialized);
mShareLoaderGlobal = Preferences::GetBool("jsloader.shareGlobal");
const char* shareGlobal = PR_GetEnv("MOZ_LOADER_SHARE_GLOBAL");
if (shareGlobal && *shareGlobal) {
nsDependentCString val(shareGlobal);
mShareLoaderGlobal = !(val.EqualsLiteral("0") ||
val.LowerCaseEqualsLiteral("no") ||
val.LowerCaseEqualsLiteral("false") ||
val.LowerCaseEqualsLiteral("off"));
} else {
mShareLoaderGlobal = Preferences::GetBool("jsloader.shareGlobal");
}
nsresult rv;
nsCOMPtr<nsIObserverService> obsSvc =
@ -701,7 +711,8 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo,
aInfo.EnsureResolvedURI();
nsAutoCString cachePath(kJSCachePrefix);
nsAutoCString cachePath(reuseGlobal ? JS_CACHE_PREFIX("non-syntactic")
: JS_CACHE_PREFIX("global"));
rv = PathifyURI(aInfo.ResolvedURI(), cachePath);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -0,0 +1,3 @@
[test_loader_global_sharing.py]
skip-if = !manage_instance || appname == 'fennec'

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

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

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

@ -0,0 +1,119 @@
from __future__ import print_function
from marionette_harness import MarionetteTestCase
GLOBAL_SHARING_PREF = 'jsloader.shareGlobal'
GLOBAL_SHARING_VAR = 'MOZ_LOADER_SHARE_GLOBAL'
class TestLoaderGlobalSharing(MarionetteTestCase):
sandbox_name = 'loader-global-sharing'
def execute_script(self, code, *args, **kwargs):
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
return self.marionette.execute_script(code,
new_sandbox=False,
sandbox=self.sandbox_name,
*args, **kwargs)
def get_global_sharing_enabled(self):
return self.execute_script(r'''
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
return (Cu.getGlobalForObject(Services) ===
Cu.getGlobalForObject(XPCOMUtils))
''')
def set_env(self, env, value):
self.execute_script('env.set(arguments[0], arguments[1]);',
script_args=(env, value))
def get_env(self, env):
return self.execute_script('return env.get(arguments[0]);',
script_args=(env,))
def restart(self, prefs=None, env=None):
if prefs:
self.marionette.set_prefs(prefs)
if env:
for name, value in env.items():
self.set_env(name, value)
self.marionette.restart(in_app=True, clean=False)
self.setUpSession()
# Sanity check our environment.
if prefs:
for key, val in prefs.items():
self.assertEqual(self.marionette.get_pref(key), val)
if env:
for key, val in env.items():
self.assertEqual(self.get_env(key), val or '')
def setUpSession(self):
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
self.execute_script(r'''
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} =
Components;
// We're running in a function, in a sandbox, that inherits from an
// X-ray wrapped window. Anything we want to be globally available
// needs to be defined on that window.
Object.assign(window, {Cc, Ci, Cu, Cr});
Cu.import("resource://gre/modules/Services.jsm");
window.env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
''')
def setUp(self):
super(TestLoaderGlobalSharing, self).setUp()
self.default_pref_value = self.marionette.get_pref(GLOBAL_SHARING_PREF)
self.setUpSession()
def tearDown(self):
self.marionette.restart(clean=True)
super(TestLoaderGlobalSharing, self).tearDown()
def test_global_sharing_settings(self):
# The different cases to test, with the first element being the value
# of the MOZ_LOADER_SHARE_GLOBAL environment variable, and the second
# being the value of the "jsloader.shareGlobal" preference.
#
# The browser is restarted after each change, but the profile is not
# reset.
CASES = (
(None, False),
(None, True),
('0', True),
('1', True),
('0', False),
('1', False),
)
for var, pref in CASES:
print('Testing %s=%r %s=%r' % (GLOBAL_SHARING_VAR, var,
GLOBAL_SHARING_PREF, pref))
# The value of the environment variable takes precedence if it's
# defined.
expect_sharing = pref if var is None else var != '0'
self.restart(prefs={GLOBAL_SHARING_PREF: pref},
env={GLOBAL_SHARING_VAR: var})
have_sharing = self.get_global_sharing_enabled()
# FIXME: User preference values currently do not always take
# effect early enough to influence loader behavior.
msg = ('Global sharing state should match settings: %r != %r'
% (have_sharing, expect_sharing))
if var is not None or pref == self.default_pref_value:
self.assertEqual(have_sharing, expect_sharing, msg)
elif have_sharing != expect_sharing:
print('TEST-EXPECTED-FAIL: ' + msg)

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

@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += [
'marionette',
'mochitest',
'chrome',
'browser',

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

@ -43,6 +43,15 @@ public:
, mPendingWrapperRestyles(aPendingWrapperRestyles)
, mPendingWrapperRestyleOffset(aPendingWrapperRestyles.Length())
, mChangesHandled(nsChangeHint(0))
#ifdef DEBUG
// If !mOwner, then we wouldn't have processed our wrapper restyles, because
// we only process those when handling an element with a frame. But that's
// OK, because if we started our traversal at an element with no frame
// (e.g. it's display:contents), that means the wrapper frames in our list
// actually inherit from one of its ancestors, not from it, and hence not
// restyling them is OK.
, mAssertWrapperRestyleLength(false)
#endif // DEBUG
{}
// We shouldn't assume that changes handled from our parent are handled for
@ -159,7 +168,7 @@ private:
// Whether we should assert in our destructor that we've processed all of the
// relevant wrapper restyles.
#ifdef DEBUG
const bool mAssertWrapperRestyleLength = true;
const bool mAssertWrapperRestyleLength;
#endif // DEBUG
};

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

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
window.onload = () => {
a = document.createElement("x")
document.documentElement.appendChild(a)
a.animate([{ "filter": "sepia(7)" }], 3000)
b = document.createElement("caption")
a.appendChild(b)
a.style = "display:contents"
//DDBEGIN
b.animate([{ "padding": "912q" }], 1500)
//DDEND
a.animate([{}])
}
</script>
</head>
</html>

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

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
window.onload = () => {
a = document.createElement("x")
document.documentElement.appendChild(a)
a.animate([{ "color": "green" }], 3000)
b = document.createElement("caption")
a.appendChild(b)
a.style = "display:contents"
//DDBEGIN
b.animate([{ "text-indent": "912q" }], 1500)
//DDEND
a.animate([{}])
}
</script>
</head>
</html>

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

@ -0,0 +1,8 @@
<!DOCTYPE html>
<span id="x" style="display: contents">
<span style="display: table-caption">
</span>
<script>
document.body.offsetWidth;
x.style.color = "green";
</script>

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

@ -497,3 +497,6 @@ asserts-if(!stylo,1) load 1388625-1.html # bug 1389286
load 1390389.html
load 1395591-1.html
load 1395715-1.html
load 1397398-1.html
load 1397398-2.html
load 1397398-3.html

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

@ -7743,10 +7743,39 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
// Deal with possible :after generated content on the parent
nsIFrame* parentAfterFrame;
nsContainerFrame* preAdjustedParentFrame = parentFrame;
parentFrame =
::AdjustAppendParentForAfterContent(this, insertion.mContainer, parentFrame,
aFirstNewContent, &parentAfterFrame);
// See if the containing block has :first-letter style applied.
bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
nsContainerFrame* containingBlock = GetFloatContainingBlock(parentFrame);
if (containingBlock) {
haveFirstLetterStyle = HasFirstLetterStyle(containingBlock);
haveFirstLineStyle =
ShouldHaveFirstLineStyle(containingBlock->GetContent(),
containingBlock->StyleContext());
}
if (haveFirstLetterStyle) {
AutoWeakFrame wf(parentAfterFrame);
// Before we get going, remove the current letter frames
RemoveLetterFrames(mPresShell, containingBlock);
if (parentAfterFrame && !wf) {
// Ouch, parentAfterFrame was a letter frame and we just deleted it!
// Retry AdjustAppendParentForAfterContent; fortunately this is rare.
parentFrame =
::AdjustAppendParentForAfterContent(this, insertion.mContainer,
preAdjustedParentFrame,
aFirstNewContent, &parentAfterFrame);
if (parentFrame != preAdjustedParentFrame) {
containingBlock = GetFloatContainingBlock(parentFrame);
}
}
}
// Create some new frames
//
// We use the provided tree match context, or create a new one on the fly
@ -7760,22 +7789,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
matchContext.ptrOr(aProvidedTreeMatchContext),
GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
GetAbsoluteContainingBlock(parentFrame, ABS_POS),
GetFloatContainingBlock(parentFrame));
// See if the containing block has :first-letter style applied.
bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
nsContainerFrame* containingBlock = state.mFloatedItems.containingBlock;
if (containingBlock) {
haveFirstLetterStyle = HasFirstLetterStyle(containingBlock);
haveFirstLineStyle =
ShouldHaveFirstLineStyle(containingBlock->GetContent(),
containingBlock->StyleContext());
}
if (haveFirstLetterStyle) {
// Before we get going, remove the current letter frames
RemoveLetterFrames(state.mPresShell, containingBlock);
}
containingBlock);
LayoutFrameType frameType = parentFrame->Type();

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

@ -146,6 +146,12 @@ FRAME_ID(nsXULLabelFrame, XULLabel, NotLeaf)
FRAME_ID(nsXULScrollFrame, Scroll, NotLeaf)
FRAME_ID(ViewportFrame, Viewport, NotLeaf)
// The following ABSTRACT_FRAME_IDs needs to come after the above
// FRAME_IDs, because we have two separate enums, one that includes
// only FRAME_IDs and another which includes both and we depend on
// FRAME_IDs to have the same number in both.
// See ClassID (the former) and FrameIID in nsQueryFrame.h.
// Non-concrete classes (for FrameIID use)
ABSTRACT_FRAME_ID(nsContainerFrame)
ABSTRACT_FRAME_ID(nsFormControlFrame)

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

@ -713,6 +713,7 @@ protected:
friend class nsLineBox; // needed to pass aDestructRoot through to children
friend class nsContainerFrame; // needed to pass aDestructRoot through to children
friend class nsFrame; // need to assign mParent
template<class Source> friend class do_QueryFrameHelper; // to read mClass
public:
/**
@ -4486,6 +4487,13 @@ private:
nsIFrame* mFrame;
};
// Use nsIFrame's fast-path to avoid QueryFrame:
inline do_QueryFrameHelper<nsIFrame>
do_QueryFrame(AutoWeakFrame& s)
{
return do_QueryFrameHelper<nsIFrame>(s.GetFrame());
}
/**
* @see AutoWeakFrame
*/
@ -4543,6 +4551,13 @@ private:
nsIFrame* mFrame;
};
// Use nsIFrame's fast-path to avoid QueryFrame:
inline do_QueryFrameHelper<nsIFrame>
do_QueryFrame(WeakFrame& s)
{
return do_QueryFrameHelper<nsIFrame>(s.GetFrame());
}
inline bool
nsFrameList::ContinueRemoveFrame(nsIFrame* aFrame)
{

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

@ -82,29 +82,66 @@ public:
virtual void* QueryFrame(FrameIID id) = 0;
};
class do_QueryFrame
class nsIFrame;
template<class Source>
class do_QueryFrameHelper
{
public:
explicit do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { }
explicit do_QueryFrameHelper(Source* s) : mRawPtr(s) { }
// The return and argument types here are arbitrarily selected so no
// corresponding member function exists.
typedef void (do_QueryFrame::* MatchNullptr)(double, float);
typedef void (do_QueryFrameHelper::* MatchNullptr)(double, float);
// Implicit constructor for nullptr, trick borrowed from already_AddRefed.
MOZ_IMPLICIT do_QueryFrame(MatchNullptr aRawPtr) : mRawPtr(nullptr) {}
MOZ_IMPLICIT do_QueryFrameHelper(MatchNullptr aRawPtr) : mRawPtr(nullptr) {}
template<class Dest>
operator Dest*() {
static_assert(mozilla::IsSame<Dest, typename Dest::Has_NS_DECL_QUERYFRAME_TARGET>::value,
"Dest must declare itself as a queryframe target");
if (!mRawPtr)
if (!mRawPtr) {
return nullptr;
}
if (Dest* f = FastQueryFrame<Source, Dest>::QueryFrame(mRawPtr)) {
MOZ_ASSERT(f ==
reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID)),
"fast and slow paths should give the same result");
return f;
}
return reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID));
}
private:
nsQueryFrame *mRawPtr;
// For non-nsIFrame types there is no fast-path.
template<class Src, class Dst, typename = void, typename = void>
struct FastQueryFrame
{
static Dst* QueryFrame(Src* aFrame) { return nullptr; }
};
// Specialization for any nsIFrame type to any nsIFrame type -- if the source
// instance's mClass matches kFrameIID of the destination type then
// downcasting is safe.
template<class Src, class Dst>
struct FastQueryFrame<Src, Dst,
typename mozilla::EnableIf<mozilla::IsBaseOf<nsIFrame, Src>::value>::Type,
typename mozilla::EnableIf<mozilla::IsBaseOf<nsIFrame, Dst>::value>::Type>
{
static Dst* QueryFrame(Src* aFrame) {
return nsQueryFrame::FrameIID(aFrame->mClass) == Dst::kFrameIID ?
reinterpret_cast<Dst*>(aFrame) : nullptr;
}
};
Source* mRawPtr;
};
template<class T>
inline do_QueryFrameHelper<T>
do_QueryFrame(T* s)
{
return do_QueryFrameHelper<T>(s);
}
#endif // nsQueryFrame_h

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

@ -1233,7 +1233,7 @@ fuzzy-if(skiaContent,1,12000) fails-if(webrender) == 461512-1.html 461512-1-ref.
== 462844-3.html 462844-ref.html
== 462844-4.html 462844-ref.html
== 463204-1.html 463204-1-ref.html
fuzzy-if(webrender,16,3425) == 463217-1.xul 463217-1-ref.xul
fuzzy-if(webrender,16-16,3425-3425) == 463217-1.xul 463217-1-ref.xul
== 463952-1.html 463952-1-ref.html
== 464811-1.html 464811-1-ref.html
== 465574-1.html 465574-1-ref.html # bug 421436

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

@ -111,6 +111,16 @@ public:
// clearly identify in DMD's output the memory measured here.
*aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
mSource.AddSizeOfExcludingThis(aSizes);
if (mNextInheritingAnonBoxStyle &&
!aSizes.mState.HaveSeenPtr(mNextInheritingAnonBoxStyle)) {
mNextInheritingAnonBoxStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
}
if (mNextLazyPseudoStyle &&
!aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
mNextLazyPseudoStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
}
}
private:

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

@ -94,6 +94,8 @@ if CONFIG['MOZ_XUL']:
if CONFIG['MOZ_XUL']:
DIRS += ['tree', 'grid']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'../base',

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

@ -52,6 +52,12 @@
#include "mozilla/Maybe.h"
#include "SVGImageContext.h"
#include "Units.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#if defined(XP_WIN)
// Undefine LoadImage to prevent naming conflict with Windows.
#undef LoadImage
#endif
#define ONLOAD_CALLED_TOO_EARLY 1
@ -341,32 +347,53 @@ nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aLists.Content()->AppendToTop(&list);
}
DrawResult
nsImageBoxFrame::PaintImage(gfxContext& aRenderingContext,
const nsRect& aDirtyRect, nsPoint aPt,
uint32_t aFlags)
already_AddRefed<imgIContainer>
nsImageBoxFrame::GetImageContainerForPainting(const nsPoint& aPt,
DrawResult& aDrawResult,
Maybe<nsPoint>& aAnchorPoint,
nsRect& aDest)
{
if (!mImageRequest) {
// This probably means we're drawn by a native theme.
return DrawResult::SUCCESS;
aDrawResult = DrawResult::SUCCESS;
return nullptr;
}
// Don't draw if the image's size isn't available.
uint32_t imgStatus;
if (!NS_SUCCEEDED(mImageRequest->GetImageStatus(&imgStatus)) ||
!(imgStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
return DrawResult::NOT_READY;
aDrawResult = DrawResult::NOT_READY;
return nullptr;
}
nsCOMPtr<imgIContainer> imgCon;
mImageRequest->GetImage(getter_AddRefs(imgCon));
if (!imgCon) {
return DrawResult::NOT_READY;
aDrawResult = DrawResult::NOT_READY;
return nullptr;
}
aDest = GetDestRect(aPt, aAnchorPoint);
aDrawResult = DrawResult::SUCCESS;
return imgCon.forget();
}
DrawResult
nsImageBoxFrame::PaintImage(gfxContext& aRenderingContext,
const nsRect& aDirtyRect, nsPoint aPt,
uint32_t aFlags)
{
DrawResult result;
Maybe<nsPoint> anchorPoint;
nsRect dest = GetDestRect(aPt, anchorPoint);
nsRect dest;
nsCOMPtr<imgIContainer> imgCon = GetImageContainerForPainting(aPt, result,
anchorPoint,
dest);
if (!imgCon) {
return result;
}
// don't draw if the image is not dirty
// XXX(seth): Can this actually happen anymore?
@ -389,6 +416,54 @@ nsImageBoxFrame::PaintImage(gfxContext& aRenderingContext,
hasSubRect ? &mSubRect : nullptr);
}
DrawResult
nsImageBoxFrame::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayItem* aItem,
nsPoint aPt,
uint32_t aFlags)
{
DrawResult result;
Maybe<nsPoint> anchorPoint;
nsRect dest;
nsCOMPtr<imgIContainer> imgCon = GetImageContainerForPainting(aPt, result,
anchorPoint,
dest);
if (!imgCon) {
return result;
}
uint32_t containerFlags = imgIContainer::FLAG_NONE;
if (aFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
}
RefPtr<layers::ImageContainer> container =
imgCon->GetImageContainer(aManager, containerFlags);
if (!container) {
NS_WARNING("Failed to get image container");
return DrawResult::NOT_READY;
}
gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aSc, size);
if (key.isNothing()) {
return DrawResult::BAD_IMAGE;
}
const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(dest,
appUnitsPerDevPixel);
wr::LayoutRect fill = aSc.ToRelativeLayoutRect(fillRect);
LayoutDeviceSize gapSize(0, 0);
SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
aBuilder.PushImage(fill, fill,
wr::ToLayoutSize(fillRect.Size()), wr::ToLayoutSize(gapSize),
wr::ToImageRendering(sampleFilter), key.value());
return DrawResult::SUCCESS;
}
nsRect
nsImageBoxFrame::GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint)
{
@ -453,6 +528,55 @@ void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder,
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
LayerState
nsDisplayXULImage::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowImageLayers) &&
CanOptimizeToImageLayer(aManager, aBuilder)) {
return LAYER_ACTIVE;
}
return LAYER_NONE;
}
already_AddRefed<Layer>
nsDisplayXULImage::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
bool
nsDisplayXULImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
if (aManager->IsLayersFreeTransaction()) {
ContainerLayerParameters parameter;
if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
return false;
}
}
uint32_t flags = imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
if (aDisplayListBuilder->ShouldSyncDecodeImages()) {
flags |= imgIContainer::FLAG_SYNC_DECODE;
}
if (aDisplayListBuilder->IsPaintingToWindow()) {
flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
}
DrawResult result = static_cast<nsImageBoxFrame*>(mFrame)->
CreateWebRenderCommands(aBuilder, aSc, aManager, this, ToReferenceFrame(), flags);
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
return true;
}
nsDisplayItemGeometry*
nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{

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

@ -90,10 +90,22 @@ public:
virtual ~nsImageBoxFrame();
already_AddRefed<imgIContainer> GetImageContainerForPainting(const nsPoint& aPt,
DrawResult& aDrawResult,
Maybe<nsPoint>& aAnchorPoint,
nsRect& aDest);
DrawResult PaintImage(gfxContext& aRenderingContext,
const nsRect& aDirtyRect,
nsPoint aPt, uint32_t aFlags);
DrawResult CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayItem* aItem,
nsPoint aPt,
uint32_t aFlags);
bool CanOptimizeToImageLayer();
nsRect GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint);
@ -158,6 +170,21 @@ public:
// event receiver for us
virtual void Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE)
};

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

@ -1,6 +1,6 @@
fails-if(Android) == textbox-multiline-noresize.xul textbox-multiline-ref.xul # reference is blank on Android (due to no native theme support?)
!= textbox-multiline-resize.xul textbox-multiline-ref.xul
== popup-explicit-size.xul popup-explicit-size-ref.xul
random-if(Android) fuzzy-if(webrender,21-21,10746-10746) == image-size.xul image-size-ref.xul
random-if(Android) == image-size.xul image-size-ref.xul
== image-scaling-min-height-1.xul image-scaling-min-height-1-ref.xul
== textbox-text-transform.xul textbox-text-transform-ref.xul

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

@ -1140,4 +1140,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1513358056232000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1513444695639000);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -169,12 +169,15 @@ linux64-jsdcov/opt:
windows7-32/debug:
build-platform: win32/debug
test-sets:
- windows-reftest-gpu
- windows-tests
windows7-32/opt:
build-platform: win32/opt
test-sets:
- awsy
- desktop-screenshot-capture
- windows-reftest-gpu
- windows-talos
- windows-talos-stylo-disabled
- windows-tests
@ -184,21 +187,24 @@ windows7-32-pgo/opt:
test-sets:
- awsy
- desktop-screenshot-capture
- windows-tests
- windows-reftest-gpu
- windows-talos
- windows-talos-stylo-disabled
- windows-tests
windows7-32-nightly/opt:
build-platform: win32-nightly/opt
test-sets:
- awsy
- desktop-screenshot-capture
- windows-reftest-gpu
- windows-tests
windows7-32-devedition/opt:
build-platform: win32-devedition-nightly/opt
test-sets:
- desktop-screenshot-capture
- windows-reftest-gpu
- windows-tests
# win64

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

@ -146,6 +146,9 @@ linux-talos-stylo-disabled:
- talos-perf-reftest-stylo-disabled
- talos-perf-reftest-singletons-stylo-disabled
windows-reftest-gpu:
- reftest-gpu
windows-tests:
- cppunit
- crashtest
@ -167,7 +170,6 @@ windows-tests:
- mochitest-media
- mochitest-webgl
- reftest
- reftest-gpu
- reftest-no-accel
- web-platform-tests
- web-platform-tests-reftests

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

@ -10,3 +10,6 @@ skip-if = asan # Bug 1223277, 1348961
# migration tests
[include:../../../../../browser/components/migration/tests/marionette/manifest.ini]
# xpconnect tests
[include:../../../../../js/xpconnect/tests/marionette/manifest.ini]