1 /* 2 * Copyright (c) 2025 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 COMMON_INTERFACES_OBJECTS_BASE_OBJECT_DISPATCHER_H 17 #define COMMON_INTERFACES_OBJECTS_BASE_OBJECT_DISPATCHER_H 18 19 #include "objects/base_object.h" 20 #include "objects/base_object_accessor.h" 21 #include "objects/base_object_descriptor.h" 22 #include "objects/base_type.h" 23 #include "objects/base_type_converter.h" 24 #include "thread/thread_holder.h" 25 26 namespace common { 27 class BaseObjectDispatcher { 28 enum class ObjectType : uint8_t { STATIC = 0x0, DYNAMIC, UNKNOWN }; 29 public: 30 // Singleton GetDispatcher()31 static BaseObjectDispatcher& GetDispatcher() 32 { 33 static BaseObjectDispatcher instance; 34 return instance; 35 } 36 RegisterDynamicTypeConverter(DynamicTypeConverterInterface * dynTypeConverter)37 void RegisterDynamicTypeConverter(DynamicTypeConverterInterface *dynTypeConverter) 38 { 39 dynTypeConverter_ = dynTypeConverter; 40 } 41 RegisterDynamicObjectAccessor(DynamicObjectAccessorInterface * dynObjAccessor)42 void RegisterDynamicObjectAccessor(DynamicObjectAccessorInterface *dynObjAccessor) 43 { 44 dynObjAccessor_ = dynObjAccessor; 45 } 46 RegisterDynamicObjectDescriptor(DynamicObjectDescriptorInterface * dynObjDescriptor)47 void RegisterDynamicObjectDescriptor(DynamicObjectDescriptorInterface *dynObjDescriptor) 48 { 49 dynObjDescriptor_ = dynObjDescriptor; 50 } 51 RegisterStaticTypeConverter(StaticTypeConverterInterface * stcTypeConverter)52 void RegisterStaticTypeConverter(StaticTypeConverterInterface *stcTypeConverter) 53 { 54 stcTypeConverter_ = stcTypeConverter; 55 } 56 RegisterStaticObjectAccessor(StaticObjectAccessorInterface * stcObjAccessor)57 void RegisterStaticObjectAccessor(StaticObjectAccessorInterface *stcObjAccessor) 58 { 59 stcObjAccessor_ = stcObjAccessor; 60 } 61 RegisterStaticObjectDescriptor(StaticObjectDescriptorInterface * stcObjDescriptor)62 void RegisterStaticObjectDescriptor(StaticObjectDescriptorInterface *stcObjDescriptor) 63 { 64 stcObjDescriptor_ = stcObjDescriptor; 65 } 66 67 template <ObjectType objType = ObjectType::UNKNOWN> GetTaggedProperty(ThreadHolder * thread,const BaseObject * obj,const char * name)68 JSTaggedValue GetTaggedProperty(ThreadHolder *thread, const BaseObject *obj, const char* name) const 69 { 70 if constexpr (objType == ObjectType::DYNAMIC) { 71 // fix(hewei): exceptions may occur, check here and return default value. 72 return dynObjAccessor_->GetProperty(thread, obj, name); 73 } else if constexpr (objType == ObjectType::STATIC) { 74 BoxedValue value = stcObjAccessor_->GetProperty(thread, obj, name); 75 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 76 return dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 77 } else { 78 if (obj->IsDynamic()) { 79 // fix(hewei): exceptions may occur, check here and return default value. 80 return dynObjAccessor_->GetProperty(thread, obj, name); 81 } else { 82 BoxedValue value = stcObjAccessor_->GetProperty(thread, obj, name); 83 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 84 return dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 85 } 86 } 87 } 88 89 template <ObjectType objType = ObjectType::UNKNOWN> GetBoxedProperty(ThreadHolder * thread,const BaseObject * obj,const char * name)90 BoxedValue GetBoxedProperty(ThreadHolder *thread, const BaseObject *obj, const char* name) const 91 { 92 if constexpr (objType == ObjectType::DYNAMIC) { 93 JSTaggedValue value = dynObjAccessor_->GetProperty(thread, obj, name); 94 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 95 return stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value)); 96 } else if constexpr (objType == ObjectType::STATIC) { 97 // fix(hewei): exceptions may occur, check here and return default value. 98 return stcObjAccessor_->GetProperty(thread, obj, name); 99 } else { 100 if (obj->IsDynamic()) { 101 JSTaggedValue value = dynObjAccessor_->GetProperty(thread, obj, name); 102 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 103 return stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value)); 104 } else { 105 // fix(hewei): exceptions may occur, check here and return default value. 106 return stcObjAccessor_->GetProperty(thread, obj, name); 107 } 108 } 109 } 110 111 template <ObjectType objType = ObjectType::UNKNOWN> GetTaggedElementByIdx(ThreadHolder * thread,const BaseObject * obj,const uint32_t index)112 JSTaggedValue GetTaggedElementByIdx(ThreadHolder *thread, const BaseObject *obj, const uint32_t index) const 113 { 114 if constexpr (objType == ObjectType::DYNAMIC) { 115 // fix(hewei): exceptions may occur, check here and return default value. 116 return dynObjAccessor_->GetElementByIdx(thread, obj, index); 117 } else if constexpr (objType == ObjectType::STATIC) { 118 BoxedValue value = stcObjAccessor_->GetElementByIdx(thread, obj, index); 119 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 120 return dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 121 } else { 122 if (obj->IsDynamic()) { 123 // fix(hewei): exceptions may occur, check here and return default value. 124 return dynObjAccessor_->GetElementByIdx(thread, obj, index); 125 } else { 126 BoxedValue value = stcObjAccessor_->GetElementByIdx(thread, obj, index); 127 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 128 return dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 129 } 130 } 131 } 132 133 template <ObjectType objType = ObjectType::UNKNOWN> GetBoxedElementByIdx(ThreadHolder * thread,const BaseObject * obj,const uint32_t index)134 BoxedValue GetBoxedElementByIdx(ThreadHolder *thread, const BaseObject *obj, const uint32_t index) const 135 { 136 if constexpr (objType == ObjectType::DYNAMIC) { 137 JSTaggedValue value = dynObjAccessor_->GetElementByIdx(thread, obj, index); 138 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 139 return stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value)); 140 } else if constexpr (objType == ObjectType::STATIC) { 141 // fix(hewei): exceptions may occur, check here and return default value. 142 return stcObjAccessor_->GetElementByIdx(thread, obj, index); 143 } else { 144 if (obj->IsDynamic()) { 145 JSTaggedValue value = dynObjAccessor_->GetElementByIdx(thread, obj, index); 146 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 147 return stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value)); 148 } else { 149 // fix(hewei): exceptions may occur, check here and return default value. 150 return stcObjAccessor_->GetElementByIdx(thread, obj, index); 151 } 152 } 153 } 154 155 template <ObjectType objType = ObjectType::UNKNOWN> SetTaggedProperty(ThreadHolder * thread,BaseObject * obj,const char * name,JSTaggedValue value)156 bool SetTaggedProperty(ThreadHolder *thread, BaseObject *obj, const char* name, JSTaggedValue value) 157 { 158 if constexpr (objType == ObjectType::DYNAMIC) { 159 // fix(hewei): exceptions may occur, check here and return default value. 160 return dynObjAccessor_->SetProperty(thread, obj, name, value); 161 } else if constexpr (objType == ObjectType::STATIC) { 162 // fix(hewei): exceptions may occur, check here and return default value. 163 return stcObjAccessor_->SetProperty(thread, obj, name, 164 stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value))); 165 } else { 166 if (obj->IsDynamic()) { 167 // fix(hewei): exceptions may occur, check here and return default value. 168 return dynObjAccessor_->SetProperty(thread, obj, name, value); 169 } else { 170 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 171 return stcObjAccessor_->SetProperty( 172 thread, obj, name, stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value))); 173 } 174 } 175 } 176 177 template <ObjectType objType = ObjectType::UNKNOWN> SetBoxedProperty(ThreadHolder * thread,BaseObject * obj,const char * name,BoxedValue value)178 bool SetBoxedProperty(ThreadHolder *thread, BaseObject *obj, const char *name, BoxedValue value) 179 { 180 if constexpr (objType == ObjectType::DYNAMIC) { 181 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 182 auto wrapedValue = dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 183 return dynObjAccessor_->SetProperty(thread, obj, name, wrapedValue); 184 } else if constexpr (objType == ObjectType::STATIC) { 185 // fix(hewei): exceptions may occur, check here and return default value. 186 return stcObjAccessor_->SetProperty(thread, obj, name, value); 187 } else { 188 if (obj->IsDynamic()) { 189 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 190 auto wrapedValue = dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value)); 191 return dynObjAccessor_->SetProperty(thread, obj, name, wrapedValue); 192 } else { 193 // fix(hewei): exceptions may occur, check here and return default value. 194 return stcObjAccessor_->SetProperty(thread, obj, name, value); 195 } 196 } 197 } 198 199 template <ObjectType objType = ObjectType::UNKNOWN> SetTaggedElementByIdx(ThreadHolder * thread,BaseObject * obj,const uint32_t index,JSTaggedValue value)200 bool SetTaggedElementByIdx(ThreadHolder *thread, BaseObject *obj, const uint32_t index, JSTaggedValue value) 201 { 202 if constexpr (objType == ObjectType::DYNAMIC) { 203 // fix(hewei): exceptions may occur, check here and return default value. 204 return dynObjAccessor_->SetElementByIdx(thread, obj, index, value); 205 } else if constexpr (objType == ObjectType::STATIC) { 206 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 207 return stcObjAccessor_->SetElementByIdx(thread, obj, index, 208 stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value))); 209 } else { 210 if (obj->IsDynamic()) { 211 // fix(hewei): exceptions may occur, check here and return default value. 212 return dynObjAccessor_->SetElementByIdx(thread, obj, index, value); 213 } else { 214 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 215 return stcObjAccessor_->SetElementByIdx( 216 thread, obj, index, stcTypeConverter_->WrapBoxed(dynTypeConverter_->UnWrapTagged(value))); 217 } 218 } 219 } 220 221 template <ObjectType objType = ObjectType::UNKNOWN> SetBoxedElementByIdx(ThreadHolder * thread,BaseObject * obj,const uint32_t index,BoxedValue value)222 bool SetBoxedElementByIdx(ThreadHolder *thread, BaseObject *obj, const uint32_t index, BoxedValue value) 223 { 224 if constexpr (objType == ObjectType::DYNAMIC) { 225 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 226 return dynObjAccessor_->SetElementByIdx(thread, obj, index, 227 dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value))); 228 } else if constexpr (objType == ObjectType::STATIC) { 229 // fix(hewei): exceptions may occur, check here and return default value. 230 return stcObjAccessor_->SetElementByIdx(thread, obj, index, value); 231 } else { 232 if (obj->IsDynamic()) { 233 // fix(hewei): exceptions may occur, check here and return. Also, check exceptions in Wrap functions. 234 return dynObjAccessor_->SetElementByIdx(thread, obj, index, 235 dynTypeConverter_->WrapTagged(thread, stcTypeConverter_->UnWrapBoxed(value))); 236 } else { 237 // fix(hewei): exceptions may occur, check here and return default value. 238 return stcObjAccessor_->SetElementByIdx(thread, obj, index, value); 239 } 240 } 241 } 242 243 template <ObjectType objType = ObjectType::UNKNOWN> HasProperty(ThreadHolder * thread,const BaseObject * obj,const char * name)244 bool HasProperty(ThreadHolder *thread, const BaseObject *obj, const char* name) const 245 { 246 if constexpr (objType == ObjectType::DYNAMIC) { 247 // fix(hewei): exceptions may occur, check here and return default value. 248 return dynObjAccessor_->HasProperty(thread, obj, name); 249 } else if constexpr (objType == ObjectType::STATIC) { 250 // fix(hewei): exceptions may occur, check here and return default value. 251 return stcObjAccessor_->HasProperty(thread, obj, name); 252 } else { 253 if (obj->IsDynamic()) { 254 // fix(hewei): exceptions may occur, check here and return default value. 255 return dynObjAccessor_->HasProperty(thread, obj, name); 256 } else { 257 // fix(hewei): exceptions may occur, check here and return default value. 258 return stcObjAccessor_->HasProperty(thread, obj, name); 259 } 260 } 261 } 262 263 template <ObjectType objType = ObjectType::UNKNOWN> HasElementByIdx(ThreadHolder * thread,const BaseObject * obj,const uint32_t index)264 bool HasElementByIdx(ThreadHolder *thread, const BaseObject *obj, const uint32_t index) const 265 { 266 if constexpr (objType == ObjectType::DYNAMIC) { 267 // fix(hewei): exceptions may occur, check here and return default value. 268 return dynObjAccessor_->HasElementByIdx(thread, obj, index); 269 } else if constexpr (objType == ObjectType::STATIC) { 270 // fix(hewei): exceptions may occur, check here and return default value. 271 return stcObjAccessor_->HasElementByIdx(thread, obj, index); 272 } else { 273 if (obj->IsDynamic()) { 274 // fix(hewei): exceptions may occur, check here and return default value. 275 return dynObjAccessor_->HasElementByIdx(thread, obj, index); 276 } else { 277 // fix(hewei): exceptions may occur, check here and return default value. 278 return stcObjAccessor_->HasElementByIdx(thread, obj, index); 279 } 280 } 281 } 282 283 private: 284 DynamicTypeConverterInterface *dynTypeConverter_; 285 StaticTypeConverterInterface *stcTypeConverter_; 286 DynamicObjectAccessorInterface *dynObjAccessor_; 287 StaticObjectAccessorInterface *stcObjAccessor_; 288 DynamicObjectDescriptorInterface *dynObjDescriptor_; 289 StaticObjectDescriptorInterface *stcObjDescriptor_; 290 }; 291 } // namespace common 292 #endif // COMMON_INTERFACES_OBJECTS_BASE_OBJECT_DISPATCHER_H