mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:27:43 +00:00
Revert "[vm/ffi] Enable creating an ExternalTypedData from a Pointer."
This reverts commit ddd83d256f
.
Reason for revert: Causing build failures in the Flutter engine, blocking the SDK roll. Build error:
org-dartlang-sdk:///third_party/dart/runtime/lib/ffi_patch.dart:76:3: Error: Type 'TypedData' not found.
TypedData asExternalTypedData({int count: 1}) =>
^^^^^^^^^
Original change's description:
> [vm/ffi] Enable creating an ExternalTypedData from a Pointer.
>
> Fixes dartbug.com/37738
>
> Change-Id: I65c6741978d36cd1c255039a4dd8a06190ea4366
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/111736
> Commit-Queue: Samir Jindel <sjindel@google.com>
> Reviewed-by: Daco Harkes <dacoharkes@google.com>
TBR=vegorov@google.com,sjindel@google.com,dacoharkes@google.com
Change-Id: I90a9cb5e2894c0bc064e620cef0a0f51505ac05d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112047
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
193985777d
commit
c262cbd414
|
@ -608,75 +608,6 @@ DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 2) {
|
|||
#endif
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Ffi_asExternalTypedData, 0, 2) {
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Integer, count, arguments->NativeArgAt(1));
|
||||
const AbstractType& pointer_type_arg =
|
||||
AbstractType::Handle(pointer.type_argument());
|
||||
const classid_t type_cid = pointer_type_arg.type_class_id();
|
||||
classid_t cid = 0;
|
||||
|
||||
switch (type_cid) {
|
||||
case kFfiInt8Cid:
|
||||
cid = kExternalTypedDataInt8ArrayCid;
|
||||
break;
|
||||
case kFfiUint8Cid:
|
||||
cid = kExternalTypedDataUint8ArrayCid;
|
||||
break;
|
||||
case kFfiInt16Cid:
|
||||
cid = kExternalTypedDataInt16ArrayCid;
|
||||
break;
|
||||
case kFfiUint16Cid:
|
||||
cid = kExternalTypedDataUint16ArrayCid;
|
||||
break;
|
||||
case kFfiInt32Cid:
|
||||
cid = kExternalTypedDataInt32ArrayCid;
|
||||
break;
|
||||
case kFfiUint32Cid:
|
||||
cid = kExternalTypedDataUint32ArrayCid;
|
||||
break;
|
||||
case kFfiInt64Cid:
|
||||
cid = kExternalTypedDataInt64ArrayCid;
|
||||
break;
|
||||
case kFfiUint64Cid:
|
||||
cid = kExternalTypedDataUint64ArrayCid;
|
||||
break;
|
||||
case kFfiIntPtrCid:
|
||||
cid = kWordSize == 4 ? kExternalTypedDataInt32ArrayCid
|
||||
: kExternalTypedDataInt64ArrayCid;
|
||||
break;
|
||||
case kFfiFloatCid:
|
||||
cid = kExternalTypedDataFloat32ArrayCid;
|
||||
break;
|
||||
case kFfiDoubleCid:
|
||||
cid = kExternalTypedDataFloat64ArrayCid;
|
||||
break;
|
||||
default: {
|
||||
const String& error = String::Handle(
|
||||
String::NewFormatted("Cannot create a TypedData from a Pointer to %s",
|
||||
pointer_type_arg.ToCString()));
|
||||
Exceptions::ThrowArgumentError(error);
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
const intptr_t element_count = count.AsInt64Value();
|
||||
|
||||
if (element_count < 0 ||
|
||||
element_count > ExternalTypedData::MaxElements(cid)) {
|
||||
const String& error = String::Handle(
|
||||
String::NewFormatted("Count must be in the range [0, %" Pd "].",
|
||||
ExternalTypedData::MaxElements(cid)));
|
||||
Exceptions::ThrowArgumentError(error);
|
||||
}
|
||||
|
||||
const intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid);
|
||||
const size_t byte_length = count.AsInt64Value() * element_size;
|
||||
return ExternalTypedData::New(
|
||||
cid, reinterpret_cast<uint8_t*>(pointer.NativeAddress()),
|
||||
count.AsInt64Value(), thread->heap()->SpaceForExternal(byte_length));
|
||||
}
|
||||
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
|
||||
void FfiMarshalledArguments::SetFunctionAddress(uint64_t value) const {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:_internal" show patch;
|
||||
import 'dart:typed_data' show TypedData;
|
||||
|
||||
@patch
|
||||
int sizeOf<T extends NativeType>() native "Ffi_sizeOf";
|
||||
|
@ -18,9 +17,6 @@ Pointer<T> _fromAddress<T extends NativeType>(int ptr) native "Ffi_fromAddress";
|
|||
DS _asFunctionInternal<DS extends Function, NS extends Function>(
|
||||
Pointer<NativeFunction<NS>> ptr) native "Ffi_asFunctionInternal";
|
||||
|
||||
dynamic _asExternalTypedData(Pointer ptr, int count)
|
||||
native "Ffi_asExternalTypedData";
|
||||
|
||||
@patch
|
||||
@pragma("vm:entry-point")
|
||||
class Pointer<T extends NativeType> {
|
||||
|
@ -71,8 +67,4 @@ class Pointer<T extends NativeType> {
|
|||
|
||||
@patch
|
||||
void free() native "Ffi_free";
|
||||
|
||||
@patch
|
||||
TypedData asExternalTypedData({int count: 1}) =>
|
||||
_asExternalTypedData(this, count);
|
||||
}
|
||||
|
|
|
@ -388,7 +388,6 @@ namespace dart {
|
|||
V(Ffi_dl_open, 1) \
|
||||
V(Ffi_dl_lookup, 2) \
|
||||
V(Ffi_dl_getHandle, 1) \
|
||||
V(Ffi_asExternalTypedData, 2) \
|
||||
V(TransferableTypedData_factory, 2) \
|
||||
V(TransferableTypedData_materialize, 1)
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
/// {@nodoc}
|
||||
library dart.ffi;
|
||||
|
||||
import 'dart:typed_data' show TypedData;
|
||||
|
||||
part "native_type.dart";
|
||||
part "annotations.dart";
|
||||
part "dynamic_library.dart";
|
||||
|
@ -93,29 +91,6 @@ class Pointer<T extends NativeType> extends NativeType {
|
|||
/// Note that this zeros out the address.
|
||||
external void free();
|
||||
|
||||
/// Creates an *external* typed data array backed by this pointer.
|
||||
///
|
||||
/// The typed data array returned is only valid for as long as the backing
|
||||
/// [Pointer]. Accessing any element of the type data array after this
|
||||
/// [Pointer] has been [Pointer.free()]d will cause undefined behavior.
|
||||
///
|
||||
/// Since [Pointer]s do not know their length, the size of the typed data is
|
||||
/// controlled by `count`, in units of the size of the native type for this
|
||||
/// [Pointer] (similarly to [Pointer.allocate]).
|
||||
///
|
||||
/// The kind of TypedData produced depends on the native type:
|
||||
///
|
||||
/// Pointer<Int8> -> Int8List
|
||||
/// Pointer<Uint8> -> Uint8List
|
||||
/// etc. up to Int64/Uint64
|
||||
/// Pointer<IntPtr> -> Int32List/Int64List depending on platform word size
|
||||
/// Pointer<Float> -> Float32List
|
||||
/// Pointer<Double> -> Float64List
|
||||
///
|
||||
/// Creation of a [Uint8ClampedList] is not supported. Creation of a typed
|
||||
/// data from a [Pointer] to any other native type is not supported.
|
||||
external TypedData asExternalTypedData({int count: 1});
|
||||
|
||||
/// Equality for Pointers only depends on their address.
|
||||
bool operator ==(other) {
|
||||
if (other == null) return false;
|
||||
|
|
|
@ -65,9 +65,9 @@
|
|||
},
|
||||
"ffi": {
|
||||
"patches": [
|
||||
"../../runtime/lib/ffi_patch.dart",
|
||||
"../../runtime/lib/ffi_dynamic_library_patch.dart",
|
||||
"../../runtime/lib/ffi_native_type_patch.dart"
|
||||
"../../runtime/lib/ffi_native_type_patch.dart",
|
||||
"../../runtime/lib/ffi_patch.dart"
|
||||
],
|
||||
"uri": "ffi/ffi.dart"
|
||||
},
|
||||
|
|
|
@ -90,9 +90,9 @@ vm:
|
|||
ffi:
|
||||
uri: "ffi/ffi.dart"
|
||||
patches:
|
||||
- "../../runtime/lib/ffi_patch.dart"
|
||||
- "../../runtime/lib/ffi_dynamic_library_patch.dart"
|
||||
- "../../runtime/lib/ffi_native_type_patch.dart"
|
||||
- "../../runtime/lib/ffi_patch.dart"
|
||||
|
||||
_http:
|
||||
uri: "_http/http.dart"
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
// Copyright (c) 2019, 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 'dart:ffi';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
main() {
|
||||
testInt8Load();
|
||||
testInt8Store();
|
||||
testUint8Load();
|
||||
testUint8Store();
|
||||
testInt16Load();
|
||||
testInt16Store();
|
||||
testUint16Load();
|
||||
testUint16Store();
|
||||
testInt32Load();
|
||||
testInt32Store();
|
||||
testUint32Load();
|
||||
testUint32Store();
|
||||
testInt64Load();
|
||||
testInt64Store();
|
||||
testUint64Load();
|
||||
testUint64Store();
|
||||
testIntPtr();
|
||||
testFloatLoad();
|
||||
testFloatStore();
|
||||
testDoubleLoad();
|
||||
testDoubleStore();
|
||||
testArrayLoad();
|
||||
testArrayStore();
|
||||
testNegativeArray();
|
||||
}
|
||||
|
||||
// For signed int tests, we store 0xf* and load -1 to check sign-extension.
|
||||
// For unsigned int tests, we store 0xf* and load the same to check truncation.
|
||||
|
||||
void testInt8Load() {
|
||||
// Load
|
||||
Pointer<Int8> ptr = Pointer.allocate();
|
||||
ptr.store(0xff);
|
||||
Int8List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], -1);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt8Store() {
|
||||
// Store
|
||||
Pointer<Int8> ptr = Pointer.allocate();
|
||||
Int8List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), -1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint8Load() {
|
||||
// Load
|
||||
Pointer<Uint8> ptr = Pointer.allocate();
|
||||
ptr.store(0xff);
|
||||
Uint8List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], 0xff);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint8Store() {
|
||||
// Store
|
||||
Pointer<Uint8> ptr = Pointer.allocate();
|
||||
Uint8List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), 0xff);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt16Load() {
|
||||
// Load
|
||||
Pointer<Int16> ptr = Pointer.allocate();
|
||||
ptr.store(0xffff);
|
||||
Int16List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], -1);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt16Store() {
|
||||
// Store
|
||||
Pointer<Int16> ptr = Pointer.allocate();
|
||||
Int16List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), -1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint16Load() {
|
||||
// Load
|
||||
Pointer<Uint16> ptr = Pointer.allocate();
|
||||
ptr.store(0xffff);
|
||||
Uint16List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], 0xffff);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint16Store() {
|
||||
// Store
|
||||
Pointer<Uint16> ptr = Pointer.allocate();
|
||||
Uint16List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), 0xffff);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt32Load() {
|
||||
// Load
|
||||
Pointer<Int32> ptr = Pointer.allocate();
|
||||
ptr.store(0xffffffff);
|
||||
Int32List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], -1);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt32Store() {
|
||||
// Store
|
||||
Pointer<Int32> ptr = Pointer.allocate();
|
||||
Int32List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffffffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), -1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint32Load() {
|
||||
// Load
|
||||
Pointer<Uint32> ptr = Pointer.allocate();
|
||||
ptr.store(0xffffffff);
|
||||
Uint32List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], 0xffffffff);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint32Store() {
|
||||
// Store
|
||||
Pointer<Uint32> ptr = Pointer.allocate();
|
||||
Uint32List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffffffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), 0xffffffff);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt64Load() {
|
||||
// Load
|
||||
Pointer<Int64> ptr = Pointer.allocate();
|
||||
ptr.store(0xffffffffffffffff);
|
||||
Int64List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], -1);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testInt64Store() {
|
||||
// Store
|
||||
Pointer<Int64> ptr = Pointer.allocate();
|
||||
Int64List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffffffffffffffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), -1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint64Load() {
|
||||
// Load
|
||||
Pointer<Uint64> ptr = Pointer.allocate();
|
||||
ptr.store(0xffffffffffffffff);
|
||||
Uint64List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], 0xffffffffffffffff);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testUint64Store() {
|
||||
// Store
|
||||
Pointer<Uint64> ptr = Pointer.allocate();
|
||||
Uint64List list = ptr.asExternalTypedData();
|
||||
list[0] = 0xffffffffffffffff;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<int>(), 0xffffffffffffffff);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testIntPtr() {
|
||||
bool is32Bit = sizeOf<IntPtr>() == 4;
|
||||
Pointer<IntPtr> ptr = Pointer.allocate();
|
||||
final array = ptr.asExternalTypedData();
|
||||
if (is32Bit) {
|
||||
Expect.type<Int32List>(array);
|
||||
} else {
|
||||
Expect.type<Int64List>(array);
|
||||
}
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
double maxFloat = (2 - pow(2, -23)) * pow(2, 127);
|
||||
double maxDouble = (2 - pow(2, -52)) * pow(2, pow(2, 10) - 1);
|
||||
|
||||
void testFloatLoad() {
|
||||
// Load
|
||||
Pointer<Float> ptr = Pointer.allocate();
|
||||
ptr.store(maxFloat);
|
||||
Float32List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], maxFloat);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testFloatStore() {
|
||||
// Store
|
||||
Pointer<Float> ptr = Pointer.allocate();
|
||||
Float32List list = ptr.asExternalTypedData();
|
||||
list[0] = maxFloat;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<double>(), maxFloat);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testDoubleLoad() {
|
||||
// Load
|
||||
Pointer<Double> ptr = Pointer.allocate();
|
||||
ptr.store(maxDouble);
|
||||
Float64List list = ptr.asExternalTypedData();
|
||||
Expect.equals(list[0], maxDouble);
|
||||
Expect.equals(list.length, 1);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testDoubleStore() {
|
||||
// Store
|
||||
Pointer<Double> ptr = Pointer.allocate();
|
||||
Float64List list = ptr.asExternalTypedData();
|
||||
list[0] = maxDouble;
|
||||
Expect.equals(list.length, 1);
|
||||
Expect.equals(ptr.load<double>(), maxDouble);
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testArrayLoad() {
|
||||
const int count = 0x100;
|
||||
Pointer<Int32> ptr = Pointer.allocate(count: count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ptr.elementAt(i).store(i);
|
||||
}
|
||||
Int32List array = ptr.asExternalTypedData(count: count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Expect.equals(array[i], i);
|
||||
}
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testArrayStore() {
|
||||
const int count = 0x100;
|
||||
Pointer<Int32> ptr = Pointer.allocate(count: count);
|
||||
Int32List array = ptr.asExternalTypedData(count: count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
array[i] = i;
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Expect.equals(ptr.elementAt(i).load<int>(), i);
|
||||
}
|
||||
ptr.free();
|
||||
}
|
||||
|
||||
void testNegativeArray() {
|
||||
Pointer<Int32> ptr = nullptr.cast();
|
||||
Expect.throws<ArgumentError>(() => ptr.asExternalTypedData(count: -1));
|
||||
}
|
|
@ -25,7 +25,7 @@ function_callbacks_test: Skip # Issue dartbug.com/37295
|
|||
*: Skip # "hardfp" calling convention is not yet supported (iOS is also supported but not tested): dartbug.com/36309
|
||||
|
||||
[ $arch == simdbc64 && $system != linux && $system != macos ]
|
||||
*: Skip # DBC is only supported on MacOS and Linux for testing
|
||||
*: Skip # FFI not yet supported outside x64 Linux: dartbug.com/36809
|
||||
|
||||
[ $runtime != dart_precompiled && $runtime != vm ]
|
||||
*: SkipByDesign # FFI is a VM-only feature. (This test suite is part of the default set.)
|
||||
|
|
Loading…
Reference in a new issue