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 PANDA_RUNTIME_INCLUDE_LANGUAGE_CONTEXT_H_ 17 #define PANDA_RUNTIME_INCLUDE_LANGUAGE_CONTEXT_H_ 18 19 #include "libpandafile/class_data_accessor-inl.h" 20 #include "libpandafile/file_items.h" 21 #include "libpandabase/utils/utf.h" 22 #include "runtime/include/class-inl.h" 23 #include "runtime/include/coretypes/tagged_value.h" 24 #include "runtime/include/class_linker_extension.h" 25 #include "runtime/include/imtable_builder.h" 26 #include "runtime/include/itable_builder.h" 27 #include "runtime/include/tooling/pt_lang_extension.h" 28 #include "runtime/include/vtable_builder.h" 29 #include "runtime/mem/gc/gc_types.h" 30 31 namespace panda { 32 class Thread; 33 class Runtime; 34 class RuntimeOptions; 35 36 namespace mem { 37 class GC; 38 class ObjectAllocatorBase; 39 struct GCSettings; 40 } // namespace mem 41 42 class LanguageContextBase { 43 public: 44 LanguageContextBase() = default; 45 46 DEFAULT_COPY_SEMANTIC(LanguageContextBase); 47 DEFAULT_MOVE_SEMANTIC(LanguageContextBase); 48 49 virtual ~LanguageContextBase() = default; 50 51 virtual panda_file::SourceLang GetLanguage() const = 0; 52 53 virtual const uint8_t *GetStringClassDescriptor() const = 0; 54 55 virtual const uint8_t *GetObjectClassDescriptor() const = 0; 56 57 virtual const uint8_t *GetClassClassDescriptor() const = 0; 58 59 virtual const uint8_t *GetClassArrayClassDescriptor() const = 0; 60 61 virtual const uint8_t *GetStringArrayClassDescriptor() const = 0; 62 63 virtual const uint8_t *GetCtorName() const = 0; 64 65 virtual const uint8_t *GetCctorName() const = 0; 66 67 virtual const uint8_t *GetNullPointerExceptionClassDescriptor() const = 0; 68 69 virtual const uint8_t *GetArrayIndexOutOfBoundsExceptionClassDescriptor() const = 0; 70 71 virtual const uint8_t *GetIndexOutOfBoundsExceptionClassDescriptor() const = 0; 72 73 virtual const uint8_t *GetIllegalStateExceptionClassDescriptor() const = 0; 74 75 virtual const uint8_t *GetNegativeArraySizeExceptionClassDescriptor() const = 0; 76 77 virtual const uint8_t *GetStringIndexOutOfBoundsExceptionClassDescriptor() const = 0; 78 79 virtual const uint8_t *GetArithmeticExceptionClassDescriptor() const = 0; 80 81 virtual const uint8_t *GetClassCastExceptionClassDescriptor() const = 0; 82 83 virtual const uint8_t *GetAbstractMethodErrorClassDescriptor() const = 0; 84 85 virtual const uint8_t *GetArrayStoreExceptionClassDescriptor() const = 0; 86 87 virtual const uint8_t *GetRuntimeExceptionClassDescriptor() const = 0; 88 89 virtual const uint8_t *GetFileNotFoundExceptionClassDescriptor() const = 0; 90 91 virtual const uint8_t *GetIOExceptionClassDescriptor() const = 0; 92 93 virtual const uint8_t *GetIllegalArgumentExceptionClassDescriptor() const = 0; 94 95 virtual const uint8_t *GetIllegalAccessExceptionClassDescriptor() const = 0; 96 97 virtual const uint8_t *GetOutOfMemoryErrorClassDescriptor() const = 0; 98 99 virtual const uint8_t *GetNoClassDefFoundErrorDescriptor() const = 0; 100 101 virtual const uint8_t *GetClassCircularityErrorDescriptor() const = 0; 102 103 virtual const uint8_t *GetNoSuchFieldErrorDescriptor() const = 0; 104 105 virtual const uint8_t *GetNoSuchMethodErrorDescriptor() const = 0; 106 107 virtual coretypes::TaggedValue GetInitialTaggedValue() const = 0; 108 109 virtual DecodedTaggedValue GetInitialDecodedValue() const = 0; 110 111 virtual DecodedTaggedValue GetDecodedTaggedValue(const coretypes::TaggedValue &value) const = 0; 112 113 virtual coretypes::TaggedValue GetEncodedTaggedValue(int64_t value, int64_t tag) const = 0; 114 115 virtual std::pair<Method *, uint32_t> GetCatchMethodAndOffset(Method *method, ManagedThread *thread) const; 116 117 virtual PandaVM *CreateVM(Runtime *runtime, const RuntimeOptions &options) const = 0; 118 119 virtual mem::GC *CreateGC(mem::GCType gc_type, mem::ObjectAllocatorBase *object_allocator, 120 const mem::GCSettings &settings) const = 0; 121 122 virtual std::unique_ptr<ClassLinkerExtension> CreateClassLinkerExtension() const; 123 124 virtual PandaUniquePtr<tooling::PtLangExt> CreatePtLangExt() const; 125 126 virtual void ThrowException(ManagedThread *thread, const uint8_t *mutf8_name, const uint8_t *mutf8_msg) const; 127 128 virtual void SetExceptionToVReg( 129 [[maybe_unused]] Frame::VRegister &vreg, // NOLINTNEXTLINE(google-runtime-references) 130 [[maybe_unused]] ObjectHeader *obj) const; 131 GetTypeTag(interpreter::TypeTag tag)132 virtual uint64_t GetTypeTag(interpreter::TypeTag tag) const 133 { 134 // return default TypeTag 135 return tag; 136 } 137 138 virtual bool IsCallableObject([[maybe_unused]] ObjectHeader *obj) const = 0; 139 140 virtual Method *GetCallTarget(ObjectHeader *obj) const = 0; 141 142 virtual const uint8_t *GetExceptionInInitializerErrorDescriptor() const = 0; 143 144 virtual const uint8_t *GetClassNotFoundExceptionDescriptor() const = 0; 145 146 virtual const uint8_t *GetInstantiationErrorDescriptor() const = 0; 147 148 virtual const uint8_t *GetUnsupportedOperationExceptionClassDescriptor() const = 0; 149 150 virtual const uint8_t *GetVerifyErrorClassDescriptor() const = 0; 151 152 virtual const uint8_t *GetReferenceErrorDescriptor() const = 0; 153 154 virtual const uint8_t *GetTypedErrorDescriptor() const = 0; 155 156 virtual const uint8_t *GetIllegalMonitorStateExceptionDescriptor() const = 0; 157 158 virtual const uint8_t *GetErrorClassDescriptor() const; 159 IsDynamicLanguage()160 bool IsDynamicLanguage() const 161 { 162 switch (GetLanguage()) { 163 case panda_file::SourceLang::PANDA_ASSEMBLY: 164 return false; 165 case panda_file::SourceLang::ECMASCRIPT: 166 return true; 167 default: 168 UNREACHABLE(); 169 return false; 170 } 171 } 172 CreateIMTableBuilder()173 virtual PandaUniquePtr<IMTableBuilder> CreateIMTableBuilder() const 174 { 175 return MakePandaUnique<IMTableBuilder>(); 176 } 177 178 virtual PandaUniquePtr<ITableBuilder> CreateITableBuilder() const; 179 180 virtual PandaUniquePtr<VTableBuilder> CreateVTableBuilder() const; 181 InitializeClass(ClassLinker * class_linker,ManagedThread * thread,Class * klass)182 virtual bool InitializeClass([[maybe_unused]] ClassLinker *class_linker, [[maybe_unused]] ManagedThread *thread, 183 [[maybe_unused]] Class *klass) const 184 { 185 return true; 186 } 187 }; 188 189 class LanguageContext { 190 public: LanguageContext(const LanguageContextBase * context)191 explicit LanguageContext(const LanguageContextBase *context) : base_(context) {} 192 193 DEFAULT_COPY_SEMANTIC(LanguageContext); 194 DEFAULT_MOVE_SEMANTIC(LanguageContext); 195 196 ~LanguageContext() = default; 197 GetLanguage()198 panda_file::SourceLang GetLanguage() const 199 { 200 return base_->GetLanguage(); 201 } 202 GetInitialTaggedValue()203 coretypes::TaggedValue GetInitialTaggedValue() const 204 { 205 return base_->GetInitialTaggedValue(); 206 } 207 GetDecodedTaggedValue(const coretypes::TaggedValue & value)208 DecodedTaggedValue GetDecodedTaggedValue(const coretypes::TaggedValue &value) const 209 { 210 return base_->GetDecodedTaggedValue(value); 211 } 212 GetEncodedTaggedValue(int64_t value,int64_t tag)213 coretypes::TaggedValue GetEncodedTaggedValue(int64_t value, int64_t tag) const 214 { 215 return base_->GetEncodedTaggedValue(value, tag); 216 } 217 GetCatchMethodAndOffset(Method * method,ManagedThread * thread)218 std::pair<Method *, uint32_t> GetCatchMethodAndOffset(Method *method, ManagedThread *thread) const 219 { 220 return base_->GetCatchMethodAndOffset(method, thread); 221 } 222 CreateVM(Runtime * runtime,const RuntimeOptions & options)223 PandaVM *CreateVM(Runtime *runtime, const RuntimeOptions &options) 224 { 225 return base_->CreateVM(runtime, options); 226 } 227 CreateGC(mem::GCType gc_type,mem::ObjectAllocatorBase * object_allocator,const mem::GCSettings & settings)228 mem::GC *CreateGC(mem::GCType gc_type, mem::ObjectAllocatorBase *object_allocator, 229 const mem::GCSettings &settings) const 230 { 231 return base_->CreateGC(gc_type, object_allocator, settings); 232 } 233 CreateClassLinkerExtension()234 std::unique_ptr<ClassLinkerExtension> CreateClassLinkerExtension() 235 { 236 return base_->CreateClassLinkerExtension(); 237 } 238 CreatePtLangExt()239 PandaUniquePtr<tooling::PtLangExt> CreatePtLangExt() 240 { 241 return base_->CreatePtLangExt(); 242 } 243 ThrowException(ManagedThread * thread,const uint8_t * mutf8_name,const uint8_t * mutf8_msg)244 void ThrowException(ManagedThread *thread, const uint8_t *mutf8_name, const uint8_t *mutf8_msg) 245 { 246 base_->ThrowException(thread, mutf8_name, mutf8_msg); 247 } 248 SetExceptionToVReg(Frame::VRegister & vreg,ObjectHeader * obj)249 void SetExceptionToVReg([[maybe_unused]] Frame::VRegister &vreg, // NOLINTNEXTLINE(google-runtime-references) 250 [[maybe_unused]] ObjectHeader *obj) const 251 { 252 base_->SetExceptionToVReg(vreg, obj); 253 } 254 GetInitialDecodedValue()255 DecodedTaggedValue GetInitialDecodedValue() const 256 { 257 return base_->GetInitialDecodedValue(); 258 } 259 GetStringClassDescriptor()260 const uint8_t *GetStringClassDescriptor() const 261 { 262 return base_->GetStringClassDescriptor(); 263 } 264 GetObjectClassDescriptor()265 const uint8_t *GetObjectClassDescriptor() const 266 { 267 return base_->GetObjectClassDescriptor(); 268 } 269 GetClassClassDescriptor()270 const uint8_t *GetClassClassDescriptor() const 271 { 272 return base_->GetClassClassDescriptor(); 273 } 274 GetClassArrayClassDescriptor()275 const uint8_t *GetClassArrayClassDescriptor() const 276 { 277 return base_->GetClassArrayClassDescriptor(); 278 } 279 GetStringArrayClassDescriptor()280 const uint8_t *GetStringArrayClassDescriptor() const 281 { 282 return base_->GetStringArrayClassDescriptor(); 283 } 284 GetCtorName()285 const uint8_t *GetCtorName() const 286 { 287 return base_->GetCtorName(); 288 } 289 GetCctorName()290 const uint8_t *GetCctorName() const 291 { 292 return base_->GetCctorName(); 293 } 294 GetNullPointerExceptionClassDescriptor()295 const uint8_t *GetNullPointerExceptionClassDescriptor() const 296 { 297 return base_->GetNullPointerExceptionClassDescriptor(); 298 } 299 GetArrayIndexOutOfBoundsExceptionClassDescriptor()300 const uint8_t *GetArrayIndexOutOfBoundsExceptionClassDescriptor() const 301 { 302 return base_->GetArrayIndexOutOfBoundsExceptionClassDescriptor(); 303 } 304 GetIndexOutOfBoundsExceptionClassDescriptor()305 const uint8_t *GetIndexOutOfBoundsExceptionClassDescriptor() const 306 { 307 return base_->GetIndexOutOfBoundsExceptionClassDescriptor(); 308 } 309 GetIllegalStateExceptionClassDescriptor()310 const uint8_t *GetIllegalStateExceptionClassDescriptor() const 311 { 312 return base_->GetIllegalStateExceptionClassDescriptor(); 313 } 314 GetNegativeArraySizeExceptionClassDescriptor()315 const uint8_t *GetNegativeArraySizeExceptionClassDescriptor() const 316 { 317 return base_->GetNegativeArraySizeExceptionClassDescriptor(); 318 } 319 GetStringIndexOutOfBoundsExceptionClassDescriptor()320 const uint8_t *GetStringIndexOutOfBoundsExceptionClassDescriptor() const 321 { 322 return base_->GetStringIndexOutOfBoundsExceptionClassDescriptor(); 323 } 324 GetArithmeticExceptionClassDescriptor()325 const uint8_t *GetArithmeticExceptionClassDescriptor() const 326 { 327 return base_->GetArithmeticExceptionClassDescriptor(); 328 } 329 GetClassCastExceptionClassDescriptor()330 const uint8_t *GetClassCastExceptionClassDescriptor() const 331 { 332 return base_->GetClassCastExceptionClassDescriptor(); 333 } 334 GetAbstractMethodErrorClassDescriptor()335 const uint8_t *GetAbstractMethodErrorClassDescriptor() const 336 { 337 return base_->GetAbstractMethodErrorClassDescriptor(); 338 } 339 GetArrayStoreExceptionClassDescriptor()340 const uint8_t *GetArrayStoreExceptionClassDescriptor() const 341 { 342 return base_->GetArrayStoreExceptionClassDescriptor(); 343 } 344 GetRuntimeExceptionClassDescriptor()345 const uint8_t *GetRuntimeExceptionClassDescriptor() const 346 { 347 return base_->GetRuntimeExceptionClassDescriptor(); 348 } 349 GetFileNotFoundExceptionClassDescriptor()350 const uint8_t *GetFileNotFoundExceptionClassDescriptor() const 351 { 352 return base_->GetFileNotFoundExceptionClassDescriptor(); 353 } 354 GetIOExceptionClassDescriptor()355 const uint8_t *GetIOExceptionClassDescriptor() const 356 { 357 return base_->GetIOExceptionClassDescriptor(); 358 } 359 GetIllegalArgumentExceptionClassDescriptor()360 const uint8_t *GetIllegalArgumentExceptionClassDescriptor() const 361 { 362 return base_->GetIllegalArgumentExceptionClassDescriptor(); 363 } 364 GetIllegalAccessExceptionClassDescriptor()365 const uint8_t *GetIllegalAccessExceptionClassDescriptor() const 366 { 367 return base_->GetIllegalAccessExceptionClassDescriptor(); 368 } 369 GetOutOfMemoryErrorClassDescriptor()370 const uint8_t *GetOutOfMemoryErrorClassDescriptor() const 371 { 372 return base_->GetOutOfMemoryErrorClassDescriptor(); 373 } 374 GetNoClassDefFoundErrorDescriptor()375 const uint8_t *GetNoClassDefFoundErrorDescriptor() const 376 { 377 return base_->GetNoClassDefFoundErrorDescriptor(); 378 } 379 GetClassCircularityErrorDescriptor()380 const uint8_t *GetClassCircularityErrorDescriptor() const 381 { 382 return base_->GetClassCircularityErrorDescriptor(); 383 } 384 GetNoSuchFieldErrorDescriptor()385 const uint8_t *GetNoSuchFieldErrorDescriptor() const 386 { 387 return base_->GetNoSuchFieldErrorDescriptor(); 388 } 389 GetNoSuchMethodErrorDescriptor()390 const uint8_t *GetNoSuchMethodErrorDescriptor() const 391 { 392 return base_->GetNoSuchMethodErrorDescriptor(); 393 } 394 GetExceptionInInitializerErrorDescriptor()395 const uint8_t *GetExceptionInInitializerErrorDescriptor() const 396 { 397 return base_->GetExceptionInInitializerErrorDescriptor(); 398 } 399 GetClassNotFoundExceptionDescriptor()400 const uint8_t *GetClassNotFoundExceptionDescriptor() const 401 { 402 return base_->GetClassNotFoundExceptionDescriptor(); 403 } 404 GetInstantiationErrorDescriptor()405 const uint8_t *GetInstantiationErrorDescriptor() const 406 { 407 return base_->GetInstantiationErrorDescriptor(); 408 } 409 GetUnsupportedOperationExceptionClassDescriptor()410 const uint8_t *GetUnsupportedOperationExceptionClassDescriptor() const 411 { 412 return base_->GetUnsupportedOperationExceptionClassDescriptor(); 413 } 414 GetVerifyErrorClassDescriptor()415 const uint8_t *GetVerifyErrorClassDescriptor() const 416 { 417 return base_->GetVerifyErrorClassDescriptor(); 418 } 419 GetIllegalMonitorStateExceptionDescriptor()420 const uint8_t *GetIllegalMonitorStateExceptionDescriptor() const 421 { 422 return base_->GetIllegalMonitorStateExceptionDescriptor(); 423 } 424 425 friend std::ostream &operator<<(std::ostream &stream, const LanguageContext &ctx) 426 { 427 switch (ctx.base_->GetLanguage()) { 428 case panda_file::SourceLang::PANDA_ASSEMBLY: 429 return stream << "PandaAssembly"; 430 case panda_file::SourceLang::ECMASCRIPT: 431 return stream << "ECMAScript"; 432 default: { 433 break; 434 } 435 } 436 437 UNREACHABLE(); 438 return stream; 439 } GetTypeTag(interpreter::TypeTag tag)440 uint64_t GetTypeTag(interpreter::TypeTag tag) const 441 { 442 // return TypeTag default 443 return base_->GetTypeTag(tag); 444 } 445 IsCallableObject(ObjectHeader * obj)446 bool IsCallableObject([[maybe_unused]] ObjectHeader *obj) const 447 { 448 return base_->IsCallableObject(obj); 449 } 450 GetCallTarget(ObjectHeader * obj)451 Method *GetCallTarget(ObjectHeader *obj) const 452 { 453 return base_->GetCallTarget(obj); 454 } 455 GetReferenceErrorDescriptor()456 const uint8_t *GetReferenceErrorDescriptor() const 457 { 458 return base_->GetReferenceErrorDescriptor(); 459 } 460 GetTypedErrorDescriptor()461 const uint8_t *GetTypedErrorDescriptor() const 462 { 463 return base_->GetTypedErrorDescriptor(); 464 } 465 GetErrorClassDescriptor()466 const uint8_t *GetErrorClassDescriptor() const 467 { 468 return base_->GetErrorClassDescriptor(); 469 } 470 IsDynamicLanguage()471 bool IsDynamicLanguage() const 472 { 473 return base_->IsDynamicLanguage(); 474 } 475 CreateIMTableBuilder()476 PandaUniquePtr<IMTableBuilder> CreateIMTableBuilder() 477 { 478 return base_->CreateIMTableBuilder(); 479 } 480 CreateITableBuilder()481 PandaUniquePtr<ITableBuilder> CreateITableBuilder() 482 { 483 return base_->CreateITableBuilder(); 484 } 485 CreateVTableBuilder()486 PandaUniquePtr<VTableBuilder> CreateVTableBuilder() 487 { 488 return base_->CreateVTableBuilder(); 489 } 490 InitializeClass(ClassLinker * class_linker,ManagedThread * thread,Class * klass)491 bool InitializeClass(ClassLinker *class_linker, ManagedThread *thread, Class *klass) const 492 { 493 return base_->InitializeClass(class_linker, thread, klass); 494 } 495 496 private: 497 const LanguageContextBase *base_; 498 }; 499 500 } // namespace panda 501 502 #endif // PANDA_RUNTIME_INCLUDE_LANGUAGE_CONTEXT_H_ 503