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/statuses.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/src/adapter_dynamic/metadata_inspect_dynamic.h"
19 #include "libabckit/src/adapter_dynamic/metadata_modify_dynamic.h"
20 #include "libabckit/src/adapter_dynamic/helpers_dynamic.h"
21 #include "libabckit/src/helpers_common.h"
22 #include "libabckit/src/macros.h"
23 #include "libabckit/src/metadata_inspect_impl.h"
24 #include "libabckit/src/statuses_impl.h"
25 #include "libabckit/src/wrappers/graph_wrapper/graph_wrapper.h"
26 #include "libabckit/src/wrappers/abcfile_wrapper.h"
27 #include "libabckit/src/adapter_static/ir_static.h"
28
29 #include "assembler/assembly-emitter.h"
30 #include "assembler/annotation.h"
31 #include "assembler/assembly-literals.h"
32 #include "assembler/assembly-program.h"
33
34 #include <cstddef>
35 #include <cstring>
36 #include <string>
37
38 namespace libabckit {
39
40 // CC-OFFNXT(WordsTool.95) sensitive word conflict
41 // NOLINTNEXTLINE(google-build-using-namespace)
42 using namespace panda;
43
44 // ========================================
45 // Module
46 // ========================================
47
ModuleEnumerateAnonymousFunctionsDynamic(AbckitCoreModule * m,void * data,bool (* cb)(AbckitCoreFunction * function,void * data))48 bool ModuleEnumerateAnonymousFunctionsDynamic(AbckitCoreModule *m, void *data,
49 bool (*cb)(AbckitCoreFunction *function, void *data))
50 {
51 LIBABCKIT_LOG_FUNC;
52 LIBABCKIT_BAD_ARGUMENT(m, false)
53 LIBABCKIT_BAD_ARGUMENT(cb, false)
54
55 for (auto &function : m->functions) {
56 if (!FunctionIsAnonymousDynamic(function.get())) {
57 continue;
58 }
59 if (!cb(function.get(), data)) {
60 return false;
61 }
62 }
63 return true;
64 }
65
66 // ========================================
67 // Namespace
68 // ========================================
69
NamespaceGetNameDynamic(AbckitCoreNamespace * n)70 AbckitString *NamespaceGetNameDynamic(AbckitCoreNamespace *n)
71 {
72 LIBABCKIT_LOG_FUNC;
73 ASSERT(n->owningModule->target == ABCKIT_TARGET_ARK_TS_V1);
74 auto func = GetDynFunction(n->GetArkTSImpl()->f.get());
75 auto name = func->name;
76 size_t sharpPos = name.rfind('#');
77 ASSERT(sharpPos != std::string::npos);
78 auto subname = name.substr(sharpPos + 1);
79 return CreateStringDynamic(n->owningModule->file, subname.data(), subname.size());
80 }
81
82 // ========================================
83 // Class
84 // ========================================
85
ClassGetNameDynamic(AbckitCoreClass * klass)86 AbckitString *ClassGetNameDynamic(AbckitCoreClass *klass)
87 {
88 LIBABCKIT_LOG_FUNC;
89
90 auto func = GetDynFunction(klass);
91 auto mPayload = GetDynModulePayload(klass->owningModule);
92
93 auto *scopesLitArr = mPayload->scopeNamesLiteralArray;
94 auto name = GetClassNameFromCtor(func->name, scopesLitArr);
95
96 return CreateStringDynamic(klass->owningModule->file, name.data(), name.size());
97 }
98
99 // ========================================
100 // Function
101 // ========================================
102
FunctionGetNameDynamic(AbckitCoreFunction * function)103 AbckitString *FunctionGetNameDynamic(AbckitCoreFunction *function)
104 {
105 LIBABCKIT_LOG_FUNC;
106 auto *functionImpl = GetDynFunction(function);
107 auto name = functionImpl->name;
108
109 size_t sharpPos = name.rfind('#');
110 if (!function->isAnonymous) {
111 if (sharpPos != std::string::npos) {
112 name = name.substr(sharpPos + 1);
113 } else {
114 name = name.substr(name.rfind('.') + 1);
115 ASSERT(name == "func_main_0");
116 }
117 }
118
119 return CreateStringDynamic(function->owningModule->file, name.data(), name.size());
120 }
121
CreateGraphFromFunctionDynamic(AbckitCoreFunction * function)122 AbckitGraph *CreateGraphFromFunctionDynamic(AbckitCoreFunction *function)
123 {
124 LIBABCKIT_LOG_FUNC;
125
126 auto *func = GetDynFunction(function);
127 LIBABCKIT_LOG(DEBUG) << func->name << '\n';
128 LIBABCKIT_LOG_DUMP(func->DebugDump(), DEBUG);
129
130 auto *file = function->owningModule->file;
131 auto program = function->owningModule->file->GetDynamicProgram();
132
133 auto maps = std::make_unique<pandasm::AsmEmitter::PandaFileToPandaAsmMaps>();
134 auto pf = EmitDynamicProgram(file, program, maps.get(), true);
135 if (pf == nullptr) {
136 return nullptr;
137 }
138
139 uint32_t functionOffset = 0;
140 for (auto &[id, s] : maps->methods) {
141 if (s == func->name) {
142 functionOffset = id;
143 }
144 }
145 if (functionOffset == 0) {
146 LIBABCKIT_LOG(DEBUG) << "functionOffset == 0\n";
147 statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_INTERNAL_ERROR);
148 return nullptr;
149 }
150
151 auto *irInterface =
152 new AbckitIrInterface(maps->methods, maps->fields, maps->classes, maps->strings, maps->literalarrays);
153
154 auto *wpf = new FileWrapper(reinterpret_cast<const void *>(pf));
155 auto graph = GraphWrapper::BuildGraphDynamic(wpf, irInterface, file, functionOffset);
156 if (statuses::GetLastError() != AbckitStatus::ABCKIT_STATUS_NO_ERROR) {
157 return nullptr;
158 }
159 LIBABCKIT_LOG_DUMP(GdumpStatic(graph, STDERR_FILENO), DEBUG);
160
161 ASSERT(graph->file == file);
162 graph->function = function;
163
164 return graph;
165 }
166
FunctionIsStaticDynamic(AbckitCoreFunction * function)167 bool FunctionIsStaticDynamic(AbckitCoreFunction *function)
168 {
169 LIBABCKIT_LOG_FUNC;
170 auto *func = GetDynFunction(function);
171 return IsStatic(func->name);
172 }
173
FunctionIsCtorDynamic(AbckitCoreFunction * function)174 bool FunctionIsCtorDynamic(AbckitCoreFunction *function)
175 {
176 LIBABCKIT_LOG_FUNC;
177 auto *func = GetDynFunction(function);
178 return IsCtor(func->name);
179 }
180
FunctionIsAnonymousDynamic(AbckitCoreFunction * function)181 bool FunctionIsAnonymousDynamic(AbckitCoreFunction *function)
182 {
183 LIBABCKIT_LOG_FUNC;
184 return function->isAnonymous;
185 }
186
FunctionIsNativeDynamic(AbckitCoreFunction * function)187 bool FunctionIsNativeDynamic(AbckitCoreFunction *function)
188 {
189 LIBABCKIT_LOG_FUNC;
190 auto *func = GetDynFunction(function);
191 return (func->metadata->GetAccessFlags() & ACC_NATIVE) != 0x0;
192 }
193
194 // ========================================
195 // Annotation
196 // ========================================
197
AnnotationInterfaceGetNameDynamic(AbckitCoreAnnotationInterface * ai)198 AbckitString *AnnotationInterfaceGetNameDynamic(AbckitCoreAnnotationInterface *ai)
199 {
200 LIBABCKIT_LOG_FUNC;
201 auto name = pandasm::GetItemName(ai->GetArkTSImpl()->GetDynamicImpl()->name);
202 return CreateStringDynamic(ai->owningModule->file, name.data(), name.size());
203 }
204
205 // ========================================
206 // ImportDescriptor
207 // ========================================
208
ImportDescriptorGetNameDynamic(AbckitCoreImportDescriptor * i)209 AbckitString *ImportDescriptorGetNameDynamic(AbckitCoreImportDescriptor *i)
210 {
211 std::string name = [i]() {
212 auto mPayload = GetDynModulePayload(i->importingModule);
213 auto idPayload = GetDynImportDescriptorPayload(i);
214 const auto *moduleLitArr = mPayload->moduleLiteralArray;
215 auto sectionOffset =
216 idPayload->isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
217 if (!idPayload->isRegularImport) {
218 return std::string("*");
219 }
220 auto importNameOffset = sectionOffset + idPayload->moduleRecordIndexOff * 3 + 1;
221 return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[importNameOffset].value_);
222 }();
223 return CreateStringDynamic(i->importingModule->file, name.data(), name.size());
224 }
225
ImportDescriptorGetAliasDynamic(AbckitCoreImportDescriptor * i)226 AbckitString *ImportDescriptorGetAliasDynamic(AbckitCoreImportDescriptor *i)
227 {
228 std::string name = [i]() {
229 auto mPayload = GetDynModulePayload(i->importingModule);
230 auto idPayload = GetDynImportDescriptorPayload(i);
231 const auto *moduleLitArr = mPayload->moduleLiteralArray;
232 auto sectionOffset =
233 idPayload->isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
234 auto gap = idPayload->isRegularImport ? 3 : 2;
235 auto importNameOffset = sectionOffset + idPayload->moduleRecordIndexOff * gap;
236 return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[importNameOffset].value_);
237 }();
238 return CreateStringDynamic(i->importingModule->file, name.data(), name.size());
239 }
240
241 // ========================================
242 // ExportDescriptor
243 // ========================================
244
ExportDescriptorGetNameDynamic(AbckitCoreExportDescriptor * i)245 AbckitString *ExportDescriptorGetNameDynamic(AbckitCoreExportDescriptor *i)
246 {
247 std::string name = [i]() {
248 auto mPayload = GetDynModulePayload(i->exportingModule);
249 auto edPayload = GetDynExportDescriptorPayload(i);
250 const auto *moduleLitArr = mPayload->moduleLiteralArray;
251 size_t exportNameOffset;
252 switch (edPayload->kind) {
253 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
254 exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2 + 1;
255 break;
256 }
257 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
258 exportNameOffset = mPayload->indirectExportsOffset + edPayload->moduleRecordIndexOff * 3 + 1;
259 break;
260 }
261 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
262 std::string res = "*";
263 return res;
264 }
265 }
266 return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
267 }();
268 return CreateStringDynamic(i->exportingModule->file, name.data(), name.size());
269 }
270
ExportDescriptorGetAliasDynamic(AbckitCoreExportDescriptor * i)271 AbckitString *ExportDescriptorGetAliasDynamic(AbckitCoreExportDescriptor *i)
272 {
273 std::string name = [i]() {
274 auto mPayload = GetDynModulePayload(i->exportingModule);
275 auto edPayload = GetDynExportDescriptorPayload(i);
276 const auto *moduleLitArr = mPayload->moduleLiteralArray;
277 size_t exportNameOffset;
278 switch (edPayload->kind) {
279 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
280 exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2;
281 break;
282 }
283 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
284 exportNameOffset = mPayload->indirectExportsOffset + edPayload->moduleRecordIndexOff * 3;
285 break;
286 }
287 case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
288 if (!edPayload->hasServiceImport) {
289 std::string res;
290 return res;
291 }
292 exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2 + 1;
293 }
294 }
295 return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
296 }();
297 return CreateStringDynamic(i->exportingModule->file, name.data(), name.size());
298 }
299
300 // ========================================
301 // Literal
302 // ========================================
303
LiteralGetBoolDynamic(AbckitLiteral * lit)304 bool LiteralGetBoolDynamic(AbckitLiteral *lit)
305 {
306 LIBABCKIT_LOG_FUNC;
307 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
308 if (!literal->IsBoolValue()) {
309 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
310 return false;
311 }
312 return std::get<bool>(literal->value_);
313 }
314
LiteralGetU8Dynamic(AbckitLiteral * lit)315 uint8_t LiteralGetU8Dynamic(AbckitLiteral *lit)
316 {
317 LIBABCKIT_LOG_FUNC;
318 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
319 if (!literal->IsByteValue()) {
320 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
321 return 0;
322 }
323 return std::get<uint8_t>(literal->value_);
324 }
325
LiteralGetU16Dynamic(AbckitLiteral * lit)326 uint16_t LiteralGetU16Dynamic(AbckitLiteral *lit)
327 {
328 LIBABCKIT_LOG_FUNC;
329 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
330 if (!literal->IsShortValue()) {
331 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
332 return 0;
333 }
334 return std::get<uint16_t>(literal->value_);
335 }
336
LiteralGetMethodAffiliateDynamic(AbckitLiteral * lit)337 uint16_t LiteralGetMethodAffiliateDynamic(AbckitLiteral *lit)
338 {
339 LIBABCKIT_LOG_FUNC;
340 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
341 if (literal->tag_ != panda_file::LiteralTag::METHODAFFILIATE) {
342 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
343 return 0;
344 }
345 return std::get<uint16_t>(literal->value_);
346 }
347
LiteralGetU32Dynamic(AbckitLiteral * lit)348 uint32_t LiteralGetU32Dynamic(AbckitLiteral *lit)
349 {
350 LIBABCKIT_LOG_FUNC;
351 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
352 if (!literal->IsIntegerValue()) {
353 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
354 return 0;
355 }
356 return std::get<uint32_t>(literal->value_);
357 }
358
LiteralGetU64Dynamic(AbckitLiteral * lit)359 uint64_t LiteralGetU64Dynamic(AbckitLiteral *lit)
360 {
361 LIBABCKIT_LOG_FUNC;
362 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
363 if (!literal->IsLongValue()) {
364 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
365 return 0;
366 }
367 return std::get<uint64_t>(literal->value_);
368 }
369
LiteralGetFloatDynamic(AbckitLiteral * lit)370 float LiteralGetFloatDynamic(AbckitLiteral *lit)
371 {
372 LIBABCKIT_LOG_FUNC;
373 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
374 if (!literal->IsFloatValue()) {
375 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
376 return 0;
377 }
378 return std::get<float>(literal->value_);
379 }
380
LiteralGetDoubleDynamic(AbckitLiteral * lit)381 double LiteralGetDoubleDynamic(AbckitLiteral *lit)
382 {
383 LIBABCKIT_LOG_FUNC;
384 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
385 if (!literal->IsDoubleValue()) {
386 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
387 return 0;
388 }
389 return std::get<double>(literal->value_);
390 }
391
LiteralGetLiteralArrayDynamic(AbckitLiteral * lit)392 AbckitLiteralArray *LiteralGetLiteralArrayDynamic(AbckitLiteral *lit)
393 {
394 LIBABCKIT_LOG_FUNC;
395 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
396 if (literal->tag_ != panda::panda_file::LiteralTag::LITERALARRAY) {
397 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
398 return nullptr;
399 }
400
401 auto &litarrs = lit->file->GetDynamicProgram()->literalarray_table;
402 auto &arrName = std::get<std::string>(literal->value_);
403
404 // Search through already created abckit litarrs
405 for (auto &item : lit->file->litarrs) {
406 if (item->GetDynamicImpl() == &litarrs[arrName]) {
407 return item.get();
408 }
409 }
410
411 // Create new abckit litarrs
412 auto litarr = std::make_unique<AbckitLiteralArray>(lit->file, &litarrs[arrName]);
413 lit->file->litarrs.emplace_back(std::move(litarr));
414 return lit->file->litarrs[lit->file->litarrs.size() - 1].get();
415 }
416
LiteralGetStringDynamic(AbckitLiteral * lit)417 AbckitString *LiteralGetStringDynamic(AbckitLiteral *lit)
418 {
419 LIBABCKIT_LOG_FUNC;
420 auto s = std::make_unique<AbckitString>();
421 auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
422 if (!literal->IsStringValue()) {
423 statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
424 return nullptr;
425 }
426
427 auto &strings = lit->file->strings;
428
429 auto &val = std::get<std::string>(literal->value_);
430 if (strings.find(val) != strings.end()) {
431 return strings[val].get();
432 }
433 s->impl = val;
434 strings.insert({val, std::move(s)});
435
436 return strings[val].get();
437 }
438
LiteralGetTagDynamic(AbckitLiteral * lit)439 AbckitLiteralTag LiteralGetTagDynamic(AbckitLiteral *lit)
440 {
441 LIBABCKIT_LOG_FUNC;
442 auto *litImpl = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
443 switch (litImpl->tag_) {
444 case panda_file::LiteralTag::ARRAY_U1:
445 case panda_file::LiteralTag::BOOL:
446 return ABCKIT_LITERAL_TAG_BOOL;
447 case panda_file::LiteralTag::ARRAY_U8:
448 case panda_file::LiteralTag::ARRAY_I8:
449 return ABCKIT_LITERAL_TAG_BYTE;
450 case panda_file::LiteralTag::ARRAY_U16:
451 case panda_file::LiteralTag::ARRAY_I16:
452 return ABCKIT_LITERAL_TAG_SHORT;
453 case panda_file::LiteralTag::ARRAY_U32:
454 case panda_file::LiteralTag::ARRAY_I32:
455 case panda_file::LiteralTag::INTEGER:
456 return ABCKIT_LITERAL_TAG_INTEGER;
457 case panda_file::LiteralTag::ARRAY_U64:
458 case panda_file::LiteralTag::ARRAY_I64:
459 return ABCKIT_LITERAL_TAG_LONG;
460 case panda_file::LiteralTag::ARRAY_F32:
461 case panda_file::LiteralTag::FLOAT:
462 return ABCKIT_LITERAL_TAG_FLOAT;
463 case panda_file::LiteralTag::ARRAY_F64:
464 case panda_file::LiteralTag::DOUBLE:
465 return ABCKIT_LITERAL_TAG_DOUBLE;
466 case panda_file::LiteralTag::ARRAY_STRING:
467 case panda_file::LiteralTag::STRING:
468 return ABCKIT_LITERAL_TAG_STRING;
469 case panda_file::LiteralTag::NULLVALUE:
470 return ABCKIT_LITERAL_TAG_NULLVALUE;
471 case panda_file::LiteralTag::TAGVALUE:
472 return ABCKIT_LITERAL_TAG_TAGVALUE;
473 case panda_file::LiteralTag::METHOD:
474 case panda_file::LiteralTag::GETTER:
475 case panda_file::LiteralTag::SETTER:
476 case panda_file::LiteralTag::GENERATORMETHOD:
477 case panda_file::LiteralTag::ASYNCGENERATORMETHOD:
478 return ABCKIT_LITERAL_TAG_METHOD;
479 case panda_file::LiteralTag::METHODAFFILIATE:
480 return ABCKIT_LITERAL_TAG_METHODAFFILIATE;
481 case panda_file::LiteralTag::LITERALARRAY:
482 return ABCKIT_LITERAL_TAG_LITERALARRAY;
483 default:
484 return ABCKIT_LITERAL_TAG_INVALID;
485 }
486 }
487
LiteralArrayEnumerateElementsDynamic(AbckitLiteralArray * litArr,void * data,bool (* cb)(AbckitFile * file,AbckitLiteral * lit,void * data))488 bool LiteralArrayEnumerateElementsDynamic(AbckitLiteralArray *litArr, void *data,
489 bool (*cb)(AbckitFile *file, AbckitLiteral *lit, void *data))
490 {
491 LIBABCKIT_LOG_FUNC;
492 auto *arrImpl = litArr->GetDynamicImpl();
493
494 size_t size = arrImpl->literals_.size();
495 if (size % 2U != 0) {
496 statuses::SetLastError(ABCKIT_STATUS_INTERNAL_ERROR);
497 return false;
498 }
499
500 for (size_t idx = 1; idx < size; idx += 2U) {
501 auto litImpl = arrImpl->literals_[idx];
502 if (!cb(litArr->file, FindOrCreateLiteralDynamic(litArr->file, litImpl), data)) {
503 return false;
504 }
505 }
506 return true;
507 }
508
509 // ========================================
510 // Value
511 // ========================================
512
ValueGetTypeDynamic(AbckitValue * value)513 AbckitType *ValueGetTypeDynamic(AbckitValue *value)
514 {
515 LIBABCKIT_LOG_FUNC;
516 auto *pVal = reinterpret_cast<pandasm::ScalarValue *>(value->val.get());
517 AbckitTypeId id;
518 switch (pVal->GetType()) {
519 case pandasm::Value::Type::U1:
520 id = ABCKIT_TYPE_ID_U1;
521 break;
522 case pandasm::Value::Type::U8:
523 id = ABCKIT_TYPE_ID_U8;
524 break;
525 case pandasm::Value::Type::U16:
526 id = ABCKIT_TYPE_ID_U16;
527 break;
528 case pandasm::Value::Type::U32:
529 id = ABCKIT_TYPE_ID_U32;
530 break;
531 case pandasm::Value::Type::U64:
532 id = ABCKIT_TYPE_ID_U64;
533 break;
534 case pandasm::Value::Type::F64:
535 id = ABCKIT_TYPE_ID_F64;
536 break;
537 case pandasm::Value::Type::STRING:
538 id = ABCKIT_TYPE_ID_STRING;
539 break;
540 case pandasm::Value::Type::LITERALARRAY:
541 id = ABCKIT_TYPE_ID_LITERALARRAY;
542 break;
543 default:
544 LIBABCKIT_UNIMPLEMENTED;
545 }
546 // NOTE implement logic for classes
547 return GetOrCreateType(value->file, id, 0, nullptr);
548 }
549
ValueGetU1Dynamic(AbckitValue * value)550 bool ValueGetU1Dynamic(AbckitValue *value)
551 {
552 LIBABCKIT_LOG_FUNC;
553 if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_U1) {
554 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
555 return false;
556 }
557
558 auto *pVal = reinterpret_cast<pandasm::ScalarValue *>(value->val.get());
559 return pVal->GetValue<bool>();
560 }
561
ValueGetDoubleDynamic(AbckitValue * value)562 double ValueGetDoubleDynamic(AbckitValue *value)
563 {
564 LIBABCKIT_LOG_FUNC;
565 if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_F64) {
566 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
567 return 0.0;
568 }
569
570 auto *pVal = reinterpret_cast<pandasm::ScalarValue *>(value->val.get());
571 return pVal->GetValue<double>();
572 }
573
ValueGetStringDynamic(AbckitValue * value)574 AbckitString *ValueGetStringDynamic(AbckitValue *value)
575 {
576 LIBABCKIT_LOG_FUNC;
577 if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_STRING) {
578 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
579 return nullptr;
580 }
581
582 auto *pVal = reinterpret_cast<pandasm::ScalarValue *>(value->val.get());
583 auto valImpl = pVal->GetValue<std::string>();
584 return CreateStringDynamic(value->file, valImpl.data(), valImpl.size());
585 }
586
ArrayValueGetLiteralArrayDynamic(AbckitValue * value)587 AbckitLiteralArray *ArrayValueGetLiteralArrayDynamic(AbckitValue *value)
588 {
589 LIBABCKIT_LOG_FUNC;
590 if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_LITERALARRAY) {
591 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
592 return nullptr;
593 }
594
595 auto *pVal = reinterpret_cast<pandasm::ScalarValue *>(value->val.get());
596 auto arrName = pVal->GetValue<std::string>();
597 auto &litarrs = value->file->GetDynamicProgram()->literalarray_table;
598
599 // Search through already created abckit litarrs
600 for (auto &item : value->file->litarrs) {
601 if (item->GetDynamicImpl() == &litarrs[arrName]) {
602 return item.get();
603 }
604 }
605
606 // Create new abckit litarr
607 auto litarr = std::make_unique<AbckitLiteralArray>(value->file, &(litarrs[arrName]));
608 return value->file->litarrs.emplace_back(std::move(litarr)).get();
609 }
610
611 } // namespace libabckit
612