Skip to content

Commit

Permalink
Reland "[vm/ffi] Introduce Struct.create and Union.create"
Browse files Browse the repository at this point in the history
Analyzer fix #54754 has
landed. A new version of package:analyzer and package:dartdoc have
been released. `pub global activate dartdoc` should now work.

Patchset 1 is identical to the original CL.
The only difference is an extra test testing with negative offsets.

=== Original CL description ===

Structs and unions can now be created from an existing typed data
with the new `create` methods.

The typed data argument to these `create` methods is optional. If
the typed data argument is omitted, a new typed data of the right
size will be allocated.

Compound field reads and writes are unchecked. (These are
TypedDataBase loads and stores, rather than TypedData loads and stores.
And Pointers have no byte length.) Therefore the `create` method taking
existing TypedData objects check whether the length in bytes it at
least the size of the compound.

TEST=pkg/analyzer/test/src/diagnostics/creation_of_struct_or_union_test.dart
TEST=pkg/vm/testcases/transformations/ffi/struct_typed_data.dart
TEST=tests/ffi/structs_typed_data_test.dart
TEST=tests/ffi/vmspecific_static_checks_test.dart

Closes: #45697
Closes: #53418

Change-Id: Id7f30bcd4a6ae55a8298b39c9eadf4e80bc699a9
CoreLibraryReviewExempt: FFI is a VM and WASM only feature.
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-release-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349260
Reviewed-by: Martin Kustermann <kustermann@google.com>
  • Loading branch information
dcharkes committed Feb 1, 2024
1 parent 0151574 commit bf683ba
Show file tree
Hide file tree
Showing 50 changed files with 944 additions and 56 deletions.
54 changes: 47 additions & 7 deletions pkg/analyzer/lib/src/generated/ffi_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
if (element is MethodElement) {
var enclosingElement = element.enclosingElement;
if (enclosingElement.isNativeStructPointerExtension ||
enclosingElement.isNativeStructArrayExtension) {
enclosingElement.isNativeStructArrayExtension ||
enclosingElement.isNativeUnionPointerExtension ||
enclosingElement.isNativeUnionArrayExtension) {
if (element.name == '[]') {
_validateRefIndexed(node);
}
Expand All @@ -232,10 +234,12 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
var constructor = node.constructorName.staticElement;
var class_ = constructor?.enclosingElement;
if (class_.isStructSubclass || class_.isUnionSubclass) {
_errorReporter.reportErrorForNode(
FfiCode.CREATION_OF_STRUCT_OR_UNION,
node.constructorName,
);
if (!constructor!.isFactory) {
_errorReporter.reportErrorForNode(
FfiCode.CREATION_OF_STRUCT_OR_UNION,
node.constructorName,
);
}
} else if (class_.isNativeCallable) {
_validateNativeCallable(node);
}
Expand Down Expand Up @@ -289,6 +293,10 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
} else if (element.name == 'elementAt') {
_validateElementAt(node);
}
} else if (enclosingElement.isStruct || enclosingElement.isUnion) {
if (element.name == 'create') {
_validateCreate(node, enclosingElement.name!);
}
} else if (enclosingElement.isNative) {
if (element.name == 'addressOf') {
_validateNativeAddressOf(node);
Expand Down Expand Up @@ -320,7 +328,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
var element = node.staticElement;
if (element != null) {
var enclosingElement = element.enclosingElement;
if (enclosingElement.isNativeStructPointerExtension) {
if (enclosingElement.isNativeStructPointerExtension ||
enclosingElement.isNativeUnionPointerExtension) {
if (element.name == 'ref') {
_validateRefPrefixedIdentifier(node);
}
Expand All @@ -334,7 +343,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
var element = node.propertyName.staticElement;
if (element != null) {
var enclosingElement = element.enclosingElement;
if (enclosingElement.isNativeStructPointerExtension) {
if (enclosingElement.isNativeStructPointerExtension ||
enclosingElement.isNativeUnionPointerExtension) {
if (element.name == 'ref') {
_validateRefPropertyAccess(node);
}
Expand Down Expand Up @@ -1148,6 +1158,22 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
}
}

void _validateCreate(MethodInvocation node, String errorClass) {
final typeArgumentTypes = node.typeArgumentTypes;
if (typeArgumentTypes == null || typeArgumentTypes.length != 1) {
return;
}
final DartType dartType = typeArgumentTypes[0];
if (!_isValidFfiNativeType(dartType)) {
final AstNode errorNode = node;
_errorReporter.reportErrorForNode(
FfiCode.NON_CONSTANT_TYPE_ARGUMENT,
errorNode,
['$errorClass.create'],
);
}
}

void _validateElementAt(MethodInvocation node) {
var targetType = node.realTarget?.staticType;
if (targetType is InterfaceType && targetType.isPointer) {
Expand Down Expand Up @@ -1856,6 +1882,20 @@ extension on Element? {
element.isFfiExtension;
}

bool get isNativeUnionArrayExtension {
final element = this;
return element is ExtensionElement &&
element.name == 'UnionArray' &&
element.isFfiExtension;
}

bool get isNativeUnionPointerExtension {
final element = this;
return element is ExtensionElement &&
element.name == 'UnionPointer' &&
element.isFfiExtension;
}

/// Return `true` if this represents the class `Opaque`.
bool get isOpaque {
final element = this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ library /*isLegacy*/;
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
import "dart:typed_data" as typ;

import "dart:ffi";
import "package:ffi/ffi.dart";
Expand All @@ -18,6 +19,9 @@ class Coordinate extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase) → self::Coordinate
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::Coordinate
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
static factory allocate(ffi::Allocator* allocator, core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
return let final self::Coordinate* #t1 = new self::Coordinate::#fromTypedDataBase(allocator.{ffi::Allocator::allocate}<self::Coordinate*>(self::Coordinate::#sizeOf){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Coordinate*>}!) in block {
#t1.{self::Coordinate::x} = x;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ library /*isLegacy*/;
import self as self;
import "dart:core" as core;
import "dart:ffi" as ffi;
import "dart:typed_data" as typ;

import "dart:ffi";
import "package:ffi/ffi.dart";
Expand All @@ -11,6 +12,9 @@ class Coordinate extends ffi::Struct {
constructor #fromTypedDataBase(synthesized core::Object #typedDataBase) → self::Coordinate
: super ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized typ::TypedData #typedData, synthesized core::int #offset, synthesized core::int #sizeInBytes) → self::Coordinate
: super ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
static factory allocate(ffi::Allocator* allocator, core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
return let final self::Coordinate* #t1 = new self::Coordinate::#fromTypedDataBase(allocator.{ffi::Allocator::allocate}<self::Coordinate*>(self::Coordinate::#sizeOf){(core::int, {alignment: core::int?}) → ffi::Pointer<self::Coordinate*>}!) in block {
#t1.{self::Coordinate::x} = x;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Y
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Y
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C7
get yy() → dart.core::int
return dart.ffi::_loadUint32(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand All @@ -35,6 +38,9 @@ library from "org-dartlang-test:///main.dart" as main {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → main::X
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → main::X
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get xx() → lib::Y
return new lib::Y::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Y
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Y
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C7
get yy() → dart.core::int
return dart.ffi::_loadUint32(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand All @@ -35,6 +38,9 @@ library from "org-dartlang-test:///main.dart" as main {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → main::X
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → main::X
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get xx() → lib::Y
return new lib::Y::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ library from "org-dartlang-test:///structs.dart" as str {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → str::A
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → str::A
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get yy() → str::Y
return new str::Y::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand All @@ -47,6 +50,9 @@ library from "org-dartlang-test:///structs.dart" as str {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → str::Y
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → str::Y
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
external get zz() → invalid-type;
external set zz(synthesized invalid-type #externalFieldValue) → void;
@#C10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ library from "org-dartlang-test:///structs.dart" as str {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → str::A
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → str::A
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get yy() → str::Y
return new str::Y::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand All @@ -47,6 +50,9 @@ library from "org-dartlang-test:///structs.dart" as str {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → str::Y
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → str::Y
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
external get zz() → invalid-type;
external set zz(synthesized invalid-type #externalFieldValue) → void;
@#C10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C8
get x() → dart.core::double
return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C10.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C8
get x() → dart.core::double
return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C10.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C8
get x() → dart.core::double
return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C10.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ library from "org-dartlang-test:///a.dart" as a {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → a::StructA
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → a::StructA
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get a1() → dart.ffi::Pointer<dart.ffi::Void>
return dart.ffi::_loadPointer<dart.ffi::Void>(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
set a1(synthesized dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
Expand Down Expand Up @@ -42,6 +45,9 @@ library from "org-dartlang-test:///a.dart" as a {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → a::NestedStruct
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → a::NestedStruct
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get n1() → dart.ffi::Pointer<dart.ffi::Void>
return dart.ffi::_loadPointer<dart.ffi::Void>(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
set n1(synthesized dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
Expand Down Expand Up @@ -74,6 +80,9 @@ library from "org-dartlang-test:///b.dart" as b {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → b::StructB
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → b::StructB
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get b1() → a::StructA
return new a::StructA::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ library from "org-dartlang-test:///a.dart" as a {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → a::StructA
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → a::StructA
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get a1() → dart.ffi::Pointer<dart.ffi::Void>
return dart.ffi::_loadPointer<dart.ffi::Void>(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
set a1(synthesized dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
Expand Down Expand Up @@ -42,6 +45,9 @@ library from "org-dartlang-test:///a.dart" as a {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → a::NestedStruct
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → a::NestedStruct
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get n1() → dart.ffi::Pointer<dart.ffi::Void>
return dart.ffi::_loadPointer<dart.ffi::Void>(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C9.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
set n1(synthesized dart.ffi::Pointer<dart.ffi::Void> #externalFieldValue) → void
Expand Down Expand Up @@ -74,6 +80,9 @@ library from "org-dartlang-test:///b.dart" as b {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → b::StructB
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → b::StructB
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
get b1() → a::StructA
return new a::StructA::#fromTypedDataBase( block {
synthesized dart.core::Object #typedDataBase = this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C8
get x() → dart.core::double
return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C10.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ library from "org-dartlang-test:///lib.dart" as lib {
constructor #fromTypedDataBase(synthesized dart.core::Object #typedDataBase) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
;
constructor #fromTypedData(synthesized dart.typed_data::TypedData #typedData, synthesized dart.core::int #offset, synthesized dart.core::int #sizeInBytes) → lib::Coordinate
: super dart.ffi::Struct::_fromTypedData(#typedData, #offset, #sizeInBytes)
;
@#C8
get x() → dart.core::double
return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}{dart.core::Object}, #C10.{dart.core::List::[]}(dart.ffi::_abi()){(dart.core::int) → dart.core::int*});
Expand Down
Loading

0 comments on commit bf683ba

Please sign in to comment.