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 #include "ets_platform_types.h"
17 #include "file.h"
18 #include "include/object_header.h"
19 #include "intrinsics.h"
20 #include "os/mutex.h"
21 #include "plugins/ets/runtime/ets_class_linker_context.h"
22 #include "plugins/ets/runtime/ets_class_linker_extension.h"
23 #include "plugins/ets/runtime/ets_coroutine.h"
24 #include "plugins/ets/runtime/ets_exceptions.h"
25 #include "plugins/ets/runtime/types/ets_abc_file.h"
26 #include "plugins/ets/runtime/types/ets_abc_runtime_linker.h"
27 #include "plugins/ets/runtime/types/ets_array.h"
28 #include "plugins/ets/runtime/types/ets_primitives.h"
29 #include "plugins/ets/runtime/types/ets_string.h"
30
31 namespace ark::ets::intrinsics {
32
EtsAbcRuntimeLinkerAddNewAbcFiles(EtsAbcRuntimeLinker * runtimeLinker,ObjectHeader * newAbcFilesArray)33 void EtsAbcRuntimeLinkerAddNewAbcFiles(EtsAbcRuntimeLinker *runtimeLinker, ObjectHeader *newAbcFilesArray)
34 {
35 auto *coro = EtsCoroutine::GetCurrent();
36 [[maybe_unused]] EtsHandleScope hs(coro);
37 EtsHandle newAbcFilesHandle(coro, EtsTypedObjectArray<EtsAbcFile>::FromCoreType(newAbcFilesArray));
38 EtsHandle linkerHandle(coro, runtimeLinker);
39 auto *ctx = reinterpret_cast<EtsClassLinkerContext *>(linkerHandle->GetClassLinkerContext());
40
41 os::memory::LockHolder lock(ctx->GetAbcFilesMutex());
42 EtsHandle currentAbcFilesHandle(coro, linkerHandle->GetAbcFiles());
43 auto currentLength = currentAbcFilesHandle->GetLength();
44 auto resultLength = newAbcFilesHandle->GetLength() + currentLength;
45 EtsHandle resultAbcFilesHandle(coro, EtsObjectArray::Create(PlatformTypes(coro)->coreAbcFile, resultLength));
46 if (UNLIKELY(resultAbcFilesHandle.GetPtr() == nullptr)) {
47 ASSERT(coro->HasPendingException());
48 return;
49 }
50
51 currentAbcFilesHandle->CopyDataTo(resultAbcFilesHandle.GetPtr());
52 for (size_t start = currentLength, i = start; i < resultLength; ++i) {
53 resultAbcFilesHandle->Set(i, newAbcFilesHandle->Get(i - start));
54 }
55 linkerHandle->SetAbcFiles(resultAbcFilesHandle.GetPtr());
56 }
57
EtsAbcRuntimeLinkerLoadClassFromAbcFiles(EtsAbcRuntimeLinker * runtimeLinker,EtsString * clsName,EtsBoolean init)58 EtsClass *EtsAbcRuntimeLinkerLoadClassFromAbcFiles(EtsAbcRuntimeLinker *runtimeLinker, EtsString *clsName,
59 EtsBoolean init)
60 {
61 const auto name = clsName->GetMutf8();
62 PandaString descriptor;
63 const auto *classDescriptor = ClassHelper::GetDescriptor(utf::CStringAsMutf8(name.c_str()), &descriptor);
64
65 auto *coro = EtsCoroutine::GetCurrent();
66 auto *classLinker = Runtime::GetCurrent()->GetClassLinker();
67 auto *errorHandler = PandaEtsVM::GetCurrent()->GetEtsClassLinkerExtension()->GetErrorHandler();
68 auto *ctx = reinterpret_cast<EtsClassLinkerContext *>(runtimeLinker->GetClassLinkerContext());
69 os::memory::LockHolder rlock(ctx->GetAbcFilesMutex());
70
71 auto *abcFiles = runtimeLinker->GetAbcFiles();
72 for (size_t i = 0, end = abcFiles->GetLength(); i < end; ++i) {
73 auto *pf = EtsAbcFile::FromEtsObject(abcFiles->Get(i))->GetPandaFile();
74 const auto classId = pf->GetClassId(classDescriptor);
75 if (!classId.IsValid() || pf->IsExternal(classId)) {
76 continue;
77 }
78
79 auto *klass = classLinker->LoadClass(*pf, classId, ctx, errorHandler, true);
80 if (UNLIKELY(klass == nullptr)) {
81 ASSERT(coro->HasPendingException());
82 return nullptr;
83 }
84
85 if (UNLIKELY(init != 0 && !klass->IsInitialized())) {
86 if (UNLIKELY(!classLinker->InitializeClass(coro, klass))) {
87 ASSERT(coro->HasPendingException());
88 return nullptr;
89 }
90 }
91 return EtsClass::FromRuntimeClass(klass);
92 }
93 return nullptr;
94 }
95
96 } // namespace ark::ets::intrinsics
97