1 /** 2 * Copyright (c) 2021-2022 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 panda { 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_CLASSROOT << 1U; 32 static constexpr uint32_t STRING = HCLASS << 1U; 33 static constexpr uint32_t ARRAY = STRING << 1U; 34 static constexpr uint32_t NATIVE_POINTER = ARRAY << 1U; 35 static constexpr uint32_t IS_DICTIONARY_ARRAY = NATIVE_POINTER << 1U; 36 static constexpr uint32_t IS_BUILTINS_CTOR = IS_DICTIONARY_ARRAY << 1U; 37 static constexpr uint32_t IS_CALLABLE = IS_BUILTINS_CTOR << 1U; 38 static constexpr uint32_t IS_FREE_OBJECT = IS_CALLABLE << 1U; 39 40 public: HClass(uint32_t flags,panda_file::SourceLang lang)41 HClass(uint32_t flags, panda_file::SourceLang lang) : BaseClass(lang) 42 { 43 SetFlags(flags | BaseClass::DYNAMIC_CLASS); 44 } 45 IsFreeObject()46 inline bool IsFreeObject() const 47 { 48 return (GetFlags() & IS_FREE_OBJECT) != 0; 49 } 50 IsNativePointer()51 inline bool IsNativePointer() const 52 { 53 return (GetFlags() & NATIVE_POINTER) != 0; 54 } 55 IsArray()56 inline bool IsArray() const 57 { 58 return (GetFlags() & ARRAY) != 0; 59 } 60 IsString()61 inline bool IsString() const 62 { 63 return (GetFlags() & STRING) != 0; 64 } 65 IsHClass()66 inline bool IsHClass() const 67 { 68 return (GetFlags() & HCLASS) != 0; 69 } 70 IsDictionary()71 bool IsDictionary() const 72 { 73 return (BaseClass::GetFlags() & IS_DICTIONARY_ARRAY) != 0U; 74 } 75 IsBuiltinsConstructor()76 bool IsBuiltinsConstructor() const 77 { 78 return (BaseClass::GetFlags() & IS_BUILTINS_CTOR) != 0U; 79 } 80 IsCallable()81 bool IsCallable() const 82 { 83 return (BaseClass::GetFlags() & IS_CALLABLE) != 0U; 84 } 85 MarkFieldAsNative(size_t offset)86 void MarkFieldAsNative(size_t offset) 87 { 88 ASSERT(offset <= MaxNativeFieldOffset()); 89 native_fields_ |= FieldOffsetToMask(offset); 90 } 91 IsNativeField(size_t offset)92 bool IsNativeField(size_t offset) const 93 { 94 if (offset > MaxNativeFieldOffset()) { 95 return false; 96 } 97 98 return (native_fields_ & FieldOffsetToMask(offset)) != 0; 99 } 100 GetNativeFieldMask()101 uint32_t GetNativeFieldMask() const 102 { 103 return native_fields_; 104 } 105 SetNativeFieldMask(uint32_t mask)106 void SetNativeFieldMask(uint32_t mask) 107 { 108 native_fields_ = mask; 109 } 110 GetDataOffset()111 static constexpr size_t GetDataOffset() 112 { 113 return MEMBER_OFFSET(HClass, data_); 114 } 115 116 ~HClass() = default; 117 118 DEFAULT_COPY_SEMANTIC(HClass); 119 DEFAULT_MOVE_SEMANTIC(HClass); 120 121 protected: SetFlags(uint32_t flags)122 void SetFlags(uint32_t flags) 123 { 124 ASSERT(flags & BaseClass::DYNAMIC_CLASS); 125 BaseClass::SetFlags(flags); 126 } 127 128 private: MaxNativeFieldOffset()129 static size_t MaxNativeFieldOffset() 130 { 131 size_t max_index = std::numeric_limits<decltype(native_fields_)>::digits - 1; 132 return ObjectHeader::ObjectHeaderSize() + max_index * TaggedValue::TaggedTypeSize(); 133 } 134 FieldOffsetToMask(size_t offset)135 static uint32_t FieldOffsetToMask(size_t offset) 136 { 137 uint32_t index = (offset - ObjectHeader::ObjectHeaderSize()) / TaggedValue::TaggedTypeSize(); 138 return 1U << index; 139 } 140 141 friend class coretypes::DynClass; 142 143 uint32_t native_fields_ {0}; 144 145 // Data for language extension flags 146 // TODO(maksenov): maybe merge this with BaseClass flags 147 FIELD_UNUSED uint64_t data_ {0}; 148 }; 149 150 } // namespace panda 151 152 #endif // PANDA_RUNTIME_HCLASS_H_ 153