Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/v8.h" | |
| 6 | |
| 7 #include "src/wasm/asm-types.h" | |
| 8 | |
| 9 namespace v8 { | |
| 10 namespace internal { | |
| 11 namespace wasm { | |
| 12 | |
| 13 AsmCallableType* AsmType::AsCallableType() { | |
| 14 DCHECK(this->AsFunctionType() != nullptr || | |
| 15 this->AsOverloadedFunctionType() != nullptr); | |
| 16 return reinterpret_cast<AsmCallableType*>(this); | |
| 17 } | |
| 18 | |
| 19 std::string AsmType::Name() { | |
| 20 AsmValueType* avt = this->AsValueType(); | |
| 21 if (avt != nullptr) { | |
| 22 switch (avt->Bitset()) { | |
| 23 #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \ | |
| 24 case AsmValueType::kAsm##CamelName: \ | |
| 25 return string_name; | |
| 26 FOR_EACH_ASM_VALUE_TYPE_LIST(RETURN_TYPE_NAME) | |
| 27 #undef RETURN_TYPE_NAME | |
| 28 default: | |
| 29 UNREACHABLE(); | |
| 30 } | |
| 31 } | |
| 32 return reinterpret_cast<AsmCallableType*>(this)->Name(); | |
| 33 } | |
| 34 | |
| 35 bool AsmType::IsExactly(AsmType* that) { | |
| 36 // TODO(jpp): maybe this can become this == that. | |
| 37 AsmValueType* avt = this->AsValueType(); | |
| 38 if (avt != nullptr) { | |
| 39 AsmValueType* tavt = that->AsValueType(); | |
| 40 if (tavt == nullptr) { | |
| 41 return false; | |
| 42 } | |
| 43 return avt->Bitset() == tavt->Bitset(); | |
| 44 } | |
| 45 return that == this; | |
| 46 } | |
| 47 | |
| 48 bool AsmType::IsA(AsmType* that) { | |
| 49 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.
| |
| 50 if (tavt != nullptr) { | |
| 51 AsmValueType* avt = this->AsValueType(); | |
| 52 if (avt == nullptr) { | |
| 53 return false; | |
| 54 } | |
| 55 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset(); | |
| 56 } | |
| 57 return that == this; | |
| 58 } | |
| 59 | |
| 60 int32_t AsmType::ElementSizeInBytes() { | |
| 61 auto* value = AsValueType(); | |
| 62 if (value == nullptr) { | |
| 63 return AsmType::kNotHeapType; | |
| 64 } | |
| 65 switch (value->Bitset()) { | |
| 66 case AsmValueType::kAsmInt8Array: | |
| 67 case AsmValueType::kAsmUint8Array: | |
| 68 return 1; | |
| 69 case AsmValueType::kAsmInt16Array: | |
| 70 case AsmValueType::kAsmUint16Array: | |
| 71 return 2; | |
| 72 case AsmValueType::kAsmInt32Array: | |
| 73 case AsmValueType::kAsmUint32Array: | |
| 74 case AsmValueType::kAsmFloat32Array: | |
| 75 return 4; | |
| 76 case AsmValueType::kAsmFloat64Array: | |
| 77 return 8; | |
| 78 default: | |
| 79 return AsmType::kNotHeapType; | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 AsmType* AsmType::LoadType() { | |
| 84 auto* value = AsValueType(); | |
| 85 if (value == nullptr) { | |
| 86 return AsmType::None(); | |
| 87 } | |
| 88 switch (value->Bitset()) { | |
| 89 case AsmValueType::kAsmInt8Array: | |
| 90 case AsmValueType::kAsmUint8Array: | |
| 91 case AsmValueType::kAsmInt16Array: | |
| 92 case AsmValueType::kAsmUint16Array: | |
| 93 case AsmValueType::kAsmInt32Array: | |
| 94 case AsmValueType::kAsmUint32Array: | |
| 95 return AsmType::Intish(); | |
| 96 case AsmValueType::kAsmFloat32Array: | |
| 97 return AsmType::FloatQ(); | |
| 98 case AsmValueType::kAsmFloat64Array: | |
| 99 return AsmType::DoubleQ(); | |
| 100 default: | |
| 101 return AsmType::None(); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 AsmType* AsmType::StoreType() { | |
| 106 auto* value = AsValueType(); | |
| 107 if (value == nullptr) { | |
| 108 return AsmType::None(); | |
| 109 } | |
| 110 switch (value->Bitset()) { | |
| 111 case AsmValueType::kAsmInt8Array: | |
| 112 case AsmValueType::kAsmUint8Array: | |
| 113 case AsmValueType::kAsmInt16Array: | |
| 114 case AsmValueType::kAsmUint16Array: | |
| 115 case AsmValueType::kAsmInt32Array: | |
| 116 case AsmValueType::kAsmUint32Array: | |
| 117 return AsmType::Intish(); | |
| 118 case AsmValueType::kAsmFloat32Array: | |
| 119 return AsmType::FloatishDoubleQ(); | |
| 120 case AsmValueType::kAsmFloat64Array: | |
| 121 return AsmType::FloatQDoubleQ(); | |
| 122 default: | |
| 123 return AsmType::None(); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 std::string AsmFunctionType::Name() { | |
| 128 std::string ret; | |
| 129 ret += "("; | |
| 130 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
| 131 ret += args_[ii]->Name(); | |
| 132 if (ii != args_.size() - 1) { | |
| 133 ret += ", "; | |
| 134 } | |
| 135 } | |
| 136 if (IsMinMaxType()) { | |
| 137 DCHECK_EQ(args_.size(), 2); | |
| 138 ret += "..."; | |
| 139 } | |
| 140 ret += ") -> "; | |
| 141 ret += return_type_->Name(); | |
| 142 return ret; | |
| 143 } | |
| 144 | |
| 145 namespace { | |
| 146 class AsmFroundType final : public AsmFunctionType { | |
| 147 public: | |
| 148 bool IsFroundType() const override { return true; } | |
| 149 | |
| 150 private: | |
| 151 friend AsmType; | |
| 152 | |
| 153 AsmFroundType(Zone* zone, AsmType* src) | |
| 154 : AsmFunctionType(zone, AsmType::Float()) { | |
| 155 AddArgument(src); | |
| 156 } | |
| 157 }; | |
| 158 } // namespace | |
| 159 | |
| 160 AsmType* AsmType::FroundType(Zone* zone, AsmType* src) { | |
| 161 DCHECK(src->AsValueType() != nullptr); | |
| 162 auto* Fround = new (zone) AsmFroundType(zone, src); | |
| 163 return reinterpret_cast<AsmType*>(Fround); | |
| 164 } | |
| 165 | |
| 166 namespace { | |
| 167 class AsmMinMaxType final : public AsmFunctionType { | |
| 168 public: | |
| 169 bool IsMinMaxType() const override { return true; } | |
| 170 | |
| 171 private: | |
| 172 friend AsmType; | |
| 173 | |
| 174 AsmMinMaxType(Zone* zone, AsmType* type) : AsmFunctionType(zone, type) { | |
| 175 AddArgument(type); | |
| 176 AddArgument(type); | |
| 177 } | |
| 178 | |
| 179 AsmType* ValidateCall(AsmType* function_type) override { | |
| 180 auto* callable = function_type->AsFunctionType(); | |
| 181 if (callable == nullptr) { | |
| 182 return nullptr; | |
| 183 } | |
| 184 | |
| 185 if (!ReturnType()->IsExactly(callable->ReturnType())) { | |
| 186 return AsmType::None(); | |
| 187 } | |
| 188 | |
| 189 if (callable->Arguments().size() < 2) { | |
| 190 return AsmType::None(); | |
| 191 } | |
| 192 | |
| 193 for (size_t ii = 0; ii < Arguments().size(); ++ii) { | |
| 194 if (!Arguments()[0]->IsExactly(callable->Arguments()[ii])) { | |
| 195 return AsmType::None(); | |
| 196 } | |
| 197 } | |
| 198 | |
| 199 return ReturnType(); | |
| 200 } | |
| 201 }; | |
| 202 } // namespace | |
| 203 | |
| 204 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* type) { | |
| 205 DCHECK(type->AsValueType() != nullptr); | |
| 206 auto* MinMax = new (zone) AsmMinMaxType(zone, type); | |
| 207 return reinterpret_cast<AsmType*>(MinMax); | |
| 208 } | |
| 209 | |
| 210 AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) { | |
| 211 auto* callable = function_type->AsFunctionType(); | |
| 212 if (callable == nullptr) { | |
| 213 return nullptr; | |
| 214 } | |
| 215 | |
| 216 if (!return_type_->IsExactly(callable->return_type_)) { | |
| 217 return AsmType::None(); | |
| 218 } | |
| 219 | |
| 220 if (args_.size() != callable->args_.size()) { | |
| 221 return AsmType::None(); | |
| 222 } | |
| 223 | |
| 224 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
| 225 if (!args_[ii]->IsExactly(callable->args_[ii])) { | |
| 226 return AsmType::None(); | |
| 227 } | |
| 228 } | |
| 229 | |
| 230 return return_type_; | |
| 231 } | |
| 232 | |
| 233 std::string AsmOverloadedFunctionType::Name() { | |
| 234 std::string ret; | |
| 235 | |
| 236 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
| 237 if (ii != 0) { | |
| 238 ret += " /\\ "; | |
| 239 } | |
| 240 ret += overloads_[ii]->Name(); | |
| 241 } | |
| 242 | |
| 243 return ret; | |
| 244 } | |
| 245 | |
| 246 AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) { | |
| 247 auto* callable = function_type->AsFunctionType(); | |
| 248 if (callable == nullptr) { | |
| 249 return AsmType::None(); | |
| 250 } | |
| 251 | |
| 252 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
| 253 auto* validated_type = | |
| 254 overloads_[ii]->AsCallableType()->ValidateCall(function_type); | |
| 255 if (validated_type != AsmType::None()) { | |
| 256 return validated_type; | |
| 257 } | |
| 258 } | |
| 259 | |
| 260 return AsmType::None(); | |
| 261 } | |
| 262 | |
| 263 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { | |
| 264 DCHECK(overload->AsFunctionType() != nullptr); | |
| 265 overloads_.push_back(overload); | |
| 266 } | |
| 267 | |
| 268 } // namespace wasm | |
| 269 } // namespace internal | |
| 270 } // namespace v8 | |
| OLD | NEW |