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_TS_TYPES_TS_TYPE_H 17 #define ECMASCRIPT_TS_TYPES_TS_TYPE_H 18 19 #include "ecmascript/ecma_macros.h" 20 #include "ecmascript/ts_types/ts_manager.h" 21 #include "ecmascript/ts_types/ts_obj_layout_info.h" 22 23 namespace panda::ecmascript { 24 #define ACCESSORS_ATTACHED_TYPEREF(name, offset, endOffset) \ 25 ACCESSORS_PRIMITIVE_FIELD(name##RawData, uint32_t, offset, endOffset) \ 26 inline void Set##name(GlobalTSTypeRef type) \ 27 { \ 28 Set##name##RawData(type.GetType()); \ 29 } \ 30 inline GlobalTSTypeRef Get##name() const \ 31 { \ 32 return GlobalTSTypeRef(Get##name##RawData()); \ 33 } 34 35 class TSType : public TaggedObject { 36 public: 37 static constexpr size_t GT_OFFSET = TaggedObjectSize(); 38 static constexpr size_t ONE_BIT = 1; 39 static constexpr size_t TWO_BITS = 2; 40 Cast(const TaggedObject * object)41 inline static TSType *Cast(const TaggedObject *object) 42 { 43 return static_cast<TSType *>(const_cast<TaggedObject *>(object)); 44 } 45 46 ACCESSORS_ATTACHED_TYPEREF(GT, GT_OFFSET, LAST_OFFSET); 47 DEFINE_ALIGN_SIZE(LAST_OFFSET); 48 }; 49 50 class TSObjectType : public TSType { 51 public: 52 CAST_CHECK(TSObjectType, IsTSObjectType); 53 54 static constexpr size_t PROPERTIES_OFFSET = TSType::SIZE; 55 56 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, JSHandle<TSObjectType> objectType, 57 JSHandle<JSTaggedValue> propName); 58 59 static bool UpdatePropTypeGT(JSThread *thread, JSHandle<TSObjectType> objectType, 60 JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT); 61 62 static GlobalTSTypeRef GetIndexSignType(JSThread *thread, const JSHandle<TSObjectType> &objectType, 63 const uint32_t typeId); 64 65 ACCESSORS(ObjLayoutInfo, PROPERTIES_OFFSET, INDEX_SIGNS_OFFSET); 66 ACCESSORS(IndexSigns, INDEX_SIGNS_OFFSET, SIZE); 67 68 DECL_VISIT_OBJECT(PROPERTIES_OFFSET, SIZE) 69 DECL_DUMP() 70 }; 71 72 class TSClassType : public TSType { 73 public: 74 CAST_CHECK(TSClassType, IsTSClassType); 75 76 static constexpr size_t INSTANCE_TYPE_OFFSET = TSType::SIZE; 77 78 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType, 79 JSHandle<JSTaggedValue> propName); 80 81 static GlobalTSTypeRef GetSuperPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType, 82 JSHandle<JSTaggedValue> propName, PropertyType propType); 83 84 static GlobalTSTypeRef GetNonStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType, 85 JSHandle<JSTaggedValue> propName); 86 87 static void UpdateNonStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType, 88 JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT); 89 90 static void UpdateStaticPropTypeGT(JSThread *thread, JSHandle<TSClassType> classType, 91 JSHandle<JSTaggedValue> propName, GlobalTSTypeRef newGT); 92 93 ACCESSORS(InstanceType, INSTANCE_TYPE_OFFSET, CONSTRUCTOR_TYPE_OFFSET); 94 ACCESSORS(ConstructorType, CONSTRUCTOR_TYPE_OFFSET, PROTOTYPE_TYPE_OFFSET); 95 ACCESSORS(PrototypeType, PROTOTYPE_TYPE_OFFSET, NAME_OFFSET); 96 ACCESSORS(Name, NAME_OFFSET, INDEX_SIGNS_OFFSET); 97 ACCESSORS(IndexSigns, INDEX_SIGNS_OFFSET, EXTENSION_GT_OFFSET); 98 ACCESSORS_ATTACHED_TYPEREF(ExtensionGT, EXTENSION_GT_OFFSET, BIT_FIELD_OFFSET); 99 ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET); 100 DEFINE_ALIGN_SIZE(LAST_OFFSET); 101 102 // define BitField 103 FIRST_BIT_FIELD(BitField, HasLinked, bool, ONE_BIT); 104 NEXT_BIT_FIELD(BitField, HasPassedSubtypingCheck, bool, ONE_BIT, HasLinked); 105 NEXT_BIT_FIELD(BitField, HasAnalysedInitialization, bool, ONE_BIT, HasPassedSubtypingCheck); 106 NEXT_BIT_FIELD(BitField, HasEscapedThisInConstructor, bool, ONE_BIT, HasAnalysedInitialization); 107 NEXT_BIT_FIELD(BitField, HasSuperCallInConstructor, bool, ONE_BIT, HasEscapedThisInConstructor); 108 DECL_VISIT_OBJECT(INSTANCE_TYPE_OFFSET,EXTENSION_GT_OFFSET)109 DECL_VISIT_OBJECT(INSTANCE_TYPE_OFFSET, EXTENSION_GT_OFFSET) 110 DECL_DUMP() 111 112 // Judgment base classType by extends typeId, ts2abc write 0 in base class type extends domain 113 inline static bool IsBaseClassType(int extendsTypeId) 114 { 115 const int baseClassTypeExtendsTypeId = 0; 116 return extendsTypeId == baseClassTypeExtendsTypeId; 117 } 118 IsBaseClassType()119 inline bool IsBaseClassType() const 120 { 121 return GetExtensionGT().IsDefault(); 122 } 123 }; 124 125 class TSClassInstanceType : public TSType { 126 public: 127 CAST_CHECK(TSClassInstanceType, IsTSClassInstanceType); 128 129 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, JSHandle<TSClassInstanceType> classInstanceType, 130 JSHandle<JSTaggedValue> propName); 131 132 static GlobalTSTypeRef GetIndexSignType(JSThread *thread, const JSHandle<TSClassInstanceType> &classInstanceType, 133 const uint32_t typeId); 134 135 static constexpr size_t CLASS_GT_OFFSET = TSType::SIZE; 136 static constexpr size_t CREATE_CLASS_OFFSET = 1; 137 ACCESSORS_ATTACHED_TYPEREF(ClassGT, CLASS_GT_OFFSET, LAST_OFFSET); 138 DEFINE_ALIGN_SIZE(LAST_OFFSET); 139 140 DECL_DUMP() 141 }; 142 143 class TSUnionType : public TSType { 144 public: 145 CAST_CHECK(TSUnionType, IsTSUnionType); 146 147 bool IsEqual(JSHandle<TSUnionType> unionB); 148 149 static constexpr size_t COMPONENTS_OFFSET = TSType::SIZE; 150 ACCESSORS(Components, COMPONENTS_OFFSET, SIZE); // the gt collection of union type components 151 152 DECL_VISIT_OBJECT(COMPONENTS_OFFSET, SIZE) 153 DECL_DUMP() 154 }; 155 156 class TSInterfaceType : public TSType { 157 public: 158 CAST_CHECK(TSInterfaceType, IsTSInterfaceType); 159 160 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, JSHandle<TSInterfaceType> classInstanceType, 161 JSHandle<JSTaggedValue> propName); 162 163 static GlobalTSTypeRef GetIndexSignType(JSThread *thread, const JSHandle<TSInterfaceType> &interfaceType, 164 const uint32_t typeId); 165 166 static constexpr size_t EXTENDS_TYPE_ID_OFFSET = TSType::SIZE; 167 ACCESSORS(Extends, EXTENDS_TYPE_ID_OFFSET, KEYS_OFFSET); 168 ACCESSORS(Fields, KEYS_OFFSET, INDEX_SIGNS_OFFSET); 169 ACCESSORS(IndexSigns, INDEX_SIGNS_OFFSET, SIZE); 170 171 DECL_VISIT_OBJECT(EXTENDS_TYPE_ID_OFFSET, SIZE) 172 DECL_DUMP() 173 }; 174 175 class TSFunctionType : public TSType { 176 public: 177 CAST_CHECK(TSFunctionType, IsTSFunctionType); 178 GetLength()179 uint32_t GetLength() const 180 { 181 TaggedArray* parameterTypes = TaggedArray::Cast(GetParameterTypes().GetTaggedObject()); 182 return parameterTypes->GetLength(); 183 } 184 185 GlobalTSTypeRef GetParameterTypeGT(int index) const; 186 187 static constexpr size_t NAME_OFFSET = TSType::SIZE; 188 ACCESSORS(Name, NAME_OFFSET, PARAMETER_TYPES_OFFSET); 189 ACCESSORS(ParameterTypes, PARAMETER_TYPES_OFFSET, RETURN_GT_OFFSET); 190 ACCESSORS_ATTACHED_TYPEREF(ReturnGT, RETURN_GT_OFFSET, THIS_GT_OFFSET); 191 ACCESSORS_ATTACHED_TYPEREF(ThisGT, THIS_GT_OFFSET, BIT_FIELD_OFFSET); 192 ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, METHOD_OFFSET_OFFSET) 193 ACCESSORS_PRIMITIVE_FIELD(MethodOffset, uint32_t, METHOD_OFFSET_OFFSET, LAST_OFFSET) 194 DEFINE_ALIGN_SIZE(LAST_OFFSET); 195 196 enum class Visibility : uint8_t { PUBLIC = 0, PRIVATE, PROTECTED }; 197 198 // define BitField 199 FIRST_BIT_FIELD(BitField, Visibility, Visibility, TWO_BITS); 200 NEXT_BIT_FIELD(BitField, Static, bool, ONE_BIT, Visibility); 201 NEXT_BIT_FIELD(BitField, Async, bool, ONE_BIT, Static); 202 NEXT_BIT_FIELD(BitField, Generator, bool, ONE_BIT, Async); 203 NEXT_BIT_FIELD(BitField, IsGetterSetter, bool, ONE_BIT, Generator); 204 NEXT_BIT_FIELD(BitField, IsAbstract, bool, ONE_BIT, IsGetterSetter); 205 NEXT_BIT_FIELD(BitField, IsSignature, bool, ONE_BIT, IsAbstract); 206 NEXT_BIT_FIELD(BitField, IsFastCall, bool, ONE_BIT, IsSignature); 207 NEXT_BIT_FIELD(BitField, IsFastCallVaild, bool, ONE_BIT, IsFastCall); 208 NEXT_BIT_FIELD(BitField, IsMethodOffsetVaild, bool, ONE_BIT, IsFastCallVaild); 209 NEXT_BIT_FIELD(BitField, IsNoGC, bool, ONE_BIT, IsMethodOffsetVaild); 210 211 DECL_VISIT_OBJECT(NAME_OFFSET, RETURN_GT_OFFSET) 212 DECL_DUMP() 213 }; 214 215 class TSArrayType : public TSType { 216 public: 217 CAST_CHECK(TSArrayType, IsTSArrayType); 218 static constexpr size_t ELEMENT_GT_OFFSET = TSType::SIZE; 219 220 ACCESSORS_ATTACHED_TYPEREF(ElementGT, ELEMENT_GT_OFFSET, LAST_OFFSET); 221 DEFINE_ALIGN_SIZE(LAST_OFFSET); 222 223 DECL_DUMP() 224 }; 225 226 class TSIteratorInstanceType : public TSType { 227 public: 228 CAST_CHECK(TSIteratorInstanceType, IsTSIteratorInstanceType); 229 static constexpr size_t KIND_GT_OFFSET = TSType::SIZE; 230 231 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, JSHandle<TSIteratorInstanceType> instanceType, 232 JSHandle<JSTaggedValue> propName); 233 234 ACCESSORS_ATTACHED_TYPEREF(KindGT, KIND_GT_OFFSET, ELEMENT_GT_OFFSET); 235 ACCESSORS_ATTACHED_TYPEREF(ElementGT, ELEMENT_GT_OFFSET, LAST_OFFSET); 236 DEFINE_ALIGN_SIZE(LAST_OFFSET); 237 238 DECL_DUMP() 239 }; 240 241 class TSNamespaceType : public TSType { 242 public: 243 CAST_CHECK(TSNamespaceType, IsTSNamespaceType); 244 static constexpr size_t PROTOTYPE_TYPE_OFFSET = TSType::SIZE; 245 246 ACCESSORS(PropertyType, PROTOTYPE_TYPE_OFFSET, SIZE); 247 248 static void AddKeyAndValue(const JSThread *thread, const JSHandle<TSNamespaceType> &namespaceType, 249 const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value); 250 251 static GlobalTSTypeRef GetPropTypeGT(JSThread *thread, const JSHandle<TSNamespaceType> &namespaceType, 252 const JSHandle<JSTaggedValue> &propName); 253 254 DECL_VISIT_OBJECT(PROTOTYPE_TYPE_OFFSET, SIZE) 255 DECL_DUMP() 256 }; 257 } // namespace panda::ecmascript 258 259 #endif // ECMASCRIPT_TS_TYPES_TS_TYPE_H 260