Backed out 4 changesets (bug 1850710, bug 1850723, bug 1489008) for causing failures on mfbt/tests/TestResult.cpp

Backed out changeset 7398cacb1ad3 (bug 1850723)
Backed out changeset 3ecdc29f9faf (bug 1850710)
Backed out changeset 0be8a44ae0b0 (bug 1489008)
Backed out changeset e1545a8ce2d8 (bug 1489008)
This commit is contained in:
Sandor Molnar 2023-11-03 06:00:46 +02:00
parent 6eecb51843
commit e8f8acdf36
7 changed files with 94 additions and 326 deletions

View File

@ -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<typeName>(); \
}
#define DECLARE_AS(typeName, longTypeName, asMethodName) \
static longTypeName asMethodName(Node node) { return &node->as<typeName>(); }
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
#undef DECLARE_AS

View File

@ -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

View File

@ -417,7 +417,7 @@ typename ParseHandler::ListNodeType GeneralParser<ParseHandler, Unit>::parse() {
return null();
}
}
stmtList = handler_.asListNode(node);
stmtList = handler_.asList(node);
}
return stmtList;
@ -1798,7 +1798,7 @@ LexicalScopeNode* Parser<FullParseHandler, Unit>::evalBody(
return null();
}
}
body = handler_.asLexicalScopeNode(node);
body = handler_.asLexicalScope(node);
if (!this->setSourceMapInfo()) {
return nullptr;
@ -2492,7 +2492,7 @@ GeneralParser<ParseHandler, Unit>::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<ParseHandler, Unit>::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<ParseHandler, Unit>::exportFunctionDeclaration(
return null();
}
if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
if (!checkExportedNameForFunction(handler_.asFunction(kid))) {
return null();
}
@ -11728,7 +11728,7 @@ bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
}
if (handler_.isName(expr)) {
checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
checkDestructuringAssignmentName(handler_.asName(expr), exprPos,
possibleError);
return true;
}
@ -12398,7 +12398,7 @@ GeneralParser<ParseHandler, Unit>::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<ParseHandler, Unit>::recordLiteral(YieldHandling yieldHandling) {
return null();
}
if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
if (!handler_.addShorthand(literal, handler_.asName(propName),
nameExpr)) {
return null();
}

View File

@ -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<ParseHandler> {
using FinalParser = Parser<ParseHandler, Unit>;
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<SyntaxParseHandler, Unit> final
using Base = GeneralParser<SyntaxParseHandler, Unit>;
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<FullParseHandler, Unit> final
using Base = GeneralParser<FullParseHandler, Unit>;
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

View File

@ -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

View File

@ -48,7 +48,6 @@ enum class PackingStrategy {
NullIsOk,
LowBitTagIsError,
PackedVariant,
ZeroIsEmptyError,
};
template <typename T>
@ -186,42 +185,6 @@ class ResultImplementationNullIsOk<V, E, false>
}
};
/**
* 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 <typename V, typename E>
class ResultImplementation<V, E, PackingStrategy::ZeroIsEmptyError> {
static_assert(std::is_integral_v<V> || std::is_pointer_v<V> ||
std::is_enum_v<V>);
static_assert(std::is_empty_v<E>);
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<T*> {
template <typename V, typename E>
struct SelectResultImpl {
static const PackingStrategy value =
(UnusedZero<V>::value && std::is_empty_v<E>)
? PackingStrategy::ZeroIsEmptyError
: (HasFreeLSB<V>::value && HasFreeLSB<E>::value)
(HasFreeLSB<V>::value && HasFreeLSB<E>::value)
? PackingStrategy::LowBitTagIsError
: (UnusedZero<E>::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 <typename V2, typename E2,
typename = std::enable_if_t<std::is_convertible_v<V2, V> &&
std::is_convertible_v<E2, E>>>
MOZ_IMPLICIT constexpr Result(Result<V2, E2>&& aOther)
* Create a (success/error) result from another (success/error) result with a
* different but convertible error type. */
template <typename E2,
typename = std::enable_if_t<std::is_convertible_v<E2, E>>>
MOZ_IMPLICIT constexpr Result(Result<V, E2>&& aOther)
: mImpl(aOther.isOk() ? Impl{aOther.unwrap()}
: Impl{aOther.unwrapErr()}) {}

View File

@ -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 <stdint.h>
#include <string.h>
#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<ZeroIsUnusedStructForPointer*> {
static const bool value = true;
};
template <>
struct mozilla::detail::UnusedZero<ZeroIsUnusedEnum1> {
static const bool value = true;
};
template <>
struct mozilla::detail::UnusedZero<ZeroIsUnusedEnum2> {
static const bool value = true;
};
template <>
struct mozilla::detail::UnusedZero<ZeroIsUnusedEnum4> {
static const bool value = true;
};
template <>
struct mozilla::detail::UnusedZero<ZeroIsUnusedEnum8> {
static const bool value = true;
};
static void ZeroIsEmptyErrorTest() {
{
ZeroIsUnusedStructForPointer s;
using V = ZeroIsUnusedStructForPointer*;
mozilla::Result<V, EmptyErrorStruct> 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<V, EmptyErrorStruct> result(Err(EmptyErrorStruct{}));
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(*reinterpret_cast<V*>(&result) == nullptr);
}
{
ZeroIsUnusedEnum1 e = ZeroIsUnusedEnum1::V1;
using V = ZeroIsUnusedEnum1;
mozilla::Result<V, EmptyErrorStruct> 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<V, EmptyErrorStruct> result(Err(EmptyErrorStruct()));
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(*reinterpret_cast<int*>(&result) == 0);
}
{
ZeroIsUnusedEnum2 e = ZeroIsUnusedEnum2::V1;
using V = ZeroIsUnusedEnum2;
mozilla::Result<V, EmptyErrorStruct> 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<V, EmptyErrorStruct> result(Err(EmptyErrorStruct()));
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(*reinterpret_cast<int*>(&result) == 0);
}
{
ZeroIsUnusedEnum4 e = ZeroIsUnusedEnum4::V1;
using V = ZeroIsUnusedEnum4;
mozilla::Result<V, EmptyErrorStruct> 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<V, EmptyErrorStruct> result(Err(EmptyErrorStruct()));
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(*reinterpret_cast<int*>(&result) == 0);
}
{
ZeroIsUnusedEnum8 e = ZeroIsUnusedEnum8::V1;
using V = ZeroIsUnusedEnum8;
mozilla::Result<V, EmptyErrorStruct> 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<V, EmptyErrorStruct> result(Err(EmptyErrorStruct()));
MOZ_RELEASE_ASSERT(result.isErr());
MOZ_RELEASE_ASSERT(*reinterpret_cast<int*>(&result) == 0);
}
}
class Foo {};
class C1 {};
class C2 : public C1 {};
class E1 {};
class E2 : public E1 {};
void UpcastTest() {
{
C2 c2;
mozilla::Result<C2*, Failed> result(&c2);
mozilla::Result<C1*, Failed> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspect() == &c2);
}
{
E2 e2;
mozilla::Result<Foo, E2*> result(Err(&e2));
mozilla::Result<Foo, E1*> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspectErr() == &e2);
}
{
C2 c2;
mozilla::Result<C2*, E2*> result(&c2);
mozilla::Result<C1*, E1*> copied(std::move(result));
MOZ_RELEASE_ASSERT(copied.inspect() == &c2);
}
{
E2 e2;
mozilla::Result<C2*, E2*> result(Err(&e2));
mozilla::Result<C1*, E1*> 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;
}