mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:49:17 +00:00
[test/ffi] Add C++ unit tests for all target ABIs
This CL introduces unit tests for the Native* classes in compiler/ffi that can run for all supported target ABIs on any host architecture. The unit tests are compiled for all target ABIs with `tools/build.py run_ffi_unit_tests` and run for all target ABIs with `tools/test.py ffi_unit`. The unit test and tested code do not conceptually depend on having a DartVM. The tests are compiled with a custom `dart::Zone` and `platform/`. This enables compiling for all `TARGET_ARCH_*` and `TARGET_OS_*` on any host, and running unit tests for all target ABIs on any host. Because the `run_ffi_unit_tests` executables do not include the DartVM their build is quick (<10seconds) and they are small (~6MB) when compared to `run_vm_tests` (~250MB). The tests are added to the existing FFI QEMU bot to prevent adding an extra bot which would add checkout overhead. The unit tests themselves are set up to be fairly similar to vm/cc tests. The only difference is the NativeCallingConvention tests which are set up with `.expect` files for easy inspection and updating. TEST=runtime/vm/compiler/ffi/native_calling_convention_test.cc TEST=runtime/vm/compiler/ffi/native_location_test.cc TEST=runtime/vm/compiler/ffi/native_type_test.cc Change-Id: I7b8bf4de9ef070e7546472217e571a60362b9639 Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171725 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Clement Skau <cskau@google.com> Reviewed-by: Alexander Thomas <athom@google.com>
This commit is contained in:
parent
b11d057572
commit
9f96aeda6f
6
BUILD.gn
6
BUILD.gn
|
@ -68,6 +68,12 @@ group("runtime") {
|
|||
}
|
||||
}
|
||||
|
||||
# A separate target and not included in group("runtime"). This way the target\
|
||||
# "runtime" does not get many executables extra as build output.
|
||||
group("run_ffi_unit_tests") {
|
||||
deps = [ "runtime/bin/ffi_unit_test:run_ffi_unit_tests" ]
|
||||
}
|
||||
|
||||
group("runtime_kernel") {
|
||||
if (targetting_fuchsia) {
|
||||
# Fuchsia has run_vm_tests marked testonly.
|
||||
|
|
|
@ -149,6 +149,12 @@ Future testConfigurations(List<TestConfiguration> configurations) async {
|
|||
// vm tests contain both cc tests (added here) and dart tests (added
|
||||
// in [TEST_SUITE_DIRECTORIES]).
|
||||
testSuites.add(VMTestSuite(configuration));
|
||||
} else if (key == 'ffi_unit') {
|
||||
// 'ffi_unit' contains cc non-DartVM unit tests.
|
||||
//
|
||||
// This is a separate suite from 'ffi', because we want to run the
|
||||
// 'ffi' suite on many architectures, but 'ffi_unit' only on one.
|
||||
testSuites.add(FfiTestSuite(configuration));
|
||||
} else if (configuration.compiler == Compiler.dart2analyzer) {
|
||||
if (key == 'analyze_library') {
|
||||
testSuites.add(AnalyzeLibraryTestSuite(configuration));
|
||||
|
|
|
@ -364,6 +364,128 @@ class VMUnitTest {
|
|||
VMUnitTest(this.name, this.expectation);
|
||||
}
|
||||
|
||||
/// A specialized [TestSuite] that runs tests written in C to unit test
|
||||
/// the standalone (non-DartVM) C/C++ code.
|
||||
///
|
||||
/// The tests are compiled into an executable for all [targetAbis] by the
|
||||
/// build step.
|
||||
/// An executable lists its tests when run with the --list command line flag.
|
||||
/// Individual tests are run by specifying them on the command line.
|
||||
class FfiTestSuite extends TestSuite {
|
||||
Map<String, String> runnerPaths;
|
||||
final String dartDir;
|
||||
|
||||
static const targetAbis = [
|
||||
"arm64_android",
|
||||
"arm64_ios",
|
||||
"arm64_linux",
|
||||
"arm64_macos",
|
||||
"arm_android",
|
||||
"arm_ios",
|
||||
"arm_linux",
|
||||
"ia32_android",
|
||||
"ia32_linux",
|
||||
"ia32_win",
|
||||
"x64_ios",
|
||||
"x64_linux",
|
||||
"x64_macos",
|
||||
"x64_win",
|
||||
];
|
||||
|
||||
FfiTestSuite(TestConfiguration configuration)
|
||||
: dartDir = Repository.dir.toNativePath(),
|
||||
super(configuration, "ffi_unit", []) {
|
||||
final binarySuffix = Platform.operatingSystem == 'windows' ? '.exe' : '';
|
||||
|
||||
// For running the tests we use multiple binaries, one for each target ABI.
|
||||
runnerPaths = Map.fromIterables(
|
||||
targetAbis,
|
||||
targetAbis.map((String config) =>
|
||||
'$buildDir/run_ffi_unit_tests_$config$binarySuffix'));
|
||||
}
|
||||
|
||||
void findTestCases(TestCaseEvent onTest, Map testCache) {
|
||||
final statusFiles =
|
||||
statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
|
||||
final expectations = ExpectationSet.read(statusFiles, configuration);
|
||||
|
||||
runnerPaths.forEach((runnerName, runnerPath) {
|
||||
try {
|
||||
for (final test in _listTests(runnerName, runnerPath)) {
|
||||
_addTest(expectations, test, onTest);
|
||||
}
|
||||
} catch (error, s) {
|
||||
print(
|
||||
"Fatal error occurred while parsing tests from $runnerName: $error");
|
||||
print(s);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _addTest(
|
||||
ExpectationSet testExpectations, FfiUnitTest test, TestCaseEvent onTest) {
|
||||
final fullName = '${test.runnerName}/${test.name}';
|
||||
var expectations = testExpectations.expectations(fullName);
|
||||
|
||||
// Get the expectation from the test itself.
|
||||
final testExpectation = Expectation.find(test.expectation);
|
||||
|
||||
// Update the legacy status-file based expectations to include
|
||||
// [testExpectation].
|
||||
if (testExpectation != Expectation.pass) {
|
||||
expectations = {...expectations, testExpectation};
|
||||
expectations.remove(Expectation.pass);
|
||||
}
|
||||
|
||||
// Update the new workflow based expectations to include [testExpectation].
|
||||
final testFile = TestFile.vmUnitTest(
|
||||
hasSyntaxError: false,
|
||||
hasCompileError: testExpectation == Expectation.compileTimeError,
|
||||
hasRuntimeError: testExpectation == Expectation.runtimeError,
|
||||
hasStaticWarning: false,
|
||||
hasCrash: testExpectation == Expectation.crash);
|
||||
|
||||
final args = [
|
||||
// This test has no VM, but pipe through vmOptions as test options.
|
||||
// Passing `--vm-options=--update` will update all test expectations.
|
||||
...configuration.vmOptions,
|
||||
test.name,
|
||||
];
|
||||
final command = ProcessCommand(
|
||||
'run_ffi_unit_test', test.runnerPath, args, environmentOverrides);
|
||||
|
||||
_addTestCase(testFile, fullName, [command], expectations, onTest);
|
||||
}
|
||||
|
||||
Iterable<FfiUnitTest> _listTests(String runnerName, String runnerPath) {
|
||||
final result = Process.runSync(runnerPath, ["--list"]);
|
||||
if (result.exitCode != 0) {
|
||||
throw "Failed to list tests: '$runnerPath --list'. "
|
||||
"Process exited with ${result.exitCode}";
|
||||
}
|
||||
|
||||
return (result.stdout as String)
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.where((name) => name.isNotEmpty)
|
||||
.map((String line) {
|
||||
final parts = line.split(' ');
|
||||
assert(parts.length == 2);
|
||||
return FfiUnitTest(runnerName, runnerPath, parts[0], parts[1]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class FfiUnitTest {
|
||||
final String runnerName;
|
||||
final String runnerPath;
|
||||
final String name;
|
||||
final String expectation;
|
||||
|
||||
FfiUnitTest(this.runnerName, this.runnerPath, this.name, this.expectation);
|
||||
}
|
||||
|
||||
/// A standard [TestSuite] implementation that searches for tests in a
|
||||
/// directory, and creates [TestCase]s that compile and/or run them.
|
||||
class StandardTestSuite extends TestSuite {
|
||||
|
|
187
runtime/bin/ffi_unit_test/BUILD.gn
Normal file
187
runtime/bin/ffi_unit_test/BUILD.gn
Normal file
|
@ -0,0 +1,187 @@
|
|||
# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import("../../platform/platform_sources.gni")
|
||||
import("../../vm/compiler/compiler_sources.gni")
|
||||
import("../../vm/vm_sources.gni")
|
||||
|
||||
template("build_run_ffi_unit_tests") {
|
||||
extra_configs = []
|
||||
if (defined(invoker.extra_configs)) {
|
||||
extra_configs += invoker.extra_configs
|
||||
}
|
||||
|
||||
executable(target_name) {
|
||||
configs += [] + extra_configs
|
||||
|
||||
defines = [
|
||||
"TESTING",
|
||||
"FFI_UNIT_TESTS",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"../..",
|
||||
"//third_party",
|
||||
]
|
||||
|
||||
constants = rebase_path(constants_sources, ".", "../../vm")
|
||||
ffi_tests = rebase_path(ffi_sources_tests, ".", "../../vm/compiler")
|
||||
platform = rebase_path(platform_sources, ".", "../../platform")
|
||||
|
||||
sources = [ "run_ffi_unit_tests.cc" ] + constants + ffi_tests + platform
|
||||
}
|
||||
}
|
||||
|
||||
config("define_target_arch_arm") {
|
||||
defines = [ "TARGET_ARCH_ARM" ]
|
||||
}
|
||||
|
||||
config("define_target_arch_arm64") {
|
||||
defines = [ "TARGET_ARCH_ARM64" ]
|
||||
}
|
||||
|
||||
config("define_target_arch_ia32") {
|
||||
defines = [ "TARGET_ARCH_IA32" ]
|
||||
}
|
||||
|
||||
config("define_target_arch_x64") {
|
||||
defines = [ "TARGET_ARCH_X64" ]
|
||||
}
|
||||
|
||||
config("define_target_os_android") {
|
||||
defines = [ "TARGET_OS_ANDROID" ]
|
||||
}
|
||||
|
||||
config("define_target_os_ios") {
|
||||
defines = [ "TARGET_OS_IOS" ]
|
||||
}
|
||||
|
||||
config("define_target_os_linux") {
|
||||
defines = [ "TARGET_OS_LINUX" ]
|
||||
}
|
||||
|
||||
config("define_target_os_macos") {
|
||||
defines = [ "TARGET_OS_MACOS" ]
|
||||
}
|
||||
|
||||
config("define_target_os_windows") {
|
||||
defines = [ "TARGET_OS_WINDOWS" ]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm_android") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm",
|
||||
":define_target_os_android",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm_ios") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm",
|
||||
":define_target_os_ios",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm_linux") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm",
|
||||
":define_target_os_linux",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_android") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm64",
|
||||
":define_target_os_android",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_ios") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm64",
|
||||
":define_target_os_ios",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_macos") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm64",
|
||||
":define_target_os_macos",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_arm64_linux") {
|
||||
extra_configs = [
|
||||
":define_target_arch_arm64",
|
||||
":define_target_os_linux",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_android") {
|
||||
extra_configs = [
|
||||
":define_target_arch_ia32",
|
||||
":define_target_os_android",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_linux") {
|
||||
extra_configs = [
|
||||
":define_target_arch_ia32",
|
||||
":define_target_os_linux",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_ia32_win") {
|
||||
extra_configs = [
|
||||
":define_target_arch_ia32",
|
||||
":define_target_os_windows",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_x64_ios") {
|
||||
extra_configs = [
|
||||
":define_target_arch_x64",
|
||||
":define_target_os_ios",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_x64_linux") {
|
||||
extra_configs = [
|
||||
":define_target_arch_x64",
|
||||
":define_target_os_linux",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_x64_macos") {
|
||||
extra_configs = [
|
||||
":define_target_arch_x64",
|
||||
":define_target_os_macos",
|
||||
]
|
||||
}
|
||||
|
||||
build_run_ffi_unit_tests("run_ffi_unit_tests_x64_win") {
|
||||
extra_configs = [
|
||||
":define_target_arch_x64",
|
||||
":define_target_os_windows",
|
||||
]
|
||||
}
|
||||
|
||||
group("run_ffi_unit_tests") {
|
||||
deps = [
|
||||
":run_ffi_unit_tests_arm64_android",
|
||||
":run_ffi_unit_tests_arm64_ios", # No other test coverage.
|
||||
":run_ffi_unit_tests_arm64_linux",
|
||||
":run_ffi_unit_tests_arm64_macos",
|
||||
":run_ffi_unit_tests_arm_android", # SoftFP
|
||||
":run_ffi_unit_tests_arm_ios", # No other test coverage.
|
||||
":run_ffi_unit_tests_arm_linux", # HardFP
|
||||
":run_ffi_unit_tests_ia32_android", # Emulator, no other test coverage.
|
||||
":run_ffi_unit_tests_ia32_linux",
|
||||
":run_ffi_unit_tests_ia32_win",
|
||||
":run_ffi_unit_tests_x64_ios", # Simulator, no other test coverage.
|
||||
":run_ffi_unit_tests_x64_linux",
|
||||
":run_ffi_unit_tests_x64_macos",
|
||||
":run_ffi_unit_tests_x64_win",
|
||||
]
|
||||
}
|
115
runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc
Normal file
115
runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc
Normal file
|
@ -0,0 +1,115 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// A slimmed down version of bin/run_vm_tests.cc that only runs C++ non-DartVM
|
||||
// unit tests.
|
||||
//
|
||||
// By slimming it down to non-VM, we can run with the defines for all target
|
||||
// architectures and operating systems.
|
||||
|
||||
#include "vm/compiler/ffi/unit_test.h"
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/syslog.h"
|
||||
|
||||
namespace dart {
|
||||
namespace compiler {
|
||||
namespace ffi {
|
||||
|
||||
static const char* const kNone = "No Test";
|
||||
static const char* const kList = "List all Tests";
|
||||
static const char* const kAll = "Run all Tests";
|
||||
static const char* run_filter = kNone;
|
||||
|
||||
static const char* kCommandAll = "--all";
|
||||
static const char* kCommandList = "--list";
|
||||
static const char* kCommandUpdate = "--update";
|
||||
|
||||
static int run_matches = 0;
|
||||
|
||||
TestCaseBase* TestCaseBase::first_ = nullptr;
|
||||
TestCaseBase* TestCaseBase::tail_ = nullptr;
|
||||
bool TestCaseBase::update_expectations = false;
|
||||
|
||||
TestCaseBase::TestCaseBase(const char* name, const char* expectation)
|
||||
: next_(nullptr), name_(name), expectation_(expectation) {
|
||||
ASSERT(strlen(expectation) > 0);
|
||||
if (first_ == nullptr) {
|
||||
first_ = this;
|
||||
} else {
|
||||
tail_->next_ = this;
|
||||
}
|
||||
tail_ = this;
|
||||
}
|
||||
|
||||
void TestCaseBase::RunAll() {
|
||||
TestCaseBase* test = first_;
|
||||
while (test != nullptr) {
|
||||
test->RunTest();
|
||||
test = test->next_;
|
||||
}
|
||||
}
|
||||
|
||||
void TestCaseBase::RunTest() {
|
||||
if (run_filter == kList) {
|
||||
Syslog::Print("%s %s\n", this->name(), this->expectation());
|
||||
run_matches++;
|
||||
} else if (run_filter == kAll) {
|
||||
this->Run();
|
||||
run_matches++;
|
||||
} else if (strcmp(run_filter, this->name()) == 0) {
|
||||
this->Run();
|
||||
run_matches++;
|
||||
}
|
||||
}
|
||||
|
||||
void RawTestCase::Run() {
|
||||
Syslog::Print("Running test: %s\n", name());
|
||||
(*run_)();
|
||||
Syslog::Print("Done: %s\n", name());
|
||||
}
|
||||
|
||||
static int Main(int argc, const char** argv) {
|
||||
if (argc == 2 && strcmp(argv[1], kCommandList) == 0) {
|
||||
run_filter = kList;
|
||||
// List all tests and benchmarks and exit.
|
||||
TestCaseBase::RunAll();
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
if (argc > 1 && strcmp(argv[1], kCommandUpdate) == 0) {
|
||||
TestCaseBase::update_expectations = true;
|
||||
}
|
||||
if (strcmp(argv[argc - 1], kCommandAll) == 0) {
|
||||
// Run all tests.
|
||||
run_filter = kAll;
|
||||
} else if (argc > 1) {
|
||||
// Run only test with specific name.
|
||||
run_filter = argv[argc - 1];
|
||||
}
|
||||
|
||||
TestCaseBase::RunAll();
|
||||
|
||||
// Print a warning message if no tests or benchmarks were matched.
|
||||
if (run_matches == 0) {
|
||||
Syslog::PrintErr("No tests matched: %s\n", run_filter);
|
||||
return 1;
|
||||
}
|
||||
if (Expect::failed()) {
|
||||
Syslog::PrintErr(
|
||||
"Some tests failed. Run the following command to update "
|
||||
"expectations.\ntools/test.py --vm-options=--update ffi_unit");
|
||||
return 255;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
return dart::compiler::ffi::Main(argc, argv);
|
||||
}
|
|
@ -339,17 +339,17 @@ typedef simd128_value_t fpu_register_t;
|
|||
// Verify that host and target architectures match, we cannot
|
||||
// have a 64 bit Dart VM generating 32 bit code or vice-versa.
|
||||
#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
|
||||
#if !defined(ARCH_IS_64_BIT)
|
||||
#if !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
|
||||
#error Mismatched Host/Target architectures.
|
||||
#endif // !defined(ARCH_IS_64_BIT)
|
||||
#endif // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
|
||||
#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
|
||||
#if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
|
||||
// This is simarm_x64, which is the only case where host/target architecture
|
||||
// mismatch is allowed.
|
||||
// mismatch is allowed. Unless, we're running FFI unit tests.
|
||||
#define IS_SIMARM_X64 1
|
||||
#elif !defined(ARCH_IS_32_BIT)
|
||||
#elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
|
||||
#error Mismatched Host/Target architectures.
|
||||
#endif // !defined(ARCH_IS_32_BIT)
|
||||
#endif // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
|
||||
#endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
|
||||
|
||||
// Determine whether we will be using the simulator.
|
||||
|
|
|
@ -20,7 +20,9 @@ BIN_LAYER_RE = re.compile(r'^runtime/bin/')
|
|||
|
||||
# Tests that don't match the simple case of *_test.cc.
|
||||
EXTRA_TEST_FILES = [
|
||||
'runtime/bin/run_vm_tests.cc', 'runtime/vm/libfuzzer/dart_libfuzzer.cc'
|
||||
'runtime/bin/run_vm_tests.cc',
|
||||
'runtime/bin/ffi_unit_test/run_ffi_unit_tests.cc',
|
||||
'runtime/vm/libfuzzer/dart_libfuzzer.cc'
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -204,3 +204,10 @@ disassembler_sources = [
|
|||
"assembler/disassembler_arm64.cc",
|
||||
"assembler/disassembler_x86.cc",
|
||||
]
|
||||
|
||||
ffi_sources_tests = [
|
||||
"ffi/native_calling_convention_test.cc",
|
||||
"ffi/native_location_test.cc",
|
||||
"ffi/native_type_test.cc",
|
||||
"ffi/unit_test_custom_zone.cc",
|
||||
]
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
#include "vm/compiler/ffi/native_location.h"
|
||||
#include "vm/compiler/ffi/native_type.h"
|
||||
#include "vm/cpu.h"
|
||||
#include "vm/zone_text_buffer.h"
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
#include "vm/cpu.h"
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
|
||||
namespace compiler {
|
||||
|
@ -17,6 +20,7 @@ namespace ffi {
|
|||
|
||||
const intptr_t kNoFpuRegister = -1;
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
// In Soft FP, floats and doubles get passed in integer registers.
|
||||
static bool SoftFpAbi() {
|
||||
#if defined(TARGET_ARCH_ARM)
|
||||
|
@ -25,6 +29,15 @@ static bool SoftFpAbi() {
|
|||
return false;
|
||||
#endif
|
||||
}
|
||||
#else // !defined(FFI_UNIT_TESTS)
|
||||
static bool SoftFpAbi() {
|
||||
#if defined(TARGET_ARCH_ARM) && defined(TARGET_OS_ANDROID)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif // !defined(FFI_UNIT_TESTS)
|
||||
|
||||
// In Soft FP, floats are treated as 4 byte ints, and doubles as 8 byte ints.
|
||||
static const NativeType& ConvertIfSoftFp(Zone* zone, const NativeType& rep) {
|
||||
|
@ -293,9 +306,11 @@ const char* NativeCallingConvention::ToCString(Zone* zone,
|
|||
return textBuffer.buffer();
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* NativeCallingConvention::ToCString(bool multi_line) const {
|
||||
return ToCString(Thread::Current()->zone(), multi_line);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ffi
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ class NativeCallingConvention : public ZoneAllocated {
|
|||
void PrintTo(BaseTextBuffer* f, bool multi_line = false) const;
|
||||
void PrintToMultiLine(BaseTextBuffer* f) const;
|
||||
const char* ToCString(Zone* zone, bool multi_line = false) const;
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* ToCString(bool multi_line = false) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
NativeCallingConvention(const NativeLocations& argument_locations,
|
||||
|
|
138
runtime/vm/compiler/ffi/native_calling_convention_test.cc
Normal file
138
runtime/vm/compiler/ffi/native_calling_convention_test.cc
Normal file
|
@ -0,0 +1,138 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "vm/compiler/ffi/unit_test.h"
|
||||
|
||||
#include "platform/syslog.h"
|
||||
#include "vm/compiler/ffi/native_calling_convention.h"
|
||||
|
||||
namespace dart {
|
||||
namespace compiler {
|
||||
namespace ffi {
|
||||
|
||||
#if defined(TARGET_ARCH_ARM)
|
||||
const char* kArch = "arm";
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
const char* kArch = "arm64";
|
||||
#elif defined(TARGET_ARCH_IA32)
|
||||
const char* kArch = "ia32";
|
||||
#elif defined(TARGET_ARCH_X64)
|
||||
const char* kArch = "x64";
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_OS_ANDROID)
|
||||
const char* kOs = "android";
|
||||
#elif defined(TARGET_OS_IOS)
|
||||
const char* kOs = "ios";
|
||||
#elif defined(TARGET_OS_LINUX)
|
||||
const char* kOs = "linux";
|
||||
#elif defined(TARGET_OS_MACOS)
|
||||
const char* kOs = "macos";
|
||||
#elif defined(TARGET_OS_WINDOWS)
|
||||
const char* kOs = "win";
|
||||
#endif
|
||||
|
||||
void WriteToFile(char* path, const char* contents) {
|
||||
FILE* file;
|
||||
file = fopen(path, "w");
|
||||
if (file != nullptr) {
|
||||
fprintf(file, "%s", contents);
|
||||
} else {
|
||||
Syslog::Print("Error %d \n", errno);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void ReadFromFile(char* path, char** buffer_pointer) {
|
||||
FILE* file = fopen(path, "rb");
|
||||
if (file == nullptr) {
|
||||
Syslog::Print("Error %d \n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
char* buffer = reinterpret_cast<char*>(malloc(sizeof(char) * (size + 1)));
|
||||
|
||||
fread(buffer, 1, size, file);
|
||||
buffer[size] = 0;
|
||||
|
||||
fclose(file);
|
||||
*buffer_pointer = buffer;
|
||||
}
|
||||
|
||||
void RunSignatureTest(dart::Zone* zone,
|
||||
const char* name,
|
||||
const NativeTypes& argument_types,
|
||||
const NativeType& return_type) {
|
||||
const auto& native_signature =
|
||||
*new (zone) NativeFunctionType(argument_types, return_type);
|
||||
|
||||
const auto& native_calling_convention =
|
||||
NativeCallingConvention::FromSignature(zone, native_signature);
|
||||
|
||||
const char* test_result =
|
||||
native_calling_convention.ToCString(zone, /*multi_line=*/true);
|
||||
|
||||
const int kFilePathLength = 100;
|
||||
char expectation_file_path[kFilePathLength];
|
||||
Utils::SNPrint(expectation_file_path, kFilePathLength,
|
||||
"runtime/vm/compiler/ffi/unit_tests/%s/%s_%s.expect", name,
|
||||
kArch, kOs);
|
||||
|
||||
if (TestCaseBase::update_expectations) {
|
||||
Syslog::Print("Updating %s\n", expectation_file_path);
|
||||
WriteToFile(expectation_file_path, test_result);
|
||||
}
|
||||
|
||||
char* expectation_file_contents = nullptr;
|
||||
ReadFromFile(expectation_file_path, &expectation_file_contents);
|
||||
EXPECT_NOTNULL(expectation_file_contents);
|
||||
if (expectation_file_contents != nullptr) {
|
||||
EXPECT_STREQ(expectation_file_contents, test_result);
|
||||
free(expectation_file_contents);
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_int8x10) {
|
||||
const auto& int8type = *new (Z) NativePrimitiveType(kInt8);
|
||||
|
||||
auto& arguments = *new (Z) NativeTypes(Z, 10);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
arguments.Add(&int8type);
|
||||
|
||||
RunSignatureTest(Z, "int8x10", arguments, int8type);
|
||||
}
|
||||
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeCallingConvention_floatx10) {
|
||||
const auto& floatType = *new (Z) NativePrimitiveType(kFloat);
|
||||
|
||||
auto& arguments = *new (Z) NativeTypes(Z, 10);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
arguments.Add(&floatType);
|
||||
|
||||
RunSignatureTest(Z, "floatx10", arguments, floatType);
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
|
@ -12,6 +12,7 @@ namespace compiler {
|
|||
|
||||
namespace ffi {
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
bool NativeLocation::LocationCanBeExpressed(Location loc, Representation rep) {
|
||||
switch (loc.kind()) {
|
||||
case Location::Kind::kRegister:
|
||||
|
@ -74,6 +75,7 @@ NativeLocation& NativeLocation::FromPairLocation(Zone* zone,
|
|||
const Location loc = pair_loc.AsPairLocation()->At(index);
|
||||
return FromLocation(zone, loc, rep);
|
||||
}
|
||||
#endif
|
||||
|
||||
const NativeRegistersLocation& NativeLocation::AsRegisters() const {
|
||||
ASSERT(IsRegisters());
|
||||
|
@ -90,6 +92,7 @@ const NativeStackLocation& NativeLocation::AsStack() const {
|
|||
return static_cast<const NativeStackLocation&>(*this);
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
Location NativeRegistersLocation::AsLocation() const {
|
||||
ASSERT(IsExpressibleAsLocation());
|
||||
switch (num_regs()) {
|
||||
|
@ -126,6 +129,7 @@ Location NativeStackLocation::AsLocation() const {
|
|||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
NativeRegistersLocation& NativeRegistersLocation::Split(Zone* zone,
|
||||
intptr_t index) const {
|
||||
|
@ -206,10 +210,12 @@ bool NativeStackLocation::Equals(const NativeLocation& other) const {
|
|||
return other_stack.offset_in_bytes_ == offset_in_bytes_;
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
compiler::Address NativeLocationToStackSlotAddress(
|
||||
const NativeStackLocation& loc) {
|
||||
return compiler::Address(loc.base_register(), loc.offset_in_bytes());
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PrintRepresentations(BaseTextBuffer* f, const NativeLocation& loc) {
|
||||
f->AddString(" ");
|
||||
|
@ -271,9 +277,11 @@ const char* NativeLocation::ToCString(Zone* zone) const {
|
|||
return textBuffer.buffer();
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* NativeLocation::ToCString() const {
|
||||
return ToCString(Thread::Current()->zone());
|
||||
}
|
||||
#endif
|
||||
|
||||
intptr_t SizeFromFpuRegisterKind(enum FpuRegisterKind kind) {
|
||||
switch (kind) {
|
||||
|
|
|
@ -10,17 +10,24 @@
|
|||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "vm/compiler/backend/locations.h"
|
||||
#include "vm/compiler/ffi/native_type.h"
|
||||
#include "vm/constants.h"
|
||||
#include "vm/growable_array.h"
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
#include "vm/compiler/backend/locations.h"
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
|
||||
class BaseTextBuffer;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
namespace target {
|
||||
extern const int kWordSize;
|
||||
}
|
||||
|
||||
namespace ffi {
|
||||
|
||||
class NativeRegistersLocation;
|
||||
|
@ -55,6 +62,7 @@ class NativeStackLocation;
|
|||
// inequality cannot be used to determine disjointness.
|
||||
class NativeLocation : public ZoneAllocated {
|
||||
public:
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
static bool LocationCanBeExpressed(Location loc, Representation rep);
|
||||
static NativeLocation& FromLocation(Zone* zone,
|
||||
Location loc,
|
||||
|
@ -63,6 +71,7 @@ class NativeLocation : public ZoneAllocated {
|
|||
Location loc,
|
||||
Representation rep,
|
||||
intptr_t index);
|
||||
#endif
|
||||
|
||||
// The type of the data at this location.
|
||||
const NativeType& payload_type() const { return payload_type_; }
|
||||
|
@ -91,14 +100,18 @@ class NativeLocation : public ZoneAllocated {
|
|||
virtual bool IsStack() const { return false; }
|
||||
|
||||
virtual bool IsExpressibleAsLocation() const { return false; }
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
virtual Location AsLocation() const {
|
||||
ASSERT(IsExpressibleAsLocation());
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void PrintTo(BaseTextBuffer* f) const;
|
||||
const char* ToCString(Zone* zone) const;
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* ToCString() const;
|
||||
#endif
|
||||
|
||||
const NativeRegistersLocation& AsRegisters() const;
|
||||
const NativeFpuRegistersLocation& AsFpuRegisters() const;
|
||||
|
@ -171,7 +184,9 @@ class NativeRegistersLocation : public NativeLocation {
|
|||
virtual bool IsExpressibleAsLocation() const {
|
||||
return num_regs() == 1 || num_regs() == 2;
|
||||
}
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
virtual Location AsLocation() const;
|
||||
#endif
|
||||
intptr_t num_regs() const { return regs_->length(); }
|
||||
Register reg_at(intptr_t index) const { return regs_->At(index); }
|
||||
|
||||
|
@ -238,10 +253,12 @@ class NativeFpuRegistersLocation : public NativeLocation {
|
|||
virtual bool IsExpressibleAsLocation() const {
|
||||
return fpu_reg_kind_ == kQuadFpuReg;
|
||||
}
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
virtual Location AsLocation() const {
|
||||
ASSERT(IsExpressibleAsLocation());
|
||||
return Location::FpuRegisterLocation(fpu_reg());
|
||||
}
|
||||
#endif
|
||||
FpuRegisterKind fpu_reg_kind() const { return fpu_reg_kind_; }
|
||||
FpuRegister fpu_reg() const {
|
||||
ASSERT(fpu_reg_kind_ == kQuadFpuReg);
|
||||
|
@ -299,6 +316,8 @@ class NativeStackLocation : public NativeLocation {
|
|||
size % compiler::target::kWordSize == 0 &&
|
||||
(size_slots == 1 || size_slots == 2);
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
virtual Location AsLocation() const;
|
||||
|
||||
// ConstantInstr expects DoubleStackSlot for doubles, even on 64-bit systems.
|
||||
|
@ -308,6 +327,7 @@ class NativeStackLocation : public NativeLocation {
|
|||
ASSERT(compiler::target::kWordSize == 8);
|
||||
return Location::DoubleStackSlot(offset_in_words(), base_register_);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual NativeStackLocation& Split(Zone* zone, intptr_t index) const;
|
||||
|
||||
|
@ -334,9 +354,11 @@ class NativeStackLocation : public NativeLocation {
|
|||
DISALLOW_COPY_AND_ASSIGN(NativeStackLocation);
|
||||
};
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
// Return a memory operand for stack slot locations.
|
||||
compiler::Address NativeLocationToStackSlotAddress(
|
||||
const NativeStackLocation& loc);
|
||||
#endif
|
||||
|
||||
} // namespace ffi
|
||||
|
||||
|
|
40
runtime/vm/compiler/ffi/native_location_test.cc
Normal file
40
runtime/vm/compiler/ffi/native_location_test.cc
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "vm/compiler/ffi/unit_test.h"
|
||||
|
||||
#include "vm/compiler/ffi/native_location.h"
|
||||
|
||||
namespace dart {
|
||||
namespace compiler {
|
||||
namespace ffi {
|
||||
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeStackLocation) {
|
||||
const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
|
||||
|
||||
const int kUnalignedStackLocation = 17;
|
||||
|
||||
const auto& native_location = *new (Z) NativeStackLocation(
|
||||
native_type, native_type, SPREG, kUnalignedStackLocation);
|
||||
|
||||
EXPECT_EQ(kUnalignedStackLocation + native_type.SizeInBytes(),
|
||||
native_location.StackTopInBytes());
|
||||
}
|
||||
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeStackLocation_Split) {
|
||||
const auto& native_type = *new (Z) NativePrimitiveType(kInt64);
|
||||
|
||||
const auto& native_location =
|
||||
*new (Z) NativeStackLocation(native_type, native_type, SPREG, 0);
|
||||
|
||||
const auto& half_0 = native_location.Split(Z, 0);
|
||||
const auto& half_1 = native_location.Split(Z, 1);
|
||||
|
||||
EXPECT_EQ(0, half_0.offset_in_bytes());
|
||||
EXPECT_EQ(4, half_1.offset_in_bytes());
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
|
@ -10,9 +10,9 @@
|
|||
#include "vm/constants.h"
|
||||
#include "vm/zone_text_buffer.h"
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
#include "vm/compiler/backend/locations.h"
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
namespace dart {
|
||||
|
||||
|
@ -127,7 +127,7 @@ intptr_t NativePrimitiveType::AlignmentInBytesField() const {
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
bool NativePrimitiveType::IsExpressibleAsRepresentation() const {
|
||||
switch (representation_) {
|
||||
case kInt8:
|
||||
|
@ -170,7 +170,7 @@ Representation NativePrimitiveType::AsRepresentation() const {
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
bool NativePrimitiveType::Equals(const NativeType& other) const {
|
||||
if (!other.IsPrimitive()) {
|
||||
|
@ -249,12 +249,14 @@ NativeType& NativeType::FromTypedDataClassId(Zone* zone, classid_t class_id) {
|
|||
return *new (zone) NativePrimitiveType(fundamental_rep);
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
NativeType& NativeType::FromAbstractType(Zone* zone, const AbstractType& type) {
|
||||
// TODO(36730): Support composites.
|
||||
return NativeType::FromTypedDataClassId(zone, type.type_class_id());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
static PrimitiveType fundamental_rep(Representation rep) {
|
||||
switch (rep) {
|
||||
case kUnboxedDouble:
|
||||
|
@ -277,7 +279,7 @@ NativePrimitiveType& NativeType::FromUnboxedRepresentation(Zone* zone,
|
|||
Representation rep) {
|
||||
return *new (zone) NativePrimitiveType(fundamental_rep(rep));
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
const char* NativeType::ToCString(Zone* zone) const {
|
||||
ZoneTextBuffer textBuffer(zone);
|
||||
|
@ -285,9 +287,11 @@ const char* NativeType::ToCString(Zone* zone) const {
|
|||
return textBuffer.buffer();
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* NativeType::ToCString() const {
|
||||
return ToCString(Thread::Current()->zone());
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* PrimitiveTypeToCString(PrimitiveType rep) {
|
||||
switch (rep) {
|
||||
|
@ -334,9 +338,11 @@ const char* NativeFunctionType::ToCString(Zone* zone) const {
|
|||
return textBuffer.buffer();
|
||||
}
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* NativeFunctionType::ToCString() const {
|
||||
return ToCString(Thread::Current()->zone());
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeFunctionType::PrintTo(BaseTextBuffer* f) const {
|
||||
f->AddString("(");
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
#include "platform/globals.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/growable_array.h"
|
||||
#include "vm/object.h"
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
#include "vm/compiler/backend/locations.h"
|
||||
#endif
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
#include "vm/object.h"
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
|
||||
|
@ -51,13 +53,15 @@ class NativePrimitiveType;
|
|||
// TODO(36730): Add composites.
|
||||
class NativeType : public ZoneAllocated {
|
||||
public:
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
static NativeType& FromAbstractType(Zone* zone, const AbstractType& type);
|
||||
#endif
|
||||
static NativeType& FromTypedDataClassId(Zone* zone, classid_t class_id);
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
static NativePrimitiveType& FromUnboxedRepresentation(Zone* zone,
|
||||
Representation rep);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
virtual bool IsPrimitive() const { return false; }
|
||||
const NativePrimitiveType& AsPrimitive() const;
|
||||
|
@ -79,7 +83,7 @@ class NativeType : public ZoneAllocated {
|
|||
// The alignment in bytes of this representation as member of a composite.
|
||||
virtual intptr_t AlignmentInBytesField() const = 0;
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
// NativeTypes which are available as unboxed Representations.
|
||||
virtual bool IsExpressibleAsRepresentation() const { return false; }
|
||||
|
||||
|
@ -91,7 +95,7 @@ class NativeType : public ZoneAllocated {
|
|||
const auto& widened = WidenTo4Bytes(zone_);
|
||||
return widened.AsRepresentation();
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
virtual bool Equals(const NativeType& other) const { UNREACHABLE(); }
|
||||
|
||||
|
@ -104,7 +108,9 @@ class NativeType : public ZoneAllocated {
|
|||
|
||||
virtual void PrintTo(BaseTextBuffer* f) const;
|
||||
const char* ToCString(Zone* zone) const;
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* ToCString() const;
|
||||
#endif
|
||||
|
||||
virtual ~NativeType() {}
|
||||
|
||||
|
@ -152,10 +158,10 @@ class NativePrimitiveType : public NativeType {
|
|||
virtual intptr_t AlignmentInBytesStack() const;
|
||||
virtual intptr_t AlignmentInBytesField() const;
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
virtual bool IsExpressibleAsRepresentation() const;
|
||||
virtual Representation AsRepresentation() const;
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
|
||||
|
||||
virtual bool Equals(const NativeType& other) const;
|
||||
virtual NativePrimitiveType& Split(Zone* zone, intptr_t part) const;
|
||||
|
@ -181,8 +187,9 @@ class NativeFunctionType : public ZoneAllocated {
|
|||
|
||||
void PrintTo(BaseTextBuffer* f) const;
|
||||
const char* ToCString(Zone* zone) const;
|
||||
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
const char* ToCString() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
const NativeTypes& argument_types_;
|
||||
|
|
25
runtime/vm/compiler/ffi/native_type_test.cc
Normal file
25
runtime/vm/compiler/ffi/native_type_test.cc
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "vm/compiler/ffi/unit_test.h"
|
||||
|
||||
#include "vm/compiler/ffi/native_type.h"
|
||||
|
||||
namespace dart {
|
||||
namespace compiler {
|
||||
namespace ffi {
|
||||
|
||||
UNIT_TEST_CASE_WITH_ZONE(NativeType) {
|
||||
const auto& native_type = *new (Z) NativePrimitiveType(kInt8);
|
||||
|
||||
EXPECT_EQ(1, native_type.SizeInBytes());
|
||||
EXPECT(native_type.IsInt());
|
||||
EXPECT(native_type.IsPrimitive());
|
||||
|
||||
EXPECT_STREQ("int8", native_type.ToCString(Z));
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
85
runtime/vm/compiler/ffi/unit_test.h
Normal file
85
runtime/vm/compiler/ffi/unit_test.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// A slimmed down version of runtime/vm/unit_test.h that only runs C++
|
||||
// non-DartVM unit tests.
|
||||
|
||||
#ifndef RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
|
||||
#define RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
|
||||
|
||||
// Don't use the DartVM zone, so include this first.
|
||||
#include "vm/compiler/ffi/unit_test_custom_zone.h"
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
// The UNIT_TEST_CASE macro is used for tests.
|
||||
#define UNIT_TEST_CASE_WITH_EXPECTATION(name, expectation) \
|
||||
void Dart_Test##name(); \
|
||||
static const dart::compiler::ffi::RawTestCase kRegister##name( \
|
||||
Dart_Test##name, #name, expectation); \
|
||||
void Dart_Test##name()
|
||||
|
||||
#define UNIT_TEST_CASE(name) UNIT_TEST_CASE_WITH_EXPECTATION(name, "Pass")
|
||||
|
||||
// The UNIT_TEST_CASE_WITH_ZONE macro is used for tests that need a custom
|
||||
// dart::Zone.
|
||||
#define UNIT_TEST_CASE_WITH_ZONE_WITH_EXPECTATION(name, expectation) \
|
||||
static void Dart_TestHelper##name(dart::Zone* Z); \
|
||||
UNIT_TEST_CASE_WITH_EXPECTATION(name, expectation) { \
|
||||
dart::Zone zone; \
|
||||
Dart_TestHelper##name(&zone); \
|
||||
} \
|
||||
static void Dart_TestHelper##name(dart::Zone* Z)
|
||||
|
||||
#define UNIT_TEST_CASE_WITH_ZONE(name) \
|
||||
UNIT_TEST_CASE_WITH_ZONE_WITH_EXPECTATION(name, "Pass")
|
||||
|
||||
namespace dart {
|
||||
namespace compiler {
|
||||
namespace ffi {
|
||||
|
||||
class TestCaseBase {
|
||||
public:
|
||||
explicit TestCaseBase(const char* name, const char* expectation);
|
||||
virtual ~TestCaseBase() {}
|
||||
|
||||
const char* name() const { return name_; }
|
||||
const char* expectation() const { return expectation_; }
|
||||
|
||||
virtual void Run() = 0;
|
||||
void RunTest();
|
||||
|
||||
static void RunAll();
|
||||
static void RunAllRaw();
|
||||
|
||||
static bool update_expectations;
|
||||
|
||||
private:
|
||||
static TestCaseBase* first_;
|
||||
static TestCaseBase* tail_;
|
||||
|
||||
TestCaseBase* next_;
|
||||
const char* name_;
|
||||
const char* expectation_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TestCaseBase);
|
||||
};
|
||||
|
||||
class RawTestCase : TestCaseBase {
|
||||
public:
|
||||
typedef void(RunEntry)();
|
||||
|
||||
RawTestCase(RunEntry* run, const char* name, const char* expectation)
|
||||
: TestCaseBase(name, expectation), run_(run) {}
|
||||
virtual void Run();
|
||||
|
||||
private:
|
||||
RunEntry* const run_;
|
||||
};
|
||||
|
||||
} // namespace ffi
|
||||
} // namespace compiler
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_VM_COMPILER_FFI_UNIT_TEST_H_
|
45
runtime/vm/compiler/ffi/unit_test_custom_zone.cc
Normal file
45
runtime/vm/compiler/ffi/unit_test_custom_zone.cc
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "vm/compiler/ffi/unit_test_custom_zone.h"
|
||||
|
||||
#include "vm/compiler/runtime_api.h"
|
||||
|
||||
// Directly compile cc files into the custom zone, so that we do not get linker
|
||||
// errors from object files compiled against the DartVM Zone.
|
||||
#include "vm/compiler/ffi/native_calling_convention.cc" // NOLINT
|
||||
#include "vm/compiler/ffi/native_location.cc" // NOLINT
|
||||
#include "vm/compiler/ffi/native_type.cc" // NOLINT
|
||||
#include "vm/zone_text_buffer.cc" // NOLINT
|
||||
|
||||
namespace dart {
|
||||
|
||||
void* ZoneAllocated::operator new(uintptr_t size, dart::Zone* zone) {
|
||||
return reinterpret_cast<void*>(zone->AllocUnsafe(size));
|
||||
}
|
||||
|
||||
Zone::~Zone() {
|
||||
while (buffers_.size() > 0) {
|
||||
free(buffers_.back());
|
||||
buffers_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void* Zone::AllocUnsafe(intptr_t size) {
|
||||
void* memory = malloc(size);
|
||||
buffers_.push_back(memory);
|
||||
return memory;
|
||||
}
|
||||
|
||||
DART_EXPORT void Dart_PrepareToAbort() {
|
||||
fprintf(stderr, "Dart_PrepareToAbort() not implemented!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
|
||||
fprintf(stderr, "Dart_DumpNativeStackTrace() not implemented!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} // namespace dart
|
51
runtime/vm/compiler/ffi/unit_test_custom_zone.h
Normal file
51
runtime/vm/compiler/ffi/unit_test_custom_zone.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
|
||||
#define RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
// We use a custom zone here which doesn't depend on VM internals (e.g. handles,
|
||||
// thread, ...)
|
||||
#if defined(RUNTIME_VM_ZONE_H_)
|
||||
#error "We want our own zone implementation"
|
||||
#endif
|
||||
#define RUNTIME_VM_ZONE_H_
|
||||
|
||||
namespace dart {
|
||||
|
||||
class Zone {
|
||||
public:
|
||||
Zone() {}
|
||||
~Zone();
|
||||
|
||||
template <class ElementType>
|
||||
inline ElementType* Alloc(intptr_t length) {
|
||||
return static_cast<ElementType*>(AllocUnsafe(sizeof(ElementType) * length));
|
||||
}
|
||||
|
||||
template <class ElementType>
|
||||
inline ElementType* Realloc(ElementType* old_array,
|
||||
intptr_t old_length,
|
||||
intptr_t new_length) {
|
||||
void* memory = AllocUnsafe(sizeof(ElementType) * new_length);
|
||||
memmove(memory, old_array, sizeof(ElementType) * old_length);
|
||||
return static_cast<ElementType*>(memory);
|
||||
}
|
||||
|
||||
template <class ElementType>
|
||||
void Free(ElementType* old_array, intptr_t len) {}
|
||||
|
||||
void* AllocUnsafe(intptr_t size);
|
||||
|
||||
private:
|
||||
Zone(const Zone&) = delete;
|
||||
void operator=(const Zone&) = delete;
|
||||
std::vector<void*> buffers_;
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_VM_COMPILER_FFI_UNIT_TEST_CUSTOM_ZONE_H_
|
|
@ -0,0 +1,12 @@
|
|||
v0 float
|
||||
v1 float
|
||||
v2 float
|
||||
v3 float
|
||||
v4 float
|
||||
v5 float
|
||||
v6 float
|
||||
v7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
v0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm64_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
v0 float
|
||||
v1 float
|
||||
v2 float
|
||||
v3 float
|
||||
v4 float
|
||||
v5 float
|
||||
v6 float
|
||||
v7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
v0 float
|
|
@ -0,0 +1,12 @@
|
|||
v0 float
|
||||
v1 float
|
||||
v2 float
|
||||
v3 float
|
||||
v4 float
|
||||
v5 float
|
||||
v6 float
|
||||
v7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
v0 float
|
|
@ -0,0 +1,12 @@
|
|||
v0 float
|
||||
v1 float
|
||||
v2 float
|
||||
v3 float
|
||||
v4 float
|
||||
v5 float
|
||||
v6 float
|
||||
v7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
v0 float
|
|
@ -0,0 +1,12 @@
|
|||
r0 int32[float]
|
||||
r1 int32[float]
|
||||
r2 int32[float]
|
||||
r3 int32[float]
|
||||
S+0 float
|
||||
S+4 float
|
||||
S+8 float
|
||||
S+12 float
|
||||
S+16 float
|
||||
S+20 float
|
||||
=>
|
||||
r0 int32[float]
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
s0 float
|
||||
s1 float
|
||||
s2 float
|
||||
s3 float
|
||||
s4 float
|
||||
s5 float
|
||||
s6 float
|
||||
s7 float
|
||||
s8 float
|
||||
s9 float
|
||||
=>
|
||||
q0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm_linux.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/arm_linux.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
s0 float
|
||||
s1 float
|
||||
s2 float
|
||||
s3 float
|
||||
s4 float
|
||||
s5 float
|
||||
s6 float
|
||||
s7 float
|
||||
s8 float
|
||||
s9 float
|
||||
=>
|
||||
q0 float
|
|
@ -0,0 +1,12 @@
|
|||
S+0 float
|
||||
S+4 float
|
||||
S+8 float
|
||||
S+12 float
|
||||
S+16 float
|
||||
S+20 float
|
||||
S+24 float
|
||||
S+28 float
|
||||
S+32 float
|
||||
S+36 float
|
||||
=>
|
||||
xmm0 float
|
|
@ -0,0 +1,12 @@
|
|||
S+0 float
|
||||
S+4 float
|
||||
S+8 float
|
||||
S+12 float
|
||||
S+16 float
|
||||
S+20 float
|
||||
S+24 float
|
||||
S+28 float
|
||||
S+32 float
|
||||
S+36 float
|
||||
=>
|
||||
xmm0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_win.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/ia32_win.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
S+0 float
|
||||
S+4 float
|
||||
S+8 float
|
||||
S+12 float
|
||||
S+16 float
|
||||
S+20 float
|
||||
S+24 float
|
||||
S+28 float
|
||||
S+32 float
|
||||
S+36 float
|
||||
=>
|
||||
xmm0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
xmm0 float
|
||||
xmm1 float
|
||||
xmm2 float
|
||||
xmm3 float
|
||||
xmm4 float
|
||||
xmm5 float
|
||||
xmm6 float
|
||||
xmm7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
xmm0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_linux.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_linux.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
xmm0 float
|
||||
xmm1 float
|
||||
xmm2 float
|
||||
xmm3 float
|
||||
xmm4 float
|
||||
xmm5 float
|
||||
xmm6 float
|
||||
xmm7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
xmm0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_macos.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_macos.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
xmm0 float
|
||||
xmm1 float
|
||||
xmm2 float
|
||||
xmm3 float
|
||||
xmm4 float
|
||||
xmm5 float
|
||||
xmm6 float
|
||||
xmm7 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
=>
|
||||
xmm0 float
|
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_win.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/floatx10/x64_win.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
xmm0 float
|
||||
xmm1 float
|
||||
xmm2 float
|
||||
xmm3 float
|
||||
S+0 float
|
||||
S+8 float
|
||||
S+16 float
|
||||
S+24 float
|
||||
S+32 float
|
||||
S+40 float
|
||||
=>
|
||||
xmm0 float
|
|
@ -0,0 +1,12 @@
|
|||
r0 int8
|
||||
r1 int8
|
||||
r2 int8
|
||||
r3 int8
|
||||
r4 int8
|
||||
r5 int8
|
||||
r6 int8
|
||||
r7 int8
|
||||
S+0 int8
|
||||
S+8 int8
|
||||
=>
|
||||
r0 int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm64_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
r0 int8
|
||||
r1 int8
|
||||
r2 int8
|
||||
r3 int8
|
||||
r4 int8
|
||||
r5 int8
|
||||
r6 int8
|
||||
r7 int8
|
||||
S+0 int8
|
||||
S+8 int8
|
||||
=>
|
||||
r0 int8
|
|
@ -0,0 +1,12 @@
|
|||
r0 int8
|
||||
r1 int8
|
||||
r2 int8
|
||||
r3 int8
|
||||
r4 int8
|
||||
r5 int8
|
||||
r6 int8
|
||||
r7 int8
|
||||
S+0 int8
|
||||
S+8 int8
|
||||
=>
|
||||
r0 int8
|
|
@ -0,0 +1,12 @@
|
|||
r0 int8
|
||||
r1 int8
|
||||
r2 int8
|
||||
r3 int8
|
||||
r4 int8
|
||||
r5 int8
|
||||
r6 int8
|
||||
r7 int8
|
||||
S+0 int8
|
||||
S+8 int8
|
||||
=>
|
||||
r0 int8
|
|
@ -0,0 +1,12 @@
|
|||
r0 int32[int8]
|
||||
r1 int32[int8]
|
||||
r2 int32[int8]
|
||||
r3 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
=>
|
||||
r0 int32[int8]
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
r0 int32[int8]
|
||||
r1 int32[int8]
|
||||
r2 int32[int8]
|
||||
r3 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
=>
|
||||
r0 int32[int8]
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm_linux.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/arm_linux.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
r0 int32[int8]
|
||||
r1 int32[int8]
|
||||
r2 int32[int8]
|
||||
r3 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
=>
|
||||
r0 int32[int8]
|
|
@ -0,0 +1,12 @@
|
|||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
S+24 int32[int8]
|
||||
S+28 int32[int8]
|
||||
S+32 int32[int8]
|
||||
S+36 int32[int8]
|
||||
=>
|
||||
eax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_linux.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_linux.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
S+24 int32[int8]
|
||||
S+28 int32[int8]
|
||||
S+32 int32[int8]
|
||||
S+36 int32[int8]
|
||||
=>
|
||||
eax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_win.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/ia32_win.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
S+0 int32[int8]
|
||||
S+4 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+12 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+20 int32[int8]
|
||||
S+24 int32[int8]
|
||||
S+28 int32[int8]
|
||||
S+32 int32[int8]
|
||||
S+36 int32[int8]
|
||||
=>
|
||||
eax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_ios.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_ios.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
rdi int32[int8]
|
||||
rsi int32[int8]
|
||||
rdx int32[int8]
|
||||
rcx int32[int8]
|
||||
r8 int32[int8]
|
||||
r9 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+24 int32[int8]
|
||||
=>
|
||||
rax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_linux.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_linux.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
rdi int32[int8]
|
||||
rsi int32[int8]
|
||||
rdx int32[int8]
|
||||
rcx int32[int8]
|
||||
r8 int32[int8]
|
||||
r9 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+24 int32[int8]
|
||||
=>
|
||||
rax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_macos.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_macos.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
rdi int32[int8]
|
||||
rsi int32[int8]
|
||||
rdx int32[int8]
|
||||
rcx int32[int8]
|
||||
r8 int32[int8]
|
||||
r9 int32[int8]
|
||||
S+0 int32[int8]
|
||||
S+8 int32[int8]
|
||||
S+16 int32[int8]
|
||||
S+24 int32[int8]
|
||||
=>
|
||||
rax int8
|
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_win.expect
Normal file
12
runtime/vm/compiler/ffi/unit_tests/int8x10/x64_win.expect
Normal file
|
@ -0,0 +1,12 @@
|
|||
rcx int8
|
||||
rdx int8
|
||||
r8 int8
|
||||
r9 int8
|
||||
S+0 int8
|
||||
S+8 int8
|
||||
S+16 int8
|
||||
S+24 int8
|
||||
S+32 int8
|
||||
S+40 int8
|
||||
=>
|
||||
rax int8
|
|
@ -288,8 +288,10 @@ static constexpr int kWordSizeLog2 = 3;
|
|||
static constexpr int kWordSize = 1 << kWordSizeLog2;
|
||||
static_assert(kWordSize == sizeof(word), "kWordSize should match sizeof(word)");
|
||||
// Our compiler code currently assumes this, so formally check it.
|
||||
#if !defined(FFI_UNIT_TESTS)
|
||||
static_assert(dart::kWordSize >= kWordSize,
|
||||
"Host word size smaller than target word size");
|
||||
#endif
|
||||
|
||||
static constexpr word kBitsPerWordLog2 = kWordSizeLog2 + kBitsPerByteLog2;
|
||||
static constexpr word kBitsPerWord = 1 << kBitsPerWordLog2;
|
||||
|
|
|
@ -1400,7 +1400,7 @@ class Instr {
|
|||
DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
|
||||
};
|
||||
|
||||
const uword kBreakInstructionFiller = 0xD4200000D4200000L; // brk #0; brk #0
|
||||
const uint64_t kBreakInstructionFiller = 0xD4200000D4200000L; // brk #0; brk #0
|
||||
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -473,7 +473,7 @@ class Instr {
|
|||
// becomes important to us.
|
||||
const int MAX_NOP_SIZE = 8;
|
||||
|
||||
const uword kBreakInstructionFiller = 0xCCCCCCCCCCCCCCCCL;
|
||||
const uint64_t kBreakInstructionFiller = 0xCCCCCCCCCCCCCCCCL;
|
||||
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -451,3 +451,15 @@ vm_sources_tests = [
|
|||
"virtual_memory_test.cc",
|
||||
"zone_test.cc",
|
||||
]
|
||||
|
||||
constants_sources = [
|
||||
"constants_arm.cc",
|
||||
"constants_arm.h",
|
||||
"constants_arm64.cc",
|
||||
"constants_arm64.h",
|
||||
"constants_base.h",
|
||||
"constants_ia32.cc",
|
||||
"constants_ia32.h",
|
||||
"constants_x64.cc",
|
||||
"constants_x64.h",
|
||||
]
|
||||
|
|
|
@ -418,6 +418,9 @@
|
|||
"flutter-frontend": {
|
||||
"__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
|
||||
},
|
||||
"vm-ffi-unit-test": {
|
||||
"__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
|
||||
},
|
||||
"unittest-asserts-no-sdk-(linux|mac|win)": {
|
||||
"options": {
|
||||
"compiler": "dartk",
|
||||
|
@ -1102,9 +1105,25 @@
|
|||
"vm-precomp-ffi-qemu-linux-release-arm"
|
||||
],
|
||||
"meta": {
|
||||
"description": "This configuration is used for running FFI tests on qemu."
|
||||
"description": "This configuration is used for running FFI tests on qemu and FFI unit tests."
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"name": "build run_ffi_unit_tests",
|
||||
"script": "tools/build.py",
|
||||
"arguments": [
|
||||
"--arch=x64",
|
||||
"--mode=debug",
|
||||
"run_ffi_unit_tests"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ffi unit tests",
|
||||
"arguments": [
|
||||
"-nvm-ffi-unit-test",
|
||||
"ffi_unit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "build dart",
|
||||
"script": "tools/build.py",
|
||||
|
|
Loading…
Reference in a new issue