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