• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "runtime/core/core_language_context.h"
17 
18 #include "runtime/core/core_itable_builder.h"
19 #include "runtime/core/core_vtable_builder.h"
20 #include "runtime/include/vtable_builder-inl.h"
21 #include "runtime/handle_scope-inl.h"
22 
23 namespace panda {
24 
GetExceptionClass(const uint8_t * mutf8_name,ManagedThread * thread,ClassLinker * class_linker)25 static Class *GetExceptionClass(const uint8_t *mutf8_name, ManagedThread *thread, ClassLinker *class_linker)
26 {
27     auto runtime = Runtime::GetCurrent();
28     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
29     auto *extension = class_linker->GetExtension(ctx);
30     auto *cls = class_linker->GetClass(mutf8_name, true, extension->GetBootContext());
31     if (cls == nullptr) {
32         LOG(ERROR, CORE) << "Class " << utf::Mutf8AsCString(mutf8_name) << " not found";
33         return nullptr;
34     }
35 
36     if (!class_linker->InitializeClass(thread, cls)) {
37         LOG(ERROR, CORE) << "Class " << utf::Mutf8AsCString(mutf8_name) << " cannot be initialized";
38         return nullptr;
39     }
40     return cls;
41 }
42 
ThrowException(ManagedThread * thread,const uint8_t * mutf8_name,const uint8_t * mutf8_msg) const43 void CoreLanguageContext::ThrowException(ManagedThread *thread, const uint8_t *mutf8_name,
44                                          const uint8_t *mutf8_msg) const
45 {
46     ASSERT(thread == ManagedThread::GetCurrent());
47 
48     if (thread->IsUsePreAllocObj()) {
49         thread->SetUsePreAllocObj(false);
50         auto *oom = thread->GetVM()->GetOOMErrorObject();
51         thread->SetException(oom);
52         return;
53     }
54 
55     [[maybe_unused]] HandleScope<ObjectHeader *> scope(thread);
56     VMHandle<ObjectHeader> cause(thread, thread->GetException());
57     thread->ClearException();
58 
59     auto runtime = Runtime::GetCurrent();
60     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
61     auto *class_linker = runtime->GetClassLinker();
62     auto *cls = GetExceptionClass(mutf8_name, thread, class_linker);
63     if (cls == nullptr) {
64         return;
65     }
66 
67     VMHandle<ObjectHeader> exc_handle(thread, ObjectHeader::Create(cls));
68 
69     coretypes::String *msg;
70     if (mutf8_msg != nullptr) {
71         msg = coretypes::String::CreateFromMUtf8(mutf8_msg, ctx, Runtime::GetCurrent()->GetPandaVM());
72         if (UNLIKELY(msg == nullptr)) {
73             // OOM happened during msg allocation
74             ASSERT(thread->HasPendingException());
75             return;
76         }
77     } else {
78         msg = nullptr;
79     }
80     VMHandle<ObjectHeader> msg_handle(thread, msg);
81 
82     Method::Proto proto(Method::Proto::ShortyVector {panda_file::Type(panda_file::Type::TypeId::VOID),
83                                                      panda_file::Type(panda_file::Type::TypeId::REFERENCE),
84                                                      panda_file::Type(panda_file::Type::TypeId::REFERENCE)},
85                         Method::Proto::RefTypeVector {utf::Mutf8AsCString(ctx.GetStringClassDescriptor()),
86                                                       utf::Mutf8AsCString(ctx.GetObjectClassDescriptor())});
87     auto *ctor_name = ctx.GetCtorName();
88     auto *ctor = cls->GetDirectMethod(ctor_name, proto);
89     if (ctor == nullptr) {
90         LOG(ERROR, CORE) << "No method " << utf::Mutf8AsCString(ctor_name) << " in class "
91                          << utf::Mutf8AsCString(mutf8_name);
92         return;
93     }
94 
95     constexpr size_t NARGS = 3;
96     std::array<Value, NARGS> args {Value(exc_handle.GetPtr()), Value(msg_handle.GetPtr()), Value(cause.GetPtr())};
97     ctor->InvokeVoid(thread, args.data());
98     if (LIKELY(!thread->HasPendingException())) {
99         thread->SetException(exc_handle.GetPtr());
100     }
101 }
102 
CreateITableBuilder() const103 PandaUniquePtr<ITableBuilder> CoreLanguageContext::CreateITableBuilder() const
104 {
105     return MakePandaUnique<CoreITableBuilder>();
106 }
107 
CreateVTableBuilder() const108 PandaUniquePtr<VTableBuilder> CoreLanguageContext::CreateVTableBuilder() const
109 {
110     return MakePandaUnique<CoreVTableBuilder>();
111 }
112 
CreateVM(Runtime * runtime,const RuntimeOptions & options) const113 PandaVM *CoreLanguageContext::CreateVM(Runtime *runtime, const RuntimeOptions &options) const
114 {
115     auto core_vm = core::PandaCoreVM::Create(runtime, options);
116     if (!core_vm) {
117         LOG(ERROR, CORE) << core_vm.Error();
118         return nullptr;
119     }
120     return core_vm.Value();
121 }
122 
CreateGC(mem::GCType gc_type,mem::ObjectAllocatorBase * object_allocator,const mem::GCSettings & settings) const123 mem::GC *CoreLanguageContext::CreateGC(mem::GCType gc_type, mem::ObjectAllocatorBase *object_allocator,
124                                        const mem::GCSettings &settings) const
125 {
126     return mem::CreateGC<PandaAssemblyLanguageConfig>(gc_type, object_allocator, settings);
127 }
128 
ThrowStackOverflowException(ManagedThread * thread) const129 void CoreLanguageContext::ThrowStackOverflowException(ManagedThread *thread) const
130 {
131     auto runtime = Runtime::GetCurrent();
132     auto *class_linker = runtime->GetClassLinker();
133     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
134     auto *extension = class_linker->GetExtension(ctx);
135     auto *cls = class_linker->GetClass(ctx.GetStackOverflowErrorClassDescriptor(), true, extension->GetBootContext());
136 
137     HandleScope<ObjectHeader *> scope(thread);
138     VMHandle<ObjectHeader> exc(thread, ObjectHeader::Create(cls));
139     thread->SetException(exc.GetPtr());
140 }
141 
GetVerificationInitAPI() const142 VerificationInitAPI CoreLanguageContext::GetVerificationInitAPI() const
143 {
144     VerificationInitAPI v_api;
145     v_api.primitive_roots_for_verification = {
146         panda_file::Type::TypeId::TAGGED, panda_file::Type::TypeId::VOID, panda_file::Type::TypeId::U1,
147         panda_file::Type::TypeId::U8,     panda_file::Type::TypeId::U16,  panda_file::Type::TypeId::U32,
148         panda_file::Type::TypeId::U64,    panda_file::Type::TypeId::I8,   panda_file::Type::TypeId::I16,
149         panda_file::Type::TypeId::I32,    panda_file::Type::TypeId::I64,  panda_file::Type::TypeId::F32,
150         panda_file::Type::TypeId::F64};
151 
152     v_api.array_elements_for_verification = {reinterpret_cast<const uint8_t *>("[Z"),
153                                              reinterpret_cast<const uint8_t *>("[B"),
154                                              reinterpret_cast<const uint8_t *>("[S"),
155                                              reinterpret_cast<const uint8_t *>("[C"),
156                                              reinterpret_cast<const uint8_t *>("[I"),
157                                              reinterpret_cast<const uint8_t *>("[J"),
158                                              reinterpret_cast<const uint8_t *>("[F"),
159                                              reinterpret_cast<const uint8_t *>("[D")
160 
161     };
162 
163     v_api.is_need_class_synthetic_class = true;
164     v_api.is_need_object_synthetic_class = true;
165     v_api.is_need_string_synthetic_class = true;
166 
167     return v_api;
168 }
169 
170 }  // namespace panda
171