Index: test/unittests/wasm/asm-types-unittest.cc |
diff --git a/test/unittests/wasm/asm-types-unittest.cc b/test/unittests/wasm/asm-types-unittest.cc |
index 49f4320a8e60f2d4e83cd2ac491c362f46bad432..9b29362537225f1978f96974816700f5183b1c47 100644 |
--- a/test/unittests/wasm/asm-types-unittest.cc |
+++ b/test/unittests/wasm/asm-types-unittest.cc |
@@ -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* { |