• 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 #include "ecmascript/ts_types/ts_type.h"
18 
19 namespace panda::ecmascript::kungfu {
Compute(ChunkVector<ObjectAccessInfo> & infos)20 bool ObjectAccessHelper::Compute(ChunkVector<ObjectAccessInfo> &infos)
21 {
22     ASSERT(infos.empty());
23     bool result = false;
24     ObjectAccessInfo info(type_);
25     TSTypeKind kind = tsManager_->GetTypeKind(type_.GetGTRef());
26     switch (kind) {
27         case TSTypeKind::CLASS_INSTANCE:
28             result = ComputeForClassInstance(info);
29             break;
30         case TSTypeKind::CLASS:
31         case TSTypeKind::OBJECT:
32             result = ComputeForClassOrObject(info);
33             break;
34         case TSTypeKind::UNION:
35             return ComputePolymorphism(infos);
36         default:
37             return false;
38     }
39 
40     infos.emplace_back(info);
41     return result;
42 }
43 
ComputeForClassInstance(ObjectAccessInfo & info)44 bool ObjectAccessHelper::ComputeForClassInstance(ObjectAccessInfo &info)
45 {
46     int hclassIndex = tsManager_->GetHClassIndexByInstanceGateType(info.Type());
47     if (hclassIndex == -1) {
48         return false;
49     }
50 
51     JSHClass *hclass = JSHClass::Cast(tsManager_->GetValueFromCache(hclassIndex).GetTaggedObject());
52     if (!hclass->HasTSSubtyping()) {
53         return false;
54     }
55 
56     PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
57     info.Set(hclassIndex, plr);
58 
59     if (IsLoading()) {
60         return plr.IsFound();
61     }
62 
63     return (plr.IsFound() && !plr.IsFunction());
64 }
65 
ComputeForClassOrObject(ObjectAccessInfo & info)66 bool ObjectAccessHelper::ComputeForClassOrObject(ObjectAccessInfo &info)
67 {
68     GateType type = info.Type();
69     int hclassIndex = -1;
70     if (tsManager_->IsClassTypeKind(type)) {
71         hclassIndex = tsManager_->GetConstructorHClassIndexByClassGateType(type);
72     } else if (tsManager_->IsObjectTypeKind(type)) {
73         hclassIndex = tsManager_->GetHClassIndexByObjectType(type);
74     }
75 
76     if (hclassIndex == -1) {
77         return false;
78     }
79 
80     JSHClass *hclass = JSHClass::Cast(tsManager_->GetValueFromCache(hclassIndex).GetTaggedObject());
81     PropertyLookupResult plr = JSHClass::LookupPropertyInAotHClass(thread_, hclass, key_);
82     info.Set(hclassIndex, plr);
83 
84     if (IsLoading()) {
85         return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor());
86     }
87 
88     return (plr.IsFound() && plr.IsLocal() && !plr.IsAccessor() && plr.IsWritable());
89 }
90 
ComputePolymorphism(ChunkVector<ObjectAccessInfo> & infos)91 bool ObjectAccessHelper::ComputePolymorphism(ChunkVector<ObjectAccessInfo> &infos)
92 {
93     DISALLOW_GARBAGE_COLLECTION;
94     ASSERT(tsManager_->IsUnionTypeKind(type_));
95     JSHandle<TSUnionType> unionType(tsManager_->GetTSType(type_.GetGTRef()));
96     TaggedArray *components = TaggedArray::Cast(unionType->GetComponents().GetTaggedObject());
97     uint32_t length = components->GetLength();
98     for (uint32_t i = 0; i < length; ++i) {
99         GlobalTSTypeRef gt(components->Get(i).GetInt());
100         GateType type = GateType(gt);
101         ObjectAccessInfo info(type);
102         TSTypeKind kind = tsManager_->GetTypeKind(gt);
103         switch (kind) {
104             case TSTypeKind::CLASS_INSTANCE: {
105                 if (!ComputeForClassInstance(info)) {
106                     return false;
107                 }
108                 break;
109             }
110             case TSTypeKind::CLASS:
111             case TSTypeKind::OBJECT: {
112                 if (!ComputeForClassOrObject(info)) {
113                     return false;
114                 }
115                 break;
116             }
117             default:
118                 return false;
119         }
120         infos.emplace_back(info);
121     }
122 
123     return infos.size() <= POLYMORPHIC_MAX_SIZE;
124 }
125 }  // namespace panda::ecmascript::kungfu
126