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, ¶ms1);
474 T params2 {};
475 params2.alias = serviceName.c_str();
476 auto nsImpIdx = AddNamespaceImportToModuleLiteralArray(exporting, exported, ¶ms2);
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