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