asmjit 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/asmjit.gemspec +1 -1
- data/ext/asmjit/asmjit/.editorconfig +10 -0
- data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
- data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
- data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
- data/ext/asmjit/asmjit/.gitignore +6 -0
- data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
- data/ext/asmjit/asmjit/LICENSE.md +17 -0
- data/ext/asmjit/asmjit/README.md +69 -0
- data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
- data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
- data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
- data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
- data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
- data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
- data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
- data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
- data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
- data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
- data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
- data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
- data/ext/asmjit/asmjit/test/broken.cpp +312 -0
- data/ext/asmjit/asmjit/test/broken.h +148 -0
- data/ext/asmjit/asmjit/test/cmdline.h +61 -0
- data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
- data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
- data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
- data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
- data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
- data/ext/asmjit/asmjit.cc +18 -0
- data/lib/asmjit/version.rb +1 -1
- metadata +197 -2
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
|
2
|
+
//
|
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
|
4
|
+
// SPDX-License-Identifier: Zlib
|
|
5
|
+
|
|
6
|
+
#include <asmjit/core.h>
|
|
7
|
+
|
|
8
|
+
#if !defined(ASMJIT_NO_X86)
|
|
9
|
+
#include <asmjit/x86.h>
|
|
10
|
+
#endif
|
|
11
|
+
|
|
12
|
+
#include "asmjitutils.h"
|
|
13
|
+
#include "broken.h"
|
|
14
|
+
|
|
15
|
+
using namespace asmjit;
|
|
16
|
+
|
|
17
|
+
static void dumpCpu(void) noexcept {
|
|
18
|
+
const CpuInfo& cpu = CpuInfo::host();
|
|
19
|
+
|
|
20
|
+
// CPU Information
|
|
21
|
+
// ---------------
|
|
22
|
+
|
|
23
|
+
INFO("CPU Info:");
|
|
24
|
+
INFO(" Vendor : %s", cpu.vendor());
|
|
25
|
+
INFO(" Brand : %s", cpu.brand());
|
|
26
|
+
INFO(" Model ID : %u", cpu.modelId());
|
|
27
|
+
INFO(" Brand ID : %u", cpu.brandId());
|
|
28
|
+
INFO(" Family ID : %u", cpu.familyId());
|
|
29
|
+
INFO(" Stepping : %u", cpu.stepping());
|
|
30
|
+
INFO(" Processor Type : %u", cpu.processorType());
|
|
31
|
+
INFO(" Max logical Processors : %u", cpu.maxLogicalProcessors());
|
|
32
|
+
INFO(" Cache-Line Size : %u", cpu.cacheLineSize());
|
|
33
|
+
INFO(" HW-Thread Count : %u", cpu.hwThreadCount());
|
|
34
|
+
INFO("");
|
|
35
|
+
|
|
36
|
+
// CPU Features
|
|
37
|
+
// ------------
|
|
38
|
+
|
|
39
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
40
|
+
INFO("CPU Features:");
|
|
41
|
+
CpuFeatures::Iterator it(cpu.features().iterator());
|
|
42
|
+
while (it.hasNext()) {
|
|
43
|
+
uint32_t featureId = uint32_t(it.next());
|
|
44
|
+
StringTmp<64> featureString;
|
|
45
|
+
Formatter::formatFeature(featureString, cpu.arch(), featureId);
|
|
46
|
+
INFO(" %s\n", featureString.data());
|
|
47
|
+
};
|
|
48
|
+
INFO("");
|
|
49
|
+
#endif // !ASMJIT_NO_LOGGING
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#define DUMP_TYPE(...) \
|
|
53
|
+
INFO(" %-26s: %u", #__VA_ARGS__, uint32_t(sizeof(__VA_ARGS__)))
|
|
54
|
+
|
|
55
|
+
static void dumpSizeOf(void) noexcept {
|
|
56
|
+
INFO("Size of C++ types:");
|
|
57
|
+
DUMP_TYPE(int8_t);
|
|
58
|
+
DUMP_TYPE(int16_t);
|
|
59
|
+
DUMP_TYPE(int32_t);
|
|
60
|
+
DUMP_TYPE(int64_t);
|
|
61
|
+
DUMP_TYPE(int);
|
|
62
|
+
DUMP_TYPE(long);
|
|
63
|
+
DUMP_TYPE(size_t);
|
|
64
|
+
DUMP_TYPE(intptr_t);
|
|
65
|
+
DUMP_TYPE(float);
|
|
66
|
+
DUMP_TYPE(double);
|
|
67
|
+
DUMP_TYPE(void*);
|
|
68
|
+
INFO("");
|
|
69
|
+
|
|
70
|
+
INFO("Size of base classes:");
|
|
71
|
+
DUMP_TYPE(BaseAssembler);
|
|
72
|
+
DUMP_TYPE(BaseEmitter);
|
|
73
|
+
DUMP_TYPE(CodeBuffer);
|
|
74
|
+
DUMP_TYPE(CodeHolder);
|
|
75
|
+
DUMP_TYPE(ConstPool);
|
|
76
|
+
DUMP_TYPE(LabelEntry);
|
|
77
|
+
DUMP_TYPE(RelocEntry);
|
|
78
|
+
DUMP_TYPE(Section);
|
|
79
|
+
DUMP_TYPE(String);
|
|
80
|
+
DUMP_TYPE(Target);
|
|
81
|
+
DUMP_TYPE(Zone);
|
|
82
|
+
DUMP_TYPE(ZoneAllocator);
|
|
83
|
+
DUMP_TYPE(ZoneBitVector);
|
|
84
|
+
DUMP_TYPE(ZoneHashNode);
|
|
85
|
+
DUMP_TYPE(ZoneHash<ZoneHashNode>);
|
|
86
|
+
DUMP_TYPE(ZoneList<int>);
|
|
87
|
+
DUMP_TYPE(ZoneVector<int>);
|
|
88
|
+
INFO("");
|
|
89
|
+
|
|
90
|
+
INFO("Size of operand classes:");
|
|
91
|
+
DUMP_TYPE(Operand);
|
|
92
|
+
DUMP_TYPE(BaseReg);
|
|
93
|
+
DUMP_TYPE(BaseMem);
|
|
94
|
+
DUMP_TYPE(Imm);
|
|
95
|
+
DUMP_TYPE(Label);
|
|
96
|
+
INFO("");
|
|
97
|
+
|
|
98
|
+
INFO("Size of function classes:");
|
|
99
|
+
DUMP_TYPE(CallConv);
|
|
100
|
+
DUMP_TYPE(FuncFrame);
|
|
101
|
+
DUMP_TYPE(FuncValue);
|
|
102
|
+
DUMP_TYPE(FuncDetail);
|
|
103
|
+
DUMP_TYPE(FuncSignature);
|
|
104
|
+
DUMP_TYPE(FuncArgsAssignment);
|
|
105
|
+
INFO("");
|
|
106
|
+
|
|
107
|
+
#if !defined(ASMJIT_NO_BUILDER)
|
|
108
|
+
INFO("Size of builder classes:");
|
|
109
|
+
DUMP_TYPE(BaseBuilder);
|
|
110
|
+
DUMP_TYPE(BaseNode);
|
|
111
|
+
DUMP_TYPE(InstNode);
|
|
112
|
+
DUMP_TYPE(InstExNode);
|
|
113
|
+
DUMP_TYPE(AlignNode);
|
|
114
|
+
DUMP_TYPE(LabelNode);
|
|
115
|
+
DUMP_TYPE(EmbedDataNode);
|
|
116
|
+
DUMP_TYPE(EmbedLabelNode);
|
|
117
|
+
DUMP_TYPE(ConstPoolNode);
|
|
118
|
+
DUMP_TYPE(CommentNode);
|
|
119
|
+
DUMP_TYPE(SentinelNode);
|
|
120
|
+
INFO("");
|
|
121
|
+
#endif
|
|
122
|
+
|
|
123
|
+
#if !defined(ASMJIT_NO_COMPILER)
|
|
124
|
+
INFO("Size of compiler classes:");
|
|
125
|
+
DUMP_TYPE(BaseCompiler);
|
|
126
|
+
DUMP_TYPE(FuncNode);
|
|
127
|
+
DUMP_TYPE(FuncRetNode);
|
|
128
|
+
DUMP_TYPE(InvokeNode);
|
|
129
|
+
INFO("");
|
|
130
|
+
#endif
|
|
131
|
+
|
|
132
|
+
#if !defined(ASMJIT_NO_X86)
|
|
133
|
+
INFO("Size of x86-specific classes:");
|
|
134
|
+
DUMP_TYPE(x86::Assembler);
|
|
135
|
+
#if !defined(ASMJIT_NO_BUILDER)
|
|
136
|
+
DUMP_TYPE(x86::Builder);
|
|
137
|
+
#endif
|
|
138
|
+
#if !defined(ASMJIT_NO_COMPILER)
|
|
139
|
+
DUMP_TYPE(x86::Compiler);
|
|
140
|
+
#endif
|
|
141
|
+
DUMP_TYPE(x86::InstDB::InstInfo);
|
|
142
|
+
DUMP_TYPE(x86::InstDB::CommonInfo);
|
|
143
|
+
DUMP_TYPE(x86::InstDB::OpSignature);
|
|
144
|
+
DUMP_TYPE(x86::InstDB::InstSignature);
|
|
145
|
+
INFO("");
|
|
146
|
+
#endif
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#undef DUMP_TYPE
|
|
150
|
+
|
|
151
|
+
static void onBeforeRun(void) noexcept {
|
|
152
|
+
dumpCpu();
|
|
153
|
+
dumpSizeOf();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
int main(int argc, const char* argv[]) {
|
|
157
|
+
#if defined(ASMJIT_BUILD_DEBUG)
|
|
158
|
+
const char buildType[] = "Debug";
|
|
159
|
+
#else
|
|
160
|
+
const char buildType[] = "Release";
|
|
161
|
+
#endif
|
|
162
|
+
|
|
163
|
+
INFO("AsmJit Unit-Test v%u.%u.%u [Arch=%s] [Mode=%s]\n\n",
|
|
164
|
+
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
|
|
165
|
+
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
|
|
166
|
+
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
|
|
167
|
+
asmjitArchAsString(Arch::kHost),
|
|
168
|
+
buildType
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
return BrokenAPI::run(argc, argv, onBeforeRun);
|
|
172
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
|
2
|
+
//
|
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
|
4
|
+
// SPDX-License-Identifier: Zlib
|
|
5
|
+
|
|
6
|
+
// ----------------------------------------------------------------------------
|
|
7
|
+
// This is a working example that demonstrates how multiple sections can be
|
|
8
|
+
// used in a JIT-based code generator. It shows also the necessary tooling
|
|
9
|
+
// that is expected to be done by the user when the feature is used. It's
|
|
10
|
+
// important to handle the following cases:
|
|
11
|
+
//
|
|
12
|
+
// - Assign offsets to sections when the code generation is finished.
|
|
13
|
+
// - Tell the CodeHolder to resolve unresolved links and check whether
|
|
14
|
+
// all links were resolved.
|
|
15
|
+
// - Relocate the code
|
|
16
|
+
// - Copy the code to the destination address.
|
|
17
|
+
// ----------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
#include <asmjit/core.h>
|
|
20
|
+
#if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86
|
|
21
|
+
|
|
22
|
+
#include <asmjit/x86.h>
|
|
23
|
+
#include <stdio.h>
|
|
24
|
+
#include <stdlib.h>
|
|
25
|
+
#include <string.h>
|
|
26
|
+
|
|
27
|
+
using namespace asmjit;
|
|
28
|
+
|
|
29
|
+
// The generated function is very simple, it only accesses the built-in data
|
|
30
|
+
// (from .data section) at the index as provided by its first argument. This
|
|
31
|
+
// data is inlined into the resulting function so we can use it this array
|
|
32
|
+
// for verification that the function returns correct values.
|
|
33
|
+
static const uint8_t dataArray[] = { 2, 9, 4, 7, 1, 3, 8, 5, 6, 0 };
|
|
34
|
+
|
|
35
|
+
static void fail(const char* message, Error err) {
|
|
36
|
+
printf("** FAILURE: %s (%s) **\n", message, DebugUtils::errorAsString(err));
|
|
37
|
+
exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
int main() {
|
|
41
|
+
printf("AsmJit X86 Sections Test\n\n");
|
|
42
|
+
|
|
43
|
+
Environment env = Environment::host();
|
|
44
|
+
JitAllocator allocator;
|
|
45
|
+
|
|
46
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
47
|
+
FileLogger logger(stdout);
|
|
48
|
+
logger.setIndentation(FormatIndentationGroup::kCode, 2);
|
|
49
|
+
#endif
|
|
50
|
+
|
|
51
|
+
CodeHolder code;
|
|
52
|
+
code.init(env);
|
|
53
|
+
|
|
54
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
55
|
+
code.setLogger(&logger);
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
Section* dataSection;
|
|
59
|
+
Error err = code.newSection(&dataSection, ".data", SIZE_MAX, SectionFlags::kNone, 8);
|
|
60
|
+
|
|
61
|
+
if (err) {
|
|
62
|
+
fail("Failed to create a .data section", err);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
printf("Generating code:\n");
|
|
66
|
+
x86::Assembler a(&code);
|
|
67
|
+
x86::Gp idx = a.zax();
|
|
68
|
+
x86::Gp addr = a.zcx();
|
|
69
|
+
|
|
70
|
+
Label data = a.newLabel();
|
|
71
|
+
|
|
72
|
+
FuncDetail func;
|
|
73
|
+
func.init(FuncSignatureT<size_t, size_t>(CallConvId::kHost), code.environment());
|
|
74
|
+
|
|
75
|
+
FuncFrame frame;
|
|
76
|
+
frame.init(func);
|
|
77
|
+
frame.addDirtyRegs(idx, addr);
|
|
78
|
+
|
|
79
|
+
FuncArgsAssignment args(&func);
|
|
80
|
+
args.assignAll(idx);
|
|
81
|
+
args.updateFuncFrame(frame);
|
|
82
|
+
frame.finalize();
|
|
83
|
+
|
|
84
|
+
a.emitProlog(frame);
|
|
85
|
+
a.emitArgsAssignment(frame, args);
|
|
86
|
+
|
|
87
|
+
a.lea(addr, x86::ptr(data));
|
|
88
|
+
a.movzx(idx, x86::byte_ptr(addr, idx));
|
|
89
|
+
|
|
90
|
+
a.emitEpilog(frame);
|
|
91
|
+
|
|
92
|
+
a.section(dataSection);
|
|
93
|
+
a.bind(data);
|
|
94
|
+
|
|
95
|
+
a.embed(dataArray, sizeof(dataArray));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Manually change he offsets of each section, start at 0. This code is very
|
|
99
|
+
// similar to what `CodeHolder::flatten()` does, however, it's shown here
|
|
100
|
+
// how to do it explicitly.
|
|
101
|
+
printf("\nCalculating section offsets:\n");
|
|
102
|
+
uint64_t offset = 0;
|
|
103
|
+
for (Section* section : code.sectionsByOrder()) {
|
|
104
|
+
offset = Support::alignUp(offset, section->alignment());
|
|
105
|
+
section->setOffset(offset);
|
|
106
|
+
offset += section->realSize();
|
|
107
|
+
|
|
108
|
+
printf(" [0x%08X %s] {Id=%u Size=%u}\n",
|
|
109
|
+
uint32_t(section->offset()),
|
|
110
|
+
section->name(),
|
|
111
|
+
section->id(),
|
|
112
|
+
uint32_t(section->realSize()));
|
|
113
|
+
}
|
|
114
|
+
size_t codeSize = size_t(offset);
|
|
115
|
+
printf(" Final code size: %zu\n", codeSize);
|
|
116
|
+
|
|
117
|
+
// Resolve cross-section links (if any). On 32-bit X86 this is not necessary
|
|
118
|
+
// as this is handled through relocations as the addressing is different.
|
|
119
|
+
if (code.hasUnresolvedLinks()) {
|
|
120
|
+
printf("\nResolving cross-section links:\n");
|
|
121
|
+
printf(" Before 'resolveUnresolvedLinks()': %zu\n", code.unresolvedLinkCount());
|
|
122
|
+
|
|
123
|
+
err = code.resolveUnresolvedLinks();
|
|
124
|
+
if (err)
|
|
125
|
+
fail("Failed to resolve cross-section links", err);
|
|
126
|
+
printf(" After 'resolveUnresolvedLinks()': %zu\n", code.unresolvedLinkCount());
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Allocate memory for the function and relocate it there.
|
|
130
|
+
void* rxPtr;
|
|
131
|
+
void* rwPtr;
|
|
132
|
+
err = allocator.alloc(&rxPtr, &rwPtr, codeSize);
|
|
133
|
+
if (err)
|
|
134
|
+
fail("Failed to allocate executable memory", err);
|
|
135
|
+
|
|
136
|
+
// Relocate to the base-address of the allocated memory.
|
|
137
|
+
code.relocateToBase(uint64_t(uintptr_t(rxPtr)));
|
|
138
|
+
|
|
139
|
+
VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadWrite);
|
|
140
|
+
|
|
141
|
+
// Copy the flattened code into `mem.rw`. There are two ways. You can either copy
|
|
142
|
+
// everything manually by iterating over all sections or use `copyFlattenedData`.
|
|
143
|
+
// This code is similar to what `copyFlattenedData(p, codeSize, 0)` would do:
|
|
144
|
+
for (Section* section : code.sectionsByOrder())
|
|
145
|
+
memcpy(static_cast<uint8_t*>(rwPtr) + size_t(section->offset()), section->data(), section->bufferSize());
|
|
146
|
+
|
|
147
|
+
VirtMem::protectJitMemory(VirtMem::ProtectJitAccess::kReadExecute);
|
|
148
|
+
VirtMem::flushInstructionCache(rwPtr, code.codeSize());
|
|
149
|
+
|
|
150
|
+
// Execute the function and test whether it works.
|
|
151
|
+
typedef size_t (*Func)(size_t idx);
|
|
152
|
+
Func fn = (Func)rxPtr;
|
|
153
|
+
|
|
154
|
+
printf("\n");
|
|
155
|
+
if (fn(0) != dataArray[0] ||
|
|
156
|
+
fn(3) != dataArray[3] ||
|
|
157
|
+
fn(6) != dataArray[6] ||
|
|
158
|
+
fn(9) != dataArray[9] ) {
|
|
159
|
+
printf("** FAILURE: The generated function returned incorrect result(s) **\n");
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
printf("** SUCCESS **\n");
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#else
|
|
168
|
+
int main() {
|
|
169
|
+
printf("AsmJit X86 Sections Test is disabled on non-x86 host\n\n");
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
#endif // !ASMJIT_NO_X86 && ASMJIT_ARCH_X86
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
|
2
|
+
//
|
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
|
4
|
+
// SPDX-License-Identifier: Zlib
|
|
5
|
+
|
|
6
|
+
#ifndef ASMJITUTILS_H_INCLUDED
|
|
7
|
+
#define ASMJITUTILS_H_INCLUDED
|
|
8
|
+
|
|
9
|
+
#include <asmjit/core.h>
|
|
10
|
+
|
|
11
|
+
static const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
|
|
12
|
+
switch (arch) {
|
|
13
|
+
case asmjit::Arch::kX86 : return "X86";
|
|
14
|
+
case asmjit::Arch::kX64 : return "X64";
|
|
15
|
+
|
|
16
|
+
case asmjit::Arch::kRISCV32 : return "RISCV32";
|
|
17
|
+
case asmjit::Arch::kRISCV64 : return "RISCV64";
|
|
18
|
+
|
|
19
|
+
case asmjit::Arch::kARM : return "ARM";
|
|
20
|
+
case asmjit::Arch::kAArch64 : return "AArch64";
|
|
21
|
+
case asmjit::Arch::kThumb : return "Thumb";
|
|
22
|
+
|
|
23
|
+
case asmjit::Arch::kMIPS32_LE : return "MIPS_LE";
|
|
24
|
+
case asmjit::Arch::kMIPS64_LE : return "MIPS64_LE";
|
|
25
|
+
|
|
26
|
+
case asmjit::Arch::kARM_BE : return "ARM_BE";
|
|
27
|
+
case asmjit::Arch::kThumb_BE : return "Thumb_BE";
|
|
28
|
+
case asmjit::Arch::kAArch64_BE: return "AArch64_BE";
|
|
29
|
+
|
|
30
|
+
case asmjit::Arch::kMIPS32_BE : return "MIPS_BE";
|
|
31
|
+
case asmjit::Arch::kMIPS64_BE : return "MIPS64_BE";
|
|
32
|
+
|
|
33
|
+
default:
|
|
34
|
+
return "<Unknown>";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#endif // ASMJITUTILS_H_INCLUDED
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// Broken - Lightweight unit testing for C++
|
|
2
|
+
//
|
|
3
|
+
// This is free and unencumbered software released into the public domain.
|
|
4
|
+
//
|
|
5
|
+
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
6
|
+
// distribute this software, either in source code form or as a compiled
|
|
7
|
+
// binary, for any purpose, commercial or non-commercial, and by any
|
|
8
|
+
// means.
|
|
9
|
+
//
|
|
10
|
+
// In jurisdictions that recognize copyright laws, the author or authors
|
|
11
|
+
// of this software dedicate any and all copyright interest in the
|
|
12
|
+
// software to the public domain. We make this dedication for the benefit
|
|
13
|
+
// of the public at large and to the detriment of our heirs and
|
|
14
|
+
// successors. We intend this dedication to be an overt act of
|
|
15
|
+
// relinquishment in perpetuity of all present and future rights to this
|
|
16
|
+
// software under copyright law.
|
|
17
|
+
//
|
|
18
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
21
|
+
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
22
|
+
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
23
|
+
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
24
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
25
|
+
//
|
|
26
|
+
// For more information, please refer to <http://unlicense.org>
|
|
27
|
+
|
|
28
|
+
#include "./broken.h"
|
|
29
|
+
#include <stdarg.h>
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// [Broken - Global]
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
// Zero initialized globals.
|
|
36
|
+
struct BrokenGlobal {
|
|
37
|
+
// Application arguments.
|
|
38
|
+
int _argc;
|
|
39
|
+
const char** _argv;
|
|
40
|
+
|
|
41
|
+
// Output file.
|
|
42
|
+
FILE* _file;
|
|
43
|
+
|
|
44
|
+
// Unit tests.
|
|
45
|
+
BrokenAPI::Unit* _unitList;
|
|
46
|
+
BrokenAPI::Unit* _unitRunning;
|
|
47
|
+
|
|
48
|
+
bool hasArg(const char* a) const noexcept {
|
|
49
|
+
for (int i = 1; i < _argc; i++)
|
|
50
|
+
if (strcmp(_argv[i], a) == 0)
|
|
51
|
+
return true;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
inline FILE* file() const noexcept { return _file ? _file : stdout; }
|
|
56
|
+
};
|
|
57
|
+
static BrokenGlobal _brokenGlobal;
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// [Broken - API]
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
// Get whether the string `a` starts with string `b`.
|
|
64
|
+
static bool BrokenAPI_startsWith(const char* a, const char* b) noexcept {
|
|
65
|
+
for (size_t i = 0; ; i++) {
|
|
66
|
+
if (b[i] == '\0') return true;
|
|
67
|
+
if (a[i] != b[i]) return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//! Compares names and priority of two unit tests.
|
|
72
|
+
static int BrokenAPI_compareUnits(const BrokenAPI::Unit* a, const BrokenAPI::Unit* b) noexcept {
|
|
73
|
+
if (a->priority == b->priority)
|
|
74
|
+
return strcmp(a->name, b->name);
|
|
75
|
+
else
|
|
76
|
+
return a->priority > b->priority ? 1 : -1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Get whether the strings `a` and `b` are equal, ignoring case and treating
|
|
80
|
+
// `-` as `_`.
|
|
81
|
+
static bool BrokenAPI_matchesFilter(const char* a, const char* b) noexcept {
|
|
82
|
+
for (size_t i = 0; ; i++) {
|
|
83
|
+
int ca = (unsigned char)a[i];
|
|
84
|
+
int cb = (unsigned char)b[i];
|
|
85
|
+
|
|
86
|
+
// If filter is defined as wildcard the rest automatically matches.
|
|
87
|
+
if (cb == '*')
|
|
88
|
+
return true;
|
|
89
|
+
|
|
90
|
+
if (ca == '-') ca = '_';
|
|
91
|
+
if (cb == '-') cb = '_';
|
|
92
|
+
|
|
93
|
+
if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A';
|
|
94
|
+
if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A';
|
|
95
|
+
|
|
96
|
+
if (ca != cb)
|
|
97
|
+
return false;
|
|
98
|
+
|
|
99
|
+
if (ca == '\0')
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static bool BrokenAPI_canRun(BrokenAPI::Unit* unit) noexcept {
|
|
105
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
106
|
+
|
|
107
|
+
int i, argc = global._argc;
|
|
108
|
+
const char** argv = global._argv;
|
|
109
|
+
|
|
110
|
+
const char* unitName = unit->name;
|
|
111
|
+
bool hasFilter = false;
|
|
112
|
+
|
|
113
|
+
for (i = 1; i < argc; i++) {
|
|
114
|
+
const char* arg = argv[i];
|
|
115
|
+
|
|
116
|
+
if (BrokenAPI_startsWith(arg, "--run-") && strcmp(arg, "--run-all") != 0) {
|
|
117
|
+
hasFilter = true;
|
|
118
|
+
|
|
119
|
+
if (BrokenAPI_matchesFilter(unitName, arg + 6))
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// If no filter has been specified the default is to run.
|
|
125
|
+
return !hasFilter;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static void BrokenAPI_runUnit(BrokenAPI::Unit* unit) noexcept {
|
|
129
|
+
BrokenAPI::info("Running %s", unit->name);
|
|
130
|
+
|
|
131
|
+
_brokenGlobal._unitRunning = unit;
|
|
132
|
+
unit->entry();
|
|
133
|
+
_brokenGlobal._unitRunning = NULL;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static void BrokenAPI_runAll() noexcept {
|
|
137
|
+
BrokenAPI::Unit* unit = _brokenGlobal._unitList;
|
|
138
|
+
|
|
139
|
+
bool hasUnits = unit != NULL;
|
|
140
|
+
size_t count = 0;
|
|
141
|
+
int currentPriority = 0;
|
|
142
|
+
|
|
143
|
+
while (unit != NULL) {
|
|
144
|
+
if (BrokenAPI_canRun(unit)) {
|
|
145
|
+
if (currentPriority != unit->priority) {
|
|
146
|
+
if (count)
|
|
147
|
+
INFO("");
|
|
148
|
+
INFO("[[Priority=%d]]", unit->priority);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
currentPriority = unit->priority;
|
|
152
|
+
BrokenAPI_runUnit(unit);
|
|
153
|
+
count++;
|
|
154
|
+
}
|
|
155
|
+
unit = unit->next;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (count) {
|
|
159
|
+
INFO("\nSuccess:");
|
|
160
|
+
INFO(" All tests passed!");
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
INFO("\nWarning:");
|
|
164
|
+
INFO(" No units %s!", hasUnits ? "matched the filter" : "defined");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static void BrokenAPI_listAll() noexcept {
|
|
169
|
+
BrokenAPI::Unit* unit = _brokenGlobal._unitList;
|
|
170
|
+
|
|
171
|
+
if (unit != NULL) {
|
|
172
|
+
INFO("Units:");
|
|
173
|
+
do {
|
|
174
|
+
INFO(" %s [priority=%d]", unit->name, unit->priority);
|
|
175
|
+
unit = unit->next;
|
|
176
|
+
} while (unit != NULL);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
INFO("Warning:");
|
|
180
|
+
INFO(" No units defined!");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
bool BrokenAPI::hasArg(const char* name) noexcept {
|
|
185
|
+
return _brokenGlobal.hasArg(name);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void BrokenAPI::add(Unit* unit) noexcept {
|
|
189
|
+
Unit** pPrev = &_brokenGlobal._unitList;
|
|
190
|
+
Unit* current = *pPrev;
|
|
191
|
+
|
|
192
|
+
// C++ static initialization doesn't guarantee anything. We sort all units by
|
|
193
|
+
// name so the execution will always happen in deterministic order.
|
|
194
|
+
while (current != NULL) {
|
|
195
|
+
if (BrokenAPI_compareUnits(current, unit) >= 0)
|
|
196
|
+
break;
|
|
197
|
+
|
|
198
|
+
pPrev = ¤t->next;
|
|
199
|
+
current = *pPrev;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
*pPrev = unit;
|
|
203
|
+
unit->next = current;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
void BrokenAPI::setOutputFile(FILE* file) noexcept {
|
|
207
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
208
|
+
|
|
209
|
+
global._file = file;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
int BrokenAPI::run(int argc, const char* argv[], Entry onBeforeRun, Entry onAfterRun) {
|
|
213
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
214
|
+
|
|
215
|
+
global._argc = argc;
|
|
216
|
+
global._argv = argv;
|
|
217
|
+
|
|
218
|
+
if (global.hasArg("--help")) {
|
|
219
|
+
INFO("Options:");
|
|
220
|
+
INFO(" --help - print this usage");
|
|
221
|
+
INFO(" --list - list all tests");
|
|
222
|
+
INFO(" --run-... - run a test(s), trailing wildcards supported");
|
|
223
|
+
INFO(" --run-all - run all tests (default)");
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (global.hasArg("--list")) {
|
|
228
|
+
BrokenAPI_listAll();
|
|
229
|
+
return 0;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (onBeforeRun)
|
|
233
|
+
onBeforeRun();
|
|
234
|
+
|
|
235
|
+
// We don't care about filters here, it's implemented by `runAll`.
|
|
236
|
+
BrokenAPI_runAll();
|
|
237
|
+
|
|
238
|
+
if (onAfterRun)
|
|
239
|
+
onAfterRun();
|
|
240
|
+
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static void BrokenAPI_printMessage(const char* prefix, const char* fmt, va_list ap) noexcept {
|
|
245
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
246
|
+
FILE* dst = global.file();
|
|
247
|
+
|
|
248
|
+
if (!fmt || fmt[0] == '\0') {
|
|
249
|
+
fprintf(dst, "\n");
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
// This looks scary, but we really want to use only a single call to vfprintf()
|
|
253
|
+
// in multithreaded code. So we change the format a bit if necessary.
|
|
254
|
+
enum : unsigned { kBufferSize = 512 };
|
|
255
|
+
char staticBuffer[512];
|
|
256
|
+
|
|
257
|
+
size_t fmtSize = strlen(fmt);
|
|
258
|
+
size_t prefixSize = strlen(prefix);
|
|
259
|
+
|
|
260
|
+
char* fmtBuf = staticBuffer;
|
|
261
|
+
if (fmtSize > kBufferSize - 2 - prefixSize)
|
|
262
|
+
fmtBuf = static_cast<char*>(malloc(fmtSize + prefixSize + 2));
|
|
263
|
+
|
|
264
|
+
if (!fmtBuf) {
|
|
265
|
+
fprintf(dst, "%sCannot allocate buffer for vfprintf()\n", prefix);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
memcpy(fmtBuf, prefix, prefixSize);
|
|
269
|
+
memcpy(fmtBuf + prefixSize, fmt, fmtSize);
|
|
270
|
+
|
|
271
|
+
fmtSize += prefixSize;
|
|
272
|
+
if (fmtBuf[fmtSize - 1] != '\n')
|
|
273
|
+
fmtBuf[fmtSize++] = '\n';
|
|
274
|
+
fmtBuf[fmtSize] = '\0';
|
|
275
|
+
|
|
276
|
+
vfprintf(dst, fmtBuf, ap);
|
|
277
|
+
|
|
278
|
+
if (fmtBuf != staticBuffer)
|
|
279
|
+
free(fmtBuf);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
fflush(dst);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
void BrokenAPI::info(const char* fmt, ...) noexcept {
|
|
287
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
288
|
+
|
|
289
|
+
va_list ap;
|
|
290
|
+
va_start(ap, fmt);
|
|
291
|
+
BrokenAPI_printMessage(global._unitRunning ? " " : "", fmt, ap);
|
|
292
|
+
va_end(ap);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
void BrokenAPI::fail(const char* file, int line, const char* expression, const char* fmt, ...) noexcept {
|
|
296
|
+
BrokenGlobal& global = _brokenGlobal;
|
|
297
|
+
FILE* dst = global.file();
|
|
298
|
+
|
|
299
|
+
fprintf(dst, " FAILED: %s\n", expression);
|
|
300
|
+
|
|
301
|
+
if (fmt) {
|
|
302
|
+
va_list ap;
|
|
303
|
+
va_start(ap, fmt);
|
|
304
|
+
BrokenAPI_printMessage(" REASON: ", fmt, ap);
|
|
305
|
+
va_end(ap);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
fprintf(dst, " SOURCE: %s (Line: %d)\n", file, line);
|
|
309
|
+
fflush(dst);
|
|
310
|
+
|
|
311
|
+
exit(1);
|
|
312
|
+
}
|