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 { ...@@ -11,8 +11,14 @@ namespace internal {
namespace wasm { namespace wasm {
AsmCallableType* AsmType::AsCallableType() { AsmCallableType* AsmType::AsCallableType() {
if (AsValueType() != nullptr) {
return nullptr;
}
DCHECK(this->AsFunctionType() != nullptr || DCHECK(this->AsFunctionType() != nullptr ||
this->AsOverloadedFunctionType() != nullptr); this->AsOverloadedFunctionType() != nullptr ||
this->AsFFIType() != nullptr ||
this->AsFunctionTableType() != nullptr);
return reinterpret_cast<AsmCallableType*>(this); return reinterpret_cast<AsmCallableType*>(this);
} }
...@@ -165,7 +171,8 @@ class AsmFroundType final : public AsmFunctionType { ...@@ -165,7 +171,8 @@ class AsmFroundType final : public AsmFunctionType {
explicit AsmFroundType(Zone* zone) explicit AsmFroundType(Zone* zone)
: AsmFunctionType(zone, AsmType::Float()) {} : AsmFunctionType(zone, AsmType::Float()) {}
AsmType* ValidateCall(AsmType* function_type) override; AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
}; };
} // namespace } // namespace
...@@ -174,13 +181,13 @@ AsmType* AsmType::FroundType(Zone* zone) { ...@@ -174,13 +181,13 @@ AsmType* AsmType::FroundType(Zone* zone) {
return reinterpret_cast<AsmType*>(Fround); return reinterpret_cast<AsmType*>(Fround);
} }
AsmType* AsmFroundType::ValidateCall(AsmType* function_type) { AsmType* AsmFroundType::ValidateCall(AsmType* return_type,
auto* callable = function_type->AsFunctionType(); const ZoneVector<AsmType*>& args) {
if (callable->Arguments().size() != 1) { if (args.size() != 1) {
return AsmType::None(); return AsmType::None();
} }
auto* arg = callable->Arguments()[0]; auto* arg = args[0];
if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) && if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
!arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) { !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
return AsmType::None(); return AsmType::None();
...@@ -203,22 +210,18 @@ class AsmMinMaxType final : public AsmFunctionType { ...@@ -203,22 +210,18 @@ class AsmMinMaxType final : public AsmFunctionType {
AddArgument(src); AddArgument(src);
} }
AsmType* ValidateCall(AsmType* function_type) override { AsmType* ValidateCall(AsmType* return_type,
auto* callable = function_type->AsFunctionType(); const ZoneVector<AsmType*>& args) override {
if (callable == nullptr) { if (!ReturnType()->IsExactly(return_type)) {
return nullptr;
}
if (!ReturnType()->IsExactly(callable->ReturnType())) {
return AsmType::None(); return AsmType::None();
} }
if (callable->Arguments().size() < 2) { if (args.size() < 2) {
return AsmType::None(); return AsmType::None();
} }
for (size_t ii = 0; ii < Arguments().size(); ++ii) { 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(); return AsmType::None();
} }
} }
...@@ -235,22 +238,29 @@ AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) { ...@@ -235,22 +238,29 @@ AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
return reinterpret_cast<AsmType*>(MinMax); return reinterpret_cast<AsmType*>(MinMax);
} }
AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) { AsmType* AsmFFIType::ValidateCall(AsmType* return_type,
auto* callable = function_type->AsFunctionType(); const ZoneVector<AsmType*>& args) {
if (callable == nullptr) { for (size_t ii = 0; ii < args.size(); ++ii) {
return nullptr; 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(); return AsmType::None();
} }
if (args_.size() != callable->args_.size()) { if (args_.size() != args.size()) {
return AsmType::None(); return AsmType::None();
} }
for (size_t ii = 0; ii < args_.size(); ++ii) { 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(); return AsmType::None();
} }
} }
...@@ -271,15 +281,11 @@ std::string AsmOverloadedFunctionType::Name() { ...@@ -271,15 +281,11 @@ std::string AsmOverloadedFunctionType::Name() {
return ret; return ret;
} }
AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) { AsmType* AsmOverloadedFunctionType::ValidateCall(
auto* callable = function_type->AsFunctionType(); AsmType* return_type, const ZoneVector<AsmType*>& args) {
if (callable == nullptr) {
return AsmType::None();
}
for (size_t ii = 0; ii < overloads_.size(); ++ii) { for (size_t ii = 0; ii < overloads_.size(); ++ii) {
auto* validated_type = auto* validated_type =
overloads_[ii]->AsCallableType()->ValidateCall(function_type); overloads_[ii]->AsCallableType()->ValidateCall(return_type, args);
if (validated_type != AsmType::None()) { if (validated_type != AsmType::None()) {
return validated_type; return validated_type;
} }
...@@ -293,6 +299,21 @@ void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { ...@@ -293,6 +299,21 @@ void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
overloads_.push_back(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 wasm
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -16,8 +16,10 @@ namespace internal { ...@@ -16,8 +16,10 @@ namespace internal {
namespace wasm { namespace wasm {
class AsmType; class AsmType;
class AsmFFIType;
class AsmFunctionType; class AsmFunctionType;
class AsmOverloadedFunctionType; class AsmOverloadedFunctionType;
class AsmFunctionTableType;
// List of V(CamelName, string_name, number, parent_types) // List of V(CamelName, string_name, number, parent_types)
#define FOR_EACH_ASM_VALUE_TYPE_LIST(V) \ #define FOR_EACH_ASM_VALUE_TYPE_LIST(V) \
...@@ -47,15 +49,17 @@ class AsmOverloadedFunctionType; ...@@ -47,15 +49,17 @@ class AsmOverloadedFunctionType;
V(Float32Array, "Float32Array", 20, kAsmHeap) \ V(Float32Array, "Float32Array", 20, kAsmHeap) \
V(Float64Array, "Float64Array", 21, kAsmHeap) \ V(Float64Array, "Float64Array", 21, kAsmHeap) \
/* Pseudo-types used in representing heap access for fp types.*/ \ /* Pseudo-types used in representing heap access for fp types.*/ \
V(FloatishDoubleQ, "floatish|double?", 23, kAsmFloatish | kAsmDoubleQ) \ V(FloatishDoubleQ, "floatish|double?", 22, kAsmFloatish | kAsmDoubleQ) \
V(FloatQDoubleQ, "float?|double?", 24, kAsmFloatQ | kAsmDoubleQ) \ V(FloatQDoubleQ, "float?|double?", 23, kAsmFloatQ | kAsmDoubleQ) \
/* None is used to represent errors in the type checker. */ \ /* None is used to represent errors in the type checker. */ \
V(None, "<none>", 31, 0) V(None, "<none>", 31, 0)
// List of V(CamelName) // List of V(CamelName)
#define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \ #define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \
V(FunctionType) \ V(FunctionType) \
V(OverloadedFunctionType) V(FFIType) \
V(OverloadedFunctionType) \
V(FunctionTableType)
class AsmValueType { class AsmValueType {
public: public:
...@@ -101,7 +105,8 @@ class AsmValueType { ...@@ -101,7 +105,8 @@ class AsmValueType {
class AsmCallableType : public ZoneObject { class AsmCallableType : public ZoneObject {
public: public:
virtual std::string Name() = 0; 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) \ #define DECLARE_CAST(CamelName) \
virtual Asm##CamelName* As##CamelName() { return nullptr; } virtual Asm##CamelName* As##CamelName() { return nullptr; }
...@@ -135,7 +140,8 @@ class AsmFunctionType : public AsmCallableType { ...@@ -135,7 +140,8 @@ class AsmFunctionType : public AsmCallableType {
friend AsmType; friend AsmType;
std::string Name() override; std::string Name() override;
AsmType* ValidateCall(AsmType* function_type) override; AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
AsmType* return_type_; AsmType* return_type_;
ZoneVector<AsmType*> args_; ZoneVector<AsmType*> args_;
...@@ -157,13 +163,52 @@ class AsmOverloadedFunctionType final : public AsmCallableType { ...@@ -157,13 +163,52 @@ class AsmOverloadedFunctionType final : public AsmCallableType {
explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {} explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {}
std::string Name() override; std::string Name() override;
AsmType* ValidateCall(AsmType* function_type) override; AsmType* ValidateCall(AsmType* return_type,
const ZoneVector<AsmType*>& args) override;
ZoneVector<AsmType*> overloads_; ZoneVector<AsmType*> overloads_;
DISALLOW_IMPLICIT_CONSTRUCTORS(AsmOverloadedFunctionType); 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 { class AsmType {
public: public:
#define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \ #define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \
...@@ -205,6 +250,19 @@ class AsmType { ...@@ -205,6 +250,19 @@ class AsmType {
// The (variadic) type for min and max. // The (variadic) type for min and max.
static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src); 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(); std::string Name();
// IsExactly returns true if this is the exact same type as that. For // IsExactly returns true if this is the exact same type as that. For
// non-value types (e.g., callables), this returns this == that. // non-value types (e.g., callables), this returns this == that.
...@@ -221,12 +279,43 @@ class AsmType { ...@@ -221,12 +279,43 @@ class AsmType {
this == AsmType::Signed() || this == AsmType::Float(); 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. // Types allowed to be parameters in asm functions.
bool IsParameterType() { bool IsParameterType() {
return this == AsmType::Double() || this == AsmType::Int() || return this == AsmType::Double() || this == AsmType::Int() ||
this == AsmType::Float(); 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. // Types allowed to be compared using the comparison operators.
bool IsComparableType() { bool IsComparableType() {
return this == AsmType::Double() || this == AsmType::Signed() || return this == AsmType::Double() || this == AsmType::Signed() ||
......
This diff is collapsed.
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