• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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_standard-inl.h"
21 #include "runtime/handle_scope-inl.h"
22 
23 namespace ark {
24 
GetExceptionClass(const uint8_t * mutf8Name,ManagedThread * thread,ClassLinker * classLinker)25 static Class *GetExceptionClass(const uint8_t *mutf8Name, ManagedThread *thread, ClassLinker *classLinker)
26 {
27     auto runtime = Runtime::GetCurrent();
28     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
29     auto *extension = classLinker->GetExtension(ctx);
30     auto *cls = classLinker->GetClass(mutf8Name, true, extension->GetBootContext());
31     if (cls == nullptr) {
32         LOG(ERROR, CORE) << "Class " << utf::Mutf8AsCString(mutf8Name) << " not found";
33         return nullptr;
34     }
35 
36     if (!classLinker->InitializeClass(thread, cls)) {
37         LOG(ERROR, CORE) << "Class " << utf::Mutf8AsCString(mutf8Name) << " cannot be initialized";
38         return nullptr;
39     }
40     return cls;
41 }
42 
ThrowException(ManagedThread * thread,const uint8_t * mutf8Name,const uint8_t * mutf8Msg) const43 void CoreLanguageContext::ThrowException(ManagedThread *thread, const uint8_t *mutf8Name, const uint8_t *mutf8Msg) const
44 {
45     ASSERT(thread == ManagedThread::GetCurrent());
46 
47     if (thread->IsUsePreAllocObj()) {
48         thread->SetUsePreAllocObj(false);
49         auto *oom = thread->GetVM()->GetOOMErrorObject();
50         thread->SetException(oom);
51         return;
52     }
53 
54     [[maybe_unused]] HandleScope<ObjectHeader *> scope(thread);
55     VMHandle<ObjectHeader> cause(thread, thread->GetException());
56     thread->ClearException();
57 
58     auto runtime = Runtime::GetCurrent();
59     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
60     auto *classLinker = runtime->GetClassLinker();
61     auto *cls = GetExceptionClass(mutf8Name, thread, classLinker);
62     if (cls == nullptr) {
63         return;
64     }
65 
66     VMHandle<ObjectHeader> excHandle(thread, ObjectHeader::Create(cls));
67 
68     coretypes::String *msg;
69     if (mutf8Msg != nullptr) {
70         msg = coretypes::String::CreateFromMUtf8(mutf8Msg, ctx, Runtime::GetCurrent()->GetPandaVM());
71         if (UNLIKELY(msg == nullptr)) {
72             // OOM happened during msg allocation
73             ASSERT(thread->HasPendingException());
74             return;
75         }
76     } else {
77         msg = nullptr;
78     }
79     VMHandle<ObjectHeader> msgHandle(thread, msg);
80 
81     Method::Proto proto(Method::Proto::ShortyVector {panda_file::Type(panda_file::Type::TypeId::VOID),
82                                                      panda_file::Type(panda_file::Type::TypeId::REFERENCE),
83                                                      panda_file::Type(panda_file::Type::TypeId::REFERENCE)},
84                         Method::Proto::RefTypeVector {utf::Mutf8AsCString(ctx.GetStringClassDescriptor()),
85                                                       utf::Mutf8AsCString(ctx.GetObjectClassDescriptor())});
86     auto *ctorName = ctx.GetCtorName();
87     auto *ctor = cls->GetDirectMethod(ctorName, proto);
88     if (ctor == nullptr) {
89         LOG(ERROR, CORE) << "No method " << utf::Mutf8AsCString(ctorName) << " in class "
90                          << utf::Mutf8AsCString(mutf8Name);
91         return;
92     }
93 
94     constexpr size_t NARGS = 3;
95     std::array<Value, NARGS> args {Value(excHandle.GetPtr()), Value(msgHandle.GetPtr()), Value(cause.GetPtr())};
96     ctor->InvokeVoid(thread, args.data());
97     if (LIKELY(!thread->HasPendingException())) {
98         thread->SetException(excHandle.GetPtr());
99     }
100 }
101 
CreateITableBuilder(ClassLinkerErrorHandler * errHandler) const102 PandaUniquePtr<ITableBuilder> CoreLanguageContext::CreateITableBuilder(
103     [[maybe_unused]] ClassLinkerErrorHandler *errHandler) const  // CC-OFF(G.FMT.06) false positive
104 {
105     return MakePandaUnique<CoreITableBuilder>();
106 }
107 
CreateVTableBuilder(ClassLinkerErrorHandler * errHandler) const108 PandaUniquePtr<VTableBuilder> CoreLanguageContext::CreateVTableBuilder(ClassLinkerErrorHandler *errHandler) const
109 {
110     return MakePandaUnique<CoreVTableBuilder>(errHandler);
111 }
112 
CreateVM(Runtime * runtime,const RuntimeOptions & options) const113 PandaVM *CoreLanguageContext::CreateVM(Runtime *runtime, const RuntimeOptions &options) const
114 {
115     auto coreVm = core::PandaCoreVM::Create(runtime, options);
116     if (!coreVm) {
117         LOG(ERROR, CORE) << coreVm.Error();
118         return nullptr;
119     }
120     return coreVm.Value();
121 }
122 
CreateGC(mem::GCType gcType,mem::ObjectAllocatorBase * objectAllocator,const mem::GCSettings & settings) const123 mem::GC *CoreLanguageContext::CreateGC(mem::GCType gcType, mem::ObjectAllocatorBase *objectAllocator,
124                                        const mem::GCSettings &settings) const
125 {
126     return mem::CreateGC<PandaAssemblyLanguageConfig>(gcType, objectAllocator, settings);
127 }
128 
ThrowStackOverflowException(ManagedThread * thread) const129 void CoreLanguageContext::ThrowStackOverflowException(ManagedThread *thread) const
130 {
131     auto runtime = Runtime::GetCurrent();
132     auto *classLinker = runtime->GetClassLinker();
133     LanguageContext ctx = runtime->GetLanguageContext(panda_file::SourceLang::PANDA_ASSEMBLY);
134     auto *extension = classLinker->GetExtension(ctx);
135     auto *cls = classLinker->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 vApi;
145     vApi.primitiveRootsForVerification = {
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     vApi.arrayElementsForVerification = {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     vApi.isNeedClassSyntheticClass = true;
164     vApi.isNeedObjectSyntheticClass = true;
165     vApi.isNeedStringSyntheticClass = true;
166 
167     return vApi;
168 }
169 
170 }  // namespace ark
171