Skip to content

Commit 4131d3d

Browse files
dcharkescommit-bot@chromium.org
authored andcommitted
[vm/ffi] Improve API docs
This changes the API docs to (1) be specialized to the specific types and (2) have more precise wording. Change-Id: I14fa37bd162f846c19e62443c53dd051eaa62ad3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121427 Reviewed-by: Kathy Walrath <kathyw@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com>
1 parent 6ccd582 commit 4131d3d

File tree

3 files changed

+545
-467
lines changed

3 files changed

+545
-467
lines changed

runtime/tools/ffi/sdk_lib_ffi_generator.dart

Lines changed: 111 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void generate(
5959
}
6060

6161
void generateHeader(StringBuffer buffer) {
62-
final header = """
62+
const header = """
6363
//
6464
// The following code is generated, do not edit by hand.
6565
//
@@ -77,66 +77,114 @@ void generatePublicExtension(StringBuffer buffer, Config config) {
7777
final typedListType = config.typedListType;
7878
final elementSize = config.elementSize;
7979

80-
final storeTrunctateInt = """
81-
/// Note that ints which do not fit in [$nativeType] are truncated.
80+
final bits = sizeOfBits(elementSize);
81+
// final sizeInBytes =
82+
// "${sizeOf(elementSize)} byte${elementSize != 1 ? "s" : ""}";
83+
84+
String property;
85+
if (_isInt(nativeType)) {
86+
if (_isSigned(nativeType)) {
87+
property = "$bits-bit two's complement integer";
88+
} else {
89+
property = "$bits-bit unsigned integer";
90+
}
91+
} else if (nativeType == "Float") {
92+
property = "float";
93+
} else {
94+
property = "double";
95+
}
96+
97+
const platformIntPtr = """
98+
///
99+
/// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms
100+
/// this is a 64-bit integer.
82101
""";
83102

84-
final storeTrunctateDouble = """
85-
/// Note that doubles stored into Pointer<[Float]> lose precision.
103+
final platform = nativeType == "IntPtr" ? platformIntPtr : "";
104+
105+
final intSignedTruncate = """
106+
///
107+
/// A Dart integer is truncated to $bits bits (as if by `.toSigned($bits)`) before
108+
/// being stored, and the $bits-bit value is sign-extended when it is loaded.
86109
""";
87110

88-
final storeTruncate =
89-
_isInt(nativeType) ? storeTrunctateInt : storeTrunctateDouble;
111+
const intPtrTruncate = """
112+
///
113+
/// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by
114+
/// `.toSigned(32)`) before being stored, and the 32-bit value is
115+
/// sign-extended when it is loaded.
116+
""";
90117

91-
final loadSignExtendInt = """
92-
/// Note that ints are signextended.
118+
final intUnsignedTruncate = """
119+
///
120+
/// A Dart integer is truncated to $bits bits (as if by `.toUnsigned($bits)`) before
121+
/// being stored, and the $bits-bit value is zero-extended when it is loaded.
93122
""";
94123

95-
final loadSignExtend = _isInt(nativeType) ? loadSignExtendInt : "";
124+
const floatTruncate = """
125+
///
126+
/// A Dart double loses precision before being stored, and the float value is
127+
/// converted to a double when it is loaded.
128+
""";
129+
130+
String truncate = "";
131+
if (nativeType == "IntPtr") {
132+
truncate = intPtrTruncate;
133+
} else if (_isInt(nativeType) && elementSize != 8) {
134+
truncate = _isSigned(nativeType) ? intSignedTruncate : intUnsignedTruncate;
135+
} else if (nativeType == "Float") {
136+
truncate = floatTruncate;
137+
}
138+
139+
final sizeTimes =
140+
elementSize != 1 ? '${bracketOr(sizeOf(elementSize))} * ' : '';
141+
142+
final alignmentDefault = """
143+
///
144+
/// The [address] must be ${sizeOf(elementSize)}-byte aligned.
145+
""";
146+
147+
const alignmentIntptr = """
148+
///
149+
/// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
150+
/// platforms the [address] must be 8-byte aligned.
151+
""";
152+
153+
String alignment = "";
154+
if (nativeType == "IntPtr") {
155+
alignment = alignmentIntptr;
156+
} else if (elementSize != 1) {
157+
alignment = alignmentDefault;
158+
}
96159

97160
final asTypedList = typedListType == kDoNotEmit
98161
? ""
99162
: """
100163
/// Creates a typed list view backed by memory in the address space.
101164
///
102-
/// The returned view will allow access to the memory range from `address`
103-
/// to `address + ${elementSize > 1 ? '$elementSize * ' : ''}length`.
165+
/// The returned view will allow access to the memory range from [address]
166+
/// to `address + ${sizeTimes}length`.
104167
///
105168
/// The user has to ensure the memory range is accessible while using the
106169
/// returned list.
107-
external $typedListType asTypedList(int length);
170+
$alignment external $typedListType asTypedList(int length);
108171
""";
109172

173+
// TODO(38892): Stop generating documentation on setter.
110174
buffer.write("""
111175
/// Extension on [Pointer] specialized for the type argument [$nativeType].
112176
extension ${nativeType}Pointer on Pointer<$nativeType> {
113-
/// Load a Dart value from this location.
114-
///
115-
/// The value is automatically unmarshalled from its native representation.
116-
$loadSignExtend ///
117-
/// Note that [address] needs to be aligned to the size of [$nativeType].
118-
external $dartType get value;
177+
/// The $property at [address].
178+
$platform$truncate$alignment external $dartType get value;
119179
120-
/// Store a Dart value into this location.
121-
///
122-
/// The [value] is automatically marshalled into its native representation.
123-
$storeTruncate ///
124-
/// Note that [address] needs to be aligned to the size of [$nativeType].
125-
external void set value($dartType value);
180+
/// The $property at [address].
181+
$platform$truncate$alignment external void set value($dartType value);
126182
127-
/// Load a Dart value from this location offset by [index].
128-
///
129-
/// The value is automatically unmarshalled from its native representation.
130-
$loadSignExtend ///
131-
/// Note that [address] needs to be aligned to the size of [$nativeType].
132-
external $dartType operator [](int index);
183+
/// The $property at `address + ${sizeTimes}index`.
184+
$platform$truncate$alignment external $dartType operator [](int index);
133185
134-
/// Store a Dart value into this location offset by [index].
135-
///
136-
/// The [value] is automatically marshalled into its native representation.
137-
$storeTruncate ///
138-
/// Note that [address] needs to be aligned to the size of [$nativeType].
139-
external void operator []=(int index, $dartType value);
186+
/// The $property at `address + ${sizeTimes}index`.
187+
$platform$truncate$alignment external void operator []=(int index, $dartType value);
140188
141189
$asTypedList
142190
}
@@ -191,6 +239,32 @@ void generateFooter(StringBuffer buffer) {
191239
//
192240

193241
bool _isInt(String type) => type.startsWith("Int") || type.startsWith("Uint");
242+
bool _isSigned(String type) => type.startsWith("Int");
243+
244+
String sizeOf(int size) {
245+
switch (size) {
246+
case kIntPtrElementSize:
247+
return "4 or 8";
248+
default:
249+
return "$size";
250+
}
251+
}
252+
253+
String sizeOfBits(int size) {
254+
switch (size) {
255+
case kIntPtrElementSize:
256+
return "32 or 64";
257+
default:
258+
return "${size * 8}";
259+
}
260+
}
261+
262+
String bracketOr(String input) {
263+
if (input.contains("or")) {
264+
return "($input)";
265+
}
266+
return input;
267+
}
194268

195269
final Uri _containingFolder = File.fromUri(Platform.script).parent.uri;
196270

0 commit comments

Comments
 (0)