• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "libabckit/include/c/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