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_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_EXTENSION_H_ 16 #define PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_EXTENSION_H_ 17 18 #include <cstddef> 19 20 #include <libpandafile/include/source_lang_enum.h> 21 22 #include "libpandabase/macros.h" 23 #include "runtime/include/class_linker_extension.h" 24 #include "runtime/include/class_linker.h" 25 #include "runtime/include/class_root.h" 26 #include "runtime/include/mem/panda_string.h" 27 #include "plugins/ets/runtime/types/ets_class.h" 28 #include "plugins/ets/runtime/ets_coroutine.h" 29 30 namespace ark { 31 32 class Class; 33 class Method; 34 class ObjectHeader; 35 36 } // namespace ark 37 38 namespace ark::ets { 39 40 class EtsClassLinkerExtension : public ClassLinkerExtension { 41 public: EtsClassLinkerExtension()42 EtsClassLinkerExtension() : ClassLinkerExtension(panda_file::SourceLang::ETS) {} 43 44 ~EtsClassLinkerExtension() override; 45 46 bool InitializeArrayClass(Class *arrayClass, Class *componentClass) override; 47 48 void InitializePrimitiveClass(Class *primitiveClass) override; 49 50 size_t GetClassVTableSize(ClassRoot root) override; 51 52 size_t GetClassIMTSize(ClassRoot root) override; 53 54 size_t GetClassSize(ClassRoot root) override; 55 56 size_t GetArrayClassVTableSize() override; 57 58 size_t GetArrayClassIMTSize() override; 59 60 size_t GetArrayClassSize() override; 61 62 Class *CreateClass(const uint8_t *descriptor, size_t vtableSize, size_t imtSize, size_t size) override; 63 64 void FreeClass(Class *klass) override; 65 66 void InitializeClassRoot(); 67 68 bool InitializeClass(Class *klass) override; 69 70 const void *GetNativeEntryPointFor(Method *method) const override; 71 CanThrowException(const Method * method)72 bool CanThrowException([[maybe_unused]] const Method *method) const override 73 { 74 return true; 75 } 76 GetErrorHandler()77 ClassLinkerErrorHandler *GetErrorHandler() override 78 { 79 return &errorHandler_; 80 }; 81 82 Class *FromClassObject(ark::ObjectHeader *obj) override; 83 size_t GetClassObjectSizeFromClassSize(uint32_t size) override; 84 85 void InitializeBuiltinClasses(); 86 GetObjectClass()87 Class *GetObjectClass() 88 { 89 return GetClassRoot(ClassRoot::OBJECT); 90 } 91 GetUndefinedClass()92 Class *GetUndefinedClass() const 93 { 94 return undefinedClass_; 95 } 96 GetPromiseClass()97 Class *GetPromiseClass() 98 { 99 return promiseClass_; 100 } 101 GetPromiseRefClass()102 Class *GetPromiseRefClass() 103 { 104 return promiseRefClass_; 105 } 106 GetBigIntClass()107 Class *GetBigIntClass() 108 { 109 return bigintClass_; 110 } 111 GetExceptionClass()112 Class *GetExceptionClass() 113 { 114 return exceptionClass_; 115 } 116 GetErrorClass()117 Class *GetErrorClass() 118 { 119 return errorClass_; 120 } 121 GetArrayAsListIntClass()122 Class *GetArrayAsListIntClass() 123 { 124 return arrayAsListIntClass_; 125 } 126 GetArrayClass()127 Class *GetArrayClass() 128 { 129 return arrayClass_; 130 } 131 GetArrayBufferClass()132 Class *GetArrayBufferClass() 133 { 134 return arraybufClass_; 135 } 136 GetStringBuilderClass()137 Class *GetStringBuilderClass() 138 { 139 return stringBuilderClass_; 140 } 141 GetSharedMemoryClass()142 Class *GetSharedMemoryClass() 143 { 144 return sharedMemoryClass_; 145 } 146 GetTypeAPIFieldClass()147 Class *GetTypeAPIFieldClass() 148 { 149 return typeapiFieldClass_; 150 } 151 GetTypeAPIMethodClass()152 Class *GetTypeAPIMethodClass() 153 { 154 return typeapiMethodClass_; 155 } 156 GetTypeAPIParameterClass()157 Class *GetTypeAPIParameterClass() 158 { 159 return typeapiParameterClass_; 160 } 161 GetIFunctionClass()162 Class *GetIFunctionClass() 163 { 164 return ifuncClass_; 165 } 166 GetBoxBooleanClass()167 Class *GetBoxBooleanClass() 168 { 169 return boxBooleanClass_; 170 } 171 GetBoxByteClass()172 Class *GetBoxByteClass() 173 { 174 return boxByteClass_; 175 } 176 GetBoxCharClass()177 Class *GetBoxCharClass() 178 { 179 return boxCharClass_; 180 } 181 GetBoxShortClass()182 Class *GetBoxShortClass() 183 { 184 return boxShortClass_; 185 } 186 GetBoxIntClass()187 Class *GetBoxIntClass() 188 { 189 return boxIntClass_; 190 } 191 GetBoxLongClass()192 Class *GetBoxLongClass() 193 { 194 return boxLongClass_; 195 } 196 GetBoxFloatClass()197 Class *GetBoxFloatClass() 198 { 199 return boxFloatClass_; 200 } 201 GetBoxDoubleClass()202 Class *GetBoxDoubleClass() 203 { 204 return boxDoubleClass_; 205 } 206 GetFinalizableWeakRefClass()207 Class *GetFinalizableWeakRefClass() 208 { 209 return finalizableWeakClass_; 210 } 211 GetSubscribeOnAnotherPromiseMethod()212 Method *GetSubscribeOnAnotherPromiseMethod() 213 { 214 return subscribeOnAnotherPromiseMethod_; 215 } 216 FromCoreType(ClassLinkerExtension * ext)217 static EtsClassLinkerExtension *FromCoreType(ClassLinkerExtension *ext) 218 { 219 ASSERT(ext->GetLanguage() == panda_file::SourceLang::ETS); 220 return static_cast<EtsClassLinkerExtension *>(ext); 221 } 222 GetLanguageContext()223 LanguageContext GetLanguageContext() const 224 { 225 return langCtx_; 226 } 227 IsJSValueClass(Class * maybeJSValue)228 bool IsJSValueClass(Class *maybeJSValue) const 229 { 230 return maybeJSValue == jsvalueClass_; 231 } 232 233 NO_COPY_SEMANTIC(EtsClassLinkerExtension); 234 NO_MOVE_SEMANTIC(EtsClassLinkerExtension); 235 236 private: 237 bool InitializeImpl(bool compressedStringEnabled) override; 238 239 Class *InitializeClass(ObjectHeader *objectHeader, const uint8_t *descriptor, size_t vtableSize, size_t imtSize, 240 size_t size); 241 242 Class *CreateClassRoot(const uint8_t *descriptor, ClassRoot root); 243 244 Class *CacheClass(std::string_view descriptor, bool forceInit = false); 245 template <typename F> 246 Class *CacheClass(std::string_view descriptor, F const &setup, bool forceInit = false); 247 248 class ErrorHandler : public ClassLinkerErrorHandler { 249 public: 250 void OnError(ClassLinker::Error error, const PandaString &message) override; 251 }; 252 253 ErrorHandler errorHandler_; 254 LanguageContext langCtx_ {nullptr}; 255 mem::HeapManager *heapManager_ {nullptr}; 256 257 // Cached classes 258 Class *undefinedClass_ = nullptr; 259 // std.core box classes 260 Class *boxBooleanClass_ = nullptr; 261 Class *boxByteClass_ = nullptr; 262 Class *boxCharClass_ = nullptr; 263 Class *boxShortClass_ = nullptr; 264 Class *boxIntClass_ = nullptr; 265 Class *boxLongClass_ = nullptr; 266 Class *boxFloatClass_ = nullptr; 267 Class *boxDoubleClass_ = nullptr; 268 // std.core 269 Class *bigintClass_ = nullptr; 270 Class *exceptionClass_ = nullptr; 271 Class *errorClass_ = nullptr; 272 Class *promiseClass_ = nullptr; 273 Method *subscribeOnAnotherPromiseMethod_ = nullptr; 274 Class *promiseRefClass_ = nullptr; 275 Class *arrayClass_ = nullptr; 276 Class *arraybufClass_ = nullptr; 277 Class *stringBuilderClass_ = nullptr; 278 Class *arrayAsListIntClass_ = nullptr; 279 Class *jsvalueClass_ = nullptr; 280 Class *finalizableWeakClass_ = nullptr; 281 // Cached type API classes 282 Class *typeapiFieldClass_ = nullptr; 283 Class *typeapiMethodClass_ = nullptr; 284 Class *typeapiParameterClass_ = nullptr; 285 Class *ifuncClass_ = nullptr; 286 // escompat 287 Class *sharedMemoryClass_ = nullptr; 288 }; 289 290 } // namespace ark::ets 291 292 #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_EXTENSION_H_ 293