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(); | |
|
ahaas
2016/06/13 16:27:03
AsCallableType()->Name();
John
2016/06/13 17:32:27
Done.
| |
| 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; | |
|
ahaas
2016/06/13 16:27:03
Could you add a comment which explains why callabl
John
2016/06/13 17:32:27
IsExactly is only supposed to be used when queryin
| |
| 46 } | |
| 47 | |
| 48 bool AsmType::IsA(AsmType* that) { | |
| 49 // IsA is used for querying inheritance relationships. Therefore it is only | |
| 50 // meaningful for basic types. | |
| 51 AsmValueType* tavt = that->AsValueType(); | |
| 52 if (tavt != nullptr) { | |
| 53 AsmValueType* avt = this->AsValueType(); | |
| 54 if (avt == nullptr) { | |
| 55 return false; | |
| 56 } | |
| 57 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset(); | |
| 58 } | |
| 59 return that == this; | |
|
ahaas
2016/06/13 16:27:03
If you say that IsA is only meaningful for basic t
John
2016/06/13 17:32:27
This is a good question, and I don't know the answ
| |
| 60 } | |
| 61 | |
| 62 int32_t AsmType::ElementSizeInBytes() { | |
| 63 auto* value = AsValueType(); | |
| 64 if (value == nullptr) { | |
| 65 return AsmType::kNotHeapType; | |
| 66 } | |
| 67 switch (value->Bitset()) { | |
| 68 case AsmValueType::kAsmInt8Array: | |
| 69 case AsmValueType::kAsmUint8Array: | |
| 70 return 1; | |
| 71 case AsmValueType::kAsmInt16Array: | |
| 72 case AsmValueType::kAsmUint16Array: | |
| 73 return 2; | |
| 74 case AsmValueType::kAsmInt32Array: | |
| 75 case AsmValueType::kAsmUint32Array: | |
| 76 case AsmValueType::kAsmFloat32Array: | |
| 77 return 4; | |
| 78 case AsmValueType::kAsmFloat64Array: | |
| 79 return 8; | |
| 80 default: | |
| 81 return AsmType::kNotHeapType; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 AsmType* AsmType::LoadType() { | |
| 86 auto* value = AsValueType(); | |
| 87 if (value == nullptr) { | |
| 88 return AsmType::None(); | |
| 89 } | |
| 90 switch (value->Bitset()) { | |
| 91 case AsmValueType::kAsmInt8Array: | |
| 92 case AsmValueType::kAsmUint8Array: | |
| 93 case AsmValueType::kAsmInt16Array: | |
| 94 case AsmValueType::kAsmUint16Array: | |
| 95 case AsmValueType::kAsmInt32Array: | |
| 96 case AsmValueType::kAsmUint32Array: | |
| 97 return AsmType::Intish(); | |
| 98 case AsmValueType::kAsmFloat32Array: | |
| 99 return AsmType::FloatQ(); | |
| 100 case AsmValueType::kAsmFloat64Array: | |
| 101 return AsmType::DoubleQ(); | |
| 102 default: | |
| 103 return AsmType::None(); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 AsmType* AsmType::StoreType() { | |
| 108 auto* value = AsValueType(); | |
| 109 if (value == nullptr) { | |
| 110 return AsmType::None(); | |
| 111 } | |
| 112 switch (value->Bitset()) { | |
| 113 case AsmValueType::kAsmInt8Array: | |
| 114 case AsmValueType::kAsmUint8Array: | |
| 115 case AsmValueType::kAsmInt16Array: | |
| 116 case AsmValueType::kAsmUint16Array: | |
| 117 case AsmValueType::kAsmInt32Array: | |
| 118 case AsmValueType::kAsmUint32Array: | |
| 119 return AsmType::Intish(); | |
| 120 case AsmValueType::kAsmFloat32Array: | |
| 121 return AsmType::FloatishDoubleQ(); | |
|
ahaas
2016/06/13 16:27:03
Is it intentional that you say FloatishDoubleQ her
John
2016/06/13 17:32:27
yes, http://asmjs.org/spec/latest/#heap-view-types
| |
| 122 case AsmValueType::kAsmFloat64Array: | |
| 123 return AsmType::FloatQDoubleQ(); | |
| 124 default: | |
| 125 return AsmType::None(); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 std::string AsmFunctionType::Name() { | |
| 130 std::string ret; | |
| 131 ret += "("; | |
| 132 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
| 133 ret += args_[ii]->Name(); | |
| 134 if (ii != args_.size() - 1) { | |
| 135 ret += ", "; | |
| 136 } | |
| 137 } | |
| 138 if (IsMinMaxType()) { | |
| 139 DCHECK_EQ(args_.size(), 2); | |
| 140 ret += "..."; | |
|
ahaas
2016/06/13 16:27:03
Is it intentional that this is "..." and not ", ..
John
2016/06/13 17:32:27
yes, http://asmjs.org/spec/latest/#global-types ,
| |
| 141 } | |
| 142 ret += ") -> "; | |
| 143 ret += return_type_->Name(); | |
| 144 return ret; | |
| 145 } | |
| 146 | |
| 147 namespace { | |
| 148 class AsmFroundType final : public AsmFunctionType { | |
| 149 public: | |
| 150 bool IsFroundType() const override { return true; } | |
| 151 | |
| 152 private: | |
| 153 friend AsmType; | |
| 154 | |
| 155 AsmFroundType(Zone* zone, AsmType* src) | |
| 156 : AsmFunctionType(zone, AsmType::Float()) { | |
| 157 AddArgument(src); | |
| 158 } | |
| 159 }; | |
| 160 } // namespace | |
| 161 | |
| 162 AsmType* AsmType::FroundType(Zone* zone, AsmType* src) { | |
| 163 DCHECK(src->AsValueType() != nullptr); | |
| 164 auto* Fround = new (zone) AsmFroundType(zone, src); | |
| 165 return reinterpret_cast<AsmType*>(Fround); | |
| 166 } | |
| 167 | |
| 168 namespace { | |
| 169 class AsmMinMaxType final : public AsmFunctionType { | |
| 170 public: | |
| 171 bool IsMinMaxType() const override { return true; } | |
| 172 | |
| 173 private: | |
| 174 friend AsmType; | |
| 175 | |
| 176 AsmMinMaxType(Zone* zone, AsmType* type) : AsmFunctionType(zone, type) { | |
| 177 AddArgument(type); | |
| 178 AddArgument(type); | |
| 179 } | |
| 180 | |
| 181 AsmType* ValidateCall(AsmType* function_type) override { | |
| 182 auto* callable = function_type->AsFunctionType(); | |
| 183 if (callable == nullptr) { | |
| 184 return nullptr; | |
| 185 } | |
| 186 | |
| 187 if (!ReturnType()->IsExactly(callable->ReturnType())) { | |
| 188 return AsmType::None(); | |
| 189 } | |
| 190 | |
| 191 if (callable->Arguments().size() < 2) { | |
| 192 return AsmType::None(); | |
| 193 } | |
| 194 | |
| 195 for (size_t ii = 0; ii < Arguments().size(); ++ii) { | |
| 196 if (!Arguments()[0]->IsExactly(callable->Arguments()[ii])) { | |
| 197 return AsmType::None(); | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 return ReturnType(); | |
| 202 } | |
| 203 }; | |
| 204 } // namespace | |
| 205 | |
| 206 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* type) { | |
| 207 DCHECK(type->AsValueType() != nullptr); | |
| 208 auto* MinMax = new (zone) AsmMinMaxType(zone, type); | |
| 209 return reinterpret_cast<AsmType*>(MinMax); | |
| 210 } | |
| 211 | |
| 212 AsmType* AsmFunctionType::ValidateCall(AsmType* function_type) { | |
| 213 auto* callable = function_type->AsFunctionType(); | |
| 214 if (callable == nullptr) { | |
| 215 return nullptr; | |
| 216 } | |
| 217 | |
| 218 if (!return_type_->IsExactly(callable->return_type_)) { | |
| 219 return AsmType::None(); | |
| 220 } | |
| 221 | |
| 222 if (args_.size() != callable->args_.size()) { | |
| 223 return AsmType::None(); | |
| 224 } | |
| 225 | |
| 226 for (size_t ii = 0; ii < args_.size(); ++ii) { | |
| 227 if (!args_[ii]->IsExactly(callable->args_[ii])) { | |
| 228 return AsmType::None(); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 return return_type_; | |
| 233 } | |
| 234 | |
| 235 std::string AsmOverloadedFunctionType::Name() { | |
| 236 std::string ret; | |
| 237 | |
| 238 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
| 239 if (ii != 0) { | |
| 240 ret += " /\\ "; | |
| 241 } | |
| 242 ret += overloads_[ii]->Name(); | |
| 243 } | |
| 244 | |
| 245 return ret; | |
| 246 } | |
| 247 | |
| 248 AsmType* AsmOverloadedFunctionType::ValidateCall(AsmType* function_type) { | |
| 249 auto* callable = function_type->AsFunctionType(); | |
| 250 if (callable == nullptr) { | |
| 251 return AsmType::None(); | |
| 252 } | |
| 253 | |
| 254 for (size_t ii = 0; ii < overloads_.size(); ++ii) { | |
| 255 auto* validated_type = | |
| 256 overloads_[ii]->AsCallableType()->ValidateCall(function_type); | |
| 257 if (validated_type != AsmType::None()) { | |
| 258 return validated_type; | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 return AsmType::None(); | |
| 263 } | |
| 264 | |
| 265 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { | |
| 266 DCHECK(overload->AsFunctionType() != nullptr); | |
| 267 overloads_.push_back(overload); | |
| 268 } | |
| 269 | |
| 270 } // namespace wasm | |
| 271 } // namespace internal | |
| 272 } // namespace v8 | |
| OLD | NEW |