• 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 "ts_type.h"
16 
17 #include "ecmascript/ic/ic_handler.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/layout_info.h"
20 #include "ecmascript/js_handle.h"
21 #include "ecmascript/js_hclass.h"
22 #include "ecmascript/object_factory.h"
23 #include "ecmascript/ts_types/ts_obj_layout_info-inl.h"
24 #include "ecmascript/ts_types/ts_type_table.h"
25 
26 namespace panda::ecmascript {
GetOrCreateHClass(JSThread * thread)27 JSHClass *TSObjectType::GetOrCreateHClass(JSThread *thread)
28 {
29     JSTaggedValue mayBeHClass = GetHClass();
30     if (mayBeHClass.IsJSHClass()) {
31         return JSHClass::Cast(mayBeHClass.GetTaggedObject());
32     }
33     JSHandle<TSObjLayoutInfo> propTypeInfo(thread, GetObjLayoutInfo().GetTaggedObject());
34     JSHClass *hclass = CreateHClassByProps(thread, propTypeInfo);
35     SetHClass(thread, JSTaggedValue(hclass));
36 
37     return hclass;
38 }
39 
CreateHClassByProps(JSThread * thread,JSHandle<TSObjLayoutInfo> propType) const40 JSHClass *TSObjectType::CreateHClassByProps(JSThread *thread, JSHandle<TSObjLayoutInfo> propType) const
41 {
42     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
43 
44     uint32_t length = propType->GetLength();
45     if (length > PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES) {
46         LOG(ERROR, RUNTIME) << "TSobject type has too many keys and cannot create hclass";
47         UNREACHABLE();
48     }
49 
50     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
51     JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length);
52     for (uint32_t index = 0; index < length; ++index) {
53         JSTaggedValue tsPropKey = propType->GetKey(index);
54         key.Update(tsPropKey);
55         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
56         PropertyAttributes attributes = PropertyAttributes::Default();
57         attributes.SetIsInlinedProps(true);
58         attributes.SetRepresentation(Representation::MIXED);
59         attributes.SetOffset(index);
60         layout->AddKey(thread, index, key.GetTaggedValue(), attributes);
61     }
62     JSHandle<JSHClass> hclass = factory->NewEcmaDynClass(JSObject::SIZE, JSType::JS_OBJECT, length);
63     hclass->SetLayout(thread, layout);
64     hclass->SetNumberOfProps(length);
65 
66     return *hclass;
67 }
68 
IsEqual(JSThread * thread,JSHandle<TSUnionType> unionB)69 bool TSUnionType::IsEqual(JSThread *thread, JSHandle<TSUnionType> unionB)
70 {
71     DISALLOW_GARBAGE_COLLECTION;
72     ASSERT(unionB->GetComponentTypes().IsTaggedArray());
73     bool findUnionTag = 0;
74 
75     TaggedArray *unionArrayA = TaggedArray::Cast(TSUnionType::GetComponentTypes().GetTaggedObject());
76     TaggedArray *unionArrayB = TaggedArray::Cast(unionB->GetComponentTypes().GetTaggedObject());
77     int unionALength = unionArrayA->GetLength();
78     int unionBLength = unionArrayB->GetLength();
79     if (unionALength != unionBLength) {
80         return false;
81     }
82     for (int unionAIndex = 0; unionAIndex < unionALength; unionAIndex++) {
83         int argUnionA = unionArrayA->Get(unionAIndex).GetNumber();
84         bool findArgTag = 0;
85         for (int unionBIndex = 0; unionBIndex < unionBLength; unionBIndex++) {
86             int argUnionB = unionArrayB->Get(unionBIndex).GetNumber();
87             if (argUnionA == argUnionB) {
88                 findArgTag = 1;
89                 break;
90             }
91         }
92         if (!findArgTag) {
93             return findUnionTag;
94         }
95     }
96     findUnionTag = 1;
97     return findUnionTag;
98 }
99 
SearchProperty(JSThread * thread,JSHandle<TSTypeTable> & table,TSTypeKind typeKind,int localtypeId,JSHandle<EcmaString> propName)100 GlobalTSTypeRef TSClassType::SearchProperty(JSThread *thread, JSHandle<TSTypeTable> &table, TSTypeKind typeKind,
101                                             int localtypeId, JSHandle<EcmaString> propName)
102 {
103     DISALLOW_GARBAGE_COLLECTION;
104     CString propertyName = ConvertToString(propName.GetTaggedValue());
105 
106     TSClassType *classType = TSClassType::Cast(table->Get(localtypeId).GetTaggedObject());
107     TSObjectType *constructorType = TSObjectType::Cast(classType->GetConstructorType().GetTaggedObject());
108     TSObjLayoutInfo *propTypeInfo = TSObjLayoutInfo::Cast(constructorType->GetObjLayoutInfo().GetTaggedObject());
109 
110     // search static propType in constructorType
111     for (uint32_t index = 0; index < propTypeInfo->NumberOfElements(); ++index) {
112         JSTaggedValue tsPropKey = propTypeInfo->GetKey(index);
113         if (ConvertToString(tsPropKey) == propertyName) {
114             int localId = propTypeInfo->GetTypeId(index).GetNumber();
115             if (localId < GlobalTSTypeRef::TS_TYPE_RESERVED_COUNT) {
116                 return GlobalTSTypeRef(localId);
117             }
118             int localIdNonOffset = TSTypeTable::GetUserdefinedTypeId(localId);
119             TSType *propertyType = TSType::Cast(table->Get(localIdNonOffset).GetTaggedObject());
120             if (JSTaggedValue(propertyType).IsTSImportType()) {
121                 TSImportType *importType = TSImportType::Cast(table->Get(localIdNonOffset).GetTaggedObject());
122                 return importType->GetGTRef();
123             }
124             return propertyType->GetGTRef();
125         }
126     }
127     return GlobalTSTypeRef::Default();
128 }
129 
SearchProperty(JSThread * thread,JSHandle<TSTypeTable> & table,TSTypeKind typeKind,int localtypeId,JSHandle<EcmaString> propName)130 GlobalTSTypeRef TSClassInstanceType::SearchProperty(JSThread *thread, JSHandle<TSTypeTable> &table, TSTypeKind typeKind,
131                                                     int localtypeId, JSHandle<EcmaString> propName)
132 {
133     DISALLOW_GARBAGE_COLLECTION;
134     CString propertyName = ConvertToString(propName.GetTaggedValue());
135 
136     TSClassInstanceType *classInstanceType = TSClassInstanceType::Cast(table->Get(localtypeId).GetTaggedObject());
137     int localId = 0;
138     TSClassType *createClassType = TSClassType::Cast(classInstanceType->GetCreateClassType().GetTaggedObject());
139     TSObjectType *instanceType = TSObjectType::Cast(createClassType->GetInstanceType().GetTaggedObject());
140     TSObjectType *prototype = TSObjectType::Cast(createClassType->GetPrototypeType().GetTaggedObject());
141     TSObjLayoutInfo *instanceTypeInfo = TSObjLayoutInfo::Cast(instanceType->GetObjLayoutInfo().GetTaggedObject());
142     TSObjLayoutInfo *prototypeTypeInfo = TSObjLayoutInfo::Cast(prototype->GetObjLayoutInfo().GetTaggedObject());
143 
144     // search non-static propType in instanceType
145     for (uint32_t index = 0; index < instanceTypeInfo->NumberOfElements(); ++index) {
146         JSTaggedValue instancePropKey = instanceTypeInfo->GetKey(index);
147         if (ConvertToString(instancePropKey) == propertyName) {
148             localId = instanceTypeInfo->GetTypeId(index).GetNumber();
149             if (localId < GlobalTSTypeRef::TS_TYPE_RESERVED_COUNT) {
150                 return GlobalTSTypeRef(localId);
151             }
152             int localIdNonOffset = TSTypeTable::GetUserdefinedTypeId(localId);
153             TSType *propertyType = TSType::Cast(table->Get(localIdNonOffset).GetTaggedObject());
154             if (propertyType->GetGTRef().GetUserDefineTypeKind() ==
155                 static_cast<int>(TSTypeKind::TS_IMPORT)) {
156                 TSImportType *importType = TSImportType::Cast(table->Get(localIdNonOffset).GetTaggedObject());
157                 return importType->GetGTRef();
158             }
159             return propertyType->GetGTRef();
160         }
161     }
162     // search functionType in prototype
163     for (uint32_t index = 0; index < prototypeTypeInfo->NumberOfElements(); ++index) {
164         JSTaggedValue prototypePropKey = prototypeTypeInfo->GetKey(index);
165         if (ConvertToString(prototypePropKey) == propertyName) {
166             localId = prototypeTypeInfo->GetTypeId(index).GetNumber();
167             ASSERT(localId > GlobalTSTypeRef::TS_TYPE_RESERVED_COUNT);
168             int localIdNonOffset = TSTypeTable::GetUserdefinedTypeId(localId);
169             TSType *propertyType = TSType::Cast(table->Get(localIdNonOffset).GetTaggedObject());
170             return propertyType->GetGTRef();
171         }
172     }
173     return GlobalTSTypeRef::Default();
174 }
175 }