5 #include "src/asmjs/asm-types.h" 16 AsmCallableType* AsmType::AsCallableType() {
17 if (AsValueType() !=
nullptr) {
21 return reinterpret_cast<AsmCallableType*
>(
this);
24 std::string AsmType::Name() {
25 AsmValueType* avt = this->AsValueType();
27 switch (avt->Bitset()) {
28 #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \ 29 case AsmValueType::kAsm##CamelName: \ 31 FOR_EACH_ASM_VALUE_TYPE_LIST(RETURN_TYPE_NAME)
32 #undef RETURN_TYPE_NAME 38 return this->AsCallableType()->Name();
41 bool AsmType::IsExactly(AsmType* that) {
43 AsmValueType* avt = this->AsValueType();
45 AsmValueType* tavt = that->AsValueType();
46 if (tavt ==
nullptr) {
49 return avt->Bitset() == tavt->Bitset();
57 bool AsmType::IsA(AsmType* that) {
60 if (
auto* avt = this->AsValueType()) {
61 if (
auto* tavt = that->AsValueType()) {
62 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset();
67 if (
auto* as_callable = this->AsCallableType()) {
68 return as_callable->IsA(that);
74 int32_t AsmType::ElementSizeInBytes() {
75 auto* value = AsValueType();
76 if (value ==
nullptr) {
77 return AsmType::kNotHeapType;
79 switch (value->Bitset()) {
80 case AsmValueType::kAsmInt8Array:
81 case AsmValueType::kAsmUint8Array:
83 case AsmValueType::kAsmInt16Array:
84 case AsmValueType::kAsmUint16Array:
86 case AsmValueType::kAsmInt32Array:
87 case AsmValueType::kAsmUint32Array:
88 case AsmValueType::kAsmFloat32Array:
90 case AsmValueType::kAsmFloat64Array:
93 return AsmType::kNotHeapType;
97 AsmType* AsmType::LoadType() {
98 auto* value = AsValueType();
99 if (value ==
nullptr) {
100 return AsmType::None();
102 switch (value->Bitset()) {
103 case AsmValueType::kAsmInt8Array:
104 case AsmValueType::kAsmUint8Array:
105 case AsmValueType::kAsmInt16Array:
106 case AsmValueType::kAsmUint16Array:
107 case AsmValueType::kAsmInt32Array:
108 case AsmValueType::kAsmUint32Array:
109 return AsmType::Intish();
110 case AsmValueType::kAsmFloat32Array:
111 return AsmType::FloatQ();
112 case AsmValueType::kAsmFloat64Array:
113 return AsmType::DoubleQ();
115 return AsmType::None();
119 AsmType* AsmType::StoreType() {
120 auto* value = AsValueType();
121 if (value ==
nullptr) {
122 return AsmType::None();
124 switch (value->Bitset()) {
125 case AsmValueType::kAsmInt8Array:
126 case AsmValueType::kAsmUint8Array:
127 case AsmValueType::kAsmInt16Array:
128 case AsmValueType::kAsmUint16Array:
129 case AsmValueType::kAsmInt32Array:
130 case AsmValueType::kAsmUint32Array:
131 return AsmType::Intish();
132 case AsmValueType::kAsmFloat32Array:
133 return AsmType::FloatishDoubleQ();
134 case AsmValueType::kAsmFloat64Array:
135 return AsmType::FloatQDoubleQ();
137 return AsmType::None();
141 bool AsmCallableType::IsA(AsmType* other) {
142 return other->AsCallableType() ==
this;
145 std::string AsmFunctionType::Name() {
148 for (
size_t ii = 0; ii < args_.size(); ++ii) {
149 ret += args_[ii]->Name();
150 if (ii != args_.size() - 1) {
155 ret += return_type_->Name();
160 class AsmFroundType final :
public AsmCallableType {
164 AsmFroundType() : AsmCallableType() {}
166 bool CanBeInvokedWith(AsmType* return_type,
167 const ZoneVector<AsmType*>& args)
override;
169 std::string Name()
override {
return "fround"; }
173 AsmType* AsmType::FroundType(Zone* zone) {
174 auto* Fround =
new (zone) AsmFroundType();
175 return reinterpret_cast<AsmType*
>(Fround);
178 bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
179 const ZoneVector<AsmType*>& args) {
180 if (args.size() != 1) {
185 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
186 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
194 class AsmMinMaxType final :
public AsmCallableType {
198 AsmMinMaxType(AsmType* dest, AsmType* src)
199 : AsmCallableType(), return_type_(dest), arg_(src) {}
201 bool CanBeInvokedWith(AsmType* return_type,
202 const ZoneVector<AsmType*>& args)
override {
203 if (!return_type_->IsExactly(return_type)) {
207 if (args.size() < 2) {
211 for (
size_t ii = 0; ii < args.size(); ++ii) {
212 if (!args[ii]->IsA(arg_)) {
220 std::string Name()
override {
221 return "(" + arg_->Name() +
", " + arg_->Name() +
"...) -> " +
222 return_type_->Name();
225 AsmType* return_type_;
230 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
231 DCHECK_NOT_NULL(dest->AsValueType());
232 DCHECK_NOT_NULL(src->AsValueType());
233 auto* MinMax =
new (zone) AsmMinMaxType(dest, src);
234 return reinterpret_cast<AsmType*
>(MinMax);
237 bool AsmFunctionType::IsA(AsmType* other) {
238 auto* that = other->AsFunctionType();
239 if (that ==
nullptr) {
242 if (!return_type_->IsExactly(that->return_type_)) {
246 if (args_.size() != that->args_.size()) {
250 for (
size_t ii = 0; ii < args_.size(); ++ii) {
251 if (!args_[ii]->IsExactly(that->args_[ii])) {
259 bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
260 const ZoneVector<AsmType*>& args) {
261 if (!return_type_->IsExactly(return_type)) {
265 if (args_.size() != args.size()) {
269 for (
size_t ii = 0; ii < args_.size(); ++ii) {
270 if (!args[ii]->IsA(args_[ii])) {
278 std::string AsmOverloadedFunctionType::Name() {
281 for (
size_t ii = 0; ii < overloads_.size(); ++ii) {
285 ret += overloads_[ii]->Name();
291 bool AsmOverloadedFunctionType::CanBeInvokedWith(
292 AsmType* return_type,
const ZoneVector<AsmType*>& args) {
293 for (
size_t ii = 0; ii < overloads_.size(); ++ii) {
294 if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
302 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
303 DCHECK_NOT_NULL(overload->AsCallableType());
304 overloads_.push_back(overload);