• 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 
16 #ifndef ECMASCRIPT_CLASS_INFO_EXTRACTOR_H
17 #define ECMASCRIPT_CLASS_INFO_EXTRACTOR_H
18 
19 #include "js_tagged_value-inl.h"
20 
21 namespace panda::ecmascript {
22 // ClassInfoExtractor will analyze and extract the contents from class literal to keys, properties and elements(both
23 // non-static and static), later generate the complete hclass (both prototype and constructor) based on keys.
24 // Attention: keys accessor stores the property key and properties accessor stores the property value, but elements
25 // accessor stores the key-value pair abuttally.
26 class ClassInfoExtractor : public TaggedObject {
27 public:
28     static constexpr uint8_t NON_STATIC_RESERVED_LENGTH = 1;
29     static constexpr uint8_t STATIC_RESERVED_LENGTH = 3;
30 
31     static constexpr uint8_t CONSTRUCTOR_INDEX = 0;
32     static constexpr uint8_t LENGTH_INDEX = 0;
33     static constexpr uint8_t NAME_INDEX = 1;
34     static constexpr uint8_t PROTOTYPE_INDEX = 2;
35 
36     struct ExtractContentsDetail {
37         uint32_t extractBegin;
38         uint32_t extractEnd;
39         uint8_t fillStartLoc;
40         JSMethod *ctorMethod;
41     };
42 
43     CAST_CHECK(ClassInfoExtractor, IsClassInfoExtractor);
44 
45     static void BuildClassInfoExtractorFromLiteral(JSThread *thread, JSHandle<ClassInfoExtractor> &extractor,
46                                                    const JSHandle<TaggedArray> &literal);
47 
48     static constexpr size_t PROTOTYPE_HCLASS_OFFSET = TaggedObjectSize();
49     ACCESSORS(PrototypeHClass, PROTOTYPE_HCLASS_OFFSET, NON_STATIC_KEYS_OFFSET)
50     ACCESSORS(NonStaticKeys, NON_STATIC_KEYS_OFFSET, NON_STATIC_PROPERTIES_OFFSET)
51     ACCESSORS(NonStaticProperties, NON_STATIC_PROPERTIES_OFFSET, NON_STATIC_ELEMENTS_OFFSET)
52     ACCESSORS(NonStaticElements, NON_STATIC_ELEMENTS_OFFSET, CONSTRUCTOR_HCLASS_OFFSET)
53     ACCESSORS(ConstructorHClass, CONSTRUCTOR_HCLASS_OFFSET, STATIC_KEYS_OFFSET)
54     ACCESSORS(StaticKeys, STATIC_KEYS_OFFSET, STATIC_PROPERTIES_OFFSET)
55     ACCESSORS(StaticProperties, STATIC_PROPERTIES_OFFSET, STATIC_ELEMENTS_OFFSET)
56     ACCESSORS(StaticElements, STATIC_ELEMENTS_OFFSET, CONSTRUCTOR_METHOD_OFFSET)
57     ACCESSORS_NATIVE_FIELD(ConstructorMethod, JSMethod, CONSTRUCTOR_METHOD_OFFSET, BIT_FIELD_OFFSET)
58     ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET)
59     DEFINE_ALIGN_SIZE(LAST_OFFSET);
60 
61     // define BitField
62     static constexpr size_t NON_STATIC_BITS = 1;
63     static constexpr size_t STATIC_BITS = 1;
64     FIRST_BIT_FIELD(BitField, NonStaticWithElements, bool, NON_STATIC_BITS)
65     NEXT_BIT_FIELD(BitField, StaticWithElements, bool, STATIC_BITS, NonStaticWithElements)
66 
67     DECL_VISIT_OBJECT(PROTOTYPE_HCLASS_OFFSET, CONSTRUCTOR_METHOD_OFFSET)
68     DECL_DUMP()
69 
70 private:
71     static bool ExtractAndReturnWhetherWithElements(JSThread *thread, const JSHandle<TaggedArray> &literal,
72                                                     const ExtractContentsDetail &detail,
73                                                     JSHandle<TaggedArray> &keys, JSHandle<TaggedArray> &properties,
74                                                     JSHandle<TaggedArray> &elements);
75 
76     static JSHandle<JSHClass> CreatePrototypeHClass(JSThread *thread, JSHandle<TaggedArray> &keys,
77                                                     JSHandle<TaggedArray> &properties);
78 
79     static JSHandle<JSHClass> CreateConstructorHClass(JSThread *thread, JSHandle<TaggedArray> &keys,
80                                                       JSHandle<TaggedArray> &properties);
81 };
82 
83 enum class ClassPropertyType : uint8_t { NON_STATIC = 0, STATIC };
84 
85 class ClassHelper {
86 public:
87     static JSHandle<JSFunction> DefineClassTemplate(JSThread *thread, JSHandle<ClassInfoExtractor> &extractor,
88                                                     const JSHandle<ConstantPool> &constantpool);
89 
90 private:
91     static JSHandle<NameDictionary> BuildDictionaryPropeties(JSThread *thread, const JSHandle<JSObject> &object,
92                                                              JSHandle<TaggedArray> &keys,
93                                                              JSHandle<TaggedArray> &properties, ClassPropertyType type,
94                                                              const JSHandle<ConstantPool> &constantpool);
95 
96     static void HandleElementsProperties(JSThread *thread, const JSHandle<JSObject> &object,
97                                          JSHandle<TaggedArray> &elements, const JSHandle<ConstantPool> &constantpool);
98 };
99 }  // namespace panda::ecmascript
100 #endif  // ECMASCRIPT_CLASS_INFO_EXTRACTOR_H
101