1 /** 2 * Copyright (c) 2021-2024 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 #ifndef PANDA_RUNTIME_HCLASS_H_ 16 #define PANDA_RUNTIME_HCLASS_H_ 17 18 #include "mem/mem.h" 19 #include "mem/vm_handle.h" 20 #include "runtime/include/class.h" 21 22 namespace ark { 23 24 namespace coretypes { 25 class DynClass; 26 } // namespace coretypes 27 28 // Class for objects in DYNAMIC_CLASS languages like JavaScript 29 class HClass : public BaseClass { 30 public: 31 static constexpr uint32_t HCLASS = DYNAMIC_CLASS << 1U; 32 static constexpr uint32_t STRING = HCLASS << 1U; 33 static constexpr uint32_t ARRAY = STRING << 1U; 34 static constexpr uint32_t BIGINT = ARRAY << 1U; 35 static constexpr uint32_t NATIVE_POINTER = BIGINT << 1U; 36 static constexpr uint32_t IS_DICTIONARY_ARRAY = NATIVE_POINTER << 1U; 37 static constexpr uint32_t IS_BUILTINS_CTOR = IS_DICTIONARY_ARRAY << 1U; 38 static constexpr uint32_t IS_CALLABLE = IS_BUILTINS_CTOR << 1U; 39 static constexpr uint32_t IS_FREE_OBJECT = IS_CALLABLE << 1U; 40 41 public: HClass(uint32_t flags, panda_file::SourceLang lang)42 HClass(uint32_t flags, panda_file::SourceLang lang) : BaseClass(lang) 43 { 44 SetFlags(flags | BaseClass::DYNAMIC_CLASS); 45 } 46 IsFreeObject() const47 inline bool IsFreeObject() const 48 { 49 return (GetFlags() & IS_FREE_OBJECT) != 0; 50 } 51 IsNativePointer() const52 inline bool IsNativePointer() const 53 { 54 return (GetFlags() & NATIVE_POINTER) != 0; 55 } 56 IsArray() const57 inline bool IsArray() const 58 { 59 return (GetFlags() & ARRAY) != 0; 60 } 61 IsString() const62 inline bool IsString() const 63 { 64 return (GetFlags() & STRING) != 0; 65 } 66 IsHClass() const67 inline bool IsHClass() const 68 { 69 return (GetFlags() & HCLASS) != 0; 70 } 71 IsDictionary() const72 bool IsDictionary() const 73 { 74 return (BaseClass::GetFlags() & IS_DICTIONARY_ARRAY) != 0U; 75 } 76 IsBuiltinsConstructor() const77 bool IsBuiltinsConstructor() const 78 { 79 return (BaseClass::GetFlags() & IS_BUILTINS_CTOR) != 0U; 80 } 81 IsCallable() const82 bool IsCallable() const 83 { 84 return (BaseClass::GetFlags() & IS_CALLABLE) != 0U; 85 } 86 MarkFieldAsNative(size_t offset)87 void MarkFieldAsNative(size_t offset) 88 { 89 ASSERT(offset <= MaxNativeFieldOffset()); 90 nativeFields_ |= FieldOffsetToMask(offset); 91 } 92 IsNativeField(size_t offset) const93 bool IsNativeField(size_t offset) const 94 { 95 if (offset > MaxNativeFieldOffset()) { 96 return false; 97 } 98 99 return (nativeFields_ & FieldOffsetToMask(offset)) != 0; 100 } 101 GetNativeFieldMask() const102 uint32_t GetNativeFieldMask() const 103 { 104 return nativeFields_; 105 } 106 SetNativeFieldMask(uint32_t mask)107 void SetNativeFieldMask(uint32_t mask) 108 { 109 nativeFields_ = mask; 110 } 111 FieldOffsetToMask(size_t offset)112 static constexpr uint32_t FieldOffsetToMask(size_t offset) 113 { 114 uint32_t index = (offset - ObjectHeader::ObjectHeaderSize()) / TaggedValue::TaggedTypeSize(); 115 return 1U << index; 116 } 117 GetCallableMask()118 static constexpr uint32_t GetCallableMask() 119 { 120 return IS_CALLABLE; 121 } 122 GetDataOffset()123 static constexpr size_t GetDataOffset() 124 { 125 return MEMBER_OFFSET(HClass, data_); 126 } 127 128 ~HClass() = default; 129 130 DEFAULT_COPY_SEMANTIC(HClass); 131 DEFAULT_MOVE_SEMANTIC(HClass); 132 133 protected: SetFlags(uint32_t flags)134 void SetFlags(uint32_t flags) 135 { 136 ASSERT(flags & BaseClass::DYNAMIC_CLASS); 137 BaseClass::SetFlags(flags); 138 } 139 140 private: MaxNativeFieldOffset()141 static size_t MaxNativeFieldOffset() 142 { 143 size_t maxIndex = std::numeric_limits<decltype(nativeFields_)>::digits - 1; 144 return ObjectHeader::ObjectHeaderSize() + maxIndex * TaggedValue::TaggedTypeSize(); 145 } 146 147 friend class coretypes::DynClass; 148 149 uint32_t nativeFields_ {0}; 150 151 // Data for language extension flags 152 // NOTE(maksenov): maybe merge this with BaseClass flags 153 FIELD_UNUSED uint64_t data_ {0}; 154 }; 155 156 } // namespace ark 157 158 #endif // PANDA_RUNTIME_HCLASS_H_ 159