From 8acccdc0b8c7dfbecc3c058f1cd0b0e26b1b8d85 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Mon, 20 Aug 2018 17:11:32 -0500 Subject: [PATCH 01/49] Bug 1484420 - Move locale-related functions into js/public/LocaleSensitive.h that isn't #include'd in jsapi.h. r=anba --HG-- extra : rebase_source : 0c594e4a64373f0432194898ab18f94722c3c54a --- dom/workers/RuntimeService.cpp | 1 + dom/workers/WorkerPrivate.cpp | 1 + js/public/LocaleSensitive.h | 99 +++++++++++++++++++ js/src/builtin/TestingFunctions.cpp | 1 + js/src/jsapi-tests/testDateToLocaleString.cpp | 1 + .../jsapi-tests/testIntlAvailableLocales.cpp | 1 + js/src/jsapi.cpp | 1 + js/src/jsapi.h | 62 ------------ js/src/jspubtd.h | 1 - js/src/moz.build | 1 + js/src/vm/Runtime.h | 1 + js/xpconnect/src/XPCLocale.cpp | 4 +- 12 files changed, 108 insertions(+), 66 deletions(-) create mode 100644 js/public/LocaleSensitive.h diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index aa5359a9f2c4..ddd7bec79040 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -29,6 +29,7 @@ #include "mozilla/ipc/BackgroundChild.h" #include "GeckoProfiler.h" #include "jsfriendapi.h" +#include "js/LocaleSensitive.h" #include "mozilla/AbstractThread.h" #include "mozilla/ArrayUtils.h" #include "mozilla/AsyncEventDispatcher.h" diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index fc91ba93a2b2..1eafa00f1d0d 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -6,6 +6,7 @@ #include "WorkerPrivate.h" +#include "js/LocaleSensitive.h" #include "js/MemoryMetrics.h" #include "MessageEventRunnable.h" #include "mozilla/ScopeExit.h" diff --git a/js/public/LocaleSensitive.h b/js/public/LocaleSensitive.h new file mode 100644 index 000000000000..d1163c5d559b --- /dev/null +++ b/js/public/LocaleSensitive.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + * Functions and structures related to locale-sensitive behavior, including + * exposure of the default locale (used by operations like toLocaleString). + */ + +#ifndef js_LocaleSensitive_h +#define js_LocaleSensitive_h + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle +#include "js/Utility.h" // JS::UniqueChars + +struct JSContext; +struct JSRuntime; +class JSString; + +namespace JS { union Value; } + +/** + * Set the default locale for the ECMAScript Internationalization API + * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat, and others that will + * arise as time passes). (Note that the Internationalization API encourages + * clients to specify their own locales; this default locale is only used when + * no locale is specified, e.g. calling a toLocaleString function without + * passing a locale argument to it.) + * + * The locale string remains owned by the caller. + */ +extern JS_PUBLIC_API(bool) +JS_SetDefaultLocale(JSRuntime* rt, const char* locale); + +/** + * Return a copy of the default locale for the ECMAScript Internationalization + * API (and for various ECMAScript functions that will invoke it). The locale + * is retrieved from the |JSRuntime| that corresponds to |cx|. + * + * XXX Bug 1483961 means it's difficult to interpret the meaning of a null + * return value for the time being, and we should fix this! + */ +extern JS_PUBLIC_API(JS::UniqueChars) +JS_GetDefaultLocale(JSContext* cx); + +/** Reset the default locale to OS defaults. */ +extern JS_PUBLIC_API(void) +JS_ResetDefaultLocale(JSRuntime* rt); + +using JSLocaleToUpperCase = + bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); + +using JSLocaleToLowerCase = + bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); + +using JSLocaleCompare = + bool (*)(JSContext* cx, JS::Handle src1, JS::Handle src2, + JS::MutableHandle rval); + +using JSLocaleToUnicode = + bool (*)(JSContext* cx, const char* src, JS::MutableHandle rval); + +/** + * A suite of locale-specific string conversion and error message callbacks + * used to implement locale-sensitive behaviors (such as those performed by + * the various toLocaleString and toLocale{Date,Time}String functions). + * + * If SpiderMonkey is compiled --with-intl-api, then #if EXPOSE_INTL_API. In + * this case, SpiderMonkey itself will implement ECMA-402-compliant behavior by + * calling on ICU, and none of the fields in this struct will ever be used. + * (You'll still be able to call the get/set-callbacks functions; they just + * won't affect JavaScript semantics.) + */ +struct JSLocaleCallbacks +{ + JSLocaleToUpperCase localeToUpperCase; + JSLocaleToLowerCase localeToLowerCase; + JSLocaleCompare localeCompare; + JSLocaleToUnicode localeToUnicode; +}; + +/** + * Set locale callbacks to be used in builds not compiled --with-intl-api. + * |callbacks| must persist as long as the |JSRuntime|. Pass |nullptr| to + * restore default behavior. + */ +extern JS_PUBLIC_API(void) +JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); + +/** + * Return the current locale callbacks, which may be nullptr. + */ +extern JS_PUBLIC_API(const JSLocaleCallbacks*) +JS_GetLocaleCallbacks(JSRuntime* rt); + +#endif /* js_LocaleSensitive_h */ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 570aaf323adb..f9ba87cffbd4 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -44,6 +44,7 @@ #include "js/AutoByteString.h" #include "js/Debug.h" #include "js/HashTable.h" +#include "js/LocaleSensitive.h" #include "js/StableStringChars.h" #include "js/StructuredClone.h" #include "js/UbiNode.h" diff --git a/js/src/jsapi-tests/testDateToLocaleString.cpp b/js/src/jsapi-tests/testDateToLocaleString.cpp index a011ca184c40..e8256b9f87e3 100644 --- a/js/src/jsapi-tests/testDateToLocaleString.cpp +++ b/js/src/jsapi-tests/testDateToLocaleString.cpp @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testDateToLocaleString) diff --git a/js/src/jsapi-tests/testIntlAvailableLocales.cpp b/js/src/jsapi-tests/testIntlAvailableLocales.cpp index dca84fde6b3e..c2393cb77be5 100644 --- a/js/src/jsapi-tests/testIntlAvailableLocales.cpp +++ b/js/src/jsapi-tests/testIntlAvailableLocales.cpp @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testIntlAvailableLocales) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 420dfd3a0ada..d0cdfa994ca7 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -61,6 +61,7 @@ #include "js/Date.h" #include "js/Initialization.h" #include "js/JSON.h" +#include "js/LocaleSensitive.h" #include "js/Proxy.h" #include "js/SliceBudget.h" #include "js/StableStringChars.h" diff --git a/js/src/jsapi.h b/js/src/jsapi.h index a0f715ed3ec8..a70e5914b326 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -223,19 +223,6 @@ typedef void JS::PromiseRejectionHandlingState state, void* data); -typedef bool -(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, - JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); - /** * Callback used to ask the embedding for the cross compartment wrapper handler * that implements the desired prolicy for this kind of object in the @@ -4725,55 +4712,6 @@ PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); /************************************************************************/ -/** - * The default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). - * Note that the Internationalization API encourages clients to - * specify their own locales. - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSRuntime* rt, const char* locale); - -/** - * Look up the default locale for the ECMAScript Internationalization API. - * NB: The locale information is retrieved from cx's runtime. - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** - * Reset the default locale to OS defaults. - */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSRuntime* rt); - -/** - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; // not used #if EXPOSE_INTL_API - JSLocaleToLowerCase localeToLowerCase; // not used #if EXPOSE_INTL_API - JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing nullptr restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); - -/** - * Return the address of the current locale callbacks struct, which may - * be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSRuntime* rt); - -/************************************************************************/ - /* * Error reporting. * diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index b5602ed8cdd7..1ee6915b07d5 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -68,7 +68,6 @@ struct JSClass; class JSErrorReport; struct JSExceptionState; struct JSFunctionSpec; -struct JSLocaleCallbacks; struct JSPrincipals; struct JSPropertySpec; struct JSSecurityCallbacks; diff --git a/js/src/moz.build b/js/src/moz.build index e6606cb490b6..106be1ef1e73 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -144,6 +144,7 @@ EXPORTS.js += [ '../public/Id.h', '../public/Initialization.h', '../public/JSON.h', + '../public/LocaleSensitive.h', '../public/MemoryFunctions.h', '../public/MemoryMetrics.h', '../public/Principals.h', diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index bde5130c444d..a52d8fdee8e2 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -69,6 +69,7 @@ class AutoHeapSession; } // namespace js struct DtoaState; +struct JSLocaleCallbacks; #ifdef JS_SIMULATOR_ARM64 namespace vixl { diff --git a/js/xpconnect/src/XPCLocale.cpp b/js/xpconnect/src/XPCLocale.cpp index 39bd44e05a2f..8944f9d645dc 100644 --- a/js/xpconnect/src/XPCLocale.cpp +++ b/js/xpconnect/src/XPCLocale.cpp @@ -6,9 +6,8 @@ #include "mozilla/Assertions.h" -#include "jsapi.h" +#include "js/LocaleSensitive.h" -#include "nsJSUtils.h" #include "nsIObserver.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" @@ -18,7 +17,6 @@ #include "xpcpublic.h" -using namespace JS; using namespace mozilla; using mozilla::intl::LocaleService; From 79b4121889b04b7bfe4a9c762f7191e2116ebbcc Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Tue, 21 Aug 2018 15:09:11 -0500 Subject: [PATCH 02/49] Bug 1484420 - Add a missing #include needed only in builds that aren't --with-intl-api. r=bustage in a CLOSED TREE --- js/src/builtin/String.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index aba6a1acf07a..25cedcb4d85e 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -31,6 +31,9 @@ #include "builtin/RegExp.h" #include "jit/InlinableNatives.h" #include "js/Conversions.h" +#if !EXPOSE_INTL_API +#include "js/LocaleSensitive.h" +#endif #include "js/StableStringChars.h" #include "js/UniquePtr.h" #if ENABLE_INTL_API From d801b3a01e721f5ab9ca7b3454763c55852f1c7e Mon Sep 17 00:00:00 2001 From: Andreea Pavel Date: Tue, 21 Aug 2018 23:19:27 +0300 Subject: [PATCH 03/49] Backed out 2 changesets (bug 1484420) for hazard failures on a CLOSED TREE Backed out changeset d910e3c8372a (bug 1484420) Backed out changeset d79cdb73c55f (bug 1484420) --- dom/workers/RuntimeService.cpp | 1 - dom/workers/WorkerPrivate.cpp | 1 - js/public/LocaleSensitive.h | 99 ------------------- js/src/builtin/String.cpp | 3 - js/src/builtin/TestingFunctions.cpp | 1 - js/src/jsapi-tests/testDateToLocaleString.cpp | 1 - .../jsapi-tests/testIntlAvailableLocales.cpp | 1 - js/src/jsapi.cpp | 1 - js/src/jsapi.h | 62 ++++++++++++ js/src/jspubtd.h | 1 + js/src/moz.build | 1 - js/src/vm/Runtime.h | 1 - js/xpconnect/src/XPCLocale.cpp | 4 +- 13 files changed, 66 insertions(+), 111 deletions(-) delete mode 100644 js/public/LocaleSensitive.h diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index ddd7bec79040..aa5359a9f2c4 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -29,7 +29,6 @@ #include "mozilla/ipc/BackgroundChild.h" #include "GeckoProfiler.h" #include "jsfriendapi.h" -#include "js/LocaleSensitive.h" #include "mozilla/AbstractThread.h" #include "mozilla/ArrayUtils.h" #include "mozilla/AsyncEventDispatcher.h" diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 1eafa00f1d0d..fc91ba93a2b2 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -6,7 +6,6 @@ #include "WorkerPrivate.h" -#include "js/LocaleSensitive.h" #include "js/MemoryMetrics.h" #include "MessageEventRunnable.h" #include "mozilla/ScopeExit.h" diff --git a/js/public/LocaleSensitive.h b/js/public/LocaleSensitive.h deleted file mode 100644 index d1163c5d559b..000000000000 --- a/js/public/LocaleSensitive.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* - * Functions and structures related to locale-sensitive behavior, including - * exposure of the default locale (used by operations like toLocaleString). - */ - -#ifndef js_LocaleSensitive_h -#define js_LocaleSensitive_h - -#include "jstypes.h" // JS_PUBLIC_API - -#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle -#include "js/Utility.h" // JS::UniqueChars - -struct JSContext; -struct JSRuntime; -class JSString; - -namespace JS { union Value; } - -/** - * Set the default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat, and others that will - * arise as time passes). (Note that the Internationalization API encourages - * clients to specify their own locales; this default locale is only used when - * no locale is specified, e.g. calling a toLocaleString function without - * passing a locale argument to it.) - * - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSRuntime* rt, const char* locale); - -/** - * Return a copy of the default locale for the ECMAScript Internationalization - * API (and for various ECMAScript functions that will invoke it). The locale - * is retrieved from the |JSRuntime| that corresponds to |cx|. - * - * XXX Bug 1483961 means it's difficult to interpret the meaning of a null - * return value for the time being, and we should fix this! - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** Reset the default locale to OS defaults. */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSRuntime* rt); - -using JSLocaleToUpperCase = - bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); - -using JSLocaleToLowerCase = - bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); - -using JSLocaleCompare = - bool (*)(JSContext* cx, JS::Handle src1, JS::Handle src2, - JS::MutableHandle rval); - -using JSLocaleToUnicode = - bool (*)(JSContext* cx, const char* src, JS::MutableHandle rval); - -/** - * A suite of locale-specific string conversion and error message callbacks - * used to implement locale-sensitive behaviors (such as those performed by - * the various toLocaleString and toLocale{Date,Time}String functions). - * - * If SpiderMonkey is compiled --with-intl-api, then #if EXPOSE_INTL_API. In - * this case, SpiderMonkey itself will implement ECMA-402-compliant behavior by - * calling on ICU, and none of the fields in this struct will ever be used. - * (You'll still be able to call the get/set-callbacks functions; they just - * won't affect JavaScript semantics.) - */ -struct JSLocaleCallbacks -{ - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Set locale callbacks to be used in builds not compiled --with-intl-api. - * |callbacks| must persist as long as the |JSRuntime|. Pass |nullptr| to - * restore default behavior. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); - -/** - * Return the current locale callbacks, which may be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSRuntime* rt); - -#endif /* js_LocaleSensitive_h */ diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index 25cedcb4d85e..aba6a1acf07a 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -31,9 +31,6 @@ #include "builtin/RegExp.h" #include "jit/InlinableNatives.h" #include "js/Conversions.h" -#if !EXPOSE_INTL_API -#include "js/LocaleSensitive.h" -#endif #include "js/StableStringChars.h" #include "js/UniquePtr.h" #if ENABLE_INTL_API diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index f9ba87cffbd4..570aaf323adb 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -44,7 +44,6 @@ #include "js/AutoByteString.h" #include "js/Debug.h" #include "js/HashTable.h" -#include "js/LocaleSensitive.h" #include "js/StableStringChars.h" #include "js/StructuredClone.h" #include "js/UbiNode.h" diff --git a/js/src/jsapi-tests/testDateToLocaleString.cpp b/js/src/jsapi-tests/testDateToLocaleString.cpp index e8256b9f87e3..a011ca184c40 100644 --- a/js/src/jsapi-tests/testDateToLocaleString.cpp +++ b/js/src/jsapi-tests/testDateToLocaleString.cpp @@ -5,7 +5,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/. */ -#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testDateToLocaleString) diff --git a/js/src/jsapi-tests/testIntlAvailableLocales.cpp b/js/src/jsapi-tests/testIntlAvailableLocales.cpp index c2393cb77be5..dca84fde6b3e 100644 --- a/js/src/jsapi-tests/testIntlAvailableLocales.cpp +++ b/js/src/jsapi-tests/testIntlAvailableLocales.cpp @@ -5,7 +5,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/. */ -#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testIntlAvailableLocales) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d0cdfa994ca7..420dfd3a0ada 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -61,7 +61,6 @@ #include "js/Date.h" #include "js/Initialization.h" #include "js/JSON.h" -#include "js/LocaleSensitive.h" #include "js/Proxy.h" #include "js/SliceBudget.h" #include "js/StableStringChars.h" diff --git a/js/src/jsapi.h b/js/src/jsapi.h index a70e5914b326..a0f715ed3ec8 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -223,6 +223,19 @@ typedef void JS::PromiseRejectionHandlingState state, void* data); +typedef bool +(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); + +typedef bool +(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); + +typedef bool +(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, + JS::MutableHandleValue rval); + +typedef bool +(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); + /** * Callback used to ask the embedding for the cross compartment wrapper handler * that implements the desired prolicy for this kind of object in the @@ -4712,6 +4725,55 @@ PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); /************************************************************************/ +/** + * The default locale for the ECMAScript Internationalization API + * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). + * Note that the Internationalization API encourages clients to + * specify their own locales. + * The locale string remains owned by the caller. + */ +extern JS_PUBLIC_API(bool) +JS_SetDefaultLocale(JSRuntime* rt, const char* locale); + +/** + * Look up the default locale for the ECMAScript Internationalization API. + * NB: The locale information is retrieved from cx's runtime. + */ +extern JS_PUBLIC_API(JS::UniqueChars) +JS_GetDefaultLocale(JSContext* cx); + +/** + * Reset the default locale to OS defaults. + */ +extern JS_PUBLIC_API(void) +JS_ResetDefaultLocale(JSRuntime* rt); + +/** + * Locale specific string conversion and error message callbacks. + */ +struct JSLocaleCallbacks { + JSLocaleToUpperCase localeToUpperCase; // not used #if EXPOSE_INTL_API + JSLocaleToLowerCase localeToLowerCase; // not used #if EXPOSE_INTL_API + JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API + JSLocaleToUnicode localeToUnicode; +}; + +/** + * Establish locale callbacks. The pointer must persist as long as the + * JSContext. Passing nullptr restores the default behaviour. + */ +extern JS_PUBLIC_API(void) +JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); + +/** + * Return the address of the current locale callbacks struct, which may + * be nullptr. + */ +extern JS_PUBLIC_API(const JSLocaleCallbacks*) +JS_GetLocaleCallbacks(JSRuntime* rt); + +/************************************************************************/ + /* * Error reporting. * diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 1ee6915b07d5..b5602ed8cdd7 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -68,6 +68,7 @@ struct JSClass; class JSErrorReport; struct JSExceptionState; struct JSFunctionSpec; +struct JSLocaleCallbacks; struct JSPrincipals; struct JSPropertySpec; struct JSSecurityCallbacks; diff --git a/js/src/moz.build b/js/src/moz.build index 106be1ef1e73..e6606cb490b6 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -144,7 +144,6 @@ EXPORTS.js += [ '../public/Id.h', '../public/Initialization.h', '../public/JSON.h', - '../public/LocaleSensitive.h', '../public/MemoryFunctions.h', '../public/MemoryMetrics.h', '../public/Principals.h', diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index a52d8fdee8e2..bde5130c444d 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -69,7 +69,6 @@ class AutoHeapSession; } // namespace js struct DtoaState; -struct JSLocaleCallbacks; #ifdef JS_SIMULATOR_ARM64 namespace vixl { diff --git a/js/xpconnect/src/XPCLocale.cpp b/js/xpconnect/src/XPCLocale.cpp index 8944f9d645dc..39bd44e05a2f 100644 --- a/js/xpconnect/src/XPCLocale.cpp +++ b/js/xpconnect/src/XPCLocale.cpp @@ -6,8 +6,9 @@ #include "mozilla/Assertions.h" -#include "js/LocaleSensitive.h" +#include "jsapi.h" +#include "nsJSUtils.h" #include "nsIObserver.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" @@ -17,6 +18,7 @@ #include "xpcpublic.h" +using namespace JS; using namespace mozilla; using mozilla::intl::LocaleService; From a07f6c3866d9f6325f8cb67ef1f4a27b9a4c6a4f Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 20 Aug 2018 09:47:00 -0400 Subject: [PATCH 04/49] Bug 1484848 - Remove the XPCOM component registrations for window and child window; r=mstange --- dom/plugins/base/nsPluginInstanceOwner.cpp | 3 +- dom/plugins/ipc/PluginWidgetParent.cpp | 6 ++-- toolkit/components/browser/nsWebBrowser.cpp | 6 ++-- widget/android/nsWidgetFactory.cpp | 7 ----- widget/android/nsWindow.cpp | 14 +++++++++ widget/cocoa/nsCocoaWindow.mm | 15 ++++++++++ widget/cocoa/nsWidgetFactory.mm | 7 ----- widget/gtk/nsWidgetFactory.cpp | 7 ----- widget/gtk/nsWindow.cpp | 13 +++++++++ widget/nsBaseWidget.cpp | 3 +- widget/nsBaseWidget.h | 4 +-- widget/nsIWidget.h | 6 ++++ widget/nsWidgetsCID.h | 10 ------- widget/uikit/nsWidgetFactory.mm | 8 ------ widget/uikit/nsWindow.mm | 14 +++++++++ widget/windows/nsWidgetFactory.cpp | 32 +-------------------- widget/windows/nsWindow.cpp | 15 ++++++++++ widget/windows/nsWindow.h | 2 +- xpfe/appshell/nsWebShellWindow.cpp | 14 +++------ 19 files changed, 90 insertions(+), 96 deletions(-) diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 37e8d38cc8a7..02520faf78ff 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -66,7 +66,6 @@ using mozilla::DefaultXDisplay; #include "nsContentCID.h" #include "nsWidgetsCID.h" -static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID); static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); #ifdef XP_WIN @@ -2983,7 +2982,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void) if (!mWidget) { // native (single process) - mWidget = do_CreateInstance(kWidgetCID, &rv); + mWidget = nsIWidget::CreateChildWindow(); nsWidgetInitData initData; initData.mWindowType = eWindowType_plugin; initData.mUnicode = false; diff --git a/dom/plugins/ipc/PluginWidgetParent.cpp b/dom/plugins/ipc/PluginWidgetParent.cpp index 5c145073f4ff..fd6b9a40d5b8 100644 --- a/dom/plugins/ipc/PluginWidgetParent.cpp +++ b/dom/plugins/ipc/PluginWidgetParent.cpp @@ -28,8 +28,6 @@ const wchar_t* kPluginWidgetContentParentProperty = namespace mozilla { namespace plugins { -static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID); - // This macro returns IPC_OK() to prevent an abort in the child process when // ipc message delivery fails. #define ENSURE_CHANNEL { \ @@ -86,8 +84,8 @@ PluginWidgetParent::RecvCreate(nsresult* aResult, uint64_t* aScrollCaptureId, *aScrollCaptureId = 0; *aPluginInstanceId = 0; - mWidget = do_CreateInstance(kWidgetCID, aResult); - NS_ASSERTION(NS_SUCCEEDED(*aResult), "widget create failure"); + mWidget = nsIWidget::CreateChildWindow(); + *aResult = mWidget ? NS_OK : NS_ERROR_FAILURE; // This returns the top level window widget nsCOMPtr parentWidget = GetTabParent()->GetWidget(); diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp index c95eb19302b1..ecdb0c607480 100644 --- a/toolkit/components/browser/nsWebBrowser.cpp +++ b/toolkit/components/browser/nsWebBrowser.cpp @@ -55,8 +55,6 @@ using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::layers; -static NS_DEFINE_CID(kChildCID, NS_CHILD_CID); - nsWebBrowser::nsWebBrowser() : mInitInfo(new nsWebBrowserInitInfo()) , mContentType(typeContentWrapper) @@ -1106,8 +1104,8 @@ nsWebBrowser::Create() nsCOMPtr docShellParentWidget(mParentWidget); if (!mParentWidget) { // Create the widget - mInternalWidget = do_CreateInstance(kChildCID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + mInternalWidget = nsIWidget::CreateChildWindow(); + NS_ENSURE_TRUE(mInternalWidget, NS_ERROR_FAILURE); docShellParentWidget = mInternalWidget; nsWidgetInitData widgetInit; diff --git a/widget/android/nsWidgetFactory.cpp b/widget/android/nsWidgetFactory.cpp index 2aa196bc143f..ec0284ca4f9a 100644 --- a/widget/android/nsWidgetFactory.cpp +++ b/widget/android/nsWidgetFactory.cpp @@ -35,7 +35,6 @@ using namespace mozilla; using namespace mozilla::widget; -NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceAndroid, nsIdleServiceAndroid::GetInstance) NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) @@ -78,8 +77,6 @@ nsNativeThemeAndroidConstructor(nsISupports *aOuter, REFNSIID aIID, } NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); -NS_DEFINE_NAMED_CID(NS_WINDOW_CID); -NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); NS_DEFINE_NAMED_CID(NS_THEMERENDERER_CID); NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID); @@ -96,8 +93,6 @@ NS_DEFINE_NAMED_CID(NS_ANDROIDPROTOCOLHANDLER_CID); NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { - { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor }, - { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor }, { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor }, { &kNS_SCREENMANAGER_CID, false, nullptr, ScreenManagerConstructor, mozilla::Module::MAIN_PROCESS_ONLY }, @@ -118,8 +113,6 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { }; static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { - { "@mozilla.org/widgets/window/android;1", &kNS_WINDOW_CID }, - { "@mozilla.org/widgets/child_window/android;1", &kNS_CHILD_CID }, { "@mozilla.org/widget/appshell/android;1", &kNS_APPSHELL_CID }, { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID, mozilla::Module::MAIN_PROCESS_ONLY }, diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 7f7616547e0d..e750e48f4e87 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -2323,3 +2323,17 @@ nsWindow::RecvScreenPixels(Shmem&& aMem, const ScreenIntSize& aSize) } } +already_AddRefed +nsIWidget::CreateTopLevelWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} + +already_AddRefed +nsIWidget::CreateChildWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} + diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 8bf78a6a177e..6e996d6d3690 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -2501,6 +2501,21 @@ nsCocoaWindow::GetEditCommands(NativeKeyBindingsType aType, keyBindings->GetEditCommands(aEvent, aCommands); } +already_AddRefed +nsIWidget::CreateTopLevelWindow() +{ + nsCOMPtr window = new nsCocoaWindow(); + return window.forget(); +} + +already_AddRefed +nsIWidget::CreateChildWindow() +{ + nsCOMPtr window = new nsChildView(); + return window.forget(); +} + + @implementation WindowDelegate // We try to find a gecko menu bar to paint. If one does not exist, just paint diff --git a/widget/cocoa/nsWidgetFactory.mm b/widget/cocoa/nsWidgetFactory.mm index 82c35bc663b1..7a25d5ccde02 100644 --- a/widget/cocoa/nsWidgetFactory.mm +++ b/widget/cocoa/nsWidgetFactory.mm @@ -66,7 +66,6 @@ nsClipboardConstructor(nsISupports *aOuter, REFNSIID aIID, } NS_GENERIC_FACTORY_CONSTRUCTOR(nsCocoaWindow) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker) NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPicker) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound) @@ -114,9 +113,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init) } // namespace widget } // namespace mozilla -NS_DEFINE_NAMED_CID(NS_WINDOW_CID); NS_DEFINE_NAMED_CID(NS_POPUP_CID); -NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID); NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); @@ -144,9 +141,7 @@ NS_DEFINE_NAMED_CID(NS_MACSYSTEMSTATUSBAR_CID); NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { - { &kNS_WINDOW_CID, false, NULL, nsCocoaWindowConstructor }, { &kNS_POPUP_CID, false, NULL, nsCocoaWindowConstructor }, - { &kNS_CHILD_CID, false, NULL, nsChildViewConstructor }, { &kNS_FILEPICKER_CID, false, NULL, nsFilePickerConstructor, mozilla::Module::MAIN_PROCESS_ONLY }, { &kNS_COLORPICKER_CID, false, NULL, nsColorPickerConstructor, @@ -183,9 +178,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { }; static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { - { "@mozilla.org/widgets/window/mac;1", &kNS_WINDOW_CID }, { "@mozilla.org/widgets/popup/mac;1", &kNS_POPUP_CID }, - { "@mozilla.org/widgets/childwindow/mac;1", &kNS_CHILD_CID }, { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, mozilla::Module::MAIN_PROCESS_ONLY }, { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, diff --git a/widget/gtk/nsWidgetFactory.cpp b/widget/gtk/nsWidgetFactory.cpp index ebd3dc2859fc..94924ce4bf88 100644 --- a/widget/gtk/nsWidgetFactory.cpp +++ b/widget/gtk/nsWidgetFactory.cpp @@ -61,7 +61,6 @@ using namespace mozilla; using namespace mozilla::widget; -NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) @@ -198,8 +197,6 @@ nsClipboardConstructor(nsISupports *aOuter, REFNSIID aIID, return inst->QueryInterface(aIID, aResult); } -NS_DEFINE_NAMED_CID(NS_WINDOW_CID); -NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID); NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID); @@ -233,8 +230,6 @@ NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { - { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor }, - { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor }, { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor, Module::ALLOW_IN_GPU_PROCESS }, { &kNS_COLORPICKER_CID, false, nullptr, nsColorPickerConstructor, Module::MAIN_PROCESS_ONLY }, { &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerConstructor, Module::MAIN_PROCESS_ONLY }, @@ -270,8 +265,6 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { }; static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { - { "@mozilla.org/widget/window/gtk;1", &kNS_WINDOW_CID }, - { "@mozilla.org/widgets/child_window/gtk;1", &kNS_CHILD_CID }, { "@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID, Module::ALLOW_IN_GPU_PROCESS }, { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY }, { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY }, diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 8d99d972f5e5..740d3d9e6215 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -7341,3 +7341,16 @@ nsWindow::GetSystemFont(nsCString& aFontName) return NS_OK; } +already_AddRefed +nsIWidget::CreateTopLevelWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} + +already_AddRefed +nsIWidget::CreateChildWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index a203721af132..bece544045db 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -435,8 +435,7 @@ nsBaseWidget::CreateChild(const LayoutDeviceIntRect& aRect, if (aInitData && aInitData->mWindowType == eWindowType_popup) { widget = AllocateChildPopupWidget(); } else { - static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID); - widget = do_CreateInstance(kCChildCID); + widget = nsIWidget::CreateChildWindow(); } if (widget && diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index f5b193bb0493..947424ca2390 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -554,9 +554,7 @@ protected: virtual already_AddRefed AllocateChildPopupWidget() { - static NS_DEFINE_IID(kCPopUpCID, NS_CHILD_CID); - nsCOMPtr widget = do_CreateInstance(kCPopUpCID); - return widget.forget(); + return nsIWidget::CreateChildWindow(); } LayerManager* CreateBasicLayerManager(); diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 7d63e185f8c7..a5976eeb94bd 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1915,6 +1915,12 @@ public: return XRE_IsContentProcess(); } + static already_AddRefed + CreateTopLevelWindow(); + + static already_AddRefed + CreateChildWindow(); + /** * Allocate and return a "puppet widget" that doesn't directly * correlate to a platform widget; platform events and data must diff --git a/widget/nsWidgetsCID.h b/widget/nsWidgetsCID.h index deabdd4dcf60..59e96973f639 100644 --- a/widget/nsWidgetsCID.h +++ b/widget/nsWidgetsCID.h @@ -3,16 +3,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/. */ -/* 2d96b3d0-c051-11d1-a827-0040959a28c9 */ -#define NS_WINDOW_CID \ -{ 0x2d96b3d0, 0xc051, 0x11d1, \ - {0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9}} - -/* 2d96b3d1-c051-11d1-a827-0040959a28c9 */ -#define NS_CHILD_CID \ -{ 0x2d96b3d1, 0xc051, 0x11d1, \ - {0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9} } - /* BA7DE611-6088-11d3-A83E-00105A183419 */ #define NS_POPUP_CID \ { 0xba7de611, 0x6088, 0x11d3, \ diff --git a/widget/uikit/nsWidgetFactory.mm b/widget/uikit/nsWidgetFactory.mm index 9e4f028ff62e..19566f6e8464 100644 --- a/widget/uikit/nsWidgetFactory.mm +++ b/widget/uikit/nsWidgetFactory.mm @@ -14,10 +14,8 @@ #include "nsAppShellSingleton.h" #include "nsLookAndFeel.h" #include "nsScreenManager.h" -#include "nsWindow.h" NS_GENERIC_FACTORY_CONSTRUCTOR(UIKitScreenManager) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) #include "GfxInfo.h" namespace mozilla { @@ -27,15 +25,11 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init) } } -NS_DEFINE_NAMED_CID(NS_WINDOW_CID); -NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { - { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor }, - { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor }, { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor }, { &kNS_SCREENMANAGER_CID, false, nullptr, UIKitScreenManagerConstructor }, { &kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor }, @@ -43,8 +37,6 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { }; static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { - { "@mozilla.org/widgets/window/uikit;1", &kNS_WINDOW_CID }, - { "@mozilla.org/widgets/childwindow/uikit;1", &kNS_CHILD_CID }, { "@mozilla.org/widget/appshell/uikit;1", &kNS_APPSHELL_CID }, { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID }, { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID }, diff --git a/widget/uikit/nsWindow.mm b/widget/uikit/nsWindow.mm index 3f57384807c9..6d6f162c7d89 100644 --- a/widget/uikit/nsWindow.mm +++ b/widget/uikit/nsWindow.mm @@ -850,3 +850,17 @@ nsWindow::RoundsWidgetCoordinatesTo() } return 1; } + +already_AddRefed +nsIWidget::CreateTopLevelWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} + +already_AddRefed +nsIWidget::CreateChildWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} diff --git a/widget/windows/nsWidgetFactory.cpp b/widget/windows/nsWidgetFactory.cpp index 7e322ec2df37..c2955aac40d5 100644 --- a/widget/windows/nsWidgetFactory.cpp +++ b/widget/windows/nsWidgetFactory.cpp @@ -28,7 +28,6 @@ #include "nsFilePicker.h" // needs to be included before other shobjidl.h includes #include "nsColorPicker.h" #include "nsNativeThemeWin.h" -#include "nsWindow.h" // Content processes #include "nsFilePickerProxy.h" @@ -44,6 +43,7 @@ #include "WinTaskbar.h" #include "JumpListBuilder.h" #include "JumpListItem.h" +#include "TaskbarPreview.h" #include "WindowsUIUtils.h" @@ -57,30 +57,6 @@ using namespace mozilla; using namespace mozilla::widget; -static nsresult -WindowConstructor(nsISupports *aOuter, REFNSIID aIID, - void **aResult) -{ - *aResult = nullptr; - if (aOuter != nullptr) { - return NS_ERROR_NO_AGGREGATION; - } - nsCOMPtr widget = new nsWindow; - return widget->QueryInterface(aIID, aResult); -} - -static nsresult -ChildWindowConstructor(nsISupports *aOuter, REFNSIID aIID, - void **aResult) -{ - *aResult = nullptr; - if (aOuter != nullptr) { - return NS_ERROR_NO_AGGREGATION; - } - nsCOMPtr widget = new nsWindow(true); - return widget->QueryInterface(aIID, aResult); -} - static nsresult FilePickerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) @@ -153,8 +129,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init) } } -NS_DEFINE_NAMED_CID(NS_WINDOW_CID); -NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID); NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); @@ -187,8 +161,6 @@ NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { - { &kNS_WINDOW_CID, false, nullptr, WindowConstructor }, - { &kNS_CHILD_CID, false, nullptr, ChildWindowConstructor }, { &kNS_FILEPICKER_CID, false, nullptr, FilePickerConstructor, Module::MAIN_PROCESS_ONLY }, { &kNS_COLORPICKER_CID, false, nullptr, ColorPickerConstructor, Module::MAIN_PROCESS_ONLY }, { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor, Module::ALLOW_IN_GPU_PROCESS }, @@ -223,8 +195,6 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { }; static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { - { "@mozilla.org/widgets/window/win;1", &kNS_WINDOW_CID }, - { "@mozilla.org/widgets/child_window/win;1", &kNS_CHILD_CID }, { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY }, { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY }, { "@mozilla.org/widget/appshell/win;1", &kNS_APPSHELL_CID, Module::ALLOW_IN_GPU_PROCESS }, diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 84b7f918cbde..3f78bfeed699 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -8578,3 +8578,18 @@ nsWindow::SynchronouslyRepaintOnResize() { return !gfxWindowsPlatform::GetPlatform()->DwmCompositionEnabled(); } + +already_AddRefed +nsIWidget::CreateTopLevelWindow() +{ + nsCOMPtr window = new nsWindow(); + return window.forget(); +} + +already_AddRefed +nsIWidget::CreateChildWindow() +{ + nsCOMPtr window = new nsWindow(true); + return window.forget(); +} + diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 4b0e741e92d9..e9dc6d28914e 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -655,7 +655,7 @@ protected: // Whether we're in the process of sending a WM_SETTEXT ourselves bool mSendingSetText; - // Whether we we're created as a NS_CHILD_CID window (aka ChildWindow) or not. + // Whether we we're created as a child window (aka ChildWindow) or not. bool mIsChildWindow : 1; // The point in time at which the last paint completed. We use this to avoid diff --git a/xpfe/appshell/nsWebShellWindow.cpp b/xpfe/appshell/nsWebShellWindow.cpp index 2e0e06a59f25..7a8ca0a23f21 100644 --- a/xpfe/appshell/nsWebShellWindow.cpp +++ b/xpfe/appshell/nsWebShellWindow.cpp @@ -74,9 +74,6 @@ using namespace mozilla; using namespace mozilla::dom; -/* Define Class IDs */ -static NS_DEFINE_CID(kWindowCID, NS_WINDOW_CID); - #define SIZE_PERSISTENCE_TIMEOUT 500 // msec nsWebShellWindow::nsWebShellWindow(uint32_t aChromeFlags) @@ -145,14 +142,11 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent, // Create top level window if (gfxPlatform::IsHeadless()) { mWindow = nsIWidget::CreateHeadlessWidget(); - if (!mWindow) { - return NS_ERROR_FAILURE; - } } else { - mWindow = do_CreateInstance(kWindowCID, &rv); - if (NS_OK != rv) { - return rv; - } + mWindow = nsIWidget::CreateTopLevelWindow(); + } + if (!mWindow) { + return NS_ERROR_FAILURE; } /* This next bit is troublesome. We carry two different versions of a pointer From 8cf7b6c21e65151be6c222bc3ee74ca710293f64 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 21 Aug 2018 14:28:49 -0400 Subject: [PATCH 05/49] Bug 1485099 - Add some logging to the AntiTracking component for the saving and reading of storage access permissions; r=smaug --- .../antitracking/AntiTrackingCommon.cpp | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/toolkit/components/antitracking/AntiTrackingCommon.cpp b/toolkit/components/antitracking/AntiTrackingCommon.cpp index b32785765bdf..58d0ab4ec478 100644 --- a/toolkit/components/antitracking/AntiTrackingCommon.cpp +++ b/toolkit/components/antitracking/AntiTrackingCommon.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/ipc/MessageChannel.h" #include "mozilla/AbstractThread.h" +#include "mozilla/Logging.h" #include "mozilla/StaticPrefs.h" #include "mozIThirdPartyUtil.h" #include "nsContentUtils.h" @@ -27,6 +28,22 @@ using namespace mozilla; using mozilla::dom::ContentChild; +static LazyLogModule gAntiTrackingLog("AntiTracking"); + +#define LOG(format) MOZ_LOG(gAntiTrackingLog, mozilla::LogLevel::Debug, format) + +#define LOG_SPEC(format, uri) \ + PR_BEGIN_MACRO \ + if (MOZ_LOG_TEST(gAntiTrackingLog, mozilla::LogLevel::Debug)) { \ + nsAutoCString _specStr(NS_LITERAL_CSTRING("(null)")); \ + if (uri) { \ + _specStr = uri->GetSpecOrDefault(); \ + } \ + const char* _spec = _specStr.get(); \ + LOG(format); \ + } \ + PR_END_MACRO + namespace { bool @@ -119,8 +136,13 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigi { MOZ_ASSERT(aParentWindow); + LOG(("Adding a first-party storage exception for %s...", + NS_ConvertUTF16toUTF8(aOrigin).get())); + if (StaticPrefs::network_cookie_cookieBehavior() != nsICookieService::BEHAVIOR_REJECT_TRACKER) { + LOG(("Disabled by network.cookie.cookieBehavior pref (%d), bailing out early", + StaticPrefs::network_cookie_cookieBehavior())); return StorageAccessGrantPromise::CreateAndResolve(true, __func__); } @@ -131,14 +153,19 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigi nsGlobalWindowOuter* outerParentWindow = nsGlobalWindowOuter::Cast(parentWindow->GetOuterWindow()); if (NS_WARN_IF(!outerParentWindow)) { + LOG(("No outer window found for our parent window, bailing out early")); return StorageAccessGrantPromise::CreateAndReject(false, __func__); } + LOG(("The current resource is %s-party", + outerParentWindow->IsTopLevelWindow() ? "first" : "third")); + // We are a first party resource. if (outerParentWindow->IsTopLevelWindow()) { CopyUTF16toUTF8(aOrigin, trackingOrigin); topLevelStoragePrincipal = parentWindow->GetPrincipal(); if (NS_WARN_IF(!topLevelStoragePrincipal)) { + LOG(("Top-level storage area principal not found, bailing out early")); return StorageAccessGrantPromise::CreateAndReject(false, __func__); } @@ -146,12 +173,16 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigi } else if (!GetParentPrincipalAndTrackingOrigin(parentWindow, getter_AddRefs(topLevelStoragePrincipal), trackingOrigin)) { + LOG(("Error while computing the parent principal and tracking origin, bailing out early")); return StorageAccessGrantPromise::CreateAndReject(false, __func__); } NS_ConvertUTF16toUTF8 grantedOrigin(aOrigin); if (XRE_IsParentProcess()) { + LOG(("Saving the permission: trackingOrigin=%s, grantedOrigin=%s", + trackingOrigin.get(), grantedOrigin.get())); + RefPtr p = new StorageAccessGrantPromise::Private(__func__); SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(topLevelStoragePrincipal, trackingOrigin, @@ -165,6 +196,9 @@ AntiTrackingCommon::AddFirstPartyStorageAccessGrantedFor(const nsAString& aOrigi ContentChild* cc = ContentChild::GetSingleton(); MOZ_ASSERT(cc); + LOG(("Asking the parent process to save the permission for us: trackingOrigin=%s, grantedOrigin=%s", + trackingOrigin.get(), grantedOrigin.get())); + // This is not really secure, because here we have the content process sending // the request of storing a permission. RefPtr p = new StorageAccessGrantPromise::Private(__func__); @@ -188,14 +222,21 @@ AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(n { MOZ_ASSERT(XRE_IsParentProcess()); + nsCOMPtr parentPrincipalURI; + Unused << aParentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); + LOG_SPEC(("Saving a first-party storage permission on %s for trackingOrigin=%s grantedOrigin=%s", + _spec, aTrackingOrigin.get(), aGrantedOrigin.get()), parentPrincipalURI); + if (NS_WARN_IF(!aParentPrincipal)) { // The child process is sending something wrong. Let's ignore it. + LOG(("aParentPrincipal is null, bailing out early")); aResolver(false); return; } nsCOMPtr pm = services::GetPermissionManager(); if (NS_WARN_IF(!pm)) { + LOG(("Permission manager is null, bailing out early")); aResolver(false); return; } @@ -208,11 +249,16 @@ AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(n nsAutoCString type; CreatePermissionKey(aTrackingOrigin, aGrantedOrigin, type); + LOG(("Computed permission key: %s, expiry: %d, proceeding to save in the permission manager", + type.get(), expirationTime)); + nsresult rv = pm->AddFromPrincipal(aParentPrincipal, type.get(), nsIPermissionManager::ALLOW_ACTION, nsIPermissionManager::EXPIRE_TIME, when); Unused << NS_WARN_IF(NS_FAILED(rv)); aResolver(NS_SUCCEEDED(rv)); + + LOG(("Result: %s", NS_SUCCEEDED(rv) ? "success" : "failure")); } bool @@ -222,34 +268,44 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWin MOZ_ASSERT(aWindow); MOZ_ASSERT(aURI); + LOG_SPEC(("Computing whether window %p has access to URI %s", aWindow, _spec), aURI); + nsGlobalWindowInner* innerWindow = nsGlobalWindowInner::Cast(aWindow); nsIPrincipal* toplevelPrincipal = innerWindow->GetTopLevelPrincipal(); if (!toplevelPrincipal) { // We are already the top-level principal. Let's use the window's principal. + LOG(("Our inner window lacks a top-level principal, use the window's principal instead")); toplevelPrincipal = innerWindow->GetPrincipal(); } if (!toplevelPrincipal) { // This should not be possible, right? + LOG(("No top-level principal, this shouldn't be happening! Bail out early")); return false; } nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); if (access != nsICookiePermission::ACCESS_DEFAULT) { + LOG(("CheckCookiePermissionForPrincipal() returned a non-default access code (%d), returning %s", + int(access), access != nsICookiePermission::ACCESS_DENY ? + "success" : "failure")); return access != nsICookiePermission::ACCESS_DENY; } int32_t behavior = CookiesBehavior(toplevelPrincipal); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { + LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; } if (behavior == nsICookieService::BEHAVIOR_REJECT) { + LOG(("The cookie behavior pref mandates rejecting all cookies!")); return false; } // Let's check if this is a 3rd party context. if (!nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr, aURI)) { + LOG(("Our window isn't a third-party window")); return true; } @@ -259,11 +315,13 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWin // simply rejecting the request to use the storage. In the future, if we // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense // for non-cookie storage types, this may change. + LOG(("Nothing more to do due to the behavior code %d", int(behavior))); return false; } MOZ_ASSERT(behavior == nsICookieService::BEHAVIOR_REJECT_TRACKER); if (!nsContentUtils::IsTrackingResourceWindow(aWindow)) { + LOG(("Our window isn't a tracking window")); return true; } @@ -272,12 +330,14 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWin if (!GetParentPrincipalAndTrackingOrigin(nsGlobalWindowInner::Cast(aWindow), getter_AddRefs(parentPrincipal), trackingOrigin)) { + LOG(("Failed to obtain the parent principal and the tracking origin")); return false; } nsAutoString origin; nsresult rv = nsContentUtils::GetUTFOrigin(aURI, origin); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG_SPEC(("Failed to compute the origin from %s", _spec), aURI); return false; } @@ -286,15 +346,24 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* aWin nsCOMPtr pm = services::GetPermissionManager(); if (NS_WARN_IF(!pm)) { + LOG(("Failed to obtain the permission manager")); return false; } uint32_t result = 0; rv = pm->TestPermissionFromPrincipal(parentPrincipal, type.get(), &result); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG(("Failed to test the permission")); return false; } + nsCOMPtr parentPrincipalURI; + Unused << parentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); + LOG_SPEC(("Testing permission type %s for %s resulted in %d (%s)", + type.get(), _spec, int(result), + result == nsIPermissionManager::ALLOW_ACTION ? + "success" : "failure"), parentPrincipalURI); + return result == nsIPermissionManager::ALLOW_ACTION; } @@ -305,8 +374,14 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel MOZ_ASSERT(aURI); MOZ_ASSERT(aChannel); + nsCOMPtr channelURI; + Unused << aChannel->GetURI(getter_AddRefs(channelURI)); + LOG_SPEC(("Computing whether channel %p has access to URI %s", aChannel, _spec), + channelURI); + nsCOMPtr loadInfo = aChannel->GetLoadInfo(); if (!loadInfo) { + LOG(("No loadInfo, bail out early")); return true; } @@ -318,6 +393,7 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel // If this is already the top-level window, we should use the loading // principal. if (!toplevelPrincipal) { + LOG(("Our loadInfo lacks a top-level principal, use the loadInfo's loading principal instead")); toplevelPrincipal = loadInfo->LoadingPrincipal(); } @@ -329,42 +405,56 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel // If we don't have a loading principal and this is a document channel, we are // a top-level window! if (!toplevelPrincipal) { + LOG(("We don't have a loading principal, let's see if this is a document channel" + " that belongs to a top-level window")); bool isDocument = false; nsresult rv2 = aChannel->GetIsMainDocumentChannel(&isDocument); if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2) && isDocument) { toplevelPrincipal = channelPrincipal; + LOG(("Yes, we guessed right!")); + } else { + LOG(("No, we guessed wrong!")); } } // Let's use the triggering principal then. if (!toplevelPrincipal) { + LOG(("Our loadInfo lacks a top-level principal, use the loadInfo's triggering principal instead")); toplevelPrincipal = loadInfo->TriggeringPrincipal(); } if (NS_WARN_IF(!toplevelPrincipal)) { + LOG(("No top-level principal! Bail out early")); return false; } nsCookieAccess access = CheckCookiePermissionForPrincipal(toplevelPrincipal); if (access != nsICookiePermission::ACCESS_DEFAULT) { + LOG(("CheckCookiePermissionForPrincipal() returned a non-default access code (%d), returning %s", + int(access), access != nsICookiePermission::ACCESS_DENY ? + "success" : "failure")); return access != nsICookiePermission::ACCESS_DENY; } if (NS_WARN_IF(NS_FAILED(rv) || !channelPrincipal)) { + LOG(("No channel principal, bail out early")); return false; } int32_t behavior = CookiesBehavior(channelPrincipal); if (behavior == nsICookieService::BEHAVIOR_ACCEPT) { + LOG(("The cookie behavior pref mandates accepting all cookies!")); return true; } if (behavior == nsICookieService::BEHAVIOR_REJECT) { + LOG(("The cookie behavior pref mandates rejecting all cookies!")); return false; } nsCOMPtr thirdPartyUtil = services::GetThirdPartyUtil(); if (!thirdPartyUtil) { + LOG(("No thirdPartyUtil, bail out early")); return true; } @@ -374,6 +464,7 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel &thirdParty); // Grant if it's not a 3rd party. if (!thirdParty) { + LOG(("Our channel isn't a third-party channel")); return true; } @@ -383,6 +474,7 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel // simply rejecting the request to use the storage. In the future, if we // change the meaning of BEHAVIOR_LIMIT_FOREIGN to be one which makes sense // for non-cookie storage types, this may change. + LOG(("Nothing more to do due to the behavior code %d", int(behavior))); return false; } @@ -390,14 +482,18 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel nsIPrincipal* parentPrincipal = loadInfo->TopLevelStorageAreaPrincipal(); if (!parentPrincipal) { + LOG(("No top-level storage area principal at hand")); + // parentPrincipal can be null if the parent window is not the top-level // window. if (loadInfo->TopLevelPrincipal()) { + LOG(("Parent window is the top-level window, bail out early")); return false; } parentPrincipal = loadInfo->TriggeringPrincipal(); if (NS_WARN_IF(!parentPrincipal)) { + LOG(("No triggering principal, this shouldn't be happening! Bail out early")); // Why we are here?!? return true; } @@ -405,6 +501,7 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel // Not a tracker. if (!aChannel->GetIsTrackingResource()) { + LOG(("Our channel isn't a tracking channel")); return true; } @@ -413,18 +510,21 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel nsCOMPtr trackingURI; rv = aChannel->GetURI(getter_AddRefs(trackingURI)); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG(("Failed to get the channel URI")); return true; } nsAutoString trackingOrigin; rv = nsContentUtils::GetUTFOrigin(trackingURI, trackingOrigin); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG_SPEC(("Failed to compute the origin from %s", _spec), trackingURI); return false; } nsAutoString origin; rv = nsContentUtils::GetUTFOrigin(aURI, origin); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG_SPEC(("Failed to compute the origin from %s", _spec), aURI); return false; } @@ -434,15 +534,24 @@ AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(nsIHttpChannel* aChannel nsCOMPtr pm = services::GetPermissionManager(); if (NS_WARN_IF(!pm)) { + LOG(("Failed to obtain the permission manager")); return false; } uint32_t result = 0; rv = pm->TestPermissionFromPrincipal(parentPrincipal, type.get(), &result); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG(("Failed to test the permission")); return false; } + nsCOMPtr parentPrincipalURI; + Unused << parentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); + LOG_SPEC(("Testing permission type %s for %s resulted in %d (%s)", + type.get(), _spec, int(result), + result == nsIPermissionManager::ALLOW_ACTION ? + "success" : "failure"), parentPrincipalURI); + return result == nsIPermissionManager::ALLOW_ACTION; } @@ -468,30 +577,41 @@ AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* MOZ_ASSERT(!nsContentUtils::IsTrackingResourceWindow(aFirstPartyWindow)); MOZ_ASSERT(aURI); + LOG_SPEC(("Computing a best guess as to whether window %p has access to URI %s", + aFirstPartyWindow, _spec), aURI); + if (StaticPrefs::network_cookie_cookieBehavior() != nsICookieService::BEHAVIOR_REJECT_TRACKER) { + LOG(("Disabled by the pref (%d), bail out early", + StaticPrefs::network_cookie_cookieBehavior())); return true; } if (!nsContentUtils::IsThirdPartyWindowOrChannel(aFirstPartyWindow, nullptr, aURI)) { + LOG(("Our window isn't a third-party window")); return true; } nsCOMPtr parentPrincipal = nsGlobalWindowInner::Cast(aFirstPartyWindow)->GetPrincipal(); if (NS_WARN_IF(!parentPrincipal)) { + LOG(("Failed to get the first party window's principal")); return false; } nsCookieAccess access = CheckCookiePermissionForPrincipal(parentPrincipal); if (access != nsICookiePermission::ACCESS_DEFAULT) { + LOG(("CheckCookiePermissionForPrincipal() returned a non-default access code (%d), returning %s", + int(access), access != nsICookiePermission::ACCESS_DENY ? + "success" : "failure")); return access != nsICookiePermission::ACCESS_DENY; } nsAutoString origin; nsresult rv = nsContentUtils::GetUTFOrigin(aURI, origin); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG_SPEC(("Failed to compute the origin from %s", _spec), aURI); return false; } @@ -502,14 +622,23 @@ AntiTrackingCommon::MaybeIsFirstPartyStorageAccessGrantedFor(nsPIDOMWindowInner* nsCOMPtr pm = services::GetPermissionManager(); if (NS_WARN_IF(!pm)) { + LOG(("Failed to obtain the permission manager")); return false; } uint32_t result = 0; rv = pm->TestPermissionFromPrincipal(parentPrincipal, type.get(), &result); if (NS_WARN_IF(NS_FAILED(rv))) { + LOG(("Failed to test the permission")); return false; } + nsCOMPtr parentPrincipalURI; + Unused << parentPrincipal->GetURI(getter_AddRefs(parentPrincipalURI)); + LOG_SPEC(("Testing permission type %s for %s resulted in %d (%s)", + type.get(), _spec, int(result), + result == nsIPermissionManager::ALLOW_ACTION ? + "success" : "failure"), parentPrincipalURI); + return result == nsIPermissionManager::ALLOW_ACTION; } From c3fdede5101a89591ca2e4f044cc677681bef7f8 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 21 Aug 2018 15:00:26 -0400 Subject: [PATCH 06/49] Bug 1485114 - Avoid creating nsPermission objects in the permission manager needlessly; r=nika --- extensions/cookie/nsPermissionManager.cpp | 62 +++++------------------ 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp index 94c5095a4537..865d1f1b219a 100644 --- a/extensions/cookie/nsPermissionManager.cpp +++ b/extensions/cookie/nsPermissionManager.cpp @@ -11,6 +11,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/BasePrincipal.h" #include "mozilla/ContentPrincipal.h" +#include "mozilla/Pair.h" #include "mozilla/Services.h" #include "mozilla/SystemGroup.h" #include "mozilla/Unused.h" @@ -2105,7 +2106,7 @@ template nsresult nsPermissionManager::RemovePermissionEntries(T aCondition) { - nsCOMArray array; + AutoTArray, nsCString>, 10> array; for (auto iter = mPermissionTable.Iter(); !iter.Done(); iter.Next()) { PermissionHashKey* entry = iter.Get(); for (const auto& permEntry : entry->GetPermissions()) { @@ -2120,39 +2121,16 @@ nsPermissionManager::RemovePermissionEntries(T aCondition) continue; } - nsCOMPtr permission = - nsPermission::Create(principal, - mTypeArray.ElementAt(permEntry.mType), - permEntry.mPermission, - permEntry.mExpireType, - permEntry.mExpireTime); - if (NS_WARN_IF(!permission)) { - continue; - } - array.AppendObject(permission); + array.AppendElement(MakePair(principal, + mTypeArray.ElementAt(permEntry.mType))); } } - for (int32_t i = 0; i principal; - nsAutoCString type; - - nsresult rv = array[i]->GetPrincipal(getter_AddRefs(principal)); - if (NS_FAILED(rv)) { - NS_ERROR("GetPrincipal() failed!"); - continue; - } - - rv = array[i]->GetType(type); - if (NS_FAILED(rv)) { - NS_ERROR("GetType() failed!"); - continue; - } - + for (size_t i = 0; i < array.Length(); ++i) { // AddInternal handles removal, so let it do the work... AddInternal( - principal, - type, + array[i].first(), + array[i].second(), nsIPermissionManager::UNKNOWN_ACTION, 0, nsIPermissionManager::EXPIRE_NEVER, 0, 0, @@ -2728,7 +2706,7 @@ nsPermissionManager::RemovePermissionsWithAttributes(const nsAString& aPattern) nsresult nsPermissionManager::RemovePermissionsWithAttributes(mozilla::OriginAttributesPattern& aPattern) { - nsCOMArray permissions; + AutoTArray, nsCString>, 10> permissions; for (auto iter = mPermissionTable.Iter(); !iter.Done(); iter.Next()) { PermissionHashKey* entry = iter.Get(); @@ -2744,28 +2722,14 @@ nsPermissionManager::RemovePermissionsWithAttributes(mozilla::OriginAttributesPa } for (const auto& permEntry : entry->GetPermissions()) { - nsCOMPtr permission = - nsPermission::Create(principal, - mTypeArray.ElementAt(permEntry.mType), - permEntry.mPermission, - permEntry.mExpireType, - permEntry.mExpireTime); - if (NS_WARN_IF(!permission)) { - continue; - } - permissions.AppendObject(permission); + permissions.AppendElement(MakePair(principal, + mTypeArray.ElementAt(permEntry.mType))); } } - for (int32_t i = 0; i < permissions.Count(); ++i) { - nsCOMPtr principal; - nsAutoCString type; - - permissions[i]->GetPrincipal(getter_AddRefs(principal)); - permissions[i]->GetType(type); - - AddInternal(principal, - type, + for (size_t i = 0; i < permissions.Length(); ++i) { + AddInternal(permissions[i].first(), + permissions[i].second(), nsIPermissionManager::UNKNOWN_ACTION, 0, nsIPermissionManager::EXPIRE_NEVER, From 781aabfe2e4bf9a61df60c743a9ec63a3d5b4d28 Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Thu, 16 Aug 2018 10:33:14 -0500 Subject: [PATCH 07/49] Bug 1483772 - Never have mAsyncTask be non-null when we cannot paint. r=nical In bug 1482415 a special check was added for the case where we fail to allocate a buffer and started an async task. This papered over one crash for another as ClientPaintedLayer also assumes that if there is an async task there is a capture. It'd be best to just null out mAsyncTask and keep those checks as is. Differential Revision: https://phabricator.services.mozilla.com/D3520 --HG-- extra : rebase_source : 8cb2458f0a98795a6ece90b38a9c194c863bbd84 --- gfx/layers/client/ContentClient.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 312f66d0c51e..6c2336ab0751 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -237,12 +237,14 @@ ContentClient::BeginPaint(PaintedLayer* aLayer, << dest.mBufferRect.Width() << ", " << dest.mBufferRect.Height(); } + result.mAsyncTask = nullptr; Clear(); return result; } if (!newBuffer->Lock(writeMode)) { gfxCriticalNote << "Failed to lock new back buffer."; + result.mAsyncTask = nullptr; Clear(); return result; } @@ -295,7 +297,7 @@ ContentClient::BeginPaint(PaintedLayer* aLayer, void ContentClient::EndPaint(PaintState& aPaintState, nsTArray* aReadbackUpdates) { - if (aPaintState.mAsyncTask && mBuffer) { + if (aPaintState.mAsyncTask) { aPaintState.mAsyncTask->mCapture = mBuffer->EndCapture(); } } From 731b450e6fd5794ae2bd2873d5dcd7fb8753a8a6 Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Fri, 17 Aug 2018 15:22:34 -0500 Subject: [PATCH 08/49] Bug 1483245 - Add telemetry probes for amount of time spent on paint thread and the amount of tasks. r=jrmuizel --HG-- extra : rebase_source : d260f473549d559fdd8ad7a22ea5bb81e301b438 --- gfx/layers/ipc/CompositorBridgeChild.cpp | 13 +++++++++++++ gfx/layers/ipc/CompositorBridgeChild.h | 6 ++++++ toolkit/components/telemetry/Histograms.json | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index eea3e84159ad..0ee742f7ff24 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -92,6 +92,7 @@ CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager) , mProcessToken(0) , mSectionAllocator(nullptr) , mPaintLock("CompositorBridgeChild.mPaintLock") + , mTotalAsyncPaints(0) , mOutstandingAsyncPaints(0) , mOutstandingAsyncEndTransaction(false) , mIsDelayingForAsyncPaints(false) @@ -1190,6 +1191,11 @@ CompositorBridgeChild::NotifyBeginAsyncPaint(PaintTask* aTask) MonitorAutoLock lock(mPaintLock); + if (mTotalAsyncPaints == 0) { + mAsyncTransactionBegin = TimeStamp::Now(); + } + mTotalAsyncPaints += 1; + // We must not be waiting for paints or buffer copying to complete yet. This // would imply we started a new paint without waiting for a previous one, which // could lead to incorrect rendering or IPDL deadlocks. @@ -1249,6 +1255,13 @@ CompositorBridgeChild::NotifyFinishedAsyncEndLayerTransaction() MonitorAutoLock lock(mPaintLock); + if (mTotalAsyncPaints > 0) { + float tenthMs = (TimeStamp::Now() - mAsyncTransactionBegin).ToMilliseconds() * 10; + Telemetry::Accumulate(Telemetry::GFX_OMTP_PAINT_TASK_COUNT, int32_t(mTotalAsyncPaints)); + Telemetry::Accumulate(Telemetry::GFX_OMTP_PAINT_TIME, int32_t(tenthMs)); + mTotalAsyncPaints = 0; + } + // Since this should happen after ALL paints are done and // at the end of a transaction, this should always be true. MOZ_RELEASE_ASSERT(mOutstandingAsyncPaints == 0); diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index 127d541e683f..c079a13b636c 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -372,6 +372,12 @@ private: // state below. Monitor mPaintLock; + // Contains the number of asynchronous paints that were queued since the + // beginning of the last async transaction, and the time stamp of when + // that was + size_t mTotalAsyncPaints; + TimeStamp mAsyncTransactionBegin; + // Contains the number of outstanding asynchronous paints tied to a // PLayerTransaction on this bridge. This is R/W on both the main and paint // threads, and must be accessed within the paint lock. diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index f3153daa3258..63c42fe6036a 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -13724,6 +13724,16 @@ "bug_numbers": [1341569], "description": "Milliseconds between starting to fill an autofill-eligible form field and submitting the form, keyed by the combination of form type and filling type." }, + "GFX_OMTP_PAINT_TIME": { + "record_in_processes": ["content"], + "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "rhunt@mozilla.com"], + "expires_in_version": "70", + "kind": "exponential", + "high": 10000, + "n_buckets": 50, + "description": "Amount of time in tenths of a millisecond from the beginning of the first async paint until all async paints are finished.", + "bug_numbers": [1483245] + }, "GFX_OMTP_PAINT_WAIT_TIME": { "record_in_processes": ["content"], "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "rhunt@mozilla.com"], @@ -13734,6 +13744,16 @@ "description": "Amount of time in milliseconds the main thread spends waiting for the paint thread to complete, if the time was greater than 200us.", "bug_numbers": [1386968] }, + "GFX_OMTP_PAINT_TASK_COUNT": { + "record_in_processes": ["content"], + "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "rhunt@mozilla.com"], + "expires_in_version": "70", + "kind": "exponential", + "high": 100, + "n_buckets": 25, + "description": "The amount of async paint tasks queued to the paint thread during a layer transaction.", + "bug_numbers": [1483245] + }, "PREFERENCES_FILE_LOAD_TIME_US": { "record_in_processes": ["main", "content"], "expires_in_version": "62", From cce0bfcd74aa5b2e8d0fe33c78a4e2f7007d117b Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Mon, 20 Aug 2018 17:11:32 -0500 Subject: [PATCH 09/49] Bug 1484420 - Move locale-related functions into js/public/LocaleSensitive.h that isn't #include'd in jsapi.h. r=anba --HG-- extra : rebase_source : 96d10bf0985da922f1992ac13f39cb4c2a944137 --- dom/workers/RuntimeService.cpp | 1 + dom/workers/WorkerPrivate.cpp | 1 + js/public/LocaleSensitive.h | 99 +++++++++++++++++++ js/src/builtin/String.cpp | 3 + js/src/builtin/TestingFunctions.cpp | 1 + js/src/jsapi-tests/testDateToLocaleString.cpp | 1 + .../jsapi-tests/testIntlAvailableLocales.cpp | 1 + js/src/jsapi.cpp | 1 + js/src/jsapi.h | 62 ------------ js/src/jsnum.cpp | 3 + js/src/jspubtd.h | 1 - js/src/moz.build | 1 + js/src/vm/Runtime.h | 1 + js/xpconnect/src/XPCLocale.cpp | 4 +- 14 files changed, 114 insertions(+), 66 deletions(-) create mode 100644 js/public/LocaleSensitive.h diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index aa5359a9f2c4..ddd7bec79040 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -29,6 +29,7 @@ #include "mozilla/ipc/BackgroundChild.h" #include "GeckoProfiler.h" #include "jsfriendapi.h" +#include "js/LocaleSensitive.h" #include "mozilla/AbstractThread.h" #include "mozilla/ArrayUtils.h" #include "mozilla/AsyncEventDispatcher.h" diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index fc91ba93a2b2..1eafa00f1d0d 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -6,6 +6,7 @@ #include "WorkerPrivate.h" +#include "js/LocaleSensitive.h" #include "js/MemoryMetrics.h" #include "MessageEventRunnable.h" #include "mozilla/ScopeExit.h" diff --git a/js/public/LocaleSensitive.h b/js/public/LocaleSensitive.h new file mode 100644 index 000000000000..d1163c5d559b --- /dev/null +++ b/js/public/LocaleSensitive.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + * Functions and structures related to locale-sensitive behavior, including + * exposure of the default locale (used by operations like toLocaleString). + */ + +#ifndef js_LocaleSensitive_h +#define js_LocaleSensitive_h + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle +#include "js/Utility.h" // JS::UniqueChars + +struct JSContext; +struct JSRuntime; +class JSString; + +namespace JS { union Value; } + +/** + * Set the default locale for the ECMAScript Internationalization API + * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat, and others that will + * arise as time passes). (Note that the Internationalization API encourages + * clients to specify their own locales; this default locale is only used when + * no locale is specified, e.g. calling a toLocaleString function without + * passing a locale argument to it.) + * + * The locale string remains owned by the caller. + */ +extern JS_PUBLIC_API(bool) +JS_SetDefaultLocale(JSRuntime* rt, const char* locale); + +/** + * Return a copy of the default locale for the ECMAScript Internationalization + * API (and for various ECMAScript functions that will invoke it). The locale + * is retrieved from the |JSRuntime| that corresponds to |cx|. + * + * XXX Bug 1483961 means it's difficult to interpret the meaning of a null + * return value for the time being, and we should fix this! + */ +extern JS_PUBLIC_API(JS::UniqueChars) +JS_GetDefaultLocale(JSContext* cx); + +/** Reset the default locale to OS defaults. */ +extern JS_PUBLIC_API(void) +JS_ResetDefaultLocale(JSRuntime* rt); + +using JSLocaleToUpperCase = + bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); + +using JSLocaleToLowerCase = + bool (*)(JSContext* cx, JS::Handle src, JS::MutableHandle rval); + +using JSLocaleCompare = + bool (*)(JSContext* cx, JS::Handle src1, JS::Handle src2, + JS::MutableHandle rval); + +using JSLocaleToUnicode = + bool (*)(JSContext* cx, const char* src, JS::MutableHandle rval); + +/** + * A suite of locale-specific string conversion and error message callbacks + * used to implement locale-sensitive behaviors (such as those performed by + * the various toLocaleString and toLocale{Date,Time}String functions). + * + * If SpiderMonkey is compiled --with-intl-api, then #if EXPOSE_INTL_API. In + * this case, SpiderMonkey itself will implement ECMA-402-compliant behavior by + * calling on ICU, and none of the fields in this struct will ever be used. + * (You'll still be able to call the get/set-callbacks functions; they just + * won't affect JavaScript semantics.) + */ +struct JSLocaleCallbacks +{ + JSLocaleToUpperCase localeToUpperCase; + JSLocaleToLowerCase localeToLowerCase; + JSLocaleCompare localeCompare; + JSLocaleToUnicode localeToUnicode; +}; + +/** + * Set locale callbacks to be used in builds not compiled --with-intl-api. + * |callbacks| must persist as long as the |JSRuntime|. Pass |nullptr| to + * restore default behavior. + */ +extern JS_PUBLIC_API(void) +JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); + +/** + * Return the current locale callbacks, which may be nullptr. + */ +extern JS_PUBLIC_API(const JSLocaleCallbacks*) +JS_GetLocaleCallbacks(JSRuntime* rt); + +#endif /* js_LocaleSensitive_h */ diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index aba6a1acf07a..25cedcb4d85e 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -31,6 +31,9 @@ #include "builtin/RegExp.h" #include "jit/InlinableNatives.h" #include "js/Conversions.h" +#if !EXPOSE_INTL_API +#include "js/LocaleSensitive.h" +#endif #include "js/StableStringChars.h" #include "js/UniquePtr.h" #if ENABLE_INTL_API diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 570aaf323adb..f9ba87cffbd4 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -44,6 +44,7 @@ #include "js/AutoByteString.h" #include "js/Debug.h" #include "js/HashTable.h" +#include "js/LocaleSensitive.h" #include "js/StableStringChars.h" #include "js/StructuredClone.h" #include "js/UbiNode.h" diff --git a/js/src/jsapi-tests/testDateToLocaleString.cpp b/js/src/jsapi-tests/testDateToLocaleString.cpp index a011ca184c40..e8256b9f87e3 100644 --- a/js/src/jsapi-tests/testDateToLocaleString.cpp +++ b/js/src/jsapi-tests/testDateToLocaleString.cpp @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testDateToLocaleString) diff --git a/js/src/jsapi-tests/testIntlAvailableLocales.cpp b/js/src/jsapi-tests/testIntlAvailableLocales.cpp index dca84fde6b3e..c2393cb77be5 100644 --- a/js/src/jsapi-tests/testIntlAvailableLocales.cpp +++ b/js/src/jsapi-tests/testIntlAvailableLocales.cpp @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "js/LocaleSensitive.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testIntlAvailableLocales) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 420dfd3a0ada..d0cdfa994ca7 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -61,6 +61,7 @@ #include "js/Date.h" #include "js/Initialization.h" #include "js/JSON.h" +#include "js/LocaleSensitive.h" #include "js/Proxy.h" #include "js/SliceBudget.h" #include "js/StableStringChars.h" diff --git a/js/src/jsapi.h b/js/src/jsapi.h index a0f715ed3ec8..a70e5914b326 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -223,19 +223,6 @@ typedef void JS::PromiseRejectionHandlingState state, void* data); -typedef bool -(* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2, - JS::MutableHandleValue rval); - -typedef bool -(* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval); - /** * Callback used to ask the embedding for the cross compartment wrapper handler * that implements the desired prolicy for this kind of object in the @@ -4725,55 +4712,6 @@ PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp); /************************************************************************/ -/** - * The default locale for the ECMAScript Internationalization API - * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat). - * Note that the Internationalization API encourages clients to - * specify their own locales. - * The locale string remains owned by the caller. - */ -extern JS_PUBLIC_API(bool) -JS_SetDefaultLocale(JSRuntime* rt, const char* locale); - -/** - * Look up the default locale for the ECMAScript Internationalization API. - * NB: The locale information is retrieved from cx's runtime. - */ -extern JS_PUBLIC_API(JS::UniqueChars) -JS_GetDefaultLocale(JSContext* cx); - -/** - * Reset the default locale to OS defaults. - */ -extern JS_PUBLIC_API(void) -JS_ResetDefaultLocale(JSRuntime* rt); - -/** - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; // not used #if EXPOSE_INTL_API - JSLocaleToLowerCase localeToLowerCase; // not used #if EXPOSE_INTL_API - JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API - JSLocaleToUnicode localeToUnicode; -}; - -/** - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing nullptr restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks); - -/** - * Return the address of the current locale callbacks struct, which may - * be nullptr. - */ -extern JS_PUBLIC_API(const JSLocaleCallbacks*) -JS_GetLocaleCallbacks(JSRuntime* rt); - -/************************************************************************/ - /* * Error reporting. * diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 957396ac7996..e138453c1637 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -28,6 +28,9 @@ #include "builtin/String.h" #include "double-conversion/double-conversion.h" #include "js/Conversions.h" +#if !EXPOSE_INTL_API +#include "js/LocaleSensitive.h" +#endif #include "util/DoubleToString.h" #include "util/StringBuffer.h" #ifdef ENABLE_BIGINT diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index b5602ed8cdd7..1ee6915b07d5 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -68,7 +68,6 @@ struct JSClass; class JSErrorReport; struct JSExceptionState; struct JSFunctionSpec; -struct JSLocaleCallbacks; struct JSPrincipals; struct JSPropertySpec; struct JSSecurityCallbacks; diff --git a/js/src/moz.build b/js/src/moz.build index e6606cb490b6..106be1ef1e73 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -144,6 +144,7 @@ EXPORTS.js += [ '../public/Id.h', '../public/Initialization.h', '../public/JSON.h', + '../public/LocaleSensitive.h', '../public/MemoryFunctions.h', '../public/MemoryMetrics.h', '../public/Principals.h', diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index bde5130c444d..a52d8fdee8e2 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -69,6 +69,7 @@ class AutoHeapSession; } // namespace js struct DtoaState; +struct JSLocaleCallbacks; #ifdef JS_SIMULATOR_ARM64 namespace vixl { diff --git a/js/xpconnect/src/XPCLocale.cpp b/js/xpconnect/src/XPCLocale.cpp index 39bd44e05a2f..8944f9d645dc 100644 --- a/js/xpconnect/src/XPCLocale.cpp +++ b/js/xpconnect/src/XPCLocale.cpp @@ -6,9 +6,8 @@ #include "mozilla/Assertions.h" -#include "jsapi.h" +#include "js/LocaleSensitive.h" -#include "nsJSUtils.h" #include "nsIObserver.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" @@ -18,7 +17,6 @@ #include "xpcpublic.h" -using namespace JS; using namespace mozilla; using mozilla::intl::LocaleService; From 3e20f0d9161cab25fdaf220746486725985d8acf Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 21 Aug 2018 17:00:59 -0400 Subject: [PATCH 10/49] Bug 1471743 - remove STRICT_FAKE_SYMLINKS code from nsLocalFileWin; r=erahm We don't define STRICT_FAKE_SYMLINKS anywhere, so this is dead code. --- xpcom/io/nsLocalFileWin.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index c667a92c08b8..c0fe1428b64d 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -3121,17 +3121,6 @@ NS_IMETHODIMP nsLocalFile::GetTarget(nsAString& aResult) { aResult.Truncate(); -#if STRICT_FAKE_SYMLINKS - bool symLink = false; - nsresult rv = IsSymlink(&symLink); - if (NS_FAILED(rv)) { - return rv; - } - - if (!symLink) { - return NS_ERROR_FILE_INVALID_PATH; - } -#endif Resolve(); aResult = mResolvedPath; From 53c0dcb241cc7ac035204658859aa70991b8bd98 Mon Sep 17 00:00:00 2001 From: Chris Lilley Date: Mon, 20 Aug 2018 22:07:58 +0000 Subject: [PATCH 11/49] Bug 1460043 [wpt PR 7633] - css generated content: added test for counter-* calc() values, a=testonly Automatic update from web-platform-testsMerge pull request #7633 from ondras/counter-calc css generated content: added test for counter-* calc() values -- wpt-commits: c1b66fc2e065d2045d258111aa4d28f9395cdb8e wpt-pr: 7633 --- testing/web-platform/meta/MANIFEST.json | 25 +++++++++++ .../calc-in-counter-001-ref.xhtml | 27 ++++++++++++ .../css-values-3/calc-in-counter-001.xhtml | 42 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 testing/web-platform/tests/css/css-values-3/calc-in-counter-001-ref.xhtml create mode 100644 testing/web-platform/tests/css/css-values-3/calc-in-counter-001.xhtml diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index ad70043b5c12..ee2e14192935 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -152027,6 +152027,18 @@ {} ] ], + "css/css-values-3/calc-in-counter-001.xhtml": [ + [ + "/css/css-values-3/calc-in-counter-001.xhtml", + [ + [ + "/css/css-values-3/calc-in-counter-001-ref.xhtml", + "==" + ] + ], + {} + ] + ], "css/css-values/attr-color-invalid-cast.html": [ [ "/css/css-values/attr-color-invalid-cast.html", @@ -263622,6 +263634,11 @@ {} ] ], + "css/css-values-3/calc-in-counter-001-ref.xhtml": [ + [ + {} + ] + ], "css/css-values/META.yml": [ [ {} @@ -559082,6 +559099,14 @@ "50af0313de5fd78476c92155161c5d2b35519e3f", "manual" ], + "css/css-values-3/calc-in-counter-001-ref.xhtml": [ + "5614ec09b2641a580f8c965c339568701e46b612", + "support" + ], + "css/css-values-3/calc-in-counter-001.xhtml": [ + "1a2db830983a89cb7852818e8ba497baa7837726", + "reftest" + ], "css/css-values/META.yml": [ "a22882a9996b14afa942d3403fa1a873f526073a", "support" diff --git a/testing/web-platform/tests/css/css-values-3/calc-in-counter-001-ref.xhtml b/testing/web-platform/tests/css/css-values-3/calc-in-counter-001-ref.xhtml new file mode 100644 index 000000000000..5614ec09b264 --- /dev/null +++ b/testing/web-platform/tests/css/css-values-3/calc-in-counter-001-ref.xhtml @@ -0,0 +1,27 @@ + + + + CSS Test: counter-* properties with a calc() expression + + + + + +

The following two lines should be the same:

+ +
+ 8 + 10 +
+ +
+ 8 + 10 +
+ + + diff --git a/testing/web-platform/tests/css/css-values-3/calc-in-counter-001.xhtml b/testing/web-platform/tests/css/css-values-3/calc-in-counter-001.xhtml new file mode 100644 index 000000000000..1a2db830983a --- /dev/null +++ b/testing/web-platform/tests/css/css-values-3/calc-in-counter-001.xhtml @@ -0,0 +1,42 @@ + + + + CSS Test: counter-* properties with a calc() expression + + + + + + + + + + + + +

The following two lines should be the same:

+ +
+ + +
+ +
+ 8 + 10 +
+ + + From a5e47f65f82e66d1b56a8e4a7a8de48ab92ccb4d Mon Sep 17 00:00:00 2001 From: Chris Lilley Date: Mon, 20 Aug 2018 22:08:20 +0000 Subject: [PATCH 12/49] Bug 1460859 [wpt PR 10963] - Add basic text in a shape tests., a=testonly Automatic update from web-platform-testsMerge pull request #10963 from Tavmjong/text-shape Add basic text in a shape tests. -- wpt-commits: 79d77b7a845d6a141feeb7f2f719fa121b34be89 wpt-pr: 10963 --- testing/web-platform/meta/MANIFEST.json | 100 ++++++++++++++++++ .../text/reftests/text-complex-001-ref.svg | 73 +++++++++++++ .../svg/text/reftests/text-complex-001.svg | 69 ++++++++++++ .../text/reftests/text-complex-002-ref.svg | 74 +++++++++++++ .../svg/text/reftests/text-complex-002.svg | 69 ++++++++++++ .../reftests/text-shape-inside-001-ref.svg | 77 ++++++++++++++ .../text/reftests/text-shape-inside-001.svg | 61 +++++++++++ .../reftests/text-shape-inside-002-ref.svg | 76 +++++++++++++ .../text/reftests/text-shape-inside-002.svg | 61 +++++++++++ 9 files changed, 660 insertions(+) create mode 100644 testing/web-platform/tests/svg/text/reftests/text-complex-001-ref.svg create mode 100755 testing/web-platform/tests/svg/text/reftests/text-complex-001.svg create mode 100644 testing/web-platform/tests/svg/text/reftests/text-complex-002-ref.svg create mode 100644 testing/web-platform/tests/svg/text/reftests/text-complex-002.svg create mode 100755 testing/web-platform/tests/svg/text/reftests/text-shape-inside-001-ref.svg create mode 100755 testing/web-platform/tests/svg/text/reftests/text-shape-inside-001.svg create mode 100755 testing/web-platform/tests/svg/text/reftests/text-shape-inside-002-ref.svg create mode 100755 testing/web-platform/tests/svg/text/reftests/text-shape-inside-002.svg diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index ee2e14192935..b5007277ed06 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -186371,6 +186371,30 @@ {} ] ], + "svg/text/reftests/text-complex-001.svg": [ + [ + "/svg/text/reftests/text-complex-001.svg", + [ + [ + "/svg/text/reftests/text-complex-001-ref.svg", + "==" + ] + ], + {} + ] + ], + "svg/text/reftests/text-complex-002.svg": [ + [ + "/svg/text/reftests/text-complex-002.svg", + [ + [ + "/svg/text/reftests/text-complex-002-ref.svg", + "==" + ] + ], + {} + ] + ], "svg/text/reftests/text-inline-size-001.svg": [ [ "/svg/text/reftests/text-inline-size-001.svg", @@ -186503,6 +186527,30 @@ {} ] ], + "svg/text/reftests/text-shape-inside-001.svg": [ + [ + "/svg/text/reftests/text-shape-inside-001.svg", + [ + [ + "/svg/text/reftests/text-shape-inside-001-ref.svg", + "==" + ] + ], + {} + ] + ], + "svg/text/reftests/text-shape-inside-002.svg": [ + [ + "/svg/text/reftests/text-shape-inside-002.svg", + [ + [ + "/svg/text/reftests/text-shape-inside-002-ref.svg", + "==" + ] + ], + {} + ] + ], "svg/text/reftests/textpath-shape-001.svg": [ [ "/svg/text/reftests/textpath-shape-001.svg", @@ -301239,6 +301287,16 @@ {} ] ], + "svg/text/reftests/text-complex-001-ref.svg": [ + [ + {} + ] + ], + "svg/text/reftests/text-complex-002-ref.svg": [ + [ + {} + ] + ], "svg/text/reftests/text-inline-size-001-ref.svg": [ [ {} @@ -301294,6 +301352,16 @@ {} ] ], + "svg/text/reftests/text-shape-inside-001-ref.svg": [ + [ + {} + ] + ], + "svg/text/reftests/text-shape-inside-002-ref.svg": [ + [ + {} + ] + ], "svg/text/reftests/textpath-shape-001-ref.svg": [ [ {} @@ -637151,6 +637219,22 @@ "51303171f09d28e3958ab74ecdce7f9cf120bd12", "testharness" ], + "svg/text/reftests/text-complex-001-ref.svg": [ + "5ade69dce1de95954861271c0e523767230ae275", + "support" + ], + "svg/text/reftests/text-complex-001.svg": [ + "747737cce7e39fb7336530328e5de7f1d2c07f01", + "reftest" + ], + "svg/text/reftests/text-complex-002-ref.svg": [ + "3d3968fa4923436e760dd80b05af292a615cffcb", + "support" + ], + "svg/text/reftests/text-complex-002.svg": [ + "40b62ac95d66f2914c8a373332f567929e8d2aae", + "reftest" + ], "svg/text/reftests/text-inline-size-001-ref.svg": [ "6abd211584ea3b500e409c0f0fa956182fe131e6", "support" @@ -637239,6 +637323,22 @@ "e52bb770521c1b60a6b3998324882a36153ef243", "reftest" ], + "svg/text/reftests/text-shape-inside-001-ref.svg": [ + "5a2c6c0b472669ce32509bd0bdbd09ba1a195ab2", + "support" + ], + "svg/text/reftests/text-shape-inside-001.svg": [ + "248fe1a44f98099dd678e9ef63f1b97a5c09cfdf", + "reftest" + ], + "svg/text/reftests/text-shape-inside-002-ref.svg": [ + "e75ce485c5cf3fa3fc5acb24bb3d2b2d4b6ef49b", + "support" + ], + "svg/text/reftests/text-shape-inside-002.svg": [ + "64b1307966c4527c0ba6546d7e80730512d8f382", + "reftest" + ], "svg/text/reftests/textpath-shape-001-ref.svg": [ "10827c85810cdf9dc7e70a665c289814d35ed219", "support" diff --git a/testing/web-platform/tests/svg/text/reftests/text-complex-001-ref.svg b/testing/web-platform/tests/svg/text/reftests/text-complex-001-ref.svg new file mode 100644 index 000000000000..5ade69dce1de --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-complex-001-ref.svg @@ -0,0 +1,73 @@ + + + + Text in Shape — 001 + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem + ipsum + dolor sit amet, + consectetur + adipisicing elit, + sed do eiusmod + tempor + + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-complex-001.svg b/testing/web-platform/tests/svg/text/reftests/text-complex-001.svg new file mode 100755 index 000000000000..747737cce7e3 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-complex-001.svg @@ -0,0 +1,69 @@ + + + + Text in Shape — 001 + + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-complex-002-ref.svg b/testing/web-platform/tests/svg/text/reftests/text-complex-002-ref.svg new file mode 100644 index 000000000000..3d3968fa4923 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-complex-002-ref.svg @@ -0,0 +1,74 @@ + + + + Text in Shape — 002 + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + لكن + لا بد أن + أوضح لك + أن كل هذه الأفكار + المغلوطة حول + استنكار النشوة + وتمجيد الألم نشأت + بالفعل، + + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-complex-002.svg b/testing/web-platform/tests/svg/text/reftests/text-complex-002.svg new file mode 100644 index 000000000000..40b62ac95d66 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-complex-002.svg @@ -0,0 +1,69 @@ + + + + Text in Shape — 002 + + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + لكن لا بد أن أوضح لك أن كل هذه الأفكار المغلوطة حول استنكار النشوة وتمجيد الألم نشأت بالفعل، وسأعرض لك التفاصيل + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001-ref.svg b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001-ref.svg new file mode 100755 index 000000000000..5a2c6c0b4726 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001-ref.svg @@ -0,0 +1,77 @@ + + + + Text in Shape — 001 + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur + adipisicing elit, + + + + + + Lorem ipsum dolor sit amet, consectetur + adipisicing elit, + + + + + + Lorem ipsum dolor sit amet, consectetur + adipisicing elit, + + + + + + Lorem + ipsum + dolor + sit + amet, + consectetur + adipisicing elit, + + + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001.svg b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001.svg new file mode 100755 index 000000000000..248fe1a44f98 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-001.svg @@ -0,0 +1,61 @@ + + + + Text in Shape — 001 + + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002-ref.svg b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002-ref.svg new file mode 100755 index 000000000000..e75ce485c5cf --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002-ref.svg @@ -0,0 +1,76 @@ + + + + Text in Shape — 002 + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, + consectetur adipisicing elit, + + + + + + Lorem ipsum dolor sit amet, + consectetur adipisicing elit, + + + + + + Lorem ipsum dolor sit amet, + consectetur adipisicing elit, + + + + + + Lorem + ipsum + dolor + sit + amet, + consectetur adipisicing elit, + + + + + diff --git a/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002.svg b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002.svg new file mode 100755 index 000000000000..64b1307966c4 --- /dev/null +++ b/testing/web-platform/tests/svg/text/reftests/text-shape-inside-002.svg @@ -0,0 +1,61 @@ + + + + Text in Shape — 002 + + + + + + TOKENS + TEST ASSERTION + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + + + + From bcb4f5ac6d7a9ab3394a2f10888438d07d71e39e Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Mon, 20 Aug 2018 22:08:38 +0000 Subject: [PATCH 13/49] Bug 1483570 [wpt PR 12503] - [css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set., a=testonly Automatic update from web-platform-tests[css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set. In StyleValueToCSSValue, when checking whether a certain CSSStyleValue matches the property in question, we now ask the registration (via CSSOMTypes) if the CSSStyleValue matches. If it doesn't match, we throw a TypeError like for normal properties. If it does match, the CSSStyleValue is stringified, tokenized, and set on the style rule as tokens. I have postponed support for and , because CSSUnsupportedStyleValue currently does not handle registered custom properties at all. This is appropriate to fix in a separate CL. Note that, because the string version of StylePropertyMap.set also uses StyleValueToCSSValue, it will no longer be possible to set registered custom properties with a string--even if the syntax is matched. A subsequent CL will fix this. R=futhark@chromium.org Bug: 641877 Change-Id: Ie0cc2f87e39f8f59015824bfd1b81efaf402c326 Reviewed-on: https://chromium-review.googlesource.com/1175822 Commit-Queue: Anders Ruud Reviewed-by: Rune Lillesveen Cr-Commit-Position: refs/heads/master@{#583695} -- wpt-commits: 218a15f938b8612bac6a74baa8cccdaf53d57221 wpt-pr: 12503 --- testing/web-platform/meta/MANIFEST.json | 2 +- .../typedom.tentative.html | 154 +++++++++++++++++- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index b5007277ed06..4113b37ebf02 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -539988,7 +539988,7 @@ "support" ], "css/css-properties-values-api/typedom.tentative.html": [ - "065280614cca9fa52b79c28e253c30ada188a1b9", + "69ebf7a13d8cf3d71413259db68336368e5032e7", "testharness" ], "css/css-properties-values-api/unit-cycles.html": [ diff --git a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html index 065280614cca..69ebf7a13d8c 100644 --- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html +++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html @@ -1,11 +1,13 @@ - + - +
From 2f6db37cb0a1d77cd2ca31ccc09622f0f8b71f30 Mon Sep 17 00:00:00 2001 From: moz-wptsync-bot Date: Wed, 15 Aug 2018 17:20:40 +0000 Subject: [PATCH 14/49] Bug 1483570 [wpt PR 12503] - Update wpt metadata, a=testonly wpt-pr: 12503 wpt-type: metadata --- .../css/css-properties-values-api/typedom.tentative.html.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/web-platform/meta/css/css-properties-values-api/typedom.tentative.html.ini b/testing/web-platform/meta/css/css-properties-values-api/typedom.tentative.html.ini index 06fe3d2271ac..d43221f39eca 100644 --- a/testing/web-platform/meta/css/css-properties-values-api/typedom.tentative.html.ini +++ b/testing/web-platform/meta/css/css-properties-values-api/typedom.tentative.html.ini @@ -1,4 +1,5 @@ [typedom.tentative.html] + expected: ERROR [Computed * is reified as CSSUnparsedValue] expected: FAIL From ef16d78959c516867d4719febdb78e9d36646fae Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Mon, 20 Aug 2018 22:08:58 +0000 Subject: [PATCH 15/49] Bug 1483991 [wpt PR 12534] - Sync Mozilla tests as of 2018-08-16, a=testonly Automatic update from web-platform-testsSync Mozilla tests as of https://hg.mozilla.org/mozilla-central/rev/4248cea4f9a1e5cb64c0d121ff248e11e003e9e2 . (#12534) This contains a single change, from [Bug 1472843](https://bugzilla.mozilla.org/show_bug.cgi?id=1472843) by @iyermihir, reviewed by @dholbert. -- wpt-commits: 507d63bba2e1d3aee550f161498f396ff4ab6842 wpt-pr: 12534 --- testing/web-platform/meta/MANIFEST.json | 147 +++++++++++++- .../flexbox-align-content-horiz-001-ref.xhtml | 28 +++ .../flexbox-align-content-horiz-001a.xhtml | 28 +++ .../flexbox-align-content-horiz-001b.xhtml | 28 +++ .../flexbox-align-content-vert-001-ref.xhtml | 28 +++ .../flexbox-align-content-vert-001a.xhtml | 28 +++ .../flexbox-align-content-vert-001b.xhtml | 28 +++ ...flexbox-align-content-wmvert-001-ref.xhtml | 173 ++++++++++++++++ .../flexbox-align-content-wmvert-001.xhtml | 179 ++++++++++++++++ .../flexbox-align-self-horiz-002-ref.xhtml | 19 +- .../flexbox-align-self-horiz-002.xhtml | 19 ++ .../flexbox-align-self-vert-002-ref.xhtml | 19 +- .../flexbox/flexbox-align-self-vert-002.xhtml | 17 ++ .../flexbox-align-self-vert-rtl-005-ref.xhtml | 105 ++++++++++ .../flexbox-align-self-vert-rtl-005.xhtml | 92 +++++++++ ...lexbox-justify-content-horiz-006-ref.xhtml | 192 ++++++++++++++++++ .../flexbox-justify-content-horiz-006.xhtml | 140 +++++++++++++ ...flexbox-justify-content-vert-006-ref.xhtml | 143 +++++++++++++ .../flexbox-justify-content-vert-006.xhtml | 141 +++++++++++++ ...exbox-justify-content-wmvert-001-ref.xhtml | 143 +++++++++++++ .../flexbox-justify-content-wmvert-001.xhtml | 142 +++++++++++++ .../flexbox/reftest.list | 5 + 22 files changed, 1831 insertions(+), 13 deletions(-) create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml create mode 100644 testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 4113b37ebf02..fa980ded6320 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -168523,6 +168523,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-items-center-nested-001.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-items-center-nested-001.html", @@ -168823,6 +168835,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-anonymous-items-001.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-anonymous-items-001.html", @@ -169903,6 +169927,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-001a.xhtml": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-001a.xhtml", @@ -169975,6 +170011,30 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-001.xhtml": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-001.xhtml", @@ -271277,6 +271337,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-items-center-nested-001-ref.html": [ [ {} @@ -271392,6 +271457,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-anonymous-items-001-ref.html": [ [ {} @@ -271707,6 +271777,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-001-ref.xhtml": [ [ {} @@ -271732,6 +271807,16 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-001-ref.xhtml": [ [ {} @@ -572856,27 +572941,35 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml": [ - "c83f5a03ce2112e10c1e9670aa22d25e3832ea68", + "33057bf5f0f8e0182850a0ad272cdddaac66a6a3", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml": [ - "96fc4cd0a4481120bba3383acaf0d339ab50daad", + "bb0a8cda64b19b85c612a0609d35c400eefaa840", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001b.xhtml": [ - "0f2a25426b3a734dc1e2a5077e86bacfe6d71c40", + "a1e192102ea9cbbdc5685085d47dfdd8b81d5023", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001-ref.xhtml": [ - "ab407a42e21e58411ae4fdd396fadf31d6c2b301", + "1bac2bcda1dfc8f919211c26841f55883c249180", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml": [ - "e8319cb75381f88b824378907374050722070064", + "c4236ef0406c48c5aec75d17d207cfb069591793", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001b.xhtml": [ - "a2e7ae6fb8adc2f1e43eddc2f3519dd2a49fb5c2", + "54a8ed31f9637eb9781a5a1fafacec498f402cf9", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml": [ + "2902a09c163759bd604b53e0b04a0be8f3bdb8c6", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml": [ + "e0c40a72553100dc9e8652fc7e6f7bef17a2b725", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-items-center-nested-001-ref.html": [ @@ -572960,11 +573053,11 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002-ref.xhtml": [ - "59d13a6454409d5ee7be8feeae0b2d8323241a94", + "bc73fa7f926715b7b813e67bf0558ba041461112", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml": [ - "cddd5b4554041b8744d5913a751fbf62ea247f1b", + "d1273d1f55b8284821a8ed47b7cfc617670f8e52", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-003-ref.xhtml": [ @@ -573016,11 +573109,11 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002-ref.xhtml": [ - "3a5ad06a5f8d148f23f6011fd71346ccef6ef402", + "14b456e67128e5ffbbaf5d570016ad4670f45871", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002.xhtml": [ - "c45d737bfbf6f32013630e286776efec35ee40cd", + "2ff89bdf5f52c8e040dd665d53888c0566cafc5d", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-003-ref.xhtml": [ @@ -573071,6 +573164,14 @@ "4f4f49afda37f66b50e6b502bf0244540d1bf84e", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml": [ + "b0c46adcb9d786cc5d7fb1455aea7c6e9dcc7d77", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml": [ + "420c334c841efb113d7e769deb3062097ff54307", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-anonymous-items-001-ref.html": [ "8f99ea1d56ae19136b91c460003ebdab1bd821b6", "support" @@ -573683,6 +573784,14 @@ "53cba03fbe579ee64179cb5c90cc9734beab9366", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml": [ + "7723b5fa2080af80c15890c7e0b73b16ae25c7fa", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml": [ + "dcbe6184c7e8156bad3c87c95af58d8e335fe958", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-001-ref.xhtml": [ "20f1c5df34e257358ad8c5ace97ee5b0fafb8864", "support" @@ -573727,6 +573836,22 @@ "bb99dd09b45f72c6aeb260ebd8e37782c173c01d", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml": [ + "b1a5bf2a9894bd421759a3abdb21fe9181a3672d", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml": [ + "38a7f91d783c246a42b2e88c14d0a173142afddf", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml": [ + "0b99be2f2538d1cafbaeec4485a9c7dcd4f0cfde", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml": [ + "f676c6c1cdc5eceaa0ccb5fb77e7f4650618fb0b", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-margin-auto-horiz-001-ref.xhtml": [ "1321e5a3878b353f54db7459517539dd9b779ab2", "support" @@ -574260,7 +574385,7 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/reftest.list": [ - "d2c5c47b6c931c4d1b6c347c77eb8b66348da6b2", + "b51226706eae57ce44afdbbc24d5fb74e4225d34", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/support/Ahem.ttf": [ diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml index c83f5a03ce21..33057bf5f0f8 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml @@ -138,5 +138,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml index 96fc4cd0a448..bb0a8cda64b1 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml @@ -147,5 +147,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001b.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001b.xhtml index 0f2a25426b3a..a1e192102ea9 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001b.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001b.xhtml @@ -148,5 +148,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001-ref.xhtml index ab407a42e21e..1bac2bcda1df 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001-ref.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001-ref.xhtml @@ -141,5 +141,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml index e8319cb75381..c4236ef0406c 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001a.xhtml @@ -147,5 +147,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001b.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001b.xhtml index a2e7ae6fb8ad..54a8ed31f963 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001b.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-vert-001b.xhtml @@ -148,5 +148,33 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml new file mode 100644 index 000000000000..2902a09c1637 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001-ref.xhtml @@ -0,0 +1,173 @@ + + + + + CSS Reftest Reference + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml new file mode 100644 index 000000000000..e0c40a725531 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-wmvert-001.xhtml @@ -0,0 +1,179 @@ + + + + + + CSS Test: Testing 'align-content' in a vertical writing-mode flex container + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002-ref.xhtml index 59d13a645440..bc73fa7f9267 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002-ref.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002-ref.xhtml @@ -22,7 +22,7 @@ .flexbox > div { float: left } .flex-start, .flex-end, .center, .baseline, .stretch, - .auto, .unspecified, .initial, .inherit { + .auto, .unspecified, .initial, .inherit, .self-start, .self-end { width: 40px; margin: 1px 2px 3px 4px; border-width: 2px 3px 4px 5px; @@ -53,6 +53,16 @@ .stretch { background: pink; } + .self-start { + background: yellow; + } + .self-end { + background: purple; + } + .wmvertrev { + writing-mode: vertical-lr; + direction: rtl; + } @@ -81,5 +91,12 @@
stretch
a b c d e f
+
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml index cddd5b455404..d1273d1f55b8 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml @@ -57,6 +57,18 @@ background: pink; align-self: stretch; } + .self-start { + background: yellow; + align-self: self-start; + } + .self-end { + background: purple; + align-self: self-end; + } + .wmvertrev { + writing-mode: vertical-lr; + direction: rtl; + } @@ -75,5 +87,12 @@
stretch
a b c d e f
+
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002-ref.xhtml index 3a5ad06a5f8d..14b456e67128 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002-ref.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002-ref.xhtml @@ -18,7 +18,8 @@ font-size: 10px; } - .flex-start, .flex-end, .center, .baseline, .stretch { + .flex-start, .flex-end, .center, .baseline, .stretch, + .self-start, .self-end { clear: both; margin: 1px 2px 3px 4px; border-width: 2px 3px 4px 5px; @@ -58,6 +59,16 @@ .stretch { background: pink; } + .self-start { + background: yellow; + float: right; + text-align: right; + } + .self-end { + background: purple; + float: left; + text-align: right; + } .clearFloats { clear: both } @@ -86,5 +97,11 @@ we use floats or inline-blocks, whose margins don't collapse. -->
a b c d e f
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002.xhtml index c45d737bfbf6..2ff89bdf5f52 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002.xhtml +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-002.xhtml @@ -56,6 +56,17 @@ background: pink; align-self: stretch; } + .self-start { + background: yellow; + align-self: self-start; + } + .self-end { + background: purple; + align-self: self-end; + } + .dirrtl { + direction: rtl; + } @@ -73,5 +84,11 @@
stretch
a b c d e f
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml new file mode 100644 index 000000000000..b0c46adcb9d7 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005-ref.xhtml @@ -0,0 +1,105 @@ + + + + + + CSS Reftest Reference + + + + +
+
start
+
a b c d e f
+
end
+
a b c d e f
+
+
+
center
+
+
+
a b c d e f
+
+
+
+
base
+
abc
+
+
stretch
+ +
a b c d e f
+
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
+ + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml new file mode 100644 index 000000000000..420c334c841e --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-vert-rtl-005.xhtml @@ -0,0 +1,92 @@ + + + + + + CSS Test: Testing the behavior of 'align-self' with a vertical flex container, with margin/padding/border on the items and with 'direction:rtl' + + + + + + +
+
start
+
a b c d e f
+
end
+
a b c d e f
+
center
+
a b c d e f
+
+
+
base
+
abc
+
stretch
+
a b c d e f
+
+
+
self-start
+
a b c d e f
+
self-end
+
a b c d e f
+
+ + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml new file mode 100644 index 000000000000..7723b5fa2080 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006-ref.xhtml @@ -0,0 +1,192 @@ + + + + + CSS Reftest Reference + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml new file mode 100644 index 000000000000..dcbe6184c7e8 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-horiz-006.xhtml @@ -0,0 +1,140 @@ + + + + + + CSS Test: Testing 'justify-content' in an auto-sized reversed horizontal flex container + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml new file mode 100644 index 000000000000..b1a5bf2a9894 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006-ref.xhtml @@ -0,0 +1,143 @@ + + + + + CSS Reftest Reference + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml new file mode 100644 index 000000000000..38a7f91d783c --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-vert-006.xhtml @@ -0,0 +1,141 @@ + + + + + + CSS Test: Testing 'justify-content' in a vertical flex container + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml new file mode 100644 index 000000000000..0b99be2f2538 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001-ref.xhtml @@ -0,0 +1,143 @@ + + + + + CSS Reftest Reference + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml new file mode 100644 index 000000000000..f676c6c1cdc5 --- /dev/null +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-justify-content-wmvert-001.xhtml @@ -0,0 +1,142 @@ + + + + + + CSS Test: Testing 'justify-content' in a vertical writing mode flex container + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/reftest.list b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/reftest.list index d2c5c47b6c93..b51226706eae 100644 --- a/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/reftest.list +++ b/testing/web-platform/tests/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/reftest.list @@ -11,6 +11,7 @@ == flexbox-align-content-horiz-001b.xhtml flexbox-align-content-horiz-001-ref.xhtml == flexbox-align-content-vert-001a.xhtml flexbox-align-content-vert-001-ref.xhtml == flexbox-align-content-vert-001b.xhtml flexbox-align-content-vert-001-ref.xhtml +== flexbox-align-content-wmvert-001.xhtml flexbox-align-content-wmvert-001-ref.xhtml # Tests for cross-axis alignment (align-self / align-items properties) == flexbox-align-self-baseline-horiz-001a.xhtml flexbox-align-self-baseline-horiz-001-ref.xhtml @@ -39,6 +40,7 @@ == flexbox-align-self-vert-rtl-002.xhtml flexbox-align-self-vert-rtl-002-ref.xhtml == flexbox-align-self-vert-rtl-003.xhtml flexbox-align-self-vert-rtl-003-ref.xhtml == flexbox-align-self-vert-rtl-004.xhtml flexbox-align-self-vert-rtl-004-ref.xhtml +== flexbox-align-self-vert-rtl-005.xhtml flexbox-align-self-vert-rtl-005-ref.xhtml == flexbox-align-items-center-nested-001.html flexbox-align-items-center-nested-001-ref.html @@ -158,12 +160,15 @@ == flexbox-justify-content-horiz-003.xhtml flexbox-justify-content-horiz-003-ref.xhtml == flexbox-justify-content-horiz-004.xhtml flexbox-justify-content-horiz-004-ref.xhtml == flexbox-justify-content-horiz-005.xhtml flexbox-justify-content-horiz-005-ref.xhtml +== flexbox-justify-content-horiz-006.xhtml flexbox-justify-content-horiz-006-ref.xhtml == flexbox-justify-content-vert-001a.xhtml flexbox-justify-content-vert-001-ref.xhtml == flexbox-justify-content-vert-001b.xhtml flexbox-justify-content-vert-001-ref.xhtml == flexbox-justify-content-vert-002.xhtml flexbox-justify-content-vert-002-ref.xhtml == flexbox-justify-content-vert-003.xhtml flexbox-justify-content-vert-003-ref.xhtml == flexbox-justify-content-vert-004.xhtml flexbox-justify-content-vert-004-ref.xhtml == flexbox-justify-content-vert-005.xhtml flexbox-justify-content-vert-005-ref.xhtml +== flexbox-justify-content-vert-006.xhtml flexbox-justify-content-vert-006-ref.xhtml +== flexbox-justify-content-wmvert-001.xhtml flexbox-justify-content-wmvert-001-ref.xhtml # Tests for flexbox with margin, border, and/or padding on flex items == flexbox-margin-auto-horiz-001.xhtml flexbox-margin-auto-horiz-001-ref.xhtml From b3dd9f7dce6f505646e19dd958848c5f5a1780a6 Mon Sep 17 00:00:00 2001 From: Peter Beverloo Date: Mon, 20 Aug 2018 22:09:16 +0000 Subject: [PATCH 16/49] Bug 1483989 [wpt PR 12533] - Re-enable the Background Fetch WPT tests, a=testonly Automatic update from web-platform-testsRe-enable the Background Fetch WPT tests The flaky crashes should have been fixed now that the associated logic has been removed from the scheduler. https://chromium-review.googlesource.com/c/chromium/src/+/1165554 Bug: 869470, 869818 Change-Id: Ie077876289a28387e5f890e9a25abe5609857c14 Reviewed-on: https://chromium-review.googlesource.com/1170909 Commit-Queue: Peter Beverloo Reviewed-by: Rayan Kanso Reviewed-by: Mugdha Lakhani Cr-Commit-Position: refs/heads/master@{#583729} -- wpt-commits: f4cfe41feec71829ec58aa0bf8ef3b8bf489dc7f wpt-pr: 12533 --- testing/web-platform/meta/MANIFEST.json | 6 +++--- .../tests/background-fetch/fetch.https.window.js | 14 ++++++++------ .../tests/background-fetch/get-ids.https.window.js | 4 ++-- .../tests/background-fetch/get.https.window.js | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index fa980ded6320..53eb886188b6 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -432601,15 +432601,15 @@ "testharness" ], "background-fetch/fetch.https.window.js": [ - "f146212987a4ebb2e90edc190e9232cbd07210f9", + "843506947f7176761f0d47b9a7fa83ab187322b1", "testharness" ], "background-fetch/get-ids.https.window.js": [ - "28f5bc3132b7209c343ee264fb0699184e7bb47c", + "4c8bf26190719108e65b446a34aafe0aeb1377be", "testharness" ], "background-fetch/get.https.window.js": [ - "0b272dbaa4961b73049325f7826713682b590f8c", + "a0b2acd4a6955274e3e05e9666f0c6182f07404f", "testharness" ], "background-fetch/idlharness.https.any.js": [ diff --git a/testing/web-platform/tests/background-fetch/fetch.https.window.js b/testing/web-platform/tests/background-fetch/fetch.https.window.js index f146212987a4..843506947f71 100644 --- a/testing/web-platform/tests/background-fetch/fetch.https.window.js +++ b/testing/web-platform/tests/background-fetch/fetch.https.window.js @@ -8,8 +8,8 @@ promise_test(async test => { // 6.3.1.9.2: If |registration|’s active worker is null, then reject promise // with a TypeError and abort these steps. - const script = 'resources/sw.js'; - const scope = 'resources/scope' + location.pathname; + const script = 'service_workers/sw.js'; + const scope = 'service_workers/' + location.pathname; const serviceWorkerRegistration = await service_worker_unregister_and_register(test, script, scope); @@ -21,7 +21,7 @@ promise_test(async test => { await promise_rejects( test, new TypeError(), serviceWorkerRegistration.backgroundFetch.fetch( - uniqueId(), ['resources/sw.js']), + uniqueId(), ['resources/feature-name.txt']), 'fetch() must reject on pending and installing workers'); }, 'Background Fetch requires an activated Service Worker'); @@ -44,7 +44,9 @@ backgroundFetchTest(async (test, backgroundFetch) => { // 6.3.1.7.2: If |internalRequest|’s mode is "no-cors", then return a // promise rejected with a TypeError. { - const request = new Request('resources/sw.js', {mode: 'no-cors'}); + const request = + new Request('resources/feature-name.txt', {mode: 'no-cors'}); + await promise_rejects( test, new TypeError(), backgroundFetch.fetch(uniqueId(), request), 'Requests must not be in no-cors mode'); @@ -56,8 +58,8 @@ backgroundFetchTest(async (test, backgroundFetch) => { // 6.3.1.9.2: If |bgFetchMap[id]| exists, reject |promise| with a TypeError // and abort these steps. return promise_rejects(test, new TypeError(), Promise.all([ - backgroundFetch.fetch('my-id', 'resources/sw.js'), - backgroundFetch.fetch('my-id', 'resources/feature-name.txt') + backgroundFetch.fetch('my-id', 'resources/feature-name.txt?1'), + backgroundFetch.fetch('my-id', 'resources/feature-name.txt?2') ])); }, 'IDs must be unique among active Background Fetch registrations'); diff --git a/testing/web-platform/tests/background-fetch/get-ids.https.window.js b/testing/web-platform/tests/background-fetch/get-ids.https.window.js index 28f5bc3132b7..4c8bf2619071 100644 --- a/testing/web-platform/tests/background-fetch/get-ids.https.window.js +++ b/testing/web-platform/tests/background-fetch/get-ids.https.window.js @@ -8,8 +8,8 @@ // https://wicg.github.io/background-fetch/#background-fetch-manager-getIds promise_test(async test => { - const script = 'resources/sw.js'; - const scope = 'resources/scope' + location.pathname; + const script = 'service_workers/sw.js'; + const scope = 'service_workers/' + location.pathname; const serviceWorkerRegistration = await service_worker_unregister_and_register(test, script, scope); diff --git a/testing/web-platform/tests/background-fetch/get.https.window.js b/testing/web-platform/tests/background-fetch/get.https.window.js index 0b272dbaa496..a0b2acd4a695 100644 --- a/testing/web-platform/tests/background-fetch/get.https.window.js +++ b/testing/web-platform/tests/background-fetch/get.https.window.js @@ -8,8 +8,8 @@ // https://wicg.github.io/background-fetch/#background-fetch-manager-get promise_test(async test => { - const script = 'resources/sw.js'; - const scope = 'resources/scope' + location.pathname; + const script = 'service_workers/sw.js'; + const scope = 'service_workers/' + location.pathname; const serviceWorkerRegistration = await service_worker_unregister_and_register(test, script, scope); From 5ea57c31bbb35f167f42a6eab0ece70718bf020a Mon Sep 17 00:00:00 2001 From: Xida Chen Date: Mon, 20 Aug 2018 22:09:32 +0000 Subject: [PATCH 17/49] Bug 1483997 [wpt PR 12536] - Revert "[css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set.", a=testonly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatic update from web-platform-testsRevert "[css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set." This reverts commit b786c57cab4e93f6736fecfcc986c36dfbddd507. Reason for revert: layout test failed: https://ci.chromium.org/buildbot/chromium.webkit/WebKit%20Linux%20Trusty%20ASAN/15210 Original change's description: > [css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set. > > In StyleValueToCSSValue, when checking whether a certain CSSStyleValue > matches the property in question, we now ask the registration (via > CSSOMTypes) if the CSSStyleValue matches. If it doesn't match, we throw > a TypeError like for normal properties. If it does match, the CSSStyleValue > is stringified, tokenized, and set on the style rule as tokens. > > I have postponed support for and , because > CSSUnsupportedStyleValue currently does not handle registered custom > properties at all. This is appropriate to fix in a separate CL. > > Note that, because the string version of StylePropertyMap.set also uses > StyleValueToCSSValue, it will no longer be possible to set registered > custom properties with a string--even if the syntax is matched. > A subsequent CL will fix this. > > R=​futhark@chromium.org > > Bug: 641877 > Change-Id: Ie0cc2f87e39f8f59015824bfd1b81efaf402c326 > Reviewed-on: https://chromium-review.googlesource.com/1175822 > Commit-Queue: Anders Ruud > Reviewed-by: Rune Lillesveen > Cr-Commit-Position: refs/heads/master@{#583695} TBR=futhark@chromium.org,andruud@chromium.org Change-Id: I2486be60ce81497253bdf64903ea870832a0ef9e No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: 641877 Reviewed-on: https://chromium-review.googlesource.com/1178503 Reviewed-by: Xida Chen Commit-Queue: Xida Chen Cr-Commit-Position: refs/heads/master@{#583747} -- wpt-commits: 5e22f7526ccd18de75184a12dc835cc23d3ea0be wpt-pr: 12536 --- testing/web-platform/meta/MANIFEST.json | 2 +- .../typedom.tentative.html | 154 +----------------- 2 files changed, 9 insertions(+), 147 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 53eb886188b6..41927df40f5b 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -540073,7 +540073,7 @@ "support" ], "css/css-properties-values-api/typedom.tentative.html": [ - "69ebf7a13d8cf3d71413259db68336368e5032e7", + "065280614cca9fa52b79c28e253c30ada188a1b9", "testharness" ], "css/css-properties-values-api/unit-cycles.html": [ diff --git a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html index 69ebf7a13d8c..065280614cca 100644 --- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html +++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html @@ -1,13 +1,11 @@ - + - +
From 0f023d83dc5bf3e13d000d946448343cd9919ce4 Mon Sep 17 00:00:00 2001 From: Peter Beverloo Date: Mon, 20 Aug 2018 22:09:49 +0000 Subject: [PATCH 18/49] Bug 1484002 [wpt PR 12537] - Remove the Budget API tests, a=testonly Automatic update from web-platform-testsRemove the Budget API tests (#12537) The specification has been made obsolete with no existing implementations. We can revive these tests from history if that changes. https://wicg.github.io/budget-api/ -- wpt-commits: d617cdbf1278785ebcfd949be18231b7fc0eebed wpt-pr: 12537 --- testing/web-platform/meta/MANIFEST.json | 32 ------------------- .../web-platform/tests/budget-api/META.yml | 3 -- .../tests/budget-api/idlharness.https.any.js | 24 -------------- .../tests/interfaces/budget-api.idl | 32 ------------------- 4 files changed, 91 deletions(-) delete mode 100644 testing/web-platform/tests/budget-api/META.yml delete mode 100644 testing/web-platform/tests/budget-api/idlharness.https.any.js delete mode 100644 testing/web-platform/tests/interfaces/budget-api.idl diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 41927df40f5b..411cda07cd61 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -195642,11 +195642,6 @@ {} ] ], - "budget-api/META.yml": [ - [ - {} - ] - ], "check_stability.ini": [ [ {} @@ -289472,11 +289467,6 @@ {} ] ], - "interfaces/budget-api.idl": [ - [ - {} - ] - ], "interfaces/clipboard-apis.idl": [ [ {} @@ -324475,16 +324465,6 @@ } ] ], - "budget-api/idlharness.https.any.js": [ - [ - "/budget-api/idlharness.https.any.html", - {} - ], - [ - "/budget-api/idlharness.https.any.worker.html", - {} - ] - ], "clear-site-data/executionContexts.sub.html": [ [ "/clear-site-data/executionContexts.sub.html", @@ -433584,14 +433564,6 @@ "4868127465adfe8ec405d843de9fc115d725c280", "testharness" ], - "budget-api/META.yml": [ - "6cc0000f6ff7547e1b1bc635cbd0cabf0754675a", - "support" - ], - "budget-api/idlharness.https.any.js": [ - "335c7a60a4dc8daecd3a2b28b86438698ac06484", - "testharness" - ], "check_stability.ini": [ "b939328be1cb69c3dcc47495930ba0df28b2bad2", "support" @@ -606552,10 +606524,6 @@ "c5e3465c59fcfadba79803f7baf1853c2c48e06b", "support" ], - "interfaces/budget-api.idl": [ - "fc86f415aeafd7df596d9607823b934f01e52f7a", - "support" - ], "interfaces/clipboard-apis.idl": [ "e48ca6a5e46330ca75faf8fb38b636358c353dbb", "support" diff --git a/testing/web-platform/tests/budget-api/META.yml b/testing/web-platform/tests/budget-api/META.yml deleted file mode 100644 index 6cc0000f6ff7..000000000000 --- a/testing/web-platform/tests/budget-api/META.yml +++ /dev/null @@ -1,3 +0,0 @@ -spec: https://wicg.github.io/budget-api/ -suggested_reviewers: - - beverloo diff --git a/testing/web-platform/tests/budget-api/idlharness.https.any.js b/testing/web-platform/tests/budget-api/idlharness.https.any.js deleted file mode 100644 index 335c7a60a4dc..000000000000 --- a/testing/web-platform/tests/budget-api/idlharness.https.any.js +++ /dev/null @@ -1,24 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -'use strict'; - -// See https://wicg.github.io/budget-api/ - -idl_test( - ['budget-api'], - ['html'], - async idl_array => { - idl_array.add_objects({ BudgetService: ['navigator.budget'] }); - if (self.Window) { - idl_array.add_objects({ Navigator: ['navigator'] }); - } else { - idl_array.add_objects({ WorkerNavigator: ['navigator'] }); - } - const budgetStates = await navigator.budget.getBudget(); - if (budgetStates.length) { - self.budgetState = budgetStates[0]; - idl_array.add_objects({ BudgetState: ['budgetState'] }); - } - } -); diff --git a/testing/web-platform/tests/interfaces/budget-api.idl b/testing/web-platform/tests/interfaces/budget-api.idl deleted file mode 100644 index fc86f415aeaf..000000000000 --- a/testing/web-platform/tests/interfaces/budget-api.idl +++ /dev/null @@ -1,32 +0,0 @@ -// GENERATED CONTENT - DO NOT EDIT -// Content was automatically extracted by Reffy into reffy-reports -// (https://github.com/tidoust/reffy-reports) -// Source: Web Budget API (https://wicg.github.io/budget-api/) - -[Exposed=Window] -partial interface Navigator { - [SameObject] readonly attribute BudgetService budget; -}; - -[Exposed=Worker] -partial interface WorkerNavigator { - [SameObject] readonly attribute BudgetService budget; -}; - -[Exposed=(Window,Worker)] -interface BudgetService { - Promise getCost(OperationType operation); - Promise> getBudget(); - - Promise reserve(OperationType operation); -}; - -[Exposed=(Window,Worker)] -interface BudgetState { - readonly attribute double budgetAt; - readonly attribute DOMTimeStamp time; -}; - -enum OperationType { - "silent-push" -}; From a3751c379392ed270d4f51d606e51e066e14b5f1 Mon Sep 17 00:00:00 2001 From: Javier Fernandez Date: Mon, 20 Aug 2018 22:10:06 +0000 Subject: [PATCH 19/49] Bug 1483770 [wpt PR 12512] - [css-grid] Distribution offset doesn't account for non-spanning items, a=testonly Automatic update from web-platform-tests[css-grid] Distribution offset doesn't account for non-spanning items We recenttly changed the track sizing algorithm so that it considers the offsets added by the Content Alignment properties. The change in r566412 introduce intermediate steps in the track sizing algorithm so that inline-axis Content Distribution accounts for the row tracks sizes computed in the next step. However, we were adding the Content Distribution offsets for any column track, but we should do it only for the tracks with spanning items. This error led to the mentioned bugs and this change fixes them. Bug: 871230, 871242 Change-Id: I8ac789ccacc2e5a51bfafd7820ed08e96a31e58b Reviewed-on: https://chromium-review.googlesource.com/1176803 Reviewed-by: Sergio Villar Commit-Queue: Javier Fernandez Cr-Commit-Position: refs/heads/master@{#583802} -- wpt-commits: 676265b89417b09c27d94a2a8538a88a34821e88 wpt-pr: 12512 --- testing/web-platform/meta/MANIFEST.json | 20 ++++++++++ ...ion-must-account-for-track-sizing-003.html | 39 +++++++++++++++++++ ...ion-must-account-for-track-sizing-004.html | 39 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html create mode 100644 testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 411cda07cd61..c12d4c644128 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -331141,6 +331141,18 @@ {} ] ], + "css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html": [ + [ + "/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html", + {} + ] + ], + "css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html": [ + [ + "/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html", + {} + ] + ], "css/css-grid/layout-algorithm/grid-find-fr-size-gutters-001.html": [ [ "/css/css-grid/layout-algorithm/grid-find-fr-size-gutters-001.html", @@ -535724,6 +535736,14 @@ "14ad64d7a0875af3c2781edd68246d742deb067d", "testharness" ], + "css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html": [ + "2ba9671f24dcd2d94d0cb48e734ee10182bf071a", + "testharness" + ], + "css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html": [ + "e6de4730a6d2fbd92248ecdfeff5d2e1e1daf6a4", + "testharness" + ], "css/css-grid/layout-algorithm/grid-find-fr-size-gutters-001.html": [ "25d236cebc65133a40538982ff040b97a71d8738", "testharness" diff --git a/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html new file mode 100644 index 000000000000..2ba9671f24dc --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-003.html @@ -0,0 +1,39 @@ + + +CSS Grid Layout Test: Content Distribution and the track sizing algorithm + + + + + + + + + + + + + +
+
XXXX XXX
+
XXX
+
+ diff --git a/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html new file mode 100644 index 000000000000..e6de4730a6d2 --- /dev/null +++ b/testing/web-platform/tests/css/css-grid/layout-algorithm/grid-content-distribution-must-account-for-track-sizing-004.html @@ -0,0 +1,39 @@ + + +CSS Grid Layout Test: Content Distribution and the track sizing algorithm + + + + + + + + + + + + + +
+
XXXX XXX
+
XXX
+
+ From 13bf4d6386fa8373e47566eafc8e7b20b574862d Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Mon, 20 Aug 2018 22:10:23 +0000 Subject: [PATCH 20/49] Bug 1482457 [wpt PR 12413] - Implement ignore-opens-during-unload counter in Document, a=testonly Automatic update from web-platform-testsImplement ignore-opens-during-unload counter in Document The removed test fast/loader/document-destruction-within-unload.html was originally added in 8809405d796cf3023e26cefd4b06f369eb67f125, to make sure that a document.write() call that blows away the current page still works in unload event listeners and blocks any current attempt to navigate. Since we no longer allow that to happen, the test is obsolete. In fact, it can be seen as contradictory to external/wpt/html/browsers/browsing-the-web/unloading-documents/005.html, which tests that document.open() in an unload event doesn't block navigation. Bug: 583586, 866274 Change-Id: I99b35dd28c97e8603455805b31d49644bc7b23a5 Reviewed-on: https://chromium-review.googlesource.com/1169320 Commit-Queue: Timothy Gu Reviewed-by: Daniel Cheng Reviewed-by: Nate Chapin Cr-Commit-Position: refs/heads/master@{#583836} -- wpt-commits: d44f0f56d5d7d5d4b9e50be0ad2c4331f81c7bf7 wpt-pr: 12413 --- testing/web-platform/meta/MANIFEST.json | 2 +- .../ignore-opens-during-unload.window.js | 51 +++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index c12d4c644128..e555a8b69904 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -605361,7 +605361,7 @@ "testharness" ], "html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js": [ - "5de4b1421b5ef10adecb10a2d5bda0d3a2c2711c", + "43506a22a46da53885a2b5a0888095bc52b460ca", "testharness" ], "html/webappapis/dynamic-markup-insertion/opening-the-input-stream/mutation-events.window.js": [ diff --git a/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js b/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js index 5de4b1421b5e..43506a22a46d 100644 --- a/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js +++ b/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js @@ -1,15 +1,60 @@ -for (const ev of ["unload", "beforeunload", "pagehide"]) { +for (const [ev, target] of [ + ["beforeunload", iframe => iframe.contentWindow], + ["pagehide", iframe => iframe.contentWindow], + ["unload", iframe => iframe.contentWindow], + ["visibilitychange", iframe => iframe.contentDocument], +]) { async_test(t => { const iframe = document.body.appendChild(document.createElement("iframe")); t.add_cleanup(() => iframe.remove()); iframe.src = "/common/blank.html"; iframe.onload = t.step_func(() => { - iframe.contentWindow.addEventListener(ev, t.step_func_done(() => { + target(iframe).addEventListener(ev, t.step_func_done(() => { assert_not_equals(iframe.contentDocument.childNodes.length, 0); assert_equals(iframe.contentDocument.open(), iframe.contentDocument); assert_not_equals(iframe.contentDocument.childNodes.length, 0); })); iframe.src = "about:blank"; }); - }, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event`); + }, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (in top-level browsing context)`); + + async_test(t => { + const iframe = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => iframe.remove()); + iframe.src = "/common/blank.html?1"; + iframe.onload = t.step_func(() => { + const doc = iframe.contentDocument; + const innerIframe = doc.body.appendChild(doc.createElement("iframe")); + innerIframe.src = "/common/blank.html?2"; + innerIframe.onload = t.step_func(() => { + // Navigate the parent, listen on the child, and open() the parent. + target(innerIframe).addEventListener(ev, t.step_func_done(() => { + assert_not_equals(iframe.contentDocument.childNodes.length, 0); + iframe.contentDocument.open(); + assert_not_equals(iframe.contentDocument.childNodes.length, 0); + })); + iframe.src = "about:blank"; + }); + }); + }, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading parent and child)`); + + async_test(t => { + const iframe = document.body.appendChild(document.createElement("iframe")); + t.add_cleanup(() => iframe.remove()); + iframe.src = "/common/blank.html?1"; + iframe.onload = t.step_func(() => { + const doc = iframe.contentDocument; + const innerIframe = doc.body.appendChild(doc.createElement("iframe")); + innerIframe.src = "/common/blank.html?2"; + innerIframe.onload = t.step_func(() => { + // Navigate the child, listen on the child, and open() the parent. + target(innerIframe).addEventListener(ev, t.step_func_done(() => { + assert_not_equals(iframe.contentDocument.childNodes.length, 0); + iframe.contentDocument.open(); + assert_equals(iframe.contentDocument.childNodes.length, 0); + })); + innerIframe.src = "about:blank"; + }); + }); + }, `document.open should bail out when ignore-opens-during-unload is greater than 0 during ${ev} event (open(parent) while unloading child only)`); } From c41d1d01b5fb9c37087dff9a0a62402aa2bfcd81 Mon Sep 17 00:00:00 2001 From: moz-wptsync-bot Date: Thu, 16 Aug 2018 21:50:35 +0000 Subject: [PATCH 21/49] Bug 1482457 [wpt PR 12413] - Update wpt metadata, a=testonly wpt-pr: 12413 wpt-type: metadata --- .../ignore-opens-during-unload.window.js.ini | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini diff --git a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini new file mode 100644 index 000000000000..a54f11232a84 --- /dev/null +++ b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini @@ -0,0 +1,5 @@ +[ignore-opens-during-unload.window.html] + expected: + if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH + if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH + if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH From c47be691bd04feeead359e91b20b986343be7992 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Mon, 20 Aug 2018 22:10:42 +0000 Subject: [PATCH 22/49] Bug 1483994 [wpt PR 12535] - Revert "Cache Storage: Check for duplicate entries in Cache.addAll().", a=testonly Automatic update from web-platform-testsRevert "Cache Storage: Check for duplicate entries in Cache.addAll()." This reverts commit 74fd352e51322e823070088c7d5c72e911966580. Reason for revert: Moving behind experimental feature flag until web compat can be assessed. Original change's description: > Cache Storage: Check for duplicate entries in Cache.addAll(). > > This implements step 4.2.3 of the BatchCacheOperations algorithm: > > https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm > > Bug: 720919 > Change-Id: I679f786441b813ed816a183522021c417f4ab7b8 > Reviewed-on: https://chromium-review.googlesource.com/1162362 > Commit-Queue: Ben Kelly > Reviewed-by: Joshua Bell > Reviewed-by: Kinuko Yasuda > Reviewed-by: Victor Costan > Cr-Commit-Position: refs/heads/master@{#582738} TBR=jsbell@chromium.org,kinuko@chromium.org,pwnall@chromium.org,wanderview@chromium.org # Not skipping CQ checks because original CL landed > 1 day ago. Bug: 720919 Change-Id: I08736e4ec638a65c48f329966f378698a6d9b045 Reviewed-on: https://chromium-review.googlesource.com/1178502 Reviewed-by: Victor Costan Commit-Queue: Ben Kelly Cr-Commit-Position: refs/heads/master@{#583849} -- wpt-commits: 2dda7b8c10c7566fa6167a32b09c85d51baf2a85 wpt-pr: 12535 --- testing/web-platform/meta/MANIFEST.json | 11 +-- .../cache-storage/resources/vary.py | 25 ------ .../cache-storage/script-tests/cache-add.js | 80 ------------------- 3 files changed, 1 insertion(+), 115 deletions(-) delete mode 100644 testing/web-platform/tests/service-workers/cache-storage/resources/vary.py diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index e555a8b69904..f7fbfd1915a6 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -298592,11 +298592,6 @@ {} ] ], - "service-workers/cache-storage/resources/vary.py": [ - [ - {} - ] - ], "service-workers/cache-storage/script-tests/cache-abort.js": [ [ {} @@ -630100,16 +630095,12 @@ "050ac0b542455ceb53ed36038af5b9b0810977cf", "support" ], - "service-workers/cache-storage/resources/vary.py": [ - "59e39bc2ae730a4cd3e1376dd003c9ffada4ed4a", - "support" - ], "service-workers/cache-storage/script-tests/cache-abort.js": [ "ec4130fded29e0070828092c2546dc46456d8fdc", "support" ], "service-workers/cache-storage/script-tests/cache-add.js": [ - "a482c42eaeb2a902a36b1d6aecd306e8ed4b4ebf", + "c03faeb0e83723eab64e648e600ba0612873d404", "support" ], "service-workers/cache-storage/script-tests/cache-delete.js": [ diff --git a/testing/web-platform/tests/service-workers/cache-storage/resources/vary.py b/testing/web-platform/tests/service-workers/cache-storage/resources/vary.py deleted file mode 100644 index 59e39bc2ae73..000000000000 --- a/testing/web-platform/tests/service-workers/cache-storage/resources/vary.py +++ /dev/null @@ -1,25 +0,0 @@ -def main(request, response): - if "clear-vary-value-override-cookie" in request.GET: - response.unset_cookie("vary-value-override") - return "vary cookie cleared" - - set_cookie_vary = request.GET.first("set-vary-value-override-cookie", - default="") - if set_cookie_vary: - response.set_cookie("vary-value-override", set_cookie_vary) - return "vary cookie set" - - # If there is a vary-value-override cookie set, then use its value - # for the VARY header no matter what the query string is set to. This - # override is necessary to test the case when two URLs are identical - # (including query), but differ by VARY header. - cookie_vary = request.cookies.get("vary-value-override"); - if cookie_vary: - response.headers.set("vary", cookie_vary) - else: - # If there is no cookie, then use the query string value, if present. - query_vary = request.GET.first("vary", default="") - if query_vary: - response.headers.set("vary", query_vary) - - return "vary response" diff --git a/testing/web-platform/tests/service-workers/cache-storage/script-tests/cache-add.js b/testing/web-platform/tests/service-workers/cache-storage/script-tests/cache-add.js index a482c42eaeb2..c03faeb0e837 100644 --- a/testing/web-platform/tests/service-workers/cache-storage/script-tests/cache-add.js +++ b/testing/web-platform/tests/service-workers/cache-storage/script-tests/cache-add.js @@ -267,84 +267,4 @@ cache_test(function(cache, test) { 'twice.'); }, 'Cache.addAll called with the same Request object specified twice'); -cache_test(async function(cache, test) { - const url = '../resources/vary.py?vary=x-shape'; - let requests = [ - new Request(url, { headers: { 'x-shape': 'circle' }}), - new Request(url, { headers: { 'x-shape': 'square' }}), - ]; - let result = await cache.addAll(requests); - assert_equals(result, undefined, 'Cache.addAll() should succeed'); - }, 'Cache.addAll should succeed when entries differ by vary header'); - -cache_test(async function(cache, test) { - const url = '../resources/vary.py?vary=x-shape'; - let requests = [ - new Request(url, { headers: { 'x-shape': 'circle' }}), - new Request(url, { headers: { 'x-shape': 'circle' }}), - ]; - await promise_rejects( - test, - 'InvalidStateError', - cache.addAll(requests), - 'Cache.addAll() should reject when entries are duplicate by vary header'); - }, 'Cache.addAll should reject when entries are duplicate by vary header'); - -// VARY header matching is asymmetric. Determining if two entries are duplicate -// depends on which entry's response is used in the comparison. The target -// response's VARY header determines what request headers are examined. This -// test verifies that Cache.addAll() duplicate checking handles this asymmetric -// behavior correctly. -cache_test(async function(cache, test) { - const base_url = '../resources/vary.py'; - - // Define a request URL that sets a VARY header in the - // query string to be echoed back by the server. - const url = base_url + '?vary=x-size'; - - // Set a cookie to override the VARY header of the response - // when the request is made with credentials. This will - // take precedence over the query string vary param. This - // is a bit confusing, but it's necessary to construct a test - // where the URL is the same, but the VARY headers differ. - // - // Note, the test could also pass this information in additional - // request headers. If the cookie approach becomes too unwieldy - // this test could be rewritten to use that technique. - await fetch(base_url + '?set-vary-value-override-cookie=x-shape'); - test.add_cleanup(_ => fetch(base_url + '?clear-vary-value-override-cookie')); - - let requests = [ - // This request will result in a Response with a "Vary: x-shape" - // header. This *will not* result in a duplicate match with the - // other entry. - new Request(url, { headers: { 'x-shape': 'circle', - 'x-size': 'big' }, - credentials: 'same-origin' }), - - // This request will result in a Response with a "Vary: x-size" - // header. This *will* result in a duplicate match with the other - // entry. - new Request(url, { headers: { 'x-shape': 'square', - 'x-size': 'big' }, - credentials: 'omit' }), - ]; - await promise_rejects( - test, - 'InvalidStateError', - cache.addAll(requests), - 'Cache.addAll() should reject when one entry has a vary header ' + - 'matching an earlier entry.'); - - // Test the reverse order now. - await promise_rejects( - test, - 'InvalidStateError', - cache.addAll(requests.reverse()), - 'Cache.addAll() should reject when one entry has a vary header ' + - 'matching a later entry.'); - - }, 'Cache.addAll should reject when one entry has a vary header ' + - 'matching another entry'); - done(); From 9f7bc78a1fac22dc5d0b686c91353e78b37dd5e7 Mon Sep 17 00:00:00 2001 From: Mike West Date: Mon, 20 Aug 2018 22:10:59 +0000 Subject: [PATCH 23/49] Bug 1484150 [wpt PR 12543] - Fix cookie prefix tests., a=testonly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatic update from web-platform-testsFix cookie prefix tests. The layout tests aren't testing much at the moment, as they're never served over HTTPS. This patch creates `.https` versions of the tests and reworks them to actually exercise the behavior of `__Host` and `__Secure` cookie prefixes. Bug: 843945 Change-Id: I31968133ca8846f3ffc4faec2339e3d0d03c77f8 Reviewed-on: https://chromium-review.googlesource.com/1179150 Commit-Queue: Mike West Reviewed-by: Mike West Reviewed-by: Philip Jägenstedt Cr-Commit-Position: refs/heads/master@{#584016} -- wpt-commits: 4205ee12965bea420482d4d08cbac00b44cbad90 wpt-pr: 12543 --HG-- rename : testing/web-platform/tests/cookies/prefix/__host.document-cookie.non-secure.html => testing/web-platform/tests/cookies/prefix/__host.document-cookie.html --- testing/web-platform/meta/MANIFEST.json | 82 ++++++++++++------- ...ecure.html => __host.document-cookie.html} | 0 .../prefix/__host.document-cookie.https.html | 42 ++++++++++ ...ttp.non-secure.html => __host.header.html} | 15 +++- .../cookies/prefix/__host.header.https.html | 43 ++++++++++ ...ure.html => __secure.document-cookie.html} | 6 +- .../__secure.document-cookie.https.html | 25 ++++++ ...p.non-secure.html => __secure.header.html} | 8 +- ...secure.html => __secure.header.https.html} | 8 +- .../prefix/document-cookie.non-secure.html | 2 +- .../cookies/resources/cookie-helper.sub.js | 24 ++---- .../tests/cookies/secure/cookie-forcing.html | 46 ----------- 12 files changed, 187 insertions(+), 114 deletions(-) rename testing/web-platform/tests/cookies/prefix/{__host.document-cookie.non-secure.html => __host.document-cookie.html} (100%) create mode 100644 testing/web-platform/tests/cookies/prefix/__host.document-cookie.https.html rename testing/web-platform/tests/cookies/prefix/{__host.http.non-secure.html => __host.header.html} (57%) create mode 100644 testing/web-platform/tests/cookies/prefix/__host.header.https.html rename testing/web-platform/tests/cookies/prefix/{__secure.document-cookie.non-secure.html => __secure.document-cookie.html} (69%) create mode 100644 testing/web-platform/tests/cookies/prefix/__secure.document-cookie.https.html rename testing/web-platform/tests/cookies/prefix/{__secure.http.non-secure.html => __secure.header.html} (71%) rename testing/web-platform/tests/cookies/prefix/{__secure.http.secure.html => __secure.header.https.html} (69%) delete mode 100644 testing/web-platform/tests/cookies/secure/cookie-forcing.html diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index f7fbfd1915a6..15a5bd9ef777 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -327374,33 +327374,51 @@ {} ] ], - "cookies/prefix/__host.document-cookie.non-secure.html": [ + "cookies/prefix/__host.document-cookie.html": [ [ - "/cookies/prefix/__host.document-cookie.non-secure.html", + "/cookies/prefix/__host.document-cookie.html", {} ] ], - "cookies/prefix/__host.http.non-secure.html": [ + "cookies/prefix/__host.document-cookie.https.html": [ [ - "/cookies/prefix/__host.http.non-secure.html", + "/cookies/prefix/__host.document-cookie.https.html", {} ] ], - "cookies/prefix/__secure.document-cookie.non-secure.html": [ + "cookies/prefix/__host.header.html": [ [ - "/cookies/prefix/__secure.document-cookie.non-secure.html", + "/cookies/prefix/__host.header.html", {} ] ], - "cookies/prefix/__secure.http.non-secure.html": [ + "cookies/prefix/__host.header.https.html": [ [ - "/cookies/prefix/__secure.http.non-secure.html", + "/cookies/prefix/__host.header.https.html", {} ] ], - "cookies/prefix/__secure.http.secure.html": [ + "cookies/prefix/__secure.document-cookie.html": [ [ - "/cookies/prefix/__secure.http.secure.html", + "/cookies/prefix/__secure.document-cookie.html", + {} + ] + ], + "cookies/prefix/__secure.document-cookie.https.html": [ + [ + "/cookies/prefix/__secure.document-cookie.https.html", + {} + ] + ], + "cookies/prefix/__secure.header.html": [ + [ + "/cookies/prefix/__secure.header.html", + {} + ] + ], + "cookies/prefix/__secure.header.https.html": [ + [ + "/cookies/prefix/__secure.header.https.html", {} ] ], @@ -327470,12 +327488,6 @@ {} ] ], - "cookies/secure/cookie-forcing.html": [ - [ - "/cookies/secure/cookie-forcing.html", - {} - ] - ], "cookies/secure/create-cookie-http.html": [ [ "/cookies/secure/create-cookie-http.html", @@ -454803,32 +454815,44 @@ "14921d1d62c0d80349cf1149e55e3af0b51f77d5", "testharness" ], - "cookies/prefix/__host.document-cookie.non-secure.html": [ + "cookies/prefix/__host.document-cookie.html": [ "e1a272a23409b91bd80bdfe99f2f07129b4c6a0f", "testharness" ], - "cookies/prefix/__host.http.non-secure.html": [ - "3ce5873543887e7f241468a356a4ae75cf168ef3", + "cookies/prefix/__host.document-cookie.https.html": [ + "05ecdff358fd0d457f30d406be0956ebd4d128bd", "testharness" ], - "cookies/prefix/__secure.document-cookie.non-secure.html": [ - "bf898f4cebc0559994e88fd4d7aa52cdd86bc6c0", + "cookies/prefix/__host.header.html": [ + "5a522cbaa018aa607628070ab79278dd855735bd", "testharness" ], - "cookies/prefix/__secure.http.non-secure.html": [ - "af844a9587fdeb8169d854ca2568854eb219fe7c", + "cookies/prefix/__host.header.https.html": [ + "53d0dba65989164f5fcb77becd021f264822ebf7", "testharness" ], - "cookies/prefix/__secure.http.secure.html": [ - "4b413e9ce3ab5accf7b51844a8d963b810d751dd", + "cookies/prefix/__secure.document-cookie.html": [ + "a1b335b9816ff226f4568a74e5848452b9a49c6e", + "testharness" + ], + "cookies/prefix/__secure.document-cookie.https.html": [ + "89b146043807fd370dc7c4a57e658c77351e79d8", + "testharness" + ], + "cookies/prefix/__secure.header.html": [ + "431e0e1ec98923feae1f1f6948c7728e5e80b007", + "testharness" + ], + "cookies/prefix/__secure.header.https.html": [ + "d912babc239acfecef7afb6f7deac9fbfeaf50bd", "testharness" ], "cookies/prefix/document-cookie.non-secure.html": [ - "bc6832b15ea88463d0b0fdb5cea4b1987e6a6c0d", + "1b5edf76a298a18e40b3b4c3cb256b29b65f1a9a", "testharness" ], "cookies/resources/cookie-helper.sub.js": [ - "428cab042e4fd0ac3f67180587f4f42e42643049", + "49cf0b1fdbf46dc0b045d35abf32e16dcb40d184", "support" ], "cookies/resources/drop.py": [ @@ -454931,10 +454955,6 @@ "1aa8e5e80bbf4319bb3903b228416a994723b4db", "testharness" ], - "cookies/secure/cookie-forcing.html": [ - "3ea59e1369d0cf9885ed1c3f9e6548f1734a5463", - "testharness" - ], "cookies/secure/create-cookie-http.html": [ "425f66fde5cbdc231c0c96b2e2b1d4fb3f9571ba", "testharness" diff --git a/testing/web-platform/tests/cookies/prefix/__host.document-cookie.non-secure.html b/testing/web-platform/tests/cookies/prefix/__host.document-cookie.html similarity index 100% rename from testing/web-platform/tests/cookies/prefix/__host.document-cookie.non-secure.html rename to testing/web-platform/tests/cookies/prefix/__host.document-cookie.html diff --git a/testing/web-platform/tests/cookies/prefix/__host.document-cookie.https.html b/testing/web-platform/tests/cookies/prefix/__host.document-cookie.https.html new file mode 100644 index 000000000000..05ecdff358fd --- /dev/null +++ b/testing/web-platform/tests/cookies/prefix/__host.document-cookie.https.html @@ -0,0 +1,42 @@ + + + + + diff --git a/testing/web-platform/tests/cookies/prefix/__host.http.non-secure.html b/testing/web-platform/tests/cookies/prefix/__host.header.html similarity index 57% rename from testing/web-platform/tests/cookies/prefix/__host.http.non-secure.html rename to testing/web-platform/tests/cookies/prefix/__host.header.html index 3ce587354388..5a522cbaa018 100644 --- a/testing/web-platform/tests/cookies/prefix/__host.http.non-secure.html +++ b/testing/web-platform/tests/cookies/prefix/__host.header.html @@ -10,7 +10,7 @@ params: "Path=/;" + extraParams, shouldExistInDOM: false, shouldExistViaHTTP: false, - title: "__Host: Non-secure origin: 'Path=/;" + extraParams + "'" + title: "__Host: Non-secure origin: Does not set 'Path=/;" + extraParams + "'" }); // With 'secure' @@ -19,7 +19,16 @@ params: "Secure; Path=/;" + extraParams, shouldExistInDOM: false, shouldExistViaHTTP: false, - title: "__Host: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + title: "__Host: Non-secure origin: Does not set 'Secure; Path=/;" + extraParams + "'" + }); + + // With 'domain' + set_prefixed_cookie_via_http_test({ + prefix: "__Host-", + params: "Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Secure origin: Does not set 'Secure; Path=/; Domain=" + document.location.hostname + "; " + extraParams + "'" }); }); @@ -28,7 +37,7 @@ params: "Secure; Path=/cookies/resources/list.py", shouldExistInDOM: false, shouldExistViaHTTP: false, - title: "__Host: Non-secure origin: 'Secure; Path=/cookies/resources/list.py'" + title: "__Host: Non-secure origin: Does not set 'Secure; Path=/cookies/resources/list.py'" }); diff --git a/testing/web-platform/tests/cookies/prefix/__host.header.https.html b/testing/web-platform/tests/cookies/prefix/__host.header.https.html new file mode 100644 index 000000000000..53d0dba65989 --- /dev/null +++ b/testing/web-platform/tests/cookies/prefix/__host.header.https.html @@ -0,0 +1,43 @@ + + + + + + diff --git a/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.non-secure.html b/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.html similarity index 69% rename from testing/web-platform/tests/cookies/prefix/__secure.document-cookie.non-secure.html rename to testing/web-platform/tests/cookies/prefix/__secure.document-cookie.html index bf898f4cebc0..a1b335b9816f 100644 --- a/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.non-secure.html +++ b/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.html @@ -3,14 +3,14 @@ diff --git a/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.https.html b/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.https.html new file mode 100644 index 000000000000..89b146043807 --- /dev/null +++ b/testing/web-platform/tests/cookies/prefix/__secure.document-cookie.https.html @@ -0,0 +1,25 @@ + + + + + diff --git a/testing/web-platform/tests/cookies/prefix/__secure.http.non-secure.html b/testing/web-platform/tests/cookies/prefix/__secure.header.html similarity index 71% rename from testing/web-platform/tests/cookies/prefix/__secure.http.non-secure.html rename to testing/web-platform/tests/cookies/prefix/__secure.header.html index af844a9587fd..431e0e1ec989 100644 --- a/testing/web-platform/tests/cookies/prefix/__secure.http.non-secure.html +++ b/testing/web-platform/tests/cookies/prefix/__secure.header.html @@ -8,18 +8,16 @@ set_prefixed_cookie_via_http_test({ prefix: "__Secure-", params: "Path=/;" + extraParams, - shouldExistInDOM: false, shouldExistViaHTTP: false, - title: "__Secure: Non-secure origin: 'Path=/;" + extraParams + "'" + title: "__Secure: Non-secure origin: Should not set 'Path=/;" + extraParams + "'" }); // With 'secure' set_prefixed_cookie_via_http_test({ prefix: "__Secure-", params: "Secure; Path=/;" + extraParams, - shouldExistInDOM: false, - shouldExistViaHTTP: false, - title: "__Secure: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + shouldExistViaHTTP: true, + title: "__Secure: Non-secure origin: Should set 'Secure; Path=/;" + extraParams + "'" }); }); diff --git a/testing/web-platform/tests/cookies/prefix/__secure.http.secure.html b/testing/web-platform/tests/cookies/prefix/__secure.header.https.html similarity index 69% rename from testing/web-platform/tests/cookies/prefix/__secure.http.secure.html rename to testing/web-platform/tests/cookies/prefix/__secure.header.https.html index 4b413e9ce3ab..d912babc239a 100644 --- a/testing/web-platform/tests/cookies/prefix/__secure.http.secure.html +++ b/testing/web-platform/tests/cookies/prefix/__secure.header.https.html @@ -6,22 +6,18 @@ ["", "domain="+CROSS_SITE_HOST, "MaxAge=10", "HttpOnly"].forEach(extraParams => { // Without 'secure' set_prefixed_cookie_via_http_test({ - origin: SECURE_CROSS_SITE_ORIGIN, prefix: "__Secure-", params: "Path=/;" + extraParams, - shouldExistInDOM: false, shouldExistViaHTTP: false, - title: "__Secure: secure origin: 'Path=/;" + extraParams + "'" + title: "__Secure: secure origin: Should not set 'Path=/;" + extraParams + "'" }); // With 'secure' set_prefixed_cookie_via_http_test({ - origin: SECURE_CROSS_SITE_ORIGIN, prefix: "__Secure-", params: "Secure;Path=/;" + extraParams, - shouldExistInDOM: false, shouldExistViaHTTP: true, - title: "__Secure: secure origin: 'Secure;Path=/;" + extraParams + "'" + title: "__Secure: secure origin: Should set 'Secure;Path=/;" + extraParams + "'" }); }); diff --git a/testing/web-platform/tests/cookies/prefix/document-cookie.non-secure.html b/testing/web-platform/tests/cookies/prefix/document-cookie.non-secure.html index bc6832b15ea8..1b5edf76a298 100644 --- a/testing/web-platform/tests/cookies/prefix/document-cookie.non-secure.html +++ b/testing/web-platform/tests/cookies/prefix/document-cookie.non-secure.html @@ -12,7 +12,7 @@ assert_dom_cookie(name, value, shouldExistInDOM); - return credFetch("/cookies/rfx6265bis/resources/list.py") + return credFetch("/cookies/resources/list.py") .then(r => r.json()) .then(cookies => assert_equals(cookies[name], shouldExistViaHTTP ? value : undefined)); }, title); diff --git a/testing/web-platform/tests/cookies/resources/cookie-helper.sub.js b/testing/web-platform/tests/cookies/resources/cookie-helper.sub.js index 428cab042e4f..49cf0b1fdbf4 100644 --- a/testing/web-platform/tests/cookies/resources/cookie-helper.sub.js +++ b/testing/web-platform/tests/cookies/resources/cookie-helper.sub.js @@ -180,27 +180,13 @@ return credFetch(origin + "/cookies/resources/dropSecure.py") } // -// DOM based cookie manipulation API's +// DOM based cookie manipulation APIs // -// borrowed from http://www.quirksmode.org/js/cookies.html -function create_cookie_from_js(name, value, days, secure_flag) { - if (days) { - var date = new Date(); - date.setTime(date.getTime()+(days*24*60*60*1000)); - var expires = "; expires="+date.toGMTString(); - } - else var expires = ""; - - var secure = ""; - if (secure_flag == true) { - secure = "secure; "; - } - document.cookie = name+"="+value+expires+"; "+secure+"path=/"; -} - // erase cookie value and set for expiration function erase_cookie_from_js(name) { - create_cookie_from_js(name,"",-1); - assert_dom_cookie(name, "", false); + let secure = self.location.protocol == "https:" ? "Secure" : ""; + document.cookie = `${name}=0; path=/; expires=${new Date(0).toUTCString()}; ${secure}`; + var re = new RegExp("(?:^|; )" + name); + assert_equals(re.test(document.cookie), false, "Sanity check: " + name + " has been deleted."); } diff --git a/testing/web-platform/tests/cookies/secure/cookie-forcing.html b/testing/web-platform/tests/cookies/secure/cookie-forcing.html deleted file mode 100644 index 3ea59e1369d0..000000000000 --- a/testing/web-platform/tests/cookies/secure/cookie-forcing.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - From 8a6d3bc3fb8a4910fa7571f49633c921d5d8dc7c Mon Sep 17 00:00:00 2001 From: moz-wptsync-bot Date: Fri, 17 Aug 2018 08:06:37 +0000 Subject: [PATCH 24/49] Bug 1484150 [wpt PR 12543] - Update wpt metadata, a=testonly wpt-pr: 12543 wpt-type: metadata --- .../prefix/__secure.header.https.html.ini | 25 +++++++++++++++++++ .../document-cookie.non-secure.html.ini | 7 ------ 2 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 testing/web-platform/meta/cookies/prefix/__secure.header.https.html.ini delete mode 100644 testing/web-platform/meta/cookies/prefix/document-cookie.non-secure.html.ini diff --git a/testing/web-platform/meta/cookies/prefix/__secure.header.https.html.ini b/testing/web-platform/meta/cookies/prefix/__secure.header.https.html.ini new file mode 100644 index 000000000000..3158545fb3ba --- /dev/null +++ b/testing/web-platform/meta/cookies/prefix/__secure.header.https.html.ini @@ -0,0 +1,25 @@ +[__secure.header.https.html] + [__Secure: secure origin: Should set 'Secure;Path=/;MaxAge=10'] + expected: FAIL + + [__Secure: secure origin: Should set 'Secure;Path=/;HttpOnly'] + expected: FAIL + + [__Secure: secure origin: Should not set 'Path=/;domain=not-web-platform.test'] + expected: FAIL + + [__Secure: secure origin: Should not set 'Path=/;MaxAge=10'] + expected: FAIL + + [__Secure: secure origin: Should not set 'Path=/;HttpOnly'] + expected: FAIL + + [__Secure: secure origin: Should set 'Secure;Path=/;domain=not-web-platform.test'] + expected: FAIL + + [__Secure: secure origin: Should set 'Secure;Path=/;'] + expected: FAIL + + [__Secure: secure origin: Should not set 'Path=/;'] + expected: FAIL + diff --git a/testing/web-platform/meta/cookies/prefix/document-cookie.non-secure.html.ini b/testing/web-platform/meta/cookies/prefix/document-cookie.non-secure.html.ini deleted file mode 100644 index 1b605a516311..000000000000 --- a/testing/web-platform/meta/cookies/prefix/document-cookie.non-secure.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[document-cookie.non-secure.html] - [No prefix, root path, no special behavior] - expected: FAIL - - [No prefix, domain, no special behavior] - expected: FAIL - From 82d8ceb845a88f7eb4d6470334ff45ba3fa1fd3d Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Mon, 20 Aug 2018 22:11:18 +0000 Subject: [PATCH 25/49] Bug 1484154 [wpt PR 12544] - Support CSSStyleValues in StylePropertyMap.set. (Reland), a=testonly Automatic update from web-platform-testsSupport CSSStyleValues in StylePropertyMap.set. (Reland) In StyleValueToCSSValue, when checking whether a certain CSSStyleValue matches the property in question, we now ask the registration (via CSSOMTypes) if the CSSStyleValue matches. If it doesn't match, we throw a TypeError like for normal properties. If it does match, the CSSStyleValue is stringified, tokenized, and set on the style rule as tokens. I have postponed support for and , because CSSUnsupportedStyleValue currently does not handle registered custom properties at all. This is appropriate to fix in a separate CL. Note that, because the string version of StylePropertyMap.set also uses StyleValueToCSSValue, it will no longer be possible to set registered custom properties with a string--even if the syntax is matched. A subsequent CL will fix this. R=futhark@chromium.org Bug: 641877 Change-Id: Ib5c31640f81e957620339c9bdf617ab1af5d3d47 Reviewed-on: https://chromium-review.googlesource.com/1179153 Reviewed-by: Rune Lillesveen Commit-Queue: Anders Ruud Cr-Commit-Position: refs/heads/master@{#584024} -- wpt-commits: b6f1c190818648dc0c33eb7ada54bf3f209fc938 wpt-pr: 12544 --- testing/web-platform/meta/MANIFEST.json | 2 +- .../typedom.tentative.html | 154 +++++++++++++++++- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 15a5bd9ef777..8f35269d6f55 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -540080,7 +540080,7 @@ "support" ], "css/css-properties-values-api/typedom.tentative.html": [ - "065280614cca9fa52b79c28e253c30ada188a1b9", + "69ebf7a13d8cf3d71413259db68336368e5032e7", "testharness" ], "css/css-properties-values-api/unit-cycles.html": [ diff --git a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html index 065280614cca..69ebf7a13d8c 100644 --- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html +++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html @@ -1,11 +1,13 @@ - + - +
From 0a0a4055e8601668342f4fb3a35259cb61cb73ce Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Mon, 20 Aug 2018 22:11:38 +0000 Subject: [PATCH 26/49] Bug 1483666 [wpt PR 12508] - [css-logical] Allow CSS logical shorthands to be serialized in inline and computed styles, a=testonly Automatic update from web-platform-tests[css-logical] Allow CSS logical shorthands to be serialized in inline and computed styles Spec: https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue BUG=873760 TEST=external/wpt/css/css-logical/logical-box-border-color.html TEST=external/wpt/css/css-logical/logical-box-border-shorthands.html TEST=external/wpt/css/css-logical/logical-box-border-style.html TEST=external/wpt/css/css-logical/logical-box-border-width.html TEST=external/wpt/css/css-logical/logical-box-inset.html TEST=external/wpt/css/css-logical/logical-box-margin.html TEST=external/wpt/css/css-logical/logical-box-padding.html Change-Id: I60fca339c419d1d19eb6b31f0426c11f9d1cf95f Reviewed-on: https://chromium-review.googlesource.com/1176084 Reviewed-by: Javier Fernandez Reviewed-by: Anders Ruud Commit-Queue: Oriol Brufau Cr-Commit-Position: refs/heads/master@{#584027} -- wpt-commits: 9c650fc212cdbba6ee0830a68d3af3e708e031de wpt-pr: 12508 --- testing/web-platform/meta/MANIFEST.json | 2 +- .../resources/test-box-properties.js | 46 +++++++++++++------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 8f35269d6f55..4f294a041451 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -536888,7 +536888,7 @@ "testharness" ], "css/css-logical/resources/test-box-properties.js": [ - "9d73b5b8fc50149e52b76ae338db4f743d9976f5", + "1f17ff296ff2c3dcf81db1a112bda24ef04eb126", "support" ], "css/css-logical/resources/test-logical-values.js": [ diff --git a/testing/web-platform/tests/css/css-logical/resources/test-box-properties.js b/testing/web-platform/tests/css/css-logical/resources/test-box-properties.js index 9d73b5b8fc50..1f17ff296ff2 100644 --- a/testing/web-platform/tests/css/css-logical/resources/test-box-properties.js +++ b/testing/web-platform/tests/css/css-logical/resources/test-box-properties.js @@ -23,9 +23,10 @@ const testValues = { * inlineStart: "margin-inline-start", inlineEnd: "margin-inline-end", * blockStart: "margin-block-start", blockEnd: "margin-block-end", * }, shorthands: { - * inline: ["margin-inline-start", "margin-inline-end"], - * block: ["margin-block-start", "margin-block-end"], - * }, type: ["length"], prerequisites: "...", property: "'margin-*'" } + * "margin": ["margin-top", "margin-right", "margin-bottom", "margin-left"], + * "margin-inline": ["margin-inline-start", "margin-inline-end"], + * "margin-block": ["margin-block-start", "margin-block-end"], + * }, type: ["length"], prerequisites: "...", property: "margin-*" } * * @param {string} property * A string representing the property names, like "margin-*". @@ -59,8 +60,10 @@ export function createBoxPropertyGroup(property, descriptor) { physical[physicalSide] = isInset ? physicalSide : property.replace("*", physicalSide); prerequisites += makeDeclaration(descriptor.prerequisites, physicalSide); } + shorthands[property.replace("-*", "")] = + ["top", "right", "bottom", "left"].map(physicalSide => physical[physicalSide]); const type = [].concat(descriptor.type); - return {name, logical, physical, shorthands, type, prerequisites, property}; + return {logical, physical, shorthands, type, prerequisites, property}; } /** @@ -109,6 +112,29 @@ export function runTests(group) { }, `Test that logical ${group.property} properties are supported.`); testElement.style.cssText = ""; + const shorthandValues = {}; + for (const [shorthand, longhands] of shorthands || []) { + let valueArray; + if (group.type.length > 1) { + valueArray = [values[0]]; + } else { + valueArray = testValues[group.type].slice(0, longhands.length); + } + shorthandValues[shorthand] = valueArray; + const value = valueArray.join(" "); + const expected = [[shorthand, value]]; + for (let [i, longhand] of longhands.entries()) { + expected.push([longhand, valueArray[group.type.length > 1 ? 0 : i]]); + } + test(function() { + testElement.style.setProperty(shorthand, value); + testCSSValues("shorthand in inline style", testElement.style, expected); + const stylesheet = `.test { ${group.prerequisites} }`; + testComputedValues("shorthand in computed style", stylesheet, expected); + }, `Test that ${shorthand} shorthand sets longhands and serializes correctly.`); + testElement.style.cssText = ""; + } + for (const writingMode of writingModes) { for (const style of writingMode.styles) { const writingModeDecl = makeDeclaration(style); @@ -141,21 +167,15 @@ export function runTests(group) { }, `Test that logical ${group.property} properties share computed values ` + `with their physical associates, with '${writingModeDecl}'.`); - // Test logical shorthand properties. if (shorthands) { test(function() { for (const [shorthand, longhands] of shorthands) { - let shorthandValues; - if (group.type.length > 1) { - shorthandValues = [values[0]]; - } else { - shorthandValues = testValues[group.type].slice(0, longhands.length); - } - const decl = group.prerequisites + `${shorthand}: ${shorthandValues.join(" ")}; `; + let valueArray = shorthandValues[shorthand]; + const decl = group.prerequisites + `${shorthand}: ${valueArray.join(" ")}; `; const expected = []; for (let [i, longhand] of longhands.entries()) { - const longhandValue = shorthandValues[group.type.length > 1 ? 0 : i]; + const longhandValue = valueArray[group.type.length > 1 ? 0 : i]; expected.push([longhand, longhandValue]); expected.push([associated[longhand], longhandValue]); } From d482886d616fd1fa8902b21bee1df2369e85a439 Mon Sep 17 00:00:00 2001 From: moz-wptsync-bot Date: Mon, 20 Aug 2018 11:32:29 +0000 Subject: [PATCH 27/49] Bug 1483666 [wpt PR 12508] - Update wpt metadata, a=testonly wpt-pr: 12508 wpt-type: metadata --- .../css/css-logical/logical-box-border-color.html.ini | 9 +++++++++ .../css-logical/logical-box-border-shorthands.html.ini | 9 +++++++++ .../css/css-logical/logical-box-border-style.html.ini | 9 +++++++++ .../css/css-logical/logical-box-border-width.html.ini | 9 +++++++++ .../meta/css/css-logical/logical-box-inset.html.ini | 9 +++++++++ .../meta/css/css-logical/logical-box-margin.html.ini | 9 +++++++++ .../meta/css/css-logical/logical-box-padding.html.ini | 9 +++++++++ 7 files changed, 63 insertions(+) diff --git a/testing/web-platform/meta/css/css-logical/logical-box-border-color.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-border-color.html.ini index 95c1ea4600cf..5fb532add356 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-border-color.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-border-color.html.ini @@ -29,3 +29,12 @@ [Test that border-*-color shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that border-block-color shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-inline-color shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-color shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-border-shorthands.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-border-shorthands.html.ini index 2d4d694ad23e..7ab3d9086fdc 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-border-shorthands.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-border-shorthands.html.ini @@ -119,3 +119,12 @@ [Test that border-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that border-block shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-inline shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-border-style.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-border-style.html.ini index 0161d09ad9cc..a1b44462c692 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-border-style.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-border-style.html.ini @@ -29,3 +29,12 @@ [Test that border-*-style shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that border-inline-style shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-block-style shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-style shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-border-width.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-border-width.html.ini index d6a694a19c8e..debce7b627c2 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-border-width.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-border-width.html.ini @@ -29,3 +29,12 @@ [Test that border-*-width shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that border-width shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-block-width shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that border-inline-width shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-inset.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-inset.html.ini index f9f6556423b8..ad0f0bb5abd1 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-inset.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-inset.html.ini @@ -29,3 +29,12 @@ [Test that inset-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that inset shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that inset-inline shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that inset-block shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-margin.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-margin.html.ini index 196b55f350ae..8a2626ae8ff1 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-margin.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-margin.html.ini @@ -29,3 +29,12 @@ [Test that margin-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that margin-block shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that margin-inline shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that margin shorthand sets longhands and serializes correctly.] + expected: FAIL + diff --git a/testing/web-platform/meta/css/css-logical/logical-box-padding.html.ini b/testing/web-platform/meta/css/css-logical/logical-box-padding.html.ini index 157545e16c21..6bdb61e2185b 100644 --- a/testing/web-platform/meta/css/css-logical/logical-box-padding.html.ini +++ b/testing/web-platform/meta/css/css-logical/logical-box-padding.html.ini @@ -29,3 +29,12 @@ [Test that padding-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: sideways-lr; direction: rtl; '.] expected: FAIL + [Test that padding shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that padding-inline shorthand sets longhands and serializes correctly.] + expected: FAIL + + [Test that padding-block shorthand sets longhands and serializes correctly.] + expected: FAIL + From 566c00863b00a0ce9423ed580e7a62e90fb767ac Mon Sep 17 00:00:00 2001 From: autofoolip <40241672+autofoolip@users.noreply.github.com> Date: Mon, 20 Aug 2018 22:11:57 +0000 Subject: [PATCH 28/49] Bug 1484200 [wpt PR 12548] - Update interfaces/web-nfc.idl, a=testonly Automatic update from web-platform-testsUpdate interfaces/web-nfc.idl (#12548) Copied by https://github.com/foolip/wpt-idl-importer from: https://github.com/tidoust/reffy-reports/blob/ae0c059/whatwg/idl/web-nfc.idl -- wpt-commits: b42c431b5a46de314af0d751d6809d85c4ca0864 wpt-pr: 12548 --- testing/web-platform/meta/MANIFEST.json | 2 +- testing/web-platform/tests/interfaces/web-nfc.idl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 4f294a041451..428ceac801d7 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -606952,7 +606952,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "cdb0e75684842a4263e69d207f18de3e90a31eb1", + "2728840b95f606c9ebf6353ae8e8e98cc9efa04e", "support" ], "interfaces/web-share.idl": [ diff --git a/testing/web-platform/tests/interfaces/web-nfc.idl b/testing/web-platform/tests/interfaces/web-nfc.idl index cdb0e7568484..2728840b95f6 100644 --- a/testing/web-platform/tests/interfaces/web-nfc.idl +++ b/testing/web-platform/tests/interfaces/web-nfc.idl @@ -54,7 +54,7 @@ enum NFCPushTarget { dictionary NFCWatchOptions { USVString url = ""; - NFCRecordType? recordType; + NFCRecordType recordType; USVString mediaType = ""; NFCWatchMode mode = "web-nfc-only"; }; From 14ebc7cdf7d2a6abb3d344634825c4a2d16fec37 Mon Sep 17 00:00:00 2001 From: Maja Kabus Date: Mon, 20 Aug 2018 22:12:14 +0000 Subject: [PATCH 29/49] Bug 1481836 [wpt PR 12355] - Introduced dictionary TrustedTypePolicyOptions, a=testonly Automatic update from web-platform-testsIntroduced dictionary TrustedTypePolicyOptions Created new dictionary TrustedTypePolicyOptions with callbacks and adjusted TrustedTypePolicyFactory and TrustedTypePolicy to accept the dictionary. Added createURL() and createScriptURL, and adjusted createHTML() in TrustedTypePolicyOptions. Bug: 739170 Change-Id: Ie63fdf90b5aac53188fcd8141c95d287c3e726fd Reviewed-on: https://chromium-review.googlesource.com/1167282 Reviewed-by: Mike West Reviewed-by: Yuki Shiino Commit-Queue: Maja Kabus Cr-Commit-Position: refs/heads/master@{#584038} -- wpt-commits: fa06664dc85df3024762f5e082e05aa293f90d88 wpt-pr: 12355 --- testing/web-platform/meta/MANIFEST.json | 2 +- ...ePolicyFactory-createPolicy.tentative.html | 221 +++++++++++++++++- 2 files changed, 219 insertions(+), 4 deletions(-) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 428ceac801d7..57b0babad628 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -643900,7 +643900,7 @@ "testharness" ], "trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html": [ - "863fe847141f9705bb5bc02fcb8f0b6f923c4aa8", + "a37b5a7197f264bb8f75e1582debff5a53cd8d5e", "testharness" ], "trusted-types/TrustedURL.tentative.html": [ diff --git a/testing/web-platform/tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html b/testing/web-platform/tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html index 863fe847141f..a37b5a7197f2 100644 --- a/testing/web-platform/tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html +++ b/testing/web-platform/tests/trusted-types/TrustedTypePolicyFactory-createPolicy.tentative.html @@ -4,11 +4,226 @@ From b997d9da4482d6025bbcf696a1d8c20862cc5819 Mon Sep 17 00:00:00 2001 From: moz-wptsync-bot Date: Mon, 20 Aug 2018 22:12:41 +0000 Subject: [PATCH 30/49] Bug 1484852 - [wpt-sync] Update web-platform-tests to fa06664dc85df3024762f5e082e05aa293f90d88, a=testonly wpt-head: fa06664dc85df3024762f5e082e05aa293f90d88 wpt-type: landing --- .../ignore-opens-during-unload.window.js.ini | 1 + testing/web-platform/meta/mozilla-sync | 4 ++-- .../meta/svg/text/reftests/text-complex-001.svg.ini | 2 ++ .../meta/svg/text/reftests/text-complex-002.svg.ini | 2 ++ .../meta/svg/text/reftests/text-shape-inside-001.svg.ini | 2 ++ .../meta/svg/text/reftests/text-shape-inside-002.svg.ini | 2 ++ 6 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini create mode 100644 testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini create mode 100644 testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini create mode 100644 testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini diff --git a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini index a54f11232a84..b99cd449488a 100644 --- a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini +++ b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini @@ -3,3 +3,4 @@ if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH + if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH diff --git a/testing/web-platform/meta/mozilla-sync b/testing/web-platform/meta/mozilla-sync index 84093ae5287a..7be67c869750 100644 --- a/testing/web-platform/meta/mozilla-sync +++ b/testing/web-platform/meta/mozilla-sync @@ -1,2 +1,2 @@ -local: 0eaab50e3ab5d4bb34367312f5035e30c1267d0e -upstream: 7dbb4b66740563687a254b8e4cd8f36ac836d48f +local: 456bcc8a4472d2b1813f30f15156a1a10bdef05f +upstream: fa06664dc85df3024762f5e082e05aa293f90d88 diff --git a/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini new file mode 100644 index 000000000000..01f90d48d854 --- /dev/null +++ b/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini @@ -0,0 +1,2 @@ +[text-complex-001.svg] + expected: FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini new file mode 100644 index 000000000000..0b45c7375768 --- /dev/null +++ b/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini @@ -0,0 +1,2 @@ +[text-complex-002.svg] + expected: FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini new file mode 100644 index 000000000000..52d123afd692 --- /dev/null +++ b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini @@ -0,0 +1,2 @@ +[text-shape-inside-001.svg] + expected: FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini new file mode 100644 index 000000000000..76a712eac871 --- /dev/null +++ b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini @@ -0,0 +1,2 @@ +[text-shape-inside-002.svg] + expected: FAIL From 38495beeb78e4915a4ee309163bea251a5f6ead8 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Fri, 27 Jul 2018 01:26:20 +0100 Subject: [PATCH 31/49] Bug 1478969 - Don't apply RUSTFLAGS defined in mozconfig when building host Rust libraries and programs. r=froydnj --HG-- extra : rebase_source : ba34d715409f6975c69d9259315cb5735d5e9ce6 extra : intermediate-source : 93e52a1e5d88d169fca83b1f8e9f0eb78d809cc9 extra : source : fe49224aa15b580499b4b52731622de628ec5c0e --- config/rules.mk | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/config/rules.mk b/config/rules.mk index 91e2de682684..33363640fa94 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -878,7 +878,7 @@ ifeq (neon,$(MOZ_FPU)) rustflags_neon += -C target_feature=+neon endif -rustflags_override = RUSTFLAGS='$(MOZ_RUST_DEFAULT_FLAGS) $(RUSTFLAGS) $(rustflags_neon)' +rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon) ifdef MOZ_MSVCBITS # If we are building a MozillaBuild shell, we want to clear out the @@ -942,8 +942,9 @@ endif # WINNT # don't use the prefix when make -n is used, so that cargo doesn't run # in that case) define RUN_CARGO -$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(environment_cleaner) $(rust_unlock_unstable) $(rustflags_override) $(sccache_wrap) \ +$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(environment_cleaner) $(rust_unlock_unstable) $(sccache_wrap) \ CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \ + RUSTFLAGS='$(2)' \ RUSTC=$(RUSTC) \ RUSTDOC=$(RUSTDOC) \ RUSTFMT=$(RUSTFMT) \ @@ -956,7 +957,7 @@ $(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(environment_cleane RUST_BACKTRACE=full \ MOZ_TOPOBJDIR=$(topobjdir) \ $(cargo_incremental) \ - $(2) \ + $(3) \ $(CARGO) $(1) $(cargo_build_flags) endef @@ -967,12 +968,20 @@ endef # but, given the idiosyncracies of make, can also be called without arguments: # # $(call CARGO_BUILD) +define CARGO_BUILD_HOST +$(call RUN_CARGO,rustc,$(rustflags_override),$(1)) +endef + +define CARGO_CHECK_HOST +$(call RUN_CARGO,check,$(rustflags_override),$(1)) +endef + define CARGO_BUILD -$(call RUN_CARGO,rustc,$(1)) +$(call RUN_CARGO,rustc,$(rustflags_override) $(RUSTFLAGS),$(1)) endef define CARGO_CHECK -$(call RUN_CARGO,check,$(1)) +$(call RUN_CARGO,check,$(rustflags_override) $(RUSTFLAGS),$(1)) endef cargo_linker_env_var := CARGO_TARGET_$(RUST_TARGET_ENV_NAME)_LINKER @@ -1037,7 +1046,7 @@ endif rust_test_flag := --no-fail-fast force-cargo-test-run: - $(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_features_flag),$(target_cargo_env_vars)) + $(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_features_flag),$(rustflags_override) $(RUSTFLAGS),$(target_cargo_env_vars)) check:: force-cargo-test-run endif @@ -1050,12 +1059,12 @@ endif force-cargo-host-library-build: $(REPORT_BUILD) - $(call CARGO_BUILD) --lib $(cargo_host_flag) $(host_rust_features_flag) + $(call CARGO_BUILD_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag) $(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build force-cargo-host-library-check: - $(call CARGO_CHECK) --lib $(cargo_host_flag) $(host_rust_features_flag) + $(call CARGO_CHECK_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag) else force-cargo-host-library-check: @true @@ -1077,13 +1086,13 @@ endif # RUST_PROGRAMS ifdef HOST_RUST_PROGRAMS force-cargo-host-program-build: $(REPORT_BUILD) - $(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) + $(call CARGO_BUILD_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) $(HOST_RUST_PROGRAMS): force-cargo-host-program-build force-cargo-host-program-check: $(REPORT_BUILD) - $(call CARGO_CHECK) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) + $(call CARGO_CHECK_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) else force-cargo-host-program-check: @true From 4a8426acf0123c5016f03145ea480f84e5571f73 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Tue, 21 Aug 2018 15:37:42 -0600 Subject: [PATCH 32/49] Bug 1478849. r=mccr8 --- ipc/glue/ProtocolUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index d22131c3d280..07be2c37a478 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -686,6 +686,7 @@ IToplevelProtocol::IToplevelProtocol(const char* aName, IToplevelProtocol::~IToplevelProtocol() { + mState = nullptr; if (mTrans) { RefPtr> task = new DeleteTask(mTrans.release()); XRE_GetIOMessageLoop()->PostTask(task.forget()); From 5b333787fe15751ad20a774c4b74578ec71b5467 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 17 Aug 2018 18:54:25 -0500 Subject: [PATCH 33/49] Bug 1484728 - Update test262 skipped files again. r=anba --- js/src/devtools/automation/cgc-jstests-slow.txt | 12 ------------ js/src/tests/jstests.list | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/js/src/devtools/automation/cgc-jstests-slow.txt b/js/src/devtools/automation/cgc-jstests-slow.txt index 02ed78e36a3d..16290cb047b5 100644 --- a/js/src/devtools/automation/cgc-jstests-slow.txt +++ b/js/src/devtools/automation/cgc-jstests-slow.txt @@ -63,15 +63,3 @@ non262/extensions/regress-477187.js non262/regress/regress-452498-052-a.js non262/extensions/clone-complex-object.js non262/extensions/clone-object-deep.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js -test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list index 44bdb5e4acc5..40446e9d1dc7 100644 --- a/js/src/tests/jstests.list +++ b/js/src/tests/jstests.list @@ -9,18 +9,6 @@ skip script non262/String/normalize-generateddata-input.js # input data for othe # Timeouts on arm and cgc builds. slow script test262/built-ins/decodeURI/S15.1.3.1_A2.5_T1.js slow script test262/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js -slow script test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js ################################################################# From ea4f0a827996249a9b74dcc040cb8c8b18035205 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 17 Aug 2018 18:40:58 -0500 Subject: [PATCH 34/49] Bug 1484728 - Update test262 from upstream again. r=anba --- js/src/tests/test262/GIT-INFO | 10 +-- .../wait/no-spurious-wakeup-no-operation.js | 2 +- .../Object/fromEntries/empty-iterable.js | 10 ++- .../Object/fromEntries/evaluation-order.js | 10 ++- ...s.js => iterator-closed-for-null-entry.js} | 21 +++++- ...js => iterator-closed-for-string-entry.js} | 19 +++++- ...closed-for-throwing-entry-key-accessor.js} | 18 ++++- ...-closed-for-throwing-entry-key-tostring.js | 18 ++++- ...losed-for-throwing-entry-value-accessor.js | 66 +++++++++++++++++++ ...ot-closed-for-next-returning-non-object.js | 27 +++++++- ...r-not-closed-for-throwing-done-accessor.js | 27 +++++++- .../iterator-not-closed-for-throwing-next.js | 27 +++++++- ...iterator-not-closed-for-uncallable-next.js | 20 +++++- .../built-ins/Object/fromEntries/length.js | 11 ++-- .../built-ins/Object/fromEntries/name.js | 11 ++-- .../Object/fromEntries/requires-argument.js | 9 ++- .../Object/fromEntries/simple-properties.js | 8 ++- .../string-entry-string-object-succeeds.js | 13 ++++ ...racter-class-digit-class-escape-flags-u.js | 23 +++---- ...it-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...lass-digit-class-escape-plus-quantifier.js | 23 +++---- .../character-class-digit-class-escape.js | 23 +++---- ...er-class-non-digit-class-escape-flags-u.js | 23 +++---- ...it-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...-non-digit-class-escape-plus-quantifier.js | 23 +++---- .../character-class-non-digit-class-escape.js | 23 +++---- ...ass-non-whitespace-class-escape-flags-u.js | 23 +++---- ...ce-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...whitespace-class-escape-plus-quantifier.js | 23 +++---- ...acter-class-non-whitespace-class-escape.js | 23 +++---- ...ter-class-non-word-class-escape-flags-u.js | 23 +++---- ...rd-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...s-non-word-class-escape-plus-quantifier.js | 23 +++---- .../character-class-non-word-class-escape.js | 23 +++---- ...r-class-whitespace-class-escape-flags-u.js | 23 +++---- ...ce-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...whitespace-class-escape-plus-quantifier.js | 23 +++---- ...character-class-whitespace-class-escape.js | 23 +++---- ...aracter-class-word-class-escape-flags-u.js | 23 +++---- ...rd-class-escape-plus-quantifier-flags-u.js | 23 +++---- ...class-word-class-escape-plus-quantifier.js | 23 +++---- .../character-class-word-class-escape.js | 23 +++---- .../RegExp/CharacterClassEscapes/shell.js | 58 ++++++++++++++++ .../property-escapes/generated/shell.js | 11 ++-- .../RegExp/prototype/Symbol.matchAll/shell.js | 11 ++-- .../next/shell.js | 11 ++-- .../String/prototype/matchAll/shell.js | 11 ++-- .../constructor/options-toobject-prototype.js | 37 +++++++++++ .../constructor/options-toobject.js | 28 ++++++++ .../constructor/options-undefined.js | 40 +++++++++++ .../supportedLocalesOf/locales-invalid.js | 22 +++++++ .../options-localeMatcher-invalid.js | 36 ++++++++++ .../supportedLocalesOf/options-null.js | 22 +++++++ .../supportedLocalesOf/options-toobject.js | 43 ++++++++++++ .../supportedLocalesOf/options-undefined.js | 28 ++++++++ .../prototype/format/en-us-numeric-auto.js | 5 ++ .../prototype/format/en-us-style-short.js | 21 +++--- .../prototype/format/pl-pl-style-short.js | 4 +- .../formatToParts/en-us-numeric-auto.js | 5 ++ .../formatToParts/en-us-style-short.js | 21 +++--- .../formatToParts/pl-pl-style-narrow.js | 6 +- 61 files changed, 866 insertions(+), 433 deletions(-) rename js/src/tests/test262/built-ins/Object/fromEntries/{iterator-closed-for-null-entry.js.js => iterator-closed-for-null-entry.js} (63%) rename js/src/tests/test262/built-ins/Object/fromEntries/{iterator-closed-for-string-entry.js.js => iterator-closed-for-string-entry.js} (65%) rename js/src/tests/test262/built-ins/Object/fromEntries/{iterator-closed-for-throwing-entry-accessor.js => iterator-closed-for-throwing-entry-key-accessor.js} (65%) create mode 100644 js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-value-accessor.js create mode 100644 js/src/tests/test262/built-ins/Object/fromEntries/string-entry-string-object-succeeds.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js create mode 100644 js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js diff --git a/js/src/tests/test262/GIT-INFO b/js/src/tests/test262/GIT-INFO index c103430e4f4d..1e9a6dad540c 100644 --- a/js/src/tests/test262/GIT-INFO +++ b/js/src/tests/test262/GIT-INFO @@ -1,5 +1,7 @@ -commit 60b9467630a7b4899058e3ad74eb88c3ecb08a40 -Author: Kevin Gibbons -Date: Fri Aug 10 23:16:46 2018 -0700 +commit ab436c465106be86719c4849c9cedecd7b570ff9 +Author: Leo Balter +Date: Fri Aug 17 18:06:19 2018 -0400 - Two more simple tests + Merge pull request #1677 from tc39/ofe-use-verifyproperty + + Object.fromEntries: use verifyProperty; add specification details diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js index 62f695d2f58d..8db49c8850d5 100644 --- a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js @@ -57,6 +57,6 @@ assert.sameValue( 'timed-out', '$262.agent.getReport() returns "timed-out"' ); -assert.sameValue(Atomics.nofity(i32a, 0), 0, 'Atomics.nofity(i32a, 0) returns 0'); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/empty-iterable.js b/js/src/tests/test262/built-ins/Object/fromEntries/empty-iterable.js index fd42ea48ff08..12dce89cac93 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/empty-iterable.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/empty-iterable.js @@ -2,8 +2,16 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: When given an empty list, makes an empty object. esid: sec-object.fromentries +description: When given an empty list, makes an empty object. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + features: [Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/evaluation-order.js b/js/src/tests/test262/built-ins/Object/fromEntries/evaluation-order.js index b87f254cd662..30677d6897df 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/evaluation-order.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/evaluation-order.js @@ -2,8 +2,16 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Evaluation order is iterator.next(), get '0', get '1', toPropertyKey, repeat. esid: sec-object.fromentries +description: Evaluation order is iterator.next(), get '0', get '1', toPropertyKey, repeat. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + includes: [compareArray.js] features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js similarity index 63% rename from js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js.js rename to js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js index 850fc6ca8667..3f3f72624b56 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-null-entry.js @@ -2,8 +2,25 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Closes iterators when they return entries which are null. esid: sec-object.fromentries +description: Closes iterators when they return entries which are null. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + ... + d. If Type(nextItem) is not Object, then + i. Let error be ThrowCompletion(a newly created TypeError object). + ii. Return ? IteratorClose(iteratorRecord, error). + features: [Symbol.iterator, Object.fromEntries] ---*/ @@ -19,7 +36,7 @@ var iterable = { advanced = true; return { done: false, - value: 'null', + value: null, }; }, return: function() { diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js similarity index 65% rename from js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js.js rename to js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js index e215dcf32f1b..615261dbb38d 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-string-entry.js @@ -2,8 +2,25 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Closes iterators when they return entries which are strings. esid: sec-object.fromentries +description: Closes iterators when they return entries which are strings. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + ... + d. If Type(nextItem) is not Object, then + i. Let error be ThrowCompletion(a newly created TypeError object). + ii. Return ? IteratorClose(iteratorRecord, error). + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-accessor.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-accessor.js similarity index 65% rename from js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-accessor.js rename to js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-accessor.js index c4516e21cc1c..c1b9e0188034 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-accessor.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-accessor.js @@ -2,8 +2,24 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Closes iterators when accessing an entry's properties throws. esid: sec-object.fromentries +description: Closes iterators when accessing an entry's key throws. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + ... + e. Let k be Get(nextItem, "0"). + f. If k is an abrupt completion, return ? IteratorClose(iteratorRecord, k). + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-tostring.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-tostring.js index bac64e6e2147..95b0e004bddf 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-tostring.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-key-tostring.js @@ -2,8 +2,24 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Closes iterators when toString on a key throws. esid: sec-object.fromentries +description: Closes iterators when toString on a key throws. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + ... + e. Let k be Get(nextItem, "0"). + f. If k is an abrupt completion, return ? IteratorClose(iteratorRecord, k). + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-value-accessor.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-value-accessor.js new file mode 100644 index 000000000000..3fc60197b775 --- /dev/null +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-closed-for-throwing-entry-value-accessor.js @@ -0,0 +1,66 @@ +// Copyright (C) 2018 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.fromentries +description: Closes iterators when accessing an entry's value throws. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + ... + g. Let v be Get(nextItem, "1"). + h. If v is an abrupt completion, return ? IteratorClose(iteratorRecord, v). + +features: [Symbol.iterator, Object.fromEntries] +---*/ + +function DummyError() {} + +var returned = false; +var iterable = { + [Symbol.iterator]: function() { + var advanced = false; + return { + next: function() { + if (advanced) { + throw new Test262Error('should only advance once'); + } + advanced = true; + return { + done: false, + value: { + get '0'() { + return 'key'; + }, + get '1'() { + throw new DummyError(); + }, + }, + }; + }, + return: function() { + if (returned) { + throw new Test262Error('should only return once'); + } + returned = true; + }, + }; + }, +}; + +assert.throws(DummyError, function() { + Object.fromEntries(iterable); +}); + +assert(returned, 'iterator should be closed when entry value property access throws'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-next-returning-non-object.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-next-returning-non-object.js index 1a767b7a4115..077e5ec08ae5 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-next-returning-non-object.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-next-returning-non-object.js @@ -2,8 +2,33 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Does not close iterators with a `next` method which returns a non-object. esid: sec-object.fromentries +description: Does not close iterators with a `next` method which returns a non-object. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + a. Let next be ? IteratorStep(iteratorRecord). + + + IteratorStep ( iteratorRecord ) + + 1. Let result be ? IteratorNext(iteratorRecord). + + + IteratorNext ( iteratorRecord [ , value ] ) + + ... + 3. If Type(result) is not Object, throw a TypeError exception. + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-done-accessor.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-done-accessor.js index 4560378dad1c..c88e496f858f 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-done-accessor.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-done-accessor.js @@ -2,8 +2,33 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Does not close iterators with a `done` accessor which throws. esid: sec-object.fromentries +description: Does not close iterators with a `done` accessor which throws. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + a. Let next be ? IteratorStep(iteratorRecord). + + + IteratorStep ( iteratorRecord ) + + 1. Let result be ? IteratorNext(iteratorRecord). + + + IteratorNext ( iteratorRecord [ , value ] ) + + ... + 3. If Type(result) is not Object, throw a TypeError exception. + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-next.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-next.js index 1fbf2fc7839c..386e4afc7cd1 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-next.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-throwing-next.js @@ -2,8 +2,33 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Does not close iterators with a `next` method which throws. esid: sec-object.fromentries +description: Does not close iterators with a `next` method which throws. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + a. Let next be ? IteratorStep(iteratorRecord). + + + IteratorStep ( iteratorRecord ) + + 1. Let result be ? IteratorNext(iteratorRecord). + + + IteratorNext ( iteratorRecord [ , value ] ) + + ... + 3. If Type(result) is not Object, throw a TypeError exception. + features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-uncallable-next.js b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-uncallable-next.js index 5ec6ee4a497a..766a7b1b5d2a 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-uncallable-next.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/iterator-not-closed-for-uncallable-next.js @@ -2,8 +2,26 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Does not close iterators with an uncallable `next` property. esid: sec-object.fromentries +description: Does not close iterators with an uncallable `next` property. +info: | + Object.fromEntries ( iterable ) + + ... + 4. Let stepsDefine be the algorithm steps defined in CreateDataPropertyOnObject Functions. + 5. Let adder be CreateBuiltinFunction(stepsDefine, « »). + 6. Return ? AddEntriesFromIterable(obj, iterable, adder). + + AddEntriesFromIterable ( target, iterable, adder ) + + ... + 4. Repeat, + a. Let next be ? IteratorStep(iteratorRecord). + + + IteratorStep ( iteratorRecord ) + + 1. Let result be ? IteratorNext(iteratorRecord). features: [Symbol.iterator, Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/length.js b/js/src/tests/test262/built-ins/Object/fromEntries/length.js index d68bf00f6765..c510253b6776 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/length.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/length.js @@ -8,10 +8,11 @@ includes: [propertyHelper.js] features: [Object.fromEntries] ---*/ -assert.sameValue(Object.fromEntries.length, 1); - -verifyNotEnumerable(Object.fromEntries, "length"); -verifyNotWritable(Object.fromEntries, "length"); -verifyConfigurable(Object.fromEntries, "length"); +verifyProperty(Object.fromEntries, "length", { + value: 1, + enumerable: false, + writable: false, + configurable: true +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/name.js b/js/src/tests/test262/built-ins/Object/fromEntries/name.js index 4c1537609145..221c5a0e72d1 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/name.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/name.js @@ -8,10 +8,11 @@ includes: [propertyHelper.js] features: [Object.fromEntries] ---*/ -assert.sameValue(Object.fromEntries.name, "fromEntries"); - -verifyNotEnumerable(Object.fromEntries, "name"); -verifyNotWritable(Object.fromEntries, "name"); -verifyConfigurable(Object.fromEntries, "name"); +verifyProperty(Object.fromEntries, "name", { + value: "fromEntries", + enumerable: false, + writable: false, + configurable: true +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/requires-argument.js b/js/src/tests/test262/built-ins/Object/fromEntries/requires-argument.js index 70d96146fbce..139182046a45 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/requires-argument.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/requires-argument.js @@ -2,8 +2,15 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Throws when called without an argument. esid: sec-object.fromentries +description: Throws when called without an argument. +info: | + + Object.fromEntries ( iterable ) + + 1. Perform ? RequireObjectCoercible(iterable). + ... + features: [Object.fromEntries] ---*/ diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/simple-properties.js b/js/src/tests/test262/built-ins/Object/fromEntries/simple-properties.js index 03790c4e27c7..431556a966ab 100644 --- a/js/src/tests/test262/built-ins/Object/fromEntries/simple-properties.js +++ b/js/src/tests/test262/built-ins/Object/fromEntries/simple-properties.js @@ -9,8 +9,10 @@ features: [Object.fromEntries] ---*/ var result = Object.fromEntries([['key', 'value']]); -verifyEnumerable(result, 'key'); -verifyWritable(result, 'key'); -verifyConfigurable(result, 'key'); +verifyProperty(result, "key", { + enumerable: true, + writable: true, + configurable: true, +}); reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Object/fromEntries/string-entry-string-object-succeeds.js b/js/src/tests/test262/built-ins/Object/fromEntries/string-entry-string-object-succeeds.js new file mode 100644 index 000000000000..91ec49b4b3dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Object/fromEntries/string-entry-string-object-succeeds.js @@ -0,0 +1,13 @@ +// Copyright (C) 2018 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Succeeds when an entry object is a boxed string. +esid: sec-object.fromentries +features: [Object.fromEntries] +---*/ + +var result = Object.fromEntries([new String('ab')]); +assert.sameValue(result['a'], 'b'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js index 80f932daecc5..f48fe5dfcd98 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\d/ug; const matchingRange = /[0-9]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js index 6a5359978915..a98b425d314e 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\d+/ug; const matchingRange = /[0-9]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js index a78ef9796974..07c766724ddf 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\d+/g; const matchingRange = /[0-9]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js index 491176f157c2..47bbdee1fe70 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\d/g; const matchingRange = /[0-9]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js index c97ef485c460..f3ac883d2db9 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\D/ug; const matchingRange = /[\0-\/:-\u{10FFFF}]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js index aa140d34b325..97cec9f73bcb 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\D+/ug; const matchingRange = /[\0-\/:-\u{10FFFF}]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js index 525b7ebad6f6..4fa2bbd00966 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\D+/g; const matchingRange = /[\0-\/:-\uFFFF]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape.js index 21de39f14ca1..d16f92f91335 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\D/g; const matchingRange = /[\0-\/:-\uFFFF]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js index e7a1b445cbf3..695dcc99f566 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\S/ug; const matchingRange = /[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uFEFE\uFF00-\u{10FFFF}]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js index 1e26a9eb9fdc..15e23d25d8ed 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\S+/ug; const matchingRange = /[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uFEFE\uFF00-\u{10FFFF}]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier.js index 8d739e237292..a74287288176 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\S+/g; const matchingRange = /[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uFEFE\uFF00-\uFFFF]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape.js index 670bba422d36..e4b182081029 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\S/g; const matchingRange = /[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uFEFE\uFF00-\uFFFF]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js index c535e65da4b8..927ab95cd054 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\W/ug; const matchingRange = /[\0-\/:-@\[-\^`\{-\u{10FFFF}]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js index aa90343bdba6..4e046677b083 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\W+/ug; const matchingRange = /[\0-\/:-@\[-\^`\{-\u{10FFFF}]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier.js index e7ca5f3d77ef..72ae2d081272 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\W+/g; const matchingRange = /[\0-\/:-@\[-\^`\{-\uFFFF]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape.js index b03a32bfcdf1..8edd1eff2a5f 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\W/g; const matchingRange = /[\0-\/:-@\[-\^`\{-\uFFFF]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js index 82a29ae44707..330a2216b845 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\s/ug; const matchingRange = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js index 128dd8bcb6f8..5e7187a9954d 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\s+/ug; const matchingRange = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier.js index 509c8ac6f8ea..1ebbe187d379 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\s+/g; const matchingRange = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape.js index 5e5e4e38759d..1224f5662b1f 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-whitespace-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\s/g; const matchingRange = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js index 92df2344e1da..7e1e0e8f7170 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\w/ug; const matchingRange = /[0-9A-Z_a-z]/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js index 4c0db445a73e..f3ad6b6758ca 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier-flags-u.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0x10ffff / 0x10000); - -for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0x10FFFF]]}); const re = /\w+/ug; const matchingRange = /[0-9A-Z_a-z]+/ug; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier.js index 7de6488fc8d9..0a67c0115ead 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape-plus-quantifier.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\w+/g; const matchingRange = /[0-9A-Z_a-z]+/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape.js index 5275ba2cf960..9073fadade32 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/character-class-word-class-escape.js @@ -33,15 +33,10 @@ info: | The production CharacterClassEscape :: W evaluates as follows: Return the set of all characters not included in the set returned by CharacterClassEscape :: w. features: [String.fromCodePoint] +includes: [regExpUtils.js] ---*/ -const chunks = []; -const totalChunks = Math.ceil(0xffff / 0x10000); - -for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) { - // split strings to avoid a super long one; - chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint); -} +const str = buildString({loneCodePoints: [], ranges: [[0, 0xFFFF]]}); const re = /\w/g; const matchingRange = /[0-9A-Z_a-z]/g; @@ -52,16 +47,14 @@ function matching(str) { return str.replace(re, '') === str.replace(matchingRange, ''); } -for (const str of chunks) { - if (!matching(str)) { - // Error, let's find out where - for (const char of str) { - if (!matching(char)) { - errors.push('0x' + char.codePointAt(0).toString(16)); - } +if (!matching(str)) { + // Error, let's find out where + for (const char of str) { + if (!matching(char)) { + errors.push('0x' + char.codePointAt(0).toString(16)); } } -}; +} assert.sameValue( errors.length, diff --git a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js index e69de29bb2d1..0b9f5373317f 100644 --- a/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/CharacterClassEscapes/shell.js @@ -0,0 +1,58 @@ +// file: regExpUtils.js +// Copyright (C) 2017 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of functions used to assert the correctness of RegExp objects. +---*/ + +function buildString({ loneCodePoints, ranges }) { + const CHUNK_SIZE = 10000; + let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const start = range[0]; + const end = range[1]; + const codePoints = []; + for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { + codePoints[length++] = codePoint; + if (length === CHUNK_SIZE) { + result += Reflect.apply(String.fromCodePoint, null, codePoints); + codePoints.length = length = 0; + } + } + result += Reflect.apply(String.fromCodePoint, null, codePoints); + } + return result; +} + +function testPropertyEscapes(regex, string, expression) { + if (!regex.test(string)) { + for (const symbol of string) { + const hex = symbol + .codePointAt(0) + .toString(16) + .toUpperCase() + .padStart(6, "0"); + assert( + regex.test(symbol), + `\`${ expression }\` should match U+${ hex } (\`${ symbol }\`)` + ); + } + } +} + +// Returns a function that will validate RegExp match result +// +// Example: +// +// var validate = matchValidator(['b'], 1, 'abc'); +// validate(/b/.exec('abc')); +// +function matchValidator(expectedEntries, expectedIndex, expectedInput) { + return function(match) { + assert.compareArray(match, expectedEntries, 'Match entries'); + assert.sameValue(match.index, expectedIndex, 'Match index'); + assert.sameValue(match.input, expectedInput, 'Match input'); + } +} diff --git a/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js b/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js index 5dda00582dba..0b9f5373317f 100644 --- a/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/property-escapes/generated/shell.js @@ -8,17 +8,20 @@ description: | function buildString({ loneCodePoints, ranges }) { const CHUNK_SIZE = 10000; - let result = String.fromCodePoint(...loneCodePoints); - for (const [start, end] of ranges) { + let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const start = range[0]; + const end = range[1]; const codePoints = []; for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { codePoints[length++] = codePoint; if (length === CHUNK_SIZE) { - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); codePoints.length = length = 0; } } - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); } return result; } diff --git a/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js b/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js index 5540020ee8f7..9c48884e7494 100644 --- a/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js +++ b/js/src/tests/test262/built-ins/RegExp/prototype/Symbol.matchAll/shell.js @@ -44,17 +44,20 @@ description: | function buildString({ loneCodePoints, ranges }) { const CHUNK_SIZE = 10000; - let result = String.fromCodePoint(...loneCodePoints); - for (const [start, end] of ranges) { + let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const start = range[0]; + const end = range[1]; const codePoints = []; for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { codePoints[length++] = codePoint; if (length === CHUNK_SIZE) { - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); codePoints.length = length = 0; } } - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); } return result; } diff --git a/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js b/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js index 5540020ee8f7..9c48884e7494 100644 --- a/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js +++ b/js/src/tests/test262/built-ins/RegExpStringIteratorPrototype/next/shell.js @@ -44,17 +44,20 @@ description: | function buildString({ loneCodePoints, ranges }) { const CHUNK_SIZE = 10000; - let result = String.fromCodePoint(...loneCodePoints); - for (const [start, end] of ranges) { + let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const start = range[0]; + const end = range[1]; const codePoints = []; for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { codePoints[length++] = codePoint; if (length === CHUNK_SIZE) { - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); codePoints.length = length = 0; } } - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); } return result; } diff --git a/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js b/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js index 5540020ee8f7..9c48884e7494 100644 --- a/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js +++ b/js/src/tests/test262/built-ins/String/prototype/matchAll/shell.js @@ -44,17 +44,20 @@ description: | function buildString({ loneCodePoints, ranges }) { const CHUNK_SIZE = 10000; - let result = String.fromCodePoint(...loneCodePoints); - for (const [start, end] of ranges) { + let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const start = range[0]; + const end = range[1]; const codePoints = []; for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { codePoints[length++] = codePoint; if (length === CHUNK_SIZE) { - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); codePoints.length = length = 0; } } - result += String.fromCodePoint(...codePoints); + result += Reflect.apply(String.fromCodePoint, null, codePoints); } return result; } diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js new file mode 100644 index 000000000000..2c352b2dd0d8 --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js @@ -0,0 +1,37 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat +description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor. +info: | + InitializeRelativeTimeFormat (relativeTimeFormat, locales, options) +features: [Intl.RelativeTimeFormat] +---*/ + +Object.defineProperties(Object.prototype, { + "style": { + value: "short", + }, + "numeric": { + value: "auto", + }, +}) + +const optionsArguments = [ + true, + "test", + 7, + Symbol(), +]; + +for (const options of optionsArguments) { + const rtf = new Intl.RelativeTimeFormat([], options); + const resolvedOptions = rtf.resolvedOptions(); + assert.sameValue(resolvedOptions.style, "short", + `options argument ${String(options)} should yield the correct value for "style"`); + assert.sameValue(resolvedOptions.numeric, "auto", + `options argument ${String(options)} should yield the correct value for "numeric"`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js new file mode 100644 index 000000000000..872308d07842 --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js @@ -0,0 +1,28 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat +description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor. +info: | + InitializeRelativeTimeFormat (relativeTimeFormat, locales, options) +features: [Intl.RelativeTimeFormat] +---*/ + +const optionsArguments = [ + true, + "test", + 7, + Symbol(), +]; + +for (const options of optionsArguments) { + const rtf = new Intl.RelativeTimeFormat([], options); + const resolvedOptions = rtf.resolvedOptions(); + assert.sameValue(resolvedOptions.style, "long", + `options argument ${String(options)} should yield the correct value for "style"`); + assert.sameValue(resolvedOptions.numeric, "always", + `options argument ${String(options)} should yield the correct value for "numeric"`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js new file mode 100644 index 000000000000..698e7318c3cc --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js @@ -0,0 +1,40 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat +description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor. +info: | + InitializeRelativeTimeFormat (relativeTimeFormat, locales, options) +features: [Intl.RelativeTimeFormat] +---*/ + +Object.defineProperties(Object.prototype, { + "style": { + get() { + throw new Error("Should not call style getter"); + } + }, + "numeric": { + get() { + throw new Error("Should not call numeric getter"); + } + }, +}) + +const optionsArguments = [ + [], + [[]], + [[], undefined], +]; + +for (const args of optionsArguments) { + const rtf = new Intl.RelativeTimeFormat(...args); + const resolvedOptions = rtf.resolvedOptions(); + assert.sameValue(resolvedOptions.style, "long", + `Calling with ${args.length} empty arguments should yield the correct value for "style"`); + assert.sameValue(resolvedOptions.numeric, "always", + `Calling with ${args.length} empty arguments should yield the correct value for "numeric"`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js new file mode 100644 index 000000000000..57cfa4a3ee73 --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js @@ -0,0 +1,22 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf +description: Checks error cases for the locales argument to the supportedLocalesOf function. +info: | + Intl.RelativeTimeFormat.supportedLocalesOf ( locales [, options ]) + + 2. Let requestedLocales be CanonicalizeLocaleList(locales). +includes: [testIntl.js] +features: [Intl.RelativeTimeFormat] +---*/ + +assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function", + "Should support Intl.RelativeTimeFormat.supportedLocalesOf."); + +for (const [locales, expectedError] of getInvalidLocaleArguments()) { + assert.throws(expectedError, () => Intl.RelativeTimeFormat.supportedLocalesOf(locales)); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js new file mode 100644 index 000000000000..854f9ca3d703 --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js @@ -0,0 +1,36 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf +description: Checks handling of invalid values for the localeMatcher option to the supportedLocalesOf function. +info: | + SupportedLocales ( availableLocales, requestedLocales, options ) + + 1. If options is not undefined, then + b. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit"). +features: [Intl.RelativeTimeFormat] +---*/ + +assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function", + "Should support Intl.RelativeTimeFormat.supportedLocalesOf."); + +const invalidOptions = [ + null, + 1, + "", + "Lookup", + "LOOKUP", + "lookup\0", + "Best fit", + "BEST FIT", + "best\u00a0fit", +]; + +for (const invalidOption of invalidOptions) { + assert.throws(RangeError, function() { + Intl.RelativeTimeFormat.supportedLocalesOf([], {"localeMatcher": invalidOption}); + }, `${invalidOption} is an invalid localeMatcher option value`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js new file mode 100644 index 000000000000..be15359c46cf --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js @@ -0,0 +1,22 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf +description: Checks handling of a null options argument to the supportedLocalesOf function. +info: | + SupportedLocales ( availableLocales, requestedLocales, options ) + + 1. If options is not undefined, then + a. Let options be ? ToObject(options). +features: [Intl.RelativeTimeFormat] +---*/ + +assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function", + "Should support Intl.RelativeTimeFormat.supportedLocalesOf."); + +assert.throws(TypeError, function() { + Intl.RelativeTimeFormat.supportedLocalesOf([], null); +}, "Should throw when passing null as the options argument"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js new file mode 100644 index 000000000000..036883f5cac6 --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js @@ -0,0 +1,43 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf +description: Checks handling of non-object options arguments to the supportedLocalesOf function. +info: | + SupportedLocales ( availableLocales, requestedLocales, options ) + + 1. If options is not undefined, then + a. Let options be ? ToObject(options). +features: [Intl.RelativeTimeFormat] +---*/ + +assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function", + "Should support Intl.RelativeTimeFormat.supportedLocalesOf."); + +let called; +Object.defineProperties(Object.prototype, { + "localeMatcher": { + get() { + ++called; + return "best fit"; + } + } +}); + +const optionsArguments = [ + true, + "test", + 7, + Symbol(), +]; + +for (const options of optionsArguments) { + called = 0; + const result = Intl.RelativeTimeFormat.supportedLocalesOf([], options); + assert.sameValue(Array.isArray(result), true, `Expected array from ${String(options)}`); + assert.sameValue(called, 1, `Expected one call from ${String(options)}`); +} + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js new file mode 100644 index 000000000000..9a0832ec149e --- /dev/null +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js @@ -0,0 +1,28 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf +description: Checks handling of an undefined options argument to the supportedLocalesOf function. +info: | + SupportedLocales ( availableLocales, requestedLocales, options ) + + 1. If options is not undefined, then + b. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit"). +features: [Intl.RelativeTimeFormat] +---*/ + +assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function", + "Should support Intl.RelativeTimeFormat.supportedLocalesOf."); + +Object.defineProperties(Object.prototype, { + "localeMatcher": { + get() { throw new Error("Should not call localeMatcher getter"); } + } +}); + +assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf()), true, "No arguments"); +assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf([])), true, "One argument"); +assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf([], undefined)), true, "Two arguments"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js index 09a186cb47cf..bda1cc8686d0 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js @@ -30,6 +30,11 @@ const exceptions = { "0": "this year", "1": "next year", }, + "quarter": { + "-1": "last quarter", + "0": "this quarter", + "1": "next quarter", + }, "month": { "-1": "last month", "0": "this month", diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js index 4101226b0c1f..869ce5036a72 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js @@ -9,14 +9,14 @@ locale: [en-US] ---*/ const units = { - "second": "sec.", - "minute": "min.", - "hour": "hr.", - "day": undefined, - "week": "wk.", - "month": "mo.", - "quarter": "qtr.", - "year": "yr.", + "second": ["sec."], + "minute": ["min."], + "hour": ["hr."], + "day": ["day", "days"], + "week": ["wk."], + "month": ["mo."], + "quarter": ["qtr.", "qtrs."], + "year": ["yr."], }; const rtf = new Intl.RelativeTimeFormat("en-US", { @@ -25,9 +25,8 @@ const rtf = new Intl.RelativeTimeFormat("en-US", { assert.sameValue(typeof rtf.format, "function", "format should be supported"); -for (const [unitArgument, unitString] of Object.entries(units)) { - const singular = unitString || `${unitArgument}`; - const plural = unitString || `${unitArgument}s`; +for (const [unitArgument, unitStrings] of Object.entries(units)) { + const [singular, plural = singular] = unitStrings; assert.sameValue(rtf.format(1000, unitArgument), `in 1,000 ${plural}`); assert.sameValue(rtf.format(10, unitArgument), `in 10 ${plural}`); assert.sameValue(rtf.format(2, unitArgument), `in 2 ${plural}`); diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js index 032bd1405da1..2b318d9e0ad9 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js @@ -18,9 +18,9 @@ function always(s) { // https://www.unicode.org/cldr/charts/33/summary/pl.html#1419 const units = { - "second": always("s"), + "second": always("sek."), "minute": always("min"), - "hour": always("g."), + "hour": always("godz."), "day": { "many": "dni", "few": "dni", diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js index 91b1fdf04184..7d33eb0f201f 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js @@ -26,6 +26,11 @@ function expected(key, unit, default_) { "0": "this year", "1": "next year", }, + "quarter": { + "-1": "last quarter", + "0": "this quarter", + "1": "next quarter", + }, "month": { "-1": "last month", "0": "this month", diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js index adc032f5b3ea..9623580aca72 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js @@ -19,14 +19,14 @@ function verifyFormatParts(actual, expected, message) { } const units = { - "second": "sec.", - "minute": "min.", - "hour": "hr.", - "day": undefined, - "week": "wk.", - "month": "mo.", - "quarter": "qtr.", - "year": "yr.", + "second": ["sec."], + "minute": ["min."], + "hour": ["hr."], + "day": ["day", "days"], + "week": ["wk."], + "month": ["mo."], + "quarter": ["qtr.", "qtrs."], + "year": ["yr."], }; const rtf = new Intl.RelativeTimeFormat("en-US", { @@ -35,9 +35,8 @@ const rtf = new Intl.RelativeTimeFormat("en-US", { assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported"); -for (const [unitArgument, unitString] of Object.entries(units)) { - const singular = unitString || `${unitArgument}`; - const plural = unitString || `${unitArgument}s`; +for (const [unitArgument, unitStrings] of Object.entries(units)) { + const [singular, plural = singular] = unitStrings; verifyFormatParts(rtf.formatToParts(1000, unitArgument), [ { "type": "literal", "value": "in " }, diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js index 192969d74d9b..d5decfa0fcc5 100644 --- a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js +++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js @@ -28,9 +28,9 @@ function always(s) { // https://www.unicode.org/cldr/charts/33/summary/pl.html#1419 const units = { - "second": always("sek."), + "second": always("s"), "minute": always("min"), - "hour": always("godz."), + "hour": always("g."), "day": { "many": "dni", "few": "dni", @@ -51,7 +51,7 @@ const units = { }; const rtf = new Intl.RelativeTimeFormat("pl-PL", { - "style": "short", + "style": "narrow", }); assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported"); From e62649a9d063bf6721867426517e39e17167536b Mon Sep 17 00:00:00 2001 From: Ashley Hauck Date: Tue, 21 Aug 2018 13:14:00 -0400 Subject: [PATCH 35/49] Bug 1473228 - Add @@toStringTag in Intl.RelativeTimeFormat. r=jorendorff --- js/src/builtin/intl/RelativeTimeFormat.cpp | 8 ++++++++ js/src/tests/jstests.list | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/js/src/builtin/intl/RelativeTimeFormat.cpp b/js/src/builtin/intl/RelativeTimeFormat.cpp index 77e98ebb8548..8f5c9904eb19 100644 --- a/js/src/builtin/intl/RelativeTimeFormat.cpp +++ b/js/src/builtin/intl/RelativeTimeFormat.cpp @@ -68,6 +68,11 @@ static const JSFunctionSpec relativeTimeFormat_methods[] = { JS_FS_END }; +static const JSPropertySpec relativeTimeFormat_properties[] = { + JS_STRING_SYM_PS(toStringTag, "Intl.RelativeTimeFormat", JSPROP_READONLY), + JS_PS_END +}; + /** * RelativeTimeFormat constructor. * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.1 @@ -148,6 +153,9 @@ js::CreateRelativeTimeFormatPrototype(JSContext* cx, HandleObject Intl, if (!JS_DefineFunctions(cx, proto, relativeTimeFormat_methods)) return nullptr; + if (!JS_DefineProperties(cx, proto, relativeTimeFormat_properties)) + return nullptr; + RootedValue ctorValue(cx, ObjectValue(*ctor)); if (!DefineDataProperty(cx, Intl, cx->names().RelativeTimeFormat, ctorValue, 0)) return nullptr; diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list index 40446e9d1dc7..e04344adce53 100644 --- a/js/src/tests/jstests.list +++ b/js/src/tests/jstests.list @@ -451,10 +451,6 @@ skip script test262/built-ins/Reflect/ownKeys/return-on-corresponding-order-larg skip script test262/intl402/ListFormat/prototype/toStringTag/toString.js skip script test262/intl402/ListFormat/prototype/toStringTag/toStringTag.js -# https://bugzilla.mozilla.org/show_bug.cgi?id=1473228 -skip script test262/intl402/RelativeTimeFormat/prototype/toStringTag/toString.js -skip script test262/intl402/RelativeTimeFormat/prototype/toStringTag/toStringTag.js - # https://bugzilla.mozilla.org/show_bug.cgi?id=1473228 skip script test262/intl402/Segmenter/prototype/toStringTag/toString.js skip script test262/intl402/Segmenter/prototype/toStringTag/toStringTag.js From 312b0e9b019216c147eee8f66c238c02de3125b3 Mon Sep 17 00:00:00 2001 From: Ashley Hauck Date: Mon, 20 Aug 2018 14:34:00 -0400 Subject: [PATCH 36/49] Bug 1449540 - Allow modification of ArrayBuffer's __proto__. r=jorendorff --- js/src/tests/non262/Proxy/regress-bug950407.js | 10 +++------- js/src/tests/non262/regress/regress-665355.js | 7 +++++-- js/src/vm/JSObject.cpp | 11 ----------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/js/src/tests/non262/Proxy/regress-bug950407.js b/js/src/tests/non262/Proxy/regress-bug950407.js index bb4a71eb042e..d253c75fc2fb 100644 --- a/js/src/tests/non262/Proxy/regress-bug950407.js +++ b/js/src/tests/non262/Proxy/regress-bug950407.js @@ -1,11 +1,7 @@ var ab = new ArrayBuffer(5); var p = new Proxy(ab, {}); var ps = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set; -var threw = 0; -try { - ps.call(p, {}); -} catch(ex) { - threw = 1; -} +var new_proto = {}; +ps.call(p, new_proto); -reportCompare(1, threw, "Setting __proto__ on a proxy to an ArrayBuffer must throw."); +reportCompare(ab.__proto__, new_proto); diff --git a/js/src/tests/non262/regress/regress-665355.js b/js/src/tests/non262/regress/regress-665355.js index ef91161c40ff..c027fa8a6447 100644 --- a/js/src/tests/non262/regress/regress-665355.js +++ b/js/src/tests/non262/regress/regress-665355.js @@ -9,8 +9,11 @@ try { } } +// assert cycle doesn't work assertEq(test(x), true); -assertEq(test({}), true); -assertEq(test(null), true); + +// works +assertEq(test({}), false); +assertEq(test(null), false); reportCompare(true, true); diff --git a/js/src/vm/JSObject.cpp b/js/src/vm/JSObject.cpp index 4cf0f84b993b..ebf37f376d31 100644 --- a/js/src/vm/JSObject.cpp +++ b/js/src/vm/JSObject.cpp @@ -2683,17 +2683,6 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object if (obj->staticPrototypeIsImmutable()) return result.fail(JSMSG_CANT_SET_PROTO); - /* - * Disallow mutating the [[Prototype]] on ArrayBuffer objects, which - * due to their complicated delegate-object shenanigans can't easily - * have a mutable [[Prototype]]. - */ - if (obj->is()) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_PROTO_OF, - "incompatible ArrayBuffer"); - return false; - } - /* * Disallow mutating the [[Prototype]] on Typed Objects, per the spec. */ From 35528f5d01d42fd67e69d51898c0a03dcec190da Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 11 Jul 2018 17:07:16 -0500 Subject: [PATCH 37/49] Bug 1475417 - Part 0: Add some passing tests. r=jimb Also deletes two tests that are completely redundant ever since we removed legacy generators. --- .../Debugger-onEnterFrame-resumption-03.js | 4 +- js/src/jit-test/tests/debug/Frame-live-06.js | 26 ++++++++ .../tests/debug/Frame-onPop-generators-04.js | 26 ++++++++ .../debug/Frame-onPop-star-generators-01.js | 20 ------- .../debug/Frame-onPop-star-generators-02.js | 21 ------- .../debug/Frame-onStep-generators-defaults.js | 33 ++++++++++ .../jit-test/tests/debug/breakpoint-oom-01.js | 39 ++++++++++++ ...Statement-async-generator-resumption-01.js | 60 +++++++++++++++++++ ...onDebuggerStatement-async-resumption-01.js | 34 +++++++++++ .../debug/onEnterFrame-async-resumption-01.js | 33 ++++++++++ 10 files changed, 253 insertions(+), 43 deletions(-) create mode 100644 js/src/jit-test/tests/debug/Frame-live-06.js create mode 100644 js/src/jit-test/tests/debug/Frame-onPop-generators-04.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js create mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js create mode 100644 js/src/jit-test/tests/debug/breakpoint-oom-01.js create mode 100644 js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js create mode 100644 js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js diff --git a/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js b/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js index a42f2183a3a4..e28b014944f2 100644 --- a/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js +++ b/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js @@ -1,4 +1,4 @@ -// If debugger.onEnterFrame returns {return:val}, the frame returns immediately. +// If debugger.onEnterFrame returns null, the debuggee is terminated immediately. load(libdir + "asserts.js"); @@ -13,7 +13,7 @@ dbg.onDebuggerStatement = function (frame) { innerSavedFrame = frame; return null; }; - // Using frame.eval lets us catch termination. + // Using frame.eval lets us catch termination. assertEq(frame.eval("set = true;"), null); assertEq(innerSavedFrame.live, false); savedFrame = frame; diff --git a/js/src/jit-test/tests/debug/Frame-live-06.js b/js/src/jit-test/tests/debug/Frame-live-06.js new file mode 100644 index 000000000000..f1cc4abf1af8 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-live-06.js @@ -0,0 +1,26 @@ +// frame.live is false for generator frames after they return. + +let g = newGlobal(); +g.eval("function* f() { debugger; }"); + +let dbg = Debugger(g); +let savedFrame; + +dbg.onDebuggerStatement = frame => { + savedFrame = frame; + assertEq(frame.callee.name, "f"); + assertEq(frame.live, true); + frame.onPop = function() { + assertEq(frame.live, true); + }; +}; +g.f().next(); + +assertEq(savedFrame.live, false); +try { + savedFrame.older; + throw new Error("expected exception, none thrown"); +} catch (exc) { + assertEq(exc.message, "Debugger.Frame is not live"); +} + diff --git a/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js b/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js new file mode 100644 index 000000000000..2c686e278efb --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js @@ -0,0 +1,26 @@ +// Terminating a generator from the onPop callback for its initial yield +// leaves the Frame in a sane but inactive state. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval("function* f(x) { yield x; }"); +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +let genFrame = null; +dbg.onDebuggerStatement = frame => { + dbg.onEnterFrame = frame => { + if (frame.callee == gw.getOwnPropertyDescriptor("f").value) { + genFrame = frame; + frame.onPop = completion => null; + } + }; + assertEq(frame.eval("f(0);"), null); +}; + +g.eval("debugger;"); + +assertEq(genFrame instanceof Debugger.Frame, true); +assertEq(genFrame.live, false); +assertThrowsInstanceOf(() => genFrame.callee, Error); diff --git a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js deleted file mode 100644 index 73cf3c8c7d3b..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js +++ /dev/null @@ -1,20 +0,0 @@ -// Returning {throw:} from an onPop handler when yielding works and -// closes the generator-iterator. - -load(libdir + "iteration.js"); - -var g = newGlobal(); -var dbg = new Debugger; -var gw = dbg.addDebuggee(g); -dbg.onDebuggerStatement = function handleDebugger(frame) { - frame.onPop = function (c) { - return {throw: "fit"}; - }; -}; -g.eval("function* g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }"); -g.eval("var it = g();"); -var rv = gw.executeInGlobal("it.next();"); -assertEq(rv.throw, "fit"); - -dbg.enabled = false; -assertIteratorDone(g.it); diff --git a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js deleted file mode 100644 index de9ad5009825..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js +++ /dev/null @@ -1,21 +0,0 @@ -// |jit-test| error: fit - -// Throwing an exception from an onPop handler when yielding terminates the debuggee -// but does not close the generator-iterator. - -load(libdir + 'iteration.js') - -var g = newGlobal(); -var dbg = new Debugger; -var gw = dbg.addDebuggee(g); -dbg.onDebuggerStatement = function handleDebugger(frame) { - frame.onPop = function (c) { - throw "fit"; - }; -}; -g.eval("function* g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }"); -g.eval("var it = g();"); -assertEq(gw.executeInGlobal("it.next();"), null); - -dbg.enabled = false; -assertIteratorNext(g.it, 1); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js new file mode 100644 index 000000000000..0c337636ee3c --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js @@ -0,0 +1,33 @@ +// onStep works during the evaluation of default parameter values in generators. +// +// (They're evaluated at a weird time in the generator life cycle, before the +// generator object is created.) + +let g = newGlobal(); +g.eval(`\ + function f1() {} // line 1 + function f2() {} // 2 + function f3() {} // 3 + // 4 + function* gen( // 5 + name, // 6 + schema = f1(), // 7 + timeToLive = f2(), // 8 + lucidity = f3() // 9 + ) { // 10 + } // 11 +`); + +let dbg = Debugger(g); +let log = []; +dbg.onEnterFrame = frame => { + frame.onStep = () => { + let line = frame.script.getOffsetLocation(frame.offset).lineNumber; + if (log.length == 0 || line != log[log.length - 1]) { + log.push(line); + } + }; +}; + +g.gen(0); +assertEq(log.toSource(), [5, 7, 1, 8, 2, 9, 3, 10].toSource()); diff --git a/js/src/jit-test/tests/debug/breakpoint-oom-01.js b/js/src/jit-test/tests/debug/breakpoint-oom-01.js new file mode 100644 index 000000000000..50b9ff7d9aaf --- /dev/null +++ b/js/src/jit-test/tests/debug/breakpoint-oom-01.js @@ -0,0 +1,39 @@ +// Test for OOM hitting a breakpoint in a generator. +// +// (The purpose is to test OOM-handling in the code that creates the +// Debugger.Frame object and associates it with the generator object.) + +let g = newGlobal(); +g.eval(`\ + function* gen(x) { // line 1 + x++; // 2 + yield x; // 3 + } // 4 +`); + +let dbg = new Debugger; + +// On OOM in the debugger, propagate it to the debuggee. +dbg.uncaughtExceptionHook = exc => exc === "out of memory" ? {throw: exc} : null; + +let gw = dbg.addDebuggee(g); +let script = gw.makeDebuggeeValue(g.gen).script; +let hits = 0; +let handler = { + hit(frame) { + hits++; + print("x=", frame.environment.getVariable("x")); + } +}; +for (let offset of script.getLineOffsets(2)) + script.setBreakpoint(offset, handler); + +let result; +oomTest(() => { + hits = 0; + result = g.gen(1).next(); +}, false); +assertEq(hits, 1); +assertEq(result.done, false); +assertEq(result.value, 2); + diff --git a/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js b/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js new file mode 100644 index 000000000000..bb83f6470e2c --- /dev/null +++ b/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js @@ -0,0 +1,60 @@ +// A Debugger can {return:} from onDebuggerStatement in an async generator. +// A resolved promise for a {value: _, done: true} object is returned. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(` + async function* f(x) { + debugger; // when==0 to force return here + await x; + yield 1; + debugger; // when==1 to force return here + } +`); + +let exc = null; +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); +function test(when) { + let hits = 0; + let outcome = "FAIL"; + dbg.onDebuggerStatement = frame => { + if (hits++ == when) + return {return: "ponies"}; + }; + + let iter = g.f(0); + + // At the initial suspend. + assertEq(hits, 0); + iter.next().then(result => { + // At the yield point, unless we already force-returned from the first + // debugger statement. + assertEq(hits, 1); + if (when == 0) + return result; + assertEq(result.value, 1); + assertEq(result.done, false); + return iter.next(); + }).then(result => { + // After forced return. + assertEq(hits, when + 1); + assertEq(result.value, "ponies"); + assertEq(result.done, true); + outcome = "pass"; + }).catch(e => { + // An assertion failed. + exc = e; + }); + + assertEq(hits, 1); + drainJobQueue(); + if (exc !== null) + throw exc; + assertEq(outcome, "pass"); +} + +for (let i = 0; i < 2; i++) { + test(i); +} diff --git a/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js b/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js new file mode 100644 index 000000000000..8f3f2c094224 --- /dev/null +++ b/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js @@ -0,0 +1,34 @@ +// A Debugger can {return:} from onDebuggerStatement in an async function. +// The async function's promise is resolved with the returned value. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(` + async function f(x) { + debugger; // when==0 to force return here + await x; + debugger; // when==1 to force return here + } +`); + +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); +function test(when, what, expected) { + let hits = 0; + let result = "FAIL"; + dbg.onDebuggerStatement = frame => { + if (hits++ == when) + return {return: gw.makeDebuggeeValue(what)}; + }; + g.f(0).then(x => { result = x; }); + assertEq(hits, 1); + drainJobQueue(); + assertEq(hits, when + 1); + assertEq(result, expected); +} + +for (let i = 0; i < 2; i++) { + test(i, "ok", "ok"); + test(i, g.Promise.resolve(37), 37); +} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js new file mode 100644 index 000000000000..fbfc2c84a5a8 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js @@ -0,0 +1,33 @@ +// A Debugger can {return:} from the first onEnterFrame for an async function. +// (The exact behavior is undocumented; we're testing that it doesn't crash.) + +let g = newGlobal(); +g.hit2 = false; +g.eval(`async function f(x) { await x; return "ponies"; }`); + +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); +let hits = 0; +let resumption = undefined; +dbg.onEnterFrame = frame => { + if (frame.type == "call" && frame.callee.name === "f") { + frame.onPop = completion => { + assertEq(completion.return, resumption.return); + hits++; + }; + + // Don't tell anyone, but if we force-return a generator object here, + // the robots accept it as one of their own and plug it right into the + // async function machinery. This may be handy against Skynet someday. + resumption = frame.eval(`(function* f2() { hit2 = true; throw "fit"; })()`); + assertEq(resumption.return.class, "Generator"); + return resumption; + } +}; + +let p = g.f(0); +assertEq(hits, 1); +let pw = gw.makeDebuggeeValue(p); +assertEq(pw.isPromise, true); +assertEq(pw.promiseState, "rejected"); +assertEq(pw.promiseReason, "fit"); From 5cd444cdaaae493f16541fea863df5f9df717189 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Thu, 12 Jul 2018 19:43:55 -0500 Subject: [PATCH 38/49] Bug 1475417 - Part 1: Minor code tweaks, in preparation. There should be no observable change in behavior yet. r=jandem --- js/src/jit/BaselineCompiler.cpp | 4 ++-- js/src/jit/VMFunctions.cpp | 4 ++++ js/src/vm/GeneratorObject.cpp | 18 +++--------------- js/src/vm/GeneratorObject.h | 4 ++-- js/src/vm/Interpreter.cpp | 16 +++++++++++++--- js/src/vm/Stack.h | 2 +- 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 02855855dd09..df3a04f1c470 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -4693,7 +4693,7 @@ static const VMFunction InterpretResumeInfo = typedef bool (*GeneratorThrowFn)(JSContext*, BaselineFrame*, Handle, HandleValue, uint32_t); -static const VMFunction GeneratorThrowInfo = +static const VMFunction GeneratorThrowOrReturnInfo = FunctionInfo(jit::GeneratorThrowOrReturn, "GeneratorThrowOrReturn", TailCall); bool @@ -4878,7 +4878,7 @@ BaselineCompiler::emit_JSOP_RESUME() pushArg(genObj); pushArg(scratch2); - TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(GeneratorThrowInfo); + TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(GeneratorThrowOrReturnInfo); // Create the frame descriptor. masm.subStackPtrFrom(scratch1); diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index e54d4063811d..8b91a778cd43 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -977,6 +977,10 @@ GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, HandleyieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()]; frame->setOverridePc(script->offsetToPC(offset)); + // In the interpreter, GeneratorObject::resume marks the generator as running, + // so we do the same. + genObj->setRunning(); + MOZ_ALWAYS_TRUE(DebugAfterYield(cx, frame)); MOZ_ALWAYS_FALSE(js::GeneratorThrowOrReturn(cx, frame, genObj, arg, resumeKind)); return false; diff --git a/js/src/vm/GeneratorObject.cpp b/js/src/vm/GeneratorObject.cpp index 4e983ae57d09..d4d61743c23e 100644 --- a/js/src/vm/GeneratorObject.cpp +++ b/js/src/vm/GeneratorObject.cpp @@ -134,7 +134,6 @@ js::GeneratorThrowOrReturn(JSContext* cx, AbstractFramePtr frame, HandlesetPendingException(arg); - genObj->setRunning(); } else { MOZ_ASSERT(resumeKind == GeneratorObject::RETURN); @@ -150,9 +149,8 @@ js::GeneratorThrowOrReturn(JSContext* cx, AbstractFramePtr frame, Handle genObj, HandleValue arg) { - Rooted genObj(cx, &obj->as()); MOZ_ASSERT(genObj->isSuspended()); RootedFunction callee(cx, &genObj->callee()); @@ -184,18 +182,8 @@ GeneratorObject::resume(JSContext* cx, InterpreterActivation& activation, MOZ_ASSERT(activation.regs().spForStackDepth(activation.regs().stackDepth())); activation.regs().sp[-1] = arg; - switch (resumeKind) { - case NEXT: - genObj->setRunning(); - return true; - - case THROW: - case RETURN: - return GeneratorThrowOrReturn(cx, activation.regs().fp(), genObj, arg, resumeKind); - - default: - MOZ_CRASH("bad resumeKind"); - } + genObj->setRunning(); + return true; } const Class GeneratorObject::class_ = { diff --git a/js/src/vm/GeneratorObject.h b/js/src/vm/GeneratorObject.h index e9f9de70a204..d09510021117 100644 --- a/js/src/vm/GeneratorObject.h +++ b/js/src/vm/GeneratorObject.h @@ -60,7 +60,7 @@ class GeneratorObject : public NativeObject static JSObject* create(JSContext* cx, AbstractFramePtr frame); static bool resume(JSContext* cx, InterpreterActivation& activation, - HandleObject obj, HandleValue arg, ResumeKind resumeKind); + Handle genObj, HandleValue arg); static bool initialSuspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc) { return suspend(cx, obj, frame, pc, nullptr, 0); @@ -147,7 +147,7 @@ class GeneratorObject : public NativeObject setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_RUNNING)); } void setClosing() { - MOZ_ASSERT(isSuspended()); + MOZ_ASSERT(isRunning()); setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_CLOSING)); } void setYieldAndAwaitIndex(uint32_t yieldAndAwaitIndex) { diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 47c84f3ea35a..468cb1033766 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4267,13 +4267,14 @@ CASE(JSOP_AWAIT) CASE(JSOP_RESUME) { { - ReservedRooted gen(&rootObject0, ®S.sp[-2].toObject()); + Rooted gen(cx, ®S.sp[-2].toObject().as()); ReservedRooted val(&rootValue0, REGS.sp[-1]); // popInlineFrame expects there to be an additional value on the stack // to pop off, so leave "gen" on the stack. GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(REGS.pc); - bool ok = GeneratorObject::resume(cx, activation, gen, val, resumeKind); + if (!GeneratorObject::resume(cx, activation, gen, val)) + goto error; JSScript* generatorScript = REGS.fp()->script(); if (cx->realm() != generatorScript->realm()) @@ -4285,8 +4286,17 @@ CASE(JSOP_RESUME) TraceLogStartEvent(logger, scriptEvent); TraceLogStartEvent(logger, TraceLogger_Interpreter); - if (!ok) + switch (resumeKind) { + case GeneratorObject::NEXT: + break; + case GeneratorObject::THROW: + case GeneratorObject::RETURN: + MOZ_ALWAYS_FALSE(GeneratorThrowOrReturn(cx, activation.regs().fp(), gen, val, + resumeKind)); goto error; + default: + MOZ_CRASH("bad resumeKind"); + } } ADVANCE_AND_DISPATCH(0); } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 65c5307acae4..ddc2cd2b210d 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -2159,7 +2159,7 @@ class FrameIter bool ensureHasRematerializedFrame(JSContext* cx); // True when isInterp() or isBaseline(). True when isIon() if it - // has a rematerialized frame. False otherwise false otherwise. + // has a rematerialized frame. False otherwise. bool hasUsableAbstractFramePtr() const; // ----------------------------------------------------------- From 071656e0824e76ad67b5338eb34caa5339cb0c99 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 15 Aug 2018 15:09:30 -0500 Subject: [PATCH 39/49] Bug 1475417 - Part 2: Fire onEnterFrame when resuming a generator or async function. r=jandem, r=jimb --- js/src/jit-test/tests/debug/Frame-live-07.js | 53 ++++++++++++ .../tests/debug/Frame-onStep-generators-01.js | 31 +++++++ .../tests/debug/Frame-onStep-generators-02.js | 44 ++++++++++ .../tests/debug/Frame-onStep-generators-03.js | 45 +++++++++++ .../debug/onEnterFrame-async-resumption-02.js | 36 +++++++++ .../debug/onEnterFrame-async-resumption-03.js | 30 +++++++ .../tests/debug/onEnterFrame-generator-01.js | 81 +++++++++++++++++++ .../tests/debug/onEnterFrame-generator-02.js | 27 +++++++ .../tests/debug/onEnterFrame-generator-03.js | 25 ++++++ .../onEnterFrame-generator-resumption-01.js | 36 +++++++++ .../onEnterFrame-generator-resumption-02.js | 39 +++++++++ .../onEnterFrame-generator-resumption-03.js | 35 ++++++++ js/src/jit/BaselineCompiler.cpp | 17 +++- js/src/jit/BaselineDebugModeOSR.cpp | 22 ++++- js/src/jit/SharedIC.h | 3 +- js/src/jit/VMFunctions.cpp | 31 +++++-- js/src/jit/VMFunctions.h | 2 +- js/src/vm/Debugger.cpp | 9 +++ js/src/vm/GeneratorObject.h | 4 + js/src/vm/Interpreter.cpp | 14 ++++ 20 files changed, 570 insertions(+), 14 deletions(-) create mode 100644 js/src/jit-test/tests/debug/Frame-live-07.js create mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-01.js create mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-02.js create mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-03.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-01.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-02.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-03.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js create mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js diff --git a/js/src/jit-test/tests/debug/Frame-live-07.js b/js/src/jit-test/tests/debug/Frame-live-07.js new file mode 100644 index 000000000000..da3b4e1bba93 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-live-07.js @@ -0,0 +1,53 @@ +// frame.live is false for generator frames popped due to exception or termination. + +load(libdir + "/asserts.js"); + +function test(when, what) { + let g = newGlobal(); + g.eval("function* f(x) { yield x; }"); + + let dbg = new Debugger; + let gw = dbg.addDebuggee(g); + let fw = gw.getOwnPropertyDescriptor("f").value; + + let t = 0; + let poppedFrame; + + function tick(frame) { + if (frame.callee == fw) { + if (t == when) { + poppedFrame = frame; + dbg.onEnterFrame = undefined; + frame.onPop = undefined; + return what; + } + t++; + } + return undefined; + } + + dbg.onDebuggerStatement = frame => { + dbg.onEnterFrame = frame => { + frame.onPop = function() { + return tick(this); + }; + return tick(frame); + }; + let result = frame.eval("for (let _ of f(0)) {}"); + assertDeepEq(result, what); + }; + g.eval("debugger;"); + + assertEq(t, when); + assertEq(poppedFrame.live, false); + assertErrorMessage(() => poppedFrame.older, + Error, + "Debugger.Frame is not live"); +} + +for (let when = 0; when < 6; when++) { + for (let what of [null, {throw: "fit"}]) { + test(when, what); + } +} + diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js new file mode 100644 index 000000000000..1183f01380e3 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js @@ -0,0 +1,31 @@ +// Stepping into the `.next()` method of a generator works as expected. + +let g = newGlobal(); +g.eval(`\ +function* nums() { // line 1 + yield 1; // 2 + yield 2; // 3 +} // 4 +function f() { // 5 + let gen = nums(); // 6 + gen.next(); // 7 + gen.next(); // 8 + gen.next(); // 9 +} // 10 +`); + +let log = []; +let previousLine = -1; +let dbg = new Debugger(g); +dbg.onEnterFrame = frame => { + frame.onStep = () => { + let line = frame.script.getOffsetLocation(frame.offset).lineNumber; + if (previousLine != line) { // We stepped to a new line. + log.push(line); + previousLine = line; + } + }; +}; + +g.f(); +assertEq(log.join(" "), "5 6 1 6 7 1 2 7 8 2 3 8 9 3 9 10"); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js new file mode 100644 index 000000000000..bc77b3d3cdd3 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js @@ -0,0 +1,44 @@ +// Stepping into the `.throw()` method of a generator with no relevant catch block. +// +// The debugger fires onEnterFrame and then frame.onPop for the generator frame when +// `gen.throw()` is called. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(`\ +function* z() { // line 1 + yield 1; // 2 + yield 2; // 3 +} // 4 +function f() { // 5 + let gen = z(); // 6 + gen.next(); // 7 + gen.throw("fit"); // 8 +} // 9 +`); + +let log = ""; +let previousLine = -1; +let dbg = new Debugger(g); +dbg.onEnterFrame = frame => { + log += frame.callee.name + "{"; + frame.onStep = () => { + let line = frame.script.getOffsetLocation(frame.offset).lineNumber; + if (previousLine != line) { // We stepped to a new line. + log += line; + previousLine = line; + } + }; + frame.onPop = completion => { + if ("throw" in completion) + log += "!"; + log += "}"; + } +}; + +assertThrowsValue(() => g.f(), "fit"); +// z{1} is the initial generator setup. +// z{12} is the first .next() call, running to `yield 1` on line 2 +// The final `z{!}` is for the .throw() call. +assertEq(log, "f{56z{1}67z{12}78z{!}!}"); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js new file mode 100644 index 000000000000..5a49b3c6df08 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js @@ -0,0 +1,45 @@ +// Stepping into the `.throw()` method of a generator with a relevant catch block. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(`\ +function* z() { // line 1 + try { // 2 + yield 1; // 3 + } catch (exc) { // 4 + yield 2; // 5 + } // 6 +} // 7 +function f() { // 8 + let gen = z(); // 9 + gen.next(); // 10 + gen.throw("fit"); // 11 +} // 12 +`); + +let log = []; +let previousLine = -1; +let dbg = new Debugger(g); +dbg.onEnterFrame = frame => { + log.push(frame.callee.name + " in"); + frame.onStep = () => { + let line = frame.script.getOffsetLocation(frame.offset).lineNumber; + if (previousLine != line) { // We stepped to a new line. + log.push(line); + previousLine = line; + } + }; + frame.onPop = completion => { + log.push(frame.callee.name + " out"); + }; +}; + +g.f(); +assertEq( + log.join(", "), + "f in, 8, 9, z in, 1, z out, " + + "9, 10, z in, 1, 2, 3, z out, " + + "10, 11, z in, 2, 4, 5, z out, " + // not sure why we hit line 2 here, source notes bug maybe + "11, 12, f out" +); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js new file mode 100644 index 000000000000..3125654d9772 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js @@ -0,0 +1,36 @@ +// A Debugger can {throw:} from onEnterFrame in an async function. +// The resulting promise (if any) is rejected with the thrown error value. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(` + async function f() { await 1; } + var err = new TypeError("object too hairy"); +`); + +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); +let errw = gw.makeDebuggeeValue(g.err); + +// Repeat the test for each onEnterFrame event. +// It fires up to three times: +// - when the async function g.f is called; +// - when we enter it to run to `await 1`; +// - when we resume after the await to run to the end. +for (let when = 0; when < 3; when++) { + let hits = 0; + dbg.onEnterFrame = frame => { + return hits++ < when ? undefined : {throw: errw}; + }; + + let result = undefined; + g.f() + .then(value => { result = {returned: value}; }) + .catch(err => { result = {threw: err}; }); + + drainJobQueue(); + + assertEq(hits, when + 1); + assertDeepEq(result, {threw: g.err}); +} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js new file mode 100644 index 000000000000..68c3ded27f4f --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js @@ -0,0 +1,30 @@ +// A Debugger can {return:} from onEnterFrame at any resume point in an async function. +// The async function's promise is resolved with the returned value. + +let g = newGlobal(); +g.eval(`async function f(x) { await x; }`); + +let dbg = new Debugger(g); +function test(when) { + let hits = 0; + dbg.onEnterFrame = frame => { + if (frame.type == "call" && frame.callee.name === "f") { + if (hits++ == when) { + return {return: "exit"}; + } + } + }; + + let result = undefined; + let finished = false; + g.f("hello").then(value => { result = value; finished = true; }); + drainJobQueue(); + assertEq(finished, true); + assertEq(hits, when + 1); + assertEq(result, "exit"); +} + +// onEnterFrame with hits==0 is not a resume point; {return:} behaves differently there +// (see onEnterFrame-async-resumption-02.js). +test(1); // force return from first resume point, immediately after the initial suspend +test(2); // force return from second resume point, immediately after the await instruction diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js new file mode 100644 index 000000000000..8cfceba5ba3f --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js @@ -0,0 +1,81 @@ +// Frame properties and methods work in generator-resuming onEnterFrame events. +// Also tests onPop events, for good measure. + +let g = newGlobal(); +g.eval(`\ + function* gen(lo, hi) { + var a = 1/2; + yield a; + yield a * a; + } +`); +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +let hits = 0; +let savedScript = null; +let savedEnv = null; +let savedOffsets = new Set; + +function check(frame) { + assertEq(frame.type, "call"); + assertEq(frame.constructing, false); + assertEq(frame.callee, gw.makeDebuggeeValue(g.gen)); + + // `arguments` elements don't work in resumed generator frames, + // because generators don't keep the arguments around. + // The first onEnterFrame and onPop events can see them. + assertEq(frame.arguments.length, hits < 2 ? args.length : 0); + for (var i = 0; i < frame.arguments.length; i++) { + assertEq(frame.arguments.hasOwnProperty(i), true); + + if (hits < 2) + assertEq(frame.arguments[i], gw.makeDebuggeeValue(args[i]), `arguments[${i}]`); + else + assertEq(frame.arguments[i], undefined); + } + + if (savedEnv === null) { + savedEnv = frame.environment; + assertEq(savedScript, null); + savedScript = frame.script; + } else { + assertEq(frame.environment, savedEnv); + assertEq(frame.script, savedScript); + } + let a_expected = hits < 3 ? undefined : 1/2; + assertEq(savedEnv.getVariable("a"), a_expected); + + assertEq(frame.generator, true); + assertEq(frame.live, true); + + let pc = frame.offset; + assertEq(savedOffsets.has(pc), false); + savedOffsets.add(pc); + + assertEq(frame.older, null); + assertEq(frame.this, gw); + assertEq(typeof frame.implementation, "string"); + + // And the moment of truth: + assertEq(frame.eval("2 + 2").return, 4); + assertEq(frame.eval("a").return, a_expected); + assertEq(frame.eval("if (a !== undefined) { assertEq(a < (lo + hi) / 2, true); } 7;").return, 7); +} + +dbg.onEnterFrame = frame => { + if (frame.type === "eval") + return; + check(frame); + hits++; + frame.onPop = completion => { + check(frame); + hits++; + }; +}; + +// g.gen ignores the arguments passed to it, but we use them to test +// frame.arguments. +let args = [0, 10, g, dbg]; +for (let v of g.gen(...args)) {} +assertEq(hits, 8); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js new file mode 100644 index 000000000000..b6b5e5181650 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js @@ -0,0 +1,27 @@ +// onEnterFrame fires after the [[GeneratorState]] is set to "executing". +// +// This test checks that Debugger doesn't accidentally make it possible to +// reenter a generator frame that's already on the stack. (Also tests a fun +// corner case in baseline debug-mode OSR.) + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval('function* f() { yield 1; yield 2; }'); +let dbg = Debugger(g); +let genObj = null; +let hits = 0; +dbg.onEnterFrame = frame => { + // The first time onEnterFrame fires, there is no generator object, so + // there's nothing to test. The generator object doesn't exist until + // JSOP_GENERATOR is reached, right before the initial yield. + if (genObj !== null) { + dbg.removeDebuggee(g); // avoid the DebuggeeWouldRun exception + assertThrowsInstanceOf(() => genObj.next(), g.TypeError); + dbg.addDebuggee(g); + hits++; + } +}; +genObj = g.f(); +for (let x of genObj) {} +assertEq(hits, 3); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js new file mode 100644 index 000000000000..744313e8d7dd --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js @@ -0,0 +1,25 @@ +// If onEnterFrame terminates a generator, the Frame is left in a sane but inactive state. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval("function* f(x) { yield x; }"); +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +let genFrame = null; +dbg.onDebuggerStatement = frame => { + dbg.onEnterFrame = frame => { + if (frame.callee == gw.getOwnPropertyDescriptor("f").value) { + genFrame = frame; + return null; + } + }; + assertEq(frame.eval("f(0);"), null); +}; + +g.eval("debugger;"); + +assertEq(genFrame instanceof Debugger.Frame, true); +assertEq(genFrame.live, false); +assertThrowsInstanceOf(() => genFrame.callee, Error); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js new file mode 100644 index 000000000000..88dcf7b27e35 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js @@ -0,0 +1,36 @@ +// A debugger can {throw:} from onEnterFrame at any resume point in a generator. +// It closes the generator. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.eval(` + function* f() { yield 1; } + var exn = new TypeError("object too hairy"); +`); + +let dbg = new Debugger; +let gw = dbg.addDebuggee(g); + +// Repeat the test for each onEnterFrame event. +// It fires up to three times: +// - when the generator g.f is called; +// - when we enter it to run to `yield 1`; +// - when we resume after the yield to run to the end. +for (let i = 0; i < 3; i++) { + let hits = 0; + dbg.onEnterFrame = frame => { + return hits++ < i ? undefined : {throw: gw.makeDebuggeeValue(g.exn)}; + }; + let genObj; + assertThrowsValue( + () => { + genObj = g.f(); + for (let x of genObj) {} + }, + g.exn + ); + assertEq(hits, i + 1); + if (hits > 1) + assertEq(genObj.next().done, true); +} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js new file mode 100644 index 000000000000..a3fa5be57c56 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js @@ -0,0 +1,39 @@ +// A Debugger can {return:} from onEnterFrame at any resume point in a generator. +// Force-returning closes the generator. + +load(libdir + "asserts.js"); + +let g = newGlobal(); +g.values = [1, 2, 3]; +g.eval(`function* f() { yield* values; }`); + +let dbg = Debugger(g); + +// onEnterFrame will fire up to 5 times. +// - once for the initial call to g.f(); +// - four times at resume points: +// - initial resume at the top of the generator body +// - resume after yielding 1 +// - resume after yielding 2 +// - resume after yielding 3 (this resumption will run to the end). +// This test ignores the initial call and focuses on resume points. +for (let i = 1; i < 5; i++) { + let hits = 0; + dbg.onEnterFrame = frame => { + return hits++ < i ? undefined : {return: "we're done here"}; + }; + + let genObj = g.f(); + let actual = []; + while (true) { + let r = genObj.next(); + if (r.done) { + assertDeepEq(r, {value: "we're done here", done: true}); + break; + } + actual.push(r.value); + } + assertEq(hits, i + 1); + assertDeepEq(actual, g.values.slice(0, i - 1)); + assertDeepEq(genObj.next(), {value: undefined, done: true}); +} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js new file mode 100644 index 000000000000..1340c1633c13 --- /dev/null +++ b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js @@ -0,0 +1,35 @@ +// Returning {throw:} from onEnterFrame when resuming inside a try block in a +// generator causes control to jump to the catch block. + +let g = newGlobal(); +g.eval(` + function* gen() { + try { + yield 0; + return "fail"; + } catch (exc) { + assertEq(exc, "fit"); + return "ok"; + } + } +`) + +let dbg = new Debugger(g); +let hits = 0; +dbg.onEnterFrame = frame => { + assertEq(frame.callee.name, "gen"); + if (++hits == 3) { + // First hit is when calling gen(); + // second hit is resuming at the implicit initial yield; + // third hit is resuming inside the try block. + return {throw: "fit"}; + } +}; + +let it = g.gen(); +let result = it.next(); +assertEq(result.done, false); +assertEq(result.value, 0); +result = it.next(); +assertEq(result.done, true); +assertEq(result.value, "ok"); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index df3a04f1c470..0f5414099732 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -4647,7 +4647,7 @@ BaselineCompiler::emit_JSOP_AWAIT() return emit_JSOP_YIELD(); } -typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*); +typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*, jsbytecode*, bool*); static const VMFunction DebugAfterYieldInfo = FunctionInfo(jit::DebugAfterYield, "DebugAfterYield"); @@ -4660,8 +4660,21 @@ BaselineCompiler::emit_JSOP_DEBUGAFTERYIELD() frame.assertSyncedStack(); masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); prepareVMCall(); + pushArg(ImmPtr(pc)); pushArg(R0.scratchReg()); - return callVM(DebugAfterYieldInfo); + if (!callVM(DebugAfterYieldInfo)) + return false; + + icEntries_.back().setFakeKind(ICEntry::Kind_DebugAfterYield); + + Label done; + masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, &done); + { + masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand); + masm.jump(&return_); + } + masm.bind(&done); + return true; } typedef bool (*FinalSuspendFn)(JSContext*, HandleObject, jsbytecode*); diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index fa8664b7d0e6..674ee3237c28 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -103,6 +103,7 @@ struct DebugModeOSREntry frameKind == ICEntry::Kind_EarlyStackCheck || frameKind == ICEntry::Kind_DebugTrap || frameKind == ICEntry::Kind_DebugPrologue || + frameKind == ICEntry::Kind_DebugAfterYield || frameKind == ICEntry::Kind_DebugEpilogue; } @@ -307,6 +308,8 @@ ICEntryKindToString(ICEntry::Kind kind) return "debug trap"; case ICEntry::Kind_DebugPrologue: return "debug prologue"; + case ICEntry::Kind_DebugAfterYield: + return "debug after yield"; case ICEntry::Kind_DebugEpilogue: return "debug epilogue"; default: @@ -367,6 +370,7 @@ PatchBaselineFramesForDebugMode(JSContext* cx, // - All the ways above. // C. From the debug trap handler. // D. From the debug prologue. + // K. From a JSOP_DEBUGAFTERYIELD instruction. // E. From the debug epilogue. // // Cycles (On to Off to On)+ or (Off to On to Off)+: @@ -470,6 +474,7 @@ PatchBaselineFramesForDebugMode(JSContext* cx, kind == ICEntry::Kind_EarlyStackCheck || kind == ICEntry::Kind_DebugTrap || kind == ICEntry::Kind_DebugPrologue || + kind == ICEntry::Kind_DebugAfterYield || kind == ICEntry::Kind_DebugEpilogue); // We will have allocated a new recompile info, so delete the @@ -546,6 +551,17 @@ PatchBaselineFramesForDebugMode(JSContext* cx, popFrameReg = true; break; + case ICEntry::Kind_DebugAfterYield: + // Case K above. + // + // Resume at the next instruction. + MOZ_ASSERT(*pc == JSOP_DEBUGAFTERYIELD); + recompInfo->resumeAddr = bl->nativeCodeForPC(script, + pc + JSOP_DEBUGAFTERYIELD_LENGTH, + &recompInfo->slotInfo); + popFrameReg = true; + break; + default: // Case E above. // @@ -945,9 +961,9 @@ HasForcedReturn(BaselineDebugModeOSRInfo* info, bool rv) if (kind == ICEntry::Kind_DebugEpilogue) return true; - // |rv| is the value in ReturnReg. If true, in the case of the prologue, - // it means a forced return. - if (kind == ICEntry::Kind_DebugPrologue) + // |rv| is the value in ReturnReg. If true, in the case of the prologue or + // after yield, it means a forced return. + if (kind == ICEntry::Kind_DebugPrologue || kind == ICEntry::Kind_DebugAfterYield) return rv; // N.B. The debug trap handler handles its own forced return, so no diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h index da4380d1cec5..17e06668691b 100644 --- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -256,8 +256,9 @@ class ICEntry Kind_DebugTrap, // A fake IC entry for returning from a callVM to - // Debug{Prologue,Epilogue}. + // Debug{Prologue,AfterYield,Epilogue}. Kind_DebugPrologue, + Kind_DebugAfterYield, Kind_DebugEpilogue, Kind_Invalid diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 8b91a778cd43..d170b0ee3c41 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -957,12 +957,19 @@ InterpretResume(JSContext* cx, HandleObject obj, HandleValue val, HandleProperty } bool -DebugAfterYield(JSContext* cx, BaselineFrame* frame) +DebugAfterYield(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn) { + *mustReturn = false; + // The BaselineFrame has just been constructed by JSOP_RESUME in the // caller. We need to set its debuggee flag as necessary. - if (frame->script()->isDebuggee()) + // + // If a breakpoint is set on JSOP_DEBUGAFTERYIELD, or stepping is enabled, + // we may already have done this work. Don't fire onEnterFrame again. + if (frame->script()->isDebuggee() && !frame->isDebuggee()) { frame->setIsDebuggee(); + return DebugPrologue(cx, frame, pc, mustReturn); + } return true; } @@ -975,13 +982,19 @@ GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, Handlescript(); uint32_t offset = script->yieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()]; - frame->setOverridePc(script->offsetToPC(offset)); + jsbytecode* pc = script->offsetToPC(offset); + frame->setOverridePc(pc); // In the interpreter, GeneratorObject::resume marks the generator as running, // so we do the same. genObj->setRunning(); - MOZ_ALWAYS_TRUE(DebugAfterYield(cx, frame)); + bool mustReturn = false; + if (!DebugAfterYield(cx, frame, pc, &mustReturn)) + return false; + if (mustReturn) + resumeKind = GeneratorObject::RETURN; + MOZ_ALWAYS_FALSE(js::GeneratorThrowOrReturn(cx, frame, genObj, arg, resumeKind)); return false; } @@ -1091,11 +1104,15 @@ HandleDebugTrap(JSContext* cx, BaselineFrame* frame, uint8_t* retAddr, bool* mus jsbytecode* pc = script->baselineScript()->icEntryFromReturnAddress(retAddr).pc(script); if (*pc == JSOP_DEBUGAFTERYIELD) { - // JSOP_DEBUGAFTERYIELD will set the frame's debuggee flag, but if we - // set a breakpoint there we have to do it now. + // JSOP_DEBUGAFTERYIELD will set the frame's debuggee flag and call the + // onEnterFrame handler, but if we set a breakpoint there we have to do + // it now. MOZ_ASSERT(!frame->isDebuggee()); - if (!DebugAfterYield(cx, frame)) + + if (!DebugAfterYield(cx, frame, pc, mustReturn)) return false; + if (*mustReturn) + return true; } MOZ_ASSERT(frame->isDebuggee()); diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 85722eef583a..ae024af85377 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -785,7 +785,7 @@ MOZ_MUST_USE bool InterpretResume(JSContext* cx, HandleObject obj, HandleValue val, HandlePropertyName kind, MutableHandleValue rval); MOZ_MUST_USE bool -DebugAfterYield(JSContext* cx, BaselineFrame* frame); +DebugAfterYield(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn); MOZ_MUST_USE bool GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, Handle genObj, HandleValue arg, uint32_t resumeKind); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 79c5752b802f..28aa12bb123f 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -1817,6 +1817,15 @@ Debugger::fireEnterFrame(JSContext* cx, MutableHandleValue vp) RootedValue scriptFrame(cx); FrameIter iter(cx); + +#if DEBUG + // Assert that the hook won't be able to re-enter the generator. + if (iter.hasScript() && *iter.pc() == JSOP_DEBUGAFTERYIELD) { + GeneratorObject* genObj = GetGeneratorObjectForFrame(cx, iter.abstractFramePtr()); + MOZ_ASSERT(genObj->isRunning() || genObj->isClosing()); + } +#endif + if (!getFrame(cx, iter, &scriptFrame)) return reportUncaughtException(ar); diff --git a/js/src/vm/GeneratorObject.h b/js/src/vm/GeneratorObject.h index d09510021117..d74ab5e1acc1 100644 --- a/js/src/vm/GeneratorObject.h +++ b/js/src/vm/GeneratorObject.h @@ -154,6 +154,10 @@ class GeneratorObject : public NativeObject MOZ_ASSERT_IF(yieldAndAwaitIndex == 0, getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).isUndefined()); MOZ_ASSERT_IF(yieldAndAwaitIndex != 0, isRunning() || isClosing()); + setYieldAndAwaitIndexNoAssert(yieldAndAwaitIndex); + } + // Debugger has to flout the state machine rules a bit. + void setYieldAndAwaitIndexNoAssert(uint32_t yieldAndAwaitIndex) { MOZ_ASSERT(yieldAndAwaitIndex < uint32_t(YIELD_AND_AWAIT_INDEX_CLOSING)); setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(yieldAndAwaitIndex)); MOZ_ASSERT(isSuspended()); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 468cb1033766..593c2e7ca1b3 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4286,6 +4286,20 @@ CASE(JSOP_RESUME) TraceLogStartEvent(logger, scriptEvent); TraceLogStartEvent(logger, TraceLogger_Interpreter); + switch (Debugger::onEnterFrame(cx, REGS.fp())) { + case ResumeMode::Continue: + break; + case ResumeMode::Throw: + case ResumeMode::Terminate: + goto error; + case ResumeMode::Return: + MOZ_ASSERT_IF(REGS.fp()->callee().isGenerator(), // as opposed to an async function + gen->isClosed()); + if (!ForcedReturn(cx, REGS)) + goto error; + goto successful_return_continuation; + } + switch (resumeKind) { case GeneratorObject::NEXT: break; From ba761cd3832c8668c5761574dd72d9891354e3dd Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 17 Aug 2018 10:35:32 +0900 Subject: [PATCH 40/49] Bug 1483778 - Skip LTO during the profile-generate phase of PGO. r=froydnj When both LTO and PGO are enabled, there is no point LTO'ing during the first phase of PGO. --- config/config.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/config.mk b/config/config.mk index 6e709a829dc3..58c2df4909cc 100644 --- a/config/config.mk +++ b/config/config.mk @@ -199,6 +199,11 @@ INCLUDES = \ include $(MOZILLA_DIR)/config/static-checking-config.mk +ifdef MOZ_PROFILE_GENERATE +MOZ_LTO_CFLAGS := +MOZ_LTO_LDFLAGS := +endif + LDFLAGS = $(MOZ_LTO_LDFLAGS) $(COMPUTED_LDFLAGS) $(PGO_LDFLAGS) $(MK_LDFLAGS) COMPILE_CFLAGS = $(MOZ_LTO_CFLAGS) $(COMPUTED_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES) From 3226912d99f899c8aac6c6dfccb6da0221f1d88d Mon Sep 17 00:00:00 2001 From: David Major Date: Tue, 21 Aug 2018 17:16:45 -0400 Subject: [PATCH 41/49] Bug 1485072: Remove some unnecessary (on-by-default) LDFLAGS from Windows builds. r=froydnj -DEBUGTYPE:CV, -NXCOMPAT, and -DYNAMICBASE are on by default in both link.exe and lld-link. --HG-- extra : rebase_source : 3b50b88bb8ac9257689df2e10146906ef9962b08 --- js/src/old-configure.in | 5 ++--- old-configure.in | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/js/src/old-configure.in b/js/src/old-configure.in index f96885b003e4..ba016082eec6 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -804,15 +804,14 @@ case "$target" in CFLAGS="$CFLAGS -we4553" CXXFLAGS="$CXXFLAGS -we4553" LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib" - MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV' + MOZ_DEBUG_LDFLAGS='-DEBUG' WARNINGS_AS_ERRORS='-WX' MOZ_OPTIMIZE_FLAGS="-O2" MOZ_FIX_LINK_PATHS= - LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT" + LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE" if test -z "$DEVELOPER_OPTIONS"; then LDFLAGS="$LDFLAGS -RELEASE" fi - LDFLAGS="$LDFLAGS -DYNAMICBASE" RCFLAGS="-nologo" fi AC_DEFINE(HAVE__MSIZE) diff --git a/old-configure.in b/old-configure.in index e69bd7f94ff8..b4f7c4b2a564 100644 --- a/old-configure.in +++ b/old-configure.in @@ -1016,7 +1016,7 @@ case "$target" in # Silence VS2017 15.5+ TR1 deprecation warnings hit by older gtest versions CXXFLAGS="$CXXFLAGS -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib secur32.lib" - MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV' + MOZ_DEBUG_LDFLAGS='-DEBUG' WARNINGS_AS_ERRORS='-WX' # Use a higher optimization level for clang-cl, so we can come closer # to MSVC's performance numbers (see bug 1443590). @@ -1026,11 +1026,10 @@ case "$target" in MOZ_OPTIMIZE_FLAGS='-O1 -Oi' fi MOZ_FIX_LINK_PATHS= - LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT" + LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE" if test -z "$DEVELOPER_OPTIONS"; then LDFLAGS="$LDFLAGS -RELEASE" fi - LDFLAGS="$LDFLAGS -DYNAMICBASE" RCFLAGS="-nologo" dnl Minimum reqiurement of Gecko is VS2015 or later which supports dnl both SSSE3 and SSE4.1. From 3449eb620eeb31dcec7a6da26c876d1e049b0ca2 Mon Sep 17 00:00:00 2001 From: Andreea Pavel Date: Wed, 22 Aug 2018 01:27:52 +0300 Subject: [PATCH 42/49] Backed out changeset d3ce115e1803 (bug 1449540) for failing jit and spidermonkey builds on a CLOSED TREE --- js/src/tests/non262/Proxy/regress-bug950407.js | 10 +++++++--- js/src/tests/non262/regress/regress-665355.js | 7 ++----- js/src/vm/JSObject.cpp | 11 +++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/js/src/tests/non262/Proxy/regress-bug950407.js b/js/src/tests/non262/Proxy/regress-bug950407.js index d253c75fc2fb..bb4a71eb042e 100644 --- a/js/src/tests/non262/Proxy/regress-bug950407.js +++ b/js/src/tests/non262/Proxy/regress-bug950407.js @@ -1,7 +1,11 @@ var ab = new ArrayBuffer(5); var p = new Proxy(ab, {}); var ps = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set; -var new_proto = {}; -ps.call(p, new_proto); +var threw = 0; +try { + ps.call(p, {}); +} catch(ex) { + threw = 1; +} -reportCompare(ab.__proto__, new_proto); +reportCompare(1, threw, "Setting __proto__ on a proxy to an ArrayBuffer must throw."); diff --git a/js/src/tests/non262/regress/regress-665355.js b/js/src/tests/non262/regress/regress-665355.js index c027fa8a6447..ef91161c40ff 100644 --- a/js/src/tests/non262/regress/regress-665355.js +++ b/js/src/tests/non262/regress/regress-665355.js @@ -9,11 +9,8 @@ try { } } -// assert cycle doesn't work assertEq(test(x), true); - -// works -assertEq(test({}), false); -assertEq(test(null), false); +assertEq(test({}), true); +assertEq(test(null), true); reportCompare(true, true); diff --git a/js/src/vm/JSObject.cpp b/js/src/vm/JSObject.cpp index ebf37f376d31..4cf0f84b993b 100644 --- a/js/src/vm/JSObject.cpp +++ b/js/src/vm/JSObject.cpp @@ -2683,6 +2683,17 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object if (obj->staticPrototypeIsImmutable()) return result.fail(JSMSG_CANT_SET_PROTO); + /* + * Disallow mutating the [[Prototype]] on ArrayBuffer objects, which + * due to their complicated delegate-object shenanigans can't easily + * have a mutable [[Prototype]]. + */ + if (obj->is()) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_PROTO_OF, + "incompatible ArrayBuffer"); + return false; + } + /* * Disallow mutating the [[Prototype]] on Typed Objects, per the spec. */ From 4f3e438279288be437ad5870a266240850f32b3f Mon Sep 17 00:00:00 2001 From: Andreea Pavel Date: Wed, 22 Aug 2018 01:31:39 +0300 Subject: [PATCH 43/49] Backed out 3 changesets (bug 1475417) for failing docker configuration ona CLOSED TREE Backed out changeset 972ad5dc9a84 (bug 1475417) Backed out changeset 13020b58f0fa (bug 1475417) Backed out changeset 50ed38c98cc0 (bug 1475417) --HG-- extra : amend_source : 143d991571f7a2e35361c8e5846ede6c85652182 --- .../Debugger-onEnterFrame-resumption-03.js | 4 +- js/src/jit-test/tests/debug/Frame-live-06.js | 26 ------ js/src/jit-test/tests/debug/Frame-live-07.js | 53 ------------ .../tests/debug/Frame-onPop-generators-04.js | 26 ------ .../debug/Frame-onPop-star-generators-01.js | 20 +++++ .../debug/Frame-onPop-star-generators-02.js | 21 +++++ .../tests/debug/Frame-onStep-generators-01.js | 31 ------- .../tests/debug/Frame-onStep-generators-02.js | 44 ---------- .../tests/debug/Frame-onStep-generators-03.js | 45 ----------- .../debug/Frame-onStep-generators-defaults.js | 33 -------- .../jit-test/tests/debug/breakpoint-oom-01.js | 39 --------- ...Statement-async-generator-resumption-01.js | 60 -------------- ...onDebuggerStatement-async-resumption-01.js | 34 -------- .../debug/onEnterFrame-async-resumption-01.js | 33 -------- .../debug/onEnterFrame-async-resumption-02.js | 36 --------- .../debug/onEnterFrame-async-resumption-03.js | 30 ------- .../tests/debug/onEnterFrame-generator-01.js | 81 ------------------- .../tests/debug/onEnterFrame-generator-02.js | 27 ------- .../tests/debug/onEnterFrame-generator-03.js | 25 ------ .../onEnterFrame-generator-resumption-01.js | 36 --------- .../onEnterFrame-generator-resumption-02.js | 39 --------- .../onEnterFrame-generator-resumption-03.js | 35 -------- js/src/jit/BaselineCompiler.cpp | 21 +---- js/src/jit/BaselineDebugModeOSR.cpp | 22 +---- js/src/jit/SharedIC.h | 3 +- js/src/jit/VMFunctions.cpp | 35 ++------ js/src/jit/VMFunctions.h | 2 +- js/src/vm/Debugger.cpp | 9 --- js/src/vm/GeneratorObject.cpp | 18 ++++- js/src/vm/GeneratorObject.h | 8 +- js/src/vm/Interpreter.cpp | 30 +------ js/src/vm/Stack.h | 2 +- 32 files changed, 80 insertions(+), 848 deletions(-) delete mode 100644 js/src/jit-test/tests/debug/Frame-live-06.js delete mode 100644 js/src/jit-test/tests/debug/Frame-live-07.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onPop-generators-04.js create mode 100644 js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js create mode 100644 js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-01.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-02.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-03.js delete mode 100644 js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js delete mode 100644 js/src/jit-test/tests/debug/breakpoint-oom-01.js delete mode 100644 js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js delete mode 100644 js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-01.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-02.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-03.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js delete mode 100644 js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js diff --git a/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js b/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js index e28b014944f2..a42f2183a3a4 100644 --- a/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js +++ b/js/src/jit-test/tests/debug/Debugger-onEnterFrame-resumption-03.js @@ -1,4 +1,4 @@ -// If debugger.onEnterFrame returns null, the debuggee is terminated immediately. +// If debugger.onEnterFrame returns {return:val}, the frame returns immediately. load(libdir + "asserts.js"); @@ -13,7 +13,7 @@ dbg.onDebuggerStatement = function (frame) { innerSavedFrame = frame; return null; }; - // Using frame.eval lets us catch termination. + // Using frame.eval lets us catch termination. assertEq(frame.eval("set = true;"), null); assertEq(innerSavedFrame.live, false); savedFrame = frame; diff --git a/js/src/jit-test/tests/debug/Frame-live-06.js b/js/src/jit-test/tests/debug/Frame-live-06.js deleted file mode 100644 index f1cc4abf1af8..000000000000 --- a/js/src/jit-test/tests/debug/Frame-live-06.js +++ /dev/null @@ -1,26 +0,0 @@ -// frame.live is false for generator frames after they return. - -let g = newGlobal(); -g.eval("function* f() { debugger; }"); - -let dbg = Debugger(g); -let savedFrame; - -dbg.onDebuggerStatement = frame => { - savedFrame = frame; - assertEq(frame.callee.name, "f"); - assertEq(frame.live, true); - frame.onPop = function() { - assertEq(frame.live, true); - }; -}; -g.f().next(); - -assertEq(savedFrame.live, false); -try { - savedFrame.older; - throw new Error("expected exception, none thrown"); -} catch (exc) { - assertEq(exc.message, "Debugger.Frame is not live"); -} - diff --git a/js/src/jit-test/tests/debug/Frame-live-07.js b/js/src/jit-test/tests/debug/Frame-live-07.js deleted file mode 100644 index da3b4e1bba93..000000000000 --- a/js/src/jit-test/tests/debug/Frame-live-07.js +++ /dev/null @@ -1,53 +0,0 @@ -// frame.live is false for generator frames popped due to exception or termination. - -load(libdir + "/asserts.js"); - -function test(when, what) { - let g = newGlobal(); - g.eval("function* f(x) { yield x; }"); - - let dbg = new Debugger; - let gw = dbg.addDebuggee(g); - let fw = gw.getOwnPropertyDescriptor("f").value; - - let t = 0; - let poppedFrame; - - function tick(frame) { - if (frame.callee == fw) { - if (t == when) { - poppedFrame = frame; - dbg.onEnterFrame = undefined; - frame.onPop = undefined; - return what; - } - t++; - } - return undefined; - } - - dbg.onDebuggerStatement = frame => { - dbg.onEnterFrame = frame => { - frame.onPop = function() { - return tick(this); - }; - return tick(frame); - }; - let result = frame.eval("for (let _ of f(0)) {}"); - assertDeepEq(result, what); - }; - g.eval("debugger;"); - - assertEq(t, when); - assertEq(poppedFrame.live, false); - assertErrorMessage(() => poppedFrame.older, - Error, - "Debugger.Frame is not live"); -} - -for (let when = 0; when < 6; when++) { - for (let what of [null, {throw: "fit"}]) { - test(when, what); - } -} - diff --git a/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js b/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js deleted file mode 100644 index 2c686e278efb..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onPop-generators-04.js +++ /dev/null @@ -1,26 +0,0 @@ -// Terminating a generator from the onPop callback for its initial yield -// leaves the Frame in a sane but inactive state. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval("function* f(x) { yield x; }"); -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -let genFrame = null; -dbg.onDebuggerStatement = frame => { - dbg.onEnterFrame = frame => { - if (frame.callee == gw.getOwnPropertyDescriptor("f").value) { - genFrame = frame; - frame.onPop = completion => null; - } - }; - assertEq(frame.eval("f(0);"), null); -}; - -g.eval("debugger;"); - -assertEq(genFrame instanceof Debugger.Frame, true); -assertEq(genFrame.live, false); -assertThrowsInstanceOf(() => genFrame.callee, Error); diff --git a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js new file mode 100644 index 000000000000..73cf3c8c7d3b --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-01.js @@ -0,0 +1,20 @@ +// Returning {throw:} from an onPop handler when yielding works and +// closes the generator-iterator. + +load(libdir + "iteration.js"); + +var g = newGlobal(); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); +dbg.onDebuggerStatement = function handleDebugger(frame) { + frame.onPop = function (c) { + return {throw: "fit"}; + }; +}; +g.eval("function* g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }"); +g.eval("var it = g();"); +var rv = gw.executeInGlobal("it.next();"); +assertEq(rv.throw, "fit"); + +dbg.enabled = false; +assertIteratorDone(g.it); diff --git a/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js new file mode 100644 index 000000000000..de9ad5009825 --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onPop-star-generators-02.js @@ -0,0 +1,21 @@ +// |jit-test| error: fit + +// Throwing an exception from an onPop handler when yielding terminates the debuggee +// but does not close the generator-iterator. + +load(libdir + 'iteration.js') + +var g = newGlobal(); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); +dbg.onDebuggerStatement = function handleDebugger(frame) { + frame.onPop = function (c) { + throw "fit"; + }; +}; +g.eval("function* g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }"); +g.eval("var it = g();"); +assertEq(gw.executeInGlobal("it.next();"), null); + +dbg.enabled = false; +assertIteratorNext(g.it, 1); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js deleted file mode 100644 index 1183f01380e3..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onStep-generators-01.js +++ /dev/null @@ -1,31 +0,0 @@ -// Stepping into the `.next()` method of a generator works as expected. - -let g = newGlobal(); -g.eval(`\ -function* nums() { // line 1 - yield 1; // 2 - yield 2; // 3 -} // 4 -function f() { // 5 - let gen = nums(); // 6 - gen.next(); // 7 - gen.next(); // 8 - gen.next(); // 9 -} // 10 -`); - -let log = []; -let previousLine = -1; -let dbg = new Debugger(g); -dbg.onEnterFrame = frame => { - frame.onStep = () => { - let line = frame.script.getOffsetLocation(frame.offset).lineNumber; - if (previousLine != line) { // We stepped to a new line. - log.push(line); - previousLine = line; - } - }; -}; - -g.f(); -assertEq(log.join(" "), "5 6 1 6 7 1 2 7 8 2 3 8 9 3 9 10"); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js deleted file mode 100644 index bc77b3d3cdd3..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onStep-generators-02.js +++ /dev/null @@ -1,44 +0,0 @@ -// Stepping into the `.throw()` method of a generator with no relevant catch block. -// -// The debugger fires onEnterFrame and then frame.onPop for the generator frame when -// `gen.throw()` is called. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(`\ -function* z() { // line 1 - yield 1; // 2 - yield 2; // 3 -} // 4 -function f() { // 5 - let gen = z(); // 6 - gen.next(); // 7 - gen.throw("fit"); // 8 -} // 9 -`); - -let log = ""; -let previousLine = -1; -let dbg = new Debugger(g); -dbg.onEnterFrame = frame => { - log += frame.callee.name + "{"; - frame.onStep = () => { - let line = frame.script.getOffsetLocation(frame.offset).lineNumber; - if (previousLine != line) { // We stepped to a new line. - log += line; - previousLine = line; - } - }; - frame.onPop = completion => { - if ("throw" in completion) - log += "!"; - log += "}"; - } -}; - -assertThrowsValue(() => g.f(), "fit"); -// z{1} is the initial generator setup. -// z{12} is the first .next() call, running to `yield 1` on line 2 -// The final `z{!}` is for the .throw() call. -assertEq(log, "f{56z{1}67z{12}78z{!}!}"); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js deleted file mode 100644 index 5a49b3c6df08..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onStep-generators-03.js +++ /dev/null @@ -1,45 +0,0 @@ -// Stepping into the `.throw()` method of a generator with a relevant catch block. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(`\ -function* z() { // line 1 - try { // 2 - yield 1; // 3 - } catch (exc) { // 4 - yield 2; // 5 - } // 6 -} // 7 -function f() { // 8 - let gen = z(); // 9 - gen.next(); // 10 - gen.throw("fit"); // 11 -} // 12 -`); - -let log = []; -let previousLine = -1; -let dbg = new Debugger(g); -dbg.onEnterFrame = frame => { - log.push(frame.callee.name + " in"); - frame.onStep = () => { - let line = frame.script.getOffsetLocation(frame.offset).lineNumber; - if (previousLine != line) { // We stepped to a new line. - log.push(line); - previousLine = line; - } - }; - frame.onPop = completion => { - log.push(frame.callee.name + " out"); - }; -}; - -g.f(); -assertEq( - log.join(", "), - "f in, 8, 9, z in, 1, z out, " + - "9, 10, z in, 1, 2, 3, z out, " + - "10, 11, z in, 2, 4, 5, z out, " + // not sure why we hit line 2 here, source notes bug maybe - "11, 12, f out" -); diff --git a/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js b/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js deleted file mode 100644 index 0c337636ee3c..000000000000 --- a/js/src/jit-test/tests/debug/Frame-onStep-generators-defaults.js +++ /dev/null @@ -1,33 +0,0 @@ -// onStep works during the evaluation of default parameter values in generators. -// -// (They're evaluated at a weird time in the generator life cycle, before the -// generator object is created.) - -let g = newGlobal(); -g.eval(`\ - function f1() {} // line 1 - function f2() {} // 2 - function f3() {} // 3 - // 4 - function* gen( // 5 - name, // 6 - schema = f1(), // 7 - timeToLive = f2(), // 8 - lucidity = f3() // 9 - ) { // 10 - } // 11 -`); - -let dbg = Debugger(g); -let log = []; -dbg.onEnterFrame = frame => { - frame.onStep = () => { - let line = frame.script.getOffsetLocation(frame.offset).lineNumber; - if (log.length == 0 || line != log[log.length - 1]) { - log.push(line); - } - }; -}; - -g.gen(0); -assertEq(log.toSource(), [5, 7, 1, 8, 2, 9, 3, 10].toSource()); diff --git a/js/src/jit-test/tests/debug/breakpoint-oom-01.js b/js/src/jit-test/tests/debug/breakpoint-oom-01.js deleted file mode 100644 index 50b9ff7d9aaf..000000000000 --- a/js/src/jit-test/tests/debug/breakpoint-oom-01.js +++ /dev/null @@ -1,39 +0,0 @@ -// Test for OOM hitting a breakpoint in a generator. -// -// (The purpose is to test OOM-handling in the code that creates the -// Debugger.Frame object and associates it with the generator object.) - -let g = newGlobal(); -g.eval(`\ - function* gen(x) { // line 1 - x++; // 2 - yield x; // 3 - } // 4 -`); - -let dbg = new Debugger; - -// On OOM in the debugger, propagate it to the debuggee. -dbg.uncaughtExceptionHook = exc => exc === "out of memory" ? {throw: exc} : null; - -let gw = dbg.addDebuggee(g); -let script = gw.makeDebuggeeValue(g.gen).script; -let hits = 0; -let handler = { - hit(frame) { - hits++; - print("x=", frame.environment.getVariable("x")); - } -}; -for (let offset of script.getLineOffsets(2)) - script.setBreakpoint(offset, handler); - -let result; -oomTest(() => { - hits = 0; - result = g.gen(1).next(); -}, false); -assertEq(hits, 1); -assertEq(result.done, false); -assertEq(result.value, 2); - diff --git a/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js b/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js deleted file mode 100644 index bb83f6470e2c..000000000000 --- a/js/src/jit-test/tests/debug/onDebuggerStatement-async-generator-resumption-01.js +++ /dev/null @@ -1,60 +0,0 @@ -// A Debugger can {return:} from onDebuggerStatement in an async generator. -// A resolved promise for a {value: _, done: true} object is returned. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(` - async function* f(x) { - debugger; // when==0 to force return here - await x; - yield 1; - debugger; // when==1 to force return here - } -`); - -let exc = null; -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); -function test(when) { - let hits = 0; - let outcome = "FAIL"; - dbg.onDebuggerStatement = frame => { - if (hits++ == when) - return {return: "ponies"}; - }; - - let iter = g.f(0); - - // At the initial suspend. - assertEq(hits, 0); - iter.next().then(result => { - // At the yield point, unless we already force-returned from the first - // debugger statement. - assertEq(hits, 1); - if (when == 0) - return result; - assertEq(result.value, 1); - assertEq(result.done, false); - return iter.next(); - }).then(result => { - // After forced return. - assertEq(hits, when + 1); - assertEq(result.value, "ponies"); - assertEq(result.done, true); - outcome = "pass"; - }).catch(e => { - // An assertion failed. - exc = e; - }); - - assertEq(hits, 1); - drainJobQueue(); - if (exc !== null) - throw exc; - assertEq(outcome, "pass"); -} - -for (let i = 0; i < 2; i++) { - test(i); -} diff --git a/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js b/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js deleted file mode 100644 index 8f3f2c094224..000000000000 --- a/js/src/jit-test/tests/debug/onDebuggerStatement-async-resumption-01.js +++ /dev/null @@ -1,34 +0,0 @@ -// A Debugger can {return:} from onDebuggerStatement in an async function. -// The async function's promise is resolved with the returned value. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(` - async function f(x) { - debugger; // when==0 to force return here - await x; - debugger; // when==1 to force return here - } -`); - -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); -function test(when, what, expected) { - let hits = 0; - let result = "FAIL"; - dbg.onDebuggerStatement = frame => { - if (hits++ == when) - return {return: gw.makeDebuggeeValue(what)}; - }; - g.f(0).then(x => { result = x; }); - assertEq(hits, 1); - drainJobQueue(); - assertEq(hits, when + 1); - assertEq(result, expected); -} - -for (let i = 0; i < 2; i++) { - test(i, "ok", "ok"); - test(i, g.Promise.resolve(37), 37); -} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js deleted file mode 100644 index fbfc2c84a5a8..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-01.js +++ /dev/null @@ -1,33 +0,0 @@ -// A Debugger can {return:} from the first onEnterFrame for an async function. -// (The exact behavior is undocumented; we're testing that it doesn't crash.) - -let g = newGlobal(); -g.hit2 = false; -g.eval(`async function f(x) { await x; return "ponies"; }`); - -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); -let hits = 0; -let resumption = undefined; -dbg.onEnterFrame = frame => { - if (frame.type == "call" && frame.callee.name === "f") { - frame.onPop = completion => { - assertEq(completion.return, resumption.return); - hits++; - }; - - // Don't tell anyone, but if we force-return a generator object here, - // the robots accept it as one of their own and plug it right into the - // async function machinery. This may be handy against Skynet someday. - resumption = frame.eval(`(function* f2() { hit2 = true; throw "fit"; })()`); - assertEq(resumption.return.class, "Generator"); - return resumption; - } -}; - -let p = g.f(0); -assertEq(hits, 1); -let pw = gw.makeDebuggeeValue(p); -assertEq(pw.isPromise, true); -assertEq(pw.promiseState, "rejected"); -assertEq(pw.promiseReason, "fit"); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js deleted file mode 100644 index 3125654d9772..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-02.js +++ /dev/null @@ -1,36 +0,0 @@ -// A Debugger can {throw:} from onEnterFrame in an async function. -// The resulting promise (if any) is rejected with the thrown error value. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(` - async function f() { await 1; } - var err = new TypeError("object too hairy"); -`); - -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); -let errw = gw.makeDebuggeeValue(g.err); - -// Repeat the test for each onEnterFrame event. -// It fires up to three times: -// - when the async function g.f is called; -// - when we enter it to run to `await 1`; -// - when we resume after the await to run to the end. -for (let when = 0; when < 3; when++) { - let hits = 0; - dbg.onEnterFrame = frame => { - return hits++ < when ? undefined : {throw: errw}; - }; - - let result = undefined; - g.f() - .then(value => { result = {returned: value}; }) - .catch(err => { result = {threw: err}; }); - - drainJobQueue(); - - assertEq(hits, when + 1); - assertDeepEq(result, {threw: g.err}); -} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js b/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js deleted file mode 100644 index 68c3ded27f4f..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-async-resumption-03.js +++ /dev/null @@ -1,30 +0,0 @@ -// A Debugger can {return:} from onEnterFrame at any resume point in an async function. -// The async function's promise is resolved with the returned value. - -let g = newGlobal(); -g.eval(`async function f(x) { await x; }`); - -let dbg = new Debugger(g); -function test(when) { - let hits = 0; - dbg.onEnterFrame = frame => { - if (frame.type == "call" && frame.callee.name === "f") { - if (hits++ == when) { - return {return: "exit"}; - } - } - }; - - let result = undefined; - let finished = false; - g.f("hello").then(value => { result = value; finished = true; }); - drainJobQueue(); - assertEq(finished, true); - assertEq(hits, when + 1); - assertEq(result, "exit"); -} - -// onEnterFrame with hits==0 is not a resume point; {return:} behaves differently there -// (see onEnterFrame-async-resumption-02.js). -test(1); // force return from first resume point, immediately after the initial suspend -test(2); // force return from second resume point, immediately after the await instruction diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js deleted file mode 100644 index 8cfceba5ba3f..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-01.js +++ /dev/null @@ -1,81 +0,0 @@ -// Frame properties and methods work in generator-resuming onEnterFrame events. -// Also tests onPop events, for good measure. - -let g = newGlobal(); -g.eval(`\ - function* gen(lo, hi) { - var a = 1/2; - yield a; - yield a * a; - } -`); -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -let hits = 0; -let savedScript = null; -let savedEnv = null; -let savedOffsets = new Set; - -function check(frame) { - assertEq(frame.type, "call"); - assertEq(frame.constructing, false); - assertEq(frame.callee, gw.makeDebuggeeValue(g.gen)); - - // `arguments` elements don't work in resumed generator frames, - // because generators don't keep the arguments around. - // The first onEnterFrame and onPop events can see them. - assertEq(frame.arguments.length, hits < 2 ? args.length : 0); - for (var i = 0; i < frame.arguments.length; i++) { - assertEq(frame.arguments.hasOwnProperty(i), true); - - if (hits < 2) - assertEq(frame.arguments[i], gw.makeDebuggeeValue(args[i]), `arguments[${i}]`); - else - assertEq(frame.arguments[i], undefined); - } - - if (savedEnv === null) { - savedEnv = frame.environment; - assertEq(savedScript, null); - savedScript = frame.script; - } else { - assertEq(frame.environment, savedEnv); - assertEq(frame.script, savedScript); - } - let a_expected = hits < 3 ? undefined : 1/2; - assertEq(savedEnv.getVariable("a"), a_expected); - - assertEq(frame.generator, true); - assertEq(frame.live, true); - - let pc = frame.offset; - assertEq(savedOffsets.has(pc), false); - savedOffsets.add(pc); - - assertEq(frame.older, null); - assertEq(frame.this, gw); - assertEq(typeof frame.implementation, "string"); - - // And the moment of truth: - assertEq(frame.eval("2 + 2").return, 4); - assertEq(frame.eval("a").return, a_expected); - assertEq(frame.eval("if (a !== undefined) { assertEq(a < (lo + hi) / 2, true); } 7;").return, 7); -} - -dbg.onEnterFrame = frame => { - if (frame.type === "eval") - return; - check(frame); - hits++; - frame.onPop = completion => { - check(frame); - hits++; - }; -}; - -// g.gen ignores the arguments passed to it, but we use them to test -// frame.arguments. -let args = [0, 10, g, dbg]; -for (let v of g.gen(...args)) {} -assertEq(hits, 8); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js deleted file mode 100644 index b6b5e5181650..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-02.js +++ /dev/null @@ -1,27 +0,0 @@ -// onEnterFrame fires after the [[GeneratorState]] is set to "executing". -// -// This test checks that Debugger doesn't accidentally make it possible to -// reenter a generator frame that's already on the stack. (Also tests a fun -// corner case in baseline debug-mode OSR.) - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval('function* f() { yield 1; yield 2; }'); -let dbg = Debugger(g); -let genObj = null; -let hits = 0; -dbg.onEnterFrame = frame => { - // The first time onEnterFrame fires, there is no generator object, so - // there's nothing to test. The generator object doesn't exist until - // JSOP_GENERATOR is reached, right before the initial yield. - if (genObj !== null) { - dbg.removeDebuggee(g); // avoid the DebuggeeWouldRun exception - assertThrowsInstanceOf(() => genObj.next(), g.TypeError); - dbg.addDebuggee(g); - hits++; - } -}; -genObj = g.f(); -for (let x of genObj) {} -assertEq(hits, 3); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js deleted file mode 100644 index 744313e8d7dd..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-03.js +++ /dev/null @@ -1,25 +0,0 @@ -// If onEnterFrame terminates a generator, the Frame is left in a sane but inactive state. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval("function* f(x) { yield x; }"); -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -let genFrame = null; -dbg.onDebuggerStatement = frame => { - dbg.onEnterFrame = frame => { - if (frame.callee == gw.getOwnPropertyDescriptor("f").value) { - genFrame = frame; - return null; - } - }; - assertEq(frame.eval("f(0);"), null); -}; - -g.eval("debugger;"); - -assertEq(genFrame instanceof Debugger.Frame, true); -assertEq(genFrame.live, false); -assertThrowsInstanceOf(() => genFrame.callee, Error); diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js deleted file mode 100644 index 88dcf7b27e35..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-01.js +++ /dev/null @@ -1,36 +0,0 @@ -// A debugger can {throw:} from onEnterFrame at any resume point in a generator. -// It closes the generator. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.eval(` - function* f() { yield 1; } - var exn = new TypeError("object too hairy"); -`); - -let dbg = new Debugger; -let gw = dbg.addDebuggee(g); - -// Repeat the test for each onEnterFrame event. -// It fires up to three times: -// - when the generator g.f is called; -// - when we enter it to run to `yield 1`; -// - when we resume after the yield to run to the end. -for (let i = 0; i < 3; i++) { - let hits = 0; - dbg.onEnterFrame = frame => { - return hits++ < i ? undefined : {throw: gw.makeDebuggeeValue(g.exn)}; - }; - let genObj; - assertThrowsValue( - () => { - genObj = g.f(); - for (let x of genObj) {} - }, - g.exn - ); - assertEq(hits, i + 1); - if (hits > 1) - assertEq(genObj.next().done, true); -} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js deleted file mode 100644 index a3fa5be57c56..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-02.js +++ /dev/null @@ -1,39 +0,0 @@ -// A Debugger can {return:} from onEnterFrame at any resume point in a generator. -// Force-returning closes the generator. - -load(libdir + "asserts.js"); - -let g = newGlobal(); -g.values = [1, 2, 3]; -g.eval(`function* f() { yield* values; }`); - -let dbg = Debugger(g); - -// onEnterFrame will fire up to 5 times. -// - once for the initial call to g.f(); -// - four times at resume points: -// - initial resume at the top of the generator body -// - resume after yielding 1 -// - resume after yielding 2 -// - resume after yielding 3 (this resumption will run to the end). -// This test ignores the initial call and focuses on resume points. -for (let i = 1; i < 5; i++) { - let hits = 0; - dbg.onEnterFrame = frame => { - return hits++ < i ? undefined : {return: "we're done here"}; - }; - - let genObj = g.f(); - let actual = []; - while (true) { - let r = genObj.next(); - if (r.done) { - assertDeepEq(r, {value: "we're done here", done: true}); - break; - } - actual.push(r.value); - } - assertEq(hits, i + 1); - assertDeepEq(actual, g.values.slice(0, i - 1)); - assertDeepEq(genObj.next(), {value: undefined, done: true}); -} diff --git a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js b/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js deleted file mode 100644 index 1340c1633c13..000000000000 --- a/js/src/jit-test/tests/debug/onEnterFrame-generator-resumption-03.js +++ /dev/null @@ -1,35 +0,0 @@ -// Returning {throw:} from onEnterFrame when resuming inside a try block in a -// generator causes control to jump to the catch block. - -let g = newGlobal(); -g.eval(` - function* gen() { - try { - yield 0; - return "fail"; - } catch (exc) { - assertEq(exc, "fit"); - return "ok"; - } - } -`) - -let dbg = new Debugger(g); -let hits = 0; -dbg.onEnterFrame = frame => { - assertEq(frame.callee.name, "gen"); - if (++hits == 3) { - // First hit is when calling gen(); - // second hit is resuming at the implicit initial yield; - // third hit is resuming inside the try block. - return {throw: "fit"}; - } -}; - -let it = g.gen(); -let result = it.next(); -assertEq(result.done, false); -assertEq(result.value, 0); -result = it.next(); -assertEq(result.done, true); -assertEq(result.value, "ok"); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 0f5414099732..02855855dd09 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -4647,7 +4647,7 @@ BaselineCompiler::emit_JSOP_AWAIT() return emit_JSOP_YIELD(); } -typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*, jsbytecode*, bool*); +typedef bool (*DebugAfterYieldFn)(JSContext*, BaselineFrame*); static const VMFunction DebugAfterYieldInfo = FunctionInfo(jit::DebugAfterYield, "DebugAfterYield"); @@ -4660,21 +4660,8 @@ BaselineCompiler::emit_JSOP_DEBUGAFTERYIELD() frame.assertSyncedStack(); masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); prepareVMCall(); - pushArg(ImmPtr(pc)); pushArg(R0.scratchReg()); - if (!callVM(DebugAfterYieldInfo)) - return false; - - icEntries_.back().setFakeKind(ICEntry::Kind_DebugAfterYield); - - Label done; - masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, &done); - { - masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand); - masm.jump(&return_); - } - masm.bind(&done); - return true; + return callVM(DebugAfterYieldInfo); } typedef bool (*FinalSuspendFn)(JSContext*, HandleObject, jsbytecode*); @@ -4706,7 +4693,7 @@ static const VMFunction InterpretResumeInfo = typedef bool (*GeneratorThrowFn)(JSContext*, BaselineFrame*, Handle, HandleValue, uint32_t); -static const VMFunction GeneratorThrowOrReturnInfo = +static const VMFunction GeneratorThrowInfo = FunctionInfo(jit::GeneratorThrowOrReturn, "GeneratorThrowOrReturn", TailCall); bool @@ -4891,7 +4878,7 @@ BaselineCompiler::emit_JSOP_RESUME() pushArg(genObj); pushArg(scratch2); - TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(GeneratorThrowOrReturnInfo); + TrampolinePtr code = cx->runtime()->jitRuntime()->getVMWrapper(GeneratorThrowInfo); // Create the frame descriptor. masm.subStackPtrFrom(scratch1); diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 674ee3237c28..fa8664b7d0e6 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -103,7 +103,6 @@ struct DebugModeOSREntry frameKind == ICEntry::Kind_EarlyStackCheck || frameKind == ICEntry::Kind_DebugTrap || frameKind == ICEntry::Kind_DebugPrologue || - frameKind == ICEntry::Kind_DebugAfterYield || frameKind == ICEntry::Kind_DebugEpilogue; } @@ -308,8 +307,6 @@ ICEntryKindToString(ICEntry::Kind kind) return "debug trap"; case ICEntry::Kind_DebugPrologue: return "debug prologue"; - case ICEntry::Kind_DebugAfterYield: - return "debug after yield"; case ICEntry::Kind_DebugEpilogue: return "debug epilogue"; default: @@ -370,7 +367,6 @@ PatchBaselineFramesForDebugMode(JSContext* cx, // - All the ways above. // C. From the debug trap handler. // D. From the debug prologue. - // K. From a JSOP_DEBUGAFTERYIELD instruction. // E. From the debug epilogue. // // Cycles (On to Off to On)+ or (Off to On to Off)+: @@ -474,7 +470,6 @@ PatchBaselineFramesForDebugMode(JSContext* cx, kind == ICEntry::Kind_EarlyStackCheck || kind == ICEntry::Kind_DebugTrap || kind == ICEntry::Kind_DebugPrologue || - kind == ICEntry::Kind_DebugAfterYield || kind == ICEntry::Kind_DebugEpilogue); // We will have allocated a new recompile info, so delete the @@ -551,17 +546,6 @@ PatchBaselineFramesForDebugMode(JSContext* cx, popFrameReg = true; break; - case ICEntry::Kind_DebugAfterYield: - // Case K above. - // - // Resume at the next instruction. - MOZ_ASSERT(*pc == JSOP_DEBUGAFTERYIELD); - recompInfo->resumeAddr = bl->nativeCodeForPC(script, - pc + JSOP_DEBUGAFTERYIELD_LENGTH, - &recompInfo->slotInfo); - popFrameReg = true; - break; - default: // Case E above. // @@ -961,9 +945,9 @@ HasForcedReturn(BaselineDebugModeOSRInfo* info, bool rv) if (kind == ICEntry::Kind_DebugEpilogue) return true; - // |rv| is the value in ReturnReg. If true, in the case of the prologue or - // after yield, it means a forced return. - if (kind == ICEntry::Kind_DebugPrologue || kind == ICEntry::Kind_DebugAfterYield) + // |rv| is the value in ReturnReg. If true, in the case of the prologue, + // it means a forced return. + if (kind == ICEntry::Kind_DebugPrologue) return rv; // N.B. The debug trap handler handles its own forced return, so no diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h index 17e06668691b..da4380d1cec5 100644 --- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -256,9 +256,8 @@ class ICEntry Kind_DebugTrap, // A fake IC entry for returning from a callVM to - // Debug{Prologue,AfterYield,Epilogue}. + // Debug{Prologue,Epilogue}. Kind_DebugPrologue, - Kind_DebugAfterYield, Kind_DebugEpilogue, Kind_Invalid diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index d170b0ee3c41..e54d4063811d 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -957,19 +957,12 @@ InterpretResume(JSContext* cx, HandleObject obj, HandleValue val, HandleProperty } bool -DebugAfterYield(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn) +DebugAfterYield(JSContext* cx, BaselineFrame* frame) { - *mustReturn = false; - // The BaselineFrame has just been constructed by JSOP_RESUME in the // caller. We need to set its debuggee flag as necessary. - // - // If a breakpoint is set on JSOP_DEBUGAFTERYIELD, or stepping is enabled, - // we may already have done this work. Don't fire onEnterFrame again. - if (frame->script()->isDebuggee() && !frame->isDebuggee()) { + if (frame->script()->isDebuggee()) frame->setIsDebuggee(); - return DebugPrologue(cx, frame, pc, mustReturn); - } return true; } @@ -982,19 +975,9 @@ GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, Handlescript(); uint32_t offset = script->yieldAndAwaitOffsets()[genObj->yieldAndAwaitIndex()]; - jsbytecode* pc = script->offsetToPC(offset); - frame->setOverridePc(pc); - - // In the interpreter, GeneratorObject::resume marks the generator as running, - // so we do the same. - genObj->setRunning(); - - bool mustReturn = false; - if (!DebugAfterYield(cx, frame, pc, &mustReturn)) - return false; - if (mustReturn) - resumeKind = GeneratorObject::RETURN; + frame->setOverridePc(script->offsetToPC(offset)); + MOZ_ALWAYS_TRUE(DebugAfterYield(cx, frame)); MOZ_ALWAYS_FALSE(js::GeneratorThrowOrReturn(cx, frame, genObj, arg, resumeKind)); return false; } @@ -1104,15 +1087,11 @@ HandleDebugTrap(JSContext* cx, BaselineFrame* frame, uint8_t* retAddr, bool* mus jsbytecode* pc = script->baselineScript()->icEntryFromReturnAddress(retAddr).pc(script); if (*pc == JSOP_DEBUGAFTERYIELD) { - // JSOP_DEBUGAFTERYIELD will set the frame's debuggee flag and call the - // onEnterFrame handler, but if we set a breakpoint there we have to do - // it now. + // JSOP_DEBUGAFTERYIELD will set the frame's debuggee flag, but if we + // set a breakpoint there we have to do it now. MOZ_ASSERT(!frame->isDebuggee()); - - if (!DebugAfterYield(cx, frame, pc, mustReturn)) + if (!DebugAfterYield(cx, frame)) return false; - if (*mustReturn) - return true; } MOZ_ASSERT(frame->isDebuggee()); diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index ae024af85377..85722eef583a 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -785,7 +785,7 @@ MOZ_MUST_USE bool InterpretResume(JSContext* cx, HandleObject obj, HandleValue val, HandlePropertyName kind, MutableHandleValue rval); MOZ_MUST_USE bool -DebugAfterYield(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn); +DebugAfterYield(JSContext* cx, BaselineFrame* frame); MOZ_MUST_USE bool GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, Handle genObj, HandleValue arg, uint32_t resumeKind); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 28aa12bb123f..79c5752b802f 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -1817,15 +1817,6 @@ Debugger::fireEnterFrame(JSContext* cx, MutableHandleValue vp) RootedValue scriptFrame(cx); FrameIter iter(cx); - -#if DEBUG - // Assert that the hook won't be able to re-enter the generator. - if (iter.hasScript() && *iter.pc() == JSOP_DEBUGAFTERYIELD) { - GeneratorObject* genObj = GetGeneratorObjectForFrame(cx, iter.abstractFramePtr()); - MOZ_ASSERT(genObj->isRunning() || genObj->isClosing()); - } -#endif - if (!getFrame(cx, iter, &scriptFrame)) return reportUncaughtException(ar); diff --git a/js/src/vm/GeneratorObject.cpp b/js/src/vm/GeneratorObject.cpp index d4d61743c23e..4e983ae57d09 100644 --- a/js/src/vm/GeneratorObject.cpp +++ b/js/src/vm/GeneratorObject.cpp @@ -134,6 +134,7 @@ js::GeneratorThrowOrReturn(JSContext* cx, AbstractFramePtr frame, HandlesetPendingException(arg); + genObj->setRunning(); } else { MOZ_ASSERT(resumeKind == GeneratorObject::RETURN); @@ -149,8 +150,9 @@ js::GeneratorThrowOrReturn(JSContext* cx, AbstractFramePtr frame, Handle genObj, HandleValue arg) + HandleObject obj, HandleValue arg, GeneratorObject::ResumeKind resumeKind) { + Rooted genObj(cx, &obj->as()); MOZ_ASSERT(genObj->isSuspended()); RootedFunction callee(cx, &genObj->callee()); @@ -182,8 +184,18 @@ GeneratorObject::resume(JSContext* cx, InterpreterActivation& activation, MOZ_ASSERT(activation.regs().spForStackDepth(activation.regs().stackDepth())); activation.regs().sp[-1] = arg; - genObj->setRunning(); - return true; + switch (resumeKind) { + case NEXT: + genObj->setRunning(); + return true; + + case THROW: + case RETURN: + return GeneratorThrowOrReturn(cx, activation.regs().fp(), genObj, arg, resumeKind); + + default: + MOZ_CRASH("bad resumeKind"); + } } const Class GeneratorObject::class_ = { diff --git a/js/src/vm/GeneratorObject.h b/js/src/vm/GeneratorObject.h index d74ab5e1acc1..e9f9de70a204 100644 --- a/js/src/vm/GeneratorObject.h +++ b/js/src/vm/GeneratorObject.h @@ -60,7 +60,7 @@ class GeneratorObject : public NativeObject static JSObject* create(JSContext* cx, AbstractFramePtr frame); static bool resume(JSContext* cx, InterpreterActivation& activation, - Handle genObj, HandleValue arg); + HandleObject obj, HandleValue arg, ResumeKind resumeKind); static bool initialSuspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc) { return suspend(cx, obj, frame, pc, nullptr, 0); @@ -147,17 +147,13 @@ class GeneratorObject : public NativeObject setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_RUNNING)); } void setClosing() { - MOZ_ASSERT(isRunning()); + MOZ_ASSERT(isSuspended()); setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(YIELD_AND_AWAIT_INDEX_CLOSING)); } void setYieldAndAwaitIndex(uint32_t yieldAndAwaitIndex) { MOZ_ASSERT_IF(yieldAndAwaitIndex == 0, getFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT).isUndefined()); MOZ_ASSERT_IF(yieldAndAwaitIndex != 0, isRunning() || isClosing()); - setYieldAndAwaitIndexNoAssert(yieldAndAwaitIndex); - } - // Debugger has to flout the state machine rules a bit. - void setYieldAndAwaitIndexNoAssert(uint32_t yieldAndAwaitIndex) { MOZ_ASSERT(yieldAndAwaitIndex < uint32_t(YIELD_AND_AWAIT_INDEX_CLOSING)); setFixedSlot(YIELD_AND_AWAIT_INDEX_SLOT, Int32Value(yieldAndAwaitIndex)); MOZ_ASSERT(isSuspended()); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 593c2e7ca1b3..47c84f3ea35a 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -4267,14 +4267,13 @@ CASE(JSOP_AWAIT) CASE(JSOP_RESUME) { { - Rooted gen(cx, ®S.sp[-2].toObject().as()); + ReservedRooted gen(&rootObject0, ®S.sp[-2].toObject()); ReservedRooted val(&rootValue0, REGS.sp[-1]); // popInlineFrame expects there to be an additional value on the stack // to pop off, so leave "gen" on the stack. GeneratorObject::ResumeKind resumeKind = GeneratorObject::getResumeKind(REGS.pc); - if (!GeneratorObject::resume(cx, activation, gen, val)) - goto error; + bool ok = GeneratorObject::resume(cx, activation, gen, val, resumeKind); JSScript* generatorScript = REGS.fp()->script(); if (cx->realm() != generatorScript->realm()) @@ -4286,31 +4285,8 @@ CASE(JSOP_RESUME) TraceLogStartEvent(logger, scriptEvent); TraceLogStartEvent(logger, TraceLogger_Interpreter); - switch (Debugger::onEnterFrame(cx, REGS.fp())) { - case ResumeMode::Continue: - break; - case ResumeMode::Throw: - case ResumeMode::Terminate: + if (!ok) goto error; - case ResumeMode::Return: - MOZ_ASSERT_IF(REGS.fp()->callee().isGenerator(), // as opposed to an async function - gen->isClosed()); - if (!ForcedReturn(cx, REGS)) - goto error; - goto successful_return_continuation; - } - - switch (resumeKind) { - case GeneratorObject::NEXT: - break; - case GeneratorObject::THROW: - case GeneratorObject::RETURN: - MOZ_ALWAYS_FALSE(GeneratorThrowOrReturn(cx, activation.regs().fp(), gen, val, - resumeKind)); - goto error; - default: - MOZ_CRASH("bad resumeKind"); - } } ADVANCE_AND_DISPATCH(0); } diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index ddc2cd2b210d..65c5307acae4 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -2159,7 +2159,7 @@ class FrameIter bool ensureHasRematerializedFrame(JSContext* cx); // True when isInterp() or isBaseline(). True when isIon() if it - // has a rematerialized frame. False otherwise. + // has a rematerialized frame. False otherwise false otherwise. bool hasUsableAbstractFramePtr() const; // ----------------------------------------------------------- From 84b50800fcdbfca2c9180ee6ae6c379a9bb8140f Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 22 Aug 2018 01:59:10 +0300 Subject: [PATCH 44/49] Bug 1484852 - Update svg/text/reftests to account for passes on Windows. CLOSED TREE --HG-- extra : amend_source : 3db224cd105419db05028ee4c0f5b9e07ecf6f51 --- .../meta/svg/text/reftests/text-complex-001.svg.ini | 3 ++- .../meta/svg/text/reftests/text-complex-002.svg.ini | 3 ++- .../meta/svg/text/reftests/text-shape-inside-001.svg.ini | 3 ++- .../meta/svg/text/reftests/text-shape-inside-002.svg.ini | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini index 01f90d48d854..441ab11ed69e 100644 --- a/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini +++ b/testing/web-platform/meta/svg/text/reftests/text-complex-001.svg.ini @@ -1,2 +1,3 @@ [text-complex-001.svg] - expected: FAIL + expected: + if os != "win": FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini index 0b45c7375768..b3e48bd38848 100644 --- a/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini +++ b/testing/web-platform/meta/svg/text/reftests/text-complex-002.svg.ini @@ -1,2 +1,3 @@ [text-complex-002.svg] - expected: FAIL + expected: + if os != "win": FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini index 52d123afd692..10af35a19efc 100644 --- a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini +++ b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-001.svg.ini @@ -1,2 +1,3 @@ [text-shape-inside-001.svg] - expected: FAIL + expected: + if os != "win": FAIL diff --git a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini index 76a712eac871..c51b3c84edf4 100644 --- a/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini +++ b/testing/web-platform/meta/svg/text/reftests/text-shape-inside-002.svg.ini @@ -1,2 +1,3 @@ [text-shape-inside-002.svg] - expected: FAIL + expected: + if os != "win": FAIL From 40deb13c65fbe0243dee803ee82954f03e331eb2 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Fri, 27 Jul 2018 01:25:49 +0100 Subject: [PATCH 45/49] Bug 1471339 - Add RUSTFLAGS to Linux coverage build to enable gcov profiling for Rust. r=jmaher --HG-- extra : rebase_source : 625c667376ad80a1f2fdd8493a7243ab18f2ff16 extra : source : 780db89a805956fc1bf0059ee55081b9fe5671f6 --- browser/config/mozconfigs/linux64/code-coverage | 1 + 1 file changed, 1 insertion(+) diff --git a/browser/config/mozconfigs/linux64/code-coverage b/browser/config/mozconfigs/linux64/code-coverage index 8e3ff958a647..d1b7ac3bc792 100644 --- a/browser/config/mozconfigs/linux64/code-coverage +++ b/browser/config/mozconfigs/linux64/code-coverage @@ -15,3 +15,4 @@ export CFLAGS="--coverage" export CXXFLAGS="--coverage" export LDFLAGS="--coverage -L$topsrcdir/clang/lib/clang/7.0.0/lib/linux/" export LIBS="-lclang_rt.profile-x86_64" +export RUSTFLAGS="-Ccodegen-units=1 -Zprofile -Zno-landing-pads" From afa2f5a21b7ef42e98f04de2490012c01b1f12c1 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 22 Aug 2018 02:10:14 +0300 Subject: [PATCH 46/49] Bug 1482457 - Update expectations for ignore-opens-during-unload to account for crashes on macOS and Windows debug. CLOSED TREE --HG-- extra : rebase_source : 7705d8a15f5f430aafdcb5bd229726b642bd7be5 --- .../ignore-opens-during-unload.window.js.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini index b99cd449488a..8176f6298437 100644 --- a/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini +++ b/testing/web-platform/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/ignore-opens-during-unload.window.js.ini @@ -4,3 +4,4 @@ if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH + if debug and (os == "mac" or os == "win"): CRASH From 9ddc2637622a9bfdf14f658569bf1d50c9c8e242 Mon Sep 17 00:00:00 2001 From: "J.C. Jones" Date: Tue, 21 Aug 2018 11:07:22 -0700 Subject: [PATCH 47/49] Bug 1470914 - land NSS d3f512d4f76e UPGRADE_NSS_RELEASE, r=me --HG-- extra : rebase_source : b1659503f5e91eae88beb66f129719960303c7fa --- security/nss/TAG-INFO | 2 +- security/nss/cmd/lib/secutil.c | 116 +++++++-- security/nss/cmd/lib/secutil.h | 4 +- security/nss/cmd/selfserv/selfserv.c | 49 ++-- security/nss/cmd/tstclnt/tstclnt.c | 105 ++++++-- security/nss/coreconf/coreconf.dep | 1 - .../nss/gtests/nss_bogo_shim/nss_bogo_shim.cc | 36 ++- .../ssl_gtest/ssl_resumption_unittest.cc | 27 ++ .../nss/gtests/ssl_gtest/tls_hkdf_unittest.cc | 38 ++- security/nss/lib/ckfw/builtins/certdata.txt | 120 +++++++++ security/nss/lib/ssl/tls13con.c | 27 +- security/nss/tests/all.sh | 2 +- security/nss/tests/ssl/ssl.sh | 231 ++++++++++-------- security/nss/tests/ssl/sslstress.txt | 7 - 14 files changed, 572 insertions(+), 193 deletions(-) diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index e5063fc3ac90..d21b9db7baba 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -6349fa699c3b +d3f512d4f76e diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index 6be2df432aa2..97c7f750a673 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -3799,7 +3799,7 @@ SECU_ParseSSLVersionRangeString(const char *input, return SECSuccess; } -SSLNamedGroup +static SSLNamedGroup groupNameToNamedGroup(char *name) { if (PL_strlen(name) == 4) { @@ -3837,6 +3837,23 @@ groupNameToNamedGroup(char *name) return ssl_grp_none; } +static SECStatus +countItems(const char *arg, unsigned int *numItems) +{ + char *str = PORT_Strdup(arg); + if (!str) { + return SECFailure; + } + char *p = strtok(str, ","); + while (p) { + ++(*numItems); + p = strtok(NULL, ","); + } + PORT_Free(str); + str = NULL; + return SECSuccess; +} + SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int *enabledGroupsCount) @@ -3847,21 +3864,12 @@ parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int numValues = 0; unsigned int count = 0; - /* Count the number of groups. */ - str = PORT_Strdup(arg); - if (!str) { + if (countItems(arg, &numValues) != SECSuccess) { return SECFailure; } - p = strtok(str, ","); - while (p) { - ++numValues; - p = strtok(NULL, ","); - } - PORT_Free(str); - str = NULL; groups = PORT_ZNewArray(SSLNamedGroup, numValues); if (!groups) { - goto done; + return SECFailure; } /* Get group names. */ @@ -3881,9 +3889,7 @@ parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, } done: - if (str) { - PORT_Free(str); - } + PORT_Free(str); if (!count) { PORT_Free(groups); return SECFailure; @@ -3893,3 +3899,83 @@ done: *enabledGroups = groups; return SECSuccess; } + +SSLSignatureScheme +schemeNameToScheme(const char *name) +{ +#define compareScheme(x) \ + do { \ + if (!PORT_Strncmp(name, #x, PORT_Strlen(#x))) { \ + return ssl_sig_##x; \ + } \ + } while (0) + + compareScheme(rsa_pkcs1_sha1); + compareScheme(rsa_pkcs1_sha256); + compareScheme(rsa_pkcs1_sha384); + compareScheme(rsa_pkcs1_sha512); + compareScheme(ecdsa_sha1); + compareScheme(ecdsa_secp256r1_sha256); + compareScheme(ecdsa_secp384r1_sha384); + compareScheme(ecdsa_secp521r1_sha512); + compareScheme(rsa_pss_rsae_sha256); + compareScheme(rsa_pss_rsae_sha384); + compareScheme(rsa_pss_rsae_sha512); + compareScheme(ed25519); + compareScheme(ed448); + compareScheme(rsa_pss_pss_sha256); + compareScheme(rsa_pss_pss_sha384); + compareScheme(rsa_pss_pss_sha512); + compareScheme(dsa_sha1); + compareScheme(dsa_sha256); + compareScheme(dsa_sha384); + compareScheme(dsa_sha512); + +#undef compareScheme + + return ssl_sig_none; +} + +SECStatus +parseSigSchemeList(const char *arg, const SSLSignatureScheme **enabledSigSchemes, + unsigned int *enabledSigSchemeCount) +{ + SSLSignatureScheme *schemes; + unsigned int numValues = 0; + unsigned int count = 0; + + if (countItems(arg, &numValues) != SECSuccess) { + return SECFailure; + } + schemes = PORT_ZNewArray(SSLSignatureScheme, numValues); + if (!schemes) { + return SECFailure; + } + + /* Get group names. */ + char *str = PORT_Strdup(arg); + if (!str) { + goto done; + } + char *p = strtok(str, ","); + while (p) { + SSLSignatureScheme scheme = schemeNameToScheme(p); + if (scheme == ssl_sig_none) { + count = 0; + goto done; + } + schemes[count++] = scheme; + p = strtok(NULL, ","); + } + +done: + PORT_Free(str); + if (!count) { + PORT_Free(schemes); + return SECFailure; + } + + *enabledSigSchemeCount = count; + *enabledSigSchemes = schemes; + return SECSuccess; +} diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h index fe07aca606b6..ed3372c14fa0 100644 --- a/security/nss/cmd/lib/secutil.h +++ b/security/nss/cmd/lib/secutil.h @@ -406,7 +406,9 @@ SECU_ParseSSLVersionRangeString(const char *input, SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups, unsigned int *enabledGroupsCount); -SSLNamedGroup groupNameToNamedGroup(char *name); +SECStatus parseSigSchemeList(const char *arg, + const SSLSignatureScheme **enabledSigSchemes, + unsigned int *enabledSigSchemeCount); /* * diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index c372ec9b83b8..093c23b8a8d8 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -165,9 +165,8 @@ PrintUsageHeader(const char *progName) " [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" " [-V [min-version]:[max-version]] [-a sni_name]\n" " [ T ] [-A ca]\n" - " [-C SSLCacheEntries] [-S dsa_nickname] -Q [-I groups]" - " [-e ec_nickname]" - "\n" + " [-C SSLCacheEntries] [-S dsa_nickname] [-Q]\n" + " [-I groups] [-J signatureschemes] [-e ec_nickname]\n" " -U [0|1] -H [0|1|2] -W [0|1]\n" "\n", progName); @@ -195,7 +194,6 @@ PrintParameterUsage() "-s means disable SSL socket locking for performance\n" "-u means enable Session Ticket extension for TLS.\n" "-v means verbose output\n" - "-z means enable compression.\n" "-L seconds means log statistics every 'seconds' seconds (default=30).\n" "-M maxProcs tells how many processes to run in a multi-process server\n" "-N means do NOT use the server session cache. Incompatible with -M.\n" @@ -228,6 +226,13 @@ PrintParameterUsage() "-I comma separated list of enabled groups for TLS key exchange.\n" " The following values are valid:\n" " P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n" + "-J comma separated list of enabled signature schemes in preference order.\n" + " The following values are valid:\n" + " rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n" + " ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n" + " ecdsa_secp521r1_sha512,\n" + " rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n" + " rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n" "-Z enable 0-RTT (for TLS 1.3; also use -u)\n", stderr); } @@ -795,13 +800,14 @@ PRBool NoReuse = PR_FALSE; PRBool hasSidCache = PR_FALSE; PRBool disableLocking = PR_FALSE; PRBool enableSessionTickets = PR_FALSE; -PRBool enableCompression = PR_FALSE; PRBool failedToNegotiateName = PR_FALSE; PRBool enableExtendedMasterSecret = PR_FALSE; PRBool zeroRTT = PR_FALSE; PRBool enableALPN = PR_FALSE; SSLNamedGroup *enabledGroups = NULL; unsigned int enabledGroupsCount = 0; +const SSLSignatureScheme *enabledSigSchemes = NULL; +unsigned int enabledSigSchemeCount = 0; static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX]; static int virtServerNameIndex = 1; @@ -1857,13 +1863,6 @@ server_main( } } - if (enableCompression) { - rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); - if (rv != SECSuccess) { - errExit("error enabling compression "); - } - } - if (virtServerNameIndex > 1) { rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig, (void *)&virtServerNameArray); @@ -1970,6 +1969,13 @@ server_main( } } + if (enabledSigSchemes) { + rv = SSL_SignatureSchemePrefSet(model_sock, enabledSigSchemes, enabledSigSchemeCount); + if (rv < 0) { + errExit("SSL_SignatureSchemePrefSet failed"); + } + } + /* This cipher is not on by default. The Acceptance test * would like it to be. Turn this cipher on. */ @@ -2214,9 +2220,10 @@ main(int argc, char **argv) /* please keep this list of options in ASCII collating sequence. ** numbers, then capital letters, then lower case, alphabetical. ** XXX: 'B', 'E', 'q', and 'x' were used in the past but removed - ** in 3.28, please leave some time before resuing those. */ + ** in 3.28, please leave some time before resuing those. + ** 'z' was removed in 3.39. */ optstate = PL_CreateOptState(argc, argv, - "2:A:C:DGH:I:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:yz"); + "2:A:C:DGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++optionsFound; switch (optstate->option) { @@ -2429,10 +2436,6 @@ main(int argc, char **argv) debugCache = PR_TRUE; break; - case 'z': - enableCompression = PR_TRUE; - break; - case 'Z': zeroRTT = PR_TRUE; break; @@ -2451,6 +2454,16 @@ main(int argc, char **argv) } break; + case 'J': + rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad signature scheme specified.\n"); + fprintf(stderr, "Run '%s -h' for usage information.\n", progName); + exit(5); + } + break; + default: case '?': fprintf(stderr, "Unrecognized or bad option specified.\n"); diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 6f5a43146ae0..b09b2922201f 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -106,6 +106,45 @@ secuPWData pwdata = { PW_NONE, 0 }; SSLNamedGroup *enabledGroups = NULL; unsigned int enabledGroupsCount = 0; +const SSLSignatureScheme *enabledSigSchemes = NULL; +unsigned int enabledSigSchemeCount = 0; + +const char * +signatureSchemeName(SSLSignatureScheme scheme) +{ + switch (scheme) { +#define strcase(x) \ + case ssl_sig_##x: \ + return #x + strcase(none); + strcase(rsa_pkcs1_sha1); + strcase(rsa_pkcs1_sha256); + strcase(rsa_pkcs1_sha384); + strcase(rsa_pkcs1_sha512); + strcase(ecdsa_sha1); + strcase(ecdsa_secp256r1_sha256); + strcase(ecdsa_secp384r1_sha384); + strcase(ecdsa_secp521r1_sha512); + strcase(rsa_pss_rsae_sha256); + strcase(rsa_pss_rsae_sha384); + strcase(rsa_pss_rsae_sha512); + strcase(ed25519); + strcase(ed448); + strcase(rsa_pss_pss_sha256); + strcase(rsa_pss_pss_sha384); + strcase(rsa_pss_pss_sha512); + strcase(dsa_sha1); + strcase(dsa_sha256); + strcase(dsa_sha384); + strcase(dsa_sha512); +#undef strcase + case ssl_sig_rsa_pkcs1_sha1md5: + return "RSA PKCS#1 SHA1+MD5"; + default: + break; + } + return "Unknown Scheme"; +} void printSecurityInfo(PRFileDesc *fd) @@ -132,11 +171,13 @@ printSecurityInfo(PRFileDesc *fd) suite.macBits, suite.macAlgorithmName); FPRINTF(stderr, "tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" - " Compression: %s, Extended Master Secret: %s\n", + " Compression: %s, Extended Master Secret: %s\n" + " Signature Scheme: %s\n", channel.authKeyBits, suite.authAlgorithmName, channel.keaKeyBits, suite.keaTypeName, channel.compressionMethodName, - channel.extendedMasterSecretUsed ? "Yes" : "No"); + channel.extendedMasterSecretUsed ? "Yes" : "No", + signatureSchemeName(channel.signatureScheme)); } } cert = SSL_RevealCert(fd); @@ -178,11 +219,12 @@ PrintUsageHeader() { fprintf(stderr, "Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n" - "[-D | -d certdir] [-C] [-b | -R root-module] \n" - "[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n" - "[-V [min-version]:[max-version]] [-K] [-T] [-U]\n" - "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]] [-I groups]\n" - "[-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n" + " [-D | -d certdir] [-C] [-b | -R root-module] \n" + " [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n" + " [-V [min-version]:[max-version]] [-K] [-T] [-U]\n" + " [-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n" + " [-I groups] [-J signatureschemes]\n" + " [-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n" "\n", progName); } @@ -225,7 +267,6 @@ PrintParameterUsage() fprintf(stderr, "%-20s Timeout for server ping (default: no timeout).\n", "-t seconds"); fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N"); fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u"); - fprintf(stderr, "%-20s Enable compression.\n", "-z"); fprintf(stderr, "%-20s Enable false start.\n", "-g"); fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T"); fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U"); @@ -255,6 +296,15 @@ PrintParameterUsage() "%-20s The following values are valid:\n" "%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n", "-I", "", ""); + fprintf(stderr, "%-20s Comma separated list of signature schemes in preference order.\n" + "%-20s The following values are valid:\n" + "%-20s rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n" + "%-20s ecdsa_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384,\n" + "%-20s ecdsa_secp521r1_sha512,\n" + "%-20s rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n" + "%-20s rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n" + "%-20s dsa_sha1, dsa_sha256, dsa_sha384, dsa_sha512\n", + "-J", "", "", "", "", "", "", ""); fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello"); fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}"); fprintf(stderr, "%-20s Exit after handshake\n", "-Q"); @@ -906,7 +956,6 @@ int multiplier = 0; SSLVersionRange enabledVersions; int disableLocking = 0; int enableSessionTickets = 0; -int enableCompression = 0; int enableFalseStart = 0; int enableCertStatus = 0; int enableSignedCertTimestamps = 0; @@ -1283,14 +1332,6 @@ run() goto done; } - /* enable compression. */ - rv = SSL_OptionSet(s, SSL_ENABLE_DEFLATE, enableCompression); - if (rv != SECSuccess) { - SECU_PrintError(progName, "error enabling compression"); - error = 1; - goto done; - } - /* enable false start. */ rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart); if (rv != SECSuccess) { @@ -1374,6 +1415,15 @@ run() } } + if (enabledSigSchemes) { + rv = SSL_SignatureSchemePrefSet(s, enabledSigSchemes, enabledSigSchemeCount); + if (rv < 0) { + SECU_PrintError(progName, "SSL_SignatureSchemePrefSet failed"); + error = 1; + goto done; + } + } + serverCertAuth.dbHandle = CERT_GetDefaultCertDB(); SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth); @@ -1628,10 +1678,12 @@ main(int argc, char **argv) } } - /* XXX: 'B' was used in the past but removed in 3.28, - * please leave some time before resuing it. */ + /* Note: 'B' was used in the past but removed in 3.28 + * 'z' was removed in 3.39 + * Please leave some time before reusing these. + */ optstate = PL_CreateOptState(argc, argv, - "46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z"); + "46A:CDFGHI:J:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -1850,10 +1902,6 @@ main(int argc, char **argv) pwdata.data = PORT_Strdup(optstate->value); break; - case 'z': - enableCompression = 1; - break; - case 'I': rv = parseGroupList(optstate->value, &enabledGroups, &enabledGroupsCount); if (rv != SECSuccess) { @@ -1862,6 +1910,15 @@ main(int argc, char **argv) Usage(); } break; + + case 'J': + rv = parseSigSchemeList(optstate->value, &enabledSigSchemes, &enabledSigSchemeCount); + if (rv != SECSuccess) { + PL_DestroyOptState(optstate); + fprintf(stderr, "Bad signature scheme specified.\n"); + Usage(); + } + break; } } PL_DestroyOptState(optstate); diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee3..5182f75552c8 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc index 51bfab1d4fba..b2b59c2f0e8d 100644 --- a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc +++ b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc @@ -346,11 +346,44 @@ class TestAgent { PR_TRUE); if (rv != SECSuccess) return false; - if (!EnableNonExportCiphers()) return false; + if (!ConfigureCiphers()) return false; return true; } + bool ConfigureCiphers() { + auto cipherList = cfg_.get("nss-cipher"); + + if (cipherList.empty()) { + return EnableNonExportCiphers(); + } + + for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) { + SSLCipherSuiteInfo csinfo; + std::string::size_type n; + SECStatus rv = SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &csinfo, + sizeof(csinfo)); + if (rv != SECSuccess) { + return false; + } + + // Check if cipherList contains the name of the Cipher Suite and + // enable/disable accordingly. + n = cipherList.find(csinfo.cipherSuiteName, 0); + if (std::string::npos == n) { + rv = SSL_CipherPrefSet(ssl_fd_.get(), SSL_ImplementedCiphers[i], + PR_FALSE); + } else { + rv = SSL_CipherPrefSet(ssl_fd_.get(), SSL_ImplementedCiphers[i], + PR_TRUE); + } + if (rv != SECSuccess) { + return false; + } + } + return true; + } + bool EnableNonExportCiphers() { for (size_t i = 0; i < SSL_NumImplementedCiphers; ++i) { SSLCipherSuiteInfo csinfo; @@ -556,6 +589,7 @@ std::unique_ptr ReadConfig(int argc, char** argv) { cfg->AddEntry>("signing-prefs", std::vector()); cfg->AddEntry>("verify-prefs", std::vector()); cfg->AddEntry("expect-peer-signature-algorithm", 0); + cfg->AddEntry("nss-cipher", ""); auto rv = cfg->ParseArgs(argc, argv); switch (rv) { diff --git a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc index 2cc98a3278d5..2f26d5509fdf 100644 --- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc @@ -394,6 +394,33 @@ TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) { ssl_sig_rsa_pss_rsae_sha256); } +// Verify that TLS 1.3 server doesn't request certificate in the main +// handshake, after resumption. +TEST_P(TlsConnectTls13, TestTls13ResumeNoCertificateRequest) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + client_->SetupClientAuth(); + server_->RequestClientAuth(true); + Connect(); + SendReceive(); // Need to read so that we absorb the session ticket. + ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd())); + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + ExpectResumption(RESUME_TICKET); + server_->RequestClientAuth(false); + auto cr_capture = + MakeTlsFilter(server_, ssl_hs_certificate_request); + cr_capture->EnableDecryption(); + Connect(); + SendReceive(); + EXPECT_EQ(0U, cr_capture->buffer().len()) << "expect nothing captured yet"; + + // Sanity check whether the client certificate matches the one + // decrypted from ticket. + ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd())); + EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert)); +} + // We need to enable different cipher suites at different times in the following // tests. Those cipher suites need to be suited to the version. static uint16_t ChooseOneCipher(uint16_t version) { diff --git a/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc b/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc index 45f6cf2bd935..a24a8e916af4 100644 --- a/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc +++ b/security/nss/gtests/ssl_gtest/tls_hkdf_unittest.cc @@ -60,9 +60,11 @@ const std::string kHashName[] = {"None", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"}; static void ImportKey(ScopedPK11SymKey* to, const DataBuffer& key, - PK11SlotInfo* slot) { + SSLHashType hash_type, PK11SlotInfo* slot) { + ASSERT_LT(hash_type, sizeof(kHashLength)); + ASSERT_LE(kHashLength[hash_type], key.len()); SECItem key_item = {siBuffer, const_cast(key.data()), - static_cast(key.len())}; + static_cast(kHashLength[hash_type])}; PK11SymKey* inner = PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, PK11_OriginUnwrap, @@ -106,8 +108,8 @@ class TlsHkdfTest : public ::testing::Test, } void SetUp() { - ImportKey(&k1_, kKey1, slot_.get()); - ImportKey(&k2_, kKey2, slot_.get()); + ImportKey(&k1_, kKey1, hash_type_, slot_.get()); + ImportKey(&k2_, kKey2, hash_type_, slot_.get()); } void VerifyKey(const ScopedPK11SymKey& key, const DataBuffer& expected) { @@ -183,9 +185,9 @@ TEST_P(TlsHkdfTest, HkdfKey1Only) { {/* ssl_hash_md5 */}, {/* ssl_hash_sha1 */}, {/* ssl_hash_sha224 */}, - {0x11, 0x87, 0x38, 0x28, 0xa9, 0x19, 0x78, 0x11, 0x33, 0x91, 0x24, - 0xb5, 0x8a, 0x1b, 0xb0, 0x9f, 0x7f, 0x0d, 0x8d, 0xbb, 0x10, 0xf4, - 0x9c, 0x54, 0xbd, 0x1f, 0xd8, 0x85, 0xcd, 0x15, 0x30, 0x33}, + {0x41, 0x6c, 0x53, 0x92, 0xb9, 0xf3, 0x6d, 0xf1, 0x88, 0xe9, 0x0e, + 0xb1, 0x4d, 0x17, 0xbf, 0x0d, 0xa1, 0x90, 0xbf, 0xdb, 0x7f, 0x1f, + 0x49, 0x56, 0xe6, 0xe5, 0x66, 0xa5, 0x69, 0xc8, 0xb1, 0x5c}, {0x51, 0xb1, 0xd5, 0xb4, 0x59, 0x79, 0x79, 0x08, 0x4a, 0x15, 0xb2, 0xdb, 0x84, 0xd3, 0xd6, 0xbc, 0xfc, 0x93, 0x45, 0xd9, 0xdc, 0x74, 0xda, 0x1a, 0x57, 0xc2, 0x76, 0x9f, 0x3f, 0x83, 0x45, 0x2f, 0xf6, 0xf3, 0x56, 0x1f, @@ -201,11 +203,9 @@ TEST_P(TlsHkdfTest, HkdfKey2Only) { {/* ssl_hash_md5 */}, {/* ssl_hash_sha1 */}, {/* ssl_hash_sha224 */}, - { - 0x2f, 0x5f, 0x78, 0xd0, 0xa4, 0xc4, 0x36, 0xee, 0x6c, 0x8a, 0x4e, - 0xf9, 0xd0, 0x43, 0x81, 0x02, 0x13, 0xfd, 0x47, 0x83, 0x63, 0x3a, - 0xd2, 0xe1, 0x40, 0x6d, 0x2d, 0x98, 0x00, 0xfd, 0xc1, 0x87, - }, + {0x16, 0xaf, 0x00, 0x54, 0x3a, 0x56, 0xc8, 0x26, 0xa2, 0xa7, 0xfc, + 0xb6, 0x34, 0x66, 0x8a, 0xfd, 0x36, 0xdc, 0x8e, 0xce, 0xc4, 0xd2, + 0x6c, 0x7a, 0xdc, 0xe3, 0x70, 0x36, 0x3d, 0x60, 0xfa, 0x0b}, {0x7b, 0x40, 0xf9, 0xef, 0x91, 0xff, 0xc9, 0xd1, 0x29, 0x24, 0x5c, 0xbf, 0xf8, 0x82, 0x76, 0x68, 0xae, 0x4b, 0x63, 0xe8, 0x03, 0xdd, 0x39, 0xa8, 0xd4, 0x6a, 0xf6, 0xe5, 0xec, 0xea, 0xf8, 0x7d, 0x91, 0x71, 0x81, 0xf1, @@ -221,11 +221,9 @@ TEST_P(TlsHkdfTest, HkdfKey1Key2) { {/* ssl_hash_md5 */}, {/* ssl_hash_sha1 */}, {/* ssl_hash_sha224 */}, - { - 0x79, 0x53, 0xb8, 0xdd, 0x6b, 0x98, 0xce, 0x00, 0xb7, 0xdc, 0xe8, - 0x03, 0x70, 0x8c, 0xe3, 0xac, 0x06, 0x8b, 0x22, 0xfd, 0x0e, 0x34, - 0x48, 0xe6, 0xe5, 0xe0, 0x8a, 0xd6, 0x16, 0x18, 0xe5, 0x48, - }, + {0xa5, 0x68, 0x02, 0x5a, 0x95, 0xc9, 0x7f, 0x55, 0x38, 0xbc, 0xf7, + 0x97, 0xcc, 0x0f, 0xd5, 0xf6, 0xa8, 0x8d, 0x15, 0xbc, 0x0e, 0x85, + 0x74, 0x70, 0x3c, 0xa3, 0x65, 0xbd, 0x76, 0xcf, 0x9f, 0xd3}, {0x01, 0x93, 0xc0, 0x07, 0x3f, 0x6a, 0x83, 0x0e, 0x2e, 0x4f, 0xb2, 0x58, 0xe4, 0x00, 0x08, 0x5c, 0x68, 0x9c, 0x37, 0x32, 0x00, 0x37, 0xff, 0xc3, 0x1c, 0x5b, 0x98, 0x0b, 0x02, 0x92, 0x3f, 0xfd, 0x73, 0x5a, 0x6f, 0x2a, @@ -241,9 +239,9 @@ TEST_P(TlsHkdfTest, HkdfExpandLabel) { {/* ssl_hash_md5 */}, {/* ssl_hash_sha1 */}, {/* ssl_hash_sha224 */}, - {0xc6, 0xdd, 0x6e, 0xc4, 0x76, 0xb8, 0x55, 0xf2, 0xa4, 0xfc, 0x59, - 0x04, 0xa4, 0x90, 0xdc, 0xa7, 0xa7, 0x0d, 0x94, 0x8f, 0xc2, 0xdc, - 0x15, 0x6d, 0x48, 0x93, 0x9d, 0x05, 0xbb, 0x9a, 0xbc, 0xc1}, + {0x3e, 0x4e, 0x6e, 0xd0, 0xbc, 0xc4, 0xf4, 0xff, 0xf0, 0xf5, 0x69, + 0xd0, 0x6c, 0x1e, 0x0e, 0x10, 0x32, 0xaa, 0xd7, 0xa3, 0xef, 0xf6, + 0xa8, 0x65, 0x8e, 0xbe, 0xee, 0xc7, 0x1f, 0x01, 0x6d, 0x3c}, {0x41, 0xea, 0x77, 0x09, 0x8c, 0x90, 0x04, 0x10, 0xec, 0xbc, 0x37, 0xd8, 0x5b, 0x54, 0xcd, 0x7b, 0x08, 0x15, 0x13, 0x20, 0xed, 0x1e, 0x3f, 0x54, 0x74, 0xf7, 0x8b, 0x06, 0x38, 0x28, 0x06, 0x37, 0x75, 0x23, 0xa2, 0xb7, diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index 572d56c430dd..193cef38f969 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -23025,3 +23025,123 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "OISTE WISeKey Global Root GC CA" +# +# Issuer: CN=OISTE WISeKey Global Root GC CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH +# Serial Number:21:2a:56:0c:ae:da:0c:ab:40:45:bf:2b:a2:2d:3a:ea +# Subject: CN=OISTE WISeKey Global Root GC CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH +# Not Valid Before: Tue May 09 09:48:34 2017 +# Not Valid After : Fri May 09 09:58:33 2042 +# Fingerprint (SHA-256): 85:60:F9:1C:36:24:DA:BA:95:70:B5:FE:A0:DB:E3:6F:F1:1A:83:23:BE:94:86:85:4F:B3:F3:4A:55:71:19:8D +# Fingerprint (SHA1): E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "OISTE WISeKey Global Root GC CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\155\061\013\060\011\006\003\125\004\006\023\002\103\110\061 +\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113\145 +\171\061\042\060\040\006\003\125\004\013\023\031\117\111\123\124 +\105\040\106\157\165\156\144\141\164\151\157\156\040\105\156\144 +\157\162\163\145\144\061\050\060\046\006\003\125\004\003\023\037 +\117\111\123\124\105\040\127\111\123\145\113\145\171\040\107\154 +\157\142\141\154\040\122\157\157\164\040\107\103\040\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\155\061\013\060\011\006\003\125\004\006\023\002\103\110\061 +\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113\145 +\171\061\042\060\040\006\003\125\004\013\023\031\117\111\123\124 +\105\040\106\157\165\156\144\141\164\151\157\156\040\105\156\144 +\157\162\163\145\144\061\050\060\046\006\003\125\004\003\023\037 +\117\111\123\124\105\040\127\111\123\145\113\145\171\040\107\154 +\157\142\141\154\040\122\157\157\164\040\107\103\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\041\052\126\014\256\332\014\253\100\105\277\053\242\055 +\072\352 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\151\060\202\001\357\240\003\002\001\002\002\020\041 +\052\126\014\256\332\014\253\100\105\277\053\242\055\072\352\060 +\012\006\010\052\206\110\316\075\004\003\003\060\155\061\013\060 +\011\006\003\125\004\006\023\002\103\110\061\020\060\016\006\003 +\125\004\012\023\007\127\111\123\145\113\145\171\061\042\060\040 +\006\003\125\004\013\023\031\117\111\123\124\105\040\106\157\165 +\156\144\141\164\151\157\156\040\105\156\144\157\162\163\145\144 +\061\050\060\046\006\003\125\004\003\023\037\117\111\123\124\105 +\040\127\111\123\145\113\145\171\040\107\154\157\142\141\154\040 +\122\157\157\164\040\107\103\040\103\101\060\036\027\015\061\067 +\060\065\060\071\060\071\064\070\063\064\132\027\015\064\062\060 +\065\060\071\060\071\065\070\063\063\132\060\155\061\013\060\011 +\006\003\125\004\006\023\002\103\110\061\020\060\016\006\003\125 +\004\012\023\007\127\111\123\145\113\145\171\061\042\060\040\006 +\003\125\004\013\023\031\117\111\123\124\105\040\106\157\165\156 +\144\141\164\151\157\156\040\105\156\144\157\162\163\145\144\061 +\050\060\046\006\003\125\004\003\023\037\117\111\123\124\105\040 +\127\111\123\145\113\145\171\040\107\154\157\142\141\154\040\122 +\157\157\164\040\107\103\040\103\101\060\166\060\020\006\007\052 +\206\110\316\075\002\001\006\005\053\201\004\000\042\003\142\000 +\004\114\351\120\300\306\017\162\030\274\330\361\272\263\211\342 +\171\112\243\026\247\153\124\044\333\121\377\352\364\011\044\303 +\013\042\237\313\152\047\202\201\015\322\300\257\061\344\164\202 +\156\312\045\331\214\165\235\361\333\320\232\242\113\041\176\026 +\247\143\220\322\071\324\261\207\170\137\030\226\017\120\033\065 +\067\017\152\306\334\331\023\115\244\216\220\067\346\275\133\061 +\221\243\124\060\122\060\016\006\003\125\035\017\001\001\377\004 +\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004 +\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004 +\024\110\207\024\254\343\303\236\220\140\072\327\312\211\356\323 +\255\214\264\120\146\060\020\006\011\053\006\001\004\001\202\067 +\025\001\004\003\002\001\000\060\012\006\010\052\206\110\316\075 +\004\003\003\003\150\000\060\145\002\060\046\307\151\133\334\325 +\347\262\347\310\014\214\214\303\335\171\214\033\143\325\311\122 +\224\116\115\202\112\163\036\262\200\204\251\045\300\114\132\155 +\111\051\140\170\023\342\176\110\353\144\002\061\000\333\064\040 +\062\010\377\232\111\002\266\210\336\024\257\135\154\231\161\215 +\032\077\213\327\340\242\066\206\034\007\202\072\166\123\375\302 +\242\355\357\173\260\200\117\130\017\113\123\071\275 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "OISTE WISeKey Global Root GC CA" +# Issuer: CN=OISTE WISeKey Global Root GC CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH +# Serial Number:21:2a:56:0c:ae:da:0c:ab:40:45:bf:2b:a2:2d:3a:ea +# Subject: CN=OISTE WISeKey Global Root GC CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH +# Not Valid Before: Tue May 09 09:48:34 2017 +# Not Valid After : Fri May 09 09:58:33 2042 +# Fingerprint (SHA-256): 85:60:F9:1C:36:24:DA:BA:95:70:B5:FE:A0:DB:E3:6F:F1:1A:83:23:BE:94:86:85:4F:B3:F3:4A:55:71:19:8D +# Fingerprint (SHA1): E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "OISTE WISeKey Global Root GC CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\340\021\204\136\064\336\276\210\201\271\234\366\026\046\321\226 +\037\303\271\061 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\251\326\271\055\057\223\144\370\245\151\312\221\351\150\007\043 +END +CKA_ISSUER MULTILINE_OCTAL +\060\155\061\013\060\011\006\003\125\004\006\023\002\103\110\061 +\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113\145 +\171\061\042\060\040\006\003\125\004\013\023\031\117\111\123\124 +\105\040\106\157\165\156\144\141\164\151\157\156\040\105\156\144 +\157\162\163\145\144\061\050\060\046\006\003\125\004\003\023\037 +\117\111\123\124\105\040\127\111\123\145\113\145\171\040\107\154 +\157\142\141\154\040\122\157\157\164\040\107\103\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\041\052\126\014\256\332\014\253\100\105\277\053\242\055 +\072\352 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE diff --git a/security/nss/lib/ssl/tls13con.c b/security/nss/lib/ssl/tls13con.c index 798d04386bac..3a10ef9d68a8 100644 --- a/security/nss/lib/ssl/tls13con.c +++ b/security/nss/lib/ssl/tls13con.c @@ -2312,6 +2312,13 @@ tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length) return SECSuccess; } +static PRBool +tls13_CanRequestClientAuth(sslSocket *ss) +{ + return ss->opt.requestCertificate && + ss->ssl3.hs.kea_def->authKeyType != ssl_auth_psk; +} + static SECStatus tls13_SendEncryptedServerSequence(sslSocket *ss) { @@ -2343,7 +2350,7 @@ tls13_SendEncryptedServerSequence(sslSocket *ss) return SECFailure; /* error code is set. */ } - if (ss->opt.requestCertificate) { + if (tls13_CanRequestClientAuth(ss)) { rv = tls13_SendCertificateRequest(ss); if (rv != SECSuccess) { return SECFailure; /* error code is set. */ @@ -2462,9 +2469,11 @@ tls13_SendServerHelloSequence(sslSocket *ss) LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } - TLS13_SET_HS_STATE(ss, - ss->opt.requestCertificate ? wait_client_cert - : wait_finished); + if (tls13_CanRequestClientAuth(ss)) { + TLS13_SET_HS_STATE(ss, wait_client_cert); + } else { + TLS13_SET_HS_STATE(ss, wait_finished); + } } ss->ssl3.hs.serverHelloTime = ssl_TimeUsec(); @@ -4168,7 +4177,7 @@ tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length) return SECFailure; } - if (!ss->opt.requestCertificate && + if (!tls13_CanRequestClientAuth(ss) && (ss->ssl3.hs.zeroRttState != ssl_0rtt_done)) { dtls_ReceivedFirstMessageInFlight(ss); } @@ -5221,9 +5230,11 @@ tls13_HandleEndOfEarlyData(sslSocket *ss, PRUint8 *b, PRUint32 length) } ss->ssl3.hs.zeroRttState = ssl_0rtt_done; - TLS13_SET_HS_STATE(ss, - ss->opt.requestCertificate ? wait_client_cert - : wait_finished); + if (tls13_CanRequestClientAuth(ss)) { + TLS13_SET_HS_STATE(ss, wait_client_cert); + } else { + TLS13_SET_HS_STATE(ss, wait_finished); + } return SECSuccess; } diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh index bc2e1480363d..9c4ba4949bfc 100755 --- a/security/nss/tests/all.sh +++ b/security/nss/tests/all.sh @@ -316,7 +316,7 @@ if [ $NO_INIT_SUPPORT -eq 0 ]; then fi NSS_SSL_TESTS="${NSS_SSL_TESTS:-$nss_ssl_tests}" -nss_ssl_run="cov auth stapling stress" +nss_ssl_run="cov auth stapling signed_cert_timestamps stress dtls scheme" NSS_SSL_RUN="${NSS_SSL_RUN:-$nss_ssl_run}" # NOTE: diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh index 13e7b80b5db4..c1730d8d769f 100755 --- a/security/nss/tests/ssl/ssl.sh +++ b/security/nss/tests/ssl/ssl.sh @@ -64,9 +64,9 @@ ssl_init() PORT=$(($PORT + $padd)) fi NSS_SSL_TESTS=${NSS_SSL_TESTS:-normal_normal} - nss_ssl_run="stapling signed_cert_timestamps cov auth stress dtls" + nss_ssl_run="stapling signed_cert_timestamps cov auth stress dtls scheme" NSS_SSL_RUN=${NSS_SSL_RUN:-$nss_ssl_run} - + # Test case files SSLCOV=${QADIR}/ssl/sslcov.txt SSLAUTH=${QADIR}/ssl/sslauth.txt @@ -210,7 +210,6 @@ start_selfserv() if [ -n "$testname" ] ; then echo "$SCRIPTNAME: $testname ----" fi - sparam=`echo $sparam | sed -e 's;_; ;g'` if [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1" ] ; then ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec" else @@ -223,16 +222,16 @@ start_selfserv() fi echo "selfserv starting at `date`" echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \\" - echo " ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss ${sparam} -i ${R_SERVERPID}\\" + echo " ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID}\\" echo " -V ssl3:tls1.2 $verbose -H 1 &" if [ ${fileout} -eq 1 ]; then ${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \ - ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss ${sparam} -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 \ + ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 \ > ${SERVEROUTFILE} 2>&1 & RET=$? else ${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \ - ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss ${sparam} -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 & + ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 & RET=$? fi @@ -275,9 +274,8 @@ ssl_cov() html_head "SSL Cipher Coverage $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" - sparam="$CIPHER_SUITES" - start_selfserv # Launch the server + start_selfserv $CIPHER_SUITES # Launch the server VMIN="ssl3" VMAX="tls1.1" @@ -290,8 +288,8 @@ ssl_cov() # RSA-PSS tests are handled in a separate function case $testname in - *RSA-PSS) - continue + *RSA-PSS) + continue ;; esac @@ -331,7 +329,6 @@ ssl_cov_rsa_pss() html_head "SSL Cipher Coverage (RSA-PSS) $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" - sparam="$CIPHER_SUITES" if [ "$NORM_EXT" = "Extended Test" ] ; then echo "$SCRIPTNAME: skipping SSL Cipher Coverage (RSA-PSS) for $NORM_EXT" @@ -340,7 +337,7 @@ ssl_cov_rsa_pss() RSA_PSS_CERT=1 NO_ECC_CERTS=1 - start_selfserv # Launch the server + start_selfserv $CIPHER_SUITES RSA_PSS_CERT=0 NO_ECC_CERTS=0 @@ -351,11 +348,11 @@ ssl_cov_rsa_pss() while read ectype testmax param testname do case $testname in - *RSA-PSS) + *RSA-PSS) + ;; + *) + continue ;; - *) - continue - ;; esac echo "$SCRIPTNAME: running $testname (RSA-PSS) ----------------------------" @@ -402,7 +399,7 @@ ssl_auth() cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" ` sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" ` fi - start_selfserv + start_selfserv `echo "$sparam" | sed -e 's,_, ,g'` echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" echo " ${cparam} < ${REQUEST_FILE}" @@ -435,15 +432,15 @@ ssl_stapling_sub() value=$3 if [ "$NORM_EXT" = "Extended Test" ] ; then - # these tests use the ext_client directory for tstclnt, - # which doesn't contain the required "TestCA" for server cert - # verification, I don't know if it would be OK to add it... - echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - return 0 + # these tests use the ext_client directory for tstclnt, + # which doesn't contain the required "TestCA" for server cert + # verification, I don't know if it would be OK to add it... + echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" + return 0 fi if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" - return 0 + return 0 fi SAVE_SERVER_OPTIONS=${SERVER_OPTIONS} @@ -460,8 +457,8 @@ ssl_stapling_sub() echo " -c v -T -O -F -M 1 -V ssl3:tls1.2 < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ - -d ${P_R_CLIENTDIR} $verbose -c v -T -O -F -M 1 -V ssl3:tls1.2 < ${REQUEST_FILE} \ - >${TMP}/$HOST.tmp.$$ 2>&1 + -d ${P_R_CLIENTDIR} $verbose -c v -T -O -F -M 1 -V ssl3:tls1.2 < ${REQUEST_FILE} \ + >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? cat ${TMP}/$HOST.tmp.$$ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null @@ -470,7 +467,7 @@ ssl_stapling_sub() # (see commands in ssl_auth html_msg $ret $value "${testname}" \ - "produced a returncode of $ret, expected is $value" + "produced a returncode of $ret, expected is $value" kill_selfserv SERVER_OPTIONS=${SAVE_SERVER_OPTIONS} @@ -484,15 +481,15 @@ ssl_stapling_stress() value=0 if [ "$NORM_EXT" = "Extended Test" ] ; then - # these tests use the ext_client directory for tstclnt, - # which doesn't contain the required "TestCA" for server cert - # verification, I don't know if it would be OK to add it... - echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - return 0 + # these tests use the ext_client directory for tstclnt, + # which doesn't contain the required "TestCA" for server cert + # verification, I don't know if it would be OK to add it... + echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" + return 0 fi if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" - return 0 + return 0 fi SAVE_SERVER_OPTIONS=${SERVER_OPTIONS} @@ -508,13 +505,13 @@ ssl_stapling_stress() echo " -c 1000 -V ssl3:tls1.2 -N -T $verbose ${HOSTADDR}" echo "strsclnt started at `date`" ${PROFTOOL} ${BINDIR}/strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss \ - -c 1000 -V ssl3:tls1.2 -N -T $verbose ${HOSTADDR} + -c 1000 -V ssl3:tls1.2 -N -T $verbose ${HOSTADDR} ret=$? echo "strsclnt completed at `date`" html_msg $ret $value \ - "${testname}" \ - "produced a returncode of $ret, expected is $value." + "${testname}" \ + "produced a returncode of $ret, expected is $value." kill_selfserv SERVER_OPTIONS=${SAVE_SERVER_OPTIONS} @@ -621,7 +618,7 @@ ssl_stress() sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" ` fi - start_selfserv + start_selfserv `echo "$sparam" | sed -e 's,_, ,g'` if [ "`uname -n`" = "sjsu" ] ; then echo "debugging disapering selfserv... ps -ef | grep selfserv" @@ -675,56 +672,56 @@ ssl_crl_ssl() if [ "$ectype" = "SNI" ]; then continue else - servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` - pwd=`echo $cparam | grep nss` - user=`echo $cparam | grep TestUser` - _cparam=$cparam - case $servarg in - 1) if [ -z "$pwd" -o -z "$user" ]; then + servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` + pwd=`echo $cparam | grep nss` + user=`echo $cparam | grep TestUser` + _cparam=$cparam + case $servarg in + 1) if [ -z "$pwd" -o -z "$user" ]; then rev_modvalue=0 else - rev_modvalue=254 + rev_modvalue=254 fi ;; - 2) rev_modvalue=254 ;; - 3) if [ -z "$pwd" -o -z "$user" ]; then - rev_modvalue=0 - else - rev_modvalue=1 - fi - ;; - 4) rev_modvalue=1 ;; - esac - TEMP_NUM=0 - while [ $TEMP_NUM -lt $CRL_GROUP_RANGE ] - do - CURR_SER_NUM=`expr ${CRL_GROUP_BEGIN} + ${TEMP_NUM}` - TEMP_NUM=`expr $TEMP_NUM + 1` - USER_NICKNAME="TestUser${CURR_SER_NUM}" - cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` - start_selfserv + 2) rev_modvalue=254 ;; + 3) if [ -z "$pwd" -o -z "$user" ]; then + rev_modvalue=0 + else + rev_modvalue=1 + fi + ;; + 4) rev_modvalue=1 ;; + esac + TEMP_NUM=0 + while [ $TEMP_NUM -lt $CRL_GROUP_RANGE ] + do + CURR_SER_NUM=`expr ${CRL_GROUP_BEGIN} + ${TEMP_NUM}` + TEMP_NUM=`expr $TEMP_NUM + 1` + USER_NICKNAME="TestUser${CURR_SER_NUM}" + cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` + start_selfserv `echo "$sparam" | sed -e 's,_, ,g'` - echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" - echo " ${cparam} < ${REQUEST_FILE}" - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ - -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ - >${TMP}/$HOST.tmp.$$ 2>&1 - ret=$? - cat ${TMP}/$HOST.tmp.$$ - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - if [ $CURR_SER_NUM -ne $UNREVOKED_CERT ]; then - modvalue=$rev_modvalue + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} $verbose \\" + echo " ${cparam} < ${REQUEST_FILE}" + rm ${TMP}/$HOST.tmp.$$ 2>/dev/null + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ + -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ + >${TMP}/$HOST.tmp.$$ 2>&1 + ret=$? + cat ${TMP}/$HOST.tmp.$$ + rm ${TMP}/$HOST.tmp.$$ 2>/dev/null + if [ $CURR_SER_NUM -ne $UNREVOKED_CERT ]; then + modvalue=$rev_modvalue testAddMsg="revoked" - else + else testAddMsg="not revoked" - modvalue=$value - fi + modvalue=$value + fi - html_msg $ret $modvalue "${testname} (cert ${USER_NICKNAME} - $testAddMsg)" \ - "produced a returncode of $ret, expected is $modvalue" - kill_selfserv - done + html_msg $ret $modvalue "${testname} (cert ${USER_NICKNAME} - $testAddMsg)" \ + "produced a returncode of $ret, expected is $modvalue" + kill_selfserv + done fi done @@ -767,7 +764,6 @@ ssl_policy() html_head "SSL POLICY $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" - sparam="$CIPHER_SUITES" if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then html_failed "${SCRIPTNAME}: ${P_R_CLIENTDIR} is not initialized" @@ -777,7 +773,7 @@ ssl_policy() echo "Saving pkcs11.txt" cp ${P_R_CLIENTDIR}/pkcs11.txt ${P_R_CLIENTDIR}/pkcs11.txt.sav - start_selfserv # Launch the server + start_selfserv $CIPHER_SUITES ignore_blank_lines ${SSLPOLICY} | \ while read value ectype testmax param policy testname @@ -840,7 +836,6 @@ ssl_policy_listsuites() html_head "SSL POLICY LISTSUITES $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" - sparam="$CIPHER_SUITES" if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then html_failed "${SCRIPTNAME}: ${P_R_CLIENTDIR} is not initialized" @@ -880,7 +875,6 @@ ssl_policy_selfserv() html_head "SSL POLICY SELFSERV $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" testname="" - sparam="$CIPHER_SUITES" if [ ! -f "${P_R_SERVERDIR}/pkcs11.txt" ] ; then html_failed "${SCRIPTNAME}: ${P_R_SERVERDIR} is not initialized" @@ -893,7 +887,7 @@ ssl_policy_selfserv() # Disallow RSA in key exchange explicitly setup_policy "disallow=rsa/ssl-key-exchange" ${P_R_SERVERDIR} - start_selfserv # Launch the server + start_selfserv $CIPHER_SUITES VMIN="ssl3" VMAX="tls1.2" @@ -1021,7 +1015,7 @@ _EOF_REQUEST_ -p ../tests.pw.928 ret=$? if [ "$ret" -eq 0 ]; then - html_passed "${CU_ACTION}" + html_passed "${CU_ACTION}" return 1 fi start_selfserv @@ -1049,8 +1043,7 @@ ssl_crl_cache() echo $? while [ $? -eq 0 -a -f ${SSLAUTH_TMP} ] do - sparam=$SERV_ARG - start_selfserv + start_selfserv `echo $SERV_ARG | sed -e 's,_, ,g'` exec < ${SSLAUTH_TMP} while read ectype value sparam cparam testname do @@ -1078,7 +1071,7 @@ ssl_crl_cache() fi ;; 4) rev_modvalue=1 ;; - esac + esac TEMP_NUM=0 LOADED_GRP=1 while [ ${LOADED_GRP} -le ${TOTAL_GRP_NUM} ] @@ -1095,7 +1088,7 @@ ssl_crl_cache() echo " ${cparam} < ${REQUEST_FILE}" rm ${TMP}/$HOST.tmp.$$ 2>/dev/null ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ - -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ + -d ${R_CLIENTDIR} $verbose < ${REQUEST_FILE} \ >${TMP}/$HOST.tmp.$$ 2>&1 ret=$? cat ${TMP}/$HOST.tmp.$$ @@ -1134,7 +1127,7 @@ ssl_crl_cache() # Restart selfserv to roll back to two initial group 1 crls # TestCA CRL and TestCA-ec CRL kill_selfserv - start_selfserv + start_selfserv `echo "$sparam" | sed -e 's,_, ,g'` fi done kill_selfserv @@ -1171,22 +1164,66 @@ ssl_dtls() -d ${P_R_SERVERDIR} $verbose -U -V tls1.1:tls1.2 -P server -n ${HOSTADDR} -w nss < ${REQUEST_FILE} 2>&1 & PID=$! - + sleep 1 - + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" echo " -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE}" ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ - -d ${P_R_CLIENTDIR} $verbose -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE} 2>&1 + -d ${P_R_CLIENTDIR} $verbose -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE} 2>&1 ret=$? html_msg $ret $value "${testname}" \ "produced a returncode of $ret, expected is $value" kill ${PID} - + html "
" } +############################ ssl_scheme ################################### +# local shell function to test tstclnt and selfserv handling of signature schemes +######################################################################### +ssl_scheme() +{ + if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then + echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" + return 0 + fi + + html_head "SSL SCHEME $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE" + + NO_ECC_CERTS=1 + schemes=("rsa_pkcs1_sha256" "rsa_pss_rsae_sha256" "rsa_pkcs1_sha256,rsa_pss_rsae_sha256") + for sscheme in "${schemes[@]}"; do + for cscheme in "${schemes[@]}"; do + testname="ssl_scheme server='$sscheme' client='$cscheme'" + echo "${testname}" + + start_selfserv -V tls1.2:tls1.2 -J "$sscheme" + + echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\" + echo " -V tls1.2:tls1.2 -J "$cscheme" < ${REQUEST_FILE}" + ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \ + -d ${P_R_CLIENTDIR} $verbose -V tls1.2:tls1.2 -J "$cscheme" < ${REQUEST_FILE} 2>&1 + ret=$? + # If both schemes include just one option and those options don't + # match, then the test should fail; otherwise, assume that it works. + if [ "${cscheme#*,}" = "$cscheme" -a \ + "${sscheme#*,}" = "$sscheme" -a \ + "$cscheme" != "$sscheme" ]; then + expected=254 + else + expected=0 + fi + html_msg $ret $expected "${testname}" \ + "produced a returncode of $ret, expected is $expected" + kill_selfserv + done + done + NO_ECC_CERTS=0 + + html "
" +} ############################## ssl_cleanup ############################# # local shell function to finish this script (no exit since it might be @@ -1228,6 +1265,9 @@ ssl_run() "dtls") ssl_dtls ;; + "scheme") + ssl_scheme + ;; esac done } @@ -1248,9 +1288,9 @@ ssl_run_all() # in FIPS mode, so cope with that. Note there's also semicolon in here # but it doesn't need escaping/quoting; the shell copes. if [ "${CLIENT_MODE}" = "fips" ]; then - USER_NICKNAME="pkcs11:token=NSS%20FIPS%20140-2%20Certificate%20DB;object=TestUser" + USER_NICKNAME="pkcs11:token=NSS%20FIPS%20140-2%20Certificate%20DB;object=TestUser" else - USER_NICKNAME="pkcs11:token=NSS%20Certificate%20DB;object=TestUser" + USER_NICKNAME="pkcs11:token=NSS%20Certificate%20DB;object=TestUser" fi NORM_EXT="" cd ${CLIENTDIR} @@ -1412,4 +1452,3 @@ ssl_run_tests() ssl_init ssl_run_tests ssl_cleanup - diff --git a/security/nss/tests/ssl/sslstress.txt b/security/nss/tests/ssl/sslstress.txt index a87eedad72f4..44794f10f601 100644 --- a/security/nss/tests/ssl/sslstress.txt +++ b/security/nss/tests/ssl/sslstress.txt @@ -12,9 +12,6 @@ noECC 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5 noECC 0 _ -c_1000_-C_c_-g Stress TLS RC4 128 with MD5 (false start) noECC 0 -u -V_ssl3:tls1.2_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket) - noECC 0 -z -V_ssl3:tls1.2_-c_1000_-C_c_-z Stress TLS RC4 128 with MD5 (compression) - noECC 0 -u_-z -V_ssl3:tls1.2_-c_1000_-C_c_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression) - noECC 0 -u_-z -V_ssl3:tls1.2_-c_1000_-C_c_-u_-z_-g Stress TLS RC4 128 with MD5 (session ticket, compression, false start) SNI 0 -u_-a_Host-sni.Dom -V_tls1.0:tls1.2_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI) # @@ -24,10 +21,6 @@ noECC 0 -r_-r -c_100_-C_c_-V_ssl3:ssl3_-N_-n_TestUser Stress SSL3 RC4 128 with MD5 (no reuse, client auth, no login) noECC 0 -r_-r -c_100_-C_c_-N_-n_TestUser Stress TLS RC4 128 with MD5 (no reuse, client auth) noECC 0 -r_-r_-u -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-u Stress TLS RC4 128 with MD5 (session ticket, client auth) - noECC 0 -r_-r_-z -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-z Stress TLS RC4 128 with MD5 (compression, client auth) - noECC 0 -r_-r_-z -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-z_-g Stress TLS RC4 128 with MD5 (compression, client auth, false start) - noECC 0 -r_-r_-u_-z -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression, client auth) - noECC 0 -r_-r_-u_-z -V_ssl3:tls1.2_-c_100_-C_c_-n_TestUser_-u_-z_-g Stress TLS RC4 128 with MD5 (session ticket, compression, client auth, false start) SNI 0 -r_-r_-u_-a_Host-sni.Dom -V_tls1.0:tls1.2_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, default virt host) SNI 0 -r_-r_-u_-a_Host-sni.Dom_-k_Host-sni.Dom -V_tls1.0:tls1.2_-c_1000_-C_c_-u_-a_Host-sni.Dom Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, change virt host) From 5ad84b56e2be739cde93a8aed0ff98b093275477 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 21 Aug 2018 19:52:19 +1000 Subject: [PATCH 48/49] Bug 1484944 - Remove nsSHEnumerator. r=qdot --HG-- extra : rebase_source : 3f52fd7bf780e53631919a0f2e6925345b714517 --- docshell/shistory/nsISHistory.idl | 24 -------------- docshell/shistory/nsSHistory.cpp | 52 ------------------------------- docshell/shistory/nsSHistory.h | 19 ----------- 3 files changed, 95 deletions(-) diff --git a/docshell/shistory/nsISHistory.idl b/docshell/shistory/nsISHistory.idl index 68d8ea0fbf53..068f11ffe8b4 100644 --- a/docshell/shistory/nsISHistory.idl +++ b/docshell/shistory/nsISHistory.idl @@ -7,7 +7,6 @@ interface nsISHEntry; interface nsISHistoryListener; -interface nsISimpleEnumerator; /** * An interface to the primary properties of the Session History @@ -132,29 +131,6 @@ interface nsISHistory: nsISupports */ void removeSHistoryListener(in nsISHistoryListener aListener); - /** - * Called to obtain a enumerator for all the documents stored in - * session history. The enumerator object thus returned by this method - * can be traversed using nsISimpleEnumerator. - * - * @note To access individual history entries of the enumerator, perform the - * following steps: - * 1) Call nsISHistory->GetSHistoryEnumerator() to obtain handle - * the nsISimpleEnumerator object. - * 2) Use nsISimpleEnumerator->GetNext() on the object returned - * by step #1 to obtain handle to the next object in the list. - * The object returned by this step is of type nsISupports. - * 3) Perform a QueryInterface on the object returned by step #2 - * to nsISHEntry. - * 4) Use nsISHEntry to access properties of each history entry. - * - * @see nsISimpleEnumerator - * @see nsISHEntry - * @see QueryInterface() - * @see do_QueryInterface() - */ - readonly attribute nsISimpleEnumerator SHistoryEnumerator; - void reloadCurrentEntry(); /** diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index e7fa886b823e..28f80827f10f 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -2110,55 +2110,3 @@ nsSHistory::SetRootDocShell(nsIDocShell* aDocShell) return NS_OK; } - -NS_IMETHODIMP -nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator) -{ - NS_ENSURE_ARG_POINTER(aEnumerator); - RefPtr iterator = new nsSHEnumerator(this); - iterator.forget(aEnumerator); - return NS_OK; -} - -nsSHEnumerator::nsSHEnumerator(nsSHistory* aSHistory) : mIndex(-1) -{ - mSHistory = aSHistory; -} - -nsSHEnumerator::~nsSHEnumerator() -{ - mSHistory = nullptr; -} - -NS_IMPL_ISUPPORTS(nsSHEnumerator, nsISimpleEnumerator) - -NS_IMETHODIMP -nsSHEnumerator::HasMoreElements(bool* aReturn) -{ - int32_t cnt; - *aReturn = false; - mSHistory->GetCount(&cnt); - if (mIndex >= -1 && mIndex < (cnt - 1)) { - *aReturn = true; - } - return NS_OK; -} - -NS_IMETHODIMP -nsSHEnumerator::GetNext(nsISupports** aItem) -{ - NS_ENSURE_ARG_POINTER(aItem); - int32_t cnt = 0; - - nsresult result = NS_ERROR_FAILURE; - mSHistory->GetCount(&cnt); - if (mIndex < (cnt - 1)) { - mIndex++; - nsCOMPtr hEntry; - result = mSHistory->GetEntryAtIndex(mIndex, false, getter_AddRefs(hEntry)); - if (hEntry) { - result = CallQueryInterface(hEntry, aItem); - } - } - return result; -} diff --git a/docshell/shistory/nsSHistory.h b/docshell/shistory/nsSHistory.h index 7d069c7d4485..52d8bc3e84f2 100644 --- a/docshell/shistory/nsSHistory.h +++ b/docshell/shistory/nsSHistory.h @@ -22,7 +22,6 @@ class nsIDocShell; class nsDocShell; -class nsSHEnumerator; class nsSHistoryObserver; class nsISHEntry; class nsISHTransaction; @@ -133,7 +132,6 @@ public: private: virtual ~nsSHistory(); - friend class nsSHEnumerator; friend class nsSHistoryObserver; nsresult GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult); @@ -192,23 +190,6 @@ private: static int32_t sHistoryMaxTotalViewers; }; -class nsSHEnumerator : public nsISimpleEnumerator -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSISIMPLEENUMERATOR - - explicit nsSHEnumerator(nsSHistory* aHistory); - -protected: - friend class nsSHistory; - virtual ~nsSHEnumerator(); - -private: - int32_t mIndex; - nsSHistory* mSHistory; -}; - inline nsISupports* ToSupports(nsSHistory* aObj) { From 9c245b8d05493748c9583c713fb30bbd26493cd8 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 21 Aug 2018 09:59:00 +0900 Subject: [PATCH 49/49] Bug 1484888 - Apply upstream patch that fixes a clang crash with stack overflow on PGO + LTO on Linux. r=froydnj For some reason, clang 6 crashes with a stack overflow on PGO + LTO on Linux 64 bits. Clang 7 doesn't, but has other problems. After some bisecting, I found the following: - r322684 is the first revision that is broken on the release_60 branch. - that revision is a cherry pick of r322313 from trunk, which is similarly broken. - trunk was fixed by r322325, which, funnily enough, predates when r322313 was cherry-picked. While the change from r322325 is relatively large, mixing multiple different changes in a single commit, there also haven't been significant changes to the same file on trunk since (one macro name change, one documentation change, and a change related to debug info), which would tend to indicate the change is not going to break anything, or at least not more than upgrading to clang 7 would. The exact part that fixes the issue could probably be found in this large commit, but I didn't feel like digging into it further considering the above. --- build/build-clang/clang-6-linux64.json | 1 + build/build-clang/r322325.patch | 1600 ++++++++++++++++++++++++ 2 files changed, 1601 insertions(+) create mode 100644 build/build-clang/r322325.patch diff --git a/build/build-clang/clang-6-linux64.json b/build/build-clang/clang-6-linux64.json index 8bbf8511b8aa..1c26b42f9b98 100644 --- a/build/build-clang/clang-6-linux64.json +++ b/build/build-clang/clang-6-linux64.json @@ -17,6 +17,7 @@ "as": "/builds/worker/workspace/build/src/gcc/bin/gcc", "patches": [ "find_symbolizer_linux.patch", + "r322325.patch", "r322401.patch", "r325356.patch", "r339636.patch" diff --git a/build/build-clang/r322325.patch b/build/build-clang/r322325.patch new file mode 100644 index 000000000000..fe7e20f7eb3a --- /dev/null +++ b/build/build-clang/r322325.patch @@ -0,0 +1,1600 @@ +From e5f83314a1df7ef7843f904da01f2aa236bbe7f0 Mon Sep 17 00:00:00 2001 +From: Matthias Braun +Date: Thu, 11 Jan 2018 22:59:33 +0000 +Subject: [PATCH] PeepholeOpt cleanup/refactor; NFC + +- Less unnecessary use of `auto` +- Add early `using RegSubRegPair(AndIdx) =` to avoid countless + `TargetInstrInfo::` qualifications. +- Use references instead of pointers where possible. +- Remove unused parameters. +- Rewrite the CopyRewriter class hierarchy: + - Pull out uncoalescable copy rewriting functionality into + PeepholeOptimizer class. + - Use an abstract base class to make it clear that rewriters are + independent. +- Remove unnecessary \brief in doxygen comments. +- Remove unused constructor and method from ValueTracker. +- Replace UseAdvancedTracking of ValueTracker with DisableAdvCopyOpt use. + +git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322325 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + lib/CodeGen/PeepholeOptimizer.cpp | 810 ++++++++++++++---------------- + 1 file changed, 370 insertions(+), 440 deletions(-) + +diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp +index 1090550243f..1320f998555 100644 +--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp ++++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp +@@ -98,6 +98,8 @@ + #include + + using namespace llvm; ++using RegSubRegPair = TargetInstrInfo::RegSubRegPair; ++using RegSubRegPairAndIdx = TargetInstrInfo::RegSubRegPairAndIdx; + + #define DEBUG_TYPE "peephole-opt" + +@@ -110,6 +112,9 @@ static cl::opt + DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), + cl::desc("Disable the peephole optimizer")); + ++/// Specifiy whether or not the value tracking looks through ++/// complex instructions. When this is true, the value tracker ++/// bails on everything that is not a copy or a bitcast. + static cl::opt + DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false), + cl::desc("Disable advanced copy optimization")); +@@ -132,11 +137,11 @@ static cl::opt MaxRecurrenceChain( + "of commuting operands")); + + +-STATISTIC(NumReuse, "Number of extension results reused"); +-STATISTIC(NumCmps, "Number of compares eliminated"); +-STATISTIC(NumImmFold, "Number of move immediate folded"); +-STATISTIC(NumLoadFold, "Number of loads folded"); +-STATISTIC(NumSelects, "Number of selects optimized"); ++STATISTIC(NumReuse, "Number of extension results reused"); ++STATISTIC(NumCmps, "Number of compares eliminated"); ++STATISTIC(NumImmFold, "Number of move immediate folded"); ++STATISTIC(NumLoadFold, "Number of loads folded"); ++STATISTIC(NumSelects, "Number of selects optimized"); + STATISTIC(NumUncoalescableCopies, "Number of uncoalescable copies optimized"); + STATISTIC(NumRewrittenCopies, "Number of copies rewritten"); + STATISTIC(NumNAPhysCopies, "Number of non-allocatable physical copies removed"); +@@ -149,9 +154,9 @@ namespace { + class PeepholeOptimizer : public MachineFunctionPass { + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; +- MachineRegisterInfo *MRI; +- MachineDominatorTree *DT; // Machine dominator tree +- MachineLoopInfo *MLI; ++ MachineRegisterInfo *MRI; ++ MachineDominatorTree *DT; // Machine dominator tree ++ MachineLoopInfo *MLI; + + public: + static char ID; // Pass identification +@@ -173,31 +178,28 @@ namespace { + } + } + +- /// \brief Track Def -> Use info used for rewriting copies. +- using RewriteMapTy = +- SmallDenseMap; ++ /// Track Def -> Use info used for rewriting copies. ++ using RewriteMapTy = SmallDenseMap; + +- /// \brief Sequence of instructions that formulate recurrence cycle. ++ /// Sequence of instructions that formulate recurrence cycle. + using RecurrenceCycle = SmallVector; + + private: +- bool optimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB); +- bool optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, ++ bool optimizeCmpInstr(MachineInstr &MI); ++ bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB, + SmallPtrSetImpl &LocalMIs); +- bool optimizeSelect(MachineInstr *MI, ++ bool optimizeSelect(MachineInstr &MI, + SmallPtrSetImpl &LocalMIs); +- bool optimizeCondBranch(MachineInstr *MI); +- bool optimizeCoalescableCopy(MachineInstr *MI); +- bool optimizeUncoalescableCopy(MachineInstr *MI, ++ bool optimizeCondBranch(MachineInstr &MI); ++ bool optimizeCoalescableCopy(MachineInstr &MI); ++ bool optimizeUncoalescableCopy(MachineInstr &MI, + SmallPtrSetImpl &LocalMIs); + bool optimizeRecurrence(MachineInstr &PHI); +- bool findNextSource(unsigned Reg, unsigned SubReg, +- RewriteMapTy &RewriteMap); +- bool isMoveImmediate(MachineInstr *MI, ++ bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap); ++ bool isMoveImmediate(MachineInstr &MI, + SmallSet &ImmDefRegs, + DenseMap &ImmDefMIs); +- bool foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB, +- SmallSet &ImmDefRegs, ++ bool foldImmediate(MachineInstr &MI, SmallSet &ImmDefRegs, + DenseMap &ImmDefMIs); + + /// \brief Finds recurrence cycles, but only ones that formulated around +@@ -212,11 +214,11 @@ namespace { + /// the set \p CopySrcRegs and \p CopyMIs. If this virtual register was + /// previously seen as a copy, replace the uses of this copy with the + /// previously seen copy's destination register. +- bool foldRedundantCopy(MachineInstr *MI, ++ bool foldRedundantCopy(MachineInstr &MI, + SmallSet &CopySrcRegs, + DenseMap &CopyMIs); + +- /// \brief Is the register \p Reg a non-allocatable physical register? ++ /// Is the register \p Reg a non-allocatable physical register? + bool isNAPhysCopy(unsigned Reg); + + /// \brief If copy instruction \p MI is a non-allocatable virtual<->physical +@@ -224,11 +226,10 @@ namespace { + /// non-allocatable physical register was previously copied to a virtual + /// registered and hasn't been clobbered, the virt->phys copy can be + /// deleted. +- bool foldRedundantNAPhysCopy( +- MachineInstr *MI, ++ bool foldRedundantNAPhysCopy(MachineInstr &MI, + DenseMap &NAPhysToVirtMIs); + +- bool isLoadFoldable(MachineInstr *MI, ++ bool isLoadFoldable(MachineInstr &MI, + SmallSet &FoldAsLoadDefCandidates); + + /// \brief Check whether \p MI is understood by the register coalescer +@@ -249,10 +250,13 @@ namespace { + (MI.isRegSequenceLike() || MI.isInsertSubregLike() || + MI.isExtractSubregLike())); + } ++ ++ MachineInstr &rewriteSource(MachineInstr &CopyLike, ++ RegSubRegPair Def, RewriteMapTy &RewriteMap); + }; + +- /// \brief Helper class to hold instructions that are inside recurrence +- /// cycles. The recurrence cycle is formulated around 1) a def operand and its ++ /// Helper class to hold instructions that are inside recurrence cycles. ++ /// The recurrence cycle is formulated around 1) a def operand and its + /// tied use operand, or 2) a def operand and a use operand that is commutable + /// with another use operand which is tied to the def operand. In the latter + /// case, index of the tied use operand and the commutable use operand are +@@ -273,13 +277,13 @@ namespace { + Optional CommutePair; + }; + +- /// \brief Helper class to hold a reply for ValueTracker queries. Contains the +- /// returned sources for a given search and the instructions where the sources +- /// were tracked from. ++ /// Helper class to hold a reply for ValueTracker queries. ++ /// Contains the returned sources for a given search and the instructions ++ /// where the sources were tracked from. + class ValueTrackerResult { + private: + /// Track all sources found by one ValueTracker query. +- SmallVector RegSrcs; ++ SmallVector RegSrcs; + + /// Instruction using the sources in 'RegSrcs'. + const MachineInstr *Inst = nullptr; +@@ -302,16 +306,20 @@ namespace { + } + + void addSource(unsigned SrcReg, unsigned SrcSubReg) { +- RegSrcs.push_back(TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg)); ++ RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg)); + } + + void setSource(int Idx, unsigned SrcReg, unsigned SrcSubReg) { + assert(Idx < getNumSources() && "Reg pair source out of index"); +- RegSrcs[Idx] = TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg); ++ RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg); + } + + int getNumSources() const { return RegSrcs.size(); } + ++ RegSubRegPair getSrc(int Idx) const { ++ return RegSrcs[Idx]; ++ } ++ + unsigned getSrcReg(int Idx) const { + assert(Idx < getNumSources() && "Reg source out of index"); + return RegSrcs[Idx].Reg; +@@ -367,59 +375,41 @@ namespace { + /// The register where the value can be found. + unsigned Reg; + +- /// Specifiy whether or not the value tracking looks through +- /// complex instructions. When this is false, the value tracker +- /// bails on everything that is not a copy or a bitcast. +- /// +- /// Note: This could have been implemented as a specialized version of +- /// the ValueTracker class but that would have complicated the code of +- /// the users of this class. +- bool UseAdvancedTracking; +- + /// MachineRegisterInfo used to perform tracking. + const MachineRegisterInfo &MRI; + +- /// Optional TargetInstrInfo used to perform some complex +- /// tracking. ++ /// Optional TargetInstrInfo used to perform some complex tracking. + const TargetInstrInfo *TII; + +- /// \brief Dispatcher to the right underlying implementation of +- /// getNextSource. ++ /// Dispatcher to the right underlying implementation of getNextSource. + ValueTrackerResult getNextSourceImpl(); + +- /// \brief Specialized version of getNextSource for Copy instructions. ++ /// Specialized version of getNextSource for Copy instructions. + ValueTrackerResult getNextSourceFromCopy(); + +- /// \brief Specialized version of getNextSource for Bitcast instructions. ++ /// Specialized version of getNextSource for Bitcast instructions. + ValueTrackerResult getNextSourceFromBitcast(); + +- /// \brief Specialized version of getNextSource for RegSequence +- /// instructions. ++ /// Specialized version of getNextSource for RegSequence instructions. + ValueTrackerResult getNextSourceFromRegSequence(); + +- /// \brief Specialized version of getNextSource for InsertSubreg +- /// instructions. ++ /// Specialized version of getNextSource for InsertSubreg instructions. + ValueTrackerResult getNextSourceFromInsertSubreg(); + +- /// \brief Specialized version of getNextSource for ExtractSubreg +- /// instructions. ++ /// Specialized version of getNextSource for ExtractSubreg instructions. + ValueTrackerResult getNextSourceFromExtractSubreg(); + +- /// \brief Specialized version of getNextSource for SubregToReg +- /// instructions. ++ /// Specialized version of getNextSource for SubregToReg instructions. + ValueTrackerResult getNextSourceFromSubregToReg(); + +- /// \brief Specialized version of getNextSource for PHI instructions. ++ /// Specialized version of getNextSource for PHI instructions. + ValueTrackerResult getNextSourceFromPHI(); + + public: +- /// \brief Create a ValueTracker instance for the value defined by \p Reg. ++ /// Create a ValueTracker instance for the value defined by \p Reg. + /// \p DefSubReg represents the sub register index the value tracker will + /// track. It does not need to match the sub register index used in the + /// definition of \p Reg. +- /// \p UseAdvancedTracking specifies whether or not the value tracker looks +- /// through complex instructions. By default (false), it handles only copy +- /// and bitcast instructions. + /// If \p Reg is a physical register, a value tracker constructed with + /// this constructor will not find any alternative source. + /// Indeed, when \p Reg is a physical register that constructor does not +@@ -427,46 +417,20 @@ namespace { + /// Use the next constructor to track a physical register. + ValueTracker(unsigned Reg, unsigned DefSubReg, + const MachineRegisterInfo &MRI, +- bool UseAdvancedTracking = false, + const TargetInstrInfo *TII = nullptr) +- : DefSubReg(DefSubReg), Reg(Reg), +- UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) { ++ : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) { + if (!TargetRegisterInfo::isPhysicalRegister(Reg)) { + Def = MRI.getVRegDef(Reg); + DefIdx = MRI.def_begin(Reg).getOperandNo(); + } + } + +- /// \brief Create a ValueTracker instance for the value defined by +- /// the pair \p MI, \p DefIdx. +- /// Unlike the other constructor, the value tracker produced by this one +- /// may be able to find a new source when the definition is a physical +- /// register. +- /// This could be useful to rewrite target specific instructions into +- /// generic copy instructions. +- ValueTracker(const MachineInstr &MI, unsigned DefIdx, unsigned DefSubReg, +- const MachineRegisterInfo &MRI, +- bool UseAdvancedTracking = false, +- const TargetInstrInfo *TII = nullptr) +- : Def(&MI), DefIdx(DefIdx), DefSubReg(DefSubReg), +- UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) { +- assert(DefIdx < Def->getDesc().getNumDefs() && +- Def->getOperand(DefIdx).isReg() && "Invalid definition"); +- Reg = Def->getOperand(DefIdx).getReg(); +- } +- + /// \brief Following the use-def chain, get the next available source + /// for the tracked value. + /// \return A ValueTrackerResult containing a set of registers + /// and sub registers with tracked values. A ValueTrackerResult with + /// an empty set of registers means no source was found. + ValueTrackerResult getNextSource(); +- +- /// \brief Get the last register where the initial value can be found. +- /// Initially this is the register of the definition. +- /// Then, after each successful call to getNextSource, this is the +- /// register of the last source. +- unsigned getReg() const { return Reg; } + }; + + } // end anonymous namespace +@@ -476,11 +440,11 @@ char PeepholeOptimizer::ID = 0; + char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID; + + INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE, +- "Peephole Optimizations", false, false) ++ "Peephole Optimizations", false, false) + INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) + INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) + INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE, +- "Peephole Optimizations", false, false) ++ "Peephole Optimizations", false, false) + + /// If instruction is a copy-like instruction, i.e. it reads a single register + /// and writes a single register and it does not modify the source, and if the +@@ -491,10 +455,10 @@ INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE, + /// the code. Since this code does not currently share EXTRACTs, just ignore all + /// debug uses. + bool PeepholeOptimizer:: +-optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, ++optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB, + SmallPtrSetImpl &LocalMIs) { + unsigned SrcReg, DstReg, SubIdx; +- if (!TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) ++ if (!TII->isCoalescableExtInstr(MI, SrcReg, DstReg, SubIdx)) + return false; + + if (TargetRegisterInfo::isPhysicalRegister(DstReg) || +@@ -535,7 +499,7 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, + bool ExtendLife = true; + for (MachineOperand &UseMO : MRI->use_nodbg_operands(SrcReg)) { + MachineInstr *UseMI = UseMO.getParent(); +- if (UseMI == MI) ++ if (UseMI == &MI) + continue; + + if (UseMI->isPHI()) { +@@ -568,7 +532,7 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, + continue; + + MachineBasicBlock *UseMBB = UseMI->getParent(); +- if (UseMBB == MBB) { ++ if (UseMBB == &MBB) { + // Local uses that come after the extension. + if (!LocalMIs.count(UseMI)) + Uses.push_back(&UseMO); +@@ -576,7 +540,7 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, + // Non-local uses where the result of the extension is used. Always + // replace these unless it's a PHI. + Uses.push_back(&UseMO); +- } else if (Aggressive && DT->dominates(MBB, UseMBB)) { ++ } else if (Aggressive && DT->dominates(&MBB, UseMBB)) { + // We may want to extend the live range of the extension result in order + // to replace these uses. + ExtendedUses.push_back(&UseMO); +@@ -640,19 +604,18 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, + /// against already sets (or could be modified to set) the same flag as the + /// compare, then we can remove the comparison and use the flag from the + /// previous instruction. +-bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI, +- MachineBasicBlock *MBB) { ++bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr &MI) { + // If this instruction is a comparison against zero and isn't comparing a + // physical register, we can try to optimize it. + unsigned SrcReg, SrcReg2; + int CmpMask, CmpValue; +- if (!TII->analyzeCompare(*MI, SrcReg, SrcReg2, CmpMask, CmpValue) || ++ if (!TII->analyzeCompare(MI, SrcReg, SrcReg2, CmpMask, CmpValue) || + TargetRegisterInfo::isPhysicalRegister(SrcReg) || + (SrcReg2 != 0 && TargetRegisterInfo::isPhysicalRegister(SrcReg2))) + return false; + + // Attempt to optimize the comparison instruction. +- if (TII->optimizeCompareInstr(*MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) { ++ if (TII->optimizeCompareInstr(MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) { + ++NumCmps; + return true; + } +@@ -661,27 +624,26 @@ bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI, + } + + /// Optimize a select instruction. +-bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI, ++bool PeepholeOptimizer::optimizeSelect(MachineInstr &MI, + SmallPtrSetImpl &LocalMIs) { + unsigned TrueOp = 0; + unsigned FalseOp = 0; + bool Optimizable = false; + SmallVector Cond; +- if (TII->analyzeSelect(*MI, Cond, TrueOp, FalseOp, Optimizable)) ++ if (TII->analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable)) + return false; + if (!Optimizable) + return false; +- if (!TII->optimizeSelect(*MI, LocalMIs)) ++ if (!TII->optimizeSelect(MI, LocalMIs)) + return false; +- MI->eraseFromParent(); ++ MI.eraseFromParent(); + ++NumSelects; + return true; + } + +-/// \brief Check if a simpler conditional branch can be +-/// generated +-bool PeepholeOptimizer::optimizeCondBranch(MachineInstr *MI) { +- return TII->optimizeCondBranch(*MI); ++/// Check if a simpler conditional branch can be generated. ++bool PeepholeOptimizer::optimizeCondBranch(MachineInstr &MI) { ++ return TII->optimizeCondBranch(MI); + } + + /// \brief Try to find the next source that share the same register file +@@ -695,30 +657,29 @@ bool PeepholeOptimizer::optimizeCondBranch(MachineInstr *MI) { + /// share the same register file as \p Reg and \p SubReg. The client should + /// then be capable to rewrite all intermediate PHIs to get the next source. + /// \return False if no alternative sources are available. True otherwise. +-bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg, ++bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg, + RewriteMapTy &RewriteMap) { + // Do not try to find a new source for a physical register. + // So far we do not have any motivating example for doing that. + // Thus, instead of maintaining untested code, we will revisit that if + // that changes at some point. ++ unsigned Reg = RegSubReg.Reg; + if (TargetRegisterInfo::isPhysicalRegister(Reg)) + return false; + const TargetRegisterClass *DefRC = MRI->getRegClass(Reg); + +- SmallVector SrcToLook; +- TargetInstrInfo::RegSubRegPair CurSrcPair(Reg, SubReg); ++ SmallVector SrcToLook; ++ RegSubRegPair CurSrcPair = RegSubReg; + SrcToLook.push_back(CurSrcPair); + + unsigned PHICount = 0; +- while (!SrcToLook.empty() && PHICount < RewritePHILimit) { +- TargetInstrInfo::RegSubRegPair Pair = SrcToLook.pop_back_val(); ++ do { ++ CurSrcPair = SrcToLook.pop_back_val(); + // As explained above, do not handle physical registers +- if (TargetRegisterInfo::isPhysicalRegister(Pair.Reg)) ++ if (TargetRegisterInfo::isPhysicalRegister(CurSrcPair.Reg)) + return false; + +- CurSrcPair = Pair; +- ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI, +- !DisableAdvCopyOpt, TII); ++ ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI, TII); + + // Follow the chain of copies until we find a more suitable source, a phi + // or have to abort. +@@ -747,14 +708,17 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg, + unsigned NumSrcs = Res.getNumSources(); + if (NumSrcs > 1) { + PHICount++; ++ if (PHICount >= RewritePHILimit) { ++ DEBUG(dbgs() << "findNextSource: PHI limit reached\n"); ++ return false; ++ } ++ + for (unsigned i = 0; i < NumSrcs; ++i) +- SrcToLook.push_back(TargetInstrInfo::RegSubRegPair( +- Res.getSrcReg(i), Res.getSrcSubReg(i))); ++ SrcToLook.push_back(Res.getSrc(i)); + break; + } + +- CurSrcPair.Reg = Res.getSrcReg(0); +- CurSrcPair.SubReg = Res.getSrcSubReg(0); ++ CurSrcPair = Res.getSrc(0); + // Do not extend the live-ranges of physical registers as they add + // constraints to the register allocator. Moreover, if we want to extend + // the live-range of a physical register, unlike SSA virtual register, +@@ -764,7 +728,8 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg, + + // Keep following the chain if the value isn't any better yet. + const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg); +- if (!TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC, CurSrcPair.SubReg)) ++ if (!TRI->shouldRewriteCopySrc(DefRC, RegSubReg.SubReg, SrcRC, ++ CurSrcPair.SubReg)) + continue; + + // We currently cannot deal with subreg operands on PHI instructions +@@ -775,7 +740,7 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg, + // We found a suitable source, and are done with this chain. + break; + } +- } ++ } while (!SrcToLook.empty()); + + // If we did not find a more suitable source, there is nothing to optimize. + return CurSrcPair.Reg != Reg; +@@ -786,54 +751,50 @@ bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg, + /// successfully traverse a PHI instruction and find suitable sources coming + /// from its edges. By inserting a new PHI, we provide a rewritten PHI def + /// suitable to be used in a new COPY instruction. +-static MachineInstr * +-insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, +- const SmallVectorImpl &SrcRegs, +- MachineInstr *OrigPHI) { ++static MachineInstr & ++insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII, ++ const SmallVectorImpl &SrcRegs, ++ MachineInstr &OrigPHI) { + assert(!SrcRegs.empty() && "No sources to create a PHI instruction?"); + +- const TargetRegisterClass *NewRC = MRI->getRegClass(SrcRegs[0].Reg); ++ const TargetRegisterClass *NewRC = MRI.getRegClass(SrcRegs[0].Reg); + // NewRC is only correct if no subregisters are involved. findNextSource() + // should have rejected those cases already. + assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand"); +- unsigned NewVR = MRI->createVirtualRegister(NewRC); +- MachineBasicBlock *MBB = OrigPHI->getParent(); +- MachineInstrBuilder MIB = BuildMI(*MBB, OrigPHI, OrigPHI->getDebugLoc(), +- TII->get(TargetOpcode::PHI), NewVR); ++ unsigned NewVR = MRI.createVirtualRegister(NewRC); ++ MachineBasicBlock *MBB = OrigPHI.getParent(); ++ MachineInstrBuilder MIB = BuildMI(*MBB, &OrigPHI, OrigPHI.getDebugLoc(), ++ TII.get(TargetOpcode::PHI), NewVR); + + unsigned MBBOpIdx = 2; +- for (auto RegPair : SrcRegs) { ++ for (const RegSubRegPair &RegPair : SrcRegs) { + MIB.addReg(RegPair.Reg, 0, RegPair.SubReg); +- MIB.addMBB(OrigPHI->getOperand(MBBOpIdx).getMBB()); ++ MIB.addMBB(OrigPHI.getOperand(MBBOpIdx).getMBB()); + // Since we're extended the lifetime of RegPair.Reg, clear the + // kill flags to account for that and make RegPair.Reg reaches + // the new PHI. +- MRI->clearKillFlags(RegPair.Reg); ++ MRI.clearKillFlags(RegPair.Reg); + MBBOpIdx += 2; + } + +- return MIB; ++ return *MIB; + } + + namespace { + +-/// \brief Helper class to rewrite the arguments of a copy-like instruction. +-class CopyRewriter { ++/// Interface to query instructions amenable to copy rewriting. ++class Rewriter { + protected: +- /// The copy-like instruction. + MachineInstr &CopyLike; +- +- /// The index of the source being rewritten. +- unsigned CurrentSrcIdx = 0; +- ++ unsigned CurrentSrcIdx = 0; ///< The index of the source being rewritten. + public: +- CopyRewriter(MachineInstr &MI) : CopyLike(MI) {} +- virtual ~CopyRewriter() = default; ++ Rewriter(MachineInstr &CopyLike) : CopyLike(CopyLike) {} ++ virtual ~Rewriter() {} + + /// \brief Get the next rewritable source (SrcReg, SrcSubReg) and +- /// the related value that it affects (TrackReg, TrackSubReg). ++ /// the related value that it affects (DstReg, DstSubReg). + /// A source is considered rewritable if its register class and the +- /// register class of the related TrackReg may not be register ++ /// register class of the related DstReg may not be register + /// coalescer friendly. In other words, given a copy-like instruction + /// not all the arguments may be returned at rewritable source, since + /// some arguments are none to be register coalescer friendly. +@@ -848,137 +809,72 @@ public: + /// the only source this instruction has: + /// (SrcReg, SrcSubReg) = (src, srcSubIdx). + /// This source defines the whole definition, i.e., +- /// (TrackReg, TrackSubReg) = (dst, dstSubIdx). ++ /// (DstReg, DstSubReg) = (dst, dstSubIdx). + /// + /// The second and subsequent calls will return false, as there is only one + /// rewritable source. + /// + /// \return True if a rewritable source has been found, false otherwise. + /// The output arguments are valid if and only if true is returned. +- virtual bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg, +- unsigned &TrackReg, +- unsigned &TrackSubReg) { +- // If CurrentSrcIdx == 1, this means this function has already been called +- // once. CopyLike has one definition and one argument, thus, there is +- // nothing else to rewrite. +- if (!CopyLike.isCopy() || CurrentSrcIdx == 1) ++ virtual bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) = 0; ++ ++ /// Rewrite the current source with \p NewReg and \p NewSubReg if possible. ++ /// \return True if the rewriting was possible, false otherwise. ++ virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) = 0; ++}; ++ ++/// Rewriter for COPY instructions. ++class CopyRewriter : public Rewriter { ++public: ++ CopyRewriter(MachineInstr &MI) : Rewriter(MI) { ++ assert(MI.isCopy() && "Expected copy instruction"); ++ } ++ virtual ~CopyRewriter() = default; ++ ++ bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) override { ++ // CurrentSrcIdx > 0 means this function has already been called. ++ if (CurrentSrcIdx > 0) + return false; + // This is the first call to getNextRewritableSource. + // Move the CurrentSrcIdx to remember that we made that call. + CurrentSrcIdx = 1; + // The rewritable source is the argument. + const MachineOperand &MOSrc = CopyLike.getOperand(1); +- SrcReg = MOSrc.getReg(); +- SrcSubReg = MOSrc.getSubReg(); ++ Src = RegSubRegPair(MOSrc.getReg(), MOSrc.getSubReg()); + // What we track are the alternative sources of the definition. + const MachineOperand &MODef = CopyLike.getOperand(0); +- TrackReg = MODef.getReg(); +- TrackSubReg = MODef.getSubReg(); ++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg()); + return true; + } + +- /// \brief Rewrite the current source with \p NewReg and \p NewSubReg +- /// if possible. +- /// \return True if the rewriting was possible, false otherwise. +- virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) { +- if (!CopyLike.isCopy() || CurrentSrcIdx != 1) ++ bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override { ++ if (CurrentSrcIdx != 1) + return false; + MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx); + MOSrc.setReg(NewReg); + MOSrc.setSubReg(NewSubReg); + return true; + } +- +- /// \brief Given a \p Def.Reg and Def.SubReg pair, use \p RewriteMap to find +- /// the new source to use for rewrite. If \p HandleMultipleSources is true and +- /// multiple sources for a given \p Def are found along the way, we found a +- /// PHI instructions that needs to be rewritten. +- /// TODO: HandleMultipleSources should be removed once we test PHI handling +- /// with coalescable copies. +- TargetInstrInfo::RegSubRegPair +- getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, +- TargetInstrInfo::RegSubRegPair Def, +- PeepholeOptimizer::RewriteMapTy &RewriteMap, +- bool HandleMultipleSources = true) { +- TargetInstrInfo::RegSubRegPair LookupSrc(Def.Reg, Def.SubReg); +- do { +- ValueTrackerResult Res = RewriteMap.lookup(LookupSrc); +- // If there are no entries on the map, LookupSrc is the new source. +- if (!Res.isValid()) +- return LookupSrc; +- +- // There's only one source for this definition, keep searching... +- unsigned NumSrcs = Res.getNumSources(); +- if (NumSrcs == 1) { +- LookupSrc.Reg = Res.getSrcReg(0); +- LookupSrc.SubReg = Res.getSrcSubReg(0); +- continue; +- } +- +- // TODO: Remove once multiple srcs w/ coalescable copies are supported. +- if (!HandleMultipleSources) +- break; +- +- // Multiple sources, recurse into each source to find a new source +- // for it. Then, rewrite the PHI accordingly to its new edges. +- SmallVector NewPHISrcs; +- for (unsigned i = 0; i < NumSrcs; ++i) { +- TargetInstrInfo::RegSubRegPair PHISrc(Res.getSrcReg(i), +- Res.getSrcSubReg(i)); +- NewPHISrcs.push_back( +- getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources)); +- } +- +- // Build the new PHI node and return its def register as the new source. +- MachineInstr *OrigPHI = const_cast(Res.getInst()); +- MachineInstr *NewPHI = insertPHI(MRI, TII, NewPHISrcs, OrigPHI); +- DEBUG(dbgs() << "-- getNewSource\n"); +- DEBUG(dbgs() << " Replacing: " << *OrigPHI); +- DEBUG(dbgs() << " With: " << *NewPHI); +- const MachineOperand &MODef = NewPHI->getOperand(0); +- return TargetInstrInfo::RegSubRegPair(MODef.getReg(), MODef.getSubReg()); +- +- } while (true); +- +- return TargetInstrInfo::RegSubRegPair(0, 0); +- } +- +- /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap +- /// and create a new COPY instruction. More info about RewriteMap in +- /// PeepholeOptimizer::findNextSource. Right now this is only used to handle +- /// Uncoalescable copies, since they are copy like instructions that aren't +- /// recognized by the register allocator. +- virtual MachineInstr * +- RewriteSource(TargetInstrInfo::RegSubRegPair Def, +- PeepholeOptimizer::RewriteMapTy &RewriteMap) { +- return nullptr; +- } + }; + + /// \brief Helper class to rewrite uncoalescable copy like instructions + /// into new COPY (coalescable friendly) instructions. +-class UncoalescableRewriter : public CopyRewriter { +-protected: +- const TargetInstrInfo &TII; +- MachineRegisterInfo &MRI; +- +- /// The number of defs in the bitcast +- unsigned NumDefs; ++class UncoalescableRewriter : public Rewriter { ++ unsigned NumDefs; ///< Number of defs in the bitcast. + + public: +- UncoalescableRewriter(MachineInstr &MI, const TargetInstrInfo &TII, +- MachineRegisterInfo &MRI) +- : CopyRewriter(MI), TII(TII), MRI(MRI) { ++ UncoalescableRewriter(MachineInstr &MI) : Rewriter(MI) { + NumDefs = MI.getDesc().getNumDefs(); + } + +- /// \brief Get the next rewritable def source (TrackReg, TrackSubReg) ++ /// \see See Rewriter::getNextRewritableSource() + /// All such sources need to be considered rewritable in order to + /// rewrite a uncoalescable copy-like instruction. This method return + /// each definition that must be checked if rewritable. +- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg, +- unsigned &TrackReg, +- unsigned &TrackSubReg) override { ++ bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) override { + // Find the next non-dead definition and continue from there. + if (CurrentSrcIdx == NumDefs) + return false; +@@ -990,64 +886,27 @@ public: + } + + // What we track are the alternative sources of the definition. ++ Src = RegSubRegPair(0, 0); + const MachineOperand &MODef = CopyLike.getOperand(CurrentSrcIdx); +- TrackReg = MODef.getReg(); +- TrackSubReg = MODef.getSubReg(); ++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg()); + + CurrentSrcIdx++; + return true; + } + +- /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap +- /// and create a new COPY instruction. More info about RewriteMap in +- /// PeepholeOptimizer::findNextSource. Right now this is only used to handle +- /// Uncoalescable copies, since they are copy like instructions that aren't +- /// recognized by the register allocator. +- MachineInstr * +- RewriteSource(TargetInstrInfo::RegSubRegPair Def, +- PeepholeOptimizer::RewriteMapTy &RewriteMap) override { +- assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) && +- "We do not rewrite physical registers"); +- +- // Find the new source to use in the COPY rewrite. +- TargetInstrInfo::RegSubRegPair NewSrc = +- getNewSource(&MRI, &TII, Def, RewriteMap); +- +- // Insert the COPY. +- const TargetRegisterClass *DefRC = MRI.getRegClass(Def.Reg); +- unsigned NewVR = MRI.createVirtualRegister(DefRC); +- +- MachineInstr *NewCopy = +- BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(), +- TII.get(TargetOpcode::COPY), NewVR) +- .addReg(NewSrc.Reg, 0, NewSrc.SubReg); +- +- NewCopy->getOperand(0).setSubReg(Def.SubReg); +- if (Def.SubReg) +- NewCopy->getOperand(0).setIsUndef(); +- +- DEBUG(dbgs() << "-- RewriteSource\n"); +- DEBUG(dbgs() << " Replacing: " << CopyLike); +- DEBUG(dbgs() << " With: " << *NewCopy); +- MRI.replaceRegWith(Def.Reg, NewVR); +- MRI.clearKillFlags(NewVR); +- +- // We extended the lifetime of NewSrc.Reg, clear the kill flags to +- // account for that. +- MRI.clearKillFlags(NewSrc.Reg); +- +- return NewCopy; ++ bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override { ++ return false; + } + }; + +-/// \brief Specialized rewriter for INSERT_SUBREG instruction. +-class InsertSubregRewriter : public CopyRewriter { ++/// Specialized rewriter for INSERT_SUBREG instruction. ++class InsertSubregRewriter : public Rewriter { + public: +- InsertSubregRewriter(MachineInstr &MI) : CopyRewriter(MI) { ++ InsertSubregRewriter(MachineInstr &MI) : Rewriter(MI) { + assert(MI.isInsertSubreg() && "Invalid instruction"); + } + +- /// \brief See CopyRewriter::getNextRewritableSource. ++ /// \see See Rewriter::getNextRewritableSource() + /// Here CopyLike has the following form: + /// dst = INSERT_SUBREG Src1, Src2.src2SubIdx, subIdx. + /// Src1 has the same register class has dst, hence, there is +@@ -1055,29 +914,27 @@ public: + /// Src2.src2SubIdx, may not be register coalescer friendly. + /// Therefore, the first call to this method returns: + /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx). +- /// (TrackReg, TrackSubReg) = (dst, subIdx). ++ /// (DstReg, DstSubReg) = (dst, subIdx). + /// + /// Subsequence calls will return false. +- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg, +- unsigned &TrackReg, +- unsigned &TrackSubReg) override { ++ bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) override { + // If we already get the only source we can rewrite, return false. + if (CurrentSrcIdx == 2) + return false; + // We are looking at v2 = INSERT_SUBREG v0, v1, sub0. + CurrentSrcIdx = 2; + const MachineOperand &MOInsertedReg = CopyLike.getOperand(2); +- SrcReg = MOInsertedReg.getReg(); +- SrcSubReg = MOInsertedReg.getSubReg(); ++ Src = RegSubRegPair(MOInsertedReg.getReg(), MOInsertedReg.getSubReg()); + const MachineOperand &MODef = CopyLike.getOperand(0); + + // We want to track something that is compatible with the + // partial definition. +- TrackReg = MODef.getReg(); + if (MODef.getSubReg()) + // Bail if we have to compose sub-register indices. + return false; +- TrackSubReg = (unsigned)CopyLike.getOperand(3).getImm(); ++ Dst = RegSubRegPair(MODef.getReg(), ++ (unsigned)CopyLike.getOperand(3).getImm()); + return true; + } + +@@ -1092,41 +949,39 @@ public: + } + }; + +-/// \brief Specialized rewriter for EXTRACT_SUBREG instruction. +-class ExtractSubregRewriter : public CopyRewriter { ++/// Specialized rewriter for EXTRACT_SUBREG instruction. ++class ExtractSubregRewriter : public Rewriter { + const TargetInstrInfo &TII; + + public: + ExtractSubregRewriter(MachineInstr &MI, const TargetInstrInfo &TII) +- : CopyRewriter(MI), TII(TII) { ++ : Rewriter(MI), TII(TII) { + assert(MI.isExtractSubreg() && "Invalid instruction"); + } + +- /// \brief See CopyRewriter::getNextRewritableSource. ++ /// \see Rewriter::getNextRewritableSource() + /// Here CopyLike has the following form: + /// dst.dstSubIdx = EXTRACT_SUBREG Src, subIdx. + /// There is only one rewritable source: Src.subIdx, + /// which defines dst.dstSubIdx. +- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg, +- unsigned &TrackReg, +- unsigned &TrackSubReg) override { ++ bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) override { + // If we already get the only source we can rewrite, return false. + if (CurrentSrcIdx == 1) + return false; + // We are looking at v1 = EXTRACT_SUBREG v0, sub0. + CurrentSrcIdx = 1; + const MachineOperand &MOExtractedReg = CopyLike.getOperand(1); +- SrcReg = MOExtractedReg.getReg(); + // If we have to compose sub-register indices, bail out. + if (MOExtractedReg.getSubReg()) + return false; + +- SrcSubReg = CopyLike.getOperand(2).getImm(); ++ Src = RegSubRegPair(MOExtractedReg.getReg(), ++ CopyLike.getOperand(2).getImm()); + + // We want to track something that is compatible with the definition. + const MachineOperand &MODef = CopyLike.getOperand(0); +- TrackReg = MODef.getReg(); +- TrackSubReg = MODef.getSubReg(); ++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg()); + return true; + } + +@@ -1156,14 +1011,14 @@ public: + } + }; + +-/// \brief Specialized rewriter for REG_SEQUENCE instruction. +-class RegSequenceRewriter : public CopyRewriter { ++/// Specialized rewriter for REG_SEQUENCE instruction. ++class RegSequenceRewriter : public Rewriter { + public: +- RegSequenceRewriter(MachineInstr &MI) : CopyRewriter(MI) { ++ RegSequenceRewriter(MachineInstr &MI) : Rewriter(MI) { + assert(MI.isRegSequence() && "Invalid instruction"); + } + +- /// \brief See CopyRewriter::getNextRewritableSource. ++ /// \see Rewriter::getNextRewritableSource() + /// Here CopyLike has the following form: + /// dst = REG_SEQUENCE Src1.src1SubIdx, subIdx1, Src2.src2SubIdx, subIdx2. + /// Each call will return a different source, walking all the available +@@ -1171,17 +1026,16 @@ public: + /// + /// The first call returns: + /// (SrcReg, SrcSubReg) = (Src1, src1SubIdx). +- /// (TrackReg, TrackSubReg) = (dst, subIdx1). ++ /// (DstReg, DstSubReg) = (dst, subIdx1). + /// + /// The second call returns: + /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx). +- /// (TrackReg, TrackSubReg) = (dst, subIdx2). ++ /// (DstReg, DstSubReg) = (dst, subIdx2). + /// + /// And so on, until all the sources have been traversed, then + /// it returns false. +- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg, +- unsigned &TrackReg, +- unsigned &TrackSubReg) override { ++ bool getNextRewritableSource(RegSubRegPair &Src, ++ RegSubRegPair &Dst) override { + // We are looking at v0 = REG_SEQUENCE v1, sub1, v2, sub2, etc. + + // If this is the first call, move to the first argument. +@@ -1194,17 +1048,17 @@ public: + return false; + } + const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx); +- SrcReg = MOInsertedReg.getReg(); ++ Src.Reg = MOInsertedReg.getReg(); + // If we have to compose sub-register indices, bail out. +- if ((SrcSubReg = MOInsertedReg.getSubReg())) ++ if ((Src.SubReg = MOInsertedReg.getSubReg())) + return false; + + // We want to track something that is compatible with the related + // partial definition. +- TrackSubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm(); ++ Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm(); + + const MachineOperand &MODef = CopyLike.getOperand(0); +- TrackReg = MODef.getReg(); ++ Dst.Reg = MODef.getReg(); + // If we have to compose sub-registers, bail. + return MODef.getSubReg() == 0; + } +@@ -1224,16 +1078,14 @@ public: + + } // end anonymous namespace + +-/// \brief Get the appropriated CopyRewriter for \p MI. +-/// \return A pointer to a dynamically allocated CopyRewriter or nullptr +-/// if no rewriter works for \p MI. +-static CopyRewriter *getCopyRewriter(MachineInstr &MI, +- const TargetInstrInfo &TII, +- MachineRegisterInfo &MRI) { ++/// Get the appropriated Rewriter for \p MI. ++/// \return A pointer to a dynamically allocated Rewriter or nullptr if no ++/// rewriter works for \p MI. ++static Rewriter *getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII) { + // Handle uncoalescable copy-like instructions. +- if (MI.isBitcast() || (MI.isRegSequenceLike() || MI.isInsertSubregLike() || +- MI.isExtractSubregLike())) +- return new UncoalescableRewriter(MI, TII, MRI); ++ if (MI.isBitcast() || MI.isRegSequenceLike() || MI.isInsertSubregLike() || ++ MI.isExtractSubregLike()) ++ return new UncoalescableRewriter(MI); + + switch (MI.getOpcode()) { + default: +@@ -1247,53 +1099,102 @@ static CopyRewriter *getCopyRewriter(MachineInstr &MI, + case TargetOpcode::REG_SEQUENCE: + return new RegSequenceRewriter(MI); + } +- llvm_unreachable(nullptr); + } + +-/// \brief Optimize generic copy instructions to avoid cross +-/// register bank copy. The optimization looks through a chain of +-/// copies and tries to find a source that has a compatible register +-/// class. +-/// Two register classes are considered to be compatible if they share +-/// the same register bank. ++/// \brief Given a \p Def.Reg and Def.SubReg pair, use \p RewriteMap to find ++/// the new source to use for rewrite. If \p HandleMultipleSources is true and ++/// multiple sources for a given \p Def are found along the way, we found a ++/// PHI instructions that needs to be rewritten. ++/// TODO: HandleMultipleSources should be removed once we test PHI handling ++/// with coalescable copies. ++static RegSubRegPair ++getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, ++ RegSubRegPair Def, ++ const PeepholeOptimizer::RewriteMapTy &RewriteMap, ++ bool HandleMultipleSources = true) { ++ RegSubRegPair LookupSrc(Def.Reg, Def.SubReg); ++ while (true) { ++ ValueTrackerResult Res = RewriteMap.lookup(LookupSrc); ++ // If there are no entries on the map, LookupSrc is the new source. ++ if (!Res.isValid()) ++ return LookupSrc; ++ ++ // There's only one source for this definition, keep searching... ++ unsigned NumSrcs = Res.getNumSources(); ++ if (NumSrcs == 1) { ++ LookupSrc.Reg = Res.getSrcReg(0); ++ LookupSrc.SubReg = Res.getSrcSubReg(0); ++ continue; ++ } ++ ++ // TODO: Remove once multiple srcs w/ coalescable copies are supported. ++ if (!HandleMultipleSources) ++ break; ++ ++ // Multiple sources, recurse into each source to find a new source ++ // for it. Then, rewrite the PHI accordingly to its new edges. ++ SmallVector NewPHISrcs; ++ for (unsigned i = 0; i < NumSrcs; ++i) { ++ RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i)); ++ NewPHISrcs.push_back( ++ getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources)); ++ } ++ ++ // Build the new PHI node and return its def register as the new source. ++ MachineInstr &OrigPHI = const_cast(*Res.getInst()); ++ MachineInstr &NewPHI = insertPHI(*MRI, *TII, NewPHISrcs, OrigPHI); ++ DEBUG(dbgs() << "-- getNewSource\n"); ++ DEBUG(dbgs() << " Replacing: " << OrigPHI); ++ DEBUG(dbgs() << " With: " << NewPHI); ++ const MachineOperand &MODef = NewPHI.getOperand(0); ++ return RegSubRegPair(MODef.getReg(), MODef.getSubReg()); ++ } ++ ++ return RegSubRegPair(0, 0); ++} ++ ++/// Optimize generic copy instructions to avoid cross register bank copy. ++/// The optimization looks through a chain of copies and tries to find a source ++/// that has a compatible register class. ++/// Two register classes are considered to be compatible if they share the same ++/// register bank. + /// New copies issued by this optimization are register allocator + /// friendly. This optimization does not remove any copy as it may + /// overconstrain the register allocator, but replaces some operands + /// when possible. + /// \pre isCoalescableCopy(*MI) is true. + /// \return True, when \p MI has been rewritten. False otherwise. +-bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) { +- assert(MI && isCoalescableCopy(*MI) && "Invalid argument"); +- assert(MI->getDesc().getNumDefs() == 1 && ++bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &MI) { ++ assert(isCoalescableCopy(MI) && "Invalid argument"); ++ assert(MI.getDesc().getNumDefs() == 1 && + "Coalescer can understand multiple defs?!"); +- const MachineOperand &MODef = MI->getOperand(0); ++ const MachineOperand &MODef = MI.getOperand(0); + // Do not rewrite physical definitions. + if (TargetRegisterInfo::isPhysicalRegister(MODef.getReg())) + return false; + + bool Changed = false; + // Get the right rewriter for the current copy. +- std::unique_ptr CpyRewriter(getCopyRewriter(*MI, *TII, *MRI)); ++ std::unique_ptr CpyRewriter(getCopyRewriter(MI, *TII)); + // If none exists, bail out. + if (!CpyRewriter) + return false; + // Rewrite each rewritable source. +- unsigned SrcReg, SrcSubReg, TrackReg, TrackSubReg; +- while (CpyRewriter->getNextRewritableSource(SrcReg, SrcSubReg, TrackReg, +- TrackSubReg)) { ++ RegSubRegPair Src; ++ RegSubRegPair TrackPair; ++ while (CpyRewriter->getNextRewritableSource(Src, TrackPair)) { + // Keep track of PHI nodes and its incoming edges when looking for sources. + RewriteMapTy RewriteMap; + // Try to find a more suitable source. If we failed to do so, or get the + // actual source, move to the next source. +- if (!findNextSource(TrackReg, TrackSubReg, RewriteMap)) ++ if (!findNextSource(TrackPair, RewriteMap)) + continue; + + // Get the new source to rewrite. TODO: Only enable handling of multiple + // sources (PHIs) once we have a motivating example and testcases for it. +- TargetInstrInfo::RegSubRegPair TrackPair(TrackReg, TrackSubReg); +- TargetInstrInfo::RegSubRegPair NewSrc = CpyRewriter->getNewSource( +- MRI, TII, TrackPair, RewriteMap, false /* multiple sources */); +- if (SrcReg == NewSrc.Reg || NewSrc.Reg == 0) ++ RegSubRegPair NewSrc = getNewSource(MRI, TII, TrackPair, RewriteMap, ++ /*HandleMultipleSources=*/false); ++ if (Src.Reg == NewSrc.Reg || NewSrc.Reg == 0) + continue; + + // Rewrite source. +@@ -1312,6 +1213,47 @@ bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) { + return Changed; + } + ++/// \brief Rewrite the source found through \p Def, by using the \p RewriteMap ++/// and create a new COPY instruction. More info about RewriteMap in ++/// PeepholeOptimizer::findNextSource. Right now this is only used to handle ++/// Uncoalescable copies, since they are copy like instructions that aren't ++/// recognized by the register allocator. ++MachineInstr & ++PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike, ++ RegSubRegPair Def, RewriteMapTy &RewriteMap) { ++ assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) && ++ "We do not rewrite physical registers"); ++ ++ // Find the new source to use in the COPY rewrite. ++ RegSubRegPair NewSrc = getNewSource(MRI, TII, Def, RewriteMap); ++ ++ // Insert the COPY. ++ const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg); ++ unsigned NewVReg = MRI->createVirtualRegister(DefRC); ++ ++ MachineInstr *NewCopy = ++ BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(), ++ TII->get(TargetOpcode::COPY), NewVReg) ++ .addReg(NewSrc.Reg, 0, NewSrc.SubReg); ++ ++ if (Def.SubReg) { ++ NewCopy->getOperand(0).setSubReg(Def.SubReg); ++ NewCopy->getOperand(0).setIsUndef(); ++ } ++ ++ DEBUG(dbgs() << "-- RewriteSource\n"); ++ DEBUG(dbgs() << " Replacing: " << CopyLike); ++ DEBUG(dbgs() << " With: " << *NewCopy); ++ MRI->replaceRegWith(Def.Reg, NewVReg); ++ MRI->clearKillFlags(NewVReg); ++ ++ // We extended the lifetime of NewSrc.Reg, clear the kill flags to ++ // account for that. ++ MRI->clearKillFlags(NewSrc.Reg); ++ ++ return *NewCopy; ++} ++ + /// \brief Optimize copy-like instructions to create + /// register coalescer friendly instruction. + /// The optimization tries to kill-off the \p MI by looking +@@ -1324,48 +1266,40 @@ bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) { + /// been removed from its parent. + /// All COPY instructions created, are inserted in \p LocalMIs. + bool PeepholeOptimizer::optimizeUncoalescableCopy( +- MachineInstr *MI, SmallPtrSetImpl &LocalMIs) { +- assert(MI && isUncoalescableCopy(*MI) && "Invalid argument"); +- +- // Check if we can rewrite all the values defined by this instruction. +- SmallVector RewritePairs; +- // Get the right rewriter for the current copy. +- std::unique_ptr CpyRewriter(getCopyRewriter(*MI, *TII, *MRI)); +- // If none exists, bail out. +- if (!CpyRewriter) +- return false; ++ MachineInstr &MI, SmallPtrSetImpl &LocalMIs) { ++ assert(isUncoalescableCopy(MI) && "Invalid argument"); ++ UncoalescableRewriter CpyRewriter(MI); + + // Rewrite each rewritable source by generating new COPYs. This works + // differently from optimizeCoalescableCopy since it first makes sure that all + // definitions can be rewritten. + RewriteMapTy RewriteMap; +- unsigned Reg, SubReg, CopyDefReg, CopyDefSubReg; +- while (CpyRewriter->getNextRewritableSource(Reg, SubReg, CopyDefReg, +- CopyDefSubReg)) { ++ RegSubRegPair Src; ++ RegSubRegPair Def; ++ SmallVector RewritePairs; ++ while (CpyRewriter.getNextRewritableSource(Src, Def)) { + // If a physical register is here, this is probably for a good reason. + // Do not rewrite that. +- if (TargetRegisterInfo::isPhysicalRegister(CopyDefReg)) ++ if (TargetRegisterInfo::isPhysicalRegister(Def.Reg)) + return false; + + // If we do not know how to rewrite this definition, there is no point + // in trying to kill this instruction. +- TargetInstrInfo::RegSubRegPair Def(CopyDefReg, CopyDefSubReg); +- if (!findNextSource(Def.Reg, Def.SubReg, RewriteMap)) ++ if (!findNextSource(Def, RewriteMap)) + return false; + + RewritePairs.push_back(Def); + } + + // The change is possible for all defs, do it. +- for (const auto &Def : RewritePairs) { ++ for (const RegSubRegPair &Def : RewritePairs) { + // Rewrite the "copy" in a way the register coalescer understands. +- MachineInstr *NewCopy = CpyRewriter->RewriteSource(Def, RewriteMap); +- assert(NewCopy && "Should be able to always generate a new copy"); +- LocalMIs.insert(NewCopy); ++ MachineInstr &NewCopy = rewriteSource(MI, Def, RewriteMap); ++ LocalMIs.insert(&NewCopy); + } + + // MI is now dead. +- MI->eraseFromParent(); ++ MI.eraseFromParent(); + ++NumUncoalescableCopies; + return true; + } +@@ -1374,18 +1308,18 @@ bool PeepholeOptimizer::optimizeUncoalescableCopy( + /// We only fold loads to virtual registers and the virtual register defined + /// has a single use. + bool PeepholeOptimizer::isLoadFoldable( +- MachineInstr *MI, SmallSet &FoldAsLoadDefCandidates) { +- if (!MI->canFoldAsLoad() || !MI->mayLoad()) ++ MachineInstr &MI, SmallSet &FoldAsLoadDefCandidates) { ++ if (!MI.canFoldAsLoad() || !MI.mayLoad()) + return false; +- const MCInstrDesc &MCID = MI->getDesc(); ++ const MCInstrDesc &MCID = MI.getDesc(); + if (MCID.getNumDefs() != 1) + return false; + +- unsigned Reg = MI->getOperand(0).getReg(); ++ unsigned Reg = MI.getOperand(0).getReg(); + // To reduce compilation time, we check MRI->hasOneNonDBGUse when inserting + // loads. It should be checked when processing uses of the load, since + // uses can be removed during peephole. +- if (!MI->getOperand(0).getSubReg() && ++ if (!MI.getOperand(0).getSubReg() && + TargetRegisterInfo::isVirtualRegister(Reg) && + MRI->hasOneNonDBGUse(Reg)) { + FoldAsLoadDefCandidates.insert(Reg); +@@ -1395,16 +1329,16 @@ bool PeepholeOptimizer::isLoadFoldable( + } + + bool PeepholeOptimizer::isMoveImmediate( +- MachineInstr *MI, SmallSet &ImmDefRegs, ++ MachineInstr &MI, SmallSet &ImmDefRegs, + DenseMap &ImmDefMIs) { +- const MCInstrDesc &MCID = MI->getDesc(); +- if (!MI->isMoveImmediate()) ++ const MCInstrDesc &MCID = MI.getDesc(); ++ if (!MI.isMoveImmediate()) + return false; + if (MCID.getNumDefs() != 1) + return false; +- unsigned Reg = MI->getOperand(0).getReg(); ++ unsigned Reg = MI.getOperand(0).getReg(); + if (TargetRegisterInfo::isVirtualRegister(Reg)) { +- ImmDefMIs.insert(std::make_pair(Reg, MI)); ++ ImmDefMIs.insert(std::make_pair(Reg, &MI)); + ImmDefRegs.insert(Reg); + return true; + } +@@ -1415,11 +1349,11 @@ bool PeepholeOptimizer::isMoveImmediate( + /// Try folding register operands that are defined by move immediate + /// instructions, i.e. a trivial constant folding optimization, if + /// and only if the def and use are in the same BB. +-bool PeepholeOptimizer::foldImmediate( +- MachineInstr *MI, MachineBasicBlock *MBB, SmallSet &ImmDefRegs, ++bool PeepholeOptimizer::foldImmediate(MachineInstr &MI, ++ SmallSet &ImmDefRegs, + DenseMap &ImmDefMIs) { +- for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { +- MachineOperand &MO = MI->getOperand(i); ++ for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) { ++ MachineOperand &MO = MI.getOperand(i); + if (!MO.isReg() || MO.isDef()) + continue; + // Ignore dead implicit defs. +@@ -1432,7 +1366,7 @@ bool PeepholeOptimizer::foldImmediate( + continue; + DenseMap::iterator II = ImmDefMIs.find(Reg); + assert(II != ImmDefMIs.end() && "couldn't find immediate definition"); +- if (TII->FoldImmediate(*MI, *II->second, Reg, MRI)) { ++ if (TII->FoldImmediate(MI, *II->second, Reg, MRI)) { + ++NumImmFold; + return true; + } +@@ -1454,28 +1388,28 @@ bool PeepholeOptimizer::foldImmediate( + // %2 = COPY %0:sub1 + // + // Should replace %2 uses with %1:sub1 +-bool PeepholeOptimizer::foldRedundantCopy( +- MachineInstr *MI, SmallSet &CopySrcRegs, ++bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &MI, ++ SmallSet &CopySrcRegs, + DenseMap &CopyMIs) { +- assert(MI->isCopy() && "expected a COPY machine instruction"); ++ assert(MI.isCopy() && "expected a COPY machine instruction"); + +- unsigned SrcReg = MI->getOperand(1).getReg(); ++ unsigned SrcReg = MI.getOperand(1).getReg(); + if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) + return false; + +- unsigned DstReg = MI->getOperand(0).getReg(); ++ unsigned DstReg = MI.getOperand(0).getReg(); + if (!TargetRegisterInfo::isVirtualRegister(DstReg)) + return false; + + if (CopySrcRegs.insert(SrcReg).second) { + // First copy of this reg seen. +- CopyMIs.insert(std::make_pair(SrcReg, MI)); ++ CopyMIs.insert(std::make_pair(SrcReg, &MI)); + return false; + } + + MachineInstr *PrevCopy = CopyMIs.find(SrcReg)->second; + +- unsigned SrcSubReg = MI->getOperand(1).getSubReg(); ++ unsigned SrcSubReg = MI.getOperand(1).getSubReg(); + unsigned PrevSrcSubReg = PrevCopy->getOperand(1).getSubReg(); + + // Can't replace different subregister extracts. +@@ -1504,19 +1438,19 @@ bool PeepholeOptimizer::isNAPhysCopy(unsigned Reg) { + } + + bool PeepholeOptimizer::foldRedundantNAPhysCopy( +- MachineInstr *MI, DenseMap &NAPhysToVirtMIs) { +- assert(MI->isCopy() && "expected a COPY machine instruction"); ++ MachineInstr &MI, DenseMap &NAPhysToVirtMIs) { ++ assert(MI.isCopy() && "expected a COPY machine instruction"); + + if (DisableNAPhysCopyOpt) + return false; + +- unsigned DstReg = MI->getOperand(0).getReg(); +- unsigned SrcReg = MI->getOperand(1).getReg(); ++ unsigned DstReg = MI.getOperand(0).getReg(); ++ unsigned SrcReg = MI.getOperand(1).getReg(); + if (isNAPhysCopy(SrcReg) && TargetRegisterInfo::isVirtualRegister(DstReg)) { + // %vreg = COPY %physreg + // Avoid using a datastructure which can track multiple live non-allocatable + // phys->virt copies since LLVM doesn't seem to do this. +- NAPhysToVirtMIs.insert({SrcReg, MI}); ++ NAPhysToVirtMIs.insert({SrcReg, &MI}); + return false; + } + +@@ -1528,8 +1462,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy( + if (PrevCopy == NAPhysToVirtMIs.end()) { + // We can't remove the copy: there was an intervening clobber of the + // non-allocatable physical register after the copy to virtual. +- DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << *MI +- << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << MI); + return false; + } + +@@ -1537,7 +1470,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy( + if (PrevDstReg == SrcReg) { + // Remove the virt->phys copy: we saw the virtual register definition, and + // the non-allocatable physical register's state hasn't changed since then. +- DEBUG(dbgs() << "NAPhysCopy: erasing " << *MI << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: erasing " << MI); + ++NumNAPhysCopies; + return true; + } +@@ -1546,7 +1479,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy( + // register get a copy of the non-allocatable physical register, and we only + // track one such copy. Avoid getting confused by this new non-allocatable + // physical register definition, and remove it from the tracked copies. +- DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << *MI << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << MI); + NAPhysToVirtMIs.erase(PrevCopy); + return false; + } +@@ -1611,11 +1544,11 @@ bool PeepholeOptimizer::findTargetRecurrence( + return false; + } + +-/// \brief Phi instructions will eventually be lowered to copy instructions. If +-/// phi is in a loop header, a recurrence may formulated around the source and +-/// destination of the phi. For such case commuting operands of the instructions +-/// in the recurrence may enable coalescing of the copy instruction generated +-/// from the phi. For example, if there is a recurrence of ++/// Phi instructions will eventually be lowered to copy instructions. ++/// If phi is in a loop header, a recurrence may formulated around the source ++/// and destination of the phi. For such case commuting operands of the ++/// instructions in the recurrence may enable coalescing of the copy instruction ++/// generated from the phi. For example, if there is a recurrence of + /// + /// LoopHeader: + /// %1 = phi(%0, %100) +@@ -1725,27 +1658,25 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { + } + + if (!MI->isCopy()) { +- for (const auto &Op : MI->operands()) { ++ for (const MachineOperand &MO : MI->operands()) { + // Visit all operands: definitions can be implicit or explicit. +- if (Op.isReg()) { +- unsigned Reg = Op.getReg(); +- if (Op.isDef() && isNAPhysCopy(Reg)) { ++ if (MO.isReg()) { ++ unsigned Reg = MO.getReg(); ++ if (MO.isDef() && isNAPhysCopy(Reg)) { + const auto &Def = NAPhysToVirtMIs.find(Reg); + if (Def != NAPhysToVirtMIs.end()) { + // A new definition of the non-allocatable physical register + // invalidates previous copies. +- DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI +- << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI); + NAPhysToVirtMIs.erase(Def); + } + } +- } else if (Op.isRegMask()) { +- const uint32_t *RegMask = Op.getRegMask(); ++ } else if (MO.isRegMask()) { ++ const uint32_t *RegMask = MO.getRegMask(); + for (auto &RegMI : NAPhysToVirtMIs) { + unsigned Def = RegMI.first; + if (MachineOperand::clobbersPhysReg(RegMask, Def)) { +- DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI +- << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI); + NAPhysToVirtMIs.erase(Def); + } + } +@@ -1761,58 +1692,57 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { + // don't know what's correct anymore. + // + // FIXME: handle explicit asm clobbers. +- DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI +- << '\n'); ++ DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI); + NAPhysToVirtMIs.clear(); + } + + if ((isUncoalescableCopy(*MI) && +- optimizeUncoalescableCopy(MI, LocalMIs)) || +- (MI->isCompare() && optimizeCmpInstr(MI, &MBB)) || +- (MI->isSelect() && optimizeSelect(MI, LocalMIs))) { ++ optimizeUncoalescableCopy(*MI, LocalMIs)) || ++ (MI->isCompare() && optimizeCmpInstr(*MI)) || ++ (MI->isSelect() && optimizeSelect(*MI, LocalMIs))) { + // MI is deleted. + LocalMIs.erase(MI); + Changed = true; + continue; + } + +- if (MI->isConditionalBranch() && optimizeCondBranch(MI)) { ++ if (MI->isConditionalBranch() && optimizeCondBranch(*MI)) { + Changed = true; + continue; + } + +- if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(MI)) { ++ if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(*MI)) { + // MI is just rewritten. + Changed = true; + continue; + } + + if (MI->isCopy() && +- (foldRedundantCopy(MI, CopySrcRegs, CopySrcMIs) || +- foldRedundantNAPhysCopy(MI, NAPhysToVirtMIs))) { ++ (foldRedundantCopy(*MI, CopySrcRegs, CopySrcMIs) || ++ foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) { + LocalMIs.erase(MI); + MI->eraseFromParent(); + Changed = true; + continue; + } + +- if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) { ++ if (isMoveImmediate(*MI, ImmDefRegs, ImmDefMIs)) { + SeenMoveImm = true; + } else { +- Changed |= optimizeExtInstr(MI, &MBB, LocalMIs); ++ Changed |= optimizeExtInstr(*MI, MBB, LocalMIs); + // optimizeExtInstr might have created new instructions after MI + // and before the already incremented MII. Adjust MII so that the + // next iteration sees the new instructions. + MII = MI; + ++MII; + if (SeenMoveImm) +- Changed |= foldImmediate(MI, &MBB, ImmDefRegs, ImmDefMIs); ++ Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs); + } + + // Check whether MI is a load candidate for folding into a later + // instruction. If MI is not a candidate, check whether we can fold an + // earlier load into MI. +- if (!isLoadFoldable(MI, FoldAsLoadDefCandidates) && ++ if (!isLoadFoldable(*MI, FoldAsLoadDefCandidates) && + !FoldAsLoadDefCandidates.empty()) { + + // We visit each operand even after successfully folding a previous +@@ -1861,7 +1791,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { + // the load candidates. Note: We might be able to fold *into* this + // instruction, so this needs to be after the folding logic. + if (MI->isLoadFoldBarrier()) { +- DEBUG(dbgs() << "Encountered load fold barrier on " << *MI << "\n"); ++ DEBUG(dbgs() << "Encountered load fold barrier on " << *MI); + FoldAsLoadDefCandidates.clear(); + } + } +@@ -1958,14 +1888,14 @@ ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() { + // duplicate the code from the generic TII. + return ValueTrackerResult(); + +- SmallVector RegSeqInputRegs; ++ SmallVector RegSeqInputRegs; + if (!TII->getRegSequenceInputs(*Def, DefIdx, RegSeqInputRegs)) + return ValueTrackerResult(); + + // We are looking at: + // Def = REG_SEQUENCE v0, sub0, v1, sub1, ... + // Check if one of the operand defines the subreg we are interested in. +- for (auto &RegSeqInput : RegSeqInputRegs) { ++ for (const RegSubRegPairAndIdx &RegSeqInput : RegSeqInputRegs) { + if (RegSeqInput.SubIdx == DefSubReg) { + if (RegSeqInput.SubReg) + // Bail if we have to compose sub registers. +@@ -1996,8 +1926,8 @@ ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() { + // duplicate the code from the generic TII. + return ValueTrackerResult(); + +- TargetInstrInfo::RegSubRegPair BaseReg; +- TargetInstrInfo::RegSubRegPairAndIdx InsertedReg; ++ RegSubRegPair BaseReg; ++ RegSubRegPairAndIdx InsertedReg; + if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg)) + return ValueTrackerResult(); + +@@ -2050,7 +1980,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() { + // duplicate the code from the generic TII. + return ValueTrackerResult(); + +- TargetInstrInfo::RegSubRegPairAndIdx ExtractSubregInputReg; ++ RegSubRegPairAndIdx ExtractSubregInputReg; + if (!TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg)) + return ValueTrackerResult(); + +@@ -2083,7 +2013,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() { + Def->getOperand(3).getImm()); + } + +-/// \brief Explore each PHI incoming operand and return its sources ++/// Explore each PHI incoming operand and return its sources. + ValueTrackerResult ValueTracker::getNextSourceFromPHI() { + assert(Def->isPHI() && "Invalid definition"); + ValueTrackerResult Res; +@@ -2095,7 +2025,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromPHI() { + + // Return all register sources for PHI instructions. + for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2) { +- auto &MO = Def->getOperand(i); ++ const MachineOperand &MO = Def->getOperand(i); + assert(MO.isReg() && "Invalid PHI instruction"); + // We have no code to deal with undef operands. They shouldn't happen in + // normal programs anyway. +@@ -2121,7 +2051,7 @@ ValueTrackerResult ValueTracker::getNextSourceImpl() { + return getNextSourceFromBitcast(); + // All the remaining cases involve "complex" instructions. + // Bail if we did not ask for the advanced tracking. +- if (!UseAdvancedTracking) ++ if (DisableAdvCopyOpt) + return ValueTrackerResult(); + if (Def->isRegSequence() || Def->isRegSequenceLike()) + return getNextSourceFromRegSequence(); +-- +2.18.0 +