• 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 = std::move(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[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 
221     std::string moduleRequest = std::string(newModule->moduleName->impl);
222     if (moduleRequest[0] != '@') {
223         moduleRequest = "./" + moduleRequest;
224     }
225     auto literalModuleRequest = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, moduleRequest};
226     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + m->md.size(), std::move(literalModuleRequest));
227 
228     mPayload->regularImportsOffset = mPayload->regularImportsOffset + 1;
229     mPayload->namespaceImportsOffset = mPayload->namespaceImportsOffset + 1;
230     mPayload->localExportsOffset = mPayload->localExportsOffset + 1;
231     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + 1;
232     mPayload->starExportsOffset = mPayload->starExportsOffset + 1;
233 }
234 
235 template <class T>
AddNamespaceImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)236 size_t AddNamespaceImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
237 {
238     auto mPayload = GetDynModulePayload(importing);
239     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
240     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
241 
242     ASSERT((imported->isExternal && importing->file->externalModules.find(imported->moduleName->impl.data()) !=
243                                         importing->file->externalModules.end()) ||
244            (!imported->isExternal && importing->file->localModules.find(imported->moduleName->impl.data()) !=
245                                          importing->file->localModules.end()));
246 
247     auto found = std::find(importing->md.begin(), importing->md.end(), imported);
248     uint16_t requestIdx;
249     if (found != importing->md.end()) {
250         requestIdx = std::distance(importing->md.begin(), found);
251     } else {
252         AddNewModuleRequest(importing, imported);
253         requestIdx = importing->md.size() - 1;
254     }
255 
256     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
257     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->localExportsOffset - 1,
258                                    std::move(literalRequestIdx));
259     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->localExportsOffset - 1,
260                                    std::move(literalLocalName));
261 
262     auto namespaceImportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->namespaceImportsOffset - 1].value_);
263     moduleLitArr->literals_[mPayload->namespaceImportsOffset - 1].value_ = namespaceImportsNum + 1;
264     mPayload->localExportsOffset = mPayload->localExportsOffset + 2U;
265     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + 2U;
266     mPayload->starExportsOffset = mPayload->starExportsOffset + 2U;
267 
268     return namespaceImportsNum;
269 }
270 
271 template <class T>
AddRegularImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)272 size_t AddRegularImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
273 {
274     auto mPayload = GetDynModulePayload(importing);
275     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
276     auto literalImportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
277     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
278 
279     ASSERT((imported->isExternal && importing->file->externalModules.find(imported->moduleName->impl.data()) !=
280                                         importing->file->externalModules.end()) ||
281            (!imported->isExternal && importing->file->localModules.find(imported->moduleName->impl.data()) !=
282                                          importing->file->localModules.end()));
283 
284     auto found = std::find(importing->md.begin(), importing->md.end(), imported);
285     uint16_t requestIdx;
286     if (found != importing->md.end()) {
287         requestIdx = std::distance(importing->md.begin(), found);
288     } else {
289         AddNewModuleRequest(importing, imported);
290         requestIdx = importing->md.size() - 1;
291     }
292 
293     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
294     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
295                                    std::move(literalRequestIdx));
296     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
297                                    std::move(literalImportName));
298     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->namespaceImportsOffset - 1,
299                                    std::move(literalLocalName));
300 
301     auto regularImportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->regularImportsOffset - 1].value_);
302     moduleLitArr->literals_[mPayload->regularImportsOffset - 1].value_ = regularImportsNum + 1;
303     const size_t three = 3;
304     mPayload->namespaceImportsOffset = mPayload->namespaceImportsOffset + three;
305     mPayload->localExportsOffset = mPayload->localExportsOffset + three;
306     mPayload->indirectExportsOffset = mPayload->indirectExportsOffset + three;
307     mPayload->starExportsOffset = mPayload->starExportsOffset + three;
308 
309     return regularImportsNum;
310 }
311 
312 template <class T>
AddImportToModuleLiteralArray(AbckitCoreModule * importing,AbckitCoreModule * imported,const T * params)313 size_t AddImportToModuleLiteralArray(AbckitCoreModule *importing, AbckitCoreModule *imported, const T *params)
314 {
315     return (std::strcmp(params->name, "*") == 0) ? AddNamespaceImportToModuleLiteralArray(importing, imported, params)
316                                                  : AddRegularImportToModuleLiteralArray(importing, imported, params);
317 }
318 
ModuleAddImportFromDynamicModuleDynamic(AbckitCoreModule * importing,AbckitCoreModule * imported,const AbckitArktsImportFromDynamicModuleCreateParams * params)319 AbckitArktsImportDescriptor *ModuleAddImportFromDynamicModuleDynamic(
320     AbckitCoreModule *importing, AbckitCoreModule *imported,
321     const AbckitArktsImportFromDynamicModuleCreateParams *params)
322 {
323     auto id = std::make_unique<AbckitCoreImportDescriptor>();
324     id->importingModule = importing;
325     id->importedModule = imported;
326     auto payloadDyn = AbckitDynamicImportDescriptorPayload();
327     payloadDyn.isRegularImport = std::strcmp(params->name, "*") != 0;
328     payloadDyn.moduleRecordIndexOff = AddImportToModuleLiteralArray(importing, imported, params);
329     auto payload = AbckitCoreImportDescriptorPayload();
330     payload.impl = payloadDyn;
331     id->impl = std::make_unique<AbckitArktsImportDescriptor>();
332     id->GetArkTSImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
333     id->GetArkTSImpl()->payload = payload;
334     id->GetArkTSImpl()->core = id.get();
335     importing->id.push_back(std::move(id));
336 
337     return importing->id[importing->id.size() - 1]->GetArkTSImpl();
338 }
339 
ModuleAddImportFromDynamicModuleDynamic(AbckitCoreModule * importing,AbckitCoreModule * imported,const AbckitJsImportFromDynamicModuleCreateParams * params)340 AbckitJsImportDescriptor *ModuleAddImportFromDynamicModuleDynamic(
341     AbckitCoreModule *importing, AbckitCoreModule *imported, const AbckitJsImportFromDynamicModuleCreateParams *params)
342 {
343     auto id = std::make_unique<AbckitCoreImportDescriptor>();
344     id->importingModule = importing;
345     id->importedModule = imported;
346     auto payloadDyn = AbckitDynamicImportDescriptorPayload();
347     payloadDyn.isRegularImport = std::strcmp(params->name, "*") != 0;
348     payloadDyn.moduleRecordIndexOff = AddImportToModuleLiteralArray(importing, imported, params);
349     auto payload = AbckitCoreImportDescriptorPayload();
350     payload.impl = payloadDyn;
351     id->impl = std::make_unique<AbckitJsImportDescriptor>();
352     id->GetJsImpl()->payload = payload;
353     id->GetJsImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
354     id->GetJsImpl()->core = id.get();
355     importing->id.push_back(std::move(id));
356 
357     return importing->id[importing->id.size() - 1]->GetJsImpl();
358 }
359 
360 template <class T>
AddLocalExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule *,const T * params)361 size_t AddLocalExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule * /*exported*/, const T *params)
362 {
363     auto mPayload = GetDynModulePayload(exporting);
364     auto literalLocalName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
365     auto literalExportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
366     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
367 
368     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->indirectExportsOffset - 1U,
369                                    std::move(literalExportName));
370     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->indirectExportsOffset - 1U,
371                                    std::move(literalLocalName));
372 
373     auto localExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->localExportsOffset - 1U].value_);
374     moduleLitArr->literals_[mPayload->localExportsOffset - 1U].value_ = localExportsNum + 1U;
375     mPayload->starExportsOffset = mPayload->indirectExportsOffset + 2U;
376     mPayload->starExportsOffset = mPayload->starExportsOffset + 2U;
377 
378     return localExportsNum;
379 }
380 
381 template <class T>
AddIndirectExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params)382 size_t AddIndirectExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params)
383 {
384     auto mPayload = GetDynModulePayload(exporting);
385     auto literalExportName =
386         pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->alias)};
387     auto literalImportName = pandasm::LiteralArray::Literal {panda_file::LiteralTag::STRING, std::string(params->name)};
388     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
389 
390     ASSERT((exported->isExternal && exporting->file->externalModules.find(exported->moduleName->impl.data()) !=
391                                         exporting->file->externalModules.end()) ||
392            (!exported->isExternal && exporting->file->localModules.find(exported->moduleName->impl.data()) !=
393                                          exporting->file->localModules.end()));
394 
395     auto found = std::find(exporting->md.begin(), exporting->md.end(), exported);
396     uint16_t requestIdx;
397     if (found != exporting->md.end()) {
398         requestIdx = std::distance(exporting->md.begin(), found);
399     } else {
400         AddNewModuleRequest(exporting, exported);
401         requestIdx = exporting->md.size() - 1;
402     }
403 
404     auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
405     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
406                                    std::move(literalRequestIdx));
407     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
408                                    std::move(literalImportName));
409     moduleLitArr->literals_.insert(moduleLitArr->literals_.begin() + mPayload->starExportsOffset - 1,
410                                    std::move(literalExportName));
411 
412     auto indirectExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->indirectExportsOffset - 1].value_);
413     moduleLitArr->literals_[mPayload->indirectExportsOffset - 1].value_ = indirectExportsNum + 1;
414     mPayload->starExportsOffset = mPayload->starExportsOffset + 3U;
415 
416     return indirectExportsNum;
417 }
418 
GetServiceExportName(AbckitCoreModule * m)419 std::string GetServiceExportName(AbckitCoreModule *m)
420 {
421     auto maxNum = -1;
422     auto mPayload = GetDynModulePayload(m);
423     const auto *moduleLitArr = mPayload->moduleLiteralArray;
424     for (auto &ed : m->ed) {
425         auto edPayload = GetDynExportDescriptorPayload(ed.get());
426         if (edPayload->hasServiceImport) {
427             auto exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2;
428             auto name = std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
429             ASSERT(name.find("=ens") != std::string::npos);
430             const int base = 10U;
431             auto serviceImportsNum = std::strtol(name.substr(4U).c_str(), nullptr, base);
432             if (serviceImportsNum > maxNum) {
433                 maxNum = serviceImportsNum;
434             }
435         }
436     }
437 
438     return "=ens" + std::to_string(maxNum + 1);
439 }
440 
441 template <class T>
AddStarExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params,AbckitDynamicExportDescriptorPayload * payload)442 size_t AddStarExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params,
443                                          AbckitDynamicExportDescriptorPayload *payload)
444 {
445     auto mPayload = GetDynModulePayload(exporting);
446     auto *moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
447 
448     ASSERT((exported->isExternal && exporting->file->externalModules.find(exported->moduleName->impl.data()) !=
449                                         exporting->file->externalModules.end()) ||
450            (!exported->isExternal && exporting->file->localModules.find(exported->moduleName->impl.data()) !=
451                                          exporting->file->localModules.end()));
452 
453     auto found = std::find(exporting->md.begin(), exporting->md.end(), exported);
454     uint16_t requestIdx;
455     if (found != exporting->md.end()) {
456         requestIdx = std::distance(exporting->md.begin(), found);
457     } else {
458         AddNewModuleRequest(exporting, exported);
459         requestIdx = exporting->md.size() - 1;
460     }
461 
462     if (params->alias == nullptr) {
463         auto starExportsNum = std::get<uint32_t>(moduleLitArr->literals_[mPayload->starExportsOffset - 1].value_);
464         auto literalRequestIdx = pandasm::LiteralArray::Literal {panda_file::LiteralTag::METHODAFFILIATE, requestIdx};
465         moduleLitArr->literals_.push_back(std::move(literalRequestIdx));
466         moduleLitArr->literals_[mPayload->starExportsOffset - 1].value_ = starExportsNum + 1;
467         return starExportsNum;
468     }
469     auto serviceName = GetServiceExportName(exporting);
470     T params1 {};
471     params1.name = params->alias;
472     params1.alias = serviceName.c_str();
473     auto localExpIdx = AddLocalExportToModuleLiteralArray(exporting, nullptr, &params1);
474     T params2 {};
475     params2.alias = serviceName.c_str();
476     auto nsImpIdx = AddNamespaceImportToModuleLiteralArray(exporting, exported, &params2);
477     payload->hasServiceImport = true;
478     payload->serviceNamespaceImportIdx = nsImpIdx;
479     return localExpIdx;
480 }
481 
482 template <class T>
AddExportToModuleLiteralArray(AbckitCoreModule * exporting,AbckitCoreModule * exported,const T * params,AbckitDynamicExportDescriptorPayload * payload,AbckitDynamicExportKind kind)483 size_t AddExportToModuleLiteralArray(AbckitCoreModule *exporting, AbckitCoreModule *exported, const T *params,
484                                      AbckitDynamicExportDescriptorPayload *payload, AbckitDynamicExportKind kind)
485 {
486     switch (kind) {
487         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
488             return AddStarExportToModuleLiteralArray(exporting, exported, params, payload);
489         }
490         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
491             return AddLocalExportToModuleLiteralArray(exporting, exported, params);
492         }
493         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
494             return AddIndirectExportToModuleLiteralArray(exporting, exported, params);
495         }
496     }
497     UNREACHABLE();
498 }
499 
DynamicModuleAddExportDynamic(AbckitCoreModule * exporting,AbckitCoreModule * exported,const AbckitArktsDynamicModuleExportCreateParams * params)500 AbckitArktsExportDescriptor *DynamicModuleAddExportDynamic(AbckitCoreModule *exporting, AbckitCoreModule *exported,
501                                                            const AbckitArktsDynamicModuleExportCreateParams *params)
502 {
503     auto ed = std::make_unique<AbckitCoreExportDescriptor>();
504     ed->exportingModule = exporting;
505     ed->exportedModule = exported;
506     auto payloadDyn = AbckitDynamicExportDescriptorPayload();
507     if (std::strcmp(params->name, "*") == 0) {
508         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
509     } else if (exported == exporting) {
510         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
511         ed->exportedModule = exporting;
512     } else {
513         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
514     }
515 
516     payloadDyn.hasServiceImport = false;
517     payloadDyn.moduleRecordIndexOff =
518         AddExportToModuleLiteralArray(exporting, exported, params, &payloadDyn, payloadDyn.kind);
519     auto payload = AbckitCoreExportDescriptorPayload();
520     payload.impl = payloadDyn;
521     ed->impl = std::make_unique<AbckitArktsExportDescriptor>();
522     ed->GetArkTSImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
523     ed->GetArkTSImpl()->payload = payload;
524     ed->GetArkTSImpl()->core = ed.get();
525     exporting->ed.push_back(std::move(ed));
526 
527     return exporting->ed[exporting->ed.size() - 1]->GetArkTSImpl();
528 }
529 
DynamicModuleAddExportDynamic(AbckitCoreModule * exporting,AbckitCoreModule * exported,const AbckitJsDynamicModuleExportCreateParams * params)530 AbckitJsExportDescriptor *DynamicModuleAddExportDynamic(AbckitCoreModule *exporting, AbckitCoreModule *exported,
531                                                         const AbckitJsDynamicModuleExportCreateParams *params)
532 {
533     auto ed = std::make_unique<AbckitCoreExportDescriptor>();
534     ed->exportingModule = exporting;
535     ed->exportedModule = exported;
536     auto payloadDyn = AbckitDynamicExportDescriptorPayload();
537     if (std::strcmp(params->name, "*") == 0) {
538         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
539     } else if (exported == exporting) {
540         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
541         ed->exportedModule = exporting;
542     } else {
543         payloadDyn.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
544     }
545 
546     payloadDyn.hasServiceImport = false;
547     payloadDyn.moduleRecordIndexOff =
548         AddExportToModuleLiteralArray(exporting, exported, params, &payloadDyn, payloadDyn.kind);
549     auto payload = AbckitCoreExportDescriptorPayload();
550     payload.impl = payloadDyn;
551     ed->impl = std::make_unique<AbckitJsExportDescriptor>();
552     ed->GetJsImpl()->payload = payload;
553     ed->GetJsImpl()->kind = AbckitImportExportDescriptorKind::UNTYPED;
554     ed->GetJsImpl()->core = ed.get();
555     exporting->ed.push_back(std::move(ed));
556     return exporting->ed[exporting->ed.size() - 1]->GetJsImpl();
557 }
558 
ModuleRemoveExportDynamic(AbckitCoreModule * m,AbckitArktsExportDescriptor * i)559 void ModuleRemoveExportDynamic(AbckitCoreModule *m, AbckitArktsExportDescriptor *i)
560 {
561     LIBABCKIT_LOG_FUNC;
562     auto found = std::find_if(m->ed.begin(), m->ed.end(),
563                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == i->core; });
564     if (found == m->ed.end()) {
565         LIBABCKIT_LOG(DEBUG) << "Can not find the export to delete\n";
566         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
567         return;
568     }
569 
570     auto idxOffset = 0;
571     auto gap = 0;
572     auto mPayload = GetDynModulePayload(m);
573     switch (i->payload.GetDynamicPayload().kind) {
574         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
575             idxOffset = mPayload->localExportsOffset;
576             gap = 2U;
577             break;
578         }
579         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
580             idxOffset = mPayload->indirectExportsOffset;
581             gap = 3U;
582             break;
583         }
584         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
585             idxOffset = mPayload->starExportsOffset;
586             gap = 1;
587         }
588     }
589     (mPayload->moduleLiteralArray->GetDynamicImpl())
590         ->literals_[idxOffset + i->payload.GetDynamicPayload().moduleRecordIndexOff * gap]
591         .tag_ = panda_file::LiteralTag::NULLVALUE;
592 
593     m->ed.erase(found);
594 }
595 
ModuleRemoveExportDynamic(AbckitCoreModule * m,AbckitJsExportDescriptor * i)596 void ModuleRemoveExportDynamic(AbckitCoreModule *m, AbckitJsExportDescriptor *i)
597 {
598     LIBABCKIT_LOG_FUNC;
599     auto found = std::find_if(m->ed.begin(), m->ed.end(),
600                               [&](std::unique_ptr<AbckitCoreExportDescriptor> const &d) { return d.get() == i->core; });
601     if (found == m->ed.end()) {
602         LIBABCKIT_LOG(DEBUG) << "Can not find the export to delete\n";
603         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
604         return;
605     }
606 
607     auto idxOffset = 0U;
608     auto gap = 0U;
609     auto mPayload = GetDynModulePayload(m);
610     switch (i->payload.GetDynamicPayload().kind) {
611         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
612             idxOffset = mPayload->localExportsOffset;
613             gap = 2U;
614             break;
615         }
616         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
617             idxOffset = mPayload->indirectExportsOffset;
618             gap = 3U;
619             break;
620         }
621         case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
622             idxOffset = mPayload->starExportsOffset;
623             gap = 1U;
624         }
625     }
626     (mPayload->moduleLiteralArray->GetDynamicImpl())
627         ->literals_[idxOffset + i->payload.GetDynamicPayload().moduleRecordIndexOff * gap]
628         .tag_ = panda_file::LiteralTag::NULLVALUE;
629 
630     m->ed.erase(found);
631 }
632 
FindOrCreateLiteralBoolDynamic(AbckitFile * file,bool value)633 AbckitLiteral *FindOrCreateLiteralBoolDynamic(AbckitFile *file, bool value)
634 {
635     LIBABCKIT_LOG_FUNC;
636     return FindOrCreateLiteralBoolDynamicImpl(file, value);
637 }
638 
FindOrCreateLiteralU8Dynamic(AbckitFile * file,uint8_t value)639 AbckitLiteral *FindOrCreateLiteralU8Dynamic(AbckitFile *file, uint8_t value)
640 {
641     LIBABCKIT_LOG_FUNC;
642     return FindOrCreateLiteralU8DynamicImpl(file, value);
643 }
644 
FindOrCreateLiteralU16Dynamic(AbckitFile * file,uint16_t value)645 AbckitLiteral *FindOrCreateLiteralU16Dynamic(AbckitFile *file, uint16_t value)
646 {
647     LIBABCKIT_LOG_FUNC;
648     return FindOrCreateLiteralU16DynamicImpl(file, value);
649 }
650 
FindOrCreateLiteralMethodAffiliateDynamic(AbckitFile * file,uint16_t value)651 AbckitLiteral *FindOrCreateLiteralMethodAffiliateDynamic(AbckitFile *file, uint16_t value)
652 {
653     LIBABCKIT_LOG_FUNC;
654     return FindOrCreateLiteralMethodAffiliateDynamicImpl(file, value);
655 }
656 
FindOrCreateLiteralU32Dynamic(AbckitFile * file,uint32_t value)657 AbckitLiteral *FindOrCreateLiteralU32Dynamic(AbckitFile *file, uint32_t value)
658 {
659     LIBABCKIT_LOG_FUNC;
660     return FindOrCreateLiteralU32DynamicImpl(file, value);
661 }
662 
FindOrCreateLiteralU64Dynamic(AbckitFile * file,uint64_t value)663 AbckitLiteral *FindOrCreateLiteralU64Dynamic(AbckitFile *file, uint64_t value)
664 {
665     LIBABCKIT_LOG_FUNC;
666     return FindOrCreateLiteralU64DynamicImpl(file, value);
667 }
668 
FindOrCreateLiteralFloatDynamic(AbckitFile * file,float value)669 AbckitLiteral *FindOrCreateLiteralFloatDynamic(AbckitFile *file, float value)
670 {
671     LIBABCKIT_LOG_FUNC;
672     return FindOrCreateLiteralFloatDynamicImpl(file, value);
673 }
674 
FindOrCreateLiteralDoubleDynamic(AbckitFile * file,double value)675 AbckitLiteral *FindOrCreateLiteralDoubleDynamic(AbckitFile *file, double value)
676 {
677     LIBABCKIT_LOG_FUNC;
678     return FindOrCreateLiteralDoubleDynamicImpl(file, value);
679 }
680 
FindOrCreateLiteralStringDynamic(AbckitFile * file,const char * value,size_t len)681 AbckitLiteral *FindOrCreateLiteralStringDynamic(AbckitFile *file, const char *value, size_t len)
682 {
683     LIBABCKIT_LOG_FUNC;
684     return FindOrCreateLiteralStringDynamicImpl(file, std::string(value, len));
685 }
686 
FindOrCreateLiteralMethodDynamic(AbckitFile * file,AbckitCoreFunction * function)687 AbckitLiteral *FindOrCreateLiteralMethodDynamic(AbckitFile *file, AbckitCoreFunction *function)
688 {
689     LIBABCKIT_LOG_FUNC;
690     return FindOrCreateLiteralMethodDynamicImpl(file, GetDynFunction(function)->name);
691 }
692 
FindOrCreateLiteralLiteralArrayDynamic(AbckitFile * file,AbckitLiteralArray * litarr)693 AbckitLiteral *FindOrCreateLiteralLiteralArrayDynamic(AbckitFile *file, AbckitLiteralArray *litarr)
694 {
695     LIBABCKIT_LOG_FUNC;
696     std::string arrName;
697     for (auto &item : file->GetDynamicProgram()->literalarray_table) {
698         if (&item.second == litarr->GetDynamicImpl()) {
699             arrName = item.first;
700             break;
701         }
702     }
703     return FindOrCreateLiteralLiteralArrayDynamicImpl(file, arrName);
704 }
705 
CreateLiteralArrayDynamic(AbckitFile * file,AbckitLiteral ** value,size_t size)706 AbckitLiteralArray *CreateLiteralArrayDynamic(AbckitFile *file, AbckitLiteral **value, size_t size)
707 {
708     LIBABCKIT_LOG_FUNC;
709     auto *prog = file->GetDynamicProgram();
710 
711     std::vector<pandasm::LiteralArray::Literal> stdLitArr;
712     for (size_t i = 0; i < size; i++) {
713         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
714         auto lit = *reinterpret_cast<pandasm::LiteralArray::Literal *>(value[i]->val.get());
715         pandasm::LiteralArray::Literal tagLit;
716         tagLit.tag_ = panda_file::LiteralTag::TAGVALUE;
717         tagLit.value_ = static_cast<uint8_t>(lit.tag_);
718         stdLitArr.emplace_back(tagLit);
719         stdLitArr.emplace_back(lit);
720     }
721 
722     // NOLINTNEXTLINE(cert-msc51-cpp)
723     uint32_t arrayOffset = 0;
724     while (prog->literalarray_table.find(std::to_string(arrayOffset)) != prog->literalarray_table.end()) {
725         arrayOffset++;
726     }
727     auto arrayName = std::to_string(arrayOffset);
728 
729     prog->literalarray_table.emplace(arrayName, pandasm::LiteralArray());
730     pandasm::LiteralArray &arrImpl = prog->literalarray_table[arrayName];
731     arrImpl.literals_ = std::move(stdLitArr);
732 
733     auto litarr = std::make_unique<AbckitLiteralArray>(file, &arrImpl);
734     return file->litarrs.emplace_back(std::move(litarr)).get();
735 }
736 
FindOrCreateValueU1Dynamic(AbckitFile * file,bool value)737 AbckitValue *FindOrCreateValueU1Dynamic(AbckitFile *file, bool value)
738 {
739     LIBABCKIT_LOG_FUNC;
740     return FindOrCreateValueU1DynamicImpl(file, value);
741 }
742 
FindOrCreateValueDoubleDynamic(AbckitFile * file,double value)743 AbckitValue *FindOrCreateValueDoubleDynamic(AbckitFile *file, double value)
744 {
745     LIBABCKIT_LOG_FUNC;
746     return FindOrCreateValueDoubleDynamicImpl(file, value);
747 }
748 
FindOrCreateValueStringDynamic(AbckitFile * file,const char * value,size_t len)749 AbckitValue *FindOrCreateValueStringDynamic(AbckitFile *file, const char *value, size_t len)
750 {
751     LIBABCKIT_LOG_FUNC;
752     return FindOrCreateValueStringDynamicImpl(file, std::string(value, len));
753 }
754 
FindOrCreateLiteralArrayValueDynamic(AbckitFile * file,AbckitValue ** value,size_t size)755 AbckitValue *FindOrCreateLiteralArrayValueDynamic(AbckitFile *file, AbckitValue **value, size_t size)
756 {
757     LIBABCKIT_LOG_FUNC;
758     std::vector<AbckitLiteral *> litArr;
759     for (size_t i = 0; i < size; i++) {
760         // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
761         switch (ValueGetTypeDynamic(value[i])->id) {
762             case ABCKIT_TYPE_ID_U1:
763                 litArr.emplace_back(FindOrCreateLiteralBoolDynamic(file, ValueGetU1Dynamic(value[i])));
764                 break;
765             case ABCKIT_TYPE_ID_F64:
766                 litArr.emplace_back(FindOrCreateLiteralDoubleDynamic(file, ValueGetDoubleDynamic(value[i])));
767                 break;
768             case ABCKIT_TYPE_ID_STRING:
769                 litArr.emplace_back(FindOrCreateLiteralStringDynamic(file, ValueGetStringDynamic(value[i])->impl.data(),
770                                                                      ValueGetStringDynamic(value[i])->impl.size()));
771                 break;
772             default:
773                 break;
774         }
775         // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
776     }
777     auto *abcArr = CreateLiteralArrayDynamic(file, litArr.data(), litArr.size());
778     auto *prog = file->GetDynamicProgram();
779     std::string arrName;
780     for (auto &item : prog->literalarray_table) {
781         if (&item.second == abcArr->GetDynamicImpl()) {
782             arrName = item.first;
783             break;
784         }
785     }
786     return FindOrCreateLiteralArrayValueDynamicImpl(file, arrName);
787 }
788 
ModuleAddAnnotationInterfaceDynamic(AbckitCoreModule * m,const AbckitArktsAnnotationInterfaceCreateParams * params)789 AbckitArktsAnnotationInterface *ModuleAddAnnotationInterfaceDynamic(
790     AbckitCoreModule *m, const AbckitArktsAnnotationInterfaceCreateParams *params)
791 {
792     std::string name = params->name;
793     auto prog = m->file->GetDynamicProgram();
794     auto progRecord = pandasm::Record {name, prog->lang};
795     progRecord.metadata->SetAccessFlags(ACC_ANNOTATION);
796     prog->record_table.emplace(name, std::move(progRecord));
797     pandasm::Record &record = prog->record_table.find(name)->second;
798     auto ai = std::make_unique<AbckitCoreAnnotationInterface>();
799     ai->owningModule = m;
800     ai->impl = std::make_unique<AbckitArktsAnnotationInterface>();
801     ai->GetArkTSImpl()->impl = &record;
802     ai->GetArkTSImpl()->core = ai.get();
803     return m->at.emplace(name, std::move(ai)).first->second->GetArkTSImpl();
804 }
805 
ClassAddAnnotationDynamic(AbckitCoreClass * klass,const AbckitArktsAnnotationCreateParams * params)806 AbckitArktsAnnotation *ClassAddAnnotationDynamic(AbckitCoreClass *klass,
807                                                  const AbckitArktsAnnotationCreateParams *params)
808 {
809     auto ai = params->ai;
810 
811     auto progFunc = klass->GetArkTSImpl()->impl.GetDynamicClass();
812     auto name = ai->GetDynamicImpl()->name;
813 
814     std::vector<pandasm::AnnotationData> vec;
815     vec.emplace_back(name);
816 
817     progFunc->metadata->AddAnnotations(vec);
818 
819     auto anno = std::make_unique<AbckitCoreAnnotation>();
820     anno->owner = klass;
821     anno->name = AnnotationInterfaceGetNameDynamic(ai->core);
822     anno->ai = ai->core;
823     anno->impl = std::make_unique<AbckitArktsAnnotation>();
824     anno->GetArkTSImpl()->core = anno.get();
825     return klass->annotations.emplace_back(std::move(anno))->GetArkTSImpl();
826 }
827 
ClassRemoveAnnotationDynamic(AbckitCoreClass * klass,AbckitCoreAnnotation * anno)828 void ClassRemoveAnnotationDynamic(AbckitCoreClass *klass, AbckitCoreAnnotation *anno)
829 {
830     auto progFunc = klass->GetArkTSImpl()->impl.GetDynamicClass();
831 
832     auto name = anno->name->impl;
833 
834     progFunc->metadata->DeleteAnnotationByName(name);
835     auto &annotations = klass->annotations;
836     auto iter = std::find_if(annotations.begin(), annotations.end(),
837                              [&name](auto &annoIt) { return name == annoIt.get()->name->impl; });
838     if (iter == annotations.end()) {
839         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation to delete\n";
840         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
841         return;
842     }
843 
844     annotations.erase(iter);
845 }
846 
FunctionAddAnnotationDynamic(AbckitCoreFunction * function,const AbckitArktsAnnotationCreateParams * params)847 AbckitArktsAnnotation *FunctionAddAnnotationDynamic(AbckitCoreFunction *function,
848                                                     const AbckitArktsAnnotationCreateParams *params)
849 {
850     auto ai = params->ai;
851 
852     auto progFunc = function->GetArkTSImpl()->GetDynamicImpl();
853     auto name = ai->GetDynamicImpl()->name;
854 
855     std::vector<pandasm::AnnotationData> vec;
856     vec.emplace_back(name);
857 
858     progFunc->metadata->AddAnnotations(vec);
859 
860     auto anno = std::make_unique<AbckitCoreAnnotation>();
861     anno->owner = function;
862     anno->name = AnnotationInterfaceGetNameDynamic(ai->core);
863     anno->ai = ai->core;
864     anno->impl = std::make_unique<AbckitArktsAnnotation>();
865     anno->GetArkTSImpl()->core = anno.get();
866     return function->annotations.emplace_back(std::move(anno))->GetArkTSImpl();
867 }
868 
FunctionRemoveAnnotationDynamic(AbckitCoreFunction * function,AbckitCoreAnnotation * anno)869 void FunctionRemoveAnnotationDynamic(AbckitCoreFunction *function, AbckitCoreAnnotation *anno)
870 {
871     auto progFunc = function->GetArkTSImpl()->GetDynamicImpl();
872 
873     auto name = anno->name->impl;
874 
875     progFunc->metadata->DeleteAnnotationByName(name);
876     auto &annotations = function->annotations;
877     auto iter = std::find_if(annotations.begin(), annotations.end(),
878                              [&name](auto &annoIt) { return name == annoIt.get()->name->impl; });
879     if (iter == annotations.end()) {
880         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation to delete\n";
881         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
882         return;
883     }
884     annotations.erase(iter);
885     anno = nullptr;
886 }
887 
AnnotationAddAnnotationElementDynamic(AbckitCoreAnnotation * anno,AbckitArktsAnnotationElementCreateParams * params)888 AbckitArktsAnnotationElement *AnnotationAddAnnotationElementDynamic(AbckitCoreAnnotation *anno,
889                                                                     AbckitArktsAnnotationElementCreateParams *params)
890 {
891     auto valuePtr = params->value;
892     auto name = params->name;
893 
894     auto progAnnoElemValue = std::make_unique<pandasm::Value>(*reinterpret_cast<pandasm::Value *>(valuePtr->val.get()));
895     pandasm::AnnotationElement progAnnoElem(params->name, std::move(progAnnoElemValue));
896 
897     auto annoElem = std::make_unique<AbckitCoreAnnotationElement>();
898     annoElem->ann = anno;
899     auto annoElemName = progAnnoElem.GetName();
900     annoElem->name = CreateStringDynamic(anno->ai->owningModule->file, annoElemName.data(), annoElemName.size());
901     annoElem->value = valuePtr;
902 
903     if (std::holds_alternative<AbckitCoreFunction *>(anno->owner)) {
904         auto *func = std::get<AbckitCoreFunction *>(anno->owner);
905         auto progOwner = func->GetArkTSImpl()->GetDynamicImpl();
906         progOwner->metadata->AddAnnotationElementByName(name, std::move(progAnnoElem));
907         annoElem->value->file = func->owningModule->file;
908     } else if (std::holds_alternative<AbckitCoreClass *>(anno->owner)) {
909         auto *klass = std::get<AbckitCoreClass *>(anno->owner);
910         auto progOwner = klass->GetArkTSImpl()->impl.GetDynamicClass();
911         progOwner->metadata->AddAnnotationElementByName(name, std::move(progAnnoElem));
912         annoElem->value->file = klass->owningModule->file;
913     }
914 
915     annoElem->impl = std::make_unique<AbckitArktsAnnotationElement>();
916     annoElem->GetArkTSImpl()->core = annoElem.get();
917 
918     return anno->elements.emplace_back(std::move(annoElem))->GetArkTSImpl();
919 }
920 
AnnotationRemoveAnnotationElementDynamic(AbckitCoreAnnotation * anno,AbckitCoreAnnotationElement * elem)921 void AnnotationRemoveAnnotationElementDynamic(AbckitCoreAnnotation *anno, AbckitCoreAnnotationElement *elem)
922 {
923     if (elem->ann != anno) {
924         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
925         return;
926     }
927 
928     auto name = elem->name;
929 
930     if (std::holds_alternative<AbckitCoreFunction *>(anno->owner)) {
931         auto progOwner = std::get<AbckitCoreFunction *>(anno->owner)->GetArkTSImpl()->GetDynamicImpl();
932         progOwner->metadata->DeleteAnnotationElementByName(anno->name->impl, name->impl);
933     } else if (std::holds_alternative<AbckitCoreClass *>(anno->owner)) {
934         auto progOwner = std::get<AbckitCoreClass *>(anno->owner)->GetArkTSImpl()->impl.GetDynamicClass();
935         progOwner->metadata->DeleteAnnotationElementByName(anno->name->impl, name->impl);
936     }
937 
938     auto &annotationElements = anno->elements;
939     auto iter = std::find_if(annotationElements.begin(), annotationElements.end(),
940                              [&name](auto &annoElemIt) { return name->impl == annoElemIt.get()->name->impl; });
941     if (iter == annotationElements.end()) {
942         LIBABCKIT_LOG(DEBUG) << "Can not find the annotation element to delete\n";
943         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
944         return;
945     }
946     annotationElements.erase(iter);
947 }
948 
TypeToName(AbckitType * type)949 std::string TypeToName(AbckitType *type)
950 {
951     if (type->id == ABCKIT_TYPE_ID_REFERENCE) {
952         auto str = ClassGetNameDynamic(type->klass);
953         if (str == nullptr) {
954             return "";
955         }
956         return std::string(str->impl);
957     }
958     switch (type->id) {
959         case ABCKIT_TYPE_ID_VOID:
960             return "void";
961         case ABCKIT_TYPE_ID_U1:
962             return "u1";
963         case ABCKIT_TYPE_ID_U8:
964             return "u8";
965         case ABCKIT_TYPE_ID_I8:
966             return "u8";
967         case ABCKIT_TYPE_ID_U16:
968             return "u16";
969         case ABCKIT_TYPE_ID_I16:
970             return "i16";
971         case ABCKIT_TYPE_ID_U32:
972             return "u32";
973         case ABCKIT_TYPE_ID_I32:
974             return "i32";
975         case ABCKIT_TYPE_ID_U64:
976             return "u64";
977         case ABCKIT_TYPE_ID_I64:
978             return "i64";
979         case ABCKIT_TYPE_ID_F32:
980             return "f32";
981         case ABCKIT_TYPE_ID_F64:
982             return "f64";
983         case ABCKIT_TYPE_ID_ANY:
984             return "any";
985         case ABCKIT_TYPE_ID_STRING:
986             return "panda.String";
987         default:
988             return "invalid";
989     }
990 }
991 
AnnotationInterfaceAddFieldDynamic(AbckitCoreAnnotationInterface * ai,const AbckitArktsAnnotationInterfaceFieldCreateParams * params)992 AbckitArktsAnnotationInterfaceField *AnnotationInterfaceAddFieldDynamic(
993     AbckitCoreAnnotationInterface *ai, const AbckitArktsAnnotationInterfaceFieldCreateParams *params)
994 {
995     auto name = params->name;
996     auto type = params->type;
997     auto value = params->defaultValue;
998 
999     auto field = std::make_unique<AbckitCoreAnnotationInterfaceField>();
1000     field->ai = ai;
1001     field->name = CreateStringDynamic(ai->owningModule->file, name, strlen(name));
1002     field->type = type;
1003     field->value = value;
1004 
1005     field->impl = std::make_unique<AbckitArktsAnnotationInterfaceField>();
1006     field->GetArkTSImpl()->core = field.get();
1007     ai->fields.emplace_back(std::move(field));
1008 
1009     auto record = ai->GetArkTSImpl()->GetDynamicImpl();
1010 
1011     auto prog = ai->owningModule->file->GetDynamicProgram();
1012     auto progField = pandasm::Field(prog->lang);
1013 
1014     progField.name = name;
1015     std::string typeName;
1016     progField.type = pandasm::Type(TypeToName(type), type->rank);
1017     progField.metadata->SetValue(*reinterpret_cast<pandasm::ScalarValue *>(value->val.get()));
1018     record->field_list.emplace_back(std::move(progField));
1019 
1020     return ai->fields.back()->GetArkTSImpl();
1021 }
1022 
AnnotationInterfaceRemoveFieldDynamic(AbckitCoreAnnotationInterface * ai,AbckitCoreAnnotationInterfaceField * field)1023 void AnnotationInterfaceRemoveFieldDynamic(AbckitCoreAnnotationInterface *ai, AbckitCoreAnnotationInterfaceField *field)
1024 {
1025     if (field->ai != ai) {
1026         statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
1027         return;
1028     }
1029 
1030     auto str = field->name;
1031     if (str == nullptr) {
1032         statuses::SetLastError(ABCKIT_STATUS_INTERNAL_ERROR);
1033         return;
1034     }
1035     auto name = str->impl;
1036 
1037     auto record = ai->GetArkTSImpl()->GetDynamicImpl();
1038 
1039     auto &fields = record->field_list;
1040 
1041     auto fieldsIter = std::find_if(fields.begin(), fields.end(), [&name](auto &field) { return name == field.name; });
1042     if (fieldsIter == fields.end()) {
1043         LIBABCKIT_LOG(DEBUG) << "Can not find the field to delete\n";
1044         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
1045         return;
1046     }
1047     fields.erase(fieldsIter);
1048 
1049     auto &aiFields = ai->fields;
1050     auto iter = std::find_if(aiFields.begin(), aiFields.end(),
1051                              [&name](auto &field) { return name == field.get()->name->impl; });
1052     if (iter == aiFields.end()) {
1053         LIBABCKIT_LOG(DEBUG) << "Can not find the field to delete\n";
1054         statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_BAD_ARGUMENT);
1055         return;
1056     }
1057     aiFields.erase(iter);
1058 }
1059 
1060 }  // namespace libabckit
1061