• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ecmascript/ts_types/ts_type.h"
16 
17 #include "ecmascript/js_function.h"
18 #include "ecmascript/object_factory.h"
19 #include "ecmascript/property_attributes.h"
20 
21 namespace panda::ecmascript {
IsEqual(JSHandle<TSUnionType> unionB)22 bool TSUnionType::IsEqual(JSHandle<TSUnionType> unionB)
23 {
24     DISALLOW_GARBAGE_COLLECTION;
25     ASSERT(unionB->GetComponents().IsTaggedArray());
26 
27     TaggedArray *unionArrayA = TaggedArray::Cast(TSUnionType::GetComponents().GetTaggedObject());
28     TaggedArray *unionArrayB = TaggedArray::Cast(unionB->GetComponents().GetTaggedObject());
29     uint32_t unionALength = unionArrayA->GetLength();
30     uint32_t unionBLength = unionArrayB->GetLength();
31     if (unionALength != unionBLength) {
32         return false;
33     }
34     for (uint32_t unionAIndex = 0; unionAIndex < unionALength; unionAIndex++) {
35         int argUnionA = unionArrayA->Get(unionAIndex).GetNumber();
36         bool findArgTag = false;
37         for (uint32_t unionBIndex = 0; unionBIndex < unionBLength; unionBIndex++) {
38             int argUnionB = unionArrayB->Get(unionBIndex).GetNumber();
39             if (argUnionA == argUnionB) {
40                 findArgTag = true;
41                 break;
42             }
43         }
44         if (!findArgTag) {
45             return false;
46         }
47     }
48     return true;
49 }
50 
GetPropTypeGT(JSThread * thread,JSHandle<TSClassType> classType,JSHandle<JSTaggedValue> propName)51 GlobalTSTypeRef TSClassType::GetPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType,
52                                            JSHandle<JSTaggedValue> propName)
53 {
54     DISALLOW_GARBAGE_COLLECTION;
55     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
56     JSMutableHandle<TSClassType> mutableClassType(thread, classType.GetTaggedValue());
57     JSMutableHandle<TSObjectType> mutableConstructorType(thread, mutableClassType->GetConstructorType());
58     GlobalTSTypeRef propTypeGT = GlobalTSTypeRef::Default();
59 
60     while (propTypeGT.IsDefault()) {  // not find
61         propTypeGT = TSObjectType::GetPropTypeGT(thread, mutableConstructorType, propName);
62         GlobalTSTypeRef classTypeGT = mutableClassType->GetExtensionGT();
63         if (classTypeGT.IsDefault()) {  // end of prototype chain
64             break;
65         }
66 
67         JSTaggedValue tmpType = tsManager->GetTSType(classTypeGT).GetTaggedValue();
68         if (tmpType.IsUndefined()) {
69             return GlobalTSTypeRef::Default();
70         }
71         mutableClassType.Update(tmpType);
72         mutableConstructorType.Update(mutableClassType->GetConstructorType());
73     }
74     return propTypeGT;
75 }
76 
GetSuperPropTypeGT(JSThread * thread,JSHandle<TSClassType> classType,JSHandle<JSTaggedValue> propName,PropertyType propType)77 GlobalTSTypeRef TSClassType::GetSuperPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType,
78                                                 JSHandle<JSTaggedValue> propName, PropertyType propType)
79 {
80     DISALLOW_GARBAGE_COLLECTION;
81     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
82     JSMutableHandle<TSClassType> mutableClassType(thread, classType.GetTaggedValue());
83     GlobalTSTypeRef propTypeGT = GlobalTSTypeRef::Default();
84     GlobalTSTypeRef notExistPropGt = kungfu::GateType::UndefinedType().GetGTRef();
85     GlobalTSTypeRef superClassTypeGT = mutableClassType->GetExtensionGT();
86     if (superClassTypeGT.IsDefault()) {  // end of prototype chain
87         return notExistPropGt;
88     }
89     ASSERT(propType != PropertyType::OTHERS);
90     bool isStatic = propType == PropertyType::STATIC;
91     mutableClassType.Update(tsManager->GetTSType(superClassTypeGT).GetTaggedValue());
92     JSMutableHandle<TSObjectType> mutablePropTypes(thread, isStatic ?
93         mutableClassType->GetConstructorType() : mutableClassType->GetPrototypeType());
94     while (propTypeGT.IsDefault()) {
95         propTypeGT = TSObjectType::GetPropTypeGT(thread, mutablePropTypes, propName);
96         GlobalTSTypeRef classTypeGT = mutableClassType->GetExtensionGT();
97         if (classTypeGT.IsDefault()) {  // end of prototype chain
98             break;
99         }
100         JSTaggedValue tmpType = tsManager->GetTSType(classTypeGT).GetTaggedValue();
101         if (tmpType.IsUndefined()) { // this is for builtin.d.abc
102             return GlobalTSTypeRef::Default();
103         }
104         mutableClassType.Update(tmpType);
105         mutablePropTypes.Update(isStatic ?
106             mutableClassType->GetConstructorType() : mutableClassType->GetPrototypeType());
107     }
108     return propTypeGT.IsDefault() ? notExistPropGt : propTypeGT;
109 }
110 
GetNonStaticPropTypeGT(JSThread * thread,JSHandle<TSClassType> classType,JSHandle<JSTaggedValue> propName)111 GlobalTSTypeRef TSClassType::GetNonStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType,
112                                                     JSHandle<JSTaggedValue> propName)
113 {
114     DISALLOW_GARBAGE_COLLECTION;
115     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
116     JSHandle<TSObjectType> instanceType(thread, classType->GetInstanceType());
117     GlobalTSTypeRef propTypeGT = TSObjectType::GetPropTypeGT(thread, instanceType, propName);
118     if (!propTypeGT.IsDefault()) {
119         return propTypeGT;
120     }
121 
122     // search on prototype chain
123     JSMutableHandle<TSClassType> mutableClassType(thread, classType.GetTaggedValue());
124     JSMutableHandle<TSObjectType> mutablePrototypeType(thread, classType->GetPrototypeType());
125     while (propTypeGT.IsDefault()) {  // not find
126         propTypeGT = TSObjectType::GetPropTypeGT(thread, mutablePrototypeType, propName);
127         GlobalTSTypeRef classTypeGT = mutableClassType->GetExtensionGT();
128         if (classTypeGT.IsDefault()) {  // end of prototype chain
129             break;
130         }
131 
132         JSTaggedValue tmpType = tsManager->GetTSType(classTypeGT).GetTaggedValue();
133         if (tmpType.IsUndefined()) {
134             return GlobalTSTypeRef::Default();
135         }
136         mutableClassType.Update(tmpType);
137         mutablePrototypeType.Update(mutableClassType->GetPrototypeType());
138     }
139     return propTypeGT;
140 }
141 
UpdateNonStaticPropTypeGT(JSThread * thread,JSHandle<TSClassType> classType,JSHandle<JSTaggedValue> propName,GlobalTSTypeRef newGT)142 void TSClassType::UpdateNonStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType,
143                                             JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT)
144 {
145     DISALLOW_GARBAGE_COLLECTION;
146     JSHandle<TSObjectType> instanceType(thread, classType->GetInstanceType());
147     TSObjectType::UpdatePropTypeGT(thread, instanceType, propName, newGT);
148 }
149 
UpdateStaticPropTypeGT(JSThread * thread,JSHandle<TSClassType> classType,JSHandle<JSTaggedValue> propName,GlobalTSTypeRef newGT)150 void TSClassType::UpdateStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType,
151                                          JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT)
152 {
153     DISALLOW_GARBAGE_COLLECTION;
154     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
155     JSMutableHandle<TSClassType> mutableClassType(thread, classType.GetTaggedValue());
156     JSMutableHandle<TSObjectType> mutableConstructorType(thread, mutableClassType->GetConstructorType());
157     bool hasUpdate = false;
158     while (!hasUpdate) {
159         hasUpdate = TSObjectType::UpdatePropTypeGT(thread, mutableConstructorType, propName, newGT);
160         GlobalTSTypeRef classTypeGT = mutableClassType->GetExtensionGT();
161         if (classTypeGT.IsDefault()) {
162             break;
163         }
164 
165         JSTaggedValue tmpType = tsManager->GetTSType(classTypeGT).GetTaggedValue();
166         if (tmpType.IsUndefined()) {
167             break;
168         }
169         mutableClassType.Update(tmpType);
170         mutableConstructorType.Update(mutableClassType->GetConstructorType());
171     }
172 }
173 
GetPropTypeGT(JSThread * thread,JSHandle<TSClassInstanceType> classInstanceType,JSHandle<JSTaggedValue> propName)174 GlobalTSTypeRef TSClassInstanceType::GetPropTypeGT(JSThread *thread, JSHandle<TSClassInstanceType> classInstanceType,
175                                                    JSHandle<JSTaggedValue> propName)
176 {
177     DISALLOW_GARBAGE_COLLECTION;
178     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
179     GlobalTSTypeRef classTypeGT = classInstanceType->GetClassGT();
180     JSHandle<JSTaggedValue> type = tsManager->GetTSType(classTypeGT);
181 
182     if (type->IsUndefined()) {
183         return GlobalTSTypeRef::Default();
184     }
185 
186     ASSERT(type->IsTSClassType());
187     JSHandle<TSClassType> classType(type);
188     GlobalTSTypeRef propTypeGT = TSClassType::GetNonStaticPropTypeGT(thread, classType, propName);
189     return propTypeGT;
190 }
191 
GetIndexSignType(JSThread * thread,const JSHandle<TSClassInstanceType> & classInstanceType,const uint32_t typeId)192 GlobalTSTypeRef TSClassInstanceType::GetIndexSignType(JSThread *thread,
193                                                       const JSHandle<TSClassInstanceType> &classInstanceType,
194                                                       const uint32_t typeId)
195 {
196     DISALLOW_GARBAGE_COLLECTION;
197     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
198     GlobalTSTypeRef classTypeGT = classInstanceType->GetClassGT();
199     JSHandle<JSTaggedValue> type = tsManager->GetTSType(classTypeGT);
200     // Es2abc no longer obeys that what is stored in classinstance types must be classtype,
201     // Retains the follwoing branch until they change it.
202     if (!type->IsTSClassType()) {
203         return GlobalTSTypeRef::Default();
204     }
205     JSHandle<TSClassType> classType(type);
206     if (classType->GetIndexSigns().IsUndefined()) {
207         return GlobalTSTypeRef::Default();
208     }
209 
210     JSHandle<TSObjLayoutInfo> indexSignInfo(thread, classType->GetIndexSigns());
211     JSTaggedValue valueType = indexSignInfo->TryGetTypeByIndexSign(typeId);
212     if (valueType.IsInt()) {
213         return GlobalTSTypeRef(static_cast<uint32_t>(valueType.GetInt()));
214     }
215     return GlobalTSTypeRef::Default();
216 }
217 
GetPropTypeGT(JSThread * thread,JSHandle<TSObjectType> objectType,JSHandle<JSTaggedValue> propName)218 GlobalTSTypeRef TSObjectType::GetPropTypeGT(JSThread *thread, JSHandle<TSObjectType> objectType,
219                                             JSHandle<JSTaggedValue> propName)
220 {
221     DISALLOW_GARBAGE_COLLECTION;
222     JSHandle<TSObjLayoutInfo> layout(thread, objectType->GetObjLayoutInfo().GetTaggedObject());
223     uint32_t numOfProps = layout->GetNumOfProperties();
224     JSMutableHandle<JSTaggedValue> propKey(thread, JSTaggedValue::Undefined());
225     for (uint32_t i = 0; i < numOfProps; ++i) {
226         propKey.Update(layout->GetKey(i));
227         if (!JSTaggedValue::Equal(thread, propName, propKey)) {
228             continue;
229         }
230         uint32_t gtRawData = static_cast<uint32_t>(layout->GetTypeId(i).GetInt());
231         return GlobalTSTypeRef(gtRawData);
232     }
233 
234     return GlobalTSTypeRef::Default();
235 }
236 
UpdatePropTypeGT(JSThread * thread,JSHandle<TSObjectType> objectType,JSHandle<JSTaggedValue> propName,GlobalTSTypeRef newGT)237 bool TSObjectType::UpdatePropTypeGT(JSThread *thread, JSHandle<TSObjectType> objectType,
238                                     JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT)
239 {
240     DISALLOW_GARBAGE_COLLECTION;
241     JSHandle<TSObjLayoutInfo> layout(thread, objectType->GetObjLayoutInfo().GetTaggedObject());
242     int propIdx = layout->GetElementIndexByKey(propName.GetTaggedValue());
243     if (!TSObjLayoutInfo::IsValidIndex(propIdx)) {
244         return false;
245     }
246     uint32_t gtRawData = static_cast<uint32_t>(layout->GetTypeId(propIdx).GetInt());
247     if (GlobalTSTypeRef(gtRawData).IsDefault()) {
248         layout->SetTypeId(thread, propIdx, JSTaggedValue(newGT.GetType()));
249         return true;
250     }
251     return false;
252 }
253 
GetIndexSignType(JSThread * thread,const JSHandle<TSObjectType> & objectType,const uint32_t typeId)254 GlobalTSTypeRef TSObjectType::GetIndexSignType(JSThread *thread, const JSHandle<TSObjectType> &objectType,
255                                                const uint32_t typeId)
256 {
257     if (objectType->GetIndexSigns().IsUndefined()) {
258         return GlobalTSTypeRef::Default();
259     }
260     DISALLOW_GARBAGE_COLLECTION;
261     JSHandle<TSObjLayoutInfo> indexSignInfo(thread, objectType->GetIndexSigns());
262     JSTaggedValue valueType = indexSignInfo->TryGetTypeByIndexSign(typeId);
263     if (valueType.IsInt()) {
264         return GlobalTSTypeRef(static_cast<uint32_t>(valueType.GetInt()));
265     }
266     return GlobalTSTypeRef::Default();
267 }
268 
GetParameterTypeGT(int index) const269 GlobalTSTypeRef TSFunctionType::GetParameterTypeGT(int index) const
270 {
271     DISALLOW_GARBAGE_COLLECTION;
272     TaggedArray* functionParametersArray = TaggedArray::Cast(GetParameterTypes().GetTaggedObject());
273     JSTaggedValue parameterType = functionParametersArray->Get(index);
274     ASSERT(parameterType.IsInt());
275     uint32_t parameterGTRawData = parameterType.GetInt();
276     return GlobalTSTypeRef(parameterGTRawData);
277 }
278 
GetPropTypeGT(JSThread * thread,JSHandle<TSIteratorInstanceType> iteratorInstanceType,JSHandle<JSTaggedValue> propName)279 GlobalTSTypeRef TSIteratorInstanceType::GetPropTypeGT(JSThread *thread,
280     JSHandle<TSIteratorInstanceType> iteratorInstanceType, JSHandle<JSTaggedValue> propName)
281 {
282     DISALLOW_GARBAGE_COLLECTION;
283     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
284     GlobalTSTypeRef kindGt = iteratorInstanceType->GetKindGT();
285     GlobalTSTypeRef elementGt = iteratorInstanceType->GetElementGT();
286 
287     JSHandle<JSTaggedValue> tsType = tsManager->GetTSType(kindGt);
288     JSHandle<TSObjectType> objType(tsType);
289     GlobalTSTypeRef propGt = TSObjectType::GetPropTypeGT(thread, objType, propName);
290     if (tsManager->IsTSIterator(kindGt)) {
291         GlobalTSTypeRef iteratorFunctionInstance =
292             tsManager->GetOrCreateTSIteratorInstanceType(static_cast<TSRuntimeType>(propGt.GetLocalId()), elementGt);
293         return iteratorFunctionInstance;
294     }
295 
296     if (tsManager->IsTSIteratorResult(kindGt)) {
297         if (propGt.IsDefault()) {
298 #ifndef NDEBUG
299             ASSERT(propName->IsString());
300             JSHandle<JSTaggedValue> valueString = thread->GlobalConstants()->GetHandledValueString();
301             ASSERT(EcmaStringAccessor::StringsAreEqual(*JSHandle<EcmaString>::Cast(propName), EcmaString::Cast(
302                 valueString.GetTaggedValue().GetTaggedObject())));
303 #endif
304             propGt = elementGt;
305         }
306         return propGt;
307     }
308     return GlobalTSTypeRef::Default();
309 }
310 
GetPropTypeGT(JSThread * thread,JSHandle<TSInterfaceType> interfaceType,JSHandle<JSTaggedValue> propName)311 GlobalTSTypeRef TSInterfaceType::GetPropTypeGT(JSThread *thread, JSHandle<TSInterfaceType> interfaceType,
312                                                JSHandle<JSTaggedValue> propName)
313 {
314     DISALLOW_GARBAGE_COLLECTION;
315     TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
316 
317     JSMutableHandle<TSInterfaceType> mutableInterfaceType(thread, interfaceType.GetTaggedValue());
318     JSMutableHandle<TSObjectType> mutableFieldsType(thread, mutableInterfaceType->GetFields());
319     GlobalTSTypeRef propTypeGT = GlobalTSTypeRef::Default();
320     propTypeGT = TSObjectType::GetPropTypeGT(thread, mutableFieldsType, propName);
321 
322     TaggedArray* extendsArray = TaggedArray::Cast(mutableInterfaceType->GetExtends().GetTaggedObject());
323     uint32_t extendsLength = extendsArray->GetLength();
324 
325     for (uint32_t index = 0; index < extendsLength; index++) {
326         if (!propTypeGT.IsDefault()) {
327             return propTypeGT;
328         }
329 
330         JSTaggedValue extendsValue = extendsArray->Get(index);
331         ASSERT(extendsValue.IsInt());
332         uint32_t gtRawData = static_cast<uint32_t>(extendsValue.GetInt());
333         GlobalTSTypeRef extendsGT = GlobalTSTypeRef(gtRawData);
334         JSHandle<JSTaggedValue> extendsType = tsManager->GetTSType(extendsGT);
335         if (extendsType->IsUndefined()) {
336             return GlobalTSTypeRef::Default();
337         }
338         ASSERT(extendsType->IsTSType());
339 
340         if (extendsType->IsTSClassType()) {
341             JSHandle<TSClassType> innerClassType(extendsType);
342             propTypeGT = TSClassType::GetNonStaticPropTypeGT(thread, innerClassType, propName);
343         } else if (extendsType->IsTSInterfaceType()) {
344             JSHandle<TSInterfaceType> extendsInterfaceType(extendsType);
345             propTypeGT = TSInterfaceType::GetPropTypeGT(thread, extendsInterfaceType, propName);
346         }
347     }
348 
349     return propTypeGT;
350 }
351 
GetIndexSignType(JSThread * thread,const JSHandle<TSInterfaceType> & interfaceType,const uint32_t typeId)352 GlobalTSTypeRef TSInterfaceType::GetIndexSignType(JSThread *thread, const JSHandle<TSInterfaceType> &interfaceType,
353                                                   const uint32_t typeId)
354 {
355     if (interfaceType->GetIndexSigns().IsUndefined()) {
356         return GlobalTSTypeRef::Default();
357     }
358     DISALLOW_GARBAGE_COLLECTION;
359     JSHandle<TSObjLayoutInfo> indexSignInfo(thread, interfaceType->GetIndexSigns());
360     JSTaggedValue valueType = indexSignInfo->TryGetTypeByIndexSign(typeId);
361     if (valueType.IsInt()) {
362         return GlobalTSTypeRef(static_cast<uint32_t>(valueType.GetInt()));
363     }
364     return GlobalTSTypeRef::Default();
365 }
366 
367 
AddKeyAndValue(const JSThread * thread,const JSHandle<TSNamespaceType> & namespaceType,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)368 void TSNamespaceType::AddKeyAndValue(const JSThread *thread, const JSHandle<TSNamespaceType> &namespaceType,
369                                      const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)
370 {
371     JSHandle<TSObjLayoutInfo> propLayout(thread, namespaceType->GetPropertyType());
372     if (propLayout->Find(key.GetTaggedValue())) {
373         return;
374     }
375     JSHandle<TSObjLayoutInfo> newPropLayout = TSObjLayoutInfo::PushBack(thread, propLayout, key, value);
376     namespaceType->SetPropertyType(thread, newPropLayout.GetTaggedValue());
377 }
378 
GetPropTypeGT(JSThread * thread,const JSHandle<TSNamespaceType> & namespaceType,const JSHandle<JSTaggedValue> & propName)379 GlobalTSTypeRef TSNamespaceType::GetPropTypeGT(JSThread *thread, const JSHandle<TSNamespaceType> &namespaceType,
380                                                const JSHandle<JSTaggedValue> &propName)
381 {
382     DISALLOW_GARBAGE_COLLECTION;
383     if (namespaceType->GetPropertyType().IsUndefined()) {
384         return GlobalTSTypeRef::Default();
385     }
386 
387     JSHandle<JSTaggedValue> properties(thread, namespaceType->GetPropertyType());
388 
389     if (properties->IsUndefined()) {
390         return GlobalTSTypeRef::Default();
391     }
392 
393     JSHandle<TSObjLayoutInfo> layout(thread, namespaceType->GetPropertyType().GetTaggedObject());
394     uint32_t numOfProps = layout->GetNumOfProperties();
395     JSMutableHandle<JSTaggedValue> propKey(thread, JSTaggedValue::Undefined());
396     for (uint32_t i = 0; i < numOfProps; ++i) {
397         propKey.Update(layout->GetKey(i));
398         if (!JSTaggedValue::Equal(thread, propName, propKey)) {
399             continue;
400         }
401         uint32_t gtRawData = static_cast<uint32_t>(layout->GetTypeId(i).GetInt());
402         return GlobalTSTypeRef(gtRawData);
403     }
404     return GlobalTSTypeRef::Default();
405 }
406 } // namespace panda::ecmascript
407