• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 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 "libabckit/include/c/metadata_core.h"
17 #include "libabckit/include/c/extensions/arkts/metadata_arkts.h"
18 #include "libabckit/include/c/extensions/js/metadata_js.h"
19 
20 #include "libabckit/src/adapter_dynamic/metadata_modify_dynamic.h"
21 #include "libabckit/src/adapter_dynamic/metadata_inspect_dynamic.h"
22 #include "libabckit/src/wrappers/graph_wrapper/graph_wrapper.h"
23 #include "libabckit/src/logger.h"
24 #include "libabckit/src/metadata_inspect_impl.h"
25 #include "assembler/annotation.h"
26 #include "assembler/assembly-literals.h"
27 #include "assembler/assembly-program.h"
28 #include "assembler/assembly-function.h"
29 #include "assembler/assembly-record.h"
30 #include "src/adapter_dynamic/helpers_dynamic.h"
31 #include "src/statuses_impl.h"
32 
33 #include <cstddef>
34 #include <cstdint>
35 #include <cstring>
36 #include <memory>
37 #include <string>
38 #include <variant>
39 #include <vector>
40 #include <tuple>
41 
42 namespace libabckit {
43 
44 // CC-OFFNXT(WordsTool.95) sensitive word conflict
45 // NOLINTNEXTLINE(google-build-using-namespace)
46 using namespace panda;
47 
CreateStringDynamic(AbckitFile * file,const char * value,size_t len)48 AbckitString *CreateStringDynamic(AbckitFile *file, const char *value, size_t len)
49 {
50     LIBABCKIT_LOG_FUNC;
51     LIBABCKIT_LOG(DEBUG) << "\"" << value << "\"" << '\n';
52     auto *prog = file->GetDynamicProgram();
53     const auto &[progValueIter, _] = prog->strings.insert(std::string(value, len));
54     const auto &progValue = *progValueIter;
55     auto &strings = file->strings;
56 
57     if (strings.find(progValue) != strings.end()) {
58         return strings.at(progValue).get();
59     }
60 
61     auto s = std::make_unique<AbckitString>();
62     s->impl = progValue;
63     strings.insert({progValue, std::move(s)});
64     return strings[progValue].get();
65 }
66 
FunctionSetGraphDynamic(AbckitCoreFunction * function,AbckitGraph * graph)67 void FunctionSetGraphDynamic(AbckitCoreFunction *function, AbckitGraph *graph)
68 {
69     LIBABCKIT_LOG_FUNC;
70 
71     auto func = GetDynFunction(function);
72     LIBABCKIT_LOG(DEBUG) << "============================================ BEFORE CODEGEN: " << func->name << '\n';
73     LIBABCKIT_LOG_DUMP(func->DebugDump(), DEBUG);
74 
75     auto res = GraphWrapper::BuildCodeDynamic(graph, func->name);
76     auto status = statuses::GetLastError();
77     if (status != AbckitStatus::ABCKIT_STATUS_NO_ERROR) {
78         return;
79     }
80     void *fw = res;
81 
82     LIBABCKIT_LOG_FUNC;
83     LIBABCKIT_LOG(DEBUG) << "============================================ AFTER CODEGEN: " << func->name << '\n';
84     LIBABCKIT_LOG_DUMP((reinterpret_cast<pandasm::Function *>(fw))->DebugDump(), DEBUG);
85 
86     auto *newFunc = reinterpret_cast<pandasm::Function *>(fw);
87     func->ins = newFunc->ins;
88     func->catch_blocks = newFunc->catch_blocks;
89     func->regs_num = newFunc->regs_num;
90 
91     // update IC slot number info in annotation
92     func->slots_num = newFunc->slots_num;
93     static const std::string SLOT_NUMBER = "_ESSlotNumberAnnotation";
94     static const std::string ELEMENT_NAME = "SlotNumber";
95     size_t slotNumAnnoIndex = 0;
96     for (const auto &an : func->metadata->GetAnnotations()) {
97         if (an.GetName() == SLOT_NUMBER) {
98             pandasm::AnnotationElement ele(ELEMENT_NAME, std::make_unique<pandasm::ScalarValue>(
99                                                              pandasm::ScalarValue::Create<pandasm::Value::Type::U32>(
100                                                                  static_cast<uint32_t>(func->slots_num))));
101             func->metadata->SetOrAddAnnotationElementByIndex(slotNumAnnoIndex, 0, std::move(ele));
102             break;
103         }
104         slotNumAnnoIndex++;
105     }
106 
107     delete newFunc;
108 }
109 
FileAddExternalJsModule(AbckitFile * file,const struct AbckitJsExternalModuleCreateParams * params)110 AbckitJsModule *FileAddExternalJsModule(AbckitFile *file, const struct AbckitJsExternalModuleCreateParams *params)
111 {
112     auto m = std::make_unique<AbckitCoreModule>();
113     m->impl = std::make_unique<AbckitJsModule>();
114     m->file = file;
115     m->target = ABCKIT_TARGET_JS;
116     m->GetJsImpl()->core = m.get();
117 
118     auto *prog = file->GetDynamicProgram();
119 
120     prog->strings.insert(params->name);
121     auto &strings = file->strings;
122     if (strings.find(params->name) != strings.end()) {
123         m->moduleName = strings.at(params->name).get();
124     } else {
125         auto s = std::make_unique<AbckitString>();
126         s->impl = params->name;
127         strings.insert({params->name, std::move(s)});
128         m->moduleName = strings[params->name].get();
129     }
130 
131     m->isExternal = true;
132     auto modulePayloadDyn = AbckitModulePayloadDyn();
133     modulePayloadDyn.absPaths = false;
134     m->GetJsImpl()->impl = modulePayloadDyn;
135     file->externalModules.insert({params->name, std::move(m)});
136     return file->externalModules[params->name]->GetJsImpl();
137 }
138 
FileAddExternalArkTsV1Module(AbckitFile * file,const struct AbckitArktsV1ExternalModuleCreateParams * params)139 AbckitArktsModule *FileAddExternalArkTsV1Module(AbckitFile *file,
140                                                 const struct AbckitArktsV1ExternalModuleCreateParams *params)
141 {
142     auto m = std::make_unique<AbckitCoreModule>();
143     m->impl = std::make_unique<AbckitArktsModule>();
144     m->file = file;
145     m->target = ABCKIT_TARGET_ARK_TS_V1;
146     m->GetArkTSImpl()->core = m.get();
147 
148     auto *prog = file->GetDynamicProgram();
149 
150     prog->strings.insert(params->name);
151     auto &strings = file->strings;
152     if (strings.find(params->name) != strings.end()) {
153         m->moduleName = strings.at(params->name).get();
154     } else {
155         auto s = std::make_unique<AbckitString>();
156         s->impl = params->name;
157         strings.insert({params->name, std::move(s)});
158         m->moduleName = strings[params->name].get();
159     }
160 
161     m->isExternal = true;
162     auto modulePayloadDyn = AbckitModulePayloadDyn();
163     modulePayloadDyn.absPaths = false;
164     m->GetArkTSImpl()->impl.GetDynModule() = modulePayloadDyn;
165     file->externalModules.insert({params->name, std::move(m)});
166     return file->externalModules[params->name]->GetArkTSImpl();
167 }
168 
ModuleRemoveImportDynamic(AbckitCoreModule * m,AbckitArktsImportDescriptor * i)169 void ModuleRemoveImportDynamic(AbckitCoreModule *m, AbckitArktsImportDescriptor *i)
170 {
171     LIBABCKIT_LOG_FUNC;
172     auto found = std::find_if(m->id.begin(), m->id.end(),
173                               [&](std::unique_ptr<AbckitCoreImportDescriptor> const &d) { return d.get() == i->core; });
174     if (found == m->id.end()) {
175         LIBABCKIT_LOG(DEBUG) << "Can not find the import to delete\n";
176         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
177         return;
178     }
179 
180     auto mPayload = GetDynModulePayload(m);
181     auto idxOffset =
182         i->payload.GetDynId().isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
183     auto gap = i->payload.GetDynId().isRegularImport ? 3 : 2;
184     (mPayload->moduleLiteralArray->GetDynamicImpl())
185         ->literals_[idxOffset + i->payload.GetDynId().moduleRecordIndexOff * gap]
186         .tag_ = panda_file::LiteralTag::NULLVALUE;
187 
188     m->id.erase(found);
189 }
190 
ModuleRemoveImportDynamic(AbckitCoreModule * m,AbckitJsImportDescriptor * i)191 void ModuleRemoveImportDynamic(AbckitCoreModule *m, AbckitJsImportDescriptor *i)
192 {
193     LIBABCKIT_LOG_FUNC;
194     auto found = std::find_if(m->id.begin(), m->id.end(),
195                               [&](std::unique_ptr<AbckitCoreImportDescriptor> const &d) { return d.get() == i->core; });
196     if (found == m->id.end()) {
197         LIBABCKIT_LOG(DEBUG) << "Can not find the import to delete\n";
198         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
199         return;
200     }
201 
202     auto mPayload = GetDynModulePayload(m);
203     auto idxOffset =
204         i->payload.GetDynId().isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
205     auto gap = i->payload.GetDynId().isRegularImport ? 3 : 2;
206     (mPayload->moduleLiteralArray->GetDynamicImpl())
207         ->literals_[idxOffset + i->payload.GetDynId().moduleRecordIndexOff * gap]
208         .tag_ = panda_file::LiteralTag::NULLVALUE;
209 
210     m->id.erase(found);
211 }
212 
AddNewModuleRequest(AbckitCoreModule * m,AbckitCoreModule * newModule)213 void AddNewModuleRequest(AbckitCoreModule *m, AbckitCoreModule *newModule)
214 {
215     auto mPayload = GetDynModulePayload(m);
216     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
217     m->md.push_back(newModule);
218     auto requestsIdxNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->moduleRequestsOffset - 1].value_);
219     moduleLitArr->literals_[mPayload->moduleRequestsOffset - 1].value_ = requestsIdxNum + 1;
220     auto literalModuleRequest = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING,
221                                                                 "./" + std::string(newModule->moduleName->impl)};
222     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + m->md.size(), std::move(literalModuleRequest));
223 
224     mPayload->regularImportsOffset = mPayload->regularImportsOffset + 1;
225     mPayload->namespaceImportsOffset = mPayload->namespaceImportsOffset + 1;
226     mPayload->localExportsOffset = mPayload->localExportsOffset + 1;
227     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + 1;
228     mPayload->starExportsOffset = mPayload->starExportsOffset + 1;
229 }
230 
231 template <class T>
AddNamespaceImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)232 size_t AddNamespaceImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
233 {
234     auto mPayload = GetDynModulePayload(importing);
235     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
236     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
237 
238     ASSERT((imported->isExternal && importing->file->externalModules.find(imported->moduleName->impl.data()) !=
239                                         importing->file->externalModules.end()) ||
240            (!imported->isExternal && importing->file->localModules.find(imported->moduleName->impl.data()) !=
241                                          importing->file->localModules.end()));
242 
243     auto found = std::find(importing->md.begin(), importing->md.end(), imported);
244     uint16_t requestIdx;
245     if (found != importing->md.end()) {
246         requestIdx = std::distance(importing->md.begin(), found);
247     } else {
248         AddNewModuleRequest(importing, imported);
249         requestIdx = importing->md.size() - 1;
250     }
251 
252     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
253     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->localExportsOffset - 1,
254                                    std::move(literalRequestIdx));
255     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->localExportsOffset - 1,
256                                    std::move(literalLocalName));
257 
258     auto namespaceImportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->namespaceImportsOffset - 1].value_);
259     moduleLitArr->literals_[mPayload->namespaceImportsOffset - 1].value_ = namespaceImportsNum + 1;
260     mPayload->localExportsOffset = mPayload->localExportsOffset + 2U;
261     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + 2U;
262     mPayload->starExportsOffset = mPayload->starExportsOffset + 2U;
263 
264     return namespaceImportsNum;
265 }
266 
267 template <class T>
AddRegularImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)268 size_t AddRegularImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
269 {
270     auto mPayload = GetDynModulePayload(importing);
271     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
272     auto literalImportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
273     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
274 
275     ASSERT((imported->isExternal && importing->file->externalModules.find(imported->moduleName->impl.data()) !=
276                                         importing->file->externalModules.end()) ||
277            (!imported->isExternal && importing->file->localModules.find(imported->moduleName->impl.data()) !=
278                                          importing->file->localModules.end()));
279 
280     auto found = std::find(importing->md.begin(), importing->md.end(), imported);
281     uint16_t requestIdx;
282     if (found != importing->md.end()) {
283         requestIdx = std::distance(importing->md.begin(), found);
284     } else {
285         AddNewModuleRequest(importing, imported);
286         requestIdx = importing->md.size() - 1;
287     }
288 
289     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
290     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
291                                    std::move(literalRequestIdx));
292     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
293                                    std::move(literalImportName));
294     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
295                                    std::move(literalLocalName));
296 
297     auto regularImportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->regularImportsOffset - 1].value_);
298     moduleLitArr->literals_[mPayload->regularImportsOffset - 1].value_ = regularImportsNum + 1;
299     const size_t three = 3;
300     mPayload->namespaceImportsOffset = mPayload->namespaceImportsOffset + three;
301     mPayload->localExportsOffset = mPayload->localExportsOffset + three;
302     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + three;
303     mPayload->starExportsOffset = mPayload->starExportsOffset + three;
304 
305     return regularImportsNum;
306 }
307 
308 template <class T>
AddImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)309 size_t AddImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
310 {
311     return (std::strcmp(params->name, "*") == 0) ? AddNamespaceImportToModuleLiteralArray(importing, imported, params)
312                                                  : AddRegularImportToModuleLiteralArray(importing, imported, params);
313 }
314 
ModuleAddImportFromDynamicModuleDynamic(AbckitCoreModule * importing,AbckitCoreModule * imported,const AbckitArktsImportFromDynamicModuleCreateParams * params)315 AbckitArktsImportDescriptor *ModuleAddImportFromDynamicModuleDynamic(
316     AbckitCoreModule *importing, AbckitCoreModule *imported,
317     const AbckitArktsImportFromDynamicModuleCreateParams *params)
318 {
319     auto id = std::make_unique<AbckitCoreImportDescriptor>();
320     id->importingModule = importing;
321     id->importedModule = imported;
322     auto payloadDyn = AbckitDynamicImportDescriptorPayload();
323     payloadDyn.isRegularImport = std::strcmp(params->name, "*") != 0;
324     payloadDyn.moduleRecordIndexOff = AddImportToModuleLiteralArray(importing, imported, params);
325     auto payload = AbckitCoreImportDescriptorPayload();
326     payload.impl = payloadDyn;
327     id->impl = std::make_unique<AbckitArktsImportDescriptor>();
328     id->GetArkTSImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
329     id->GetArkTSImpl()->payload = payload;
330     id->GetArkTSImpl()->core = id.get();
331     importing->id.push_back(std::move(id));
332 
333     return importing->id[importing->id.size() - 1]->GetArkTSImpl();
334 }
335 
ModuleAddImportFromDynamicModuleDynamic(AbckitCoreModule * importing,AbckitCoreModule * imported,const AbckitJsImportFromDynamicModuleCreateParams * params)336 AbckitJsImportDescriptor *ModuleAddImportFromDynamicModuleDynamic(
337     AbckitCoreModule *importing, AbckitCoreModule *imported, const AbckitJsImportFromDynamicModuleCreateParams *params)
338 {
339     auto id = std::make_unique<AbckitCoreImportDescriptor>();
340     id->importingModule = importing;
341     id->importedModule = imported;
342     auto payloadDyn = AbckitDynamicImportDescriptorPayload();
343     payloadDyn.isRegularImport = std::strcmp(params->name, "*") != 0;
344     payloadDyn.moduleRecordIndexOff = AddImportToModuleLiteralArray(importing, imported, params);
345     auto payload = AbckitCoreImportDescriptorPayload();
346     payload.impl = payloadDyn;
347     id->impl = std::make_unique<AbckitJsImportDescriptor>();
348     id->GetJsImpl()->payload = payload;
349     id->GetJsImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
350     id->GetJsImpl()->core = id.get();
351     importing->id.push_back(std::move(id));
352 
353     return importing->id[importing->id.size() - 1]->GetJsImpl();
354 }
355 
356 template <class T>
AddLocalExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule *,const T * params)357 size_t AddLocalExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule * /*exported*/, const T *params)
358 {
359     auto mPayload = GetDynModulePayload(exporting);
360     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
361     auto literalExportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
362     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
363 
364     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->indirectExportsOffset - 1U,
365                                    std::move(literalExportName));
366     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->indirectExportsOffset - 1U,
367                                    std::move(literalLocalName));
368 
369     auto localExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->localExportsOffset - 1U].value_);
370     moduleLitArr->literals_[mPayload->localExportsOffset - 1U].value_ = localExportsNum + 1U;
371     mPayload->starExportsOffset = mPayload->indirectExportsOffset + 2U;
372     mPayload->starExportsOffset = mPayload->starExportsOffset + 2U;
373 
374     return localExportsNum;
375 }
376 
377 template <class T>
AddIndirectExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params)378 size_t AddIndirectExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params)
379 {
380     auto mPayload = GetDynModulePayload(exporting);
381     auto literalExportName =
382         pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
383     auto literalImportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
384     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
385 
386     ASSERT((exported->isExternal && exporting->file->externalModules.find(exported->moduleName->impl.data()) !=
387                                         exporting->file->externalModules.end()) ||
388            (!exported->isExternal && exporting->file->localModules.find(exported->moduleName->impl.data()) !=
389                                          exporting->file->localModules.end()));
390 
391     auto found = std::find(exporting->md.begin(), exporting->md.end(), exported);
392     uint16_t requestIdx;
393     if (found != exporting->md.end()) {
394         requestIdx = std::distance(exporting->md.begin(), found);
395     } else {
396         AddNewModuleRequest(exporting, exported);
397         requestIdx = exporting->md.size() - 1;
398     }
399 
400     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
401     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
402                                    std::move(literalRequestIdx));
403     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
404                                    std::move(literalImportName));
405     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
406                                    std::move(literalExportName));
407 
408     auto indirectExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->indirectExportsOffset - 1].value_);
409     moduleLitArr->literals_[mPayload->indirectExportsOffset - 1].value_ = indirectExportsNum + 1;
410     mPayload->starExportsOffset = mPayload->starExportsOffset + 3U;
411 
412     return indirectExportsNum;
413 }
414 
GetServiceExportName(AbckitCoreModule * m)415 std::string GetServiceExportName(AbckitCoreModule *m)
416 {
417     auto maxNum = -1;
418     auto mPayload = GetDynModulePayload(m);
419     const auto *moduleLitArr = mPayload->moduleLiteralArray;
420     for (auto &ed : m->ed) {
421         auto edPayload = GetDynExportDescriptorPayload(ed.get());
422         if (edPayload->hasServiceImport) {
423             auto exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2;
424             auto name = std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
425             ASSERT(name.find("=ens") != std::string::npos);
426             const int base = 10U;
427             auto serviceImportsNum = std::strtol(name.substr(4U).c_str(), nullptr, base);
428             if (serviceImportsNum > maxNum) {
429                 maxNum = serviceImportsNum;
430             }
431         }
432     }
433 
434     return "=ens" + std::to_string(maxNum + 1);
435 }
436 
437 template <class T>
AddStarExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params,AbckitDynamicExportDescriptorPayload * payload)438 size_t AddStarExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params,
439                                          AbckitDynamicExportDescriptorPayload *payload)
440 {
441     auto mPayload = GetDynModulePayload(exporting);
442     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
443 
444     ASSERT((exported->isExternal && exporting->file->externalModules.find(exported->moduleName->impl.data()) !=
445                                         exporting->file->externalModules.end()) ||
446            (!exported->isExternal && exporting->file->localModules.find(exported->moduleName->impl.data()) !=
447                                          exporting->file->localModules.end()));
448 
449     auto found = std::find(exporting->md.begin(), exporting->md.end(), exported);
450     uint16_t requestIdx;
451     if (found != exporting->md.end()) {
452         requestIdx = std::distance(exporting->md.begin(), found);
453     } else {
454         AddNewModuleRequest(exporting, exported);
455         requestIdx = exporting->md.size() - 1;
456     }
457 
458     if (params->alias == nullptr) {
459         auto starExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->starExportsOffset - 1].value_);
460         auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
461         moduleLitArr->literals_.push_back(std::move(literalRequestIdx));
462         moduleLitArr->literals_[mPayload->starExportsOffset - 1].value_ = starExportsNum + 1;
463         return starExportsNum;
464     }
465     auto serviceName = GetServiceExportName(exporting);
466     T params1 {};
467     params1.name = params->alias;
468     params1.alias = serviceName.c_str();
469     auto localExpIdx = AddLocalExportToModuleLiteralArray(exporting, nullptr, &params1);
470     T params2 {};
471     params2.alias = serviceName.c_str();
472     auto nsImpIdx = AddNamespaceImportToModuleLiteralArray(exporting, exported, &params2);
473     payload->hasServiceImport = true;
474     payload->serviceNamespaceImportIdx = nsImpIdx;
475     return localExpIdx;
476 }
477 
478 template <class T>
AddExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params,AbckitDynamicExportDescriptorPayload * payload,AbckitDynamicExportKind kind)479 size_t AddExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params,
480                                      AbckitDynamicExportDescriptorPayload *payload, AbckitDynamicExportKind kind)
481 {
482     switch (kind) {
483         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
484             return AddStarExportToModuleLiteralArray(exporting, exported, params, payload);
485         }
486         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
487             return AddLocalExportToModuleLiteralArray(exporting, exported, params);
488         }
489         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
490             return AddIndirectExportToModuleLiteralArray(exporting, exported, params);
491         }
492     }
493     UNREACHABLE();
494 }
495 
DynamicModuleAddExportDynamic(AbckitCoreModule * exporting,AbckitCoreModule * exported,const AbckitArktsDynamicModuleExportCreateParams * params)496 AbckitArktsExportDescriptor *DynamicModuleAddExportDynamic(AbckitCoreModule *exporting, AbckitCoreModule *exported,
497                                                            const AbckitArktsDynamicModuleExportCreateParams *params)
498 {
499     auto ed = std::make_unique<AbckitCoreExportDescriptor>();
500     ed->exportingModule = exporting;
501     ed->exportedModule = exported;
502     auto payloadDyn = AbckitDynamicExportDescriptorPayload();
503     if (std::strcmp(params->name, "*") == 0) {
504         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
505     } else if (exported == exporting) {
506         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
507         ed->exportedModule = exporting;
508     } else {
509         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
510     }
511 
512     payloadDyn.hasServiceImport = false;
513     payloadDyn.moduleRecordIndexOff =
514         AddExportToModuleLiteralArray(exporting, exported, params, &payloadDyn, payloadDyn.kind);
515     auto payload = AbckitCoreExportDescriptorPayload();
516     payload.impl = payloadDyn;
517     ed->impl = std::make_unique<AbckitArktsExportDescriptor>();
518     ed->GetArkTSImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
519     ed->GetArkTSImpl()->payload = payload;
520     ed->GetArkTSImpl()->core = ed.get();
521     exporting->ed.push_back(std::move(ed));
522 
523     return exporting->ed[exporting->ed.size() - 1]->GetArkTSImpl();
524 }
525 
DynamicModuleAddExportDynamic(AbckitCoreModule * exporting,AbckitCoreModule * exported,const AbckitJsDynamicModuleExportCreateParams * params)526 AbckitJsExportDescriptor *DynamicModuleAddExportDynamic(AbckitCoreModule *exporting, AbckitCoreModule *exported,
527                                                         const AbckitJsDynamicModuleExportCreateParams *params)
528 {
529     auto ed = std::make_unique<AbckitCoreExportDescriptor>();
530     ed->exportingModule = exporting;
531     ed->exportedModule = exported;
532     auto payloadDyn = AbckitDynamicExportDescriptorPayload();
533     if (std::strcmp(params->name, "*") == 0) {
534         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
535     } else if (exported == exporting) {
536         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
537         ed->exportedModule = exporting;
538     } else {
539         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
540     }
541 
542     payloadDyn.hasServiceImport = false;
543     payloadDyn.moduleRecordIndexOff =
544         AddExportToModuleLiteralArray(exporting, exported, params, &payloadDyn, payloadDyn.kind);
545     auto payload = AbckitCoreExportDescriptorPayload();
546     payload.impl = payloadDyn;
547     ed->impl = std::make_unique<AbckitJsExportDescriptor>();
548     ed->GetJsImpl()->payload = payload;
549     ed->GetJsImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
550     ed->GetJsImpl()->core = ed.get();
551     exporting->ed.push_back(std::move(ed));
552     return exporting->ed[exporting->ed.size() - 1]->GetJsImpl();
553 }
554 
ModuleRemoveExportDynamic(AbckitCoreModule * m,AbckitArktsExportDescriptor * i)555 void ModuleRemoveExportDynamic(AbckitCoreModule *m, AbckitArktsExportDescriptor *i)
556 {
557     LIBABCKIT_LOG_FUNC;
558     auto found = std::find_if(m->ed.begin(), m->ed.end(),
559                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == i->core; });
560     if (found == m->ed.end()) {
561         LIBABCKIT_LOG(DEBUG) << "Can not find the export to delete\n";
562         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
563         return;
564     }
565 
566     auto idxOffset = 0;
567     auto gap = 0;
568     auto mPayload = GetDynModulePayload(m);
569     switch (i->payload.GetDynamicPayload().kind) {
570         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
571             idxOffset = mPayload->localExportsOffset;
572             gap = 2U;
573             break;
574         }
575         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
576             idxOffset = mPayload->indirectExportsOffset;
577             gap = 3U;
578             break;
579         }
580         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
581             idxOffset = mPayload->starExportsOffset;
582             gap = 1;
583         }
584     }
585     (mPayload->moduleLiteralArray->GetDynamicImpl())
586         ->literals_[idxOffset + i->payload.GetDynamicPayload().moduleRecordIndexOff * gap]
587         .tag_ = panda_file::LiteralTag::NULLVALUE;
588 
589     m->ed.erase(found);
590 }
591 
ModuleRemoveExportDynamic(AbckitCoreModule * m,AbckitJsExportDescriptor * i)592 void ModuleRemoveExportDynamic(AbckitCoreModule *m, AbckitJsExportDescriptor *i)
593 {
594     LIBABCKIT_LOG_FUNC;
595     auto found = std::find_if(m->ed.begin(), m->ed.end(),
596                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == i->core; });
597     if (found == m->ed.end()) {
598         LIBABCKIT_LOG(DEBUG) << "Can not find the export to delete\n";
599         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
600         return;
601     }
602 
603     auto idxOffset = 0U;
604     auto gap = 0U;
605     auto mPayload = GetDynModulePayload(m);
606     switch (i->payload.GetDynamicPayload().kind) {
607         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
608             idxOffset = mPayload->localExportsOffset;
609             gap = 2U;
610             break;
611         }
612         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
613             idxOffset = mPayload->indirectExportsOffset;
614             gap = 3U;
615             break;
616         }
617         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
618             idxOffset = mPayload->starExportsOffset;
619             gap = 1U;
620         }
621     }
622     (mPayload->moduleLiteralArray->GetDynamicImpl())
623         ->literals_[idxOffset + i->payload.GetDynamicPayload().moduleRecordIndexOff * gap]
624         .tag_ = panda_file::LiteralTag::NULLVALUE;
625 
626     m->ed.erase(found);
627 }
628 
FindOrCreateLiteralBoolDynamic(AbckitFile * file,bool value)629 AbckitLiteral *FindOrCreateLiteralBoolDynamic(AbckitFile *file, bool value)
630 {
631     LIBABCKIT_LOG_FUNC;
632     return FindOrCreateLiteralBoolDynamicImpl(file, value);
633 }
634 
FindOrCreateLiteralU8Dynamic(AbckitFile * file,uint8_t value)635 AbckitLiteral *FindOrCreateLiteralU8Dynamic(AbckitFile *file, uint8_t value)
636 {
637     LIBABCKIT_LOG_FUNC;
638     return FindOrCreateLiteralU8DynamicImpl(file, value);
639 }
640 
FindOrCreateLiteralU16Dynamic(AbckitFile * file,uint16_t value)641 AbckitLiteral *FindOrCreateLiteralU16Dynamic(AbckitFile *file, uint16_t value)
642 {
643     LIBABCKIT_LOG_FUNC;
644     return FindOrCreateLiteralU16DynamicImpl(file, value);
645 }
646 
FindOrCreateLiteralMethodAffiliateDynamic(AbckitFile * file,uint16_t value)647 AbckitLiteral *FindOrCreateLiteralMethodAffiliateDynamic(AbckitFile *file, uint16_t value)
648 {
649     LIBABCKIT_LOG_FUNC;
650     return FindOrCreateLiteralMethodAffiliateDynamicImpl(file, value);
651 }
652 
FindOrCreateLiteralU32Dynamic(AbckitFile * file,uint32_t value)653 AbckitLiteral *FindOrCreateLiteralU32Dynamic(AbckitFile *file, uint32_t value)
654 {
655     LIBABCKIT_LOG_FUNC;
656     return FindOrCreateLiteralU32DynamicImpl(file, value);
657 }
658 
FindOrCreateLiteralU64Dynamic(AbckitFile * file,uint64_t value)659 AbckitLiteral *FindOrCreateLiteralU64Dynamic(AbckitFile *file, uint64_t value)
660 {
661     LIBABCKIT_LOG_FUNC;
662     return FindOrCreateLiteralU64DynamicImpl(file, value);
663 }
664 
FindOrCreateLiteralFloatDynamic(AbckitFile * file,float value)665 AbckitLiteral *FindOrCreateLiteralFloatDynamic(AbckitFile *file, float value)
666 {
667     LIBABCKIT_LOG_FUNC;
668     return FindOrCreateLiteralFloatDynamicImpl(file, value);
669 }
670 
FindOrCreateLiteralDoubleDynamic(AbckitFile * file,double value)671 AbckitLiteral *FindOrCreateLiteralDoubleDynamic(AbckitFile *file, double value)
672 {
673     LIBABCKIT_LOG_FUNC;
674     return FindOrCreateLiteralDoubleDynamicImpl(file, value);
675 }
676 
FindOrCreateLiteralStringDynamic(AbckitFile * file,const char * value,size_t len)677 AbckitLiteral *FindOrCreateLiteralStringDynamic(AbckitFile *file, const char *value, size_t len)
678 {
679     LIBABCKIT_LOG_FUNC;
680     return FindOrCreateLiteralStringDynamicImpl(file, std::string(value, len));
681 }
682 
FindOrCreateLiteralMethodDynamic(AbckitFile * file,AbckitCoreFunction * function)683 AbckitLiteral *FindOrCreateLiteralMethodDynamic(AbckitFile *file, AbckitCoreFunction *function)
684 {
685     LIBABCKIT_LOG_FUNC;
686     return FindOrCreateLiteralMethodDynamicImpl(file, GetDynFunction(function)->name);
687 }
688 
FindOrCreateLiteralLiteralArrayDynamic(AbckitFile * file,AbckitLiteralArray * litarr)689 AbckitLiteral *FindOrCreateLiteralLiteralArrayDynamic(AbckitFile *file, AbckitLiteralArray *litarr)
690 {
691     LIBABCKIT_LOG_FUNC;
692     std::string arrName;
693     for (auto &item : file->GetDynamicProgram()->literalarray_table) {
694         if (&item.second == litarr->GetDynamicImpl()) {
695             arrName = item.first;
696             break;
697         }
698     }
699     return FindOrCreateLiteralLiteralArrayDynamicImpl(file, arrName);
700 }
701 
CreateLiteralArrayDynamic(AbckitFile * file,AbckitLiteral ** value,size_t size)702 AbckitLiteralArray *CreateLiteralArrayDynamic(AbckitFile *file, AbckitLiteral **value, size_t size)
703 {
704     LIBABCKIT_LOG_FUNC;
705     auto *prog = file->GetDynamicProgram();
706 
707     std::vector<pandasm::LiteralArray::Literal> stdLitArr;
708     for (size_t i = 0; i < size; i++) {
709         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
710         auto lit = *reinterpret_cast<pandasm::LiteralArray::Literal *>(value[i]->val.get());
711         pandasm::LiteralArray::Literal tagLit;
712         tagLit.tag_ = panda_file::LiteralTag::TAGVALUE;
713         tagLit.value_ = static_cast<uint8_t>(lit.tag_);
714         stdLitArr.emplace_back(tagLit);
715         stdLitArr.emplace_back(lit);
716     }
717 
718     // NOLINTNEXTLINE(cert-msc51-cpp)
719     uint32_t arrayOffset = 0;
720     while (prog->literalarray_table.find(std::to_string(arrayOffset)) != prog->literalarray_table.end()) {
721         arrayOffset++;
722     }
723     auto arrayName = std::to_string(arrayOffset);
724 
725     prog->literalarray_table.emplace(arrayName, pandasm::LiteralArray());
726     pandasm::LiteralArray &arrImpl = prog->literalarray_table[arrayName];
727     arrImpl.literals_ = std::move(stdLitArr);
728 
729     auto litarr = std::make_unique<AbckitLiteralArray>(file, &arrImpl);
730     return file->litarrs.emplace_back(std::move(litarr)).get();
731 }
732 
FindOrCreateValueU1Dynamic(AbckitFile * file,bool value)733 AbckitValue *FindOrCreateValueU1Dynamic(AbckitFile *file, bool value)
734 {
735     LIBABCKIT_LOG_FUNC;
736     return FindOrCreateValueU1DynamicImpl(file, value);
737 }
738 
FindOrCreateValueDoubleDynamic(AbckitFile * file,double value)739 AbckitValue *FindOrCreateValueDoubleDynamic(AbckitFile *file, double value)
740 {
741     LIBABCKIT_LOG_FUNC;
742     return FindOrCreateValueDoubleDynamicImpl(file, value);
743 }
744 
FindOrCreateValueStringDynamic(AbckitFile * file,const char * value,size_t len)745 AbckitValue *FindOrCreateValueStringDynamic(AbckitFile *file, const char *value, size_t len)
746 {
747     LIBABCKIT_LOG_FUNC;
748     return FindOrCreateValueStringDynamicImpl(file, std::string(value, len));
749 }
750 
FindOrCreateLiteralArrayValueDynamic(AbckitFile * file,AbckitValue ** value,size_t size)751 AbckitValue *FindOrCreateLiteralArrayValueDynamic(AbckitFile *file, AbckitValue **value, size_t size)
752 {
753     LIBABCKIT_LOG_FUNC;
754     std::vector<AbckitLiteral *> litArr;
755     for (size_t i = 0; i < size; i++) {
756         // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
757         switch (ValueGetTypeDynamic(value[i])->id) {
758             case ABCKIT_TYPE_ID_U1:
759                 litArr.emplace_back(FindOrCreateLiteralBoolDynamic(file, ValueGetU1Dynamic(value[i])));
760                 break;
761             case ABCKIT_TYPE_ID_F64:
762                 litArr.emplace_back(FindOrCreateLiteralDoubleDynamic(file, ValueGetDoubleDynamic(value[i])));
763                 break;
764             case ABCKIT_TYPE_ID_STRING:
765                 litArr.emplace_back(FindOrCreateLiteralStringDynamic(file, ValueGetStringDynamic(value[i])->impl.data(),
766                                                                      ValueGetStringDynamic(value[i])->impl.size()));
767                 break;
768             default:
769                 break;
770         }
771         // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
772     }
773     auto *abcArr = CreateLiteralArrayDynamic(file, litArr.data(), litArr.size());
774     auto *prog = file->GetDynamicProgram();
775     std::string arrName;
776     for (auto &item : prog->literalarray_table) {
777         if (&item.second == abcArr->GetDynamicImpl()) {
778             arrName = item.first;
779             break;
780         }
781     }
782     return FindOrCreateLiteralArrayValueDynamicImpl(file, arrName);
783 }
784 
ModuleAddAnnotationInterfaceDynamic(AbckitCoreModule * m,const AbckitArktsAnnotationInterfaceCreateParams * params)785 AbckitArktsAnnotationInterface *ModuleAddAnnotationInterfaceDynamic(
786     AbckitCoreModule *m, const AbckitArktsAnnotationInterfaceCreateParams *params)
787 {
788     std::string name = params->name;
789     auto prog = m->file->GetDynamicProgram();
790     auto progRecord = pandasm::Record {name, prog->lang};
791     progRecord.metadata->SetAccessFlags(ACC_ANNOTATION);
792     prog->record_table.emplace(name, std::move(progRecord));
793     pandasm::Record &record = prog->record_table.find(name)->second;
794     auto ai = std::make_unique<AbckitCoreAnnotationInterface>();
795     ai->owningModule = m;
796     ai->impl = std::make_unique<AbckitArktsAnnotationInterface>();
797     ai->GetArkTSImpl()->impl = &record;
798     ai->GetArkTSImpl()->core = ai.get();
799     return m->at.emplace(name, std::move(ai)).first->second->GetArkTSImpl();
800 }
801 
ClassAddAnnotationDynamic(AbckitCoreClass * klass,const AbckitArktsAnnotationCreateParams * params)802 AbckitArktsAnnotation *ClassAddAnnotationDynamic(AbckitCoreClass *klass,
803                                                  const AbckitArktsAnnotationCreateParams *params)
804 {
805     auto ai = params->ai;
806 
807     auto progFunc = klass->GetArkTSImpl()->impl.GetDynamicClass();
808     auto name = ai->GetDynamicImpl()->name;
809 
810     std::vector<pandasm::AnnotationData> vec;
811     vec.emplace_back(name);
812 
813     progFunc->metadata->AddAnnotations(vec);
814 
815     auto anno = std::make_unique<AbckitCoreAnnotation>();
816     anno->owner = klass;
817     anno->name = AnnotationInterfaceGetNameDynamic(ai->core);
818     anno->ai = ai->core;
819     anno->impl = std::make_unique<AbckitArktsAnnotation>();
820     anno->GetArkTSImpl()->core = anno.get();
821     return klass->annotations.emplace_back(std::move(anno))->GetArkTSImpl();
822 }
823 
ClassRemoveAnnotationDynamic(AbckitCoreClass * klass,AbckitCoreAnnotation * anno)824 void ClassRemoveAnnotationDynamic(AbckitCoreClass *klass, AbckitCoreAnnotation *anno)
825 {
826     auto progFunc = klass->GetArkTSImpl()->impl.GetDynamicClass();
827 
828     auto name = anno->name->impl;
829 
830     progFunc->metadata->DeleteAnnotationByName(name);
831     auto &annotations = klass->annotations;
832     auto iter = std::find_if(annotations.begin(), annotations.end(),
833                              [&name](auto &annoIt) { return name == annoIt.get()->name->impl; });
834     if (iter == annotations.end()) {
835         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation to delete\n";
836         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
837         return;
838     }
839 
840     annotations.erase(iter);
841 }
842 
FunctionAddAnnotationDynamic(AbckitCoreFunction * function,const AbckitArktsAnnotationCreateParams * params)843 AbckitArktsAnnotation *FunctionAddAnnotationDynamic(AbckitCoreFunction *function,
844                                                     const AbckitArktsAnnotationCreateParams *params)
845 {
846     auto ai = params->ai;
847 
848     auto progFunc = function->GetArkTSImpl()->GetDynamicImpl();
849     auto name = ai->GetDynamicImpl()->name;
850 
851     std::vector<pandasm::AnnotationData> vec;
852     vec.emplace_back(name);
853 
854     progFunc->metadata->AddAnnotations(vec);
855 
856     auto anno = std::make_unique<AbckitCoreAnnotation>();
857     anno->owner = function;
858     anno->name = AnnotationInterfaceGetNameDynamic(ai->core);
859     anno->ai = ai->core;
860     anno->impl = std::make_unique<AbckitArktsAnnotation>();
861     anno->GetArkTSImpl()->core = anno.get();
862     return function->annotations.emplace_back(std::move(anno))->GetArkTSImpl();
863 }
864 
FunctionRemoveAnnotationDynamic(AbckitCoreFunction * function,AbckitCoreAnnotation * anno)865 void FunctionRemoveAnnotationDynamic(AbckitCoreFunction *function, AbckitCoreAnnotation *anno)
866 {
867     auto progFunc = function->GetArkTSImpl()->GetDynamicImpl();
868 
869     auto name = anno->name->impl;
870 
871     progFunc->metadata->DeleteAnnotationByName(name);
872     auto &annotations = function->annotations;
873     auto iter = std::find_if(annotations.begin(), annotations.end(),
874                              [&name](auto &annoIt) { return name == annoIt.get()->name->impl; });
875     if (iter == annotations.end()) {
876         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation to delete\n";
877         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
878         return;
879     }
880     annotations.erase(iter);
881     anno = nullptr;
882 }
883 
AnnotationAddAnnotationElementDynamic(AbckitCoreAnnotation * anno,AbckitArktsAnnotationElementCreateParams * params)884 AbckitArktsAnnotationElement *AnnotationAddAnnotationElementDynamic(AbckitCoreAnnotation *anno,
885                                                                     AbckitArktsAnnotationElementCreateParams *params)
886 {
887     auto valuePtr = params->value;
888     auto name = params->name;
889 
890     auto progAnnoElemValue = std::make_unique<pandasm::Value>(*reinterpret_cast<pandasm::Value *>(valuePtr->val.get()));
891     pandasm::AnnotationElement progAnnoElem(params->name, std::move(progAnnoElemValue));
892 
893     auto annoElem = std::make_unique<AbckitCoreAnnotationElement>();
894     annoElem->ann = anno;
895     auto annoElemName = progAnnoElem.GetName();
896     annoElem->name = CreateStringDynamic(anno->ai->owningModule->file, annoElemName.data(), annoElemName.size());
897     annoElem->value = valuePtr;
898 
899     if (std::holds_alternative<AbckitCoreFunction *>(anno->owner)) {
900         auto *func = std::get<AbckitCoreFunction *>(anno->owner);
901         auto progOwner = func->GetArkTSImpl()->GetDynamicImpl();
902         progOwner->metadata->AddAnnotationElementByName(name, std::move(progAnnoElem));
903         annoElem->value->file = func->owningModule->file;
904     } else if (std::holds_alternative<AbckitCoreClass *>(anno->owner)) {
905         auto *klass = std::get<AbckitCoreClass *>(anno->owner);
906         auto progOwner = klass->GetArkTSImpl()->impl.GetDynamicClass();
907         progOwner->metadata->AddAnnotationElementByName(name, std::move(progAnnoElem));
908         annoElem->value->file = klass->owningModule->file;
909     }
910 
911     annoElem->impl = std::make_unique<AbckitArktsAnnotationElement>();
912     annoElem->GetArkTSImpl()->core = annoElem.get();
913 
914     return anno->elements.emplace_back(std::move(annoElem))->GetArkTSImpl();
915 }
916 
AnnotationRemoveAnnotationElementDynamic(AbckitCoreAnnotation * anno,AbckitCoreAnnotationElement * elem)917 void AnnotationRemoveAnnotationElementDynamic(AbckitCoreAnnotation *anno, AbckitCoreAnnotationElement *elem)
918 {
919     if (elem->ann != anno) {
920         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
921         return;
922     }
923 
924     auto name = elem->name;
925 
926     if (std::holds_alternative<AbckitCoreFunction *>(anno->owner)) {
927         auto progOwner = std::get<AbckitCoreFunction *>(anno->owner)->GetArkTSImpl()->GetDynamicImpl();
928         progOwner->metadata->DeleteAnnotationElementByName(anno->name->impl, name->impl);
929     } else if (std::holds_alternative<AbckitCoreClass *>(anno->owner)) {
930         auto progOwner = std::get<AbckitCoreClass *>(anno->owner)->GetArkTSImpl()->impl.GetDynamicClass();
931         progOwner->metadata->DeleteAnnotationElementByName(anno->name->impl, name->impl);
932     }
933 
934     auto &annotationElements = anno->elements;
935     auto iter = std::find_if(annotationElements.begin(), annotationElements.end(),
936                              [&name](auto &annoElemIt) { return name->impl == annoElemIt.get()->name->impl; });
937     if (iter == annotationElements.end()) {
938         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation element to delete\n";
939         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
940         return;
941     }
942     annotationElements.erase(iter);
943 }
944 
TypeToName(AbckitType * type)945 std::string TypeToName(AbckitType *type)
946 {
947     if (type->id == ABCKIT_TYPE_ID_REFERENCE) {
948         auto str = ClassGetNameDynamic(type->klass);
949         if (str == nullptr) {
950             return "";
951         }
952         return std::string(str->impl);
953     }
954     switch (type->id) {
955         case ABCKIT_TYPE_ID_VOID:
956             return "void";
957         case ABCKIT_TYPE_ID_U1:
958             return "u1";
959         case ABCKIT_TYPE_ID_U8:
960             return "u8";
961         case ABCKIT_TYPE_ID_I8:
962             return "u8";
963         case ABCKIT_TYPE_ID_U16:
964             return "u16";
965         case ABCKIT_TYPE_ID_I16:
966             return "i16";
967         case ABCKIT_TYPE_ID_U32:
968             return "u32";
969         case ABCKIT_TYPE_ID_I32:
970             return "i32";
971         case ABCKIT_TYPE_ID_U64:
972             return "u64";
973         case ABCKIT_TYPE_ID_I64:
974             return "i64";
975         case ABCKIT_TYPE_ID_F32:
976             return "f32";
977         case ABCKIT_TYPE_ID_F64:
978             return "f64";
979         case ABCKIT_TYPE_ID_ANY:
980             return "any";
981         case ABCKIT_TYPE_ID_STRING:
982             return "panda.String";
983         default:
984             return "invalid";
985     }
986 }
987 
AnnotationInterfaceAddFieldDynamic(AbckitCoreAnnotationInterface * ai,const AbckitArktsAnnotationInterfaceFieldCreateParams * params)988 AbckitArktsAnnotationInterfaceField *AnnotationInterfaceAddFieldDynamic(
989     AbckitCoreAnnotationInterface *ai, const AbckitArktsAnnotationInterfaceFieldCreateParams *params)
990 {
991     auto name = params->name;
992     auto type = params->type;
993     auto value = params->defaultValue;
994 
995     auto field = std::make_unique<AbckitCoreAnnotationInterfaceField>();
996     field->ai = ai;
997     field->name = CreateStringDynamic(ai->owningModule->file, name, strlen(name));
998     field->type = type;
999     field->value = value;
1000 
1001     field->impl = std::make_unique<AbckitArktsAnnotationInterfaceField>();
1002     field->GetArkTSImpl()->core = field.get();
1003     ai->fields.emplace_back(std::move(field));
1004 
1005     auto record = ai->GetArkTSImpl()->GetDynamicImpl();
1006 
1007     auto prog = ai->owningModule->file->GetDynamicProgram();
1008     auto progField = pandasm::Field(prog->lang);
1009 
1010     progField.name = name;
1011     std::string typeName;
1012     progField.type = pandasm::Type(TypeToName(type), type->rank);
1013     progField.metadata->SetValue(*reinterpret_cast<pandasm::ScalarValue *>(value->val.get()));
1014     record->field_list.emplace_back(std::move(progField));
1015 
1016     return ai->fields.back()->GetArkTSImpl();
1017 }
1018 
AnnotationInterfaceRemoveFieldDynamic(AbckitCoreAnnotationInterface * ai,AbckitCoreAnnotationInterfaceField * field)1019 void AnnotationInterfaceRemoveFieldDynamic(AbckitCoreAnnotationInterface *ai, AbckitCoreAnnotationInterfaceField *field)
1020 {
1021     if (field->ai != ai) {
1022         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1023         return;
1024     }
1025 
1026     auto str = field->name;
1027     if (str == nullptr) {
1028         statuses::SetLastError(ABCKIT_STATUS_INTERNAL_ERROR);
1029         return;
1030     }
1031     auto name = str->impl;
1032 
1033     auto record = ai->GetArkTSImpl()->GetDynamicImpl();
1034 
1035     auto &fields = record->field_list;
1036 
1037     auto fieldsIter = std::find_if(fields.begin(), fields.end(), [&name](auto &field) { return name == field.name; });
1038     if (fieldsIter == fields.end()) {
1039         LIBABCKIT_LOG(DEBUG) << "Can not find the field to delete\n";
1040         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
1041         return;
1042     }
1043     fields.erase(fieldsIter);
1044 
1045     auto &aiFields = ai->fields;
1046     auto iter = std::find_if(aiFields.begin(), aiFields.end(),
1047                              [&name](auto &field) { return name == field.get()->name->impl; });
1048     if (iter == aiFields.end()) {
1049         LIBABCKIT_LOG(DEBUG) << "Can not find the field to delete\n";
1050         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
1051         return;
1052     }
1053     aiFields.erase(iter);
1054 }
1055 
1056 }  // namespace libabckit
1057