Chromium Code Reviews| Index: src/wasm/asm-types.cc |
| diff --git a/src/wasm/asm-types.cc b/src/wasm/asm-types.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ebbec87b998748f5d3999b42e8a8770fb9671b35 |
| --- /dev/null |
| +++ b/src/wasm/asm-types.cc |
| @@ -0,0 +1,270 @@ |
| +// Copyright 2016 the V8 project authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "src/v8.h" |
| + |
| +#include "src/wasm/asm-types.h" |
| + |
| +namespace v8 { |
| +namespace internal { |
| +namespace wasm { |
| + |
| +AsmCallableType* AsmType::AsCallableType() { |
| + DCHECK(this->AsFunctionType() != nullptr || |
| + this->AsOverloadedFunctionType() != nullptr); |
| + return reinterpret_cast<AsmCallableType*>(this); |
| +} |
| + |
| +std::string AsmType::Name() { |
| + AsmValueType* avt = this->AsValueType(); |
| + if (avt != nullptr) { |
| + switch (avt->Bitset()) { |
| +#define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \ |
| + case AsmValueType::kAsm##CamelName: \ |
| + return string_name; |
| + FOR_EACH_ASM_VALUE_TYPE_LIST(RETURN_TYPE_NAME) |
| +#undef RETURN_TYPE_NAME |
| + default: |
| + UNREACHABLE(); |
| + } |
| + } |
| + return reinterpret_cast<AsmCallableType*>(this)->Name(); |
| +} |
| + |
| +bool AsmType::IsExactly(AsmType* that) { |
| + // TODO(jpp): maybe this can become this == that. |
| + AsmValueType* avt = this->AsValueType(); |
| + if (avt != nullptr) { |
| + AsmValueType* tavt = that->AsValueType(); |
| + if (tavt == nullptr) { |
| + return false; |
| + } |
| + return avt->Bitset() == tavt->Bitset(); |
| + } |
| + return that == this; |
| +} |
| + |
| +bool AsmType::IsA(AsmType* that) { |
| + AsmValueType* tavt = that->AsValueType(); |
|
bradnelson
2016/06/10 05:59:51
Maybe comment that IsA only relates basic types?
John
2016/06/13 14:20:47
Done.
|
| + if (tavt != nullptr) { |
| + AsmValueType* avt = this->AsValueType(); |
| + if (avt == nullptr) { |
| + return false; |
| + } |
| + return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset(); |
| + } |
| + return that == this; |
| +} |
| + |
| +int32_t AsmType::ElementSizeInBytes() { |
| + auto* value = AsValueType(); |
| + if (value == nullptr) { |
| + return AsmType::kNotHeapType; |
| + } |
| + switch (value->Bitset()) { |
| + case AsmValueType::kAsmInt8Array: |
| + case AsmValueType::kAsmUint8Array: |
| + return 1; |
| + case AsmValueType::kAsmInt16Array: |
| + case AsmValueType::kAsmUint16Array: |
| + return 2; |
| + case AsmValueType::kAsmInt32Array: |
| + case AsmValueType::kAsmUint32Array: |
| + case AsmValueType::kAsmFloat32Array: |
| + return 4; |
| + case AsmValueType::kAsmFloat64Array: |
| + return 8; |
| + default: |
| + return AsmType::kNotHeapType; |
| + } |
| +} |
| + |
| +AsmType* AsmType::LoadType() { |
| + auto* value = AsValueType(); |
| + if (value == nullptr) { |
| + return AsmType::None(); |
| + } |
| + switch (value->Bitset()) { |
| + case AsmValueType::kAsmInt8Array: |
| + case AsmValueType::kAsmUint8Array: |
| + case AsmValueType::kAsmInt16Array: |
| + case AsmValueType::kAsmUint16Array: |
| + case AsmValueType::kAsmInt32Array: |
| + case AsmValueType::kAsmUint32Array: |
| + return AsmType::Intish(); |
| + case AsmValueType::kAsmFloat32Array: |
| + return AsmType::FloatQ(); |
| + case AsmValueType::kAsmFloat64Array: |
| + return AsmType::DoubleQ(); |
| + default: |
| + return AsmType::None(); |
| + } |
| +} |
| + |
| +AsmType* AsmType::StoreType() { |
| + auto* value = AsValueType(); |
| + if (value == nullptr) { |
| + return AsmType::None(); |
| + } |
| + switch (value->Bitset()) { |
| + case AsmValueType::kAsmInt8Array: |
| + case AsmValueType::kAsmUint8Array: |
| + case AsmValueType::kAsmInt16Array: |
| + case AsmValueType::kAsmUint16Array: |
| + case AsmValueType::kAsmInt32Array: |
| + case AsmValueType::kAsmUint32Array: |
| + return AsmType::Intish(); |
| + case AsmValueType::kAsmFloat32Array: |
| + return AsmType::FloatishDoubleQ(); |
| + case AsmValueType::kAsmFloat64Array: |
| + return AsmType::FloatQDoubleQ(); |
| + default: |
| + return AsmType::None(); |
| + } |
| +} |
| + |
| +std::string AsmFunctionType::Name() { |
| + std::string ret; |
| + ret += "("; |
| + for (size_t ii = 0; ii < args_.size(); ++ii) { |
| + ret += args_[ii]->Name(); |
| + if (ii != args_.size() - 1) { |
| + ret += ", "; |
| + } |
| + } |
| + if (IsMinMaxType()) { |
| + DCHECK_EQ(args_.size(), 2); |
| + ret += "..."; |
| + } |
| + ret += ") -> "; |
| + ret += return_type_->Name(); |
| + return ret; |
| +} |
| + |
| +namespace { |
| +class AsmFroundType final : public AsmFunctionType { |
| + public: |
| + bool IsFroundType() const override { return true; } |
| + |
| + private: |
| + friend AsmType; |
| + |
| + AsmFroundType(Zone* zone, AsmType* src) |
| + : AsmFunctionType(zone, AsmType::Float()) { |
| + AddArgument(src); |
| + } |
| +}; |
| +} // namespace |
| + |
| +AsmType* AsmType::FroundType(Zone* zone, AsmType* src) { |
| + DCHECK(src->AsValueType() != nullptr); |
| + auto* Fround = new (zone) AsmFroundType(zone, src); |
| + return reinterpret_cast<AsmType*>(Fround); |
| +} |
| + |
| +namespace { |
| +class AsmMinMaxType final : public AsmFunctionType { |
| + public: |
| + bool IsMinMaxType() const override { return true; } |
| + |
| + private: |
| + friend AsmType; |
| + |
| + AsmMinMaxType(Zone* zone, AsmType* type) : AsmFunctionType(zone, type) { |
| + AddArgument(type); |
| + AddArgument(type); |
| + } |
| + |
| + AsmType* ValidateCall(AsmType* function_type) override { |
| + auto* callable = function_type->AsFunctionType(); |
| + if (callable == nullptr) { |
| + return nullptr; |
| + } |
| + |
| + if (!ReturnType()->IsExactly(callable->ReturnType())) { |
| + return AsmType::None(); |
| + } |
| + |
| + if (callable->Arguments().size() < 2) { |
| + return AsmType::None(); |
| + } |
| + |
| + for (size_t ii = 0; ii < Arguments().size(); ++ii) { |
| + if (!Arguments()[0]->IsExactly(callable->Arguments()[ii])) { |
| + return AsmType::None(); |
| + } |
| + } |
| + |
| + return ReturnType(); |
| + } |
| +}; |
| +} // namespace |
| + |
| +AsmType* AsmType::MinMaxType(Zone* zone, AsmType* type) { |
| + DCHECK(type->AsValueType() != nullptr); |
| + auto* MinMax = new (zone) AsmMinMaxType(zone, type); |
| + return reinterpret_cast<AsmType*>(MinMax); |
| +} |
| + |
| +AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) { |
| + auto* callable = function_type->AsFunctionType(); |
| + if (callable == nullptr) { |
| + return nullptr; |
| + } |
| + |
| + if (!return_type_->IsExactly(callable->return_type_)) { |
| + return AsmType::None(); |
| + } |
| + |
| + if (args_.size() != callable->args_.size()) { |
| + return AsmType::None(); |
| + } |
| + |
| + for (size_t ii = 0; ii < args_.size(); ++ii) { |
| + if (!args_[ii]->IsExactly(callable->args_[ii])) { |
| + return AsmType::None(); |
| + } |
| + } |
| + |
| + return return_type_; |
| +} |
| + |
| +std::string AsmOverloadedFunctionType::Name() { |
| + std::string ret; |
| + |
| + for (size_t ii = 0; ii < overloads_.size(); ++ii) { |
| + if (ii != 0) { |
| + ret += " /\\ "; |
| + } |
| + ret += overloads_[ii]->Name(); |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) { |
| + auto* callable = function_type->AsFunctionType(); |
| + if (callable == nullptr) { |
| + return AsmType::None(); |
| + } |
| + |
| + for (size_t ii = 0; ii < overloads_.size(); ++ii) { |
| + auto* validated_type = |
| + overloads_[ii]->AsCallableType()->ValidateCall(function_type); |
| + if (validated_type != AsmType::None()) { |
| + return validated_type; |
| + } |
| + } |
| + |
| + return AsmType::None(); |
| +} |
| + |
| +void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { |
| + DCHECK(overload->AsFunctionType() != nullptr); |
| + overloads_.push_back(overload); |
| +} |
| + |
| +} // namespace wasm |
| +} // namespace internal |
| +} // namespace v8 |