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 #ifndef ECMASCRIPT_PROPERTY_ACCESSOR_H
17 #define ECMASCRIPT_PROPERTY_ACCESSOR_H
18 
19 #include "ecmascript/js_handle.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/js_thread.h"
22 
23 namespace panda::ecmascript {
24 class JSObject;
25 class TaggedArray;
26 class PropertyAccessor {
27 public:
28     PropertyAccessor(JSThread *thread, JSHandle<JSTaggedValue> object);
29 
30     JSHandle<JSTaggedValue> GetKeysFast();
31     JSHandle<JSTaggedValue> GetKeysSlow();
32 
33     JSHandle<JSTaggedValue> GetCachedHclass();
34     uint32_t GetActualKeyLength() const;
35 
36 private:
37     void PreLoad();
38     void CollectPrototypeInfo();
39     void InitSimplePropertiesEnumCache();
40     void AccumulateKeyLength(uint32_t length);
41     void AccumulateShadowKeyLength(uint32_t length);
42     void PushRemainingKeys(JSHandle<JSObject> object, std::vector<JSHandle<TaggedArray>> &remainings);
43     void MergeRemainings(const std::vector<JSHandle<TaggedArray>> &remainings,
44                          const std::vector<JSHandle<JSTaggedValue>> &visited);
45     void SetActualKeyLength(uint32_t length);
46     void AddKeysEndIfNeeded(JSHandle<TaggedArray> keys);
47     void TryInitEnumCacheWithProtoChainInfo();
48 
49     JSThread *thread_{nullptr};
50     JSMutableHandle<JSTaggedValue> receiver_;
51     JSMutableHandle<JSTaggedValue> fastKeysArray_;
52     JSMutableHandle<JSTaggedValue> cachedHclass_;
53     uint32_t keyLength_ {0};
54     uint32_t shadowKeyLength_ {0};
55     // receiver has no elements, and is not dictionary mode and has empty prototype
56     bool onlyHasSimpleProperties_ {true};
57     bool canUseEnumCache_ {true};
58     bool hasSlowProperties_ {false};
59     JSMutableHandle<TaggedArray> slowKeysArray_;
60     uint32_t acutalKeyLength_ {0};
61 };
62 }  // namespace panda::ecmascript
63 #endif  // ECMASCRIPT_PROPERTY_ACCESSOR_H
64