Commit 0ef1982f authored by Francis McCabe's avatar Francis McCabe Committed by Commit Bot

Revert "Reland "[torque] move class tests to unittests""

This reverts commit c33a1ef2.

Reason for revert: fails win32 test:
https://ci.chromium.org/p/v8/builders/ci/V8%20Win32%20-%20nosnap%20-%20shared/33658

Original change's description:
> Reland "[torque] move class tests to unittests"
> 
> This is a reland of f589d561
> 
> Now with an ASAN-container-overflow false positive workaround:
> Somehow ASAN was unhappy about a simple
> std::vector<std::string>::push_back.
> Increasing the std::vector capacity before doing the push_back
> strangely fixes the problem.
> 
> Original change's description:
> > [torque] move class tests to unittests
> >
> > This avoids the generation of fake external classes.
> >
> > Bug: v8:7793
> > Change-Id: I9744b299d3ec474d72b298b4f6143f95e345d1d9
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1625991
> > Reviewed-by: Simon Zünd <szuend@chromium.org>
> > Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#61778}
> 
> TBR: szuend@chromium.org, sigurds@chromium.org
> Bug: v8:7793
> Change-Id: Ifa1958e4d6e850ba27632aa95c7efaf5ca4bfefa
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1627970
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#61807}

TBR=sigurds@chromium.org,tebbi@chromium.org,szuend@chromium.org

Change-Id: I079e3ccf2c7a4778e3e6aabee85313ab5a070ee3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7793
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1626834Reviewed-by: 's avatarFrancis McCabe <fgm@chromium.org>
Commit-Queue: Francis McCabe <fgm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61808}
parent c33a1ef2
...@@ -155,48 +155,68 @@ void ImplementationVisitor::Visit(NamespaceConstant* decl) { ...@@ -155,48 +155,68 @@ void ImplementationVisitor::Visit(NamespaceConstant* decl) {
void ImplementationVisitor::Visit(TypeAlias* alias) { void ImplementationVisitor::Visit(TypeAlias* alias) {
if (alias->IsRedeclaration()) return; if (alias->IsRedeclaration()) return;
if (const ClassType* class_type = ClassType::DynamicCast(alias->type())) { const ClassType* class_type = ClassType::DynamicCast(alias->type());
if (class_type->IsExtern() && !class_type->nspace()->IsDefaultNamespace()) { if (class_type && class_type->IsExtern()) {
Error( // Classes that are in the default namespace are defined in the C++
"extern classes are currently only supported in the default " // world and all of their fields and methods are declared explicitly.
"namespace"); // Internal classes (e.g. ones used for testing that are not in the default
} // name space) need to be defined by Torque.
} else if (const StructType* struct_type = // TODO(danno): This is a pretty cheesy hack for now. There should be a more
StructType::DynamicCast(alias->type())) { // robust mechanism for this, e.g. declaring classes 'extern' or something.
const std::string& name = struct_type->name(); if (class_type->nspace()->IsTestNamespace()) {
header_out() << " struct " << name << " {\n"; const ClassType* super = class_type->GetSuperClass();
for (auto& field : struct_type->fields()) { std::string class_name{super->GetGeneratedTNodeTypeName()};
header_out() << " " header_out() << " class " << class_type->name() << " : public "
<< field.name_and_type.type->GetGeneratedTypeName(); << class_name << " {\n";
header_out() << " " << field.name_and_type.name << ";\n"; header_out() << " public:\n";
} header_out() << " DEFINE_FIELD_OFFSET_CONSTANTS(" << class_name
header_out() << "\n std::tuple<"; << "::";
bool first = true; header_out() << (super->IsAbstract() ? "kHeaderSize" : "kSize");
for (const Type* type : LowerType(struct_type)) { header_out() << ", TORQUE_GENERATED_"
if (!first) { << CapifyStringWithUnderscores(class_type->name())
header_out() << ", "; << "_FIELDS)\n";
} header_out() << " };\n";
first = false; } else if (!class_type->nspace()->IsDefaultNamespace()) {
header_out() << type->GetGeneratedTypeName(); ReportError(
"extern classes are currently only supported in the default and test "
"namespaces");
} }
header_out() << "> Flatten() const {\n" return;
<< " return std::tuple_cat("; }
first = true; const StructType* struct_type = StructType::DynamicCast(alias->type());
for (auto& field : struct_type->fields()) { if (!struct_type) return;
if (!first) { const std::string& name = struct_type->name();
header_out() << ", "; header_out() << " struct " << name << " {\n";
} for (auto& field : struct_type->fields()) {
first = false; header_out() << " " << field.name_and_type.type->GetGeneratedTypeName();
if (field.name_and_type.type->IsStructType()) { header_out() << " " << field.name_and_type.name << ";\n";
header_out() << field.name_and_type.name << ".Flatten()"; }
} else { header_out() << "\n std::tuple<";
header_out() << "std::make_tuple(" << field.name_and_type.name << ")"; bool first = true;
} for (const Type* type : LowerType(struct_type)) {
if (!first) {
header_out() << ", ";
}
first = false;
header_out() << type->GetGeneratedTypeName();
}
header_out() << "> Flatten() const {\n"
<< " return std::tuple_cat(";
first = true;
for (auto& field : struct_type->fields()) {
if (!first) {
header_out() << ", ";
}
first = false;
if (field.name_and_type.type->IsStructType()) {
header_out() << field.name_and_type.name << ".Flatten()";
} else {
header_out() << "std::make_tuple(" << field.name_and_type.name << ")";
} }
header_out() << ");\n";
header_out() << " }\n";
header_out() << " };\n";
} }
header_out() << ");\n";
header_out() << " }\n";
header_out() << " };\n";
} }
VisitResult ImplementationVisitor::InlineMacro( VisitResult ImplementationVisitor::InlineMacro(
......
...@@ -231,14 +231,7 @@ class Stack { ...@@ -231,14 +231,7 @@ class Stack {
void Poke(BottomOffset from_bottom, T x) { void Poke(BottomOffset from_bottom, T x) {
elements_.at(from_bottom.offset) = std::move(x); elements_.at(from_bottom.offset) = std::move(x);
} }
void Push(T x) { void Push(T x) { elements_.push_back(std::move(x)); }
// Manually increasing the std::vector capacity is a workaround for an
// ASAN-container-overflow false positive.
if (elements_.size() == elements_.capacity()) {
elements_.reserve(2 * elements_.size() + 1);
}
elements_.push_back(std::move(x));
}
StackRange TopRange(size_t slot_count) const { StackRange TopRange(size_t slot_count) const {
DCHECK_GE(Size(), slot_count); DCHECK_GE(Size(), slot_count);
return StackRange{AboveTop() - slot_count, AboveTop()}; return StackRange{AboveTop() - slot_count, AboveTop()};
......
...@@ -823,6 +823,59 @@ namespace test { ...@@ -823,6 +823,59 @@ namespace test {
assert(a.b.GetX() == 2); assert(a.b.GetX() == 2);
} }
@noVerifier
extern class TestClassWithAllTypes extends JSObject {
a: int8;
b: uint8;
b2: uint8;
b3: uint8;
c: int16;
d: uint16;
e: int32;
f: uint32;
g: RawPtr;
h: intptr;
i: uintptr;
}
// This class should throw alignment errors if @if decorators aren't
// working.
@noVerifier
extern class PreprocessingTest extends JSObject {
@if(FALSE_FOR_TESTING) a: int8;
@if(TRUE_FOR_TESTING) a: int16;
b: int16;
d: int32;
@ifnot(TRUE_FOR_TESTING) e: int8;
@ifnot(FALSE_FOR_TESTING) f: int16;
g: int16;
h: int32;
}
@export
macro TestClassWithAllTypesLoadsAndStores(
t: TestClassWithAllTypes, r: RawPtr, v1: int8, v2: uint8, v3: int16,
v4: uint16) {
t.a = v1;
t.b = v2;
t.c = v3;
t.d = v4;
t.e = 0;
t.f = 0;
t.g = r;
t.h = 0;
t.i = 0;
t.a = t.a;
t.b = t.b;
t.c = t.c;
t.d = t.d;
t.e = t.e;
t.f = t.f;
t.g = t.g;
t.h = t.h;
t.i = t.i;
}
class InternalClass { class InternalClass {
Flip() labels NotASmi { Flip() labels NotASmi {
const tmp = Cast<Smi>(this.b) otherwise NotASmi; const tmp = Cast<Smi>(this.b) otherwise NotASmi;
...@@ -903,6 +956,24 @@ namespace test { ...@@ -903,6 +956,24 @@ namespace test {
check(array.b == 9); check(array.b == 9);
} }
type Baztype = Foo | FooType;
@abstract
@noVerifier
extern class Foo extends JSObject {
fooField: FooType;
}
@noVerifier
extern class Bar extends Foo {
barField: Bartype;
bazfield: Baztype;
}
type Bartype = FooType;
type FooType = Smi | Bar;
@export @export
macro TestStaticAssert() { macro TestStaticAssert() {
StaticAssert(1 + 2 == 3); StaticAssert(1 + 2 == 3);
......
...@@ -13,83 +13,17 @@ namespace torque { ...@@ -13,83 +13,17 @@ namespace torque {
namespace { namespace {
// This is a simplified version of the basic Torque type definitions. TorqueCompilerResult TestCompileTorque(const std::string& source) {
// Some class types are replaced by abstact types to keep it self-contained and
// small.
constexpr const char* kTestTorquePrelude = R"(
type void;
type never;
type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';
@abstract
extern class HeapObject extends Tagged {
map: Map;
}
type Map extends HeapObject generates 'TNode<Map>';
type Object = Smi | HeapObject;
type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
type JSObject extends JSReceiver generates 'TNode<JSObject>';
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t';
type int31 extends int32
generates 'TNode<Int32T>' constexpr 'int31_t';
type uint31 extends uint32
generates 'TNode<Uint32T>' constexpr 'uint31_t';
type int16 extends int31
generates 'TNode<Int16T>' constexpr 'int16_t';
type uint16 extends uint31
generates 'TNode<Uint16T>' constexpr 'uint16_t';
type int8 extends int16 generates 'TNode<Int8T>' constexpr 'int8_t';
type uint8 extends uint16
generates 'TNode<Uint8T>' constexpr 'uint8_t';
type int64 generates 'TNode<Int64T>' constexpr 'int64_t';
type intptr generates 'TNode<IntPtrT>' constexpr 'intptr_t';
type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t';
type float32 generates 'TNode<Float32T>' constexpr 'float';
type float64 generates 'TNode<Float64T>' constexpr 'double';
type bool generates 'TNode<BoolT>' constexpr 'bool';
type bint generates 'TNode<BInt>' constexpr 'BInt';
type string constexpr 'const char*';
type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
type Code extends HeapObject generates 'TNode<Code>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context;
)";
TorqueCompilerResult TestCompileTorque(std::string source) {
TorqueCompilerOptions options; TorqueCompilerOptions options;
options.output_directory = ""; options.output_directory = "";
options.collect_language_server_data = false; options.collect_language_server_data = false;
options.force_assert_statements = false; options.force_assert_statements = false;
source = kTestTorquePrelude + source;
return CompileTorque(source, options); return CompileTorque(source, options);
} }
void ExpectSuccessfulCompilation(std::string source) {
TorqueCompilerResult result = TestCompileTorque(std::move(source));
std::vector<std::string> messages;
for (const auto& message : result.messages) {
messages.push_back(message.message);
}
EXPECT_EQ(messages, std::vector<std::string>{});
}
template <class T>
void ExpectFailingCompilation(
std::string source, ::testing::PolymorphicMatcher<T> message_pattern) {
TorqueCompilerResult result = TestCompileTorque(std::move(source));
ASSERT_FALSE(result.messages.empty());
EXPECT_THAT(result.messages[0].message, message_pattern);
}
} // namespace } // namespace
TEST(Torque, Prelude) { ExpectSuccessfulCompilation(""); }
TEST(Torque, StackDeleteRange) { TEST(Torque, StackDeleteRange) {
Stack<int> stack = {1, 2, 3, 4, 5, 6, 7}; Stack<int> stack = {1, 2, 3, 4, 5, 6, 7};
stack.DeleteRange(StackRange{BottomOffset{2}, BottomOffset{4}}); stack.DeleteRange(StackRange{BottomOffset{2}, BottomOffset{4}});
...@@ -99,112 +33,31 @@ TEST(Torque, StackDeleteRange) { ...@@ -99,112 +33,31 @@ TEST(Torque, StackDeleteRange) {
using ::testing::HasSubstr; using ::testing::HasSubstr;
TEST(Torque, TypeNamingConventionLintError) { TEST(Torque, TypeNamingConventionLintError) {
ExpectFailingCompilation(R"( std::string source = R"(
type void;
type never;
type foo generates 'TNode<Foo>'; type foo generates 'TNode<Foo>';
)", )";
HasSubstr("\"foo\""));
}
TEST(Torque, StructNamingConventionLintError) { const TorqueCompilerResult result = TestCompileTorque(source);
ExpectFailingCompilation(R"(
struct foo {}
)",
HasSubstr("\"foo\""));
}
TEST(Torque, ClassDefinition) { ASSERT_EQ(result.messages.size(), static_cast<size_t>(1));
ExpectSuccessfulCompilation(R"( EXPECT_THAT(result.messages[0].message, HasSubstr("\"foo\""));
extern class TestClassWithAllTypes extends HeapObject {
a: int8;
b: uint8;
b2: uint8;
b3: uint8;
c: int16;
d: uint16;
e: int32;
f: uint32;
g: RawPtr;
h: intptr;
i: uintptr;
}
macro TestClassWithAllTypesLoadsAndStores(
t: TestClassWithAllTypes, r: RawPtr, v1: int8, v2: uint8, v3: int16,
v4: uint16, v5: int32, v6: uint32, v7: intptr, v8: uintptr) {
t.a = v1;
t.b = v2;
t.c = v3;
t.d = v4;
t.e = v5;
t.f = v6;
t.g = r;
t.h = v7;
t.i = v8;
t.a = t.a;
t.b = t.b;
t.c = t.c;
t.d = t.d;
t.e = t.e;
t.f = t.f;
t.g = t.g;
t.h = t.h;
t.i = t.i;
}
)");
} }
TEST(Torque, TypeDeclarationOrder) { TEST(Torque, StructNamingConventionLintError) {
ExpectSuccessfulCompilation(R"( const std::string source = R"(
type Baztype = Foo | FooType; type void;
type never;
@abstract
@noVerifier
extern class Foo extends HeapObject {
fooField: FooType;
}
@noVerifier
extern class Bar extends Foo {
barField: Bartype;
bazfield: Baztype;
}
type Bartype = FooType; struct foo {}
)";
type FooType = Smi | Bar; const TorqueCompilerResult result = TestCompileTorque(source);
)");
}
TEST(Torque, ConditionalFields) { ASSERT_EQ(result.messages.size(), static_cast<size_t>(1));
// This class should throw alignment errors if @if decorators aren't EXPECT_THAT(result.messages[0].message, HasSubstr("\"foo\""));
// working.
ExpectSuccessfulCompilation(R"(
@noVerifier
extern class PreprocessingTest extends HeapObject {
@if(FALSE_FOR_TESTING) a: int8;
@if(TRUE_FOR_TESTING) a: int16;
b: int16;
d: int32;
@ifnot(TRUE_FOR_TESTING) e: int8;
@ifnot(FALSE_FOR_TESTING) f: int16;
g: int16;
h: int32;
}
)");
ExpectFailingCompilation(R"(
@noVerifier
extern class PreprocessingTest extends HeapObject {
@if(TRUE_FOR_TESTING) a: int8;
@if(FALSE_FOR_TESTING) a: int16;
b: int16;
d: int32;
@ifnot(FALSE_FOR_TESTING) e: int8;
@ifnot(TRUE_FOR_TESTING) f: int16;
g: int16;
h: int32;
}
)",
HasSubstr("aligned"));
} }
} // namespace torque } // namespace torque
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment