diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 13a76ce992..77993a1aff 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -715,8 +715,6 @@ var interfaceNamesInGlobalScope = "NodeList", // IMPORTANT: Do not change this list without review from a DOM peer! "Notification", -// IMPORTANT: Do not change this list without review from a DOM peer! - "NotifyPaintEvent", // IMPORTANT: Do not change this list without review from a DOM peer! {name: "OffscreenCanvas", disabled: true}, // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/NotifyPaintEvent.webidl b/dom/webidl/NotifyPaintEvent.webidl index 799abbb299..b4be1c3a79 100644 --- a/dom/webidl/NotifyPaintEvent.webidl +++ b/dom/webidl/NotifyPaintEvent.webidl @@ -6,13 +6,18 @@ * For more information about this interface see nsIDOMNotifyPaintEvent.idl */ +[ChromeOnly] interface NotifyPaintEvent : Event { + [ChromeOnly] readonly attribute DOMRectList clientRects; + [ChromeOnly] readonly attribute DOMRect boundingClientRect; + [ChromeOnly] readonly attribute PaintRequestList paintRequests; + [ChromeOnly] readonly attribute unsigned long long transactionId; }; diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index f00cb9c687..48ec896fd8 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -4143,8 +4143,15 @@ Parser::statementList(YieldHandling yieldHandling) return null(); bool canHaveDirectives = pc->atBodyLevel(); - if (canHaveDirectives) + if (canHaveDirectives) { tokenStream.clearSawOctalEscape(); + } + + bool canHaveHashbangComment = pc->atTopLevel(); + if (canHaveHashbangComment) { + tokenStream.consumeOptionalHashbangComment(); + } + bool afterReturn = false; bool warnedAboutStatementsAfterReturn = false; uint32_t statementBegin = 0; diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 4a8e038d6e..b1a9bf83c5 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -470,6 +470,12 @@ class ParseContext : public Nestable return atBodyLevel() && sc_->isModuleContext(); } + // True if we are at the topmost level of an entire script or module. For + // example, in the comment on |atBodyLevel()| above, we would encounter |f1| + // and the outermost |if (cond)| at top level, and everything else would not + // be at top level. + bool atTopLevel() { return atBodyLevel() && sc_->isTopLevelContext(); } + void setIsStandaloneFunctionBody() { isStandaloneFunctionBody_ = true; } diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index bc0212054b..d938bfab7e 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -289,6 +289,16 @@ class SharedContext bool isEvalContext() { return kind_ == Kind::Eval; } inline EvalSharedContext* asEvalContext(); + bool isTopLevelContext() const { + switch (kind_) { + case Kind::Module: + case Kind::Global: + case Kind::Eval: + return true; + } + return false; + } + ThisBinding thisBinding() const { return thisBinding_; } bool hasModuleGoal() const { return hasModuleGoal_; } diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index b11c7df584..cd0e1b29e4 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -1300,6 +1300,21 @@ TokenStream::putIdentInTokenbuf(const char16_t* identStart) return true; } +void +TokenStream::consumeOptionalHashbangComment() { + int c = userbuf.getRawChar(); + if (c == '#') { + if (matchChar('!')) { + // Hashbang; ignore rest of line as comment. + while ((c = getChar()) != EOF && c != '\n') + continue; + } + } + ungetChar(c); + cursor = (cursor - 1) & ntokensMask; +} + + enum FirstCharKind { // A char16_t has the 'OneChar' kind if it, by itself, constitutes a valid // token that cannot also be a prefix of a longer token. E.g. ';' has the diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index e7a3f7b808..3d4695fdea 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -428,6 +428,13 @@ class MOZ_STACK_CLASS TokenStream // asm.js reporter void reportAsmJSError(uint32_t offset, unsigned errorNumber, ...); + /** + * Consume any hashbang comment at the start of a Script or Module, if one is + * present. Stops consuming just before any terminating LineTerminator or + * before an encoding error is encountered. + */ + void consumeOptionalHashbangComment(); + JSAtom* getRawTemplateStringAtom() { MOZ_ASSERT(currentToken().type == TOK_TEMPLATE_HEAD || currentToken().type == TOK_NO_SUBS_TEMPLATE); diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index cbf3113b50..b9266514e3 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -188,21 +188,19 @@ FetchName(JSContext* cx, HandleObject obj, HandleObject obj2, HandlePropertyName } /* Take the slow path if shape was not found in a native object. */ - if (!obj->isNative() || !obj2->isNative()) { + if (!obj->isNative() || !obj2->isNative() || + obj->is()) { Rooted id(cx, NameToId(name)); if (!GetProperty(cx, obj, obj, id, vp)) return false; } else { RootedShape shape(cx, prop.shape()); - RootedObject normalized(cx, obj); - if (normalized->is() && !shape->hasDefaultGetter()) - normalized = &normalized->as().object(); if (shape->isDataDescriptor() && shape->hasDefaultGetter()) { /* Fast path for Object instance properties. */ MOZ_ASSERT(shape->hasSlot()); vp.set(obj2->as().getSlot(shape->slot())); } else { - if (!NativeGetExistingProperty(cx, normalized, obj2.as(), shape, vp)) + if (!NativeGetExistingProperty(cx, obj, obj2.as(), shape, vp)) return false; } } diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 9e46f2dae0..6ce1104179 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1264,7 +1264,10 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin // about:memory may use that information xpc::SetLocationForGlobal(sandbox, options.sandboxName); - xpc::SetSandboxMetadata(cx, sandbox, options.metadata); + nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, options.metadata); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } JS_FireOnNewGlobalObject(cx, sandbox); diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 6c2711210a..97f5c36fe8 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3111,7 +3111,7 @@ nsresult GetSandboxMetadata(JSContext* cx, JS::HandleObject sandboxArg, JS::MutableHandleValue rval); -nsresult +[[nodiscard]] nsresult SetSandboxMetadata(JSContext* cx, JS::HandleObject sandboxArg, JS::HandleValue metadata); diff --git a/layout/base/tests/test_after_paint_pref.html b/layout/base/tests/test_after_paint_pref.html index 33a8c71625..c1a8e6a294 100644 --- a/layout/base/tests/test_after_paint_pref.html +++ b/layout/base/tests/test_after_paint_pref.html @@ -24,14 +24,19 @@ window.addEventListener("load", step0, false); is(SpecialPowers.getBoolPref("dom.send_after_paint_to_content"), true, "pref defaults to true in mochitest harness"); function print_rect(rect) { + if (!rect) { + rect = { top: 0, left: 0, width: 0, right: 0 }; + } return "(top=" + rect.top + ",left=" + rect.left + ",width=" + rect.width + ",height=" + rect.height + ")"; } function print_event(event) { var res = "boundingClientRect=" + print_rect(event.boundingClientRect); var rects = event.clientRects; - for (var i = 0; i < rects.length; ++i) { - res += " clientRects[" + i + "]=" + print_rect(rects[i]); + if (rects) { + for (var i = 0; i < rects.length; ++i) { + res += " clientRects[" + i + "]=" + print_rect(rects[i]); + } } return res; } diff --git a/testing/mochitest/tests/SimpleTest/paint_listener.js b/testing/mochitest/tests/SimpleTest/paint_listener.js index 304a0fd629..4054ce0d0e 100644 --- a/testing/mochitest/tests/SimpleTest/paint_listener.js +++ b/testing/mochitest/tests/SimpleTest/paint_listener.js @@ -10,11 +10,15 @@ function paintListener(event) { if (event.target != window) return; - var eventRect = - [ event.boundingClientRect.left, - event.boundingClientRect.top, - event.boundingClientRect.right, - event.boundingClientRect.bottom ]; + var clientRect = event.boundingClientRect; + var eventRect; + if (clientRect) { + eventRect = + [ clientRect.left, clientRect.top, + clientRect.right, clientRect.bottom ]; + } else { + eventRect = [ 0, 0, 0, 0 ]; + } if (debug) { dump("got MozAfterPaint: " + eventRect.join(",") + "\n"); }