7a4d1c118f
The various ABIs lay out structs with inline arrays the same way as they do with only nested structs and primitive values. Most notably, homogenous structs (arm and arm64) and structs spread over a CPU and FPU register in x64 Linux/MacOS will even be laid out this way if irregular size nested arrays are involved. These cases are covered in the unit tests. This CL introduces the ByteRange to ease the ContainsOnlyFloats calculation for x64. Bug: https://github.com/dart-lang/sdk/issues/35763 tools/build.py run_ffi_unit_tests && tools/test.py ffi_unit TEST=runtime/vm/compiler/ffi/native_calling_convention_test.cc TEST=runtime/vm/compiler/ffi/native_type_test.cc tools/test.py ffi ffi_2 TEST=tests/ffi(_2)/(.*)by_value_(*.)_test.dart Change-Id: I4bbcbffd47eb8901a87db64e62aa5cbe67d03e18 Cq-Include-Trybots: luci.dart.try:vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-win-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-mac-debug-x64-try,vm-ffi-android-debug-arm64-try,vm-ffi-android-debug-arm-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183682 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Clement Skau <cskau@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
104 lines
3.0 KiB
C++
104 lines
3.0 KiB
C++
// Copyright (c) 2021, 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_RANGE_H_
|
|
#define RUNTIME_VM_COMPILER_FFI_RANGE_H_
|
|
|
|
#include "platform/assert.h"
|
|
#include "platform/utils.h"
|
|
#include "vm/allocation.h"
|
|
|
|
namespace dart {
|
|
|
|
namespace compiler {
|
|
|
|
namespace ffi {
|
|
|
|
// A non-empty range.
|
|
//
|
|
// Ranges are positive and non-empty.
|
|
//
|
|
// The end is exclusive.
|
|
class Range : public ValueObject {
|
|
public:
|
|
// Constructs a Range from start (inclusive) and length.
|
|
//
|
|
// The resulting range is `[start_inclusive, start_inclusive + length)`.
|
|
static Range StartAndLength(intptr_t start_inclusive, intptr_t length) {
|
|
return Range(start_inclusive, start_inclusive + length);
|
|
}
|
|
|
|
// Constructs a Range from start (inclusive) and end (exclusive).
|
|
//
|
|
// The resulting range is `[start_inclusive, end_exclusive)`.
|
|
static Range StartAndEnd(intptr_t start_inclusive, intptr_t end_exclusive) {
|
|
return Range(start_inclusive, end_exclusive);
|
|
}
|
|
|
|
Range(const Range& other)
|
|
: start_(other.start_), end_exclusive_(other.end_exclusive_) {}
|
|
|
|
intptr_t start() const { return start_; }
|
|
intptr_t end_exclusive() const { return end_exclusive_; }
|
|
intptr_t end_inclusive() const { return end_exclusive_ - 1; }
|
|
|
|
intptr_t Length() const { return end_exclusive_ - start_; }
|
|
|
|
// Returs true iff number is in this range.
|
|
bool Contains(intptr_t number) const {
|
|
return start_ <= number && number < end_exclusive_;
|
|
}
|
|
|
|
// Returns true iff [this] contains [other] completely.
|
|
bool Contains(const Range& other) const {
|
|
return Contains(other.start_) && Contains(other.end_inclusive());
|
|
}
|
|
|
|
// Returns true iff [this] is completey after [other].
|
|
bool After(const Range& other) const {
|
|
return other.end_exclusive_ <= start_;
|
|
}
|
|
|
|
// Returns true iff [this] contains some numbers of [other].
|
|
bool Overlaps(const Range& other) const {
|
|
return !this->After(other) && !other.After(*this);
|
|
}
|
|
|
|
// Returns the intersection of [this] with [other].
|
|
//
|
|
// Requires [this] and [other] to overlap.
|
|
const Range Intersect(const Range& other) const {
|
|
ASSERT(Overlaps(other));
|
|
return Range(Utils::Maximum(start_, other.start_),
|
|
Utils::Minimum(end_exclusive_, other.end_exclusive_));
|
|
}
|
|
|
|
// Returns a range moved by [delta].
|
|
//
|
|
// `this.start() - delta` must be positive.
|
|
const Range Translate(intptr_t delta) const {
|
|
return Range(start_ + delta, end_exclusive_ + delta);
|
|
}
|
|
|
|
private:
|
|
Range(intptr_t start_inclusive, intptr_t end_exclusive)
|
|
: start_(start_inclusive), end_exclusive_(end_exclusive) {
|
|
if (!(start_ >= 0 && end_exclusive_ > start_)) {
|
|
ASSERT(start_ >= 0);
|
|
ASSERT(end_exclusive_ > start_);
|
|
}
|
|
}
|
|
|
|
const intptr_t start_;
|
|
const intptr_t end_exclusive_;
|
|
};
|
|
|
|
} // namespace ffi
|
|
|
|
} // namespace compiler
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_COMPILER_FFI_RANGE_H_
|