• 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/vtable.h"
17 
18 namespace panda::ecmascript {
CreateTuple(const JSThread * thread,JSTaggedValue phc,const JSHandle<JSTaggedValue> & owner,uint32_t propIndex)19 VTable::Tuple VTable::CreateTuple(const JSThread *thread, JSTaggedValue phc,
20                                   const JSHandle<JSTaggedValue> &owner, uint32_t propIndex)
21 {
22     DISALLOW_GARBAGE_COLLECTION;
23     JSHClass *phcPoint = JSHClass::Cast(phc.GetTaggedObject());
24     LayoutInfo *layoutInfo = LayoutInfo::Cast(phcPoint->GetLayout().GetTaggedObject());
25     JSHandle<JSTaggedValue> name(thread, layoutInfo->GetKey(propIndex));
26 
27     // get type
28     JSTaggedValue typeVal;
29     PropertyAttributes attr = layoutInfo->GetAttr(propIndex);
30     if (attr.IsAccessor()) {
31         typeVal = JSTaggedValue(VTable::TypeKind::ACCESSOR);
32     } else {
33         typeVal = JSTaggedValue(VTable::TypeKind::FUNCTION);
34     }
35     JSHandle<JSTaggedValue> type(thread, typeVal);
36 
37     // get offset
38     uint32_t propsNumber = phcPoint->NumberOfProps();
39     int entry = layoutInfo->FindElementWithCache(thread, phcPoint, name.GetTaggedValue(), propsNumber);
40     ASSERT(entry != -1);
41     uint32_t offsetInt = phcPoint->GetInlinedPropertiesOffset(static_cast<uint32_t>(entry));
42     JSHandle<JSTaggedValue> offset(thread, JSTaggedValue(offsetInt));
43 
44     CVector<JSHandle<JSTaggedValue>> vec {name, type, owner, offset};
45     return VTable::Tuple(vec);
46 }
47 
GetTuple(const JSThread * thread,uint32_t tupleIdx) const48 VTable::Tuple VTable::GetTuple(const JSThread *thread, uint32_t tupleIdx) const
49 {
50     CVector<JSHandle<JSTaggedValue>> vec;
51     for (uint32_t loc = 0; loc < ITEM_NUM; ++loc) {
52         JSTaggedValue val = Get(tupleIdx * TUPLE_SIZE + loc);
53         vec.emplace_back(JSHandle<JSTaggedValue>(thread, val));
54     }
55     return Tuple(vec);
56 }
57 
SetByIndex(const JSThread * thread,uint32_t idx,const VTable::Tuple & tuple)58 void VTable::SetByIndex(const JSThread *thread, uint32_t idx, const VTable::Tuple &tuple)
59 {
60     uint32_t beginIdx = idx * TUPLE_SIZE;
61     for (uint32_t i = 0; i < TUPLE_SIZE; ++i) {
62         uint32_t currIdx = beginIdx + i;
63         JSTaggedValue val = tuple.GetItem(TupleItem(i)).GetTaggedValue();
64         Set(thread, currIdx, val);
65     }
66 }
67 
Trim(const JSThread * thread,uint32_t newLength)68 void VTable::Trim(const JSThread *thread, uint32_t newLength)
69 {
70     TaggedArray::Trim(thread, newLength * VTable::TUPLE_SIZE);
71 }
72 
GetTupleIndexByName(JSTaggedValue name) const73 int VTable::GetTupleIndexByName(JSTaggedValue name) const
74 {
75     DISALLOW_GARBAGE_COLLECTION;
76     uint32_t len = GetNumberOfTuples();
77     if (len == 0) {
78         return -1;
79     }
80 
81     [[maybe_unused]] EcmaString *str = EcmaString::Cast(name.GetTaggedObject());
82     ASSERT_PRINT(EcmaStringAccessor(str).IsInternString(), "The name of the property is not an intern string");
83 
84     for (uint32_t index = 0; index < len; ++index) {
85         JSTaggedValue nameVal = GetTupleItem(index, VTable::TupleItem::NAME);
86         if (nameVal == name) {
87             return index;
88         }
89     }
90 
91     return -1;
92 }
93 
Find(JSTaggedValue name) const94 bool VTable::Find(JSTaggedValue name) const
95 {
96     return GetTupleIndexByName(name) != -1;
97 }
98 
Copy(const JSThread * thread,const JSHandle<VTable> & vtable)99 JSHandle<VTable> VTable::Copy(const JSThread *thread, const JSHandle<VTable> &vtable)
100 {
101     uint32_t length = vtable->GetLength();
102     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
103     JSHandle<TaggedArray> copyVtable = factory->CopyArray(JSHandle<TaggedArray>(vtable), length, length);
104     return JSHandle<VTable>(copyVtable);
105 }
106 }  // namespace panda::ecmascript
107