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, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 * either express or implied. See the License for the specific language governing permissions and limitations under the
12 * License.
13 */
14
15 #include <cassert>
16 #include <cstdint>
17 #include "libabckit/include/c/abckit.h"
18 #include "libabckit/include/c/metadata_core.h"
19
20 #include "libabckit/include/c/statuses.h"
21 #include "libabckit/src/macros.h"
22 #include "scoped_timer.h"
23
24 #include "libabckit/src/metadata_inspect_impl.h"
25 #include "libabckit/src/ir_impl.h"
26 #include "libabckit/src/adapter_dynamic/metadata_modify_dynamic.h"
27 #include "libabckit/src/adapter_static/metadata_modify_static.h"
28 #include "libabckit/src/helpers_common.h"
29 #include "libabckit/src/statuses_impl.h"
30
31 namespace libabckit {
32
33 // ========================================
34 // File
35 // ========================================
36
37 // ========================================
38 // Module
39 // ========================================
40
41 // ========================================
42 // Class
43 // ========================================
44
45 // ========================================
46 // AnnotationInterface
47 // ========================================
48
49 // ========================================
50 // Function
51 // ========================================
52
FunctionSetGraph(AbckitCoreFunction * function,AbckitGraph * graph)53 extern "C" void FunctionSetGraph(AbckitCoreFunction *function, AbckitGraph *graph)
54 {
55 LIBABCKIT_CLEAR_LAST_ERROR;
56 LIBABCKIT_IMPLEMENTED;
57 LIBABCKIT_TIME_EXEC;
58
59 LIBABCKIT_BAD_ARGUMENT_VOID(function)
60 LIBABCKIT_BAD_ARGUMENT_VOID(graph)
61
62 LIBABCKIT_WRONG_CTX_VOID(function->owningModule->file, graph->file);
63
64 if (IsDynamic(function->owningModule->target)) {
65 FunctionSetGraphDynamic(function, graph);
66 } else {
67 FunctionSetGraphStatic(function, graph);
68 }
69 }
70
71 // ========================================
72 // Annotation
73 // ========================================
74
75 // ========================================
76 // Type
77 // ========================================
78
CreateType(AbckitFile * file,AbckitTypeId id)79 extern "C" AbckitType *CreateType(AbckitFile *file, AbckitTypeId id)
80 {
81 LIBABCKIT_CLEAR_LAST_ERROR;
82 LIBABCKIT_IMPLEMENTED;
83 LIBABCKIT_TIME_EXEC;
84
85 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
86 if (id == ABCKIT_TYPE_ID_INVALID) {
87 statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
88 return nullptr;
89 }
90 return GetOrCreateType(file, id, 0, nullptr);
91 }
92
CreateReferenceType(AbckitFile * file,AbckitCoreClass * klass)93 extern "C" AbckitType *CreateReferenceType(AbckitFile *file, AbckitCoreClass *klass)
94 {
95 LIBABCKIT_CLEAR_LAST_ERROR;
96 LIBABCKIT_IMPLEMENTED;
97 LIBABCKIT_TIME_EXEC;
98
99 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
100 LIBABCKIT_BAD_ARGUMENT(klass, nullptr);
101 return GetOrCreateType(file, AbckitTypeId::ABCKIT_TYPE_ID_REFERENCE, 0, klass);
102 }
103
104 // ========================================
105 // Value
106 // ========================================
107
CreateValueU1(AbckitFile * file,bool value)108 extern "C" AbckitValue *CreateValueU1(AbckitFile *file, bool value)
109 {
110 LIBABCKIT_CLEAR_LAST_ERROR;
111 LIBABCKIT_IMPLEMENTED;
112 LIBABCKIT_TIME_EXEC;
113
114 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
115 switch (file->frontend) {
116 case Mode::DYNAMIC:
117 return FindOrCreateValueU1Dynamic(file, value);
118 case Mode::STATIC:
119 return FindOrCreateValueU1Static(file, value);
120 default:
121 LIBABCKIT_UNREACHABLE;
122 }
123 }
124
CreateValueDouble(AbckitFile * file,double value)125 extern "C" AbckitValue *CreateValueDouble(AbckitFile *file, double value)
126 {
127 LIBABCKIT_CLEAR_LAST_ERROR;
128 LIBABCKIT_IMPLEMENTED;
129 LIBABCKIT_TIME_EXEC;
130
131 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
132 switch (file->frontend) {
133 case Mode::DYNAMIC:
134 return FindOrCreateValueDoubleDynamic(file, value);
135 case Mode::STATIC:
136 return FindOrCreateValueDoubleStatic(file, value);
137 default:
138 LIBABCKIT_UNREACHABLE;
139 }
140 }
141
CreateValueString(AbckitFile * file,const char * value,size_t len)142 extern "C" AbckitValue *CreateValueString(AbckitFile *file, const char *value, size_t len)
143 {
144 LIBABCKIT_CLEAR_LAST_ERROR;
145 LIBABCKIT_IMPLEMENTED;
146 LIBABCKIT_TIME_EXEC;
147
148 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
149 LIBABCKIT_BAD_ARGUMENT(value, nullptr);
150 LIBABCKIT_ZERO_ARGUMENT(len, nullptr);
151 switch (file->frontend) {
152 case Mode::DYNAMIC:
153 return FindOrCreateValueStringDynamic(file, value, len);
154 case Mode::STATIC:
155 return FindOrCreateValueStringStatic(file, value, len);
156 default:
157 LIBABCKIT_UNREACHABLE;
158 }
159 }
160
CreateLiteralArrayValue(AbckitFile * file,AbckitValue ** value,size_t size)161 extern "C" AbckitValue *CreateLiteralArrayValue(AbckitFile *file, AbckitValue **value, size_t size)
162 {
163 LIBABCKIT_CLEAR_LAST_ERROR;
164 LIBABCKIT_IMPLEMENTED;
165 LIBABCKIT_TIME_EXEC;
166
167 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
168 LIBABCKIT_BAD_ARGUMENT(value, nullptr);
169 switch (file->frontend) {
170 case Mode::DYNAMIC:
171 return FindOrCreateLiteralArrayValueDynamic(file, value, size);
172 case Mode::STATIC:
173 statuses::SetLastError(ABCKIT_STATUS_UNSUPPORTED);
174 return nullptr;
175 default:
176 LIBABCKIT_UNREACHABLE;
177 }
178 }
179
180 // ========================================
181 // String
182 // ========================================
183
CreateString(AbckitFile * file,const char * value,size_t len)184 extern "C" AbckitString *CreateString(AbckitFile *file, const char *value, size_t len)
185 {
186 LIBABCKIT_CLEAR_LAST_ERROR;
187 LIBABCKIT_IMPLEMENTED;
188 LIBABCKIT_TIME_EXEC;
189
190 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
191 LIBABCKIT_BAD_ARGUMENT(value, nullptr);
192 LIBABCKIT_ZERO_ARGUMENT(len, nullptr);
193 switch (file->frontend) {
194 case Mode::DYNAMIC:
195 return CreateStringDynamic(file, value, len);
196 case Mode::STATIC:
197 return CreateStringStatic(file, value, len);
198 default:
199 LIBABCKIT_UNREACHABLE;
200 }
201 }
202
203 // ========================================
204 // LiteralArray
205 // ========================================
206
CreateLiteralArray(AbckitFile * file,AbckitLiteral ** value,size_t size)207 extern "C" AbckitLiteralArray *CreateLiteralArray(AbckitFile *file, AbckitLiteral **value, size_t size)
208 {
209 LIBABCKIT_CLEAR_LAST_ERROR;
210 LIBABCKIT_IMPLEMENTED;
211 LIBABCKIT_TIME_EXEC;
212
213 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
214 LIBABCKIT_BAD_ARGUMENT(value, nullptr);
215 switch (file->frontend) {
216 case Mode::DYNAMIC:
217 return CreateLiteralArrayDynamic(file, value, size);
218 case Mode::STATIC:
219 return CreateLiteralArrayStatic(file, value, size);
220 default:
221 LIBABCKIT_UNREACHABLE;
222 }
223 }
224
CreateLiteralBool(AbckitFile * file,bool value)225 extern "C" AbckitLiteral *CreateLiteralBool(AbckitFile *file, bool value)
226 {
227 LIBABCKIT_CLEAR_LAST_ERROR;
228 LIBABCKIT_IMPLEMENTED;
229 LIBABCKIT_TIME_EXEC;
230
231 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
232 switch (file->frontend) {
233 case Mode::DYNAMIC:
234 return FindOrCreateLiteralBoolDynamic(file, value);
235 case Mode::STATIC:
236 return FindOrCreateLiteralBoolStatic(file, value);
237 default:
238 LIBABCKIT_UNREACHABLE;
239 }
240 }
241
CreateLiteralU8(AbckitFile * file,uint8_t value)242 extern "C" AbckitLiteral *CreateLiteralU8(AbckitFile *file, uint8_t value)
243 {
244 LIBABCKIT_CLEAR_LAST_ERROR;
245 LIBABCKIT_IMPLEMENTED;
246 LIBABCKIT_TIME_EXEC;
247
248 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
249 switch (file->frontend) {
250 case Mode::DYNAMIC:
251 return FindOrCreateLiteralU8Dynamic(file, value);
252 case Mode::STATIC:
253 return FindOrCreateLiteralU8Static(file, value);
254 default:
255 LIBABCKIT_UNREACHABLE;
256 }
257 }
258
CreateLiteralU16(AbckitFile * file,uint16_t value)259 extern "C" AbckitLiteral *CreateLiteralU16(AbckitFile *file, uint16_t value)
260 {
261 LIBABCKIT_CLEAR_LAST_ERROR;
262 LIBABCKIT_IMPLEMENTED;
263 LIBABCKIT_TIME_EXEC;
264
265 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
266 switch (file->frontend) {
267 case Mode::DYNAMIC:
268 return FindOrCreateLiteralU16Dynamic(file, value);
269 case Mode::STATIC:
270 return FindOrCreateLiteralU16Static(file, value);
271 default:
272 LIBABCKIT_UNREACHABLE;
273 }
274 }
275
CreateLiteralMethodAffiliate(AbckitFile * file,uint16_t value)276 extern "C" AbckitLiteral *CreateLiteralMethodAffiliate(AbckitFile *file, uint16_t value)
277 {
278 LIBABCKIT_CLEAR_LAST_ERROR;
279 LIBABCKIT_IMPLEMENTED;
280 LIBABCKIT_TIME_EXEC;
281
282 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
283 switch (file->frontend) {
284 case Mode::DYNAMIC:
285 return FindOrCreateLiteralMethodAffiliateDynamic(file, value);
286 case Mode::STATIC:
287 return FindOrCreateLiteralMethodAffiliateStatic(file, value);
288 default:
289 LIBABCKIT_UNREACHABLE;
290 }
291 }
CreateLiteralU32(AbckitFile * file,uint32_t value)292 extern "C" AbckitLiteral *CreateLiteralU32(AbckitFile *file, uint32_t value)
293 {
294 LIBABCKIT_CLEAR_LAST_ERROR;
295 LIBABCKIT_IMPLEMENTED;
296 LIBABCKIT_TIME_EXEC;
297
298 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
299 switch (file->frontend) {
300 case Mode::DYNAMIC:
301 return FindOrCreateLiteralU32Dynamic(file, value);
302 case Mode::STATIC:
303 return FindOrCreateLiteralU32Static(file, value);
304 default:
305 LIBABCKIT_UNREACHABLE;
306 }
307 }
308
CreateLiteralU64(AbckitFile * file,uint64_t value)309 extern "C" AbckitLiteral *CreateLiteralU64(AbckitFile *file, uint64_t value)
310 {
311 LIBABCKIT_CLEAR_LAST_ERROR;
312 LIBABCKIT_IMPLEMENTED;
313 LIBABCKIT_TIME_EXEC;
314
315 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
316 switch (file->frontend) {
317 case Mode::DYNAMIC:
318 return FindOrCreateLiteralU64Dynamic(file, value);
319 case Mode::STATIC:
320 return FindOrCreateLiteralU64Static(file, value);
321 default:
322 LIBABCKIT_UNREACHABLE;
323 }
324 }
325
CreateLiteralFloat(AbckitFile * file,float value)326 extern "C" AbckitLiteral *CreateLiteralFloat(AbckitFile *file, float value)
327 {
328 LIBABCKIT_CLEAR_LAST_ERROR;
329 LIBABCKIT_IMPLEMENTED;
330 LIBABCKIT_TIME_EXEC;
331
332 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
333 switch (file->frontend) {
334 case Mode::DYNAMIC:
335 return FindOrCreateLiteralFloatDynamic(file, value);
336 case Mode::STATIC:
337 return FindOrCreateLiteralFloatStatic(file, value);
338 default:
339 LIBABCKIT_UNREACHABLE;
340 }
341 }
342
CreateLiteralDouble(AbckitFile * file,double value)343 extern "C" AbckitLiteral *CreateLiteralDouble(AbckitFile *file, double value)
344 {
345 LIBABCKIT_CLEAR_LAST_ERROR;
346 LIBABCKIT_IMPLEMENTED;
347 LIBABCKIT_TIME_EXEC;
348
349 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
350 switch (file->frontend) {
351 case Mode::DYNAMIC:
352 return FindOrCreateLiteralDoubleDynamic(file, value);
353 case Mode::STATIC:
354 return FindOrCreateLiteralDoubleStatic(file, value);
355 default:
356 LIBABCKIT_UNREACHABLE;
357 }
358 }
359
CreateLiteralLiteralArray(AbckitFile * file,AbckitLiteralArray * litarr)360 extern "C" AbckitLiteral *CreateLiteralLiteralArray(AbckitFile *file, AbckitLiteralArray *litarr)
361 {
362 LIBABCKIT_CLEAR_LAST_ERROR;
363 LIBABCKIT_IMPLEMENTED;
364 LIBABCKIT_TIME_EXEC;
365
366 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
367 LIBABCKIT_BAD_ARGUMENT(litarr, nullptr);
368 switch (file->frontend) {
369 case Mode::DYNAMIC:
370 return FindOrCreateLiteralLiteralArrayDynamic(file, litarr);
371 case Mode::STATIC:
372 statuses::SetLastError(ABCKIT_STATUS_UNSUPPORTED);
373 return nullptr;
374 default:
375 LIBABCKIT_UNREACHABLE;
376 }
377 }
378
CreateLiteralString(AbckitFile * file,const char * value,size_t len)379 extern "C" AbckitLiteral *CreateLiteralString(AbckitFile *file, const char *value, size_t len)
380 {
381 LIBABCKIT_CLEAR_LAST_ERROR;
382 LIBABCKIT_IMPLEMENTED;
383 LIBABCKIT_TIME_EXEC;
384
385 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
386 LIBABCKIT_BAD_ARGUMENT(value, nullptr);
387 LIBABCKIT_ZERO_ARGUMENT(len, nullptr);
388 switch (file->frontend) {
389 case Mode::DYNAMIC:
390 return FindOrCreateLiteralStringDynamic(file, value, len);
391 case Mode::STATIC:
392 return FindOrCreateLiteralStringStatic(file, value, len);
393 default:
394 LIBABCKIT_UNREACHABLE;
395 }
396 }
397
CreateLiteralMethod(AbckitFile * file,AbckitCoreFunction * function)398 extern "C" AbckitLiteral *CreateLiteralMethod(AbckitFile *file, AbckitCoreFunction *function)
399 {
400 LIBABCKIT_CLEAR_LAST_ERROR;
401 LIBABCKIT_IMPLEMENTED;
402 LIBABCKIT_TIME_EXEC;
403
404 LIBABCKIT_BAD_ARGUMENT(file, nullptr);
405 LIBABCKIT_BAD_ARGUMENT(function, nullptr);
406 switch (file->frontend) {
407 case Mode::DYNAMIC:
408 return FindOrCreateLiteralMethodDynamic(file, function);
409 case Mode::STATIC:
410 return FindOrCreateLiteralMethodStatic(file, function);
411 default:
412 LIBABCKIT_UNREACHABLE;
413 }
414 }
415
416 AbckitModifyApi g_modifyApiImpl = {
417
418 // ========================================
419 // File
420 // ========================================
421
422 // ========================================
423 // Module
424 // ========================================
425
426 // ========================================
427 // Class
428 // ========================================
429
430 // ========================================
431 // AnnotationInterface
432 // ========================================
433
434 // ========================================
435 // Function
436 // ========================================
437
438 FunctionSetGraph,
439
440 // ========================================
441 // Annotation
442 // ========================================
443
444 // ========================================
445 // Type
446 // ========================================
447
448 CreateType,
449 CreateReferenceType,
450
451 // ========================================
452 // Value
453 // ========================================
454
455 CreateValueU1,
456 CreateValueDouble,
457 CreateValueString,
458 CreateLiteralArrayValue,
459
460 // ========================================
461 // String
462 // ========================================
463
464 CreateString,
465
466 // ========================================
467 // LiteralArray
468 // ========================================
469
470 CreateLiteralArray,
471
472 // ========================================
473 // LiteralArray
474 // ========================================
475
476 CreateLiteralBool,
477 CreateLiteralU8,
478 CreateLiteralU16,
479 CreateLiteralMethodAffiliate,
480 CreateLiteralU32,
481 CreateLiteralU64,
482 CreateLiteralFloat,
483 CreateLiteralDouble,
484 CreateLiteralLiteralArray,
485 CreateLiteralString,
486 CreateLiteralMethod,
487 };
488
489 } // namespace libabckit
490
491 #ifdef ABCKIT_ENABLE_MOCK_IMPLEMENTATION
492 #include "./mock/abckit_mock.h"
493 #endif
494
AbckitGetModifyApiImpl(AbckitApiVersion version)495 extern "C" AbckitModifyApi const *AbckitGetModifyApiImpl(AbckitApiVersion version)
496 {
497 #ifdef ABCKIT_ENABLE_MOCK_IMPLEMENTATION
498 return AbckitGetMockModifyApiImpl(version);
499 #endif
500 switch (version) {
501 case ABCKIT_VERSION_RELEASE_1_0_0:
502 return &libabckit::g_modifyApiImpl;
503 default:
504 libabckit::statuses::SetLastError(ABCKIT_STATUS_UNKNOWN_API_VERSION);
505 return nullptr;
506 }
507 }
508