Merge pull request !1308 from ivagin/libmanipulasm-poc
This commit is contained in:
openharmony_ci 2024-10-26 18:32:24 +00:00 committed by Gitee
commit 22fab97cf4
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
692 changed files with 107789 additions and 108 deletions

2
.gitignore vendored
View File

@ -14,6 +14,8 @@ tags
.byebug_history
.cache
*.swp
libabckit/node_modules
libabckit/package-lock.json
static_core/build
static_core/plugins/ecmascript
static_core/plugins/ets/tools/declgen_ts2ets/build

127
libabckit/.clang-format Normal file
View File

@ -0,0 +1,127 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...

156
libabckit/.clang-tidy Normal file
View File

@ -0,0 +1,156 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
WarningsAsErrors: "*"
AnalyzeTemporaryDtors: false
User: user
CheckOptions:
- key: google-readability-braces-around-statements.ShortStatementLines
value: "1"
- key: google-readability-function-size.StatementThreshold
value: "800"
- key: google-readability-namespace-comments.ShortNamespaceLines
value: "10"
- key: google-readability-namespace-comments.SpacesBeforeComments
value: "2"
- key: modernize-loop-convert.MaxCopySize
value: "16"
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: "NULL"
- key: readability-function-size.LineThreshold
value: 200
- key: readability-magic-numbers.IgnoredIntegerValues
value: "1;2;3;4;5;6;7;8"
- key: readability-identifier-naming.AbstractClassCase
value: CamelCase
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.ClassConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.ClassMemberCase
value: camelBack
- key: readability-identifier-naming.ClassMemberSuffix
value: _
- key: readability-identifier-naming.ClassMethodCase
value: CamelCase
- key: readability-identifier-naming.ConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.ConstantMemberCase
value: camelBack
- key: readability-identifier-naming.ConstantMemberSuffix
value: _
- key: readability-identifier-naming.ConstantParameterCase
value: camelBack
- key: readability-identifier-naming.ConstantPointerParameterCase
value: camelBack
- key: readability-identifier-naming.ConstexprFunctionCase
value: CamelCase
- key: readability-identifier-naming.ConstexprMethodCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariableCase
value: UPPER_CASE
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.EnumConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.FunctionCase
value: CamelCase
- key: readability-identifier-naming.GlobalConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.GlobalConstantPointerCase
value: UPPER_CASE
- key: readability-identifier-naming.GlobalFunctionCase
value: CamelCase
- key: readability-identifier-naming.GlobalPointerCase
value: camelBack
- key: readability-identifier-naming.GlobalPointerPrefix
value: g_
- key: readability-identifier-naming.GlobalVariableCase
value: camelBack
- key: readability-identifier-naming.GlobalVariablePrefix
value: g_
- key: readability-identifier-naming.InlineNamespaceCase
value: lower_case
- key: readability-identifier-naming.LocalConstantCase
value: camelBack
- key: readability-identifier-naming.LocalConstantPointerCase
value: camelBack
- key: readability-identifier-naming.LocalPointerCase
value: camelBack
- key: readability-identifier-naming.LocalVariableCase
value: camelBack
- key: readability-identifier-naming.MemberCase
value: camelBack
- key: readability-identifier-naming.MemberSuffix
value: _
- key: readability-identifier-naming.MethodCase
value: CamelCase
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.ParameterCase
value: camelBack
- key: readability-identifier-naming.ParameterPackCase
value: camelBack
- key: readability-identifier-naming.PointerParameterCase
value: camelBack
- key: readability-identifier-naming.PrivateMemberCase
value: camelBack
- key: readability-identifier-naming.PrivateMemberSuffix
value: _
- key: readability-identifier-naming.PrivateMethodCase
value: CamelCase
- key: readability-identifier-naming.ProtectedMemberCase
value: camelBack
- key: readability-identifier-naming.ProtectedMemberSuffix
value: _
- key: readability-identifier-naming.ProtectedMethodCase
value: CamelCase
- key: readability-identifier-naming.PublicMemberCase
value: camelBack
- key: readability-identifier-naming.PublicMemberSuffix
value: ""
- key: readability-identifier-naming.PublicMethodCase
value: CamelCase
- key: readability-identifier-naming.StaticConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.StaticVariableCase
value: camelBack
- key: readability-identifier-naming.StructCase
value: CamelCase
- key: readability-identifier-naming.TemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TemplateTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TypeAliasCase
value: CamelCase
- key: readability-identifier-naming.TypedefCase
value: CamelCase
- key: readability-identifier-naming.TypeTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.UnionCase
value: CamelCase
- key: readability-identifier-naming.ValueTemplateParameterCase
value: UPPER_CASE
- key: readability-identifier-naming.VariableCase
value: camelBack
- key: readability-identifier-naming.VirtualMethodCase
value: CamelCase

2579
libabckit/.doxygen Normal file

File diff suppressed because it is too large Load Diff

396
libabckit/BUILD.gn Normal file
View File

@ -0,0 +1,396 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/runtime_core/ark_config.gni")
import("//arkcompiler/runtime_core/libabckit/libabckit_config.gni")
declare_args() {
enable_libabckit_coverage = false
}
config("libabckit_coverage") {
if (enable_libabckit_coverage) {
cflags = [
"-fprofile-instr-generate",
"-fcoverage-mapping",
"-mllvm",
"-runtime-counter-relocation",
]
ldflags = [
"-fprofile-instr-generate",
"-fcoverage-mapping",
]
}
}
config("libabckit_config") {
cflags_cc = [
"-std=c++17",
"-pedantic",
"-pedantic-errors",
"-Wall",
"-Wextra",
"-Werror",
]
if (!is_debug) {
defines = [ "NDEBUG" ]
}
if (libabckit_with_sanitizers) {
cflags = [
"-fsanitize=address",
"-fsanitize-address-use-after-scope",
"-fsanitize=undefined",
"-fno-omit-frame-pointer",
]
ldflags = [
"-lasan",
"-lubsan",
]
}
configs = [ sdk_libc_secshared_config ]
}
ark_gen_file("abckit_options_gen_h") {
template_file = "$ark_root/templates/options/options.h.erb"
data_file = "$ark_root/libabckit/src/options.yaml"
requires = [ "$ark_root/templates/common.rb" ]
output_file = "$target_gen_dir/generated/tmp/abckit_options_gen.h"
}
action("abckit_options") {
script = "./scripts/fix_options.sh"
args = [
rebase_path("$target_gen_dir/generated/tmp/abckit_options_gen.h"),
rebase_path("$target_gen_dir/generated/abckit_options_gen.h"),
]
inputs = [ "$ark_root/libabckit/src/options.yaml" ]
outputs = [ "$target_gen_dir/generated/abckit_options_gen.h" ]
deps = [ ":abckit_options_gen_h" ]
}
action("get_abckit_status") {
script = "scripts/get_abckit_status.py"
outputs = [ "$target_gen_dir/abckit_status.csv" ]
}
ohos_executable("abckit_canary") {
cflags = [
"-std=c99",
"-pedantic",
"-pedantic-errors",
"-Wall",
"-Wextra",
"-Werror",
"-Wno-typedef-redefinition",
]
cflags += [ "-Wno-typedef-redefinition" ] # NOTE(ivagin)
sources = [ "tests/canary.c" ]
include_dirs = [ "$ark_root" ]
install_enable = false
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}
group("libabckit_packages") {
if (enable_libabckit) {
deps = [
":libabckit(${host_toolchain})",
"abckit:abckit(${host_toolchain})",
]
}
}
group("libabckit_tests") {
testonly = true
deps = [
":abckit_canary(${host_toolchain})",
":abckit_check_clang_format",
":abckit_check_clang_tidy",
":abckit_documentation",
":get_abckit_status",
"tests:AbcKitTestAction",
]
}
config("libabckit_public_config") {
include_dirs = [ "include" ]
}
ohos_source_set("libabckit_static") {
sources = [
"src/abckit_impl.cpp",
"src/helpers_common.cpp",
"src/ir_impl.cpp",
"src/ir_interface_impl.cpp",
"src/isa_dynamic_impl.cpp",
"src/isa_dynamic_impl_instr_1.cpp",
"src/isa_dynamic_impl_instr_2.cpp",
"src/isa_static_impl.cpp",
"src/metadata_arkts_inspect_impl.cpp",
"src/metadata_arkts_modify_impl.cpp",
"src/metadata_inspect_impl.cpp",
"src/metadata_js_inspect_impl.cpp",
"src/metadata_js_modify_impl.cpp",
"src/metadata_modify_impl.cpp",
"src/statuses_impl.cpp",
]
include_dirs = [
"$ark_root",
"$ark_root/libpandabase",
"$target_gen_dir/src",
]
configs = [
"$abckit_root:libabckit_coverage",
":libabckit_config",
]
deps = [ ":abckit_options" ]
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}
group("libabckit_adapter_static_header_deps") {
deps = [
"src/adapter_dynamic/templates:isa_gen_libabckit_inst_props_helpers_dynamic_inc",
"src/adapter_static:get_intrinsic_id_static_inc",
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_inl",
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_opcodes_inc",
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_vreg_width_h",
"src/templates/dyn_intrinsics:isa_gen_libabckit_dyn_intrinsics_enum_inc",
"src/templates/dyn_intrinsics:isa_gen_libabckit_dyn_intrinsics_flags_inc",
"src/templates/dyn_intrinsics:isa_gen_libabckit_get_dyn_intrinsics_names_inc",
]
}
ohos_source_set("libabckit_adapter_static_source_set") {
sources = [
"src/adapter_static/abckit_static.cpp",
"src/adapter_static/helpers_static.cpp",
"src/adapter_static/ir_static.cpp",
"src/adapter_static/ir_static_instr_1.cpp",
"src/adapter_static/metadata_inspect_static.cpp",
"src/adapter_static/metadata_modify_static.cpp",
"src/adapter_static/runtime_adapter_static.cpp",
]
ins_create_wrapper_dyn_dir = get_label_info(
"$ark_root/libabckit/src/wrappers:isa_gen_libabckit_ins_create_wrapper_api_inc",
"target_gen_dir")
intrinsics_gen_dir = get_label_info(
"$ark_root/libabckit/src/adapter_dynamic/templates:isa_gen_libabckit_dyn_intrinsics_enum_inl",
"target_gen_dir")
include_dirs = [
"$ark_root/static_core", # this target should not include headers from
# dynamic runtime, so static_core must be listed
# first
"$ark_root",
"$ark_root/libabckit",
"$ark_root/include",
"$target_gen_dir/src/codegen",
"$target_gen_dir/src/adapter_static",
"$target_gen_dir/src/adapter_dynamic/generated",
"$target_gen_dir/libabckit/src",
"$intrinsics_gen_dir/../generated",
"$ins_create_wrapper_dyn_dir",
]
part_name = "runtime_core"
subsystem_name = "arkcompiler"
configs = [
"$ark_root/static_core/assembler:arkassembler_public_config",
"$ark_root/static_core/bytecode_optimizer:bytecodeopt_public_config",
"$ark_root/static_core/compiler:arkcompiler_public_config",
"$ark_root/static_core/libpandafile:arkfile_public_config",
"$ark_root/static_core/libpandabase:arkbase_public_config",
"$ark_root/static_core/runtime:arkruntime_public_config", # NOTE
"$ark_root/static_core:ark_config", # NOTE
":libabckit_config",
]
configs += [ "$abckit_root:libabckit_coverage" ]
deps = [
":concat_abckit_intrinsics_yaml",
":libabckit_adapter_static_header_deps",
"$ark_root/static_core/abc2program:arkts_abc2program",
"$ark_root/static_core/assembler:libarktsassembler",
"$ark_root/static_core/assembler:libarktsassembler",
"$ark_root/static_core/bytecode_optimizer:libarktsbytecodeopt",
"$ark_root/static_core/bytecode_optimizer:libarktsbytecodeopt",
"$ark_root/static_core/libpandabase:libarktsbase",
"$ark_root/static_core/libpandafile:libarktsfile",
]
}
abckit_yaml = "abckit_compiler_intrinsics.yaml"
action("crop_abckit_intrinsics_yaml") {
script = "./scripts/fix_intrinsics_yml.sh"
args = [
rebase_path("src/$abckit_yaml"),
rebase_path("$target_gen_dir/generated/$abckit_yaml"),
]
inputs = [ "src/$abckit_yaml" ]
outputs = [ "$target_gen_dir/generated/$abckit_yaml" ]
}
runtime_intrinsics_gen_dir =
get_label_info(
"$ark_root/static_core/runtime:arkruntime_gen_intrinsics_yaml",
"target_gen_dir")
concat_yamls("concat_abckit_intrinsics_yaml") {
extra_dependencies = [
"$ark_root/static_core/runtime:arkruntime_gen_intrinsics_yaml",
":crop_abckit_intrinsics_yaml",
]
output_file = "$runtime_intrinsics_gen_dir/abckit_intrinsics.yaml"
default_file = "$runtime_intrinsics_gen_dir/intrinsics.yaml"
add_yamls = [ "$target_gen_dir/generated/$abckit_yaml" ]
}
group("libabckit_adapter_dynamic_header_deps") {
deps = [
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_inl",
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_opcodes_inc",
"src/templates/abckit_intrinsics:ark_gen_libabckit_abckit_intrinsics_vreg_width_h",
"src/templates/dyn_intrinsics:isa_gen_libabckit_dyn_intrinsics_enum_inc",
"src/templates/dyn_intrinsics:isa_gen_libabckit_dyn_intrinsics_flags_inc",
"src/templates/dyn_intrinsics:isa_gen_libabckit_get_dyn_intrinsics_names_inc",
]
}
ohos_source_set("libabckit_adapter_dynamic_source_set") {
sources = [
"src/adapter_dynamic/abckit_dynamic.cpp",
"src/adapter_dynamic/helpers_dynamic.cpp",
"src/adapter_dynamic/metadata_inspect_dynamic.cpp",
"src/adapter_dynamic/metadata_modify_dynamic.cpp",
]
ins_create_wrapper_dyn_dir = get_label_info(
"$ark_root/libabckit/src/wrappers:isa_gen_libabckit_ins_create_wrapper_api_inc",
"target_gen_dir")
include_dirs = [
"$ark_root",
"$ark_root/libabckit",
"$ark_root/include",
"$ins_create_wrapper_dyn_dir",
]
part_name = "runtime_core"
subsystem_name = "arkcompiler"
configs = [
"$ark_root:ark_config",
"$ark_root/assembler:arkassembler_public_config",
"$ark_root/libpandabase:arkbase_public_config",
"$ark_root/libpandafile:arkfile_public_config",
":libabckit_config",
]
configs += [ "$abckit_root:libabckit_coverage" ]
deps = [
":concat_abckit_intrinsics_yaml",
":libabckit_adapter_dynamic_header_deps",
"$ark_root/abc2program:abc2program",
"$ark_root/assembler:libarkassembler",
"src/wrappers/graph_wrapper:libabckit_graph_wrapper_source_set",
]
# external_deps = [
# "ets_runtime:libark_jsruntime",
# ]
}
ohos_shared_library("libabckit") {
deps = [
":libabckit_adapter_dynamic_source_set",
":libabckit_adapter_static_source_set",
":libabckit_static",
"src/codegen:libabckit_codegen_dynamic_source_set",
"src/codegen:libabckit_codegen_static_source_set",
"src/irbuilder_dynamic:libabckit_ir_builder_dynamic_source_set",
"src/mem_manager:libabckit_mem_manager_source_set",
"src/wrappers:libabckit_abcfile_wrapper_source_set",
"src/wrappers:libabckit_pandasm_wrapper_source_set",
]
configs = [
"$abckit_root:libabckit_coverage",
":libabckit_config",
]
if (is_linux) {
libs = [ "stdc++fs" ]
}
output_extension = "so"
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}
action("abckit_documentation") {
script = "$ark_root/libabckit/scripts/run_script.sh"
args = [
"--script=doxygen",
"--ret-code=0",
"--env=ABCKIT_DOXYGEN_OUT_DIR=" + rebase_path("$target_gen_dir") +
"/doxygen/",
"--env=ABCKIT_PROJECT_ROOT=" + rebase_path("$ark_root") + "/libabckit/",
"--script-args=" + rebase_path("$ark_root") + "/libabckit/.doxygen",
]
outputs = [ "$target_gen_dir/abckit_documentation_status.txt" ]
}
action("abckit_force_clang_format") {
script = "$ark_root/static_core/scripts/code_style/code_style_check.py"
args = [
rebase_path("$ark_root") + "/libabckit/",
"--reformat",
]
outputs = [ "$target_gen_dir/generated/tmp/force_clang_format_status.txt" ]
}
action("abckit_check_clang_format") {
script = "$ark_root/static_core/scripts/code_style/code_style_check.py"
args = [ rebase_path("$ark_root") + "/libabckit/" ]
outputs = [ "$target_gen_dir/generated/tmp/check_clang_format_status.txt" ]
}
action("abckit_check_clang_tidy") {
script = "$ark_root/static_core/scripts/clang-tidy/clang_tidy_check.py"
args = [
rebase_path("$ark_root"),
rebase_path("$root_out_dir"),
"--check-libabckit",
"--filename-filter=libabckit/*",
"--header-filter=.*/libabckit/.*",
]
outputs = [ "$target_gen_dir/generated/tmp/check_clang_tidy_status.txt" ]
deps = [
":abckit_options",
":libabckit",
]
}

23
libabckit/README.md Normal file
View File

@ -0,0 +1,23 @@
# AbcKit
AbcKit is a library for `abc` file inspection and modification.
Documentation:
* [How to build and test](doc/how_to_build_and_test.md)
* [Cook Book](doc/mini_cookbook.md)
* [Implementation description](doc/implementation_description.md)
## How to download and build
Download:
```sh
repo init -u https://gitee.com/ark-standalone-build/manifest.git -b master
repo sync -c -j8
repo forall -c 'git lfs pull'
./prebuilts_download.sh
```
Build AbcKit:
```sh
./ark.py x64.release libabckit_packages --gn-args="is_standard_system=true enable_libabckit=true"
```

32
libabckit/abckit/BUILD.gn Normal file
View File

@ -0,0 +1,32 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/runtime_core/ark_config.gni")
ohos_executable("abckit") {
sources = [ "abckit.cpp" ]
include_dirs = [
"$ark_root/libabckit/include",
"$target_gen_dir",
]
configs = [
"$ark_root/libpandabase:arkbase_public_config",
"$ark_root/libabckit:libabckit_config",
]
deps = [
"$ark_root/assembler:libarkassembler",
"$ark_root/libabckit:libabckit",
]
install_enable = false
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}

123
libabckit/abckit/abckit.cpp Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "libabckit/include/c/abckit.h"
#include "utils/pandargs.h"
#include "libabckit/src/abckit_options.h"
#include <dlfcn.h>
#include <iostream>
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
void PrintHelp(panda::PandArgParser &paParser)
{
std::cerr << "Usage:" << std::endl;
std::cerr << "abckit --plugin-path <libabckitplugin.so> --input-file <input.abc> [--output-file <output.abc>]"
<< std::endl;
std::cerr << "Supported options:" << std::endl;
std::cerr << paParser.GetHelpString() << std::endl;
}
bool ProcessArgs(panda::PandArgParser &paParser, int /*argc*/, const char ** /*argv*/)
{
if (libabckit::g_abckitOptions.GetInputFile().empty()) {
std::cerr << "ERROR: --input-file is required\n";
PrintHelp(paParser);
return false;
}
if (!fs::exists(libabckit::g_abckitOptions.GetInputFile())) {
std::cerr << "ERROR: file doesn't exist: " << libabckit::g_abckitOptions.GetInputFile() << '\n';
PrintHelp(paParser);
return false;
}
if (libabckit::g_abckitOptions.GetPluginPath().empty()) {
std::cerr << "ERROR: --plugin-path is required\n";
PrintHelp(paParser);
return false;
}
if (!fs::exists(libabckit::g_abckitOptions.GetPluginPath())) {
std::cerr << "ERROR: file doesn't exist: " << libabckit::g_abckitOptions.GetPluginPath() << '\n';
PrintHelp(paParser);
return false;
}
return true;
}
int main(int argc, const char **argv)
{
panda::PandArgParser paParser;
libabckit::g_abckitOptions.AddOptions(&paParser);
if (!paParser.Parse(argc, argv)) {
std::cerr << "Error: " << paParser.GetErrorString() << "\n";
PrintHelp(paParser);
return 1;
}
if (!ProcessArgs(paParser, argc, argv)) {
return 1;
}
if (libabckit::g_abckitOptions.IsHelp()) {
PrintHelp(paParser);
return 0;
}
void *handler = dlopen(libabckit::g_abckitOptions.GetPluginPath().c_str(), RTLD_LAZY);
if (handler == nullptr) {
std::cerr << "ERROR: failed load plugin: " << libabckit::g_abckitOptions.GetPluginPath() << '\n';
return 1;
}
auto *entry = reinterpret_cast<int (*)(AbckitFile *)>(dlsym(handler, "Entry"));
if (entry == nullptr) {
std::cerr << "ERROR: failed find symbol 'Entry'\n";
return 1;
}
AbckitFile *file = g_impl->openAbc(libabckit::g_abckitOptions.GetInputFile().c_str());
if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR || file == nullptr) {
std::cerr << "ERROR: failed to open: " << libabckit::g_abckitOptions.GetInputFile() << '\n';
return 1;
}
int ret = entry(file);
if (ret != 0) {
std::cerr << "ERROR: plugin returned non-zero return code";
return ret;
}
if (!libabckit::g_abckitOptions.GetOutputFile().empty()) {
g_impl->writeAbc(file, libabckit::g_abckitOptions.GetOutputFile().c_str());
if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR || file == nullptr) {
std::cerr << "ERROR: failed to write: " << libabckit::g_abckitOptions.GetOutputFile() << '\n';
return 1;
}
g_impl->closeFile(file);
}
return 0;
}

View File

@ -0,0 +1,54 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/runtime_core/ark_config.gni")
import("//arkcompiler/runtime_core/libabckit/libabckit_config.gni")
template("abckit_plugin") {
ohos_shared_library("${target_name}") {
forward_variables_from(invoker,
"*",
[
"configs",
"deps",
"include_dirs",
])
deps = [ "$abckit_root:libabckit" ]
include_dirs = [ "$abckit_root/include" ]
if (defined(invoker.include_dirs)) {
deps += invoker.include_dirs
}
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}
}
abckit_plugin("abckit_stress_plugin") {
sources = [ "stress.cpp" ]
install_enable = false
part_name = "runtime_core"
subsystem_name = "arkcompiler"
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "c/abckit.h"
#include "c/extensions/arkts/metadata_arkts.h"
#include "c/metadata_core.h"
#include "c/ir_core.h"
#include "c/statuses.h"
#include <iostream>
#include <functional>
static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
static auto g_implArkI = AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
static void TransformMethod(AbckitCoreFunction *method)
{
if (g_implI->moduleGetTarget(g_implI->functionGetModule(method)) == ABCKIT_TARGET_ARK_TS_V2) {
auto *arktsMethod = g_implArkI->coreFunctionToArktsFunction(method);
if (g_implArkI->functionIsNative(arktsMethod)) {
return;
}
}
AbckitGraph *graph = g_implI->createGraphFromFunction(method);
if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR) {
return;
}
g_implM->functionSetGraph(method, graph);
}
// CC-OFFNXT(超大函数[C++] Oversized function) huge_function
extern "C" int Entry(AbckitFile *file)
{
bool hasError = false;
std::function<bool(AbckitCoreFunction *)> cbFunc = [&](AbckitCoreFunction *f) {
g_implI->functionEnumerateNestedFunctions(f, &cbFunc, [](AbckitCoreFunction *f, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(f);
});
TransformMethod(f);
if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR) {
hasError = true;
}
return !hasError;
};
std::function<bool(AbckitCoreClass *)> cbClass = [&](AbckitCoreClass *c) {
g_implI->classEnumerateMethods(c, (void *)&cbFunc, [](AbckitCoreFunction *m, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(m);
});
return !hasError;
};
std::function<void(AbckitCoreNamespace *)> cbNamespce = [&](AbckitCoreNamespace *n) {
g_implI->namespaceEnumerateNamespaces(n, &cbNamespce, [](AbckitCoreNamespace *n, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreNamespace *)> *>(cb))(n);
});
g_implI->namespaceEnumerateClasses(n, &cbClass, [](AbckitCoreClass *c, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreClass *)> *>(cb))(c);
});
g_implI->namespaceEnumerateTopLevelFunctions(n, (void *)&cbFunc, [](AbckitCoreFunction *f, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(f);
});
return !hasError;
};
std::function<void(AbckitCoreModule *)> cbModule = [&](AbckitCoreModule *m) {
g_implI->moduleEnumerateNamespaces(m, &cbNamespce, [](AbckitCoreNamespace *n, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreNamespace *)> *>(cb))(n);
});
g_implI->moduleEnumerateClasses(m, &cbClass, [](AbckitCoreClass *c, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreClass *)> *>(cb))(c);
});
g_implI->moduleEnumerateTopLevelFunctions(m, (void *)&cbFunc, [](AbckitCoreFunction *m, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(m);
});
return !hasError;
};
g_implI->fileEnumerateModules(file, &cbModule, [](AbckitCoreModule *m, void *cb) {
return (*reinterpret_cast<std::function<bool(AbckitCoreModule *)> *>(cb))(m);
});
return hasError ? 1 : 0;
}

View File

@ -0,0 +1,53 @@
# How to download
```sh
repo init -u https://gitee.com/ark-standalone-build/manifest.git -b master
repo sync -c -j8
repo forall -c 'git lfs pull'
./prebuilts_download.sh
```
# How to build and test
Build AbcKit:
```sh
# Debug mode
./ark.py x64.debug libabckit_packages --gn-args="is_standard_system=true enable_libabckit=true"
# Release mode
./ark.py x64.release libabckit_packages --gn-args="is_standard_system=true enable_libabckit=true"
```
Run unit tests:
```sh
# Debug mode
./ark.py x64.debug libabckit_tests --gn-args="is_standard_system=true enable_libabckit=true"
# Release mode
./ark.py x64.release libabckit_tests --gn-args="is_standard_system=true enable_libabckit=true"
```
Run unit tests with sanitizers:
```sh
# Debug mode
./ark.py x64.debug libabckit_tests --gn-args="is_standard_system=true enable_libabckit=true libabckit_with_sanitizers=true"
# Release mode
./ark.py x64.release libabckit_tests --gn-args="is_standard_system=true enable_libabckit=true libabckit_with_sanitizers=true"
```
# Full tests (`self-check.sh`)
Remove out, build AbcKit, execute format, tidy, unit-tests and stress tests in debug and release modes:
```sh
./arkcompiler/runtime_core/libabckit/scripts/self-check.sh --dir=/path/to/standalone/root
```
# Code coverage (`self-check.sh`)
Remove out, build AbcKit, execute unit-tests and stress tests in debug mode and collect code coverage:
```sh
./arkcompiler/runtime_core/libabckit/scripts/self-check.sh --dir=/path/to/standalone/root --coverage
```

View File

@ -0,0 +1,282 @@
# Implementation description
Important note: Currently AbcKit supports JS, ArkTS1 and ArkTS2, but **ArkTS2 support is experimental**.
Compiled JS and ArkTS1 are stored in "dynamic" `abc` file format and ArkTS2 in "static" `abc` file format.
AbcKit works with these file formats using "dynamic" and "static" runtimes.
Please take a look at [cookbook](mini_cookbook.md) beforehand to find out how API looks like from user' point of view.
1. [Two types of `abc` files](#two-types-of-abc-files)
2. [C API and C++ implementation](#c-api-and-c-implementation)
3. [Control flow by components](#control-flow-by-components)
4. [Control flow by source files](#control-flow-by-source-files)
5. [Dispatch between dynamic and static file formats](#dispatch-between-dynamic-and-static-file-formats)
6. [Data structures (context) and opaque pointers](#data-structures-context-and-opaque-pointers)
7. [Data structures (context) implementation](#data-structures-context-implementation)
8. [Includes naming conflict](#includes-naming-conflict)
9. [Bytecode<-->IR](#bytecode--ir)
## Two types of abc files
**AbcKit supports two types of `abc` files**: dynamic and static.
Depending on `abc` file type different components are used, so there are two kinds of:
1. `panda::panda_file` and `ark::panda_file`
2. `panda::abc2program` and `ark::abc2program`
3. `panda::pandasm` and `ark::pandasm`
4. IR builder: `libabckit::IrBuilderDynamic` and `ark::compiler::IrBuilder`
5. Codegen: `libabckit::CodeGenDynamic` and `libabckit::CodeGenStatic`
NOTE: `panda::` is dynamic runtime namespace, `ark::` is static runtime namespace
And only one static runtime compiler is used for AbcKit graph representation: `ark::compiler::Graph`.
## C API and C++ implementation
All public API is stored in `./include/c` folder and has such structure:
```
include/c/
├── abckit.h // Entry point API
├── metadata_core.h // API for language-independent metadata inspection/transformation
├── extensions
│   ├── arkts
│   │   └── metadata_arkts.h // API for language-specific (ArkTS1 and ArkTS2) metadata inspection/transformation
│   └── js
│   └── metadata_js.h // API for language-specific (JS) metadata inspection/transformation
├── ir_core.h // API for language-independent graph inspection/transformation
├── isa
│   ├── isa_dynamic.h // API for language-specific (JS and ArkTS1) graph inspection/transformation
│   └── isa_static.h // API for language-specific (ArkTS2) graph inspection/transformation (This header is now hidden)
├── statuses.h // List of error codes
```
Abckit APIs are pure C functions, all implementations are stored in `./src/` folder and written in C++
## Control flow by components
1. When `openAbc` is called:
1. Read `abc` file into `panda_file`
2. Convert `panda_file` into `pandasm` using `abc2program`
2. Abckit metadata API inspects/transforms `pandasm` program
3. When `createGraphFromFunction` is called:
1. `pandasm` program is converted back into `panda_file` (because current IR builders support only `panda_file` input)
2. IR builder builds `ark::compiler::Graph`
4. Abckit graph API inspects/transforms `ark::compiler::Graph`
5. When `functionSetGraph` is called, `codegen` generates `pandasm` bytecode from `ark::compiler::Graph` and replaces original code of function
6. When `writeAbc` is called, transformed `pandasm` program is emitted into `abc` file
```
──────────────────────────────────────────────────────────────────────────────────────────────────
| /\
\/ |
x.abc────>(ark/panda)::panda_file───>(ark/panda)::abc2program────>(ark/panda)::pandasm────>(ark/panda)::panda_file───>(ark/panda)::ir_builder────>ark::compiler::Graph──>(ark/panda::)codegen
| /\ | /\ |
| | | | |
| | | | |
(abckit metadata API) | | \/
──────────>(ark/panda)::RuntimeIface───────────────>(abckit IR API)
```
## Control flow by source files
1. C API declarations
2. C++ implementations for above APIs, in most cases implementation is just dispatch between dynamic and static runtimes
3. Runtime specific implementation:
1. Dynamic runtime implementation
2. Static runtime implementation
4. APIs consumes and produces pointers to opaque `AbckitXXX` structures
```
|───────────────────────────────────────────|
| 4. Data structures (context) (./src) |
| metadata_inspect_impl.h |
| ir_impl.h |
|───────────────────────────────────────────|
/\
|
\/
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
/\
|
\/
|──────────────────────────────────────| |───────────────────────────────────────────| |─────────────────────────────────────────────────────────────────|
| 1. API declarations (./include/c)| | 2. API implementation (./src/) | | 3.1 Dynamic runtime implementation (./src/adapter_dynamic/) |
| abckit.h | | abckit_impl.cpp | | abckit_dynamic.cpp |
| metadata_core.h | | metadata_(inspect|modify)_impl.cpp | | metadata_(inspect|modify)_dynamic.cpp |
| ir_core.h | | ir_impl.cpp | | |
| extensions/arkts/metadata_arkts.h |───────>| metadata_arkts_(inspect|modify)_impl.cpp |───────>| |
| extensions/js/metadata_js.h | | metadata_js_(inspect|modify)_impl.cpp | | |
| isa/isa_dynamic.h | | isa_dynamic_impl.cpp | | |
| isa/isa_static.h | | isa_static_impl.cpp | | |
|──────────────────────────────────────| |───────────────────────────────────────────| |─────────────────────────────────────────────────────────────────|
|
\/
|───────────────────────────────────────────────────────────────|
| 3.2 Static runtime implementation (./src/adapter_static/) |
| abckit_static.cpp |
| metadata_(inspect|modify)_static.cpp |
| ir_static.cpp |
|───────────────────────────────────────────────────────────────|
```
## Dispatch between dynamic and static file formats
Lots of APIs are able to work with both dynamic and static file formats depending on source language of `abc` file.
Runtime specific implementations are stored in `./src/adapter_dynamic/` and `./src/adapter_static/`
For example here is `functionGetName()` API implementation (`./src/metadata_inspect_impl.cpp`):
```cpp
switch (function->module->target) {
case ABCKIT_TARGET_JS:
case ABCKIT_TARGET_ARKTS_V1:
return FunctionGetNameDynamic(function);
case ABCKIT_TARGET_ARKTS_V2:
return FunctionGetNameStatic(function);
}
```
So depending on function's source language one of two functions is called:
- `FunctionGetNameDynamic()` from `./src/adapter_dynamic/metadata_inspect_dynamic.cpp` <-- this is implementation specific for dynamic file format
- `FunctionGetNameStatic()` from `./src/adapter_static/metadata_inspect_static.cpp` <-- this is implementation specific for static file format
## Data structures (context) and opaque pointers
Abckit C API consumes and returns pointers to opaque `AbckitXXX` structures.
User has forward declaration types for these structures (implementation is hidden from user and stored in `./src/metadata_inspect_impl.h`),
so user can only receive pointer from API and pass it to another API and can't modify it manually.
For example here is type forward declaration from `./include/c/metadata_core.h`:
```
typedef struct AbckitLiteral AbckitLiteral;
```
And here is implementation from `./src/metadata_inspect_impl.h`:
```
struct AbckitLiteral {
AbckitFile *file;
libabckit::pandasm_Literal* val;
};
```
## Data structures (context) implementation
### Metadata
On `openAbc` API call abckit doing next steps:
1. Open `abc` file with `panda_file`
2. Convert opened panda file into `pandasm` program with `abc2program`
3. **Greedily** traverse all `pandasm` structures and create related `AbckitXXX` structures
Implementation of all `AbckitXXX` data structures is stored in `metadata_inspect_impl.h` and `ir_core.h`.
Top level data structure is `AbckitFile`, user receives `AbckitFile*` pointer after `openAbc` call.
`AbckitXXX` metadata structures has "tree structure" which matches source program structure, for example:
1. `AbckitFile` owns verctor of `unique_ptr<AbckitCoreModule>` (each module usually corresponds to one source file)
2. `AbckitCoreModule` owns vectors of `unique_ptr<AbckitCoreNamesapce>` (top level namespaces),
`unique_ptr<AbckitCoreClass>` (top level classes), `unique_ptr<AbckitCoreFunction>` (top level functions)
3. `AbckitNamespace` owns vectors of `unique_ptr<AbckitCoreNamesapce>` (namespaces nested in namespace),
`unique_ptr<AbckitCoreClass>` (classes nested in namespace), `unique_ptr<AbckitCoreFunction>` (top level namespace functions)
4. `AbckitCoreClass` owns vector of `unique_ptr<AbckitCoreFunction>` (class methods)
5. `AbckitCoreFunction` owns vector of `unique_ptr<AbckitCoreFunction>` (for function nested in other functions)
### Graph
On `createGraphFromFunction` API call abckit doing next steps:
1. Emit `panda_file` from `pandasm` function (this is needed because currently `ir_builder` supports only `panda_file` input)
2. Build `ark::compiler::Graph` using `IrBuilder`
3. **Greedily traverse `ark::compiler::Graph` and create related `AbckitXXX` structures**
`AbckitXXX` graph structures are: `AbckitGraph`, `AbckitBasicBock`, `AbckitInst` and `AbckitIrInterface`.
For each `ark::compiler::Graph` basic block and instruction, `AbckitBasicBock` and `AbckitInst` are created.
`AbckitGraph` contains such maps:
```cpp
std::unordered_map<ark::compiler::BasicBlock *, AbckitBasicBlock *> implToBB;
std::unordered_map<ark::compiler::Inst *, AbckitInst *> implToInst;
```
So we can get from internal graph implementation related `AbckitXXX` structure.
## Includes naming conflict
**Important implementation restriction:** libabckit includes headers from both dynamic and static runtimes,
so during build clang must be provided with include paths (`-I`) to both runtimes' folders.
But there are a lot of files and folders with same names in two runtimes, it causes naming conflict for `#include`s.
Thats why no file in AbcKit includes headers from both runtimes:
- there are `./src/adapter_dynamic/` folder for files which includes dynamic runtime headers
- and `./src/adapter_static/` folder for files which includes static runtime headers
### Wrappers
But for some cases we need to work with two runtimes in single file, for example:
- When we generate `ark::compiler::Graph` from `panda::panda_file::Function`
- Or when we generate `panda::pandasm::Function` from `ark::compiler::Graph`
For such cases we are using **wrappers** (they are stored in `./src/wrappers/`).
On next picture (arrows show includes direction) you can see how:
- `metadata_inspect_dynamic.cpp` includes dynamic runtime headers and also uses static graph (via `graph_wrapper.h`)
- `graph_wrapper.cpp` includes static runtime headers and also uses dynamic `panda_file` (via `abcfile_wrapper.h`)
```
metadata_inspect_dynamic.cpp ──>graph_wrapper.h<────|
| |
\/ |
DynamicRuntime |<───graph_wrapper.cpp──>StaticRuntime
/\ |
| |
abcfile_wrapper.cpp────────────>abcfile_wrapper.h<───|
```
If you follow arrows from above picture you can see that no file includes both static and dynamic runtimes' headers
## Bytecode <──> IR
abckit uses `ark::compiler::Graph` for internal graph representation,
so both dynamic and static `pandasm` bytecodes are converted into single `IR`
Bytecode <──> IR transformation approach is the same as for bytecode optimizer,
IR builder converts bytecode into IR and codegen converts IR into bytecode.
- There are two IR builders: `libabckit::IrBuilderDynamic` and `ark::compiler::IrBuilder`
- Two bytecode optimizers: `libabckit::CodeGenDynamic` and `libabckit::CodeGenStatic`
- Two runtime interfaces: `libabckit::AbckitRuntimeAdapterDynamic` and `libabckit::AbckitRuntimeAdapterStatic`
Runtime interface is part of static compiler, it is needed to abstract IR builder from it's source.
Each user of IR builder should provide it's own runtime interface (by design of compiler).
IR interface (`AbckitIrInterface`) idea is also taken from bytecode optimizer, it is needed to store relation between `panda_file` entity names and offsets.
Instance of IR interface is:
1. Created when function's bytecode converted into IR
2. Stored inside `AbckitGraph` instance
3. Used inside abckit API implementations to obtain `panda_file` entity from instruction's immediate offsets
### IR builder
For static bytecode abckit just reuses IrBuilder from static runtime.
For dynamic bytecode abckit uses fork of IrBuilder from dynamic runtime with various changes.
For dynamic bytecode almost all instructions are just converted into intrinsic calls (for example `Intrinsic.callthis0`).
### Codegen
For static bytecode abckit uses fork of bytecode optimizer codegen from static runtime with various changes.
For dynamic bytecode abckit uses fork of bytecode optimizer codegen from dynamic runtime with various changes.
### Compiler passes
There are additional graph clean up and optimization passes applied during graph creation and bytecode generation,
so if you do like this: `graph1`->`bytecode`->`graph2` without any additional changes,
`graph1` **may be different** from `graph2`!

View File

@ -0,0 +1,377 @@
### The main goals of this cookbook are to provide recipes for the main supported functions and to help you quickly get started with the LibAbcKit API.
## Get API implementations
```cpp
enum AbckitApiVersion version = ABCKIT_VERSION_RELEASE_1_0_0;
auto impl = AbckitGetApiImpl(version); // top level api with entry points
auto implI = AbckitGetInspectApiImpl(version); // language-independent inspect api
auto implM = AbckitGetModifyApiImpl(version); // language-independent modify api
auto implArkI = AbckitGetArkTSInspectApiImpl(version); // language-dependent inspect api
auto implArkM = AbckitGetArkTSModifyApiImpl(version); // language-dependent modify api
auto implG = AbckitGetGraphApiImpl(version); // language-independent graph api
auto dynG = AbckitGetIsaApiDynamicImpl(version); // language-dependent graph api
auto statG = AbckitGetIsaApiStaticImpl(version); // language-dependent graph api
```
One static instance of each at the beginning of the .cpp file is enough
## Errors
Every API in libabckit sets error value after execution. You can get it with `impl->getLastError()`. If there are no errors, the return value will be ABCKIT_STATUSNO_ERROR.
Сheck the execution status with:
```cpp
assert(impl->getLastError() == ABCKIT_STATUSNO_ERROR);
```
## Strings in LibAbcKit
Here is an useful example of a custom function for working with strings in libabckit:
```cpp
AbckitString *str = implI->createString(file, "new_string");
std::string AbckitStringToString(AbckitFile *file, AbckitString *str)
{
std::size_t len = 0;
implI->abckitStringToString(file, str, nullptr, &len);
auto name = malloc(len + 1);
implI->abckitStringToString(file, str, name, &len);
std::string res {name};
free(name);
return res;
}
```
# Metadata
## Open/Close/Write
### *Open file*
Mandatory and only entry point
```cpp
AbckitFile *file = implI->openAbc(path_to_abc);
```
Make sure that you have used the WriteAbc() or CloseFile() function after working with the file. This way you will avoid memory leaks
### *Write or Close*
```cpp
impl->writeAbc(file, path_to_output_file); // save changes and close
// or
impl->closeFile(file); // close without saving changes
```
## Traversing
libabckit objects hierarchy:
1. file contains modules ("file" is ".abc file" and "module" is the abstract of "source code file")
2. module contains: namespaces, top level classes, top level functions
3. namespace contains: nested namespaces, classes, functions
4. class contains: functions (methods)
5. functions contains: nested functions
<!-- file module class function -> introduce hierarchy -->
All the enumerators in libabckit accepts libabckit object, void* data with user data and callback lambda:
```cpp
void XXXEnumerateYYY(AbckitCoreXXX* xxx, void *data, bool(*cb)(AbckitCoreYYY* yyy, void *data))
```
### *Enumerate methods from class*
```cpp
// AbckitCoreClass *klass
implI->classEnumerateMethods(klass, data, [](AbckitCoreMethod *method, void *data) {
return true;
});
```
### *Collect all top level classes from module*
```cpp
// AbckitCoreModule *module
std::vector<AbckitCoreClass *> classes;
implI->moduleEnumerateClasses(module, (void*)&classes, [](AbckitCoreClass *klass, void *data) {
((std::vector<AbckitCoreClass*>*)data)->emplace.back(klass);
return true;
});
```
## Inspecting
### *Get method's parent class*
```cpp
// AbckitCoreMethod *method
AbckitCoreClass *klass = implI->functionGetParentClass(method);
```
### *Get value*
<!-- Test: LiteralGetU32_2 -->
```cpp
// AbckitLiteral *res
void GetValues(AbckitValue *u32_res, AbckitValue *double_res, AbckitValue *string_res) {
uint32_t val = implI->literalGetU32(u32_res);
double d = implI->valueGetDouble(double_res);
AbckitString *s = implI->valueGetString(string_res);
}
```
### *Get module name*
```cpp
// AbckitCoreModule *mod
AbckitString *GetModuleName(AbckitCoreModule *mod) {
return implI->moduleGetName(mod);
}
```
## Metadata Lang API
### *Add annotation for arkts method*
```cpp
void AddAnno(AbckitModifyContext *file, AbckitCoreMethod *method) {
auto mod = implI->functionGetModule(method);
// Find annoation interface with name "Anno"
AbckitCoreAnnotationInterface *ai;
implI->moduleEnumerateAnnotationInterfaces(mod, &ai, [](AbckitCoreAnnotationInterface *annoI, void *data) {
auto ai1 = (AbckitCoreAnnotationInterface **)data;
auto file = implI->annotationInterfaceGetInspectContext(annoI);
auto str = implI->annotationInterfaceGetName(annoI);
auto name = AbckitStringToString(file, str);
if (name == "Anno") {
(*ai1) = annoI;
}
return true;
});
// Add "@Anno" annotation for method
struct AbckitArktsAnnotationCreateParams annoCreateParams;
annoCreateParams.ai = implArkI->coreAnnotationInterfaceToArkTsAnnotationInterface(ai);
AbckitArktsAnnotation *anno = implArkM->functionAddAnnotation(file,
implArkI->coreFunctionToArkTsFunction(method), &annoCreateParams);
}
```
### *Cast AbckitArtksXXX -> AbckitXXX / AbckitXXX -> AbckitArktsXXX*
```cpp
AbckitCoreModule *CastToAbcKit(AbckitArktsInspectApi implArkI, AbckitArktsModule *mod) {
return implArkI->arkTsModuleToCoreModule(mod); }
AbckitArktsAnnotation *CastToArkTS(AbckitArktsInspectApi implArkI, AbckitCoreAnnotation *anno) {
return implArkI->coreAnnotationToArkTsAnnotation(anno); }
```
## Modification
### *Create values*
```cpp
AbckitLiteral *res1 = implM->createLiteralString(file, "asdf");
AbckitLiteral *res2 = implM->createLiteralDouble(file, 1.0);
AbckitLiteral *res = implM->createLiteralU32(file, 1);
```
```cpp
AbckitValue *res_u = implM->createValueU1(file, true);
AbckitValue *res_d = implM->createValueDouble(file, 1.2);
```
### *Get value type*
<!-- Test: ValueGetType_1 -->
```cpp
AbckitType *s_type = implI->valueGetType(res_s); // val_s->id == ABCKIT_TYPE_ID_STRING
AbckitType *u_type = implI->valueGetType(res_u); // val_u->id == ABCKIT_TYPE_ID_U1
AbckitType *d_type = implI->valueGetType(res_d); // val_d->id == ABCKIT_TYPE_ID_F32,
```
# Graph
## *Create and destroy graph*
```cpp
AbckitGraph *graph = implI->createGraphFromFunction(method);
// ...
implM->functionSetGraph(method, graph); // save with changes
// or
impl->destroyGraph(graph); // without changes
```
## *Graph traversal*
```cpp
implG->gVisitBlocksRpo(ctxG, &bbs, [](AbckitBasicBlock *bb, void *data) {
// user lambda
});
```
```cpp
implG->bbVisitSuccBlocks(bb, (void *)&succBBs, []([[maybe_unused]] AbckitBasicBlock *curBasicBlock,
AbckitBasicBlock *succBasicBlock, void *d) {
// user lambda
});
```
```cpp
implG->bbVisitPredBlocks(bb, (void *)&predBBs,
[]([[maybe_unused]] AbckitBasicBlock *curBasicBlock, AbckitBasicBlock *succBasicBlock, void *d) {
// user lambda
});
// ...
```
### *Collect all basic blocks from graph*
```cpp
std::vector<AbckitBasicBlock *> bbs;
implG->gVisitBlocksRPO(ctxG, &bbs, [](AbckitBasicBlock *bb, void *data) {
((std::vector<AbckitBasicBlock *> *)data)->emplace_back(bb);
});
```
### *Collect all inst in basic block*
```cpp
std::vector<AbckitInst *> insts;
for (auto *inst = implG->bbGetFirstInst(bb); inst != nullptr; inst = implG->iGetNext(inst)) {
insts.emplace_back(inst);
}
```
### *Collect block's succs*
```cpp
std::vector<AbckitBasicBlock *> succBBs;
implG->bbVisitSuccBlocks(bb, (void *)&succBBs,
[]([[maybe_unused]] AbckitBasicBlock *curBasicBlock, AbckitBasicBlock *succBasicBlock, void *d) {
auto *succs = (std::vector<AbckitBasicBlock *> *)d;
succs->emplace_back(succBasicBlock);
});
```
## Graph inspecting
### *Get method*
```cpp
AbckitCoreMethod *method = implG->iGetFunction(curInst);
```
## Graph modification
### *Create basic block*
```cpp
AbckitBasicBlock *empty = implG->bbCreateEmpty(ctxG);
```
### *Create insts with const*
```cpp
AbckitInst *new_inst = implG->gCreateConstantI64(ctxG, 1U);
```
### *Connect and disconnect blocks*
<!-- Test: BBcreateEmptyBlock_1 -->
```cpp
auto *start = implG->gGetStartBasicBlock(ctxG);
auto *bb = implG->bbCreateEmpty(ctxG);
implG->bbInsertSuccBlock(start, bb, 0);
implG->bbEraseSuccBlock(start, 0);
```
### *Insert instructions*
```cpp
implG->bbAddInstBack(bb, some_inst_1);
implG->iInsertAfter(some_inst_1, some_inst_2);
```
## Graph-lang
### *Create instructions*
```cpp
// for static
AbckitInst *neg_inst = statG->iCreateNeg(ctxG, new_inst);
AbckitInst *add_inst = statG->iCreateAdd(ctxG, neg_inst, new_inst);
AbckitInst *ret = statG->iCreateReturnVoid(ctxG);
// for dynamic
AbckitInst *neg_inst = dynG->iCreateNeg(ctxG, new_inst);
AbckitInst *add_inst = dynG->iCreateAdd2(ctxG, neg_inst, new_inst);
AbckitInst *ret = dynG->iCreateReturnundefined(ctxG);
```
### *Create 'print("Hello")' for ArkTS1.0*
```cpp
AbckitInst *str = dynG->iCreateLoadString(ctxG, implM->createString(file, "Hello"));
AbckitInst *print = dynG->iCreateTryldglobalbyname(ctxG, implM->createString(file, "print"));
AbckitInst *callArg = dynG->iCreateCallarg1(ctxG, print, str);
```
# User scenarios
### *Enumerate the names of methods from the module*
```cpp
std::vector<std::string> functionNames;
std::function<void(AbckitCoreFunction *)> cbFunc = [&](AbckitCoreFunction *f) {
auto funcName = helpers::AbckitStringToString(implI->functionGetName(f));
functionNames.emplace_back(funcName);
};
std::function<void(AbckitCoreClass *)> cbClass = [&](AbckitCoreClass *c) {
implI->classEnumerateMethods(c, &cbFunc, [](AbckitCoreFunction *m, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreFunction *)> *>(cb))(m);
return true;
});
};
std::function<void(AbckitCoreNamespace *)> cbNamespce;
cbNamespce = [&](AbckitCoreNamespace *n) {
implI->namespaceEnumerateNamespaces(n, &cbNamespce, [](AbckitCoreNamespace *n, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreNamespace *)> *>(cb))(n);
return true;
});
implI->namespaceEnumerateClasses(n, &cbClass, [](AbckitCoreClass *c, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreClass *)> *>(cb))(c);
return true;
});
implI->namespaceEnumerateTopLevelFunctions(n, &cbFunc, [](AbckitCoreFunction *f, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreFunction *)> *>(cb))(f);
return true;
});
};
std::function<void(AbckitCoreModule *)> cbModule = [&](AbckitCoreModule *m) {
implI->moduleEnumerateNamespaces(m, &cbNamespce, [](AbckitCoreNamespace *n, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreNamespace *)> *>(cb))(n);
return true;
});
implI->moduleEnumerateClasses(m, &cbClass, [](AbckitCoreClass *c, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreClass *)> *>(cb))(c);
return true;
});
implI->moduleEnumerateTopLevelFunctions(m, &cbFunc, [](AbckitCoreFunction *m, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreFunction *)> *>(cb))(m);
return true;
});
};
implI->fileEnumerateModules(file, &cbModule, [](AbckitCoreModule *m, void *cb) {
(*reinterpret_cast<std::function<void(AbckitCoreModule *)> *>(cb))(m);
return true;
});
```
### *Collect predecessor basic blocks*
```cpp
std::vector<AbckitBasicBlock *> predBBs;
implG->bbVisitPredBlocks(bb, (void *)&predBBs,
[]([[maybe_unused]] AbckitBasicBlock *curBasicBlock, AbckitBasicBlock *succBasicBlock, void *d) {
auto *preds = (std::vector<AbckitBasicBlock *> *)d;
preds->emplace_back(succBasicBlock);
});
```

View File

@ -0,0 +1,40 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import stylisticJs from '@stylistic/eslint-plugin-js';
export default [
{
plugins: {
'@stylistic/js': stylisticJs,
},
rules: {
'@stylistic/js/semi': ['error', 'always'],
curly: ['error', 'all'],
eqeqeq: ['error', 'always'],
'dot-notation': ['error'],
'no-var': ['error'],
'one-var': ['error', 'never'],
'prefer-rest-params': ['error'],
camelcase: ['error'],
'@stylistic/js/eol-last': ['error', 'always'],
'@stylistic/js/linebreak-style': ['error', 'unix'],
'@stylistic/js/quotes': ['error', 'single'],
},
},
{
selector: 'function',
format: ['camelCase'],
},
];

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_H
#define LIBABCKIT_H
#ifndef __cplusplus
#include <stdbool.h>
#endif
#include "statuses.h"
#ifdef __cplusplus
extern "C" {
#endif
struct AbckitModifyApi;
struct AbckitInspectApi;
struct AbckitGraphApi;
struct AbckitFile;
struct AbckitGraph;
#ifndef __cplusplus
typedef struct AbckitModifyApi AbckitModifyApi;
typedef struct AbckitInspectApi AbckitInspectApi;
typedef struct AbckitGraphApi AbckitGraphApi;
typedef struct AbckitFile AbckitFile;
typedef struct AbckitGraph AbckitGraph;
#endif
enum AbckitApiVersion {
ABCKIT_VERSION_RELEASE_1_0_0,
};
/**
* @brief Struct that holds the pointers to the top-level Abckit API.
*/
struct AbckitApi {
/**
* @brief Version of the Abckit API. Used for versioning the support for certain binary file features.
*/
int apiVersion;
/**
* @brief Returns status of last abckit API call.
* @return `AbckitStatus`.
*/
enum AbckitStatus (*getLastError)(void); // NOLINT(modernize-redundant-void-arg)
/**
* @brief Opens abc file from given `path`.
* @return Pointer to the `AbckitFile`.
* @param [ in ] path - Path to abc file.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `path` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `path` doesn't point to a valid abc file.
* @note Allocates
*/
AbckitFile *(*openAbc)(const char *path);
/**
* @brief Writes `file` to the specified `path`.
* @return None.
* @param [ in ] file - File to write.
* @param [ in ] path - Path where file will be written.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `file` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `path` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `path` is not valid.
* @note Allocates
*/
void (*writeAbc)(AbckitFile *file, const char *path);
/**
* @brief Closes file, frees resources.
* @return None.
* @param [ in ] file - File to close.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `file` is NULL.
*/
void (*closeFile)(AbckitFile *file);
/**
* @brief Destroys graph, frees resources.
* @return None.
* @param [ in ] graph - Graph to destroy.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
void (*destroyGraph)(AbckitGraph *graph);
};
/**
* @brief Instantiates Abckit API.
* @return Instance of the `AbckitApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitApi const *AbckitGetApiImpl(enum AbckitApiVersion version);
#ifdef __cplusplus
}
#endif
#endif /* LIBABCKIT_H */

View File

@ -0,0 +1,705 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_METADATA_ARKTS_H
#define LIBABCKIT_METADATA_ARKTS_H
#ifndef __cplusplus
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#else
#include <cstddef>
#include <cstdint>
#endif /* __cplusplus */
#include "../../metadata_core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct AbckitArktsModule;
struct AbckitArktsNamespace;
struct AbckitArktsClass;
struct AbckitArktsFunction;
struct AbckitArktsField;
struct AbckitArktsAnnotation;
struct AbckitArktsAnnotationElement;
struct AbckitArktsAnnotationInterface;
struct AbckitArktsAnnotationInterfaceField;
struct AbckitArktsImportDescriptor;
struct AbckitArktsExportDescriptor;
#ifndef __cplusplus
typedef struct AbckitArktsModule AbckitArktsModule;
typedef struct AbckitArktsNamespace AbckitArktsNamespace;
typedef struct AbckitArktsClass AbckitArktsClass;
typedef struct AbckitArktsFunction AbckitArktsFunction;
typedef struct AbckitArktsField AbckitArktsField;
typedef struct AbckitArktsAnnotation AbckitArktsAnnotation;
typedef struct AbckitArktsAnnotationElement AbckitArktsAnnotationElement;
typedef struct AbckitArktsAnnotationInterface AbckitArktsAnnotationInterface;
typedef struct AbckitArktsAnnotationInterfaceField AbckitArktsAnnotationInterfaceField;
typedef struct AbckitArktsImportDescriptor AbckitArktsImportDescriptor;
typedef struct AbckitArktsExportDescriptor AbckitArktsExportDescriptor;
#endif /* __cplusplus */
/**
* @brief Struct that holds the pointers to the non-modifying API for Arkts-specific Abckit types.
*/
struct AbckitArktsInspectApi {
/* ========================================
* Language-independent abstractions
* ======================================== */
/* ========================================
* File
* ======================================== */
/* ========================================
* String
* ======================================== */
/* ========================================
* Type
* ======================================== */
/* ========================================
* Value
* ======================================== */
/* ========================================
* Literal
* ======================================== */
/* ========================================
* LiteralArray
* ======================================== */
/* ========================================
* Language-dependent abstractions
* ======================================== */
/* ========================================
* Module
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsModule` to the instance of type `AbckitCoreModule`, which can be
* used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `m`.
* @param [ in ] m - Module to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
*/
AbckitCoreModule *(*arktsModuleToCoreModule)(AbckitArktsModule *m);
/**
* @brief Convert an instance of type `AbckitCoreModule` to the instance of type `AbckitArktsModule`, which can be
* used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `m`.
* @param [ in ] m - Module to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `m` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsModule *(*coreModuleToArktsModule)(AbckitCoreModule *m);
/* ========================================
* Namespace
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsNamespace` to the instance of type `AbckitCoreNamespace`, which
* can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `ns`.
* @param [ in ] ns - Namespace to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ns` is NULL.
*/
AbckitCoreNamespace *(*arktsNamespaceToCoreNamespace)(AbckitArktsNamespace *ns);
/**
* @brief Convert an instance of type `AbckitCoreNamespace` to the instance of type `AbckitArktsNamespace`, which
* can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `ns`.
* @param [ in ] ns - Namespace to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ns` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `ns` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsNamespace *(*coreNamespaceToArktsNamespace)(AbckitCoreNamespace *ns);
/**
* @brief Returns constructor function for namespace.
* @return Function that is invoked upon namespace `ns` construction.
* @param [ in ] ns - Namespace to get the constructor function for.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ns` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `ns` is does not have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
AbckitArktsFunction *(*arktsV1NamespaceGetConstructor)(AbckitArktsNamespace *ns);
/* ========================================
* ImportDescriptor
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsImportDescriptorToCoreImportDescrip` to the instance of type `r`,
* which can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `id`.
* @param [ in ] id - Import descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
*/
AbckitCoreImportDescriptor *(*arktsImportDescriptorToCoreImportDescriptor)(AbckitArktsImportDescriptor *id);
/**
* @brief Convert an instance of type `AbckitCoreImportDescriptorToArktsImportDescrip` to the instance of type `r`,
* which can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `id`.
* @param [ in ] id - Import descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `id` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsImportDescriptor *(*coreImportDescriptorToArktsImportDescriptor)(AbckitCoreImportDescriptor *id);
/* ========================================
* ExportDescriptor
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsExportDescriptorToCoreExportDescrip` to the instance of type `r`,
* which can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `ed`.
* @param [ in ] ed - Export descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
*/
AbckitCoreExportDescriptor *(*arktsExportDescriptorToCoreExportDescriptor)(AbckitArktsExportDescriptor *ed);
/**
* @brief Convert an instance of type `AbckitCoreExportDescriptorToArktsExportDescrip` to the instance of type `r`,
* which can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `ed`.
* @param [ in ] ed - Export descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `ed` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsExportDescriptor *(*coreExportDescriptorToArktsExportDescriptor)(AbckitCoreExportDescriptor *ed);
/* ========================================
* Class
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsClass` to the instance of type `AbckitCoreClass`, which can be
* used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `klass`.
* @param [ in ] klass - Class to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `klass` is NULL.
*/
AbckitCoreClass *(*arktsClassToCoreClass)(AbckitArktsClass *klass);
/**
* @brief Convert an instance of type `AbckitCoreClass` to the instance of type `AbckitArktsClass`, which can be
* used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `klass`.
* @param [ in ] klass - Class to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `klass` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `klass` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsClass *(*coreClassToArktsClass)(AbckitCoreClass *klass);
/* ========================================
* Function
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsFunction` to the instance of type `AbckitCoreFunction`, which can
* be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `function`.
* @param [ in ] function - Function to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
*/
AbckitCoreFunction *(*arktsFunctionToCoreFunction)(AbckitArktsFunction *function);
/**
* @brief Convert an instance of type `AbckitCoreFunction` to the instance of type `AbckitArktsFunction`, which can
* be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `function`.
* @param [ in ] function - Function to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `function` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsFunction *(*coreFunctionToArktsFunction)(AbckitCoreFunction *function);
/**
* @brief Check whether the `function` is native.
* @return `true` if `function` is native, `false` otherwise.
* @param [ in ] function - Function to inspect.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
*/
bool (*functionIsNative)(AbckitArktsFunction *function);
/* ========================================
* Annotation
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsAnnotation` to the instance of type `AbckitCoreAnnotation`, which
* can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `anno`.
* @param [ in ] anno - Annotation to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
*/
AbckitCoreAnnotation *(*arktsAnnotationToCoreAnnotation)(AbckitArktsAnnotation *anno);
/**
* @brief Convert an instance of type `AbckitCoreAnnotation` to the instance of type `AbckitArktsAnnotation`, which
* can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `anno`.
* @param [ in ] anno - Annotation to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `anno` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsAnnotation *(*coreAnnotationToArktsAnnotation)(AbckitCoreAnnotation *anno);
/* ========================================
* AnnotationElement
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsAnnotationElement` to the instance of type
* `AbckitCoreAnnotationElement`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `annoElem`.
* @param [ in ] annoElem - Annotation element to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoElem` is NULL.
*/
AbckitCoreAnnotationElement *(*arktsAnnotationElementToCoreAnnotationElement)(
AbckitArktsAnnotationElement *annoElem);
/**
* @brief Convert an instance of type `AbckitCoreAnnotationElement` to the instance of type
* `AbckitArktsAnnotationElement`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `annoElem`.
* @param [ in ] annoElem - Annotation element to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoElem` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `annoElem` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsAnnotationElement *(*coreAnnotationElementToArktsAnnotationElement)(
AbckitCoreAnnotationElement *annoElem);
/* ========================================
* AnnotationInterface
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsAnnotationInterface` to the instance of type
* `AbckitCoreAnnotationInterface`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `annoInterface`.
* @param [ in ] annoInterface - Annotataion interface to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoInterface` is NULL.
*/
AbckitCoreAnnotationInterface *(*arktsAnnotationInterfaceToCoreAnnotationInterface)(
AbckitArktsAnnotationInterface *annoInterface);
/**
* @brief Convert an instance of type `AbckitCoreAnnotationInterface` to the instance of type
* `AbckitArktsAnnotationInterface`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `annoInterface`.
* @param [ in ] annoInterface - Annotataion interface to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoInterface` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `annoInterface` is does not have `ABCKIT_TARGET_ARK_TS_V1` or
* `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsAnnotationInterface *(*coreAnnotationInterfaceToArktsAnnotationInterface)(
AbckitCoreAnnotationInterface *annoInterface);
/* ========================================
* AnnotationInterfaceField
* ======================================== */
/**
* @brief Convert an instance of type `AbckitArktsAnnotationInterfaceField` to the instance of type
* `AbckitCoreAnnotationInterfaceField`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-independent representation of the `annoInterfaceField`.
* @param [ in ] annoInterfaceField - Annotation inteface field to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoInterfaceField` is NULL.
*/
AbckitCoreAnnotationInterfaceField *(*arktsAnnotationInterfaceFieldToCoreAnnotationInterfaceField)(
AbckitArktsAnnotationInterfaceField *annoInterfaceField);
/**
* @brief Convert an instance of type `AbckitCoreAnnotationInterfaceField` to the instance of type
* `AbckitArktsAnnotationInterfaceField`, which can be used to invoke the corresponding APIs.
* @return Pointer to the language-dependent representation of the `annoInterfaceField`.
* @param [ in ] annoInterfaceField - Annotation inteface field to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `annoInterfaceField` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `annoInterfaceField` is does not have `ABCKIT_TARGET_ARK_TS_V1`
* or `ABCKIT_TARGET_ARK_TS_V2` target.
*/
AbckitArktsAnnotationInterfaceField *(*coreAnnotationInterfaceFieldToArktsAnnotationInterfaceField)(
AbckitCoreAnnotationInterfaceField *annoInterfaceField);
};
/**
* @brief Struct that is used to create new annotation interfaces.
*/
struct AbckitArktsAnnotationInterfaceCreateParams {
/**
* @brief Name of the created annotation interface.
*/
const char *name;
};
/**
* @brief Struct that is used to create new annotation interface fields.
*/
struct AbckitArktsAnnotationInterfaceFieldCreateParams {
/**
* @brief Name of the created annotation interface field.
*/
const char *name;
/**
* @brief Type of the created annotation interface field.
*/
AbckitType *type;
/**
* @brief Default value of the created annotation interface field. Leave as NULL for no default value.
*/
AbckitValue *defaultValue;
};
/**
* @brief Struct that is used to create new annotations.
*/
struct AbckitArktsAnnotationCreateParams {
/**
* @brief Annotation interface that created annotation instantiates.
*/
AbckitArktsAnnotationInterface *ai;
};
/**
* @brief Struct that is used to create new annotation elements.
*/
struct AbckitArktsAnnotationElementCreateParams {
/**
* @brief Name of the created annotation element. Must be equal to one of the fields of the corresponding annotation
* interface.
*/
const char *name;
/**
* @brief Value that should be assigned to the annotation element.
*/
AbckitValue *value;
};
/**
* @brief Struct that is used to create new imports.
*/
struct AbckitArktsImportFromDynamicModuleCreateParams {
/**
* @brief Import name. For namespace imports equals to "*". For default imports equals to "default". For regular
* imports is the same as in user code.
*/
const char *name;
/**
* @brief Alias name for the import. For namespace imports is the same as in user code. For delault import is the
* same as the default import name in user code. For regular imports is the same as in user code.
*/
const char *alias;
};
/**
* @brief Struct that is used to create new exports.
*/
struct AbckitArktsDynamicModuleExportCreateParams {
/**
* @brief Name of the entity that should be exported. For star exports equals to "*". For indirect exports is the
* same as in user code. For local exports is the same as in user code.
*/
const char *name;
/**
* @brief Alias under which entity should be exported. For star exports equals nullptr. For indirect exports is the
* same as in user code. For local exports is the same as in user code.
*/
const char *alias;
};
/**
* @brief Struct that is used to create new external modules.
*/
struct AbckitArktsExternalModuleCreateParams {
/**
* @brief Name of the created external module
*/
const char *name;
};
/**
* @brief Struct that holds the pointers to the modifying API for Arkts-specific Abckit types.
*/
struct AbckitArktsModifyApi {
/* ========================================
* File
* ======================================== */
/**
* @brief Creates an external Arkts module and adds it to the file `file`.
* @return AbckitArktsModule *.
* @param [ in ] file - Binary file to .
* @param [ in ] params - Data that is used to create the external module.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `file` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Allocates
*/
AbckitArktsModule *(*fileAddExternalModule)(AbckitFile *file,
const struct AbckitArktsExternalModuleCreateParams *params);
/* ========================================
* Module
* ======================================== */
/**
* @brief Adds import from one Arkts module to another Arkts module.
* @return Pointer to the newly created import descriptor.
* @param [ in ] importing - Importing module.
* @param [ in ] imported - The module the `importing` module imports from.
* @param [ in ] params - Data that is used to create the import.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `importing` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `imported` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Allocates
*/
AbckitArktsImportDescriptor *(*moduleAddImportFromArktsV1ToArktsV1)(
AbckitArktsModule *importing, AbckitArktsModule *imported,
const struct AbckitArktsImportFromDynamicModuleCreateParams *params);
/**
* @brief Removes import `id` from module `m`.
* @return None.
* @param [ in ] m - Module to remove the import `id` from.
* @param [ in ] id - Import to remove from the module `m`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if module `m` does not have the import descriptor `id`.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if module `m` doesn;t have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
void (*moduleRemoveImport)(AbckitArktsModule *m, AbckitArktsImportDescriptor *id);
/**
* @brief Adds export from one Arkts module to another Arkts module.
* @return Pointer to the newly created export descriptor.
* @param [ in ] exporting - The module to add export to.
* @param [ in ] exported - The module the entity is exported from. In case of local export is the same as
* `exporting`.
* @param [ in ] params - Data that is used to create the export.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `exporting` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `exported` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if module `m` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
* @note Allocates
*/
AbckitArktsExportDescriptor *(*moduleAddExportFromArktsV1ToArktsV1)(
AbckitArktsModule *exporting, AbckitArktsModule *exported,
const struct AbckitArktsDynamicModuleExportCreateParams *params);
/**
* @brief Removes export `ed` from module `m`.
* @return None.
* @param [ in ] m - Module to remove the export `e` from.
* @param [ in ] ed - Export to remove from the module `m`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if module `m` does not have the export descriptor `ed`.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if module `m` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
void (*moduleRemoveExport)(AbckitArktsModule *m, AbckitArktsExportDescriptor *ed);
/**
* @brief Adds new annotation interface to the module `m`.
* @return Pointer to the newly constructed annotation interface.
* @param [ in ] m - Module to add annotation interface to.
* @param [ in ] params - Data that is used to create the annotation interface.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if module `m` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
* @note Allocates
*/
AbckitArktsAnnotationInterface *(*moduleAddAnnotationInterface)(
AbckitArktsModule *m, const struct AbckitArktsAnnotationInterfaceCreateParams *params);
/* ========================================
* Class
* ======================================== */
/**
* @brief Add annotation to the class declaration.
* @return Pointer to the newly created annotation.
* @param [ in ] klass - Class to add annotation to.
* @param [ in ] params - Data that is used to create the annotation.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `klass` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if class `klass` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
* @note Allocates
*/
AbckitArktsAnnotation *(*classAddAnnotation)(AbckitArktsClass *klass,
const struct AbckitArktsAnnotationCreateParams *params);
/**
* @brief Remove annotation from the class declaration.
* @return None.
* @param [ in ] klass - Class to remove annotation from.
* @param [ in ] anno - Annotation to remove.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `klass` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if class `klass` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
void (*classRemoveAnnotation)(AbckitArktsClass *klass, AbckitArktsAnnotation *anno);
/* ========================================
* AnnotationInterface
* ======================================== */
/**
* @brief Add new field to the annotation interface.
* @return Pointer to the newly created annotation field.
* @param [ in ] ai - Annotation interface to add new field to.
* @param [ in ] params - Data that is used to create the field of the annotation interface `ai`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ai` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if annotation interface `ai` doesn't have `ABCKIT_TARGET_ARK_TS_V1`
* target.
* @note Allocates
*/
AbckitArktsAnnotationInterfaceField *(*annotationInterfaceAddField)(
AbckitArktsAnnotationInterface *ai, const struct AbckitArktsAnnotationInterfaceFieldCreateParams *params);
/**
* @brief Remove field from the annotation interface.
* @return None.
* @param [ in ] ai - Annotation interface to remove the field `field` from.
* @param [ in ] field - Field to remove from the annotation interface `ai`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ai` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `field` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if annotation interface `ai` doesn't have `ABCKIT_TARGET_ARK_TS_V1`
* target.
* @note Set `ABCKIT_STATUS_TODO` error if annotation interface `ai` does not have the field `field`.
*/
void (*annotationInterfaceRemoveField)(AbckitArktsAnnotationInterface *ai,
AbckitArktsAnnotationInterfaceField *field);
/* ========================================
* Function
* ======================================== */
/**
* @brief Function to add annotation to.
* @return Pointer to the newly created annotation.
* @param [ in ] function - Function to add annotation to.
* @param [ in ] params - Data that is used to create the annotation.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if function `function` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
* @note Allocates
*/
AbckitArktsAnnotation *(*functionAddAnnotation)(AbckitArktsFunction *function,
const struct AbckitArktsAnnotationCreateParams *params);
/**
* @brief Remove annotation from the function.
* @return None.
* @param [ in ] function - Function to remove annotation `anno` from.
* @param [ in ] anno - Annotation to remove from the function `function`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if function `function` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
void (*functionRemoveAnnotation)(AbckitArktsFunction *function, AbckitArktsAnnotation *anno);
/* ========================================
* Annotation
* ======================================== */
/**
* @brief Add annotation element to the existing annotation.
* @return Pointer to the newly created annotation element.
* @param [ in ] anno - Annotation to add new element to.
* @param [ in ] params - Data that is used to create the annotation element.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if annotation `anno` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
* @note Allocates
*/
AbckitArktsAnnotationElement *(*annotationAddAnnotationElement)(
AbckitArktsAnnotation *anno, struct AbckitArktsAnnotationElementCreateParams *params);
/**
* @brief Remove annotation element `elem` from the annotation `anno`.
* @return None.
* @param [ in ] anno - Annotation to remove the annotataion element `elem` from.
* @param [ in ] elem - Annotation element to remove from the annotation `anno`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `anno` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `elem` is NULL.
* @note Set `ABCKIT_STATUS_UNSUPPORTED` error if annotation `anno` doesn't have `ABCKIT_TARGET_ARK_TS_V1` target.
*/
void (*annotationRemoveAnnotationElement)(AbckitArktsAnnotation *anno, AbckitArktsAnnotationElement *elem);
/* ========================================
* Type
* ======================================== */
/* ========================================
* Value
* ======================================== */
/* ========================================
* String
* ======================================== */
/* ========================================
* LiteralArray
* ======================================== */
/* ========================================
* Literal
* ======================================== */
};
/**
* @brief Instantiates non-modifying API for Arkts-specific Abckit types.
* @return Instance of the `AbckitApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitArktsInspectApi const *AbckitGetArktsInspectApiImpl(enum AbckitApiVersion version);
/**
* @brief Instantiates modifying API for Arkts-specific Abckit types.
* @return Instance of the `AbckitApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitArktsModifyApi const *AbckitGetArktsModifyApiImpl(enum AbckitApiVersion version);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !LIBABCKIT_METADATA_ARKTS_H */

View File

@ -0,0 +1,395 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_METADATA_JS_H
#define LIBABCKIT_METADATA_JS_H
#ifndef __cplusplus
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#else
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#endif /* __cplusplus */
#include "../../metadata_core.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct AbckitJsModule;
struct AbckitJsClass;
struct AbckitJsFunction;
struct AbckitJsImportDescriptor;
struct AbckitJsExportDescriptor;
#ifndef __cplusplus
typedef struct AbckitJsModule AbckitJsModule;
typedef struct AbckitJsClass AbckitJsClass;
typedef struct AbckitJsFunction AbckitJsFunction;
typedef struct AbckitJsImportDescriptor AbckitJsImportDescriptor;
typedef struct AbckitJsExportDescriptor AbckitJsExportDescriptor;
#endif /* __cplusplus */
/**
* @brief Struct that holds the pointers to the non-modifying API for Js-specific Abckit types.
*/
struct AbckitJsInspectApi {
/* ========================================
* Language-independent abstractions
* ======================================== */
/* ========================================
* File
* ======================================== */
/* ========================================
* String
* ======================================== */
/* ========================================
* Type
* ======================================== */
/* ========================================
* Value
* ======================================== */
/* ========================================
* Literal
* ======================================== */
/* ========================================
* LiteralArray
* ======================================== */
/* ========================================
* Language-dependent abstractions
* ======================================== */
/* ========================================
* Module
* ======================================== */
/**
* @brief Convert an instance of type `AbckitJsModule` to the instance of type `AbckitCoreModule`, which can be used
* to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-independent representation of the `m`.
* @param [ in ] m - Module to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
*/
AbckitCoreModule *(*jsModuleToCoreModule)(AbckitJsModule *m);
/**
* @brief Convert an instance of type `AbckitCoreModule` to the instance of type `AbckitJsModule`, which can be used
* to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-dependent representation of the `m`.
* @param [ in ] m - Module to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `m` is does not have `ABCKIT_TARGET_JS` target.
*/
AbckitJsModule *(*coreModuleToJsModule)(AbckitCoreModule *m);
/* ========================================
* ImportDescriptor
* ======================================== */
/**
* @brief Convert an instance of type `AbckitJsImportDescriptor` to the instance of type
* `AbckitCoreImportDescriptor`, which can be used to invoke the corresponding APIs. The original pointer can still
* be used after the conversion.
* @return Pointer to the language-independent representation of the `id`.
* @param [ in ] id - Import descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
*/
AbckitCoreImportDescriptor *(*jsImportDescriptorToCoreImportDescriptor)(AbckitJsImportDescriptor *id);
/**
* @brief Convert an instance of type `AbckitCoreImportDescriptor` to the instance of type
* `AbckitJsImportDescriptor`, which can be used to invoke the corresponding APIs. The original pointer can still be
* used after the conversion.
* @return Pointer to the language-dependent representation of the `id`.
* @param [ in ] id - Import descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `id` is does not have `ABCKIT_TARGET_JS` target.
*/
AbckitJsImportDescriptor *(*coreImportDescriptorToJsImportDescriptor)(AbckitCoreImportDescriptor *id);
/* ========================================
* ExportDescriptor
* ======================================== */
/**
* @brief Convert an instance of type `AbckitJsExportDescriptor` to the instance of type
* `AbckitCoreExportDescriptor`, which can be used to invoke the corresponding APIs. The original pointer can still
* be used after the conversion.
* @return Pointer to the language-independent representation of the `ed`.
* @param [ in ] ed - Export descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
*/
AbckitCoreExportDescriptor *(*jsExportDescriptorToCoreExportDescriptor)(AbckitJsExportDescriptor *ed);
/**
* @brief Convert an instance of type `AbckitCoreExportDescriptor` to the instance of type
* `AbckitJsExportDescriptor`, which can be used to invoke the corresponding APIs. The original pointer can still be
* used after the conversion.
* @return Pointer to the language-dependent representation of the `ed`.
* @param [ in ] ed - Export descriptor to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `ed` is does not have `ABCKIT_TARGET_JS` target.
*/
AbckitJsExportDescriptor *(*coreExportDescriptorToJsExportDescriptor)(AbckitCoreExportDescriptor *ed);
/* ========================================
* Class
* ======================================== */
/**
* @brief Convert an instance of type `AbckitJsClass` to the instance of type `AbckitCoreClass`, which can be used
* to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-independent representation of the `c`.
* @param [ in ] c - Class to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `c` is NULL.
*/
AbckitCoreClass *(*jsClassToCoreClass)(AbckitJsClass *c);
/**
* @brief Convert an instance of type `AbckitCoreClass` to the instance of type `AbckitJsClass`, which can be used
* to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-dependent representation of the `c`.
* @param [ in ] c - Class to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `c` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `c` is does not have `ABCKIT_TARGET_JS` target.
*/
AbckitJsClass *(*coreClassToJsClass)(AbckitCoreClass *c);
/* ========================================
* Function
* ======================================== */
/**
* @brief Convert an instance of type `AbckitJsFunction` to the instance of type `AbckitCoreFunction`, which can be
* used to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-independent representation of the `f`.
* @param [ in ] f - Function to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `f` is NULL.
*/
AbckitCoreFunction *(*jsFunctionToCoreFunction)(AbckitJsFunction *f);
/**
* @brief Convert an instance of type `AbckitCoreFunction` to the instance of type `AbckitJsFunction`, which can be
* used to invoke the corresponding APIs. The original pointer can still be used after the conversion.
* @return Pointer to the language-dependent representation of the `f`.
* @param [ in ] f - Function to convert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `f` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_TARGET` error if `f` is does not have `ABCKIT_TARGET_JS` target.
*/
AbckitJsFunction *(*coreFunctionToJsFunction)(AbckitCoreFunction *f);
/* ========================================
* Annotation
* ======================================== */
/* ========================================
* AnnotationElement
* ======================================== */
/* ========================================
* AnnotationInterface
* ======================================== */
/* ========================================
* AnnotationInterfaceField
* ======================================== */
};
/**
* @brief Struct that is used to create new imports.
*/
struct AbckitJsImportFromDynamicModuleCreateParams {
/**
* @brief Import name. For namespace imports equals to "*". For default imports equals to "default". For regular
* imports is the same as in user code.
*/
const char *name;
/**
* @brief Alias name for the import. For namespace imports is the same as in user code. For delault import is the
* same as the default import name in user code. For regular imports is the same as in user code.
*/
const char *alias;
};
/**
* @brief Struct that is used to create new exports.
*/
struct AbckitJsDynamicModuleExportCreateParams {
/**
* @brief Name of the entity that should be exported. For star exports equals to "*". For indirect exports is the
* same as in user code. For local exports is the same as in user code.
*/
const char *name;
/**
* @brief Alias under which entity should be exported. For star exports equals nullptr. For indirect exports is the
* same as in user code. For local exports is the same as in user code.
*/
const char *alias;
};
/**
* @brief Struct that is used to create new external modules.
*/
struct AbckitJsExternalModuleCreateParams {
/**
* @brief Name of the external module.
*/
const char *name;
};
/**
* @brief Struct that holds the pointers to the modifying API for Js-specific Abckit types.
*/
struct AbckitJsModifyApi {
/* ========================================
* File
* ======================================== */
/**
* @brief Creates an external Js module and adds it to the file `file`.
* @return Pointer to the created module.
* @param [ in ] file - Binary file to add the external module to.
* @param [ in ] params - Data that is used to create the external module.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `file` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Allocates
*/
AbckitJsModule *(*fileAddExternalModule)(AbckitFile *file, const struct AbckitJsExternalModuleCreateParams *params);
/* ========================================
* Module
* ======================================== */
/**
* @brief Adds import from one Js module to another Js module.
* @return Pointer to the newly created import descriptor.
* @param [ in ] importing - Importing module.
* @param [ in ] imported - The module the `importing` module imports from.
* @param [ in ] params - Data that is used to create the import.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `importing` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `imported` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Allocates
*/
AbckitJsImportDescriptor *(*moduleAddImportFromJsToJs)(
AbckitJsModule *importing, AbckitJsModule *imported,
const struct AbckitJsImportFromDynamicModuleCreateParams *params);
/**
* @brief Removes import `id` from module `m`.
* @return None.
* @param [ in ] m - The module to remove the import `id` from.
* @param [ in ] id - Import to remove from the module `m`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `id` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if module `m` does not have the import descriptor `id`.
*/
void (*moduleRemoveImport)(AbckitJsModule *m, AbckitJsImportDescriptor *id);
/**
* @brief Adds export to the Js module.
* @return Pointer to the newly created export descriptor.
* @param [ in ] exporting - The module to add export to.
* @param [ in ] exported - The module the entity is exported from. In case of local export is the same as
* `exporting`.
* @param [ in ] params - Data that is used to create the export.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `exporting` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `exported` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `params` is NULL.
* @note Allocates
*/
AbckitJsExportDescriptor *(*moduleAddExportFromJsToJs)(
AbckitJsModule *exporting, AbckitJsModule *exported,
const struct AbckitJsDynamicModuleExportCreateParams *params);
/**
* @brief Removes export `ed` from module `m`.
* @return None.
* @param [ in ] m - Module to remove the export `ed` from.
* @param [ in ] ed - Export to remove from the module `m`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `m` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ed` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if module `m` does not have the export descriptor `ed`.
*/
void (*moduleRemoveExport)(AbckitJsModule *m, AbckitJsExportDescriptor *ed);
/* ========================================
* Class
* ======================================== */
/* ========================================
* AnnotationInterface
* ======================================== */
/* ========================================
* Function
* ======================================== */
/* ========================================
* Annotation
* ======================================== */
/* ========================================
* Type
* ======================================== */
/* ========================================
* Value
* ======================================== */
/* ========================================
* String
* ======================================== */
/* ========================================
* LiteralArray
* ======================================== */
/* ========================================
* Literal
* ======================================== */
};
/**
* @brief Instantiates non-modifying API for Js-specific Abckit types.
* @return Instance of the `AbckitApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitJsInspectApi const *AbckitGetJsInspectApiImpl(enum AbckitApiVersion version);
/**
* @brief Instantiates modifying API for Js-specific Abckit types.
* @return Instance of the `AbckitApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitJsModifyApi const *AbckitGetJsModifyApiImpl(enum AbckitApiVersion version);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !LIBABCKIT_METADATA_JS_H */

View File

@ -0,0 +1,917 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_IR_H
#define LIBABCKIT_IR_H
#ifndef __cplusplus
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#else
#include <cstddef>
#include <cstdint>
#endif
#include "metadata_core.h"
#ifdef __cplusplus
extern "C" {
#endif
enum AbckitIsaType {
/*
* For invalid input.
*/
ABCKIT_ISA_TYPE_UNSUPPORTED,
/*
* For .abc files that use mainline ISA.
*/
ABCKIT_ISA_TYPE_DYNAMIC,
/*
* Reserved for future versions.
*/
ABCKIT_ISA_TYPE_STATIC,
};
struct AbckitGraph;
struct AbckitBasicBlock;
struct AbckitInst;
#ifndef __cplusplus
typedef struct AbckitGraph AbckitGraph;
typedef struct AbckitBasicBlock AbckitBasicBlock;
typedef struct AbckitInst AbckitInst;
#endif
enum { ABCKIT_TRUE_SUCC_IDX = 0, ABCKIT_FALSE_SUCC_IDX = 1 };
/**
* @brief Struct that holds the pointers to the graph manipulation API.
*/
struct AbckitGraphApi {
/**
* @brief Returns ISA type for given graph.
* @return ISA of the graph.
* @param [ in ] graph - Graph to read ISA type from.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
enum AbckitIsaType (*gGetIsa)(AbckitGraph *graph);
/**
* @brief Returns binary file from which the given `graph` was created.
* @return Pointer to the `AbckitFile` from which given `graph` was created.
* @param [ in ] graph - Graph to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
AbckitFile *(*gGetFile)(AbckitGraph *graph);
/* ========================================
* Api for Graph manipulation
* ======================================== */
/**
* @brief Returns start basic block of given `graph`.
* @return Pointer to start `AbckitBasicBlock`.
* @param [ in ] graph - Graph to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
AbckitBasicBlock *(*gGetStartBasicBlock)(AbckitGraph *graph);
/**
* @brief Returns end basic block of given `graph`.
* @return Pointer to end `AbckitBasicBlock`.
* @param [ in ] graph - Graph to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
AbckitBasicBlock *(*gGetEndBasicBlock)(AbckitGraph *graph);
/**
* @brief Returns number of basic blocks in given `graph`.
* @return Number of basic blocks in given `graph`.
* @param [ in ] graph - Graph to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
uint32_t (*gGetNumberOfBasicBlocks)(AbckitGraph *graph);
/**
* @brief Enumerates basic blocks of the `graph` in reverse postorder, invoking callback `cb` for each basic block.
* @return None.
* @param [ in ] graph - Graph to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*gVisitBlocksRpo)(AbckitGraph *graph, void *data, void (*cb)(AbckitBasicBlock *basicBlock, void *data));
/**
* @brief Returns basic blocks with given `id` of the given `graph`.
* @return Pointer to the `AbckitBasicBlock` with given `id`.
* @param [ in ] graph - Graph to be inspected.
* @param [ in ] id - ID of basic block.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no basic block with given `id` in `graph`.
*/
AbckitBasicBlock *(*gGetBasicBlock)(AbckitGraph *graph, uint32_t id);
/**
* @brief Returns parameter instruction under given `index` of the given `graph`.
* @return Pointer to the `AbckitInst` corresponding to parameter under given `index`.
* @param [ in ] graph - Graph to be inspected.
* @param [ in ] index - Index of the parameter.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no parameter under given `index` in `graph`.
*/
AbckitInst *(*gGetParameter)(AbckitGraph *graph, uint32_t index);
/**
* @brief Wraps basic blocks from `tryFirstBB` to `tryLastBB` into try,
* inserts basic blocks from `catchBeginBB` to `catchEndBB` into graph.
* Basic blocks from `catchBeginBB` to `catchEndBB` are used for exception handling.
* @return None.
* @param [ in ] tryFirstBB - Start basic block to wrap into try.
* @param [ in ] tryLastBB - End basic block to wrap into try.
* @param [ in ] catchBeginBB - Start basic block to handle exception.
* @param [ in ] catchEndBB - End basic block to handle exception.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `tryFirstBB` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `tryLastBB` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `catchBeginBB` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `catchEndBB` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning input basic blocks differs.
*/
void (*gInsertTryCatch)(AbckitBasicBlock *tryFirstBB, AbckitBasicBlock *tryLastBB, AbckitBasicBlock *catchBeginBB,
AbckitBasicBlock *catchEndBB);
/**
* @brief Dumps given `graph` into given file descriptor.
* @return None.
* @param [ in ] graph - Graph to be inspected.
* @param [ in ] fd - File descriptor where dump is written.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
void (*gDump)(AbckitGraph *graph, int32_t fd);
/**
* @brief Creates I32 constant instruction and inserts it in start basic block of given `graph`.
* @return Pointer to created `AbckitInst`.
* @param [ in ] graph - Graph in which instruction is inserted.
* @param [ in ] value - value of created constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
AbckitInst *(*gCreateConstantI32)(AbckitGraph *graph, int32_t value);
/**
* @brief Creates I64 constant instruction and inserts it in start basic block of given `graph`.
* @return Pointer to created `AbckitInst`.
* @param [ in ] graph - Graph in which instruction is inserted.
* @param [ in ] value - value of created constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
AbckitInst *(*gCreateConstantI64)(AbckitGraph *graph, int64_t value);
/**
* @brief Creates U64 constant instruction and inserts it in start basic block of given `graph`.
* @return Pointer to created `AbckitInst`.
* @param [ in ] graph - Graph in which instruction is inserted.
* @param [ in ] value - value of created constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
AbckitInst *(*gCreateConstantU64)(AbckitGraph *graph, uint64_t value);
/**
* @brief Creates F64 constant instruction and inserts it in start basic block of given `graph`.
* @return Pointer to created `AbckitInst`.
* @param [ in ] graph - Graph in which instruction is inserted.
* @param [ in ] value - value of created constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
AbckitInst *(*gCreateConstantF64)(AbckitGraph *graph, double value);
/**
* @brief Removes all basic blocks unreachable from start basic block.
* @return None.
* @param [ in ] graph - Graph to be modified.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
*/
void (*gRunPassRemoveUnreachableBlocks)(AbckitGraph *graph);
/* ========================================
* Api for basic block manipulation
* ======================================== */
/**
* @brief Creates empty basic block.
* @return Pointer to the created `AbckitBasicBlock`.
* @param [ in ] graph - Graph for which basic block is created.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `graph` is NULL.
* @note Allocates
*/
AbckitBasicBlock *(*bbCreateEmpty)(AbckitGraph *graph);
/**
* @brief Returns ID of given `basicBlock`.
* @return ID of given `basicBlock`.
* @param [ in ] basicBlock - basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
uint32_t (*bbGetId)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns graph owning given `basicBlock`.
* @return Pointer to `AbckitGraph`.
* @param [ in ] basicBlock - basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
AbckitGraph *(*bbGetGraph)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns the number of basic blocks preceding the given `basicBlock`.
* @return Number of predecessor basic blocks.
* @param [ in ] basicBlock - basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
uint64_t (*bbGetPredBlockCount)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns basic block predcessing to `basicBlock` under given `index`.
* @return Pointer to the `AbckitBasicBlock`.
* @param [ in ] basicBlock - basic block to be inspected.
* @param [ in ] index - Index of predecessor basic block.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no predecessor basic block under given `index`.
*/
AbckitBasicBlock *(*bbGetPredBlock)(AbckitBasicBlock *basicBlock, uint32_t index);
/**
* @brief Enumerates basic blocks preceding to the given `basicBlock`, invoking callback `cb` for each basic
* block.
* @return None.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*bbVisitPredBlocks)(AbckitBasicBlock *basicBlock, void *data,
void (*cb)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *predBasicBlock, void *data));
/**
* @brief Returns the number of basic blocks successing the given `basicBlock`.
* @return Number of successor basic blocks.
* @param [ in ] basicBlock - basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
uint64_t (*bbGetSuccBlockCount)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns basic block successing to `basicBlock` under given `index`.
* @return Pointer to the `AbckitBasicBlock`.
* @param [ in ] basicBlock - basic block to be inspected.
* @param [ in ] index - Index of successor basic block.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if there is no successor basic block under given `index`.
*/
AbckitBasicBlock *(*bbGetSuccBlock)(AbckitBasicBlock *basicBlock, uint32_t index);
/**
* @brief Inserts `succBlock` by `index` in `basicBlock` successors list
* and shifts the rest if there were successors with a larger index.
* @return None.
* @param [ in ] basicBlock - Basic block for which successor will be inserted.
* @param [ in ] succBlock - Basic block to be inserted.
* @param [ in ] index - Index by which the `succBlock` will be inserted.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `succBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` is larger than quantity of `basicBlock` successors.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning `basicBlock` and `succBlock`
* differs.
* @note Allocates
*/
void (*bbInsertSuccBlock)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock, uint32_t index);
/**
* @brief Appends successor to the end of `basicBlock` successors list.
* @return None.
* @param [ in ] basicBlock - Basic block for which successor will be inserted.
* @param [ in ] succBlock - Basic block to be inserted.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `succBlock` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning `basicBlock` and `succBlock`
* differs.
*/
void (*bbAppendSuccBlock)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBlock);
/**
* @brief Deletes the successor and shifts the rest if there were successors with a larger index.
* @return None.
* @param [ in ] basicBlock - Basic block for which successor will be deleted.
* @param [ in ] index - Index of successor to be deleted.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` is larger than `basicBlock` successors quantity.
*/
void (*bbEraseSuccBlock)(AbckitBasicBlock *basicBlock, uint32_t index);
/**
* @brief Enumerates basic blocks successing to the given `basicBlock`, invoking callback `cb` for each basic block.
* @return None.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*bbVisitSuccBlocks)(AbckitBasicBlock *basicBlock, void *data,
void (*cb)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *succBasicBlock, void *data));
/**
* @brief Returns successor of `basicBlock` with index 0.
* @return Pinter to the `AbckitBasicBlock`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` has no successors.
*/
AbckitBasicBlock *(*bbGetTrueBranch)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns successor of `basicBlock` with index 1.
* @return Pinter to the `AbckitBasicBlock`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` has less than one successor.
*/
AbckitBasicBlock *(*bbGetFalseBranch)(AbckitBasicBlock *basicBlock);
/**
* @brief Creates new basic block and moves all instructions after `inst` into new basic block.
* @return Pointer to newly create `AbckitBasicBlock`.
* @param [ in ] inst - Instruction after which all instructions will be moved into new basic block.
* @param [ in ] makeEdge - If `true` connects old and new basic blocks.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Allocates
*/
AbckitBasicBlock *(*bbSplitBlockAfterInstruction)(AbckitInst *inst, bool makeEdge);
/**
* @brief Insert `inst` at the beginning of `basicBlock`.
* @return None.
* @param [ in ] basicBlock - Block for which instruction is appended.
* @param [ in ] inst - Instruction to insert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is constant.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning `basicBlock` and `inst`
* differs.
* @note Allocates
*/
void (*bbAddInstFront)(AbckitBasicBlock *basicBlock, AbckitInst *inst);
/**
* @brief Appends `inst` at the end of `basicBlock`.
* @return None.
* @param [ in ] basicBlock - Block for which instruction is appended.
* @param [ in ] inst - Instruction to insert.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is constant.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning `basicBlock` and `inst`
* differs.
* @note Allocates
*/
void (*bbAddInstBack)(AbckitBasicBlock *basicBlock, AbckitInst *inst);
/**
* @brief Removes all instructions from `basicBlock`.
* @return None.
* @param [ in ] basicBlock - basic block to clear.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
void (*bbClear)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns first instruction from `basicBlock`.
* @return Pointer to the `AbckitInst`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
AbckitInst *(*bbGetFirstInst)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns last instruction from `basicBlock`.
* @return Pointer to the `AbckitInst`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
AbckitInst *(*bbGetLastInst)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns number of instruction in `basicBlock`.
* @return Number of instruction in `basicBlock`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
uint32_t (*bbGetNumberOfInstructions)(AbckitBasicBlock *basicBlock);
/**
* @brief Returns immediate dominator of `basicBlock`.
* @return Pinter to the `AbckitBasicBlock`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
AbckitBasicBlock *(*bbGetImmediateDominator)(AbckitBasicBlock *basicBlock);
/**
* @brief Checks that `basicBlock` is dominated by `dominator`
* @return True if `basicBlock` is dominated by `dominator`.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in ] dominator - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `dominator` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraphs`s owning `basicBlock` and `dominator`
* differs.
*/
bool (*bbCheckDominance)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *dominator);
/**
* @brief Enumerates basic blocks successing to the given `basicBlock`, invoking callback `cb` for each basic block.
* @return None.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
/**
* @brief Enumerates basic blocks dominating to the given `basicBlock`, invoking callback `cb` for each basic block.
* @return None.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*bbVisitDominatedBlocks)(AbckitBasicBlock *basicBlock, void *data,
void (*cb)(AbckitBasicBlock *basicBlock, AbckitBasicBlock *dominatedBasicBlock,
void *data));
/**
* @brief Tells if `basicBlock` is start basic block.
* @return `true` if `basicBlock` is start basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsStart)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is end basic block.
* @return `true` if `basicBlock` is end basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsEnd)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is loop head basic block.
* @return `true` if `basicBlock` is loop head basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsLoopHead)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is loop prehead basic block.
* @return `true` if `basicBlock` is loop prehead basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsLoopPrehead)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is try begin basic block.
* @return `true` if `basicBlock` is try begin basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsTryBegin)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is try basic block.
* @return `true` if `basicBlock` is try basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsTry)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is try end basic block.
* @return `true` if `basicBlock` is try end basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsTryEnd)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is catch begin basic block.
* @return `true` if `basicBlock` is catch begin basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsCatchBegin)(AbckitBasicBlock *basicBlock);
/**
* @brief Tells if `basicBlock` is catch basic block.
* @return `true` if `basicBlock` is catch basic block, `false` otherwise.
* @param [ in ] basicBlock - Basic block to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
*/
bool (*bbIsCatch)(AbckitBasicBlock *basicBlock);
/**
* @brief Dumps given `basicBlock` into given file descriptor.
* @return None.
* @param [ in ] basicBlock - Basic block to be inspected.
* @param [ in ] fd - File descriptor where dump is written.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Allocates
*/
void (*bbDump)(AbckitBasicBlock *basicBlock, int32_t fd);
/**
* @brief Creates phi instruction and inserts it into `basicBlock`.
* @return Pointer to created phi instruction.
* @param [ in ] basicBlock - Basic block where phi instruction will be inserted.
* @param [ in ] argCount - Number of phi inputs.
* @param [ in ] ... - Phi inputs, must be pointers to `AbckitInst`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `basicBlock` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `argCount` is zero.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if types of phi inputs are inconsistent.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if one of inputs is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `basicBlock` and phi input
* instruction differs.
* @note Allocates
*/
AbckitInst *(*bbCreatePhi)(AbckitBasicBlock *basicBlock, size_t argCount, ...);
/**
* @brief Removes instruction from it's basic block.
* @return None.
* @param [ in ] inst - Instruction to be removed.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
void (*iRemove)(AbckitInst *inst);
/**
* @brief Returns ID of instruction.
* @return ID of instruction.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
uint32_t (*iGetId)(AbckitInst *inst);
/**
* @brief Returns instruction following `inst` from `inst`'s basic block.
* @return Pointer to next `AbckitInst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
AbckitInst *(*iGetNext)(AbckitInst *inst);
/**
* @brief Returns instruction preceding `inst` from `inst`'s basic block.
* @return Pointer to previous `AbckitInst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
AbckitInst *(*iGetPrev)(AbckitInst *inst);
/**
* @brief Inserts `newInst` instruction after `ref` instruction into `ref`'s basic block.
* @return None.
* @param [ in ] newInst - Instruction to be inserted.
* @param [ in ] ref - Instruction after which `newInst` will be inserted.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `newInst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ref` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `newInst` is constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ref` is constant instruction.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `newInst` and `ref` differs.
* @note Allocates
*/
void (*iInsertAfter)(AbckitInst *newInst, AbckitInst *ref);
/**
* @brief Inserts `newInst` instruction before `ref` instruction into `ref`'s basic block.
* @return None.
* @param [ in ] newInst - Instruction to be inserted.
* @param [ in ] ref - Instruction before which `newInst` will be inserted.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `newInst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ref` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `newInst` is constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `ref` is constant instruction.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `newInst` and `ref` differs.
* @note Allocates
*/
void (*iInsertBefore)(AbckitInst *newInst, AbckitInst *ref);
/**
* @brief Returns the type of the `inst` result.
* @return Pointer to the `AbckitType`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Allocates
*/
AbckitType *(*iGetType)(AbckitInst *inst);
/**
* @brief Returns basic block that owns `inst`.
* @return Pointer to the `AbckitBasicBlock`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
AbckitBasicBlock *(*iGetBasicBlock)(AbckitInst *inst);
/**
* @brief Checks that `inst` is dominated by `dominator`.
* @return `true` if `inst` is dominated by `dominator`, `false` otherwise.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in ] dominator - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `dominator` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and `dominator` differs.
*/
bool (*iCheckDominance)(AbckitInst *inst, AbckitInst *dominator);
/**
* @brief Checks if `inst` is "call" instruction.
* @return `true` if `inst` is "call" instruction, `false` otherwise.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
bool (*iCheckIsCall)(AbckitInst *inst);
/**
* @brief Returns number of `inst` users.
* @return Number of `inst` users.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
uint32_t (*iGetUserCount)(AbckitInst *inst);
/**
* @brief Enumerates `insts` user instructions, invoking callback `cb` for each user instruction.
* @return None.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*iVisitUsers)(AbckitInst *inst, void *data, void (*cb)(AbckitInst *inst, AbckitInst *user, void *data));
/**
* @brief Returns number of `inst` inputs.
* @return Number of `inst` inputs.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
uint32_t (*iGetInputCount)(AbckitInst *inst);
/**
* @brief Returns `inst` input under given `index`.
* @return Pointer to the input `AbckitInst`.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in ] index - Index of input to be returned.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` is larger than number of `inst` inputs.
*/
AbckitInst *(*iGetInput)(AbckitInst *inst, uint32_t index);
/**
* @brief Enumerates `insts` input instructions, invoking callback `cb` for each input instruction.
* @return None.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in, out ] data - Pointer to the user-defined data that will be passed to the callback `cb` each time
* it is invoked.
* @param [ in ] cb - Callback that will be invoked.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `cb` is NULL.
*/
void (*iVisitInputs)(AbckitInst *inst, void *data,
void (*cb)(AbckitInst *inst, AbckitInst *input, size_t inputIdx, void *data));
/**
* @brief Sets `inst` input, overwrites existing input.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] input - Input instruction to be set.
* @param [ in ] index - Index of input to be set.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `input` is NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and `input` differs.
*/
void (*iSetInput)(AbckitInst *inst, AbckitInst *input, uint32_t index);
/**
* @brief Sets input instructions for `inst` starting from index 0, overwrites existing inputs.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] argCount - Number of input instructions.
* @param [ in ] ... - Instructions to be set as input for `inst`.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if one of inst inputs are NULL.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and input inst differs.
*/
void (*iSetInputs)(AbckitInst *inst, size_t argCount, ...);
/**
* @brief Appends `input` instruction to `inst` inputs.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] input - Instruction to be appended as input.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `input` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not applicable for input appending.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitGraph`s owning `inst` and `input` differs.
* @note Allocates
*/
void (*iAppendInput)(AbckitInst *inst, AbckitInst *input);
/**
* @brief Dumps given `inst` into given file descriptor.
* @return None.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in ] fd - File descriptor where dump is written.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Allocates
*/
void (*iDump)(AbckitInst *inst, int32_t fd);
/**
* @brief Returns `inst` function operand.
* @return Pointer to the `AbckitCoreFunction`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no function operand.
*/
AbckitCoreFunction *(*iGetFunction)(AbckitInst *inst);
/**
* @brief Sets `inst` function operand.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] function - Function to be set as `inst` operand.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `function` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no function operand.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitFile`s owning `inst` and `function` differs.
*/
void (*iSetFunction)(AbckitInst *inst, AbckitCoreFunction *function);
/**
* @brief Returns `inst` immediate under given `index`.
* @return uint64_t .
* @param [ in ] inst - Instruction to be inspected.
* @param [ in ] index - Index of immediate.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no immediates.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` larger than `inst` immediates number.
*/
uint64_t (*iGetImmediate)(AbckitInst *inst, size_t index);
/**
* @brief Sets `inst` immediate under given `index` with value `imm`.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] index - Index of immediate to be set.
* @param [ in ] imm - Value of immediate to be set.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no immediates.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `index` larger than `inst` immediates number.
*/
void (*iSetImmediate)(AbckitInst *inst, size_t index, uint64_t imm);
/**
* @brief Returns number of `inst` immediates.
* @return Number of `inst` immediates.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
*/
uint64_t (*iGetImmediateCount)(AbckitInst *inst);
/**
* @brief Returns `inst` literal array operand.
* @return Pointer to the `AbckitLiteralArray`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no literal array operand.
*/
AbckitLiteralArray *(*iGetLiteralArray)(AbckitInst *inst);
/**
* @brief Sets `inst` literal array operand.
* @return None.
* @param [ in ] inst - Instruction to be modified.
* @param [ in ] la - Literal array to be set as operand.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `la` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no literal array operand.
* @note Set `ABCKIT_STATUS_WRONG_CTX` error if corresponding `AbckitFile`s owning `inst` and `la` differs.
*/
void (*iSetLiteralArray)(AbckitInst *inst, AbckitLiteralArray *la);
/**
* @brief Returns `inst` string operand.
* @return Pointer to the `AbckitString`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no string operand.
*/
AbckitString *(*iGetString)(AbckitInst *inst);
/**
* @brief Sets `inst` string operand.
* @return None.
* @param [ in ] inst - Instruction to be inspected.
* @param [ in ] s - String to be set as operand.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `s` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` has no string operand.
*/
void (*iSetString)(AbckitInst *inst, AbckitString *s);
/**
* @brief Returns value of I32 constant `inst`.
* @return Value of `inst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not I32 constant instruction.
*/
int32_t (*iGetConstantValueI32)(AbckitInst *inst);
/**
* @brief Returns value of I64 constant `inst`.
* @return Value of `inst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not I64 constant instruction.
*/
int64_t (*iGetConstantValueI64)(AbckitInst *inst);
/**
* @brief Returns value of U64 constant `inst`.
* @return Value of `inst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not U64 constant instruction.
*/
uint64_t (*iGetConstantValueU64)(AbckitInst *inst);
/**
* @brief Returns value of F64 constant `inst`.
* @return Value of `inst`.
* @param [ in ] inst - Instruction to be inspected.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is NULL.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not a constant instruction.
* @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if `inst` is not F64 constant instruction.
*/
double (*iGetConstantValueF64)(AbckitInst *inst);
};
/**
* @brief Instantiates API for Abckit graph manipulation.
* @return Instance of the `AbckitGraphApi` struct with valid function pointers.
* @param [ in ] version - Version of the API to instantiate.
* @note Set `ABCKIT_STATUS_UNKNOWN_API_VERSION` error if `version` value is not in the `AbckitApiVersion` enum.
*/
struct AbckitGraphApi const *AbckitGetGraphApiImpl(enum AbckitApiVersion version);
#ifdef __cplusplus
}
#endif
#endif /* LIBABCKIT_IR_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_STATUSES_H
#define LIBABCKIT_STATUSES_H
#ifdef __cplusplus
extern "C" {
#endif
enum AbckitStatus {
ABCKIT_STATUS_NO_ERROR,
ABCKIT_STATUS_BAD_ARGUMENT,
ABCKIT_STATUS_MEMORY_ALLOCATION,
ABCKIT_STATUS_WRONG_MODE,
ABCKIT_STATUS_WRONG_TARGET,
ABCKIT_STATUS_WRONG_LITERAL_TYPE,
ABCKIT_STATUS_UNSUPPORTED,
ABCKIT_STATUS_WRONG_CTX,
ABCKIT_STATUS_TODO,
ABCKIT_STATUS_UNKNOWN_API_VERSION,
};
#ifdef __cplusplus
}
#endif
#endif /* LIBABCKIT_STATUSES_H */

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_H
#define CPP_ABCKIT_H
#include "headers/utils.h"
#include "headers/declarations.h"
#include "headers/graph.h"
#include "headers/instruction.h"
#include "headers/basic_block.h"
#include "headers/file.h"
#include "headers/value.h"
#include "headers/literal.h"
#include "headers/literal_array.h"
#include "headers/core/annotation_element.h"
#include "headers/core/annotation_interface_field.h"
#include "headers/core/annotation_interface.h"
#include "headers/core/annotation.h"
#include "headers/core/class.h"
#include "headers/core/export_descriptor.h"
#include "headers/core/field.h"
#include "headers/core/function.h"
#include "headers/core/import_descriptor.h"
#include "headers/core/module.h"
#include "headers/core/namespace.h"
#include "headers/arkts/annotation_element.h"
#include "headers/arkts/annotation_interface_field.h"
#include "headers/arkts/annotation_interface.h"
#include "headers/arkts/annotation.h"
#include "headers/arkts/class.h"
#include "headers/arkts/export_descriptor.h"
#include "headers/arkts/field.h"
#include "headers/arkts/function.h"
#include "headers/arkts/import_descriptor.h"
#include "headers/arkts/module.h"
#include "headers/arkts/namespace.h"
// implementations
#include "headers/core/annotation_interface_field_impl.h"
#include "headers/core/annotation_interface_impl.h"
#include "headers/core/module_impl.h"
#include "headers/core/class_impl.h"
#include "headers/core/function_impl.h"
#include "headers/core/export_descriptor_impl.h"
#include "headers/core/import_descriptor_impl.h"
#include "headers/arkts/annotation_element_impl.h"
#include "headers/arkts/annotation_impl.h"
#include "headers/arkts/function_impl.h"
#include "headers/dynamic_isa_impl.h"
#include "headers/basic_block_impl.h"
#include "headers/file_impl.h"
#include "headers/graph_impl.h"
#include "headers/instruction_impl.h"
#include "headers/literal_impl.h"
#endif // CPP_ABCKIT

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/value.h"
#include "cpp/headers/core/annotation.h"
#include "cpp/headers/core/annotation_element.h"
#include "cpp/headers/arkts/annotation_element.h"
#include "metadata_inspect_impl.h"
#include <string_view>
namespace abckit::arkts {
class Annotation : public core::Annotation {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class arkts::Class;
friend class arkts::Function;
public:
Annotation(const Annotation &other) = default;
Annotation &operator=(const Annotation &other) = default;
Annotation(Annotation &&other) = default;
Annotation &operator=(Annotation &&other) = default;
// CC-OFFNXT(G.FMT.02) project code style
explicit Annotation(const core::Annotation &coreOther) : core::Annotation(coreOther) {};
~Annotation() override = default;
arkts::Annotation &AddElement(const abckit::Value &val, const std::string &name);
arkts::AnnotationElement AddAndGetElement(const abckit::Value &val, const std::string_view name);
AbckitCoreAnnotationElement *AddAndGetElementImpl(AbckitArktsAnnotationElementCreateParams *params);
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_H

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_element.h"
#include "metadata_inspect_impl.h"
#include <string_view>
namespace abckit::arkts {
class AnnotationElement : public core::AnnotationElement {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class arkts::Class;
friend class arkts::Function;
friend class arkts::Annotation;
public:
AnnotationElement(const AnnotationElement &other) = default;
AnnotationElement &operator=(const AnnotationElement &other) = default;
AnnotationElement(AnnotationElement &&other) = default;
AnnotationElement &operator=(AnnotationElement &&other) = default;
// CC-OFFNXT(G.FMT.02) project code style
explicit AnnotationElement(const core::AnnotationElement &coreOther) : core::AnnotationElement(coreOther) {};
~AnnotationElement() override = default;
std::string_view GetName() const;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_IMPL_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_IMPL_H
#include "cpp/headers/arkts/annotation_element.h"
namespace abckit::arkts {
inline std::string_view AnnotationElement::GetName() const
{
AbckitString *abcName = GetApiConfig()->cIapi_->annotationElementGetName(GetView());
CheckError(GetApiConfig());
std::string_view name = GetApiConfig()->cIapi_->abckitStringToString(abcName);
CheckError(GetApiConfig());
return name;
}
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_ELEMENT_IMPL_H

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_IMPL_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_IMPL_H
#include "cpp/headers/arkts/annotation.h"
namespace abckit::arkts {
inline arkts::Annotation &Annotation::AddElement(const abckit::Value &val, const std::string &name)
{
struct AbckitArktsAnnotationElementCreateParams params {
name.c_str(), val.GetView()
};
AbckitArktsAnnotation *arktsAnn = GetApiConfig()->cArktsIapi_->coreAnnotationToArktsAnnotation(GetView());
CheckError(GetApiConfig());
GetApiConfig()->cArktsMapi_->annotationAddAnnotationElement(arktsAnn, &params);
CheckError(GetApiConfig());
return *this;
}
inline AbckitCoreAnnotationElement *Annotation::AddAndGetElementImpl(AbckitArktsAnnotationElementCreateParams *params)
{
AbckitArktsAnnotation *arktsAnn = GetApiConfig()->cArktsIapi_->coreAnnotationToArktsAnnotation(GetView());
CheckError(GetApiConfig());
AbckitArktsAnnotationElement *arktsAnni =
GetApiConfig()->cArktsMapi_->annotationAddAnnotationElement(arktsAnn, params);
CheckError(GetApiConfig());
AbckitCoreAnnotationElement *coreAnni =
GetApiConfig()->cArktsIapi_->arktsAnnotationElementToCoreAnnotationElement(arktsAnni);
CheckError(GetApiConfig());
return coreAnni;
}
inline arkts::AnnotationElement Annotation::AddAndGetElement(const abckit::Value &val, const std::string_view name)
{
struct AbckitArktsAnnotationElementCreateParams params {
name.data(), val.GetView()
};
auto *coreAnni = AddAndGetElementImpl(&params);
core::AnnotationElement element(coreAnni, GetApiConfig());
return arkts::AnnotationElement(element);
}
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_IMPL_H

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_interface.h"
namespace abckit::arkts {
class AnnotationInterface : public core::AnnotationInterface {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class arkts::Class;
friend class arkts::Function;
public:
AnnotationInterface(const AnnotationInterface &other) = default;
AnnotationInterface &operator=(const AnnotationInterface &other) = default;
AnnotationInterface(AnnotationInterface &&other) = default;
AnnotationInterface &operator=(AnnotationInterface &&other) = default;
// CC-OFFNXT(G.FMT.02) project code style
explicit AnnotationInterface(const core::AnnotationInterface &coreOther) : core::AnnotationInterface(coreOther) {};
~AnnotationInterface() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_H

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_FIELD_H
#define CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_FIELD_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_interface_field.h"
namespace abckit::arkts {
class AnnotationInterfaceField : public core::AnnotationInterfaceField {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class arkts::Annotation;
friend class arkts::AnnotationInterface;
public:
AnnotationInterfaceField(const AnnotationInterfaceField &other) = default;
AnnotationInterfaceField &operator=(const AnnotationInterfaceField &other) = default;
AnnotationInterfaceField(AnnotationInterfaceField &&other) = default;
AnnotationInterfaceField &operator=(AnnotationInterfaceField &&other) = default;
// CC-OFFNXT(G.FMT.02) project code style
explicit AnnotationInterfaceField(const core::AnnotationInterfaceField &coreOther)
: core::AnnotationInterfaceField(coreOther) {};
~AnnotationInterfaceField() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_ANNOTATION_INTERFACE_FIELD_H

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_CLASS_H
#define CPP_ABCKIT_ARKTS_CLASS_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/class.h"
namespace abckit::arkts {
class Class final : public core::Class {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Module;
friend class Namespace;
public:
Class(const Class &other) = default;
Class &operator=(const Class &other) = default;
Class(Class &&other) = default;
Class &operator=(Class &&other) = default;
~Class() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_CLASS_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_EXPORT_DESCRIPTOR_H
#define CPP_ABCKIT_ARKTS_EXPORT_DESCRIPTOR_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/module.h"
#include "cpp/headers/core/export_descriptor.h"
namespace abckit::arkts {
class ExportDescriptor final : public core::ExportDescriptor {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class core::Module;
friend class arkts::Module;
public:
ExportDescriptor(const ExportDescriptor &other) = default;
ExportDescriptor &operator=(const ExportDescriptor &other) = default;
ExportDescriptor(ExportDescriptor &&other) = default;
ExportDescriptor &operator=(ExportDescriptor &&other) = default;
~ExportDescriptor() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_EXPORT_DESCRIPTOR_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_FIELD_H
#define CPP_ABCKIT_ARKTS_FIELD_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/field.h"
namespace abckit::arkts {
class Field final : public core::Field {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::core::Field;
public:
Field(const Field &other) = default;
Field &operator=(const Field &other) = default;
Field(Field &&other) = default;
Field &operator=(Field &&other) = default;
~Field() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_FIELD_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_FUNCTION_H
#define CPP_ABCKIT_ARKTS_FUNCTION_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/function.h"
#include "cpp/headers/core/annotation_interface.h"
#include "cpp/headers/arkts/annotation_interface.h"
namespace abckit::arkts {
class Function final : public core::Function {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Class;
public:
Function(const Function &other) = default;
Function &operator=(const Function &other) = default;
Function(Function &&other) = default;
Function &operator=(Function &&other) = default;
// CC-OFFNXT(G.FMT.02) project code style
explicit Function(const core::Function &coreOther) : core::Function(coreOther) {};
~Function() override = default;
arkts::Function &AddAnnotation(const arkts::AnnotationInterface &iface);
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_FUNCTION_H

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_FUNCTION_IMPL_H
#define CPP_ABCKIT_ARKTS_FUNCTION_IMPL_H
#include "cpp/headers/arkts/function.h"
namespace abckit::arkts {
inline arkts::Function &Function::AddAnnotation(const arkts::AnnotationInterface &iface)
{
auto *arktsImpl = GetApiConfig()->cArktsIapi_->coreFunctionToArktsFunction(GetView());
CheckError(GetApiConfig());
const AbckitArktsAnnotationCreateParams paramsImpl {
GetApiConfig()->cArktsIapi_->coreAnnotationInterfaceToArktsAnnotationInterface(iface.GetView())};
CheckError(GetApiConfig());
GetApiConfig()->cArktsMapi_->functionAddAnnotation(arktsImpl, &paramsImpl);
CheckError(GetApiConfig());
return *this;
}
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_FUNCTION_IMPL_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_IMPORT_DESCRIPTOR_H
#define CPP_ABCKIT_ARKTS_IMPORT_DESCRIPTOR_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/import_descriptor.h"
namespace abckit::arkts {
class ImportDescriptor final : public core::ImportDescriptor {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::File;
public:
ImportDescriptor(const ImportDescriptor &other) = default;
ImportDescriptor &operator=(const ImportDescriptor &other) = default;
ImportDescriptor(ImportDescriptor &&other) = default;
ImportDescriptor &operator=(ImportDescriptor &&other) = default;
~ImportDescriptor() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_IMPORT_DESCRIPTOR_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_MODULE_H
#define CPP_ABCKIT_ARKTS_MODULE_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/module.h"
namespace abckit::arkts {
class Module final : public core::Module {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::File;
public:
Module(const Module &other) = default;
Module &operator=(const Module &other) = default;
Module(Module &&other) = default;
Module &operator=(Module &&other) = default;
~Module() override = default;
// Other API.
// ...
};
} // namespace abckit::arkts
#endif // CPP_ABCKIT_ARKTS_MODULE_H

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_ARKTS_NAMESPACE_H
#define CPP_ABCKIT_ARKTS_NAMESPACE_H
#endif // CPP_ABCKIT_ARKTS_NAMESPACE_H

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_BASE_CLASSES_H
#define CPP_ABCKIT_BASE_CLASSES_H
#include "cpp/headers/config.h"
#include "cpp/headers/declarations.h"
#include <memory>
namespace abckit {
// Interface to provide global API-related features,
// a base for every API class defined
class Entity {
public:
Entity(const Entity &other) = default;
Entity &operator=(const Entity &other) = default;
Entity(Entity &&other) = default;
Entity &operator=(Entity &&other) = default;
protected:
Entity() = default;
virtual ~Entity() = default;
virtual const ApiConfig *GetApiConfig() const = 0;
};
// View - value semantics
template <typename T>
class View : public Entity {
public:
template <typename... Args>
explicit View(Args &&...a) : view_(std::forward<Args>(a)...)
{
}
// Can move and copy views
View(const View &other) = default;
View &operator=(const View &other) = default;
View(View &&other) = default;
View &operator=(View &&other) = default;
bool operator==(const View<T> &rhs)
{
return GetView() == rhs.GetView();
}
protected:
~View() override = default;
T GetView() const
{
return view_;
}
void SetView(T newView)
{
view_ = newView;
}
private:
T view_;
};
// Resource - ptr semantics
template <typename T>
class Resource : public Entity {
public:
template <typename... Args>
explicit Resource(std::unique_ptr<IResourceDeleter> d, Args &&...a)
: deleter_(std::move(d)), resource_(std::forward<Args>(a)...)
{
}
template <typename... Args>
explicit Resource(Args &&...a) : resource_(std::forward<Args>(a)...)
{
}
// No copy for resources
Resource(Resource &other) = delete;
Resource &operator=(Resource &other) = delete;
// Resources are movable
Resource(Resource &&other)
{
released_ = false;
resource_ = other.ReleaseResource();
};
Resource &operator=(Resource &&other)
{
released_ = false;
resource_ = other.ReleaseResource();
return *this;
};
T ReleaseResource()
{
released_ = true;
return resource_;
}
T GetResource() const
{
return resource_;
}
protected:
~Resource() override
{
if (!released_) {
deleter_->DeleteResource();
}
};
void SetDeleter(std::unique_ptr<IResourceDeleter> deleter)
{
deleter_ = std::move(deleter);
}
private:
T resource_;
std::unique_ptr<IResourceDeleter> deleter_ = std::make_unique<DefaultResourceDeleter>();
bool released_ = false;
};
} // namespace abckit
#endif // CPP_ABCKIT_BASE_CLASSES_H

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_BASIC_BLOCK_H
#define CPP_ABCKIT_BASIC_BLOCK_H
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/isa/isa_dynamic.h"
#include "libabckit/src/include_v2/c/isa/isa_static.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/config.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/instruction.h"
#include <cstdint>
#include <memory>
#include <vector>
namespace abckit {
class BasicBlock final : public View<AbckitBasicBlock *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Graph;
public:
BasicBlock(const BasicBlock &other) = default;
BasicBlock &operator=(const BasicBlock &other) = default;
BasicBlock(BasicBlock &&other) = default;
BasicBlock &operator=(BasicBlock &&other) = default;
~BasicBlock() override = default;
uint64_t GetSuccCount() const;
BasicBlock GetSuccByIdx(int idx) const;
std::vector<BasicBlock> GetSuccs() const;
BasicBlock &AddInstFront(const Instruction &inst);
std::vector<Instruction> GetInstructions() const;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
void GetSuccsInner(std::vector<BasicBlock> &bBs) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<BasicBlock> *, const ApiConfig *>;
EnumerateData enumerateData(&bBs, conf);
conf->cGapi_->bbVisitSuccBlocks(GetView(), (void *)&enumerateData,
[]([[maybe_unused]] AbckitBasicBlock *bb, AbckitBasicBlock *succ, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(BasicBlock(succ, config));
});
}
BasicBlock(AbckitBasicBlock *bb, const ApiConfig *conf) : View(bb), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_BASIC_BLOCK_H

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_BASIC_BLOCK_IMPL_H
#define CPP_ABCKIT_BASIC_BLOCK_IMPL_H
#include "cpp/headers/basic_block.h"
namespace abckit {
inline uint64_t BasicBlock::GetSuccCount() const
{
uint64_t count = GetApiConfig()->cGapi_->bbGetSuccBlockCount(GetView());
CheckError(GetApiConfig());
return count;
}
inline BasicBlock BasicBlock::GetSuccByIdx(int idx) const
{
const ApiConfig *conf = GetApiConfig();
AbckitBasicBlock *abcBB = conf->cGapi_->bbGetSuccBlock(GetView(), idx);
CheckError(conf);
return BasicBlock(abcBB, conf);
}
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<BasicBlock> BasicBlock::GetSuccs() const
{
const ApiConfig *conf = GetApiConfig();
std::vector<BasicBlock> bBs;
using EnumerateData = std::pair<std::vector<BasicBlock> *, const ApiConfig *>;
EnumerateData enumerateData(&bBs, conf);
conf->cGapi_->bbVisitSuccBlocks(GetView(), (void *)&enumerateData,
[]([[maybe_unused]] AbckitBasicBlock *bb, AbckitBasicBlock *succ, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(BasicBlock(succ, config));
});
CheckError(conf);
return bBs;
}
inline std::vector<Instruction> BasicBlock::GetInstructions() const
{
std::vector<Instruction> insts;
auto *conf = GetApiConfig();
auto *inst = conf->cGapi_->bbGetFirstInst(GetView());
CheckError(conf);
while (inst != nullptr) {
insts.push_back(Instruction(inst, conf));
inst = conf->cGapi_->iGetNext(inst);
CheckError(conf);
}
return insts;
}
inline BasicBlock &BasicBlock::AddInstFront(const Instruction &inst)
{
GetApiConfig()->cGapi_->bbAddInstFront(GetView(), inst.GetView());
CheckError(GetApiConfig());
return *this;
}
} // namespace abckit
#endif // CPP_ABCKIT_BASIC_BLOCK_H

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CONFIG_H
#define CPP_ABCKIT_CONFIG_H
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/metadata_core.h"
#include "libabckit/include/c/ir_core.h"
#include "libabckit/include/c/isa/isa_dynamic.h"
#include "libabckit/src/include_v2/c/isa/isa_static.h"
#include "libabckit/include/c/extensions/arkts/metadata_arkts.h"
#include "libabckit/include/c/extensions/js/metadata_js.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/utils.h"
#include <memory>
namespace abckit {
// Class containing pointers to underlying C API's,
// hides C implementation from C++ API user
class ApiConfig final {
// Befrend with all core entities so they have an access to config
friend DynamicIsa;
friend StaticIsa;
friend File;
friend Graph;
friend BasicBlock;
friend Instruction;
friend Value;
friend Literal;
friend LiteralArray;
friend core::Module;
friend core::Namespace;
friend core::Class;
friend core::Function;
friend core::Field;
friend core::Annotation;
friend core::AnnotationInterface;
friend core::AnnotationElement;
friend core::AnnotationInterfaceField;
friend core::ImportDescriptor;
friend core::ExportDescriptor;
friend arkts::Module;
friend arkts::Namespace;
friend arkts::Class;
friend arkts::Function;
friend arkts::Field;
friend arkts::Annotation;
friend arkts::AnnotationInterface;
friend arkts::AnnotationElement;
friend arkts::AnnotationInterfaceField;
friend arkts::ImportDescriptor;
friend arkts::ExportDescriptor;
friend void CheckError(const ApiConfig *conf);
public:
ApiConfig(const ApiConfig &other) = delete;
ApiConfig &operator=(const ApiConfig &other) = delete;
ApiConfig(ApiConfig &&other) = delete;
ApiConfig &operator=(ApiConfig &&other) = delete;
~ApiConfig() = default;
protected:
explicit ApiConfig(std::unique_ptr<IErrorHandler> eh)
: cApi_(AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cIapi_(AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cMapi_(AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cArktsIapi_(AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cArktsMapi_(AbckitGetArktsModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cGapi_(AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cDynapi_(AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
cStatapi_(AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0)),
eh_(std::move(eh)) {};
private:
// NOTE(nsizov): make getters for these pointers
const AbckitApi *cApi_;
const AbckitInspectApi *cIapi_;
const AbckitModifyApi *cMapi_;
const AbckitArktsInspectApi *cArktsIapi_;
const AbckitArktsModifyApi *cArktsMapi_;
const AbckitGraphApi *cGapi_;
const AbckitIsaApiDynamic *cDynapi_;
const AbckitIsaApiStatic *cStatapi_;
const std::unique_ptr<IErrorHandler> eh_;
};
inline void CheckError(const ApiConfig *conf)
{
const AbckitStatus status = conf->cApi_->getLastError();
if (status != ABCKIT_STATUS_NO_ERROR) {
conf->eh_->HandleError(abckit::Exception(status));
}
}
} // namespace abckit
#endif // CPP_ABCKIT_CONFIG_H

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_H
#define CPP_ABCKIT_CORE_ANNOTATION_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/core/annotation_interface.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
namespace abckit::core {
class Annotation : public View<AbckitCoreAnnotation *> {
friend class core::Function;
friend class arkts::Function;
friend class core::Class;
friend class arkts::Class;
public:
Annotation(const Annotation &other) = default;
Annotation &operator=(const Annotation &other) = default;
Annotation(Annotation &&other) = default;
Annotation &operator=(Annotation &&other) = default;
~Annotation() override = default;
// Core API's.
// ...
core::AnnotationInterface GetInterface()
{
AnnotationInterface iface(GetApiConfig()->cIapi_->annotationGetInterface(GetView()), GetApiConfig());
CheckError(GetApiConfig());
return iface;
}
private:
Annotation(AbckitCoreAnnotation *ann, const ApiConfig *conf) : View(ann), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_H

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_ELEMENT_H
#define CPP_ABCKIT_CORE_ANNOTATION_ELEMENT_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include <string_view>
namespace abckit::core {
class AnnotationElement : public View<AbckitCoreAnnotationElement *> {
friend class core::Annotation;
friend class arkts::Annotation;
friend class core::Module;
friend class arkts::Module;
public:
AnnotationElement(const AnnotationElement &other) = default;
AnnotationElement &operator=(const AnnotationElement &other) = default;
AnnotationElement(AnnotationElement &&other) = default;
AnnotationElement &operator=(AnnotationElement &&other) = default;
~AnnotationElement() override = default;
// Core API's.
// ...
private:
AnnotationElement(AbckitCoreAnnotationElement *anne, const ApiConfig *conf) : View(anne), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_ELEMENT_H

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_H
#define CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_interface_field.h"
#include "libabckit/include/c/metadata_core.h"
#include <string>
#include <vector>
#include <string_view>
namespace abckit::core {
class AnnotationInterface : public View<AbckitCoreAnnotationInterface *> {
friend class core::Annotation;
friend class core::Module;
public:
AnnotationInterface(const AnnotationInterface &other) = default;
AnnotationInterface &operator=(const AnnotationInterface &other) = default;
AnnotationInterface(AnnotationInterface &&other) = default;
AnnotationInterface &operator=(AnnotationInterface &&other) = default;
~AnnotationInterface() override = default;
// Core API's.
// ...
std::string_view GetName();
std::vector<AnnotationInterfaceField> GetFields();
private:
template <typename EnumerateData>
inline void GetFieldsInner(EnumerateData enumerateData)
{
GetApiConfig()->cIapi_->annotationInterfaceEnumerateFields(
GetView(), (void *)&enumerateData, [](AbckitCoreAnnotationInterfaceField *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::AnnotationInterfaceField(func, config));
return true;
});
}
AnnotationInterface(AbckitCoreAnnotationInterface *anni, const ApiConfig *conf) : View(anni), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_H

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_H
#define CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/metadata_core.h"
#include <string>
#include <string_view>
namespace abckit::core {
class AnnotationInterfaceField : public View<AbckitCoreAnnotationInterfaceField *> {
friend class core::Annotation;
friend class arkts::Annotation;
friend class core::AnnotationInterface;
friend class arkts::AnnotationInterface;
public:
AnnotationInterfaceField(const AnnotationInterfaceField &other) = default;
AnnotationInterfaceField &operator=(const AnnotationInterfaceField &other) = default;
AnnotationInterfaceField(AnnotationInterfaceField &&other) = default;
AnnotationInterfaceField &operator=(AnnotationInterfaceField &&other) = default;
~AnnotationInterfaceField() override = default;
// Core API's.
// ...
std::string_view GetName();
private:
AnnotationInterfaceField(AbckitCoreAnnotationInterfaceField *anni, const ApiConfig *conf)
: View(anni), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_H

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_IMPL_H
#define CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_IMPL_H
#include "cpp/headers/core/annotation_interface_field.h"
namespace abckit::core {
inline std::string_view AnnotationInterfaceField::GetName()
{
const ApiConfig *conf = GetApiConfig();
AbckitString *abcStr = conf->cIapi_->annotationInterfaceFieldGetName(GetView());
CheckError(conf);
std::string_view sView = conf->cIapi_->abckitStringToString(abcStr);
CheckError(conf);
return sView;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_FIELD_IMPL_H

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_IMPL_H
#define CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_IMPL_H
#include "cpp/headers/core/annotation_interface.h"
namespace abckit::core {
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<AnnotationInterfaceField> AnnotationInterface::GetFields()
{
const ApiConfig *conf = GetApiConfig();
std::vector<core::AnnotationInterfaceField> namespaces;
using EnumerateData = std::pair<std::vector<core::AnnotationInterfaceField> *, const ApiConfig *>;
EnumerateData enumerateData(&namespaces, conf);
conf->cIapi_->annotationInterfaceEnumerateFields(GetView(), (void *)&enumerateData,
[](AbckitCoreAnnotationInterfaceField *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::AnnotationInterfaceField(func, config));
return true;
});
CheckError(conf);
return namespaces;
}
inline std::string_view AnnotationInterface::GetName()
{
const ApiConfig *conf = GetApiConfig();
AbckitString *abcStr = conf->cIapi_->annotationInterfaceGetName(GetView());
CheckError(conf);
std::string_view sView = conf->cIapi_->abckitStringToString(abcStr);
CheckError(conf);
return sView;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_ANNOTATION_INTERFACE_IMPL_H

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_CLASS_H
#define CPP_ABCKIT_CORE_CLASS_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_interface.h"
#include "cpp/headers/core/function.h"
#include "libabckit/include/c/metadata_core.h"
#include <vector>
#include <utility>
namespace abckit::core {
class Class : public View<AbckitCoreClass *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Module;
friend class Namespace;
public:
Class(const Class &other) = default;
Class &operator=(const Class &other) = default;
Class(Class &&other) = default;
Class &operator=(Class &&other) = default;
~Class() override = default;
std::vector<core::Function> GetAllMethods() const;
std::vector<core::Annotation> GetAnnotations() const;
// Core API's.
// ...
private:
inline void GetAllMethodsInner(std::vector<core::Function> &methods) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Function> *, const ApiConfig *>;
EnumerateData enumerateData(&methods, conf);
conf->cIapi_->classEnumerateMethods(GetView(), (void *)&enumerateData,
[](AbckitCoreFunction *method, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Function(method, config));
return true;
});
}
inline void GetAllAnnotationsInner(std::vector<core::Annotation> &anns) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Annotation> *, const ApiConfig *>;
EnumerateData enumerateData(&anns, conf);
conf->cIapi_->classEnumerateAnnotations(GetView(), (void *)&enumerateData,
[](AbckitCoreAnnotation *method, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Annotation(method, config));
return true;
});
}
Class(AbckitCoreClass *klass, const ApiConfig *conf) : View(klass), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_CLASS_H

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_CLASS_IMPL_H
#define CPP_ABCKIT_CORE_CLASS_IMPL_H
#include "cpp/headers/core/class.h"
namespace abckit::core {
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<core::Function> Class::GetAllMethods() const
{
const ApiConfig *conf = GetApiConfig();
std::vector<core::Function> methods;
using EnumerateData = std::pair<std::vector<core::Function> *, const ApiConfig *>;
EnumerateData enumerateData(&methods, conf);
conf->cIapi_->classEnumerateMethods(GetView(), (void *)&enumerateData, [](AbckitCoreFunction *method, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Function(method, config));
return true;
});
CheckError(conf);
return methods;
}
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<core::Annotation> Class::GetAnnotations() const
{
const ApiConfig *conf = GetApiConfig();
std::vector<core::Annotation> anns;
using EnumerateData = std::pair<std::vector<core::Annotation> *, const ApiConfig *>;
EnumerateData enumerateData(&anns, conf);
conf->cIapi_->classEnumerateAnnotations(GetView(), (void *)&enumerateData,
[](AbckitCoreAnnotation *method, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Annotation(method, config));
return true;
});
CheckError(conf);
return anns;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_CLASS_IMPL_H

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_H
#define CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_H
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/metadata_core.h"
#include <string_view>
#include <vector>
namespace abckit::core {
class ExportDescriptor : public View<AbckitCoreExportDescriptor *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::File;
friend class abckit::core::Module;
friend class abckit::arkts::Module;
public:
ExportDescriptor(const ExportDescriptor &other) = default;
ExportDescriptor &operator=(const ExportDescriptor &other) = default;
ExportDescriptor(ExportDescriptor &&other) = default;
ExportDescriptor &operator=(ExportDescriptor &&other) = default;
~ExportDescriptor() override = default;
std::string_view GetName() const;
// Core API's.
// ...
private:
ExportDescriptor(AbckitCoreExportDescriptor *module, const ApiConfig *conf) : View(module), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_IMPL_H
#define CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_IMPL_H
#include "cpp/headers/core/export_descriptor.h"
namespace abckit::core {
inline std::string_view ExportDescriptor::GetName() const
{
AbckitString *abcName = GetApiConfig()->cIapi_->exportDescriptorGetName(GetView());
CheckError(GetApiConfig());
std::string_view name = GetApiConfig()->cIapi_->abckitStringToString(abcName);
CheckError(GetApiConfig());
return name;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_EXPORT_DESCRIPTOR_IMPL_H

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_FIELD_H
#define CPP_ABCKIT_CORE_FIELD_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/metadata_core.h"
namespace abckit::core {
class Field : public View<AbckitCoreField *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Module;
friend class Namespace;
public:
Field(const Field &other) = default;
Field &operator=(const Field &other) = default;
Field(Field &&other) = default;
Field &operator=(Field &&other) = default;
~Field() override = default;
// Core API's.
// ...
private:
Field(AbckitCoreField *field, const ApiConfig *conf) : View(field), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_FIELD_H

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_FUNCTION_H
#define CPP_ABCKIT_CORE_FUNCTION_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/graph.h"
#include "cpp/headers/core/annotation.h"
#include <string_view>
#include <vector>
namespace abckit::core {
class Function : public View<AbckitCoreFunction *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class core::Class;
friend class core::Module;
public:
Function(const Function &other) = default;
Function &operator=(const Function &other) = default;
Function(Function &&other) = default;
Function &operator=(Function &&other) = default;
~Function() override = default;
Graph GetGraph() const;
void SetGraph(const Graph &graph);
std::string_view GetName() const;
std::vector<core::Annotation> GetAnnotations() const;
bool IsStatic() const;
// Core API's.
// ...
private:
Function(AbckitCoreFunction *func, const ApiConfig *conf) : View(func), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_FUNCTION_H

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_FUNCTION_IMPL_H
#define CPP_ABCKIT_CORE_FUNCTION_IMPL_H
#include "cpp/headers/core/function.h"
namespace abckit::core {
inline Graph Function::GetGraph() const
{
const ApiConfig *conf = GetApiConfig();
AbckitGraph *graph = conf->cIapi_->createGraphFromFunction(GetView());
CheckError(conf);
return Graph(graph, conf_);
}
inline void Function::SetGraph(const Graph &graph)
{
const ApiConfig *conf = GetApiConfig();
conf->cMapi_->functionSetGraph(GetView(), graph.GetResource());
CheckError(conf);
}
inline std::string_view Function::GetName() const
{
const ApiConfig *conf = GetApiConfig();
AbckitString *cString = conf->cIapi_->functionGetName(GetView());
CheckError(conf);
std::string_view view = conf->cIapi_->abckitStringToString(cString);
CheckError(conf);
return view;
}
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<core::Annotation> Function::GetAnnotations() const
{
const ApiConfig *conf = GetApiConfig();
std::vector<core::Annotation> anns;
using EnumerateData = std::pair<std::vector<core::Annotation> *, const ApiConfig *>;
EnumerateData enumerateData(&anns, conf);
conf->cIapi_->functionEnumerateAnnotations(GetView(), (void *)&enumerateData,
[](AbckitCoreAnnotation *ann, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Annotation(ann, config));
return true;
});
CheckError(conf);
return anns;
}
inline bool Function::IsStatic() const
{
const ApiConfig *conf = GetApiConfig();
bool result = conf->cIapi_->functionIsStatic(GetView());
CheckError(conf);
return result;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_FUNCTION_IMPL_H

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_H
#define CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_H
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/metadata_core.h"
#include <string_view>
#include <vector>
namespace abckit::core {
class ImportDescriptor : public View<AbckitCoreImportDescriptor *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::File;
friend class abckit::core::Module;
friend class abckit::arkts::Module;
public:
ImportDescriptor(const ImportDescriptor &other) = default;
ImportDescriptor &operator=(const ImportDescriptor &other) = default;
ImportDescriptor(ImportDescriptor &&other) = default;
ImportDescriptor &operator=(ImportDescriptor &&other) = default;
~ImportDescriptor() override = default;
std::string_view GetName() const;
// Core API's.
// ...
private:
ImportDescriptor(AbckitCoreImportDescriptor *module, const ApiConfig *conf) : View(module), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_IMPL_H
#define CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_IMPL_H
#include "cpp/headers/core/import_descriptor.h"
namespace abckit::core {
inline std::string_view ImportDescriptor::GetName() const
{
AbckitString *abcName = GetApiConfig()->cIapi_->importDescriptorGetName(GetView());
CheckError(GetApiConfig());
std::string_view name = GetApiConfig()->cIapi_->abckitStringToString(abcName);
CheckError(GetApiConfig());
return name;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_IMPORT_DESCRIPTOR_IMPL_H

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_MODULE_H
#define CPP_ABCKIT_CORE_MODULE_H
#include "cpp/headers/declarations.h"
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/class.h"
#include "cpp/headers/core/export_descriptor.h"
#include "cpp/headers/core/import_descriptor.h"
#include "cpp/headers/core/namespace.h"
#include "libabckit/include/c/metadata_core.h"
#include <string_view>
#include <vector>
namespace abckit::core {
class Module : public View<AbckitCoreModule *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class abckit::File;
public:
Module(const Module &other) = default;
Module &operator=(const Module &other) = default;
Module(Module &&other) = default;
Module &operator=(Module &&other) = default;
~Module() override = default;
std::vector<core::Class> GetClasses() const;
std::vector<core::Function> GetTopLevelFunctions() const;
std::vector<core::AnnotationInterface> GetAnnotationInterfaces() const;
std::vector<core::Namespace> GetNamespaces() const;
std::vector<core::ImportDescriptor> GetImports() const;
std::vector<core::ExportDescriptor> GetExports() const;
// Core API's.
// ...
private:
inline void GetClassesInner(std::vector<core::Class> &classes) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Class> *, const ApiConfig *>;
EnumerateData enumerateData(&classes, GetApiConfig());
conf->cIapi_->moduleEnumerateClasses(GetView(), (void *)&enumerateData, [](AbckitCoreClass *klass, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Class(klass, config));
return true;
});
}
inline void GetTopLevelFunctionsInner(std::vector<core::Function> &functions) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Function> *, const ApiConfig *>;
EnumerateData enumerateData(&functions, conf);
conf->cIapi_->moduleEnumerateTopLevelFunctions(GetView(), (void *)&enumerateData,
[](AbckitCoreFunction *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Function(func, config));
return true;
});
}
inline void GetAnnotationInterfacesInner(std::vector<core::AnnotationInterface> &ifaces) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::AnnotationInterface> *, const ApiConfig *>;
EnumerateData enumerateData(&ifaces, conf);
conf->cIapi_->moduleEnumerateAnnotationInterfaces(GetView(), (void *)&enumerateData,
[](AbckitCoreAnnotationInterface *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::AnnotationInterface(func, config));
return true;
});
}
inline void GetNamespacesInner(std::vector<core::Namespace> &namespaces) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Namespace> *, const ApiConfig *>;
EnumerateData enumerateData(&namespaces, conf);
conf->cIapi_->moduleEnumerateNamespaces(GetView(), (void *)&enumerateData,
[](AbckitCoreNamespace *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Namespace(func, config));
return true;
});
}
inline void GetImportsInner(std::vector<core::ImportDescriptor> &imports) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::ImportDescriptor> *, const ApiConfig *>;
EnumerateData enumerateData(&imports, conf);
conf->cIapi_->moduleEnumerateImports(GetView(), (void *)&enumerateData,
[](AbckitCoreImportDescriptor *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::ImportDescriptor(func, config));
return true;
});
}
inline void GetExportsInner(std::vector<core::ExportDescriptor> &exports) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::ExportDescriptor> *, const ApiConfig *>;
EnumerateData enumerateData(&exports, conf);
conf->cIapi_->moduleEnumerateExports(GetView(), (void *)&enumerateData,
[](AbckitCoreExportDescriptor *func, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::ExportDescriptor(func, config));
return true;
});
}
Module(AbckitCoreModule *module, const ApiConfig *conf) : View(module), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_MODULE_H

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_MODULE_IMPL_H
#define CPP_ABCKIT_CORE_MODULE_IMPL_H
#include "cpp/headers/core/module.h"
#include "cpp/headers/declarations.h"
#include "libabckit/include/c/metadata_core.h"
namespace abckit::core {
inline std::vector<core::Class> Module::GetClasses() const
{
std::vector<core::Class> classes;
GetClassesInner(classes);
CheckError(GetApiConfig());
return classes;
}
inline std::vector<core::Function> Module::GetTopLevelFunctions() const
{
std::vector<core::Function> functions;
GetTopLevelFunctionsInner(functions);
CheckError(GetApiConfig());
return functions;
}
inline std::vector<core::AnnotationInterface> Module::GetAnnotationInterfaces() const
{
std::vector<core::AnnotationInterface> ifaces;
GetAnnotationInterfacesInner(ifaces);
CheckError(GetApiConfig());
return ifaces;
}
inline std::vector<core::Namespace> Module::GetNamespaces() const
{
std::vector<core::Namespace> namespaces;
GetNamespacesInner(namespaces);
CheckError(GetApiConfig());
return namespaces;
}
inline std::vector<core::ImportDescriptor> Module::GetImports() const
{
std::vector<core::ImportDescriptor> imports;
GetImportsInner(imports);
CheckError(GetApiConfig());
return imports;
}
inline std::vector<core::ExportDescriptor> Module::GetExports() const
{
std::vector<core::ExportDescriptor> exports;
GetExportsInner(exports);
CheckError(GetApiConfig());
return exports;
}
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_MODULE_IMPL_H

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_CORE_NAMESPACE_H
#define CPP_ABCKIT_CORE_NAMESPACE_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/core/annotation_interface.h"
#include "cpp/headers/core/function.h"
#include <vector>
#include <utility>
namespace abckit::core {
class Namespace : public View<AbckitCoreNamespace *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Module;
public:
Namespace(const Namespace &other) = default;
Namespace &operator=(const Namespace &other) = default;
Namespace(Namespace &&other) = default;
Namespace &operator=(Namespace &&other) = default;
~Namespace() override = default;
std::string_view GetName() const
{
AbckitString *abcName = GetApiConfig()->cIapi_->namespaceGetName(GetView());
CheckError(GetApiConfig());
std::string_view name = GetApiConfig()->cIapi_->abckitStringToString(abcName);
CheckError(GetApiConfig());
return name;
}
// Core API's.
// ...
private:
Namespace(AbckitCoreNamespace *ns, const ApiConfig *conf) : View(ns), conf_(conf) {};
const ApiConfig *conf_;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
};
} // namespace abckit::core
#endif // CPP_ABCKIT_CORE_NAMESPACE_H

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_DECLARATIONS_H
#define CPP_ABCKIT_DECLARATIONS_H
namespace abckit {
// ISA API's
class DynamicIsa;
class StaticIsa;
// IR core interfaces
class Graph;
class BasicBlock;
class Instruction;
// Language-independent entities interfaces
class File;
class Type;
class Value;
class Literal;
class LiteralArray;
// Core declarations
namespace core {
class Module; // Check
class Namespace; // Check
class Class; // Check
class Function; // Check
class Field;
class Annotation; // Check
class AnnotationElement; // Check
class AnnotationInterface; // Check
class AnnotationInterfaceField; // Check
class ImportDescriptor;
class ExportDescriptor;
} // namespace core
// ArkTS extension declarations
namespace arkts {
class Module;
class Namespace;
class Class;
class Function;
class Field;
class Annotation;
class AnnotationElement;
class AnnotationInterface;
class AnnotationInterfaceField;
class ImportDescriptor;
class ExportDescriptor;
} // namespace arkts
} // namespace abckit
#endif // CPP_ABCKIT_DECLARATIONS_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_DYNAMIC_ISA_H
#define CPP_ABCKIT_DYNAMIC_ISA_H
#include "cpp/headers/config.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/instruction.h"
#include <memory>
namespace abckit {
// Third type of Entity? Or just a view?
class DynamicIsa final {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class Graph;
public:
DynamicIsa(const DynamicIsa &other) = delete;
DynamicIsa &operator=(const DynamicIsa &other) = delete;
DynamicIsa(DynamicIsa &&other) = delete;
DynamicIsa &operator=(DynamicIsa &&other) = delete;
~DynamicIsa() = default;
// Rvalue annotated so we can call it only in callchain context
Instruction CreateLoadString(const std::string &str) &&;
Instruction CreateTryldglobalbyname(const std::string &str) &&;
Instruction CreateCallArg1(const Instruction &acc, const Instruction &input0) &&;
// Other dynamic API methods declarations
private:
explicit DynamicIsa(const Graph &graph) : graph_(graph) {};
const Graph &graph_;
};
} // namespace abckit
#endif // CPP_ABCKIT_DYNAMIC_ISA_H

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_DYNAMIC_ISA_IMPL_H
#define CPP_ABCKIT_DYNAMIC_ISA_IMPL_H
#include "cpp/headers/dynamic_isa.h"
#include "cpp/headers/instruction.h"
#include "cpp/headers/graph.h"
#include <memory>
namespace abckit {
inline Instruction DynamicIsa::CreateCallArg1(const Instruction &acc, const Instruction &input0) &&
{
const ApiConfig *conf = graph_.GetApiConfig();
AbckitInst *callArg1 = conf->cDynapi_->iCreateCallarg1(graph_.GetResource(), acc.GetView(), input0.GetView());
CheckError(conf);
return Instruction(callArg1, conf);
}
inline Instruction DynamicIsa::CreateTryldglobalbyname(const std::string &str) &&
{
const ApiConfig *conf = graph_.GetApiConfig();
AbckitFile *file = conf->cGapi_->gGetFile(graph_.GetResource());
CheckError(conf);
AbckitInst *callArg1 =
conf->cDynapi_->iCreateTryldglobalbyname(graph_.GetResource(), conf->cMapi_->createString(file, str.c_str()));
CheckError(conf);
return Instruction(callArg1, conf);
}
inline Instruction DynamicIsa::CreateLoadString(const std::string &str) &&
{
auto *conf = graph_.GetApiConfig();
AbckitFile *file = conf->cGapi_->gGetFile(graph_.GetResource());
CheckError(conf);
AbckitString *abcStr = conf->cMapi_->createString(file, str.c_str());
CheckError(conf);
AbckitInst *abcLoadstring = conf->cDynapi_->iCreateLoadString(graph_.GetResource(), abcStr);
CheckError(conf);
return Instruction(abcLoadstring, conf);
}
} // namespace abckit
#endif // CPP_ABCKIT_DYNAMIC_ISA_IMPL_H

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_FILE_H
#define CPP_ABCKIT_FILE_H
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/isa/isa_dynamic.h"
#include "libabckit/src/include_v2/c/isa/isa_static.h"
#include "libabckit/include/cpp/headers/base_classes.h"
#include "libabckit/include/cpp/headers/config.h"
#include "libabckit/include/cpp/headers/declarations.h"
#include "libabckit/include/cpp/headers/basic_block.h"
#include "libabckit/include/cpp/headers/instruction.h"
#include "libabckit/include/cpp/headers/dynamic_isa.h"
#include "libabckit/include/cpp/headers/value.h"
#include "libabckit/include/cpp/headers/literal.h"
#include "libabckit/include/cpp/headers/literal_array.h"
#include "libabckit/src/include_v2/cpp/headers/static_isa.h"
#include "libabckit/include/cpp/headers/core/module.h"
#include "libabckit/include/c/metadata_core.h"
#include <memory>
#include <vector>
namespace abckit {
class File final : public Resource<AbckitFile *> {
private:
class FileDeleter final : public IResourceDeleter {
public:
FileDeleter(const ApiConfig *conf, const File &file) : conf_(conf), deleterFile_(file) {};
FileDeleter(const FileDeleter &other) = delete;
FileDeleter &operator=(const FileDeleter &other) = delete;
FileDeleter(FileDeleter &&other) = delete;
FileDeleter &operator=(FileDeleter &&other) = delete;
~FileDeleter() override = default;
void DeleteResource() override
{
conf_->cApi_->closeFile(deleterFile_.GetResource());
}
private:
const ApiConfig *conf_;
const File &deleterFile_;
};
public:
explicit File(const char *path) : File(std::string(path)) {};
explicit File(const std::string &path) : File(path, std::make_unique<DefaultErrorHandler>()) {}
File(const File &file) = delete;
File &operator=(const File &file) = delete;
File(File &&file) = delete;
File &operator=(File &&file) = delete;
File(const std::string &path, std::unique_ptr<IErrorHandler> eh)
: Resource(AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0)->openAbc(path.c_str())), conf_(std::move(eh))
{
CheckError(&conf_);
SetDeleter(std::make_unique<FileDeleter>(&conf_, *this));
}
~File() override = default;
abckit::Value CreateValueU1(bool val)
{
AbckitValue *value = GetApiConfig()->cMapi_->createValueU1(GetResource(), val);
CheckError(GetApiConfig());
return abckit::Value(value, GetApiConfig());
}
abckit::Value CreateValueDouble(double val)
{
AbckitValue *value = GetApiConfig()->cMapi_->createValueDouble(GetResource(), val);
CheckError(GetApiConfig());
return abckit::Value(value, GetApiConfig());
}
abckit::Literal CreateLiteralBool(bool val)
{
AbckitLiteral *literal = GetApiConfig()->cMapi_->createLiteralBool(GetResource(), val);
CheckError(GetApiConfig());
return abckit::Literal(literal, GetApiConfig());
}
abckit::Literal CreateLiteralDouble(double val)
{
AbckitLiteral *literal = GetApiConfig()->cMapi_->createLiteralDouble(GetResource(), val);
CheckError(GetApiConfig());
return abckit::Literal(literal, GetApiConfig());
}
abckit::Literal CreateLiteralU32(double val)
{
AbckitLiteral *literal = GetApiConfig()->cMapi_->createLiteralU32(GetResource(), val);
CheckError(GetApiConfig());
return abckit::Literal(literal, GetApiConfig());
}
abckit::Literal CreateLiteralLiteralArray(const abckit::LiteralArray &val)
{
AbckitLiteral *literal = GetApiConfig()->cMapi_->createLiteralLiteralArray(GetResource(), val.GetView());
CheckError(GetApiConfig());
return abckit::Literal(literal, GetApiConfig());
}
abckit::LiteralArray CreateLiteralArray(const std::vector<abckit::Literal> &literals) const;
void WriteAbc(const std::string &path)
{
GetApiConfig()->cApi_->writeAbc(GetResource(), path.c_str());
CheckError(GetApiConfig());
}
// Returns a vector of core::Module's in a particular file
std::vector<core::Module> GetModules() const;
// Returns all functions in a file (consider to delete for mainenace reasons)
std::vector<core::Function> GetAllFunctions() const;
// Other API.
protected:
const ApiConfig *GetApiConfig() const override
{
return &conf_;
}
private:
inline void GetAllFunctionsInner(std::vector<core::Function> &functions) const
{
for (auto &module : GetModules()) {
for (auto &klass : module.GetClasses()) {
for (auto &function : klass.GetAllMethods()) {
functions.push_back(function);
}
}
for (auto &function : module.GetTopLevelFunctions()) {
functions.push_back(function);
}
}
}
inline void GetModulesInner(std::vector<core::Module> &modules) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<core::Module> *, const ApiConfig *>;
EnumerateData enumerateData(&modules, conf);
conf->cIapi_->fileEnumerateModules(GetResource(), (void *)&enumerateData,
[](AbckitCoreModule *module, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Module(module, config));
return true;
});
}
const ApiConfig conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_FILE_H

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_FILE_IMPL_H
#define CPP_ABCKIT_FILE_IMPL_H
#include "cpp/headers/file.h"
namespace abckit {
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<core::Module> File::GetModules() const
{
const ApiConfig *conf = GetApiConfig();
std::vector<core::Module> modules;
using EnumerateData = std::pair<std::vector<core::Module> *, const ApiConfig *>;
EnumerateData enumerateData(&modules, conf);
conf->cIapi_->fileEnumerateModules(GetResource(), (void *)&enumerateData, [](AbckitCoreModule *module, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(core::Module(module, config));
return true;
});
CheckError(conf);
return modules;
}
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<core::Function> File::GetAllFunctions() const
{
std::vector<core::Function> functions;
for (auto &module : GetModules()) {
for (auto &klass : module.GetClasses()) {
for (auto &function : klass.GetAllMethods()) {
functions.push_back(function);
}
}
for (auto &function : module.GetTopLevelFunctions()) {
functions.push_back(function);
}
}
CheckError(GetApiConfig());
return functions;
}
inline abckit::LiteralArray File::CreateLiteralArray(const std::vector<abckit::Literal> &literals) const
{
std::vector<AbckitLiteral *> litsImpl;
litsImpl.reserve(literals.size());
for (const auto &literal : literals) {
litsImpl.push_back(literal.GetView());
}
AbckitLiteralArray *litaIml =
GetApiConfig()->cMapi_->createLiteralArray(GetResource(), litsImpl.data(), litsImpl.size());
CheckError(GetApiConfig());
return abckit::LiteralArray(litaIml, GetApiConfig());
}
} // namespace abckit
#endif // CPP_ABCKIT_FILE_IMPL_H

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_GRAPH_H
#define CPP_ABCKIT_GRAPH_H
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/isa/isa_dynamic.h"
#include "libabckit/src/include_v2/c/isa/isa_static.h"
#include "libabckit/include/cpp/headers/base_classes.h"
#include "libabckit/include/cpp/headers/config.h"
#include "libabckit/include/cpp/headers/declarations.h"
#include "libabckit/include/cpp/headers/basic_block.h"
#include "libabckit/include/cpp/headers/dynamic_isa.h"
#include "libabckit/src/include_v2/cpp/headers/static_isa.h"
#include <memory>
#include <vector>
namespace abckit {
class Graph final : public Resource<AbckitGraph *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class core::Function;
friend class DynamicIsa;
friend class StaticIsa;
public:
Graph(const Graph &other) = delete;
Graph &operator=(const Graph &other) = delete;
Graph(Graph &&other) = default;
Graph &operator=(Graph &&other) = default;
~Graph() override = default;
BasicBlock GetStartBb() const;
std::vector<BasicBlock> GetBlocksRPO() const;
DynamicIsa DynIsa()
{
return DynamicIsa(*this);
}
StaticIsa StatIsa()
{
return StaticIsa(*this);
}
// Other Graph API's
// ...
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
class GraphDeleter final : public IResourceDeleter {
public:
GraphDeleter(const ApiConfig *conf, const Graph &graph) : conf_(conf), deleterGraph_(graph) {};
GraphDeleter(const GraphDeleter &other) = delete;
GraphDeleter &operator=(const GraphDeleter &other) = delete;
GraphDeleter(GraphDeleter &&other) = delete;
GraphDeleter &operator=(GraphDeleter &&other) = delete;
~GraphDeleter() override = default;
void DeleteResource() override
{
// NOTE(nsizov): add Graph destroying when C API will stop delete graph on functionSetGraph
(void)conf_;
(void)deleterGraph_;
}
private:
const ApiConfig *conf_;
const Graph &deleterGraph_;
};
inline void GetBlocksRPOInner(std::vector<BasicBlock> &blocks) const
{
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<BasicBlock> *, const ApiConfig *>;
EnumerateData enumerateData(&blocks, conf);
conf->cGapi_->gVisitBlocksRpo(GetResource(), (void *)&enumerateData, [](AbckitBasicBlock *bb, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(BasicBlock(bb, config));
});
}
Graph(AbckitGraph *graph, const ApiConfig *conf) : Resource(graph), conf_(conf)
{
SetDeleter(std::make_unique<GraphDeleter>(conf_, *this));
};
// for interop with API
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_GRAPH_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_GRAPH_IMPL_H
#define CPP_ABCKIT_GRAPH_IMPL_H
#include "cpp/headers/graph.h"
namespace abckit {
inline BasicBlock Graph::GetStartBb() const
{
const ApiConfig *conf = GetApiConfig();
AbckitBasicBlock *bb = conf->cGapi_->gGetStartBasicBlock(GetResource());
CheckError(conf);
return BasicBlock(bb, conf);
}
// CC-OFFNXT(G.FUD.06) perf critical
inline std::vector<BasicBlock> Graph::GetBlocksRPO() const
{
std::vector<BasicBlock> blocks;
const ApiConfig *conf = GetApiConfig();
using EnumerateData = std::pair<std::vector<BasicBlock> *, const ApiConfig *>;
EnumerateData enumerateData(&blocks, conf);
conf->cGapi_->gVisitBlocksRpo(GetResource(), (void *)&enumerateData, [](AbckitBasicBlock *bb, void *data) {
auto *vec = static_cast<EnumerateData *>(data)->first;
auto *config = static_cast<EnumerateData *>(data)->second;
vec->push_back(BasicBlock(bb, config));
});
CheckError(conf);
return blocks;
}
} // namespace abckit
#endif // CPP_ABCKIT_GRAPH_IMPL_H

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_INSTRUCTION_H
#define CPP_ABCKIT_INSTRUCTION_H
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/isa/isa_dynamic.h"
#include "libabckit/src/include_v2/c/isa/isa_static.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/config.h"
#include "cpp/headers/declarations.h"
#include <memory>
namespace abckit {
class Instruction final : public View<AbckitInst *> {
// To access private constructor.
// We restrict constructors in order to prevent C/C++ API mix-up by user.
friend class BasicBlock;
friend class StaticIsa;
friend class DynamicIsa;
public:
Instruction(const Instruction &other) = default;
Instruction &operator=(const Instruction &other) = default;
Instruction(Instruction &&other) = default;
Instruction &operator=(Instruction &&other) = default;
~Instruction() override = default;
Instruction &InsertAfter(const Instruction &inst);
Instruction &InsertBefore(const Instruction &inst);
AbckitIsaApiDynamicOpcode GetOpcodeDyn() const;
AbckitIsaApiStaticOpcode GetOpcodeStat() const;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
Instruction(AbckitInst *inst, const ApiConfig *conf) : View(inst), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_INSTRUCTION_H

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_INSTRUCTION_IMPL_H
#define CPP_ABCKIT_INSTRUCTION_IMPL_H
#include "cpp/headers/instruction.h"
namespace abckit {
inline Instruction &Instruction::InsertAfter(const Instruction &inst)
{
const ApiConfig *conf = GetApiConfig();
conf->cGapi_->iInsertAfter(GetView(), inst.GetView());
CheckError(conf);
return *this;
}
inline Instruction &Instruction::InsertBefore(const Instruction &inst)
{
const ApiConfig *conf = GetApiConfig();
conf->cGapi_->iInsertBefore(GetView(), inst.GetView());
CheckError(conf);
return *this;
}
inline AbckitIsaApiDynamicOpcode Instruction::GetOpcodeDyn() const
{
const ApiConfig *conf = GetApiConfig();
AbckitIsaApiDynamicOpcode opc = conf->cDynapi_->iGetOpcode(GetView());
CheckError(conf);
return opc;
}
inline AbckitIsaApiStaticOpcode Instruction::GetOpcodeStat() const
{
const ApiConfig *conf = GetApiConfig();
AbckitIsaApiStaticOpcode opc = conf->cStatapi_->iGetOpcode(GetView());
CheckError(conf);
return opc;
}
} // namespace abckit
#endif // CPP_ABCKIT_INSTRUCTION_IMPL_H

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_LITERAL_H
#define CPP_ABCKIT_LITERAL_H
#include "cpp/headers/utils.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "cpp/headers/literal_array.h"
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/metadata_core.h"
namespace abckit {
class Literal : public View<AbckitLiteral *> {
friend class abckit::File;
public:
Literal(const Literal &other) = default;
Literal &operator=(const Literal &other) = default;
Literal(Literal &&other) = default;
Literal &operator=(Literal &&other) = default;
~Literal() override = default;
bool GetBool() const;
abckit::LiteralArray GetLiteralArray() const;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
Literal(AbckitLiteral *lit, const ApiConfig *conf) : View(lit), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_LITERAL_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_LITERAL_ARRAY_H
#define CPP_ABCKIT_LITERAL_ARRAY_H
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/metadata_core.h"
#include <vector>
namespace abckit {
class LiteralArray : public View<AbckitLiteralArray *> {
friend class abckit::File;
friend class abckit::Literal;
public:
LiteralArray(const LiteralArray &other) = default;
LiteralArray &operator=(const LiteralArray &other) = default;
LiteralArray(LiteralArray &&other) = default;
LiteralArray &operator=(LiteralArray &&other) = default;
~LiteralArray() override = default;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
LiteralArray(AbckitLiteralArray *lita, const ApiConfig *conf) : View(lita), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_LITERAL_ARRAY_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_LITERAL_IMPL_H
#define CPP_ABCKIT_LITERAL_IMPL_H
#include "cpp/headers/literal.h"
namespace abckit {
inline bool Literal::GetBool() const
{
bool ret = GetApiConfig()->cIapi_->literalGetBool(GetView());
CheckError(GetApiConfig());
return ret;
}
inline abckit::LiteralArray Literal::GetLiteralArray() const
{
LiteralArray ret(GetApiConfig()->cIapi_->literalGetLiteralArray(GetView()), GetApiConfig());
CheckError(GetApiConfig());
return ret;
}
} // namespace abckit
#endif // CPP_ABCKIT_LITERAL_IMPL_H

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_TYPE_H
#define CPP_ABCKIT_TYPE_H
#include "cpp/headers/core/annotation.h"
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/metadata_core.h"
namespace abckit {
class Type : public View<AbckitType *> {
friend class abckit::File;
public:
Type(const Type &other) = default;
Type &operator=(const Type &other) = default;
Type(Type &&other) = default;
Type &operator=(Type &&other) = default;
~Type() override = default;
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
explicit Type(AbckitType *val, const ApiConfig *conf) : View(val), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_TYPE_H

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_UTILS_H
#define CPP_ABCKIT_UTILS_H
#include "libabckit/include/c/statuses.h"
#include "statuses_impl.h"
#include "cpp/headers/declarations.h"
#include <string>
#ifdef ABCKIT_USE_EXCEPTIONS
#include <stdexcept>
#endif
namespace abckit {
class ApiConfig;
// CC-OFFNXT(G.FUD.06) perf critical
// NOLINTBEGIN(performance-unnecessary-value-param)
inline std::string StatusToString(AbckitStatus status)
{
switch (status) {
case ABCKIT_STATUS_NO_ERROR:
return "No error";
case ABCKIT_STATUS_BAD_ARGUMENT:
return "Bad argument";
case ABCKIT_STATUS_MEMORY_ALLOCATION:
return "Memory allocation error";
case ABCKIT_STATUS_WRONG_MODE:
return "Wrong mode";
case ABCKIT_STATUS_WRONG_TARGET:
return "Wrong target";
case ABCKIT_STATUS_WRONG_LITERAL_TYPE:
return "Wrong literal type";
case ABCKIT_STATUS_UNSUPPORTED:
return "Unsupported feature";
case ABCKIT_STATUS_WRONG_CTX:
return "Wrong context";
case ABCKIT_STATUS_TODO:
default:
break;
}
return "Unsupported status type";
}
#ifdef ABCKIT_USE_EXCEPTIONS
class Exception : public std::runtime_error {
public:
explicit Exception(AbckitStatus e) : std::runtime_error(StatusToString(e)) {}
virtual const char *what() const noexcept override
{
return std::runtime_error::what();
}
};
#else
class Exception {
public:
explicit Exception(AbckitStatus e) : whatMessage_(StatusToString(e)) {}
const char *What() const noexcept
{
return whatMessage_.c_str();
}
private:
std::string whatMessage_;
};
#endif
class IErrorHandler {
public:
IErrorHandler() = default;
IErrorHandler(const IErrorHandler &other) = default;
IErrorHandler &operator=(const IErrorHandler &other) = default;
IErrorHandler(IErrorHandler &&other) = default;
IErrorHandler &operator=(IErrorHandler &&other) = default;
virtual ~IErrorHandler() = default;
virtual void HandleError(Exception &&e) = 0;
};
class DefaultErrorHandler final : public IErrorHandler {
public:
DefaultErrorHandler() = default;
DefaultErrorHandler(const DefaultErrorHandler &other) = default;
DefaultErrorHandler &operator=(const DefaultErrorHandler &other) = default;
DefaultErrorHandler(DefaultErrorHandler &&other) = default;
DefaultErrorHandler &operator=(DefaultErrorHandler &&other) = default;
~DefaultErrorHandler() override = default;
void HandleError([[maybe_unused]] Exception &&e) override
{
// Default behaviour - do nothing.
// If at compile time exceptions are enabled - re-throw.
#ifdef ABCKIT_USE_EXCEPTIONS
throw e;
#endif
}
};
class IResourceDeleter {
public:
IResourceDeleter() = default;
IResourceDeleter(const IResourceDeleter &other) = default;
IResourceDeleter &operator=(const IResourceDeleter &other) = default;
IResourceDeleter(IResourceDeleter &&other) = default;
IResourceDeleter &operator=(IResourceDeleter &&other) = default;
virtual ~IResourceDeleter() = default;
virtual void DeleteResource() = 0;
};
class DefaultResourceDeleter final : public IResourceDeleter {
public:
DefaultResourceDeleter() = default;
DefaultResourceDeleter(const DefaultResourceDeleter &other) = default;
DefaultResourceDeleter &operator=(const DefaultResourceDeleter &other) = default;
DefaultResourceDeleter(DefaultResourceDeleter &&other) = default;
DefaultResourceDeleter &operator=(DefaultResourceDeleter &&other) = default;
~DefaultResourceDeleter() override = default;
void DeleteResource() override
{ /* Do nothing by default. Debug log here, probably? */
}
};
} // namespace abckit
#endif // CPP_ABCKIT_UTILS_H

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CPP_ABCKIT_VALUE_H
#define CPP_ABCKIT_VALUE_H
#include "cpp/headers/core/annotation.h"
#include "libabckit/include/c/abckit.h"
#include "cpp/headers/declarations.h"
#include "cpp/headers/config.h"
#include "cpp/headers/base_classes.h"
#include "libabckit/include/c/metadata_core.h"
namespace abckit {
class Value : public View<AbckitValue *> {
friend class abckit::File;
friend class abckit::core::Annotation;
friend class abckit::arkts::Annotation;
public:
Value(const Value &other) = default;
Value &operator=(const Value &other) = default;
Value(Value &&other) = default;
Value &operator=(Value &&other) = default;
~Value() override = default;
bool GetU1() const
{
bool ret = GetApiConfig()->cIapi_->valueGetU1(GetView());
CheckError(GetApiConfig());
return ret;
}
double GetDouble() const
{
double ret = GetApiConfig()->cIapi_->valueGetDouble(GetView());
CheckError(GetApiConfig());
return ret;
}
protected:
const ApiConfig *GetApiConfig() const override
{
return conf_;
}
private:
explicit Value(AbckitValue *val, const ApiConfig *conf) : View(val), conf_(conf) {};
const ApiConfig *conf_;
};
} // namespace abckit
#endif // CPP_ABCKIT_VALUE_H

View File

@ -0,0 +1,20 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
js_root = "//arkcompiler/ets_runtime"
abckit_root = "//arkcompiler/runtime_core/libabckit"
declare_args() {
enable_libabckit = false
libabckit_with_sanitizers = false
}

20
libabckit/package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "libabckit",
"version": "1.0.0",
"description": "libabckit is a tool for binary manipulation. eslint is needed to ensure codecheck",
"main": "index.js",
"directories": {
"tests": "tests"
},
"type": "module",
"scripts": {
"test": "npx eslint",
"fix": "npx eslint --fix"
},
"dependencies": {
"eslint": "^9.13.0"
},
"devDependencies": {
"@stylistic/eslint-plugin-js": "^2.9.0"
}
}

2
libabckit/scripts/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
abckit_status.csv

View File

@ -0,0 +1,50 @@
#!/bin/bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A very simple wrapper around clang-format:
# Compare the original file with what clang-format thinks it should
# look like and output corresponding diff. Exit with the same code as diff.
#
# USAGE:
# scripts/run-clang-format /path/to/clang-format /path/to/checked/file
#
# The only reason of this script's existence is to avoid messing with
# escaping special chatracters in CMake files.
set -exu
FILE_NAME="${1}"
CLANG_FORMAT_BIN="clang-format-14"
SCRIPT_DIR="$(dirname $(realpath "${0}"))"
if [ ! -f "${FILE_NAME}" ]; then
echo "FATAL: Input file '${FILE_NAME}' is not found"
exit 1
fi
# Here we rely on diff's exit code:
diff -u --color=auto \
--label="${FILE_NAME} (original)" \
--label="${FILE_NAME} (reformatted)" \
"${FILE_NAME}" <(${CLANG_FORMAT_BIN} "${FILE_NAME}")
# Run additional checks
SCRIPTS_DIR="${SCRIPT_DIR}/../extras/code_style/"
SCRIPTS_TO_RUN=("run-check-concurrency-format.sh" "run_check_atomic_format.py")
for S in "${SCRIPTS_TO_RUN[@]}"; do
if [ -f "${SCRIPTS_DIR}/${S}" ]; then
"${SCRIPTS_DIR}/${S}" "${FILE_NAME}"
fi
done

View File

@ -0,0 +1,36 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def collect_implemented_api_map(excluded_funcs)
implemented_api_raw = nil
Dir.chdir(File.dirname(__FILE__)) do
implemented_api_raw = `python get_abckit_status.py --print-implemented`.split(/\n/)
end
implemented_api_map = {}
implemented_api_raw.each do |api_func_raw|
domain, api_func = *api_func_raw.split(/::/)
if excluded_funcs.include?(api_func)
next
end
if implemented_api_map[domain].nil?
implemented_api_map[domain] = [api_func]
else
implemented_api_map[domain].append(api_func)
end
end
return implemented_api_map
end

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
base="$(basename $1)"
tmp="$(echo $base | sed 's/\..*//')"
tmp_file="/tmp/merge_$tmp.txt"
echo "$base;$tmp;esm;$base;entry" > $tmp_file
dir="$(dirname $1)"
modules_dir="$dir/modules"
if [ -d "$modules_dir" ]; then
for file in "$modules_dir"/*; do
name=$(basename "$file")
tmp_module="$(echo $name | sed 's/\..*//')"
echo "modules/$name;modules/$tmp_module;esm;modules/$name;entry" >> $tmp_file
done
fi
/usr/bin/python3 "$(dirname $0)/../../../ets_runtime/test/quickfix/generate_merge_file.py" --input "$tmp_file" --output "$2" --prefix "$dir/"

View File

@ -0,0 +1,187 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'ostruct'
require 'yaml'
scripts_dir = File.dirname(__FILE__)
Dir.chdir(scripts_dir)
isa = YAML.load_file('../../isa/isa.yaml')['groups']
insts = []
def process_inst_params(inst_params)
inst_params.map! { |param|
# param can be either "some_id" or "v:in:any"
param_options = param.split(":")
processed_param = OpenStruct.new
processed_param.name = param_options[0][/[a-z_]*/]
processed_param.direction = param_options[1] ? param_options[1] : "in"
param = processed_param
}
end
isa.each { |isa_title|
isa_title['instructions'].each { |isa_inst|
inst = OpenStruct.new
inst.opcode, *inst.params = isa_inst['sig'].split(' ')
inst.opcode = inst.opcode.split(".").map!{ |str| str.capitalize }.join
process_inst_params(inst.params)
inst.ic = isa_inst['properties'] ?
isa_inst['properties'].any?{
|str| str.include? "ic_slot" or str.include? "jit_ic_slot"
} : false
inst.inacc = isa_inst['acc'] ?
(isa_inst['acc'] =~ /inout:/ or isa_inst['acc'] =~ /in:/): false
insts.append(inst)
}
}
dyn_opcodes = File.open("../include/c/isa/isa_dynamic.h").read.split()
.select{ |str|
str.start_with?("ABCKIT_ISA_API_DYNAMIC_OPCODE_")
}.map!{ |str|
str.delete_prefix("ABCKIT_ISA_API_DYNAMIC_OPCODE_").chop!.split("_").map! { |str|
str.capitalize
}.join
}
declaration_num = 0
# tmp workaround: isa.yaml does not have If opcode, but opcodes.h does
declaration_num += 1
puts "--> declarations"
insts.each { |inst|
next unless dyn_opcodes.include? inst.opcode
declaration_num += 1
indent = ' ' * 4
inst_input = imm_input = 0
declaration = indent + "AbckitInst *(*Icreate#{inst.opcode})(\n"
indent += ' ' * 4
declaration += indent + "/* in */ AbckitGraph *graph"
if inst.inacc
declaration += ",\n" + indent
declaration += "/* in */ AbckitInst *acc"
end
inst.params.each { |param|
# case when first inst param is imm number of ic_slot
next imm_input += 1 if inst.ic and param.name == "imm" and imm_input == 0
declaration += ",\n" + indent
declaration += "/* #{param.direction} */ "
case param.name
when "v"
declaration += "AbckitInst *input#{inst_input}"
inst_input += 1
when "method_id"
declaration += "AbckitCoreFunction *method"
when "literalarray_id"
declaration += "AbckitLiteralArray *literalArray"
when "string_id"
declaration += "AbckitString *string"
when "imm"
case inst.opcode
when "Getmodulenamespace", "WideGetmodulenamespace"
declaration += "AbckitCoreModule *md"
when "Ldexternalmodulevar", "WideLdexternalmodulevar"
declaration += "AbckitCoreImportDescriptor *id"
when "Ldlocalmodulevar", "WideLdlocalmodulevar", "Stmodulevar", "WideStmodulevar"
declaration += "AbckitCoreExportDescriptor *ed"
else
declaration += "uint64_t imm#{inst.ic ? imm_input - 1 : imm_input}"
end
imm_input += 1
else
puts "Unknown type of inst param"
exit 1
end
}
declaration += ");"
puts declaration
puts "\n"
}
if declaration_num != dyn_opcodes.length()
puts "Missed some declarations"
puts "total printed declarations: #{declaration_num}"
puts "total dynamic opcodes: #{dyn_opcodes.length()}"
dyn_opcodes.each { |opcode|
next unless insts.index { |inst| inst.opcode == opcode }.nil?
puts "No declaration for #{opcode} opcode"
}
exit 1
end
puts "--> definitions"
insts.each { |inst|
next unless dyn_opcodes.include? inst.opcode
inst_input = imm_input = 0
definition = "extern \"C\" AbckitInst *Icreate#{inst.opcode}("
definition += "AbckitGraph *graph"
if inst.inacc
definition += ", AbckitInst *acc"
end
inst.params.each { |param|
# case when first inst param is imm number of ic_slot
next imm_input += 1 if inst.ic and param.name == "imm" and imm_input == 0
case param.name
when "v"
definition += ", AbckitInst *input#{inst_input}"
inst_input += 1
when "method_id"
definition += ", AbckitCoreFunction *method"
when "literalarray_id"
definition += ", AbckitLiteralArray *literalArray"
when "string_id"
definition += ", AbckitString *string"
when "imm"
case inst.opcode
when "Getmodulenamespace", "WideGetmodulenamespace"
definition += ", AbckitCoreModule *md"
when "Ldexternalmodulevar", "WideLdexternalmodulevar"
definition += ", AbckitCoreImportDescriptor *id"
when "Ldlocalmodulevar", "WideLdlocalmodulevar", "Stmodulevar", "WideStmodulevar"
definition += ", AbckitCoreExportDescriptor *ed"
else
definition += ", uint64_t imm#{inst.ic ? imm_input - 1 : imm_input}"
end
imm_input += 1
else
puts "Unknown type of inst param"
exit 1
end
}
indent = ' ' * 4
definition += ")\n{\n";
definition += indent + "LIBABCKIT_UNIMPLEMENTED\n";
definition += "}\n";
puts definition
puts "\n"
}
puts "--> dyn instruction constructor names"
insts.each { |inst|
next unless dyn_opcodes.include? inst.opcode
constructor_name = "Icreate#{inst.opcode},"
puts constructor_name
}

View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
sed 's/intrinsics://' $1 &> $2

View File

@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
FILE_PATH="${1}"
basename "$FILE_PATH"
echo "Fix options file path in ${FILE_PATH}"
sed -r 's/ PandArg/ panda::PandArg/' $1 | sed 's/PandArgParser/panda::PandArgParser/' &> $2

View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
OUTPUT_DIR="${1}"
shift
for FILE_PATH in "${@}"
do
basename "$FILE_PATH"
f="$(basename -- $FILE_PATH)"
echo "Fix plugin's file path in ${FILE_PATH}"
cat "${FILE_PATH}" | sed -r 's/BytecodeGen/CodeGenStatic/g' &> "${OUTPUT_DIR}/$f"
sed -i 's/plugins\/ets\/bytecode_optimizer\/visitors\///g' "${OUTPUT_DIR}/$f"
done

View File

@ -0,0 +1,45 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'erb'
require_relative 'common_gen_tests_api'
abckit_scripts = File.dirname(__FILE__)
abckit_root = File.expand_path("../", abckit_scripts)
abckit_test = File.join(abckit_root, "/tests/null_args_tests/")
excluded_funcs = [
"getLastError",
"moduleAddImportFromArkTsV2ToArkTsV2",
"moduleAddExportFromArkTsV2ToArkTsV2"
]
implemented_api_map = collect_implemented_api_map(excluded_funcs)
null_args_tests_erb = File.join(abckit_test, "null_args_tests.cpp.erb")
implemented_api_map.each_key do |domain|
iteration = 0
index = 0
slice_size = 100
api_funcs_arr = implemented_api_map[domain]
total_domain_api_funcs = api_funcs_arr.length
puts "#{domain}: #{total_domain_api_funcs}"
while index < total_domain_api_funcs do
testfile_fullpath = File.join(abckit_test, "null_args_tests_#{domain}_#{iteration}.cpp")
res = ERB.new(File.read(null_args_tests_erb), nil, "%").result(binding)
File.write(testfile_fullpath, res)
iteration += 1
index += slice_size
end
end

View File

@ -0,0 +1,371 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'erb'
require_relative 'common_gen_tests_api'
abckit_scripts = File.dirname(__FILE__)
abckit_root = File.expand_path("../", abckit_scripts)
abckit_test = File.join(abckit_root, "/tests/wrong_ctx_tests/")
excluded_funcs = [
"getLastError",
]
funcs_without_two_abckit_entites = [
"destroyGraph",
"closeFile",
"openAbc",
"writeAbc",
"fileGetVersion",
"fileEnumerateModules",
"fileEnumerateExternalModules",
"moduleGetFile",
"moduleGetName",
"moduleIsExternal",
"moduleEnumerateImports",
"moduleEnumerateExports",
"moduleEnumerateClasses",
"moduleEnumerateTopLevelFunctions",
"importDescriptorGetFile",
"importDescriptorGetImportedModule",
"importDescriptorGetImportingModule",
"importDescriptorGetName",
"importDescriptorGetAlias",
"exportDescriptorGetFile",
"exportDescriptorGetExportingModule",
"exportDescriptorGetExportedModule",
"exportDescriptorGetName",
"exportDescriptorGetAlias",
"classGetFile",
"classGetModule",
"classGetName",
"classEnumerateMethods",
"functionGetFile",
"functionGetModule",
"functionGetName",
"functionGetParentClass",
"functionEnumerateAnnotations",
"functionIsStatic",
"functionIsNative",
"functionIsCtor",
"functionIsAnonymous",
"annotationGetFile",
"annotationEnumerateElements",
"typeGetTypeId",
"typeGetReferenceClass",
"literalArrayEnumerateElements",
"arrayValueGetLiteralArray",
"literalGetBool",
"literalGetDouble",
"literalGetFloat",
"literalGetString",
"literalGetMethodAffiliate",
"literalGetTag",
"literalGetU16",
"literalGetMethodAffiliate",
"literalGetU32",
"literalGetU64",
"literalGetU8",
"valueGetDouble",
"valueGetString",
"valueGetType",
"valueGetU1",
"createLiteralArrayValue",
"createLiteralArrayValue",
"createLiteralBool",
"createLiteralDouble",
"createLiteralFloat",
"createLiteralString",
"createLiteralMethodAffiliate",
"createLiteralU16",
"createLiteralMethodAffiliate",
"createLiteralU32",
"createLiteralU64",
"createLiteralU8",
"createReferenceType",
"createString",
"iCreateTypeof",
"createValueDouble",
"createValueString",
"createValueU1",
"moduleRemoveExport",
"moduleRemoveImport",
"iSetConditionCode",
"iSetExportDescriptor",
"iSetInput",
"iSetInputs",
"iSetLiteralArray",
"iSetModule",
"iSetTargetType",
"iVisitInputs",
"iVisitUsers",
"iSetImportDescriptor",
"bbClear",
"bbCreateEmpty",
"bbDump",
"bbGetFalseBranch",
"bbGetTrueBranch",
"bbGetFirstInst",
"bbGetGraph",
"bbGetId",
"bbGetImmediateDominator",
"bbGetLastInst",
"bbGetNumberOfInstructions",
"bbGetPredBlockCount",
"bbGetPredBlockCount",
"bbGetSuccBlockCount",
"bbGetSuccBlockCount",
"bbGetTrueBranch",
"bbIsCatchBegin",
"bbIsCatchBegin",
"bbIsEnd",
"bbIsLoopHead",
"bbIsLoopPrehead",
"bbIsStart",
"bbIsTryBegin",
"bbIsTryBegin",
"bbIsTryEnd",
"bbSplitBlockAfterInstruction",
"bbVisitDominatedBlocks",
"bbVisitPredBlocks",
"bbVisitSuccBlocks",
"bbCreatePhi",
"gCreateConstantF64",
"gCreateConstantI32",
"gCreateConstantI64",
"gCreateConstantU64",
"gCreateNullPtr",
"gDump",
"gGetBasicBlock",
"gGetEndBasicBlock",
"gGetNumberOfBasicBlocks",
"gGetParameter",
"gGetStartBasicBlock",
"gRunPassRemoveUnreachableBlocks",
"gVisitBlocksRpo",
"iCheckIsCall",
"iCreateAsyncfunctionenter",
"iCreateCallruntimeCreateprivateproperty",
"iCreateCallruntimeLdsendableclass",
"iCreateCallruntimeLdsendableexternalmodulevar",
"iCreateCallruntimeLdsendablevar",
"iCreateCallruntimeNewsendableenv",
"iCreateCallruntimeWideldsendableexternalmodulevar",
"iCreateCallruntimeWideldsendablevar",
"iCreateCallruntimeWidenewsendableenv",
"iCreateCopyrestargs",
"iCreateCreatearraywithbuffer",
"iCreateCreateemptyarray",
"iCreateCreateemptyobject",
"iCreateCreateobjectwithbuffer",
"iCreateDebugger",
"iCreateGetunmappedargs",
"iCreateLdbigint",
"iCreateLdexternalmodulevar",
"iCreateLdfalse",
"iCreateLdfunction",
"iCreateLdglobal",
"iCreateLdglobalvar",
"iCreateLdhole",
"iCreateLdinfinity",
"iCreateLdlexvar",
"iCreateLdlocalmodulevar",
"iCreateLdnan",
"iCreateLdnewtarget",
"iCreateLdnull",
"iCreateLdsymbol",
"iCreateLdthis",
"iCreateLdthisbyname",
"iCreateLdtrue",
"iCreateLdundefined",
"iCreateNewlexenv",
"iCreateNewlexenvwithname",
"iCreatePoplexenv",
"iCreateReturnundefined",
"iCreateThrowDeletesuperproperty",
"iCreateThrowNotexists",
"iCreateThrowPatternnoncoercible",
"iCreateTryldglobalbyname",
"iCreateWideCopyrestargs",
"iCreateWideLdexternalmodulevar",
"iCreateWideLdlexvar",
"iCreateWideLdlocalmodulevar",
"iCreateWideLdpatchvar",
"iCreateWideNewlexenv",
"iCreateWideNewlexenvwithname",
"iCreateLoadString",
"iCreateReturnVoid",
"iDump",
"iGetBasicBlock",
"iGetConditionCode",
"iGetConstantValueF64",
"iGetConstantValueI64",
"iGetConstantValueU64",
"iGetExportDescriptor",
"iGetId",
"iGetImmediate",
"iGetImmediateCount",
"iGetImportDescriptor",
"iGetInputCount",
"iGetInputCount",
"iGetLiteralArray",
"iGetFunction",
"iGetModule",
"iGetNext",
"iGetOpcode",
"iGetPrev",
"iGetTargetType",
"iGetType",
"iGetUserCount",
"iRemove",
"iSetImmediate",
"iCreateLoadConstArray",
"iCreateLoadUndefined",
"iGetString",
"iSetString"
]
funcs_without_helper = [
"coreAnnotationElementToArkTsAnnotationElement",
"coreNamespaceToArkTsNamespace",
"annotationElementGetAnnotation",
"moduleEnumerateAnonymousFunctions",
"annotationInterfaceFieldGetName",
"classEnumerateAnnotations",
"functionEnumerateNestedFunctions",
"literalGetMethod",
"namespaceGetName",
"functionGetParentNamespace",
"moduleEnumerateNamespaces",
"annotationInterfaceGetFile",
"annotationInterfaceGetName",
"moduleEnumerateAnnotationInterfaces",
"annotationElementGetFile",
"namespaceGetParentNamespace",
"coreFunctionToArkTsFunction",
"coreAnnotationInterfaceFieldToArkTsAnnotationInterfaceField",
"arkTsAnnotationInterfaceFieldToCoreAnnotationInterfaceField",
"coreImportDescriptorToArkTsImportDescriptor",
"arkTsImportDescriptorToCoreImportDescriptor",
"coreClassToArkTsClass",
"arkTsClassToCoreClass",
"arkTsModuleToCoreModule",
"coreAnnotationToArkTsAnnotation",
"arkTsAnnotationElementToCoreAnnotationElement",
"arkTsFunctionToCoreFunction",
"arkTsExportDescriptorToCoreExportDescriptor",
"arkTsAnnotationToCoreAnnotation",
"arkTsV1NamespaceGetConstructor",
"arkTsNamespaceToCoreNamespace",
"arkTsAnnotationInterfaceToCoreAnnotationInterface",
"coreExportDescriptorToArkTsExportDescriptor",
"coreModuleToArkTsModule",
"coreAnnotationInterfaceToArkTsAnnotationInterface",
"annotationInterfaceRemoveField",
"annotationRemoveAnnotationElement",
"classRemoveAnnotation",
"functionAddAnnotation",
"functionRemoveAnnotation",
"annotationAddAnnotationElement",
"moduleAddImportFromArkTsV1ToArkTsV1",
"classAddAnnotation",
"moduleAddExportFromArkTsV2ToArkTsV2",
"moduleAddImportFromArkTsV2ToArkTsV2",
"moduleAddAnnotationInterface",
"fileAddExternalModule",
"annotationInterfaceAddField",
"moduleAddExportFromArkTsV1ToArkTsV1",
"bbGetPredBlock",
"bbGetSuccBlock",
"gInsertTryCatch",
"iGetConstantValueI32",
"bbEraseSuccBlock",
"bbIsTry",
"gGetIsa",
"bbIsCatch",
"iGetInput",
"gGetFile",
"annotationInterfaceFieldGetFile",
"annotationInterfaceFieldGetDefaultValue",
"literalGetLiteralArray",
"annotationInterfaceGetModule",
"namespaceEnumerateTopLevelFunctions",
"annotationInterfaceFieldGetInterface",
"literalGetFile",
"annotationElementGetValue",
"classGetParentNamespace",
"annotationGetInterface",
"annotationInterfaceFieldGetType",
"annotationInterfaceEnumerateFields",
"moduleGetTarget",
"namespaceEnumerateNamespaces",
"annotationElementGetName",
"createGraphFromFunction",
"namespaceEnumerateClasses",
"valueGetFile",
"abckitStringToString",
"iCreateCatchPhi",
"iGetClass",
"iCreateCatchPhi",
"iSetClass",
"jsImportDescriptorToCoreImportDescriptor",
"jsFunctionToCoreFunction",
"jsClassToCoreClass",
"coreClassToJsClass",
"jsExportDescriptorToCoreExportDescriptor",
"coreImportDescriptorToJsImportDescriptor",
"coreModuleToJsModule",
"coreFunctionToJsFunction",
"coreExportDescriptorToJsExportDescriptor",
"jsModuleToCoreModule",
"fileAddExternalModule",
"moduleAddExportFromJsToJs",
"moduleAddImportFromJsToJs",
"createLiteralMethod",
"createLiteralLiteralArray",
"createLiteralArray",
"createType",
]
funcs_varargs = [
"iCreateNewobjrange",
"iCreateWideSupercallthisrange",
"iCreateSupercallthisrange",
"iCreateWideNewobjrange",
]
excluded_funcs += funcs_without_two_abckit_entites
excluded_funcs += funcs_varargs
excluded_funcs += funcs_without_helper
implemented_api_map = collect_implemented_api_map(excluded_funcs)
wrong_ctx_tests_erb = File.join(abckit_test, "wrong_ctx_tests.cpp.erb")
implemented_api_map.each_key do |domain|
iteration = 0
index = 0
slice_size = 100
api_funcs_arr = implemented_api_map[domain]
total_domain_api_funcs = api_funcs_arr.length
puts "#{domain}: #{total_domain_api_funcs}"
while index < total_domain_api_funcs do
testfile_fullpath = File.join(abckit_test, "wrong_ctx_tests_#{domain}_#{iteration}.cpp")
res = ERB.new(File.read(wrong_ctx_tests_erb), nil, "%").result(binding)
File.write(testfile_fullpath, res)
iteration += 1
index += slice_size
end
end

View File

@ -0,0 +1,73 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'erb'
abckit_scripts = File.dirname(__FILE__)
abckit_root = File.expand_path("../", abckit_scripts)
abckit_test = File.join(abckit_root, "/tests/wrong_mode_tests/")
implemented_api_raw = nil
Dir.chdir(abckit_scripts) do
implemented_api_raw = `python get_abckit_status.py --print-implemented`.split(/\n/)
end
implemented_api_map = {}
# excluded_funcs = [
# "IcreateLoadString"
# ]
implemented_api_raw.each do |api_func_raw|
domain, api_func = *api_func_raw.split(/::/)
# if excluded_funcs.include?(api_func)
# next
# end
# if domain.include? "IsaApiDynamicImpl"
if api_func.include? "iCreate" and domain.include? "IsaApiDynamicImpl"
if implemented_api_map[domain].nil?
implemented_api_map[domain] = [api_func]
else
implemented_api_map[domain].append(api_func)
end
next
end
if api_func.include? "iCreate" and domain.include? "IsaApiStaticImpl"
if implemented_api_map[domain].nil?
implemented_api_map[domain] = [api_func]
else
implemented_api_map[domain].append(api_func)
end
end
end
wrong_mode_tests_erb = File.join(abckit_test, "wrong_mode_tests.cpp.erb")
implemented_api_map.each_key do |domain|
iteration = 0
index = 0
slice_size = 100
api_funcs_arr = implemented_api_map[domain]
total_domain_api_funcs = api_funcs_arr.length
puts "#{domain}: #{total_domain_api_funcs}"
while index < total_domain_api_funcs do
testfile_fullpath = File.join(abckit_test, "wrong_mode_tests_#{domain}_#{iteration}.cpp")
res = ERB.new(File.read(wrong_mode_tests_erb), nil, "%").result(binding)
File.write(testfile_fullpath, res)
iteration += 1
index += slice_size
end
end

View File

@ -0,0 +1,334 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
import os
import argparse
import logging
script_dir = os.path.dirname(os.path.realpath(__file__))
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
def get_args():
parser = argparse.ArgumentParser(description="Abckit status script")
parser.add_argument(
"--print-implemented",
action="store_true",
default=False,
help=f"Print list of implemented API and exit")
return parser.parse_args()
args = get_args()
API_PATTERN = "^[\w,\d,_, ,*]+\(\*([\w,\d,_]+)\)\(.*"
domain_patterns = ["struct Abckit\S*Api\s\{", "struct Abckit\S*ApiStatic\s\{", "struct Abckit\S*ApiDynamic\s\{"]
libabckit_dir = os.path.join(script_dir, "..")
libabckit_tests = os.path.join(libabckit_dir, "tests")
sources = {
"include/c/ir_core.h",
"include/c/metadata_core.h",
"include/c/extensions/arkts/metadata_arkts.h",
"include/c/extensions/js/metadata_js.h",
"src/include_v2/c/isa/isa_static.h",
"include/c/isa/isa_dynamic.h",
"include/c/abckit.h"
}
TS = 'TS'
JS = 'JS'
ARKTS1 = 'ArkTS1'
ARKTS2 = 'ArkTS2'
NO_ABC = 'NoABC'
def check(cond, msg=''):
if not cond:
raise Exception(msg)
class API:
def __init__(self, name, domain):
self.name = name
self.domain = domain
self.dynamic_positive_tests = 0
self.static_positive_tests = 0
self.arkts1_tests = 0
self.arkts2_tests = 0
self.js_tests = 0
self.ts_tests = 0
self.no_abc_tests = 0
self.positive_tests = 0
self.negative_tests = 0
self.negative_nullptr_tests = 0
self.negative_ctx_tests = 0
self.negative_mode_tests = 0
self.other_tests = 0
def domain_match(line):
for pattern in domain_patterns:
if re.fullmatch(pattern, line.strip()):
return line
return None
def update_domain(old_domain, l):
new_domain = domain_match(l.strip())
if not new_domain:
return old_domain
return re.search('struct Abckit(.*)\s\{',
new_domain.strip()).group(1)
def collect_api(path):
api = {}
domain = ""
with open(path) as f:
for l in f.readlines():
domain = update_domain(domain, l)
if not re.fullmatch(API_PATTERN, l.strip()):
continue
# CC-OFFNXT(G.FIO.05) regexp false positive
if re.fullmatch('\/\/' + API_PATTERN, l.strip()):
continue
func_name = re.search('^[\w,\d,_, ,*]+\(\*([\w,\d,_]+)\)\(.*', l.strip()).group(1)
if func_name == "cb":
continue
check(domain)
api[f'{domain}Impl::{func_name}'] = API(func_name, domain)
return api
def check_test_anno_line(line):
mul_lines = False
anno_line = False
if re.fullmatch("^\/\/ Test: test-kind=.*\n", line):
anno_line = True
mul_lines = line.strip()[-1] == ','
return {"is_annotation_line" : anno_line, "mul_annotation_lines": mul_lines}
def get_full_annotation(it, annotation_start):
annotation = annotation_start.strip()
next_anno_line = True
while next_anno_line:
new_line = next(it)
annotation += new_line.replace('//', '').strip()
if not re.fullmatch("^\/\/.*,$", new_line):
next_anno_line = False
return annotation
class Test:
def __init__(self, s):
err = f'Wrong test annotation: "{s}"'
self.kind = ''
self.abc_kind = ''
self.api = ''
self.category = ''
check('// Test:' in s, err)
s = s.replace('// Test:', '')
entries = [x.strip() for x in s.split(',') if x]
for entry in entries:
key, value = entry.strip().split('=')
if key == 'test-kind':
check(value in ['api', 'scenario', 'internal'], err)
self.kind = value
elif key == 'abc-kind':
check(value in [ARKTS1, ARKTS2, JS, TS, NO_ABC], err)
self.abc_kind = value
elif key == 'api':
self.api = value
elif key == 'category':
possible_values = [
'positive',
'negative-mode',
'negative-nullptr',
'negative-file',
'internal',
'negative'
]
check(value in possible_values, err)
self.category = value
else:
check(False, f'Wrong key: {key}')
check(self.kind, err)
check(self.abc_kind, err)
check(self.category, err)
if self.kind == 'api':
check(self.api, err)
def is_first_test_line(line):
if re.fullmatch("TEST_F\(.*,.*\n", line):
return True
return False
def get_test_from_annotation(api, annotation):
test = Test(annotation)
if "api=" in annotation and test.api != 'ApiImpl::GetLastError':
check(test.api in api, f'No such API: {test.api}')
return test
def collect_tests(path, api):
with open(path, "r") as f:
lines = f.readlines()
it = iter(lines)
tests = []
ano_count, test_count = 0, 0
annotation = ''
line = '\n'
while True:
line = next(it, None)
if (line is None):
break
if is_first_test_line(line):
test_count += 1
check(test_count <= ano_count, f'Test has no annotation:\n{path}\n{line}\n')
continue
info = check_test_anno_line(line)
if not info.get("is_annotation_line"):
annotation = ''
continue
ano_count += 1
annotation += line.strip()
if info.get("mul_annotation_lines"):
annotation = get_full_annotation(it, line)
else:
annotation = line.strip()
if annotation:
tests.append(get_test_from_annotation(api, annotation))
check(ano_count == test_count, f'Annotation without test:\n{path}\n')
return tests
def get_tests_statistics(api, tests):
for test in tests:
if test.kind != 'api' or test.api == 'ApiImpl::GetLastError':
continue
if test.abc_kind == ARKTS1:
api[test.api].arkts1_tests += 1
if test.abc_kind == ARKTS2:
api[test.api].arkts2_tests += 1
elif test.abc_kind == JS:
api[test.api].js_tests += 1
elif test.abc_kind == TS:
api[test.api].ts_tests += 1
elif test.abc_kind == NO_ABC:
api[test.api].no_abc_tests += 1
if test.category == 'positive':
api[test.api].positive_tests += 1
if test.abc_kind == TS or test.abc_kind == JS or test.abc_kind == ARKTS1:
api[test.api].dynamic_positive_tests += 1
if test.abc_kind == ARKTS2:
api[test.api].static_positive_tests += 1
elif test.category == 'negative':
api[test.api].negative_tests += 1
elif test.category == 'negative-nullptr':
api[test.api].negative_nullptr_tests += 1
elif test.category == 'negative-file':
api[test.api].negative_ctx_tests += 1
elif test.category == 'negative-mode':
api[test.api].negative_mode_tests += 1
else:
api[test.api].other_tests += 1
return api
def main(api) :
tests = []
for dirpath, _, filenames in os.walk(libabckit_tests):
for name in filenames:
if name.endswith(".cpp"):
tests += collect_tests(os.path.join(dirpath, name), api)
api = get_tests_statistics(api, tests)
csv = (
'api,dynamic_positive_tests,static_positive_tests,'
'arkts1_tests,arkts2_tests,js_tests,ts_tests,no_abc_tests,positive_tests,'
'negative_tests,negative_nullptr_tests,negative_ctx_tests,other_tests\n'
)
for name in api:
csv += (
f'{name},{api[name].dynamic_positive_tests},{api[name].static_positive_tests},'
f'{api[name].arkts1_tests},{api[name].arkts2_tests},{api[name].js_tests},{api[name].ts_tests},'
f'{api[name].no_abc_tests},{api[name].positive_tests},{api[name].negative_tests},'
f'{api[name].negative_nullptr_tests},{api[name].negative_ctx_tests},{api[name].other_tests}\n'
)
with os.fdopen(os.open(os.path.join(libabckit_dir, 'scripts/abckit_status.csv'),
os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o755), 'w') as f:
f.write(csv)
def api_test_category(name):
return len(list(filter(lambda t: t.kind == 'api' and t.category == name, tests)))
def api_lang(name):
return len(list(filter(lambda t: t.kind == 'api' and t.abc_kind == name, tests)))
def scenario_lang(name):
return len(list(filter(lambda t: t.kind == 'scenario' and t.abc_kind == name, tests)))
logging.debug('Total API: %s', len(api))
logging.debug('')
logging.debug('Total Tests: %s', len(tests))
logging.debug('')
logging.debug('Total API tests: %s',
len(list(filter(lambda t: t.kind == "api", tests))))
logging.debug('Positive/Negative/NullArg/WrongCtx/WrongMode API tests: %s/%s/%s/%s/%s',
api_test_category("positive"),
api_test_category("negative"),
api_test_category("negative-nullptr"),
api_test_category("negative-file"),
api_test_category("negative-mode"))
logging.debug('ArkTS1/ArkTS2/JS/TS/NoABC API tests: %s/%s/%s/%s/%s',
api_lang(ARKTS1), api_lang(ARKTS2), api_lang(JS), api_lang(TS), api_lang(NO_ABC))
logging.debug('')
logging.debug('Total scenario tests: %s',
len(list(filter(lambda t: t.kind == "scenario", tests))))
logging.debug('ArkTS1/ArkTS2/JS/TS scenario tests: %s/%s/%s/%s',
scenario_lang(ARKTS1), scenario_lang(ARKTS2), scenario_lang(JS), scenario_lang(TS))
logging.debug('')
logging.debug('Internal tests: %s',
len(list(filter(lambda t: t.kind == "internal", tests))))
collected_api = {}
for src in sources:
collected_api = dict(collected_api.items() | collect_api(f'{libabckit_dir}/' + src).items())
if args.print_implemented:
logging.debug('\n'.join(collected_api))
else:
main(collected_api)

View File

@ -0,0 +1,28 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'ostruct'
abckit_scripts = File.dirname(__FILE__)
abckit_root = File.expand_path('../', abckit_scripts)
opcodes_path = File.expand_path('include/c/isa/isa_dynamic.h', abckit_root)
Opcodes = []
File.open(opcodes_path, 'r').read.split()
.select{ |opcode|
opcode.start_with?('ABCKIT_ISA_API_DYNAMIC_OPCODE_')
}.each{ |opcode|
res = OpenStruct.new
res.abckit_opcode = opcode.chop!
res.bc_opcode = opcode.delete_prefix('ABCKIT_ISA_API_DYNAMIC_OPCODE_').split('_').map!{|str| str.downcase }.join('.')
Opcodes.append(res)
}

View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
cur_path="$(pwd)"
cur_dir="$(basename $cur_path)"
if [ "$cur_dir" != "libabckit" ]; then
echo "please rerun from runtime_core/libabckit"
exit 1
fi
function clear_tests() {
rm -rf tests/null_args_tests/null_args_tests_*
rm -rf tests/wrong_ctx_tests/wrong_ctx_tests_*
rm -rf tests/wrong_mode_tests/wrong_mode_tests_*
}
function generate_tests() {
ruby scripts/gen_wrong_ctx_tests.rb
ruby scripts/gen_wrong_mode_tests.rb
ruby scripts/gen_null_arg_tests.rb
}
if [[ "${1}" == "clear" ]]; then
clear_tests
if [[ "${2}" == "gen" ]]; then
generate_tests
fi
fi
if [[ "$1" == "gen" ]]; then
generate_tests
if [[ "$2" == "clear" ]]; then
clear_tests
fi
fi

146
libabckit/scripts/run_script.sh Executable file
View File

@ -0,0 +1,146 @@
#!/bin/bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -u
set -e
set -o pipefail
TRUE=1
FALSE=0
ENV_VALUE=""
SCRIPT_ARGS_VALUE=""
RUNNER_VALUE=""
RUNNER_ARGS_VALUE=""
HELP_VALUE=""
SCRIPT_ARGUMENT="--script"
SCRIPT_ARGS_OPTION="--script-args"
RUNNER_OPTION="--runner"
RUNNER_ARGS_OPTION="--runner-args"
ENV_OPTION="--env"
RET_CODE_OPTION="--ret-code"
HELP_OPTION="--help"
print_help() {
echo "Usage: run_script.sh ${SCRIPT_ARGUMENT}= "
echo " [${SCRIPT_ARGS_OPTION}=]+ [${RUNNER_ARGS_OPTION}=]+ [${ENV_OPTION}=]+ "
echo " [${RUNNER_OPTION}=] [${RET_CODE_OPTION}=] [--help] "
echo "Arguments: "
echo " ${SCRIPT_ARGUMENT} Path for the script to be executed. "
echo "Options: "
echo " ${SCRIPT_ARGS_OPTION} Arguments for the script. "
echo " ${RUNNER_OPTION} Specify command that shall execute the script. "
echo " ${RUNNER_ARGS_OPTION} Specify arguments for the script runner. "
echo " ${ENV_OPTION} Environment for the script execution. "
echo " ${RET_CODE_OPTION} Specify expected return code of the command. Set to 0 by default. "
echo " ${HELP_OPTION} Print this message. "
}
report_error() {
echo "[ERROR]/: " "$@"
exit 1
}
parse_args() {
for i in "$@"; do
case "$i" in
"${SCRIPT_ARGUMENT}"=*)
SCRIPT_VALUE="${i#*=}"
shift
;;
"${SCRIPT_ARGS_OPTION}"=*)
# CC-OFFNXT(bc-50008) false positive
SCRIPT_ARGS_VALUE="${SCRIPT_ARGS_VALUE} ${i#*=}"
shift
;;
"${RUNNER_OPTION}"=*)
# CC-OFFNXT(bc-50008) false positive
RUNNER_VALUE="${i#*=}"
shift
;;
"${RET_CODE_OPTION}"=*)
RET_CODE_VALUE="${i#*=}"
shift
;;
"${RUNNER_ARGS_OPTION}"=*)
# CC-OFFNXT(bc-50008) false positive
RUNNER_ARGS_VALUE="${RUNNER_ARGS_VALUE} ${i#*=}"
shift
;;
"${ENV_OPTION}"=*)
# CC-OFFNXT(bc-50008) false positive
ENV_VALUE="${ENV_VALUE} ${i#*=}"
shift
;;
"${HELP_OPTION}")
# CC-OFFNXT(bc-50008) false positive
HELP_VALUE=$TRUE
shift
;;
*)
print_help
report_error "Recieved unexpected argument: ${i}"
;;
esac
done
if [ -z "$RET_CODE_VALUE" ]; then
RET_CODE_VALUE=0
fi
}
check_args() {
if [ -z "$SCRIPT_VALUE" ]; then
report_error "${SCRIPT_ARGUMENT} argument can not be empty."
fi
if [[ -z "${RUNNER_VALUE}" && -n "${RUNNER_ARGS_VALUE}" ]]; then
report_error "You must specify ${RUNNER_OPTION} for ${RUNNER_ARGS_OPTION} to be passed to."
fi
}
print_parsed_args() {
echo "Parsed arguments:"
echo "${SCRIPT_ARGUMENT}=${SCRIPT_VALUE}"
echo "${SCRIPT_ARGS_OPTION}=${SCRIPT_ARGS_VALUE}"
echo "${RUNNER_OPTION}=${RUNNER_VALUE}"
echo "${RUNNER_ARGS_OPTION}=${RUNNER_ARGS_VALUE}"
echo "${ENV_OPTION}=${ENV_VALUE}"
echo "${RET_CODE_OPTION}=${RET_CODE_VALUE}"
echo "${HELP_OPTION}=${HELP_VALUE}"
}
main() {
parse_args "$@"
print_parsed_args
if [ ${HELP_VALUE} -eq ${TRUE} ]; then
print_help
exit 0
fi
check_args
local -i ret_code=0
export ${ENV_VALUE?}
${RUNNER_VALUE} ${RUNNER_ARGS_VALUE} ${SCRIPT_VALUE} ${SCRIPT_ARGS_VALUE} || ret_code=$?
if [ ! ${ret_code} -eq ${RET_CODE_VALUE} ]; then
report_error "Unexpected error code returned! Expected: ${RET_CODE_VALUE} vs actual: ${ret_code}"
fi
}
main "$@"

197
libabckit/scripts/self-check.sh Executable file
View File

@ -0,0 +1,197 @@
#!/bin/bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -x
set -e
set -o pipefail
OHOS_DIR=""
SANITIZERS=false
COVERAGE=false
print_usage() {
set +x
echo "Usage: self-check.sh [options] [mode] --dir=<ohos_dir> "
echo " "
echo " <ohos_dir> -- path to OHOS root "
echo "Mode: "
echo " -s, --sanitize build with sanitizers "
echo " -c, --coverage collect code coverage "
echo " "
echo "Options: "
echo " -h, --help print help text "
set -x
}
for i in "$@"; do
case "$i" in
-c | --coverage)
COVERAGE=true
shift
;;
-s | --sanitize)
SANITIZERS=true
shift
;;
--dir=*)
OHOS_DIR="${i#*=}"
OHOS_DIR="${OHOS_DIR/#\~/$HOME}"
shift
;;
-h | --help)
print_usage
exit 1
;;
*)
echo "Unknown option \"$i\""
print_usage
exit 1
;;
esac
done
build_standalone() {
set -e
rm -rf out/$TARGET
./ark.py $TARGET libabckit_packages --gn-args="is_standard_system=true libabckit_with_sanitizers=$SANITIZERS enable_notice_collection=false enable_libabckit_coverage=$COVERAGE ohos_components_checktype=3 enable_libabckit=true"
set +e
}
run_check_clang_format() {
set -e
ninja abckit_check_clang_format
set +e
}
run_check_clang_tidy() {
set -e
ninja abckit_check_clang_tidy
set +e
}
run_check_documentation() {
set -e
ninja abckit_documentation
set +e
}
build_and_run_tests() {
set -e
ninja AbcKitTest
LSAN_OPTIONS=""
if [ "$SANITIZERS" = "true" ]; then
LSAN_OPTIONS="suppressions=$OHOS_DIR/arkcompiler/runtime_core/libabckit/tests/sanitizers/ignored_leaks.supp"
if [ -f /etc/ld.so.preload ]; then
echo "/etc/ld.so.preload detected! Trying to manually specify LD_PRELOAD"
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6
fi
fi
if [ "$COVERAGE" = "true" ]; then
export LLVM_PROFILE_FILE="abckit%m.profraw"
fi
LD_LIBRARY_PATH=./arkcompiler/runtime_core/:./arkcompiler/ets_runtime/:./thirdparty/icu/:./thirdparty/zlib/ \
LSAN_OPTIONS="$LSAN_OPTIONS" \
ASAN_OPTIONS=verify_asan_link_order=0 \
./tests/unittest/arkcompiler/runtime_core/libabckit/AbcKitTest
if [ "$SANITIZERS" = "false" ]; then
ninja abckit_stress_test_package
if [ "$TARGET" = "x64.debug" ]; then
../../arkcompiler/runtime_core/libabckit/tests/stress/stress.py --build-dir $(realpath .)
../../arkcompiler/runtime_core/libabckit/tests/stress/stress_ets.py --build-dir $(realpath .)
../../arkcompiler/runtime_core/libabckit/tests/stress/stress_hermes.py --build-dir $(realpath .)
../../arkcompiler/runtime_core/libabckit/tests/stress/stress_node_js.py --build-dir $(realpath .)
else
ninja ark_js_vm
../../arkcompiler/runtime_core/libabckit/tests/stress/stress_js_full.py --build-dir $(realpath .)
../../arkcompiler/runtime_core/libabckit/tests/stress/stress_hermes_full.py --build-dir $(realpath .)
fi
fi
if [ "$COVERAGE" = "true" ]; then
../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-profdata merge -sparse abckit*.profraw -o abckit.profdata
../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov show \
--instr-profile=./abckit.profdata \
--summary-only --output-dir=abckit_coverage \
./arkcompiler/runtime_core/libabckit.so
../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov report \
--ignore-filename-regex='(.*third_party/.*|.*/runtime_core/static_core/.*|.*/runtime_core/libpandabase/.*|.*/arkcompiler/ets_frontend/|.*/runtime_core/abc2program/.*|.*/runtime_core/libpandafile/.*|.*/runtime_core/assembler/.*|.*/runtime_core/platforms/.*)' \
--instr-profile=./abckit.profdata ./arkcompiler/runtime_core/libabckit.so |
sed 's|\([^ ]\) \([^ ]\)|\1_\2|g' |
tr -s ' ' |
grep -v '\------------' |
grep -v 'Files_which_contain_no_functions:' |
sed 's| |,|g' >abckit_coverage.csv
../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov report \
--ignore-filename-regex='(.*third_party/.*|.*/runtime_core/libabckit/src/adapter_static/.*|.*/runtime_core/static_core/.*|.*/runtime_core/abc2program/.*|.*/runtime_core/libpandabase/.*|.*/arkcompiler/ets_frontend/|.*/runtime_core/libpandafile/.*|.*/runtime_core/assembler/.*|.*/runtime_core/platforms/.*|.*/runtime_core/libabckit/src/codegen/generated/insn_selection_static.cpp|.*/runtime_core/libabckit/src/codegen/codegen_static.cpp|.*/runtime_core/libabckit/src/codegen/generated/codegen_intrinsics_static.cpp|.*/runtime_core/libabckit/src/isa_static_impl.cpp|.*/runtime_core/libabckit/src/codegen/codegen_static.h|.*/runtime_core/libabckit/src/codegen/generated/codegen_visitors_static.inc|.*/runtime_core/libabckit/src/codegen/generated/codegen_call_intrinsics_static.inc)' \
--instr-profile=./abckit.profdata ./arkcompiler/runtime_core/libabckit.so |
sed 's|\([^ ]\) \([^ ]\)|\1_\2|g' |
tr -s ' ' |
grep -v '\------------' |
grep -v 'Files_which_contain_no_functions:' |
sed 's| |,|g' >abckit_dynamic_coverage.csv
echo "Summary abckit coverage report file: $(realpath abckit_coverage.csv)"
echo "Summary abckit dynamic coverage report file: $(realpath abckit_dynamic_coverage.csv)"
echo "Verbose abckit coverage report dir: $(realpath abckit_coverage)"
fi
if [ "$SANITIZERS" = "true" ]; then
rm -f "$TMP"
fi
set +e
}
if [ -z "$OHOS_DIR" ]; then
echo "ERROR: Path to OHOS root was not provided"
print_usage
exit 1
fi
TARGET=x64.debug
pushd "$OHOS_DIR" || exit 1
build_standalone
pushd out/$TARGET || exit 1
run_check_documentation
run_check_clang_format
if [ "$COVERAGE" = "false" ] && [ "$SANITIZERS" = "false" ]; then
run_check_clang_tidy
fi
build_and_run_tests
popd || exit 1
if [ "$COVERAGE" = "false" ] && [ "$SANITIZERS" = "false" ]; then
TARGET=x64.release
pushd "$OHOS_DIR" || exit 1
build_standalone
pushd out/$TARGET || exit 1
run_check_documentation
run_check_clang_format
run_check_clang_tidy
build_and_run_tests
popd || exit 1
fi
popd || exit 1

39
libabckit/scripts/stress.sh Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
if [ -z "$1" ]; then
echo "usage: stress.sh input.abc [output.abc]"
exit 1
fi
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if [ ! -d "$OUT_DIR" ]; then
echo "No such directory (OUT_DIR): $OUT_DIR"
fi
ABCKIT="$OUT_DIR/arkcompiler/runtime_core/abckit"
STRESS_PLUGIN="$OUT_DIR/arkcompiler/runtime_core/libabckit_stress_plugin.so"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:\
$OUT_DIR/arkcompiler/runtime_core:\
$OUT_DIR/arkcompiler/ets_runtime:\
$OUT_DIR/arkcompiler/ets_frontend:\
$OUT_DIR/thirdparty/icu:\
$OUT_DIR/thirdparty/zlib"
set -x
"$ABCKIT" --plugin-path "$STRESS_PLUGIN" "$@"

View File

@ -0,0 +1,734 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
intrinsics:
- name: AbckitLoadConstArray
space: abckit
class_name: "LoadConstArray"
method_name: "lda.const"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ literalarray_id ]
clear_flags: [ "require_state", "call", "heap_inv", "acc_write", "acc_read" ]
set_flags: ["load"]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadString
space: abckit
class_name: "LoadString"
method_name: "lda.str"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ string_id ]
clear_flags: [ "require_state", "call", "heap_inv", "acc_read", "no_dce", "barrier" ]
set_flags: ["load"]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitCheckCast
space: abckit
class_name: "CheckCast"
method_name: "checkcast"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, type_id ]
clear_flags: [ "require_state", "call", "heap_inv", "acc_write", "barrier" ]
set_flags: ["load", "no_dst"]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitIsInstance
space: abckit
class_name: "IsInstance"
method_name: "isinstance"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: i32
args: [ ref, type_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "can_throw", "no_dce", "no_hoist", "no_cse"]
set_flags: []
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitThrow
space: abckit
class_name: "Throw"
method_name: "throw"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref ]
clear_flags: [ "require_state", "call", "heap_inv", "runtime_call", "acc_read", "acc_write" ]
set_flags: ["cf", "terminator", "no_dst"]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitNewArray
space: abckit
class_name: "NewArray"
method_name: "newarr"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ i32, type_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "acc_read", "acc_write" ]
set_flags: [ "alloc", "mem_barrier" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitNewObject
space: abckit
class_name: "NewObject"
method_name: "newobj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ type_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "acc_read", "acc_write" ]
set_flags: [ "alloc", "mem_barrier" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitInitObjectShort
space: abckit
class_name: "InitObject"
method_name: "initobj.short"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ none, none, method_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "alloc" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitInitObject
space: abckit
class_name: "InitObject"
method_name: "initobj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ none, none, none, none, method_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "alloc" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitInitObjectRange
space: abckit
class_name: "InitObject"
method_name: "initobj.range"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ none, method_id ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "alloc" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadObject
space: abckit
class_name: "LoadObject"
method_name: "ldobj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: b32
args: [ ref, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadObjectWide
space: abckit
class_name: "LoadObject"
method_name: "ldobj.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: b64
args: [ ref, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadObjectObject
space: abckit
class_name: "LoadObject"
method_name: "ldobj.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ ref, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreObject
space: abckit
class_name: "StoreObject"
method_name: "stobj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, b32, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreObjectWide
space: abckit
class_name: "StoreObject"
method_name: "stobj.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, b64, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreObjectObject
space: abckit
class_name: "StoreObject"
method_name: "stobj.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, ref, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadStatic
space: abckit
class_name: "LoadStatic"
method_name: "ldstatic"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: b32
args: [ field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadStaticWide
space: abckit
class_name: "LoadStatic"
method_name: "ldstatic.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: b64
args: [ field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadStaticObject
space: abckit
class_name: "LoadStatic"
method_name: "ldstatic.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_read"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreStatic
space: abckit
class_name: "StoreStatic"
method_name: "ststatic"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ b32, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreStaticWide
space: abckit
class_name: "StoreStatic"
method_name: "ststatic.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ b64, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreStaticObject
space: abckit
class_name: "StoreStatic"
method_name: "ststatic.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, field_id ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreArray
space: abckit
class_name: "StoreArray"
method_name: "starr"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, i32, i32 ]
clear_flags: [ "can_throw", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreArrayWide
space: abckit
class_name: "StoreArray"
method_name: "starr.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, i32, i64 ]
clear_flags: [ "can_throw", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitStoreArrayObject
space: abckit
class_name: "StoreArray"
method_name: "starr.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: none
args: [ ref, i32, ref ]
clear_flags: [ "can_throw", "require_state", "call", "runtime_call", "heap_inv", "barrier", "acc_write"]
set_flags: [ "store", "no_dst" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadArray
space: abckit
class_name: "LoadArray"
method_name: "ldarr"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: i32
args: [ i32, ref ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadArrayWide
space: abckit
class_name: "LoadArray"
method_name: "ldarr.64"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: i64
args: [ i32, ref ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitLoadArrayObject
space: abckit
class_name: "LoadArray"
method_name: "ldarr.obj"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: ref
args: [ i32, ref ]
clear_flags: [ "can_throw", "no_dce", "require_state", "call", "runtime_call", "heap_inv", "barrier"]
set_flags: [ "load" ]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitEquals
space: abckit
class_name: "Equals"
method_name: "ets.equals"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: i32
args: [ ref, ref ]
clear_flags: ["acc_read", "require_state", "can_throw", "heap_inv", "no_dce", "no_cse", "no_hoist"]
set_flags: ["commutative"]
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
- name: AbckitIsUndefined
space: abckit
class_name: "IsUndefined"
method_name: "ets.isundefined"
compiler_only: true
private: false
static: true
safepoint_after_call: false
signature:
ret: u1
args: [ ref ]
clear_flags: [ "require_state", "call", "heap_inv", "barrier", "can_throw", "no_dce", "no_hoist", "no_cse"]
set_flags: []
is_stub: false
additional_temps: 0
codegen_arch: []
need_nullcheck: []
is_fastpath: false
need_param_locations: false
# - name: AbckitLaunchShort
# space: abckit
# class_name: "Lanch"
# method_name: "launch.short"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false
# - name: AbckitLaunch
# space: abckit
# class_name: "Lanch"
# method_name: "launch"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, top, top, top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false
# - name: AbckitLaunchRange
# space: abckit
# class_name: "Lanch"
# method_name: "launch.range"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false
# - name: AbckitLaunchVirtShort
# space: abckit
# class_name: "LanchVirt"
# method_name: "launch.virt.short"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false
# - name: AbckitLaunchVirt
# space: abckit
# class_name: "LanchVirt"
# method_name: "launch.virt"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, top, top, top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false
# - name: AbckitLaunchVirtRange
# space: abckit
# class_name: "LanchVirt"
# method_name: "launch.virt.range"
# compiler_only: true
# private: false
# static: true
# safepoint_after_call: false
# signature:
# ret: top
# args: [ top, method_id ]
# clear_flags: [ "require_state", "heap_inv" ]
# set_flags: [ "alloc", "mem_barrier" ]
# is_stub: false
# additional_temps: 0
# codegen_arch: []
# need_nullcheck: []
# is_fastpath: false
# need_param_locations: false

View File

@ -0,0 +1,162 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "libabckit/include/c/abckit.h"
#include "libabckit/include/c/statuses.h"
#include "libabckit/src/macros.h"
#include "libabckit/src/helpers_common.h"
#include "libabckit/src/statuses_impl.h"
#include "libabckit/src/metadata_inspect_impl.h"
#include "libabckit/src/ir_impl.h"
#include "libabckit/src/adapter_dynamic/abckit_dynamic.h"
#include "libabckit/src/adapter_static/abckit_static.h"
#include "libabckit/src/mem_manager/mem_manager.h"
#include "libabckit/src/logger.h"
#include "libabckit/src/abckit_options.h"
#include <cstddef>
#include <iostream>
libabckit::Logger *libabckit::Logger::logger_ = nullptr;
thread_local libabckit::Logger::MODE g_abckitGlobalMode {libabckit::Logger::MODE::RELEASE_MODE};
thread_local libabckit::NullBuffer libabckit::g_nB {};
thread_local std::ostream libabckit::g_nullStream {&g_nB};
namespace libabckit {
libabckit::Options g_abckitOptions("");
extern "C" AbckitStatus GetLastError()
{
LIBABCKIT_IMPLEMENTED;
return statuses::GetLastError();
}
extern "C" AbckitFile *OpenAbc(const char *path)
{
LIBABCKIT_CLEAR_LAST_ERROR;
LIBABCKIT_IMPLEMENTED;
LIBABCKIT_BAD_ARGUMENT(path, nullptr);
LIBABCKIT_LOG(DEBUG) << path << '\n';
MemManager::Initialize(g_abckitOptions.GetMemorySizeLimit());
AbckitFile *file = nullptr;
file = OpenAbcStatic(path);
if (file != nullptr) {
return file;
}
LIBABCKIT_LOG(DEBUG) << (std::string() + "Load file with path '" + path +
"' failed for static mode, trying dynamic mode\n");
file = OpenAbcDynamic(path);
if (file != nullptr) {
return file;
}
LIBABCKIT_LOG(DEBUG) << (std::string() + "Load file with path '" + path + "' failed for both modes\n");
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return nullptr;
}
extern "C" void WriteAbc(AbckitFile *file, const char *path)
{
LIBABCKIT_CLEAR_LAST_ERROR;
LIBABCKIT_IMPLEMENTED;
LIBABCKIT_BAD_ARGUMENT_VOID(file)
LIBABCKIT_BAD_ARGUMENT_VOID(path)
switch (file->frontend) {
case Mode::DYNAMIC:
return WriteAbcDynamic(file, path);
case Mode::STATIC:
return WriteAbcStatic(file, path);
default:
LIBABCKIT_UNREACHABLE;
}
}
extern "C" void CloseFile(AbckitFile *file)
{
LIBABCKIT_CLEAR_LAST_ERROR;
LIBABCKIT_IMPLEMENTED;
LIBABCKIT_BAD_ARGUMENT_VOID(file);
switch (file->frontend) {
case Mode::DYNAMIC:
return CloseFileDynamic(file);
case Mode::STATIC:
return CloseFileStatic(file);
default:
LIBABCKIT_UNREACHABLE;
}
}
extern "C" void DestroyGraph(AbckitGraph *graph)
{
LIBABCKIT_CLEAR_LAST_ERROR;
LIBABCKIT_IMPLEMENTED;
LIBABCKIT_BAD_ARGUMENT_VOID(graph);
if (IsDynamic(graph->function->m->target)) {
return DestroyGraphDynamic(graph);
}
DestroyGraphStatic(graph);
}
AbckitApi g_impl = {
// ========================================
// Common API
// ========================================
ABCKIT_VERSION_RELEASE_1_0_0,
GetLastError,
// ========================================
// Inspection API entrypoints
// ========================================
OpenAbc,
WriteAbc,
CloseFile,
// ========================================
// IR API entrypoints
// ========================================
DestroyGraph,
};
} // namespace libabckit
extern "C" AbckitApi const *AbckitGetApiImpl(AbckitApiVersion version)
{
switch (version) {
case ABCKIT_VERSION_RELEASE_1_0_0:
return &libabckit::g_impl;
default:
libabckit::statuses::SetLastError(ABCKIT_STATUS_UNKNOWN_API_VERSION);
return nullptr;
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_SRC_ABCKIT_OPTIONS_H
#define LIBABCKIT_SRC_ABCKIT_OPTIONS_H
#include "arkcompiler/runtime_core/libabckit/generated/abckit_options_gen.h"
namespace libabckit {
extern libabckit::Options g_abckitOptions;
} // namespace libabckit
#endif // LIBABCKIT_SRC_ABCKIT_OPTIONS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_SRC_ADAPTER_DYNAMIC_ABCKIT_DYNAMIC_H
#define LIBABCKIT_SRC_ADAPTER_DYNAMIC_ABCKIT_DYNAMIC_H
#include "libabckit/include/c/ir_core.h"
#include "libabckit/include/c/metadata_core.h"
namespace libabckit {
AbckitFile *OpenAbcDynamic(const char *path);
void WriteAbcDynamic(AbckitFile *file, const char *path);
void DestroyGraphDynamic(AbckitGraph *graph);
void CloseFileDynamic(AbckitFile *file);
} // namespace libabckit
#endif // LIBABCKIT_SRC_ADAPTER_DYNAMIC_ABCKIT_DYNAMIC_H

View File

@ -0,0 +1,742 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "libabckit/src/metadata_inspect_impl.h"
#include "libabckit/src/adapter_dynamic/helpers_dynamic.h"
#include "libabckit/src/logger.h"
#include "libabckit/src/statuses_impl.h"
#include "assembler/assembly-program.h"
#include <cstdint>
#include <memory>
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#define STD_FILESYSTEM_EXPERIMENTAL
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
// CC-OFFNXT(WordsTool.95 Google) sensitive word conflict
// NOLINTNEXTLINE(google-build-using-namespace)
using namespace panda;
// CC-OFFNXT(WordsTool.95 Google) sensitive word conflict
// NOLINTNEXTLINE(google-build-using-namespace)
using namespace libabckit;
namespace {
// CC-OFFNXT(G.NAM.03) project code style
bool UpdateLitArrSectionPostAction(ModuleIterateData *data, std::pair<size_t, size_t> res)
{
bool *isChangeField {nullptr};
size_t *offset {nullptr};
if (data->isRegularImport.first) {
if (data->isRegularImport.second) {
ASSERT(data->payload->regularImportsOffset == res.second);
isChangeField = &(data->updateData.isRegularImportsChange);
offset = &(data->payload->regularImportsOffset);
} else {
offset = &(data->payload->namespaceImportsOffset);
}
} else {
switch (data->kind) {
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
isChangeField = &(data->updateData.isLocalExportsChange);
offset = &(data->payload->localExportsOffset);
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
offset = &(data->payload->indirectExportsOffset);
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
offset = &(data->payload->starExportsOffset);
break;
}
}
}
auto prevNum = std::get<uint32_t>(data->moduleLitArr->literals_[*offset - 1].value_);
auto newNum = std::get<uint32_t>((data->updateData.newLiterals)[res.second - 1].value_);
if (prevNum != newNum && (isChangeField != nullptr)) {
*isChangeField = true;
}
return true;
}
std::pair<size_t, size_t> UpdateLitArrSection(ModuleIterateData *data, size_t idx, size_t fieldNum)
{
auto &newLiterals = data->updateData.newLiterals;
auto *idxMap =
data->isRegularImport.first ? &data->updateData.regularImportsIdxMap : &data->updateData.localExportsIdxMap;
auto num = std::get<uint32_t>(data->moduleLitArr->literals_[idx].value_);
newLiterals.push_back(std::move(data->moduleLitArr->literals_[idx++]));
auto newOffset = newLiterals.size();
auto prevOffset = idx;
uint32_t oldIdx = 0;
uint32_t actualNumber = 0;
while (idx < prevOffset + num * fieldNum) {
if (data->moduleLitArr->literals_[idx].tag_ == panda_file::LiteralTag::NULLVALUE) {
for (size_t i = 0; i < fieldNum; i++) {
idx++;
}
oldIdx++;
continue;
}
idxMap->emplace(oldIdx, actualNumber);
actualNumber++;
oldIdx++;
for (size_t i = 0; i < fieldNum; i++) {
newLiterals.push_back(std::move(data->moduleLitArr->literals_[idx++]));
}
}
if (actualNumber != num) {
newLiterals[newOffset - 1].value_ = actualNumber;
}
return {idx, newOffset};
}
size_t IterateRequestIdxSectionBeforeUpdate(ModuleIterateData *data)
{
auto &newLiterals = data->updateData.newLiterals;
size_t idx = 0;
while (idx < (data->payload->regularImportsOffset - 1)) {
newLiterals.push_back(std::move(data->moduleLitArr->literals_[idx++]));
}
return idx;
}
bool CheckRegularImport(ModuleUpdateData *updateData, panda::pandasm::Ins *inst)
{
if (updateData->isRegularImportsChange) {
if (inst->opcode == pandasm::Opcode::LDEXTERNALMODULEVAR ||
inst->opcode == pandasm::Opcode::WIDE_LDEXTERNALMODULEVAR) {
auto imm = static_cast<uint32_t>(std::get<int64_t>(inst->imms[0]));
auto foundIdx = updateData->regularImportsIdxMap.find(imm);
if (foundIdx == updateData->regularImportsIdxMap.end()) {
LIBABCKIT_LOG(DEBUG) << "There is an instruction '" << inst->ToString()
<< "' with an unknown regular import index '" << std::hex << imm << "'\n";
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return false;
}
inst->imms[0] = (int64_t)foundIdx->second;
}
}
return true;
}
bool CheckLocalExports(ModuleUpdateData *updateData, panda::pandasm::Ins *inst)
{
if (updateData->isLocalExportsChange) {
auto op = inst->opcode;
if (op == pandasm::Opcode::LDLOCALMODULEVAR || op == pandasm::Opcode::WIDE_LDLOCALMODULEVAR ||
op == pandasm::Opcode::STMODULEVAR || op == pandasm::Opcode::WIDE_STMODULEVAR) {
auto imm = static_cast<uint32_t>(std::get<int64_t>(inst->imms[0]));
auto foundIdx = updateData->localExportsIdxMap.find(imm);
if (foundIdx == updateData->localExportsIdxMap.end()) {
LIBABCKIT_LOG(DEBUG) << "There is an instruction '" << inst->ToString()
<< "' with an unknown local export index '" << std::hex << imm << "'\n";
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return false;
}
inst->imms[0] = (int64_t)foundIdx->second;
}
}
return true;
}
bool UpdateInsImms(pandasm::Program *program, ModuleUpdateData *updateData, const std::string &mainRecordName)
{
for (auto &[name, func] : program->function_table) {
if (pandasm::GetOwnerName(name) != mainRecordName) {
continue;
}
for (auto &inst : func.ins) {
if (!CheckRegularImport(updateData, &inst)) {
return false;
}
if (!CheckLocalExports(updateData, &inst)) {
return false;
}
}
}
return true;
}
AbckitModulePayloadDyn *GetModulePayload(AbckitCoreModule *module)
{
switch (module->target) {
case ABCKIT_TARGET_JS:
return &(module->GetJSImpl()->impl);
break;
case ABCKIT_TARGET_ARK_TS_V1:
return &(module->GetArkTSImpl()->impl.GetDynModule());
default:
LIBABCKIT_UNREACHABLE;
}
}
bool UpdateModuleLiteralArray(AbckitFile *file, const std::string &recName)
{
auto program = file->GetDynamicProgram();
auto module = file->localModules.find(recName);
if (module == file->localModules.end()) {
LIBABCKIT_LOG(DEBUG) << "Can not find module with name '" << recName << "'\n";
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return false;
}
AbckitModulePayloadDyn *mPayload = GetModulePayload(module->second.get());
auto moduleLitArr = mPayload->moduleLiteralArray->GetDynamicImpl();
if (mPayload->absPaths) {
size_t idx = 1;
auto moduleBasePath = fs::path("./" + recName).remove_filename();
while (idx < (mPayload->regularImportsOffset - 1)) {
auto moduleAbsPath = std::get<std::string>(moduleLitArr->literals_[idx].value_);
if (moduleAbsPath[0] == '@') {
moduleLitArr->literals_[idx++].value_ = moduleAbsPath;
} else {
auto relativePath = Relative(moduleAbsPath, moduleBasePath.c_str());
moduleLitArr->literals_[idx++].value_ = "./" + relativePath;
}
}
mPayload->absPaths = false;
}
bool modified = std::any_of(
moduleLitArr->literals_.cbegin(), moduleLitArr->literals_.cend(),
[](const pandasm::LiteralArray::Literal &lit) { return lit.tag_ == panda_file::LiteralTag::NULLVALUE; });
if (!modified) {
return true;
}
ModuleIterateData iterData;
iterData.m = module->second.get();
iterData.payload = mPayload;
iterData.moduleLitArr = moduleLitArr;
if (!IterateModuleSections(iterData, IterateRequestIdxSectionBeforeUpdate, UpdateLitArrSection,
UpdateLitArrSectionPostAction)) {
return false;
}
if (iterData.updateData.isRegularImportsChange || iterData.updateData.isLocalExportsChange) {
if (!UpdateInsImms(program, &iterData.updateData, recName)) {
return false;
}
}
moduleLitArr->literals_ = std::move(iterData.updateData.newLiterals);
LIBABCKIT_LOG_DUMP(DumpModuleArray(moduleLitArr, iterData.m->moduleName->impl), DEBUG);
return true;
}
} // namespace
namespace libabckit {
const panda_file::File *EmitDynamicProgram(AbckitFile *file, pandasm::Program *program,
pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp, bool getFile,
const char *path)
{
for (auto &[recName, rec] : program->record_table) {
if (IsServiceRecord(recName) || IsAnnotationInterfaceRecord(rec) || IsExternalRecord(rec)) {
continue;
}
if (!UpdateModuleLiteralArray(file, recName)) {
return nullptr;
}
}
const panda_file::File *pf = [&]() {
const panda_file::File *res {nullptr};
if (!getFile) {
std::map<std::string, size_t> *statp = nullptr;
if (!pandasm::AsmEmitter::Emit(path, *program, statp, mapsp)) {
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
}
return res;
}
return pandasm::AsmEmitter::Emit(*program, mapsp, 1U).release();
}();
if (getFile && pf == nullptr) {
LIBABCKIT_LOG(DEBUG) << "LIBABCKIT WriteAbcDynamic FAILURE: " << pandasm::AsmEmitter::GetLastError() << '\n';
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return nullptr;
}
return pf;
}
std::string Relative(const std::string &src, const std::string &base)
{
#ifdef STD_FILESYSTEM_EXPERIMENTAL
fs::path tmpPath = src;
fs::path relPath;
while (panda::os::GetAbsolutePath(tmpPath.c_str()) != panda::os::GetAbsolutePath(base)) {
relPath = relPath.empty() ? tmpPath.filename() : tmpPath.filename() / relPath;
if (tmpPath == tmpPath.parent_path()) {
return "";
}
tmpPath = tmpPath.parent_path().c_str();
}
return relPath;
#else
return fs::relative(src, base);
#endif
}
bool IterateModuleSections(
ModuleIterateData &data, const std::function<size_t(ModuleIterateData *)> &requestIdxSectionModifier,
const std::function<std::pair<size_t, size_t>(ModuleIterateData *, size_t, size_t)> &sectionModifier,
const std::function<bool(ModuleIterateData *, std::pair<size_t, size_t>)> &postAction)
{
auto idx = requestIdxSectionModifier(&data);
data.isRegularImport = {true, true};
auto r = sectionModifier(&data, idx, 3U);
if (!postAction(&data, r)) {
return false;
}
idx = r.first;
data.payload->regularImportsOffset = r.second;
data.isRegularImport = {true, false};
r = sectionModifier(&data, idx, 2U);
if (!postAction(&data, r)) {
return false;
}
idx = r.first;
data.payload->namespaceImportsOffset = r.second;
data.isRegularImport = {false, false};
data.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
r = sectionModifier(&data, idx, 2U);
if (!postAction(&data, r)) {
return false;
}
idx = r.first;
data.payload->localExportsOffset = r.second;
data.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
r = sectionModifier(&data, idx, 3U);
if (!postAction(&data, r)) {
return false;
}
idx = r.first;
data.payload->indirectExportsOffset = r.second;
data.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
r = sectionModifier(&data, idx, 1);
if (!postAction(&data, r)) {
return false;
}
data.payload->starExportsOffset = r.second;
return true;
}
void DumpModuleRequests(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numModuleRequests = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto moduleRequestsOffset = idx;
ss << "\n numModuleRequests " << numModuleRequests << " | offset " << idx << std::endl;
while (idx < moduleRequestsOffset + numModuleRequests) {
ss << " [\n";
ss << " module_request: " << std::get<std::string>(moduleLitArr->literals_[idx].value_) << std::endl;
idx++;
ss << " ]\n";
}
}
void DumpRegularImports(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numRegularImports = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto regularImportsOffset = idx;
ss << " numRegularImports " << numRegularImports << " | offset " << idx << std::endl;
while (idx < regularImportsOffset + numRegularImports * 3U) {
ss << " [\n";
ss << " localNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " importNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " moduleRequestIdx: " << std::get<uint16_t>(moduleLitArr->literals_[idx].value_) << std::endl;
idx++;
ss << " ]\n";
}
}
void DumpNamespaceImports(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numNamespaceImports = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto namespaceImportsOffset = idx;
ss << " numNamespaceImports " << numNamespaceImports << " | offset " << idx << std::endl;
while (idx < namespaceImportsOffset + numNamespaceImports * 2U) {
ss << " [\n";
ss << " localNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " moduleRequestIdx: " << std::get<uint16_t>(moduleLitArr->literals_[idx].value_) << std::endl;
idx++;
ss << " ]\n";
}
}
void DumpLocalExports(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numLocalExports = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto localExportsOffset = idx;
ss << " numLocalExports " << numLocalExports << " | offset " << idx << std::endl;
while (idx < localExportsOffset + numLocalExports * 2U) {
ss << " [\n";
ss << " localNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " exportNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " ]\n";
}
}
void DumpIndirectExports(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numIndirectExports = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto indirectExportsOffset = idx;
ss << " numIndirectExports " << numIndirectExports << " | offset " << idx << std::endl;
while (idx < indirectExportsOffset + numIndirectExports * 3U) {
ss << " [\n";
ss << " exportNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " importNameOffset: " << std::get<std::string>(moduleLitArr->literals_[idx].value_)
<< std::endl;
idx++;
ss << " moduleRequestIdx: " << std::get<uint16_t>(moduleLitArr->literals_[idx].value_) << std::endl;
idx++;
ss << " ]\n";
}
}
void DumpStarExports(const pandasm::LiteralArray *moduleLitArr, size_t &idx, std::stringstream &ss)
{
auto numStarExports = std::get<uint32_t>(moduleLitArr->literals_[idx++].value_);
auto starExportsOffset = idx;
ss << " numStarExports " << numStarExports << " | offset " << idx << std::endl;
while (idx < starExportsOffset + numStarExports) {
ss << " [\n";
ss << " moduleRequestIdx: " << std::get<uint16_t>(moduleLitArr->literals_[idx].value_) << std::endl;
idx++;
ss << " ]\n";
}
ss << "]\n";
}
void DumpModuleArray(const pandasm::LiteralArray *moduleLitArr, std::string_view name)
{
std::stringstream ss;
ss << "ModuleLiteralArray " << name << " \n[";
size_t idx = 0;
DumpModuleRequests(moduleLitArr, idx, ss);
DumpRegularImports(moduleLitArr, idx, ss);
DumpNamespaceImports(moduleLitArr, idx, ss);
DumpLocalExports(moduleLitArr, idx, ss);
DumpIndirectExports(moduleLitArr, idx, ss);
DumpStarExports(moduleLitArr, idx, ss);
LIBABCKIT_LOG(DEBUG) << ss.str();
}
bool IsServiceRecord(const std::string &name)
{
constexpr const std::string_view TSTYPE_ANNO_RECORD_NAME = "_TestAnnotation";
return name == TSTYPE_ANNO_RECORD_NAME || name == "_ESConcurrentModuleRequestsAnnotation" ||
name == "L_ESSlotNumberAnnotation" || name == "_ESSlotNumberAnnotation";
}
bool IsAnnotationInterfaceRecord(const pandasm::Record &rec)
{
return (rec.metadata->GetAccessFlags() & ACC_ANNOTATION) != 0;
}
bool IsExternalRecord(const pandasm::Record &rec)
{
return rec.metadata->IsForeign();
}
bool IsMain(const std::string &funcName)
{
size_t dotPos = funcName.rfind('.');
ASSERT(dotPos != std::string::npos);
return funcName.substr(dotPos + 1) == "func_main_0";
}
bool IsFunction(const std::string &fullFuncName)
{
if (IsMain(fullFuncName)) {
return true;
}
size_t dotPos = fullFuncName.rfind('.');
ASSERT(dotPos != std::string::npos);
std::string funcName = fullFuncName.substr(dotPos);
for (auto &sub : {"<#", ">#", "=#", "*#"}) {
if (funcName.find(sub) != std::string::npos) {
return true;
}
}
return false;
}
bool IsCtor(const std::string &funcName)
{
return funcName.find("=#") != std::string::npos;
}
bool IsStatic(const std::string &funcName)
{
if (IsMain(funcName)) {
return true;
}
if (funcName.find("<#") != std::string::npos) {
return true;
}
return funcName.find("*#") != std::string::npos;
}
bool IsAnonymous(const std::string &funcName)
{
if (IsMain(funcName)) {
return false;
}
size_t pos = funcName.rfind('#');
ASSERT(pos != std::string::npos);
std::string name = funcName.substr(pos + 1);
return name.empty() || name.find('^') == 0;
}
static std::string DemangleScopeName(const std::string &mangled, const AbckitLiteralArray *scopeNames)
{
size_t scopeIdx = stoi(mangled);
auto *litArr = scopeNames->GetDynamicImpl();
ASSERT(litArr->literals_.size() % 2U == 0);
ASSERT(scopeIdx < litArr->literals_.size());
auto &lit = litArr->literals_[scopeIdx * 2 + 1];
ASSERT(lit.tag_ == panda_file::LiteralTag::STRING);
return std::get<std::string>(lit.value_);
}
panda::pandasm::Function *GetDynFunction(AbckitCoreFunction *function)
{
switch (function->m->target) {
case ABCKIT_TARGET_JS:
return function->GetJSImpl()->impl;
case ABCKIT_TARGET_ARK_TS_V1:
return function->GetArkTSImpl()->GetDynamicImpl();
default:
LIBABCKIT_UNREACHABLE;
}
}
panda::pandasm::Function *GetDynFunction(AbckitCoreClass *klass)
{
switch (klass->m->target) {
case ABCKIT_TARGET_JS:
return klass->GetJSImpl()->impl;
case ABCKIT_TARGET_ARK_TS_V1:
return klass->GetArkTSImpl()->impl.GetDynamicClass();
default:
LIBABCKIT_UNREACHABLE;
}
}
AbckitModulePayloadDyn *GetDynModulePayload(AbckitCoreModule *mod)
{
switch (mod->target) {
case ABCKIT_TARGET_JS:
return &mod->GetJSImpl()->impl;
case ABCKIT_TARGET_ARK_TS_V1:
return &mod->GetArkTSImpl()->impl.GetDynModule();
default:
LIBABCKIT_UNREACHABLE;
}
}
AbckitDynamicImportDescriptorPayload *GetDynImportDescriptorPayload(AbckitCoreImportDescriptor *id)
{
switch (id->importingModule->target) {
case ABCKIT_TARGET_JS:
return &id->GetJSImpl()->payload.GetDynId();
case ABCKIT_TARGET_ARK_TS_V1:
return &id->GetArkTSImpl()->payload.GetDynId();
default:
LIBABCKIT_UNREACHABLE;
}
}
AbckitDynamicExportDescriptorPayload *GetDynExportDescriptorPayload(AbckitCoreExportDescriptor *ed)
{
AbckitDynamicExportDescriptorPayload *edPayload = nullptr;
switch (ed->exportingModule->target) {
case ABCKIT_TARGET_JS:
edPayload = &ed->GetJSImpl()->payload.GetDynamicPayload();
break;
case ABCKIT_TARGET_ARK_TS_V1:
edPayload = &ed->GetArkTSImpl()->payload.GetDynamicPayload();
break;
default:
LIBABCKIT_UNREACHABLE;
}
return edPayload;
}
std::string GetClassNameFromCtor(const std::string &ctorName, const AbckitLiteralArray *scopeNames)
{
ASSERT(IsCtor(ctorName));
auto className = ctorName.substr(ctorName.find('~') + 1);
className = className.substr(0, className.find("=#"));
if (className[0] != '@') {
return className;
}
return DemangleScopeName(className.substr(1), scopeNames);
}
static void LiteralDeleter(pandasm_Literal *p)
{
delete reinterpret_cast<pandasm::LiteralArray::Literal *>(p);
}
template <class T>
static AbckitLiteral *GetOrCreateLit(AbckitFile *file, std::unordered_map<T, std::unique_ptr<AbckitLiteral>> &cache,
T value, panda_file::LiteralTag tagImpl)
{
if (cache.count(value) == 1) {
return cache[value].get();
}
auto *literal = new pandasm::LiteralArray::Literal();
literal->tag_ = tagImpl;
literal->value_ = value;
auto abcLit = std::make_unique<AbckitLiteral>(
file, AbckitLiteralImplT(reinterpret_cast<pandasm_Literal *>(literal), LiteralDeleter));
cache.insert({value, std::move(abcLit)});
return cache[value].get();
}
AbckitLiteral *GetOrCreateLiteralBoolDynamic(AbckitFile *file, bool value)
{
return GetOrCreateLit(file, file->literals.boolLits, value, panda_file::LiteralTag::BOOL);
}
AbckitLiteral *GetOrCreateLiteralU8Dynamic(AbckitFile *file, uint8_t value)
{
return GetOrCreateLit(file, file->literals.u8Lits, value, panda_file::LiteralTag::ARRAY_U8);
}
AbckitLiteral *GetOrCreateLiteralU16Dynamic(AbckitFile *file, uint16_t value)
{
return GetOrCreateLit(file, file->literals.u16Lits, value, panda_file::LiteralTag::ARRAY_U16);
}
AbckitLiteral *GetOrCreateLiteralMethodAffiliateDynamic(AbckitFile *file, uint16_t value)
{
return GetOrCreateLit(file, file->literals.methodAffilateLits, value, panda_file::LiteralTag::METHODAFFILIATE);
}
AbckitLiteral *GetOrCreateLiteralU32Dynamic(AbckitFile *file, uint32_t value)
{
return GetOrCreateLit(file, file->literals.u32Lits, value, panda_file::LiteralTag::INTEGER);
}
AbckitLiteral *GetOrCreateLiteralU64Dynamic(AbckitFile *file, uint64_t value)
{
return GetOrCreateLit(file, file->literals.u64Lits, value, panda_file::LiteralTag::ARRAY_U64);
}
AbckitLiteral *GetOrCreateLiteralFloatDynamic(AbckitFile *file, float value)
{
return GetOrCreateLit(file, file->literals.floatLits, value, panda_file::LiteralTag::FLOAT);
}
AbckitLiteral *GetOrCreateLiteralDoubleDynamic(AbckitFile *file, double value)
{
return GetOrCreateLit(file, file->literals.doubleLits, value, panda_file::LiteralTag::DOUBLE);
}
AbckitLiteral *GetOrCreateLiteralLiteralArrayDynamic(AbckitFile *file, const std::string &value)
{
return GetOrCreateLit(file, file->literals.litArrLits, value, panda_file::LiteralTag::LITERALARRAY);
}
AbckitLiteral *GetOrCreateLiteralStringDynamic(AbckitFile *file, const std::string &value)
{
return GetOrCreateLit(file, file->literals.stringLits, value, panda_file::LiteralTag::STRING);
}
AbckitLiteral *GetOrCreateLiteralMethodDynamic(AbckitFile *file, const std::string &value)
{
return GetOrCreateLit(file, file->literals.methodLits, value, panda_file::LiteralTag::METHOD);
}
AbckitLiteral *GetOrCreateLiteralDynamic(AbckitFile *file, const pandasm::LiteralArray::Literal &value)
{
switch (value.tag_) {
case panda_file::LiteralTag::ARRAY_U1:
case panda_file::LiteralTag::BOOL:
return GetOrCreateLiteralBoolDynamic(file, std::get<bool>(value.value_));
case panda_file::LiteralTag::ARRAY_U8:
case panda_file::LiteralTag::ARRAY_I8:
return GetOrCreateLiteralU8Dynamic(file, std::get<uint8_t>(value.value_));
case panda_file::LiteralTag::ARRAY_U16:
case panda_file::LiteralTag::ARRAY_I16:
return GetOrCreateLiteralU16Dynamic(file, std::get<uint16_t>(value.value_));
case panda_file::LiteralTag::ARRAY_U32:
case panda_file::LiteralTag::ARRAY_I32:
case panda_file::LiteralTag::INTEGER:
return GetOrCreateLiteralU32Dynamic(file, std::get<uint32_t>(value.value_));
case panda_file::LiteralTag::ARRAY_U64:
case panda_file::LiteralTag::ARRAY_I64:
return GetOrCreateLiteralU64Dynamic(file, std::get<uint64_t>(value.value_));
case panda_file::LiteralTag::ARRAY_F32:
case panda_file::LiteralTag::FLOAT:
return GetOrCreateLiteralFloatDynamic(file, std::get<float>(value.value_));
case panda_file::LiteralTag::ARRAY_F64:
case panda_file::LiteralTag::DOUBLE:
return GetOrCreateLiteralDoubleDynamic(file, std::get<double>(value.value_));
case panda_file::LiteralTag::ARRAY_STRING:
case panda_file::LiteralTag::STRING:
return GetOrCreateLiteralStringDynamic(file, std::get<std::string>(value.value_));
case panda_file::LiteralTag::METHOD:
case panda_file::LiteralTag::GETTER:
case panda_file::LiteralTag::SETTER:
case panda_file::LiteralTag::GENERATORMETHOD:
case panda_file::LiteralTag::ASYNCGENERATORMETHOD:
return GetOrCreateLiteralMethodDynamic(file, std::get<std::string>(value.value_));
case panda_file::LiteralTag::METHODAFFILIATE:
return GetOrCreateLiteralMethodAffiliateDynamic(file, std::get<uint16_t>(value.value_));
case panda_file::LiteralTag::LITERALARRAY:
return GetOrCreateLiteralLiteralArrayDynamic(file, std::get<std::string>(value.value_));
default:
LIBABCKIT_UNREACHABLE;
}
}
} // namespace libabckit

View File

@ -0,0 +1,89 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIBABCKIT_SRC_ADAPTER_DYNAMIC_HELPERS_DYNAMIC_H
#define LIBABCKIT_SRC_ADAPTER_DYNAMIC_HELPERS_DYNAMIC_H
#include <string>
#include "libabckit/include/c/abckit.h"
#include "libabckit/src/metadata_inspect_impl.h"
#include "assembler/assembly-emitter.h"
#include "assembler/assembly-literals.h"
namespace libabckit {
struct ModuleUpdateData {
bool isRegularImportsChange = false;
bool isLocalExportsChange = false;
std::vector<panda::pandasm::LiteralArray::Literal> newLiterals {};
std::unordered_map<uint32_t, uint32_t> regularImportsIdxMap {};
std::unordered_map<uint32_t, uint32_t> localExportsIdxMap {};
};
struct ModuleIterateData {
AbckitCoreModule *m = nullptr;
AbckitModulePayloadDyn *payload = nullptr;
panda::pandasm::LiteralArray *moduleLitArr = nullptr;
std::pair<bool, bool> isRegularImport {}; // {isImport, isRegular}
AbckitDynamicExportKind kind = ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
libabckit::ModuleUpdateData updateData {};
};
const panda::panda_file::File *EmitDynamicProgram(AbckitFile *file, panda::pandasm::Program *program,
panda::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp,
bool getFile, const char *path = nullptr);
bool IterateModuleSections(
ModuleIterateData &data, const std::function<size_t(ModuleIterateData *)> &requestIdxSectionModifier,
const std::function<std::pair<size_t, size_t>(ModuleIterateData *, size_t, size_t)> &sectionModifier,
const std::function<bool(ModuleIterateData *, std::pair<size_t, size_t>)> &postAction);
void DumpModuleArray(const panda::pandasm::LiteralArray *moduleLitArr, std::string_view name);
std::string Relative(const std::string &src, const std::string &base);
bool IsServiceRecord(const std::string &name);
bool IsAnnotationInterfaceRecord(const panda::pandasm::Record &rec);
bool IsExternalRecord(const panda::pandasm::Record &rec);
bool IsMain(const std::string &funcName);
bool IsFunction(const std::string &funcName);
bool IsCtor(const std::string &funcName);
bool IsStatic(const std::string &funcName);
bool IsAnonymous(const std::string &funcName);
panda::pandasm::Function *GetDynFunction(AbckitCoreFunction *function);
panda::pandasm::Function *GetDynFunction(AbckitCoreClass *klass);
AbckitModulePayloadDyn *GetDynModulePayload(AbckitCoreModule *mod);
AbckitDynamicImportDescriptorPayload *GetDynImportDescriptorPayload(AbckitCoreImportDescriptor *id);
AbckitDynamicExportDescriptorPayload *GetDynExportDescriptorPayload(AbckitCoreExportDescriptor *ed);
std::string GetClassNameFromCtor(const std::string &ctorName, const AbckitLiteralArray *scopeNames);
AbckitLiteral *GetOrCreateLiteralBoolDynamic(AbckitFile *file, bool value);
AbckitLiteral *GetOrCreateLiteralU8Dynamic(AbckitFile *file, uint8_t value);
AbckitLiteral *GetOrCreateLiteralU16Dynamic(AbckitFile *file, uint16_t value);
AbckitLiteral *GetOrCreateLiteralMethodAffiliateDynamic(AbckitFile *file, uint16_t value);
AbckitLiteral *GetOrCreateLiteralU32Dynamic(AbckitFile *file, uint32_t value);
AbckitLiteral *GetOrCreateLiteralU64Dynamic(AbckitFile *file, uint64_t value);
AbckitLiteral *GetOrCreateLiteralFloatDynamic(AbckitFile *file, float value);
AbckitLiteral *GetOrCreateLiteralDoubleDynamic(AbckitFile *file, double value);
AbckitLiteral *GetOrCreateLiteralLiteralArrayDynamic(AbckitFile *file, const std::string &value);
AbckitLiteral *GetOrCreateLiteralStringDynamic(AbckitFile *file, const std::string &value);
AbckitLiteral *GetOrCreateLiteralMethodDynamic(AbckitFile *file, const std::string &value);
AbckitLiteral *GetOrCreateLiteralDynamic(AbckitFile *file, const panda::pandasm::LiteralArray::Literal &value);
} // namespace libabckit
#endif

View File

@ -0,0 +1,607 @@
/**
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "libabckit/include/c/statuses.h"
#include "libabckit/include/c/metadata_core.h"
#include "libabckit/src/adapter_dynamic/metadata_inspect_dynamic.h"
#include "libabckit/src/adapter_dynamic/metadata_modify_dynamic.h"
#include "libabckit/src/adapter_dynamic/helpers_dynamic.h"
#include "libabckit/src/macros.h"
#include "libabckit/src/metadata_inspect_impl.h"
#include "libabckit/src/statuses_impl.h"
#include "libabckit/src/wrappers/graph_wrapper/graph_wrapper.h"
#include "libabckit/src/wrappers/abcfile_wrapper.h"
#include "assembler/assembly-emitter.h"
#include "assembler/annotation.h"
#include "assembler/assembly-literals.h"
#include "assembler/assembly-program.h"
#include <cstddef>
#include <cstring>
#include <string>
namespace libabckit {
// CC-OFFNXT(WordsTool.95 Google) sensitive word conflict
// NOLINTNEXTLINE(google-build-using-namespace)
using namespace panda;
// ========================================
// Module
// ========================================
void ModuleEnumerateAnonymousFunctionsDynamic(AbckitCoreModule *m, void *data,
bool (*cb)(AbckitCoreFunction *function, void *data))
{
LIBABCKIT_LOG_FUNC;
LIBABCKIT_BAD_ARGUMENT_VOID(m)
LIBABCKIT_BAD_ARGUMENT_VOID(cb)
for (auto &function : m->functions) {
if (!FunctionIsAnonymousDynamic(function.get())) {
continue;
}
if (!cb(function.get(), data)) {
return;
}
}
}
// ========================================
// Namespace
// ========================================
AbckitString *NamespaceGetNameDynamic(AbckitCoreNamespace *n)
{
LIBABCKIT_LOG_FUNC;
ASSERT(n->m->target == ABCKIT_TARGET_ARK_TS_V1);
auto func = GetDynFunction(n->GetArkTSImpl()->f.get());
auto name = func->name;
size_t sharpPos = name.rfind('#');
ASSERT(sharpPos != std::string::npos);
return CreateStringDynamic(n->m->file, name.substr(sharpPos + 1).data());
}
// ========================================
// Class
// ========================================
AbckitString *ClassGetNameDynamic(AbckitCoreClass *klass)
{
LIBABCKIT_LOG_FUNC;
auto func = GetDynFunction(klass);
auto mPayload = GetDynModulePayload(klass->m);
auto *scopesLitArr = mPayload->scopeNamesLiteralArray;
auto name = GetClassNameFromCtor(func->name, scopesLitArr);
return CreateStringDynamic(klass->m->file, name.data());
}
// ========================================
// Function
// ========================================
AbckitString *FunctionGetNameDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *functionImpl = GetDynFunction(function);
auto name = functionImpl->name;
size_t sharpPos = name.rfind('#');
if (!IsAnonymous(name)) {
if (sharpPos != std::string::npos) {
name = name.substr(sharpPos + 1);
} else {
name = name.substr(name.rfind('.') + 1);
ASSERT(name == "func_main_0");
}
}
return CreateStringDynamic(function->m->file, name.data());
}
AbckitGraph *CreateGraphFromFunctionDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *func = GetDynFunction(function);
LIBABCKIT_LOG(DEBUG) << func->name << '\n';
LIBABCKIT_LOG_DUMP(func->DebugDump(), DEBUG);
auto *file = function->m->file;
auto program = function->m->file->GetDynamicProgram();
auto maps = std::make_unique<pandasm::AsmEmitter::PandaFileToPandaAsmMaps>();
auto pf = EmitDynamicProgram(file, program, maps.get(), true);
if (pf == nullptr) {
return nullptr;
}
uint32_t functionOffset = 0;
for (auto &[id, s] : maps->methods) {
if (s == func->name) {
functionOffset = id;
}
}
if (functionOffset == 0) {
LIBABCKIT_LOG(DEBUG) << "functionOffset == 0\n";
statuses::SetLastError(AbckitStatus::ABCKIT_STATUS_TODO);
return nullptr;
}
auto *irInterface =
new AbckitIrInterface(maps->methods, maps->fields, maps->classes, maps->strings, maps->literalarrays);
auto *wpf = new FileWrapper(reinterpret_cast<const void *>(pf));
auto [graph, error] = GraphWrapper::BuildGraphDynamic(wpf, irInterface, file, functionOffset);
if (error != AbckitStatus::ABCKIT_STATUS_NO_ERROR) {
statuses::SetLastError(error);
return nullptr;
}
ASSERT(graph->file == file);
graph->function = function;
return graph;
}
bool FunctionIsStaticDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *func = GetDynFunction(function);
return IsStatic(func->name);
}
bool FunctionIsCtorDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *func = GetDynFunction(function);
return IsCtor(func->name);
}
bool FunctionIsAnonymousDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *func = GetDynFunction(function);
return IsAnonymous(func->name);
}
bool FunctionIsNativeDynamic(AbckitCoreFunction *function)
{
LIBABCKIT_LOG_FUNC;
auto *func = GetDynFunction(function);
return (func->metadata->GetAccessFlags() & ACC_NATIVE) != 0x0;
}
// ========================================
// Annotation
// ========================================
AbckitString *AnnotationInterfaceGetNameDynamic(AbckitCoreAnnotationInterface *ai)
{
LIBABCKIT_LOG_FUNC;
auto name = pandasm::GetItemName(ai->GetArkTSImpl()->GetDynamicImpl()->name);
return CreateStringDynamic(ai->m->file, name.data());
}
// ========================================
// ImportDescriptor
// ========================================
AbckitString *ImportDescriptorGetNameDynamic(AbckitCoreImportDescriptor *i)
{
std::string name = [i]() {
auto mPayload = GetDynModulePayload(i->importingModule);
auto idPayload = GetDynImportDescriptorPayload(i);
const auto *moduleLitArr = mPayload->moduleLiteralArray;
auto sectionOffset =
idPayload->isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
if (!idPayload->isRegularImport) {
return std::string("*");
}
auto importNameOffset = sectionOffset + idPayload->moduleRecordIndexOff * 3 + 1;
return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[importNameOffset].value_);
}();
return CreateStringDynamic(i->importingModule->file, name.data());
}
AbckitString *ImportDescriptorGetAliasDynamic(AbckitCoreImportDescriptor *i)
{
std::string name = [i]() {
auto mPayload = GetDynModulePayload(i->importingModule);
auto idPayload = GetDynImportDescriptorPayload(i);
const auto *moduleLitArr = mPayload->moduleLiteralArray;
auto sectionOffset =
idPayload->isRegularImport ? mPayload->regularImportsOffset : mPayload->namespaceImportsOffset;
auto gap = idPayload->isRegularImport ? 3 : 2;
auto importNameOffset = sectionOffset + idPayload->moduleRecordIndexOff * gap;
return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[importNameOffset].value_);
}();
return CreateStringDynamic(i->importingModule->file, name.data());
}
// ========================================
// ExportDescriptor
// ========================================
AbckitString *ExportDescriptorGetNameDynamic(AbckitCoreExportDescriptor *i)
{
std::string name = [i]() {
auto mPayload = GetDynModulePayload(i->exportingModule);
auto edPayload = GetDynExportDescriptorPayload(i);
const auto *moduleLitArr = mPayload->moduleLiteralArray;
size_t exportNameOffset;
switch (edPayload->kind) {
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2 + 1;
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
exportNameOffset = mPayload->indirectExportsOffset + edPayload->moduleRecordIndexOff * 3 + 1;
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
std::string res = "*";
return res;
}
}
return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
}();
return CreateStringDynamic(i->exportingModule->file, name.data());
}
AbckitString *ExportDescriptorGetAliasDynamic(AbckitCoreExportDescriptor *i)
{
std::string name = [i]() {
auto mPayload = GetDynModulePayload(i->exportingModule);
auto edPayload = GetDynExportDescriptorPayload(i);
const auto *moduleLitArr = mPayload->moduleLiteralArray;
size_t exportNameOffset;
switch (edPayload->kind) {
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT: {
exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2;
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT: {
exportNameOffset = mPayload->indirectExportsOffset + edPayload->moduleRecordIndexOff * 3;
break;
}
case AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT: {
if (!edPayload->hasServiceImport) {
std::string res;
return res;
}
exportNameOffset = mPayload->localExportsOffset + edPayload->moduleRecordIndexOff * 2 + 1;
}
}
return std::get<std::string>(moduleLitArr->GetDynamicImpl()->literals_[exportNameOffset].value_);
}();
return CreateStringDynamic(i->exportingModule->file, name.data());
}
// ========================================
// Literal
// ========================================
bool LiteralGetBoolDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsBoolValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return false;
}
return std::get<bool>(literal->value_);
}
uint8_t LiteralGetU8Dynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsByteValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<uint8_t>(literal->value_);
}
uint16_t LiteralGetU16Dynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsShortValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<uint16_t>(literal->value_);
}
uint16_t LiteralGetMethodAffiliateDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (literal->tag_ != panda_file::LiteralTag::METHODAFFILIATE) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<uint16_t>(literal->value_);
}
uint32_t LiteralGetU32Dynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsIntegerValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<uint32_t>(literal->value_);
}
uint64_t LiteralGetU64Dynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsLongValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<uint64_t>(literal->value_);
}
float LiteralGetFloatDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsFloatValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<float>(literal->value_);
}
double LiteralGetDoubleDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsDoubleValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return 0;
}
return std::get<double>(literal->value_);
}
AbckitLiteralArray *LiteralGetLiteralArrayDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (literal->tag_ != panda::panda_file::LiteralTag::LITERALARRAY) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return nullptr;
}
auto &litarrs = lit->file->GetDynamicProgram()->literalarray_table;
auto &val = std::get<std::string>(literal->value_);
if (litarrs.find(val) != litarrs.end()) {
for (auto &item : lit->file->litarrs) {
if (item->GetDynamicImpl() == &litarrs[val]) {
return item.get();
}
}
statuses::SetLastError(ABCKIT_STATUS_BAD_ARGUMENT);
}
panda::pandasm::LiteralArray *impl = nullptr;
for (auto &item : lit->file->GetDynamicProgram()->literalarray_table) {
if (item.first == val) {
impl = &item.second;
break;
}
}
auto litarr = std::make_unique<AbckitLiteralArray>(lit->file, impl);
lit->file->litarrs.emplace_back(std::move(litarr));
return lit->file->litarrs[lit->file->litarrs.size() - 1].get();
}
AbckitString *LiteralGetStringDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto s = std::make_unique<AbckitString>();
auto *literal = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
if (!literal->IsStringValue()) {
statuses::SetLastError(ABCKIT_STATUS_WRONG_LITERAL_TYPE);
return nullptr;
}
auto &strings = lit->file->strings;
auto &val = std::get<std::string>(literal->value_);
if (strings.find(val) != strings.end()) {
return strings[val].get();
}
s->impl = val;
strings.insert({val, std::move(s)});
return strings[val].get();
}
AbckitLiteralTag LiteralGetTagDynamic(AbckitLiteral *lit)
{
LIBABCKIT_LOG_FUNC;
auto *litImpl = reinterpret_cast<pandasm::LiteralArray::Literal *>(lit->val.get());
switch (litImpl->tag_) {
case panda_file::LiteralTag::ARRAY_U1:
case panda_file::LiteralTag::BOOL:
return ABCKIT_LITERAL_TAG_BOOL;
case panda_file::LiteralTag::ARRAY_U8:
case panda_file::LiteralTag::ARRAY_I8:
return ABCKIT_LITERAL_TAG_BYTE;
case panda_file::LiteralTag::ARRAY_U16:
case panda_file::LiteralTag::ARRAY_I16:
return ABCKIT_LITERAL_TAG_SHORT;
case panda_file::LiteralTag::ARRAY_U32:
case panda_file::LiteralTag::ARRAY_I32:
case panda_file::LiteralTag::INTEGER:
return ABCKIT_LITERAL_TAG_INTEGER;
case panda_file::LiteralTag::ARRAY_U64:
case panda_file::LiteralTag::ARRAY_I64:
return ABCKIT_LITERAL_TAG_LONG;
case panda_file::LiteralTag::ARRAY_F32:
case panda_file::LiteralTag::FLOAT:
return ABCKIT_LITERAL_TAG_FLOAT;
case panda_file::LiteralTag::ARRAY_F64:
case panda_file::LiteralTag::DOUBLE:
return ABCKIT_LITERAL_TAG_DOUBLE;
case panda_file::LiteralTag::ARRAY_STRING:
case panda_file::LiteralTag::STRING:
return ABCKIT_LITERAL_TAG_STRING;
case panda_file::LiteralTag::NULLVALUE:
return ABCKIT_LITERAL_TAG_NULLVALUE;
case panda_file::LiteralTag::TAGVALUE:
return ABCKIT_LITERAL_TAG_TAGVALUE;
case panda_file::LiteralTag::METHOD:
case panda_file::LiteralTag::GETTER:
case panda_file::LiteralTag::SETTER:
case panda_file::LiteralTag::GENERATORMETHOD:
case panda_file::LiteralTag::ASYNCGENERATORMETHOD:
return ABCKIT_LITERAL_TAG_METHOD;
case panda_file::LiteralTag::METHODAFFILIATE:
return ABCKIT_LITERAL_TAG_METHODAFFILIATE;
case panda_file::LiteralTag::LITERALARRAY:
return ABCKIT_LITERAL_TAG_LITERALARRAY;
default:
return ABCKIT_LITERAL_TAG_INVALID;
}
}
void LiteralArrayEnumerateElementsDynamic(AbckitLiteralArray *litArr, void *data,
bool (*cb)(AbckitFile *file, AbckitLiteral *lit, void *data))
{
LIBABCKIT_LOG_FUNC;
auto *arrImpl = litArr->GetDynamicImpl();
size_t size = arrImpl->literals_.size();
if (size % 2U != 0) {
statuses::SetLastError(ABCKIT_STATUS_TODO);
return;
}
for (size_t idx = 1; idx < size; idx += 2U) {
auto litImpl = arrImpl->literals_[idx];
if (!cb(litArr->file, GetOrCreateLiteralDynamic(litArr->file, litImpl), data)) {
return;
}
}
}
// ========================================
// Value
// ========================================
AbckitType *ValueGetTypeDynamic(AbckitValue *value)
{
LIBABCKIT_LOG_FUNC;
auto *pVal = static_cast<pandasm::ScalarValue *>(value->GetDynamicImpl());
auto type = std::make_unique<AbckitType>();
type->klass = nullptr; // NOTE implement logic for classes
switch (pVal->GetType()) {
case pandasm::Value::Type::U1:
type->id = ABCKIT_TYPE_ID_U1;
break;
case pandasm::Value::Type::U8:
type->id = ABCKIT_TYPE_ID_U8;
break;
case pandasm::Value::Type::U16:
type->id = ABCKIT_TYPE_ID_U16;
break;
case pandasm::Value::Type::U32:
type->id = ABCKIT_TYPE_ID_U32;
break;
case pandasm::Value::Type::U64:
type->id = ABCKIT_TYPE_ID_U64;
break;
case pandasm::Value::Type::F64:
type->id = ABCKIT_TYPE_ID_F64;
break;
case pandasm::Value::Type::STRING:
type->id = ABCKIT_TYPE_ID_STRING;
break;
case pandasm::Value::Type::LITERALARRAY:
type->id = ABCKIT_TYPE_ID_LITERALARRAY;
break;
default:
LIBABCKIT_UNIMPLEMENTED;
}
value->file->types.emplace_back(std::move(type));
return value->file->types.back().get();
}
bool ValueGetU1Dynamic(AbckitValue *value)
{
LIBABCKIT_LOG_FUNC;
if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_U1) {
statuses::SetLastError(ABCKIT_STATUS_TODO);
return false;
}
auto *pVal = static_cast<pandasm::ScalarValue *>(value->GetDynamicImpl());
return pVal->GetValue<bool>();
}
double ValueGetDoubleDynamic(AbckitValue *value)
{
LIBABCKIT_LOG_FUNC;
if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_F64) {
statuses::SetLastError(ABCKIT_STATUS_TODO);
return 0.0;
}
auto *pVal = static_cast<pandasm::ScalarValue *>(value->GetDynamicImpl());
return pVal->GetValue<double>();
}
AbckitString *ValueGetStringDynamic(AbckitValue *value)
{
LIBABCKIT_LOG_FUNC;
if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_STRING) {
statuses::SetLastError(ABCKIT_STATUS_TODO);
return nullptr;
}
auto *pVal = static_cast<pandasm::ScalarValue *>(value->GetDynamicImpl());
auto valImpl = pVal->GetValue<std::string>();
return CreateStringDynamic(value->file, valImpl.data());
}
AbckitLiteralArray *ArrayValueGetLiteralArrayDynamic(AbckitValue *value)
{
LIBABCKIT_LOG_FUNC;
if (ValueGetTypeDynamic(value)->id != ABCKIT_TYPE_ID_LITERALARRAY) {
statuses::SetLastError(ABCKIT_STATUS_TODO);
return nullptr;
}
auto *pVal = static_cast<pandasm::ScalarValue *>(value->GetDynamicImpl());
auto valImpl = pVal->GetValue<std::string>();
auto *prog = value->file->GetDynamicProgram();
auto litarr = std::make_unique<AbckitLiteralArray>(value->file, &(prog->literalarray_table[valImpl]));
return value->file->litarrs.emplace_back(std::move(litarr)).get();
}
} // namespace libabckit

Some files were not shown because too many files have changed in this diff Show More