diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index e778cfb4f824..73b7c0077741 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -61,9 +61,11 @@ class FullParseHandler { /* new_ methods for creating parse nodes. These report OOM on context. */ JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline) + // FIXME: Use ListNode instead of ListNodeType as an alias (bug 1489008). using Node = ParseNode*; -#define DECLARE_TYPE(typeName) using typeName##Type = typeName*; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = typeName*; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE @@ -109,10 +111,8 @@ class FullParseHandler { static NullNode null() { return NullNode(); } -#define DECLARE_AS(typeName) \ - static typeName##Type as##typeName(Node node) { \ - return &node->as(); \ - } +#define DECLARE_AS(typeName, longTypeName, asMethodName) \ + static longTypeName asMethodName(Node node) { return &node->as(); } FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) #undef DECLARE_AS diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index 653d6a9deb96..77fa71347879 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -605,64 +605,70 @@ inline bool IsTypeofKind(ParseNodeKind kind) { * kid: expr or null */ -#define FOR_EACH_PARSENODE_SUBCLASS(MACRO) \ - MACRO(BinaryNode) \ - MACRO(AssignmentNode) \ - MACRO(CaseClause) \ - MACRO(ClassMethod) \ - MACRO(ClassField) \ - MACRO(StaticClassBlock) \ - MACRO(PropertyDefinition) \ - MACRO(ClassNames) \ - MACRO(ForNode) \ - MACRO(PropertyAccess) \ - MACRO(OptionalPropertyAccess) \ - MACRO(PropertyByValue) \ - MACRO(OptionalPropertyByValue) \ - MACRO(PrivateMemberAccess) \ - MACRO(OptionalPrivateMemberAccess) \ - MACRO(NewTargetNode) \ - MACRO(SwitchStatement) \ - MACRO(DeclarationListNode) \ - \ - MACRO(ParamsBodyNode) \ - MACRO(FunctionNode) \ - MACRO(ModuleNode) \ - \ - MACRO(LexicalScopeNode) \ - MACRO(ClassBodyScopeNode) \ - \ - MACRO(ListNode) \ - MACRO(CallSiteNode) \ - MACRO(CallNode) \ - \ - MACRO(LoopControlStatement) \ - MACRO(BreakStatement) \ - MACRO(ContinueStatement) \ - \ - MACRO(NameNode) \ - MACRO(LabeledStatement) \ - \ - MACRO(NullaryNode) \ - MACRO(BooleanLiteral) \ - MACRO(DebuggerStatement) \ - MACRO(NullLiteral) \ - MACRO(RawUndefinedLiteral) \ - \ - MACRO(NumericLiteral) \ - MACRO(BigIntLiteral) \ - \ - MACRO(RegExpLiteral) \ - \ - MACRO(TernaryNode) \ - MACRO(ClassNode) \ - MACRO(ConditionalExpression) \ - MACRO(TryNode) \ - \ - MACRO(UnaryNode) \ - MACRO(ThisLiteral) +// FIXME: Remove `*Type` (bug 1489008) +#define FOR_EACH_PARSENODE_SUBCLASS(MACRO) \ + MACRO(BinaryNode, BinaryNodeType, asBinary) \ + MACRO(AssignmentNode, AssignmentNodeType, asAssignment) \ + MACRO(CaseClause, CaseClauseType, asCaseClause) \ + MACRO(ClassMethod, ClassMethodType, asClassMethod) \ + MACRO(ClassField, ClassFieldType, asClassField) \ + MACRO(StaticClassBlock, StaticClassBlockType, asStaticClassBlock) \ + MACRO(PropertyDefinition, PropertyDefinitionType, asPropertyDefinition) \ + MACRO(ClassNames, ClassNamesType, asClassNames) \ + MACRO(ForNode, ForNodeType, asFor) \ + MACRO(PropertyAccess, PropertyAccessType, asPropertyAccess) \ + MACRO(OptionalPropertyAccess, OptionalPropertyAccessType, \ + asOptionalPropertyAccess) \ + MACRO(PropertyByValue, PropertyByValueType, asPropertyByValue) \ + MACRO(OptionalPropertyByValue, OptionalPropertyByValueType, \ + asOptionalPropertyByValue) \ + MACRO(PrivateMemberAccess, PrivateMemberAccessType, asPrivateMemberAccess) \ + MACRO(OptionalPrivateMemberAccess, OptionalPrivateMemberAccessType, \ + asOptionalPrivateMemberAccess) \ + MACRO(NewTargetNode, NewTargetNodeType, asNewTargetNode) \ + MACRO(SwitchStatement, SwitchStatementType, asSwitchStatement) \ + MACRO(DeclarationListNode, DeclarationListNodeType, asDeclarationList) \ + \ + MACRO(ParamsBodyNode, ParamsBodyNodeType, asParamsBody) \ + MACRO(FunctionNode, FunctionNodeType, asFunction) \ + MACRO(ModuleNode, ModuleNodeType, asModule) \ + \ + MACRO(LexicalScopeNode, LexicalScopeNodeType, asLexicalScope) \ + MACRO(ClassBodyScopeNode, ClassBodyScopeNodeType, asClassBodyScope) \ + \ + MACRO(ListNode, ListNodeType, asList) \ + MACRO(CallSiteNode, CallSiteNodeType, asCallSite) \ + MACRO(CallNode, CallNodeType, asCallNode) \ + \ + MACRO(LoopControlStatement, LoopControlStatementType, \ + asLoopControlStatement) \ + MACRO(BreakStatement, BreakStatementType, asBreakStatement) \ + MACRO(ContinueStatement, ContinueStatementType, asContinueStatement) \ + \ + MACRO(NameNode, NameNodeType, asName) \ + MACRO(LabeledStatement, LabeledStatementType, asLabeledStatement) \ + \ + MACRO(NullaryNode, NullaryNodeType, asNullary) \ + MACRO(BooleanLiteral, BooleanLiteralType, asBooleanLiteral) \ + MACRO(DebuggerStatement, DebuggerStatementType, asDebuggerStatement) \ + MACRO(NullLiteral, NullLiteralType, asNullLiteral) \ + MACRO(RawUndefinedLiteral, RawUndefinedLiteralType, asRawUndefinedLiteral) \ + \ + MACRO(NumericLiteral, NumericLiteralType, asNumericLiteral) \ + MACRO(BigIntLiteral, BigIntLiteralType, asBigIntLiteral) \ + \ + MACRO(RegExpLiteral, RegExpLiteralType, asRegExpLiteral) \ + \ + MACRO(TernaryNode, TernaryNodeType, asTernary) \ + MACRO(ClassNode, ClassNodeType, asClass) \ + MACRO(ConditionalExpression, ConditionalExpressionType, \ + asConditionalExpression) \ + MACRO(TryNode, TryNodeType, asTry) \ + \ + MACRO(UnaryNode, UnaryNodeType, asUnary) \ + MACRO(ThisLiteral, ThisLiteralType, asThisLiteral) -#define DECLARE_CLASS(typeName) class typeName; +#define DECLARE_CLASS(typeName, longTypeName, asMethodName) class typeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_CLASS) #undef DECLARE_CLASS diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 38be8fa700c6..cbcdcd16dfb0 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -417,7 +417,7 @@ typename ParseHandler::ListNodeType GeneralParser::parse() { return null(); } } - stmtList = handler_.asListNode(node); + stmtList = handler_.asList(node); } return stmtList; @@ -1798,7 +1798,7 @@ LexicalScopeNode* Parser::evalBody( return null(); } } - body = handler_.asLexicalScopeNode(node); + body = handler_.asLexicalScope(node); if (!this->setSourceMapInfo()) { return nullptr; @@ -2492,7 +2492,7 @@ GeneralParser::functionBody(InHandling inHandling, if (!generator) { return null(); } - if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) { + if (!handler_.prependInitialYield(handler_.asList(body), generator)) { return null(); } } @@ -4431,7 +4431,7 @@ GeneralParser::objectBindingPattern( return null(); } - if (!handler_.addShorthand(literal, handler_.asNameNode(propName), + if (!handler_.addShorthand(literal, handler_.asName(propName), binding)) { return null(); } @@ -6035,7 +6035,7 @@ GeneralParser::exportFunctionDeclaration( return null(); } - if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) { + if (!checkExportedNameForFunction(handler_.asFunction(kid))) { return null(); } @@ -11728,7 +11728,7 @@ bool GeneralParser::checkDestructuringAssignmentTarget( } if (handler_.isName(expr)) { - checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos, + checkDestructuringAssignmentName(handler_.asName(expr), exprPos, possibleError); return true; } @@ -12398,7 +12398,7 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, checkDestructuringAssignmentName(nameExpr, namePos, possibleError); } - if (!handler_.addShorthand(literal, handler_.asNameNode(propName), + if (!handler_.addShorthand(literal, handler_.asName(propName), nameExpr)) { return null(); } @@ -12615,7 +12615,7 @@ GeneralParser::recordLiteral(YieldHandling yieldHandling) { return null(); } - if (!handler_.addShorthand(literal, handler_.asNameNode(propName), + if (!handler_.addShorthand(literal, handler_.asName(propName), nameExpr)) { return null(); } diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 19aff54c18ac..c5d7c5108233 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -441,8 +441,8 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase { private: using Node = typename ParseHandler::Node; -#define DECLARE_TYPE(typeName) \ - using typeName##Type = typename ParseHandler::typeName##Type; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = typename ParseHandler::longTypeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE @@ -688,8 +688,8 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { using FinalParser = Parser; using Node = typename ParseHandler::Node; -#define DECLARE_TYPE(typeName) \ - using typeName##Type = typename ParseHandler::typeName##Type; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = typename ParseHandler::longTypeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE @@ -1526,8 +1526,8 @@ class MOZ_STACK_CLASS Parser final using Base = GeneralParser; using Node = SyntaxParseHandler::Node; -#define DECLARE_TYPE(typeName) \ - using typeName##Type = SyntaxParseHandler::typeName##Type; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = SyntaxParseHandler::longTypeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE @@ -1660,8 +1660,8 @@ class MOZ_STACK_CLASS Parser final using Base = GeneralParser; using Node = FullParseHandler::Node; -#define DECLARE_TYPE(typeName) \ - using typeName##Type = FullParseHandler::typeName##Type; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = FullParseHandler::longTypeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h index 1eda11beb02c..40c1078e4cd7 100644 --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -133,7 +133,8 @@ class SyntaxParseHandler { NodeSuperBase }; -#define DECLARE_TYPE(typeName) using typeName##Type = Node; +#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \ + using longTypeName = Node; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) #undef DECLARE_TYPE @@ -178,8 +179,8 @@ class SyntaxParseHandler { static NullNode null() { return NodeFailure; } -#define DECLARE_AS(typeName) \ - static typeName##Type as##typeName(Node node) { return node; } +#define DECLARE_AS(typeName, longTypeName, asMethodName) \ + static longTypeName asMethodName(Node node) { return node; } FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) #undef DECLARE_AS diff --git a/mfbt/Result.h b/mfbt/Result.h index 052920fdbf17..929279046b78 100644 --- a/mfbt/Result.h +++ b/mfbt/Result.h @@ -48,7 +48,6 @@ enum class PackingStrategy { NullIsOk, LowBitTagIsError, PackedVariant, - ZeroIsEmptyError, }; template @@ -186,42 +185,6 @@ class ResultImplementationNullIsOk } }; -/** - * Specialization for when the success type is one of integral, pointer, or - * enum, where 0 is unused, and the error type is an empty struct. - */ -template -class ResultImplementation { - static_assert(std::is_integral_v || std::is_pointer_v || - std::is_enum_v); - static_assert(std::is_empty_v); - - V mValue; - - public: - static constexpr PackingStrategy Strategy = PackingStrategy::ZeroIsEmptyError; - - explicit constexpr ResultImplementation(V aValue) : mValue(aValue) {} - explicit constexpr ResultImplementation(E aErrorValue) : mValue(V(0)) {} - - constexpr bool isOk() const { return mValue != V(0); } - - constexpr V inspect() const { return mValue; } - constexpr V unwrap() { return inspect(); } - - constexpr E inspectErr() const { return E(); } - constexpr E unwrapErr() { return inspectErr(); } - - constexpr void updateAfterTracing(V&& aValue) { - this->~ResultImplementation(); - new (this) ResultImplementation(std::move(aValue)); - } - constexpr void updateErrorAfterTracing(E&& aErrorValue) { - this->~ResultImplementation(); - new (this) ResultImplementation(std::move(aErrorValue)); - } -}; - /** * Specialization for when the success type is default-constructible and the * error type is a value type which can never have the value 0 (as determined by @@ -444,9 +407,7 @@ struct HasFreeLSB { template struct SelectResultImpl { static const PackingStrategy value = - (UnusedZero::value && std::is_empty_v) - ? PackingStrategy::ZeroIsEmptyError - : (HasFreeLSB::value && HasFreeLSB::value) + (HasFreeLSB::value && HasFreeLSB::value) ? PackingStrategy::LowBitTagIsError : (UnusedZero::value && sizeof(E) <= sizeof(uintptr_t)) ? PackingStrategy::NullIsOk @@ -561,13 +522,11 @@ class [[nodiscard]] Result final { } /** - * Create a (success/error) result from another (success/error) result with - * different but convertible value and error types. - */ - template && - std::is_convertible_v>> - MOZ_IMPLICIT constexpr Result(Result&& aOther) + * Create a (success/error) result from another (success/error) result with a + * different but convertible error type. */ + template >> + MOZ_IMPLICIT constexpr Result(Result&& aOther) : mImpl(aOther.isOk() ? Impl{aOther.unwrap()} : Impl{aOther.unwrapErr()}) {} diff --git a/mfbt/tests/TestResult.cpp b/mfbt/tests/TestResult.cpp index 9c31b10080aa..22da6d29fd50 100644 --- a/mfbt/tests/TestResult.cpp +++ b/mfbt/tests/TestResult.cpp @@ -4,7 +4,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 #include #include "mozilla/ResultVariant.h" #include "mozilla/Try.h" @@ -657,201 +656,6 @@ static void UniquePtrTest() { } } -struct ZeroIsUnusedStructForPointer { - int x; -}; -enum class ZeroIsUnusedEnum1 : uint8_t { - V1 = 1, - V2 = 2, -}; -enum class ZeroIsUnusedEnum2 : uint16_t { - V1 = 1, - V2 = 2, -}; -enum class ZeroIsUnusedEnum4 : uint32_t { - V1 = 1, - V2 = 2, -}; -enum class ZeroIsUnusedEnum8 : uint64_t { - V1 = 1, - V2 = 2, -}; -struct EmptyErrorStruct {}; - -template <> -struct mozilla::detail::UnusedZero { - static const bool value = true; -}; -template <> -struct mozilla::detail::UnusedZero { - static const bool value = true; -}; -template <> -struct mozilla::detail::UnusedZero { - static const bool value = true; -}; -template <> -struct mozilla::detail::UnusedZero { - static const bool value = true; -}; -template <> -struct mozilla::detail::UnusedZero { - static const bool value = true; -}; - -static void ZeroIsEmptyErrorTest() { - { - ZeroIsUnusedStructForPointer s; - - using V = ZeroIsUnusedStructForPointer*; - - mozilla::Result result(&s); - MOZ_RELEASE_ASSERT(sizeof(result) == sizeof(V)); - - MOZ_RELEASE_ASSERT(result.isOk()); - MOZ_RELEASE_ASSERT(result.inspect() == &s); - } - - { - using V = ZeroIsUnusedStructForPointer*; - - mozilla::Result result(Err(EmptyErrorStruct{})); - - MOZ_RELEASE_ASSERT(result.isErr()); - MOZ_RELEASE_ASSERT(*reinterpret_cast(&result) == nullptr); - } - - { - ZeroIsUnusedEnum1 e = ZeroIsUnusedEnum1::V1; - - using V = ZeroIsUnusedEnum1; - - mozilla::Result result(e); - MOZ_RELEASE_ASSERT(sizeof(result) == sizeof(V)); - - MOZ_RELEASE_ASSERT(result.isOk()); - MOZ_RELEASE_ASSERT(result.inspect() == e); - } - - { - using V = ZeroIsUnusedEnum1; - - mozilla::Result result(Err(EmptyErrorStruct())); - - MOZ_RELEASE_ASSERT(result.isErr()); - MOZ_RELEASE_ASSERT(*reinterpret_cast(&result) == 0); - } - - { - ZeroIsUnusedEnum2 e = ZeroIsUnusedEnum2::V1; - - using V = ZeroIsUnusedEnum2; - - mozilla::Result result(e); - MOZ_RELEASE_ASSERT(sizeof(result) == sizeof(V)); - - MOZ_RELEASE_ASSERT(result.isOk()); - MOZ_RELEASE_ASSERT(result.inspect() == e); - } - - { - using V = ZeroIsUnusedEnum2; - - mozilla::Result result(Err(EmptyErrorStruct())); - - MOZ_RELEASE_ASSERT(result.isErr()); - MOZ_RELEASE_ASSERT(*reinterpret_cast(&result) == 0); - } - - { - ZeroIsUnusedEnum4 e = ZeroIsUnusedEnum4::V1; - - using V = ZeroIsUnusedEnum4; - - mozilla::Result result(e); - MOZ_RELEASE_ASSERT(sizeof(result) == sizeof(V)); - - MOZ_RELEASE_ASSERT(result.isOk()); - MOZ_RELEASE_ASSERT(result.inspect() == e); - } - - { - using V = ZeroIsUnusedEnum4; - - mozilla::Result result(Err(EmptyErrorStruct())); - - MOZ_RELEASE_ASSERT(result.isErr()); - MOZ_RELEASE_ASSERT(*reinterpret_cast(&result) == 0); - } - - { - ZeroIsUnusedEnum8 e = ZeroIsUnusedEnum8::V1; - - using V = ZeroIsUnusedEnum8; - - mozilla::Result result(e); - MOZ_RELEASE_ASSERT(sizeof(result) == sizeof(V)); - - MOZ_RELEASE_ASSERT(result.isOk()); - MOZ_RELEASE_ASSERT(result.inspect() == e); - } - - { - using V = ZeroIsUnusedEnum8; - - mozilla::Result result(Err(EmptyErrorStruct())); - - MOZ_RELEASE_ASSERT(result.isErr()); - MOZ_RELEASE_ASSERT(*reinterpret_cast(&result) == 0); - } -} - -class Foo {}; - -class C1 {}; -class C2 : public C1 {}; - -class E1 {}; -class E2 : public E1 {}; - -void UpcastTest() { - { - C2 c2; - - mozilla::Result result(&c2); - mozilla::Result copied(std::move(result)); - - MOZ_RELEASE_ASSERT(copied.inspect() == &c2); - } - - { - E2 e2; - - mozilla::Result result(Err(&e2)); - mozilla::Result copied(std::move(result)); - - MOZ_RELEASE_ASSERT(copied.inspectErr() == &e2); - } - - { - C2 c2; - - mozilla::Result result(&c2); - mozilla::Result copied(std::move(result)); - - MOZ_RELEASE_ASSERT(copied.inspect() == &c2); - } - - { - E2 e2; - - mozilla::Result result(Err(&e2)); - mozilla::Result copied(std::move(result)); - - MOZ_RELEASE_ASSERT(copied.inspectErr() == &e2); - } -} - /* * */ int main() { @@ -864,7 +668,5 @@ int main() { OrElseTest(); AndThenTest(); UniquePtrTest(); - ZeroIsEmptyErrorTest(); - UpcastTest(); return 0; }