Commit 4257fdea authored by jpp's avatar jpp Committed by Commit bot

V8. ASM-2-WASM. Another asm-types.h revision.

BUG=

Review-Url: https://codereview.chromium.org/2078053002
Cr-Commit-Position: refs/heads/master@{#37110}
parent 0b177bc0
......@@ -11,8 +11,14 @@ namespace internal {
namespace wasm {
AsmCallableType* AsmType::AsCallableType() {
if (AsValueType() != nullptr) {
return nullptr;
}
DCHECK(this->AsFunctionType() != nullptr ||
this->AsOverloadedFunctionType() != nullptr);
this->AsOverloadedFunctionType() != nullptr ||
this->AsFFIType() != nullptr ||
this->AsFunctionTableType() != nullptr);
return reinterpret_cast<AsmCallableType*>(this);
}
......@@ -165,7 +171,8 @@ class AsmFroundType final : public AsmFunctionType {
explicit AsmFroundType(Zone* zone)
: AsmFunctionType(zone, AsmType::Float()) {}
AsmType* ValidateCall(AsmType* function_type) override;
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
};
} // namespace
......@@ -174,13 +181,13 @@ AsmType* AsmType::FroundType(Zone* zone) {
return reinterpret_cast<AsmType*>(Fround);
}
AsmType* AsmFroundType::ValidateCall(AsmType* function_type) {
auto* callable = function_type->AsFunctionType();
if (callable->Arguments().size() != 1) {
AsmType* AsmFroundType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (args.size() != 1) {
return AsmType::None();
}
auto* arg = callable->Arguments()[0];
auto* arg = args[0];
if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
!arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
return AsmType::None();
......@@ -203,22 +210,18 @@ class AsmMinMaxType final : public AsmFunctionType {
AddArgument(src);
}
AsmType* ValidateCall(AsmType* function_type) override {
auto* callable = function_type->AsFunctionType();
if (callable == nullptr) {
return nullptr;
}
if (!ReturnType()->IsExactly(callable->ReturnType())) {
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override {
if (!ReturnType()->IsExactly(return_type)) {
return AsmType::None();
}
if (callable->Arguments().size() < 2) {
if (args.size() < 2) {
return AsmType::None();
}
for (size_t ii = 0; ii < Arguments().size(); ++ii) {
if (!Arguments()[0]->IsExactly(callable->Arguments()[ii])) {
if (!Arguments()[0]->IsExactly(args[ii])) {
return AsmType::None();
}
}
......@@ -235,22 +238,29 @@ AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
return reinterpret_cast<AsmType*>(MinMax);
}
AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) {
auto* callable = function_type->AsFunctionType();
if (callable == nullptr) {
return nullptr;
AsmType* AsmFFIType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
for (size_t ii = 0; ii < args.size(); ++ii) {
if (!args[ii]->IsA(AsmType::Extern())) {
return AsmType::None();
}
}
if (!return_type_->IsExactly(callable->return_type_)) {
return return_type;
}
AsmType* AsmFunctionType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
if (!return_type_->IsExactly(return_type)) {
return AsmType::None();
}
if (args_.size() != callable->args_.size()) {
if (args_.size() != args.size()) {
return AsmType::None();
}
for (size_t ii = 0; ii < args_.size(); ++ii) {
if (!args_[ii]->IsExactly(callable->args_[ii])) {
if (!args_[ii]->IsExactly(args[ii])) {
return AsmType::None();
}
}
......@@ -271,15 +281,11 @@ std::string AsmOverloadedFunctionType::Name() {
return ret;
}
AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) {
auto* callable = function_type->AsFunctionType();
if (callable == nullptr) {
return AsmType::None();
}
AsmType* AsmOverloadedFunctionType::ValidateCall(
AsmType* return_type, const ZoneVector<AsmType*>& args) {
for (size_t ii = 0; ii < overloads_.size(); ++ii) {
auto* validated_type =
overloads_[ii]->AsCallableType()->ValidateCall(function_type);
overloads_[ii]->AsCallableType()->ValidateCall(return_type, args);
if (validated_type != AsmType::None()) {
return validated_type;
}
......@@ -293,6 +299,21 @@ void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
overloads_.push_back(overload);
}
AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature)
: length_(length), signature_(signature) {
DCHECK(signature_ != nullptr);
DCHECK(signature_->AsFunctionType() != nullptr);
}
std::string AsmFunctionTableType::Name() {
return signature_->Name() + "[" + std::to_string(length_) + "]";
}
AsmType* AsmFunctionTableType::ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) {
return signature_->AsCallableType()->ValidateCall(return_type, args);
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -16,8 +16,10 @@ namespace internal {
namespace wasm {
class AsmType;
class AsmFFIType;
class AsmFunctionType;
class AsmOverloadedFunctionType;
class AsmFunctionTableType;
// List of V(CamelName, string_name, number, parent_types)
#define FOR_EACH_ASM_VALUE_TYPE_LIST(V) \
......@@ -47,15 +49,17 @@ class AsmOverloadedFunctionType;
V(Float32Array, "Float32Array", 20, kAsmHeap) \
V(Float64Array, "Float64Array", 21, kAsmHeap) \
/* Pseudo-types used in representing heap access for fp types.*/ \
V(FloatishDoubleQ, "floatish|double?", 23, kAsmFloatish | kAsmDoubleQ) \
V(FloatQDoubleQ, "float?|double?", 24, kAsmFloatQ | kAsmDoubleQ) \
V(FloatishDoubleQ, "floatish|double?", 22, kAsmFloatish | kAsmDoubleQ) \
V(FloatQDoubleQ, "float?|double?", 23, kAsmFloatQ | kAsmDoubleQ) \
/* None is used to represent errors in the type checker. */ \
V(None, "<none>", 31, 0)
// List of V(CamelName)
#define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \
V(FunctionType) \
V(OverloadedFunctionType)
V(FFIType) \
V(OverloadedFunctionType) \
V(FunctionTableType)
class AsmValueType {
public:
......@@ -101,7 +105,8 @@ class AsmValueType {
class AsmCallableType : public ZoneObject {
public:
virtual std::string Name() = 0;
virtual AsmType* ValidateCall(AsmType* function_type) = 0;
virtual AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) = 0;
#define DECLARE_CAST(CamelName) \
virtual Asm##CamelName* As##CamelName() { return nullptr; }
......@@ -135,7 +140,8 @@ class AsmFunctionType : public AsmCallableType {
friend AsmType;
std::string Name() override;
AsmType* ValidateCall(AsmType* function_type) override;
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
AsmType* return_type_;
ZoneVector<AsmType*> args_;
......@@ -157,13 +163,52 @@ class AsmOverloadedFunctionType final : public AsmCallableType {
explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {}
std::string Name() override;
AsmType* ValidateCall(AsmType* function_type) override;
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
ZoneVector<AsmType*> overloads_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AsmOverloadedFunctionType);
};
class AsmFFIType final : public AsmCallableType {
public:
AsmFFIType* AsFFIType() override { return this; }
std::string Name() override { return "Function"; }
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
private:
friend AsmType;
AsmFFIType() = default;
DISALLOW_COPY_AND_ASSIGN(AsmFFIType);
};
class AsmFunctionTableType : public AsmCallableType {
public:
AsmFunctionTableType* AsFunctionTableType() override { return this; }
std::string Name() override;
AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
size_t length() const { return length_; }
private:
friend class AsmType;
AsmFunctionTableType(size_t length, AsmType* signature);
size_t length_;
AsmType* signature_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AsmFunctionTableType);
};
class AsmType {
public:
#define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \
......@@ -205,6 +250,19 @@ class AsmType {
// The (variadic) type for min and max.
static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src);
// The type for foreign functions.
static AsmType* FFIType(Zone* zone) {
auto* f = new (zone) AsmFFIType();
return reinterpret_cast<AsmType*>(f);
}
// The type for function tables.
static AsmType* FunctionTableType(Zone* zone, size_t length,
AsmType* signature) {
auto* f = new (zone) AsmFunctionTableType(length, signature);
return reinterpret_cast<AsmType*>(f);
}
std::string Name();
// IsExactly returns true if this is the exact same type as that. For
// non-value types (e.g., callables), this returns this == that.
......@@ -221,12 +279,43 @@ class AsmType {
this == AsmType::Signed() || this == AsmType::Float();
}
// Converts this to the corresponding valid argument type.
AsmType* ToReturnType() {
if (this->IsA(AsmType::Signed())) {
return AsmType::Signed();
}
if (this->IsA(AsmType::Double())) {
return AsmType::Double();
}
if (this->IsA(AsmType::Float())) {
return AsmType::Float();
}
if (this->IsA(AsmType::Void())) {
return AsmType::Void();
}
return AsmType::None();
}
// Types allowed to be parameters in asm functions.
bool IsParameterType() {
return this == AsmType::Double() || this == AsmType::Int() ||
this == AsmType::Float();
}
// Converts this to the corresponding valid argument type.
AsmType* ToParameterType() {
if (this->IsA(AsmType::Int())) {
return AsmType::Int();
}
if (this->IsA(AsmType::Double())) {
return AsmType::Double();
}
if (this->IsA(AsmType::Float())) {
return AsmType::Float();
}
return AsmType::None();
}
// Types allowed to be compared using the comparison operators.
bool IsComparableType() {
return this == AsmType::Double() || this == AsmType::Signed() ||
......
......@@ -225,8 +225,14 @@ TEST_F(AsmTypeTest, Names) {
StrEq("(int, int...) -> signed"));
EXPECT_THAT(Type::MinMaxType(zone(), Type::Float(), Type::Floatish())->Name(),
StrEq("(floatish, floatish...) -> float"));
EXPECT_THAT(Type::MinMaxType(zone(), Type::Double(), Type::Double())->Name(),
StrEq("(double, double...) -> double"));
EXPECT_THAT(Type::MinMaxType(zone(), Type::Double(), Type::DoubleQ())->Name(),
StrEq("(double?, double?...) -> double"));
EXPECT_THAT(Type::FFIType(zone())->Name(), StrEq("Function"));
auto* ft =
Type::FunctionTableType(zone(), 15, Function(Type::Double)(Type::Int));
EXPECT_THAT(ft->Name(), StrEq("(int) -> double[15]"));
}
TEST_F(AsmTypeTest, IsExactly) {
......@@ -240,6 +246,8 @@ TEST_F(AsmTypeTest, IsExactly) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
for (size_t ii = 0; ii < arraysize(test_types); ++ii) {
......@@ -263,6 +271,8 @@ TEST_F(AsmTypeTest, IsA) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
for (size_t ii = 0; ii < arraysize(test_types); ++ii) {
......@@ -284,13 +294,21 @@ TEST_F(AsmTypeTest, ValidateCall) {
auto* iiii2s =
Function(Type::Signed)(Type::Int, Type::Int, Type::Int, Type::Int);
EXPECT_EQ(Type::Signed(),
min_max_int->AsCallableType()->ValidateCall(min_max_int));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(ii2s));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(iii2s));
EXPECT_EQ(Type::Signed(),
min_max_int->AsCallableType()->ValidateCall(iiii2s));
EXPECT_EQ(Type::None(), min_max_int->AsCallableType()->ValidateCall(i2s));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(
min_max_int->AsFunctionType()->ReturnType(),
min_max_int->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(
ii2s->AsFunctionType()->ReturnType(),
ii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(
iii2s->AsFunctionType()->ReturnType(),
iii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max_int->AsCallableType()->ValidateCall(
iiii2s->AsFunctionType()->ReturnType(),
iiii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), min_max_int->AsCallableType()->ValidateCall(
i2s->AsFunctionType()->ReturnType(),
i2s->AsFunctionType()->Arguments()));
auto* min_max_double =
Type::MinMaxType(zone(), Type::Double(), Type::Double());
......@@ -300,49 +318,88 @@ TEST_F(AsmTypeTest, ValidateCall) {
Function(Type::Double)(Type::Double, Type::Double, Type::Double);
auto* dddd2d = Function(Type::Double)(Type::Double, Type::Double,
Type::Double, Type::Double);
EXPECT_EQ(Type::Double(),
min_max_double->AsCallableType()->ValidateCall(min_max_double));
EXPECT_EQ(Type::Double(),
min_max_double->AsCallableType()->ValidateCall(dd2d));
EXPECT_EQ(Type::Double(),
min_max_double->AsCallableType()->ValidateCall(ddd2d));
EXPECT_EQ(Type::Double(),
min_max_double->AsCallableType()->ValidateCall(dddd2d));
EXPECT_EQ(Type::None(), min_max_double->AsCallableType()->ValidateCall(d2d));
EXPECT_EQ(Type::Double(), min_max_double->AsCallableType()->ValidateCall(
min_max_double->AsFunctionType()->ReturnType(),
min_max_double->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max_double->AsCallableType()->ValidateCall(
dd2d->AsFunctionType()->ReturnType(),
dd2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max_double->AsCallableType()->ValidateCall(
ddd2d->AsFunctionType()->ReturnType(),
ddd2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max_double->AsCallableType()->ValidateCall(
dddd2d->AsFunctionType()->ReturnType(),
dddd2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), min_max_double->AsCallableType()->ValidateCall(
d2d->AsFunctionType()->ReturnType(),
d2d->AsFunctionType()->Arguments()));
auto* min_max = Overload(min_max_int, min_max_double);
EXPECT_EQ(Type::None(), min_max->AsCallableType()->ValidateCall(min_max));
EXPECT_EQ(Type::None(), min_max->AsCallableType()->ValidateCall(i2s));
EXPECT_EQ(Type::None(), min_max->AsCallableType()->ValidateCall(d2d));
EXPECT_EQ(Type::Signed(),
min_max->AsCallableType()->ValidateCall(min_max_int));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(ii2s));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(iii2s));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(iiii2s));
EXPECT_EQ(Type::Double(),
min_max->AsCallableType()->ValidateCall(min_max_double));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(dd2d));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(ddd2d));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(dddd2d));
EXPECT_EQ(Type::None(), min_max->AsCallableType()->ValidateCall(
i2s->AsFunctionType()->ReturnType(),
i2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), min_max->AsCallableType()->ValidateCall(
d2d->AsFunctionType()->ReturnType(),
d2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(
min_max_int->AsFunctionType()->ReturnType(),
min_max_int->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(
ii2s->AsFunctionType()->ReturnType(),
ii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(
iii2s->AsFunctionType()->ReturnType(),
iii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Signed(), min_max->AsCallableType()->ValidateCall(
iiii2s->AsFunctionType()->ReturnType(),
iiii2s->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(
min_max_double->AsFunctionType()->ReturnType(),
min_max_double->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(
dd2d->AsFunctionType()->ReturnType(),
dd2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(
ddd2d->AsFunctionType()->ReturnType(),
ddd2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), min_max->AsCallableType()->ValidateCall(
dddd2d->AsFunctionType()->ReturnType(),
dddd2d->AsFunctionType()->Arguments()));
auto* fround = Type::FroundType(zone());
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::Floatish)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::FloatQ)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::Float)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::DoubleQ)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::Double)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::Signed)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::Unsigned)));
EXPECT_EQ(Type::Float(), fround->AsCallableType()->ValidateCall(
Function(Type::Float)(Type::FixNum)));
ZoneVector<AsmType*> arg(zone());
arg.push_back(Type::Floatish());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::FloatQ());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::Float());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::DoubleQ());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::Double());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::Signed());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::Unsigned());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
arg.clear();
arg.push_back(Type::FixNum());
EXPECT_EQ(Type::Float(),
fround->AsCallableType()->ValidateCall(Type::Float(), arg));
auto* idf2v = Function(Type::Void)(Type::Int, Type::Double, Type::Float);
auto* i2d = Function(Type::Double)(Type::Int);
......@@ -351,12 +408,88 @@ TEST_F(AsmTypeTest, ValidateCall) {
auto* idif2i =
Function(Type::Int)(Type::Int, Type::Double, Type::Int, Type::Float);
auto* overload = Overload(idf2v, i2f, /*i2d missing, */ fi2d, idif2i);
EXPECT_EQ(Type::Void(), overload->AsCallableType()->ValidateCall(idf2v));
EXPECT_EQ(Type::Float(), overload->AsCallableType()->ValidateCall(i2f));
EXPECT_EQ(Type::Double(), overload->AsCallableType()->ValidateCall(fi2d));
EXPECT_EQ(Type::Int(), overload->AsCallableType()->ValidateCall(idif2i));
EXPECT_EQ(Type::None(), overload->AsCallableType()->ValidateCall(i2d));
EXPECT_EQ(Type::None(), i2f->AsCallableType()->ValidateCall(i2d));
EXPECT_EQ(Type::Void(), overload->AsCallableType()->ValidateCall(
idf2v->AsFunctionType()->ReturnType(),
idf2v->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Float(), overload->AsCallableType()->ValidateCall(
i2f->AsFunctionType()->ReturnType(),
i2f->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Double(), overload->AsCallableType()->ValidateCall(
fi2d->AsFunctionType()->ReturnType(),
fi2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::Int(), overload->AsCallableType()->ValidateCall(
idif2i->AsFunctionType()->ReturnType(),
idif2i->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), overload->AsCallableType()->ValidateCall(
i2d->AsFunctionType()->ReturnType(),
i2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), i2f->AsCallableType()->ValidateCall(
i2d->AsFunctionType()->ReturnType(),
i2d->AsFunctionType()->Arguments()));
auto* ffi = Type::FFIType(zone());
AsmType* (*kReturnTypes[])() = {
Type::Void, Type::Double, Type::Signed,
};
AsmType* (*kParameterTypes[])() = {
Type::Double, Type::Signed, Type::FixNum,
};
for (size_t ii = 0; ii < arraysize(kReturnTypes); ++ii) {
for (size_t jj = 0; jj < arraysize(kParameterTypes); ++jj) {
auto* f = Function(kReturnTypes[ii])(kParameterTypes[jj]);
EXPECT_EQ(kReturnTypes[ii](), ffi->AsCallableType()->ValidateCall(
f->AsFunctionType()->ReturnType(),
f->AsFunctionType()->Arguments()))
<< kReturnTypes[ii]()->Name();
// Call with non-parameter type type should fail.
f = Function(kReturnTypes[ii])(kParameterTypes[jj], Type::Int);
EXPECT_EQ(Type::None(), ffi->AsCallableType()->ValidateCall(
f->AsFunctionType()->ReturnType(),
f->AsFunctionType()->Arguments()))
<< kReturnTypes[ii]()->Name();
}
}
auto* ft0 = Type::FunctionTableType(zone(), 10, fi2d);
EXPECT_EQ(Type::Double(), ft0->AsCallableType()->ValidateCall(
fi2d->AsFunctionType()->ReturnType(),
fi2d->AsFunctionType()->Arguments()));
EXPECT_EQ(Type::None(), ft0->AsCallableType()->ValidateCall(
i2d->AsFunctionType()->ReturnType(),
i2d->AsFunctionType()->Arguments()));
}
TEST_F(AsmTypeTest, ToReturnType) {
std::unordered_map<AsmType*, AsmType*> kToReturnType = {
{Type::Signed(), Type::Signed()}, {Type::FixNum(), Type::Signed()},
{Type::Double(), Type::Double()}, {Type::Float(), Type::Float()},
{Type::Void(), Type::Void()},
};
Type* test_types[] = {
#define CREATE(CamelName, string_name, number, parent_types) Type::CamelName(),
FOR_EACH_ASM_VALUE_TYPE_LIST(CREATE)
#undef CREATE
Function(Type::Int)(Type::Double),
Function(Type::Int)(Type::DoubleQ),
Overload(Function(Type::Int)(Type::Double)),
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
for (size_t ii = 0; ii < arraysize(test_types); ++ii) {
auto* return_type = Type::None();
auto to_return_type_iter = kToReturnType.find(test_types[ii]);
if (to_return_type_iter != kToReturnType.end()) {
return_type = to_return_type_iter->second;
}
EXPECT_EQ(return_type, test_types[ii]->ToReturnType())
<< return_type->Name() << " != " << test_types[ii]->ToReturnType();
}
}
TEST_F(AsmTypeTest, IsReturnType) {
......@@ -370,6 +503,8 @@ TEST_F(AsmTypeTest, IsReturnType) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
std::unordered_set<Type*> return_types{
......@@ -384,6 +519,39 @@ TEST_F(AsmTypeTest, IsReturnType) {
}
}
TEST_F(AsmTypeTest, ToParameterType) {
std::unordered_map<AsmType*, AsmType*> kToParameterType = {
{Type::Int(), Type::Int()}, {Type::Signed(), Type::Int()},
{Type::Unsigned(), Type::Int()}, {Type::FixNum(), Type::Int()},
{Type::Double(), Type::Double()}, {Type::Float(), Type::Float()},
};
Type* test_types[] = {
#define CREATE(CamelName, string_name, number, parent_types) Type::CamelName(),
FOR_EACH_ASM_VALUE_TYPE_LIST(CREATE)
#undef CREATE
Function(Type::Int)(Type::Double),
Function(Type::Int)(Type::DoubleQ),
Overload(Function(Type::Int)(Type::Double)),
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
for (size_t ii = 0; ii < arraysize(test_types); ++ii) {
auto* parameter_type = Type::None();
auto to_parameter_type_iter = kToParameterType.find(test_types[ii]);
if (to_parameter_type_iter != kToParameterType.end()) {
parameter_type = to_parameter_type_iter->second;
}
EXPECT_EQ(parameter_type, test_types[ii]->ToParameterType())
<< parameter_type->Name()
<< " != " << test_types[ii]->ToParameterType();
}
}
TEST_F(AsmTypeTest, IsParameterType) {
Type* test_types[] = {
#define CREATE(CamelName, string_name, number, parent_types) Type::CamelName(),
......@@ -395,6 +563,8 @@ TEST_F(AsmTypeTest, IsParameterType) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
std::unordered_set<Type*> parameter_types{
......@@ -421,6 +591,8 @@ TEST_F(AsmTypeTest, IsComparableType) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
std::unordered_set<Type*> comparable_types{
......@@ -447,6 +619,8 @@ TEST_F(AsmTypeTest, ElementSizeInBytes) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
auto ElementSizeInBytesForType = [](Type* type) -> int32_t {
......@@ -483,6 +657,8 @@ TEST_F(AsmTypeTest, LoadType) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
auto LoadTypeForType = [](Type* type) -> Type* {
......@@ -519,6 +695,8 @@ TEST_F(AsmTypeTest, StoreType) {
Function(Type::Int)(Type::Int, Type::Int),
Type::MinMaxType(zone(), Type::Signed(), Type::Int()),
Function(Type::Int)(Type::Float), Type::FroundType(zone()),
Type::FFIType(zone()),
Type::FunctionTableType(zone(), 10, Function(Type::Void)()),
};
auto StoreTypeForType = [](Type* type) -> Type* {
......
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