• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 
16 #include "ecmascript/compiler/object_access_helper.h"
17 
18 #include "ecmascript/js_hclass-inl.h"
19 #include "ecmascript/ts_types/ts_type.h"
20 
21 namespace panda::ecmascript::kungfu {
Compute(ChunkVector<ObjectAccessInfo> & infos)22 bool ObjectAccessHelper::Compute(ChunkVector<ObjectAccessInfo> &infos)
23 {
24     ASSERT(infos.empty());
25     bool result = false;
26     ObjectAccessInfo info(type_);
27     TSTypeKind kind = tsManager_->GetTypeKind(type_.GetGTRef());
28     switch (kind) {
29         case TSTypeKind::CLASS_INSTANCE:
30             result = ComputeForClassInstance(info);
31             break;
32         case TSTypeKind::CLASS:
33         case TSTypeKind::OBJECT:
34             result = ComputeForClassOrObject(info);
35             break;
36         case TSTypeKind::UNION:
37             return ComputePolymorphism(infos);
38         default:
39             return false;
40     }
41 
42     infos.emplace_back(info);
43     return result;
44 }
45 
ComputeForClassInstance(ObjectAccessInfo & info)46 bool ObjectAccessHelper::ComputeForClassInstance(ObjectAccessInfo &info)
47 {
48     int hclassIndex = tsManager_->GetHClassIndexByInstanceGateType(info.Type());
49     if (hclassIndex == -1) {
50         return false;
51     }
52 
53     JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
54     if (!hclass->HasTSSubtyping()) {
55         return false;
56     }
57 
58     PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
59     info.Set(hclassIndex, plr);
60 
61     if (IsLoading()) {
62         return plr.IsFound();
63     }
64 
65     return (plr.IsFound() && !plr.IsFunction());
66 }
67 
ComputeForClassOrObject(ObjectAccessInfo & info)68 bool ObjectAccessHelper::ComputeForClassOrObject(ObjectAccessInfo &info)
69 {
70     GateType type = info.Type();
71     int hclassIndex = -1;
72     if (tsManager_->IsClassTypeKind(type)) {
73         hclassIndex = tsManager_->GetConstructorHClassIndexByClassGateType(type);
74     } else if (tsManager_->IsObjectTypeKind(type)) {
75         hclassIndex = tsManager_->GetHClassIndexByObjectType(type);
76     }
77 
78     if (hclassIndex == -1) {
79         return false;
80     }
81 
82     JSHClass *hclass = JSHClass::Cast(tsManager_->GetAOTHClassInfoByIndex(hclassIndex).GetTaggedObject());
83     PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
84     info.Set(hclassIndex, plr);
85 
86     if (IsLoading()) {
87         return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor());
88     }
89 
90     return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor() && plr.IsWritable());
91 }
92 
ComputePolymorphism(ChunkVector<ObjectAccessInfo> & infos)93 bool ObjectAccessHelper::ComputePolymorphism(ChunkVector<ObjectAccessInfo> &infos)
94 {
95     DISALLOW_GARBAGE_COLLECTION;
96     ASSERT(tsManager_->IsUnionTypeKind(type_));
97     JSHandle<TSUnionType> unionType(tsManager_->GetTSType(type_.GetGTRef()));
98     TaggedArray *components = TaggedArray::Cast(unionType->GetComponents().GetTaggedObject());
99     uint32_t length = components->GetLength();
100     for (uint32_t i = 0; i < length; ++i) {
101         GlobalTSTypeRef gt(components->Get(i).GetInt());
102         GateType type = GateType(gt);
103         ObjectAccessInfo info(type);
104         TSTypeKind kind = tsManager_->GetTypeKind(gt);
105         switch (kind) {
106             case TSTypeKind::CLASS_INSTANCE: {
107                 if (!ComputeForClassInstance(info)) {
108                     return false;
109                 }
110                 break;
111             }
112             case TSTypeKind::CLASS:
113             case TSTypeKind::OBJECT: {
114                 if (!ComputeForClassOrObject(info)) {
115                     return false;
116                 }
117                 break;
118             }
119             default:
120                 return false;
121         }
122         infos.emplace_back(info);
123     }
124 
125     return infos.size() <= POLYMORPHIC_MAX_SIZE;
126 }
127 
ComputeForClassInstance(PGOObjectAccessInfo & info)128 bool PGOObjectAccessHelper::ComputeForClassInstance(PGOObjectAccessInfo &info)
129 {
130     auto type = info.Type();
131     PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
132     int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
133     if (hclassIndex == -1) {
134         return false;
135     }
136 
137     JSHClass *hclass = JSHClass::Cast(ptManager->QueryHClass(type.first, type.second).GetTaggedObject());
138 
139     PropertyLookupResult plr = JSHClass::LookupPropertyInPGOHClass(thread_, hclass, key_);
140     info.Set(hclassIndex, plr);
141 
142     if (IsLoading()) {
143         return plr.IsFound();
144     }
145 
146     return (plr.IsFound() && !plr.IsFunction());
147 }
148 
ClassInstanceIsCallable(PGOObjectAccessInfo & info)149 bool PGOObjectAccessHelper::ClassInstanceIsCallable(PGOObjectAccessInfo &info)
150 {
151     auto type = info.Type();
152     PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
153     int hclassIndex = static_cast<int>(ptManager->GetHClassIndexByProfileType(type));
154     if (hclassIndex == -1) {
155         return false;
156     }
157 
158     JSHClass *hclass = JSHClass::Cast(ptManager->QueryHClass(type.first, type.second).GetTaggedObject());
159 
160     return hclass->IsCallable();
161 }
162 }  // namespace panda::ecmascript::kungfu
163