@@ -247,6 +247,9 @@ class FfiTransformer extends Transformer {
247
247
/// Classes corresponding to [NativeType] , indexed by [NativeType] .
248
248
final List <Class > nativeTypesClasses;
249
249
250
+ Library currentLibrary;
251
+ IndexedLibrary currentLibraryIndex;
252
+
250
253
FfiTransformer (this .index, this .coreTypes, this .hierarchy,
251
254
this .diagnosticReporter, this .referenceFromIndex)
252
255
: env = new TypeEnvironment (coreTypes, hierarchy),
@@ -336,6 +339,16 @@ class FfiTransformer extends Transformer {
336
339
'DynamicLibraryExtension' ,
337
340
LibraryIndex .tearoffPrefix + 'lookupFunction' );
338
341
342
+ @override
343
+ TreeNode visitLibrary (Library node) {
344
+ assert (currentLibrary == null );
345
+ currentLibrary = node;
346
+ currentLibraryIndex = referenceFromIndex? .lookupLibrary (node);
347
+ final result = super .visitLibrary (node);
348
+ currentLibrary = null ;
349
+ return result;
350
+ }
351
+
339
352
/// Computes the Dart type corresponding to a ffi.[NativeType] , returns null
340
353
/// if it is not a valid NativeType.
341
354
///
@@ -441,6 +454,111 @@ class FfiTransformer extends Transformer {
441
454
Arguments ([StaticInvocation (abiMethod, Arguments ([]))]),
442
455
listElementAt);
443
456
}
457
+
458
+ /// Generates an expression that returns a new `Pointer<dartType>` offset
459
+ /// by [offset] from [pointer] .
460
+ ///
461
+ /// Sample output:
462
+ ///
463
+ /// ```
464
+ /// _fromAddress<dartType>(pointer.address + #offset)
465
+ /// ```
466
+ Expression _pointerOffset (Expression pointer, Expression offset,
467
+ DartType dartType, int fileOffset) =>
468
+ StaticInvocation (
469
+ fromAddressInternal,
470
+ Arguments ([
471
+ MethodInvocation (
472
+ PropertyGet (pointer, addressGetter.name, addressGetter)
473
+ ..fileOffset = fileOffset,
474
+ numAddition.name,
475
+ Arguments ([offset]),
476
+ numAddition)
477
+ ], types: [
478
+ dartType
479
+ ]))
480
+ ..fileOffset = fileOffset;
481
+
482
+ /// Generates an expression that returns a new `TypedData` offset
483
+ /// by [offset] from [typedData] .
484
+ ///
485
+ /// Sample output:
486
+ ///
487
+ /// ```
488
+ /// TypedData #typedData = typedData;
489
+ /// #typedData.buffer.asInt8List(#typedData.offsetInBytes + offset, length)
490
+ /// ```
491
+ Expression _typedDataOffset (Expression typedData, Expression offset,
492
+ Expression length, int fileOffset) {
493
+ final typedDataVar = VariableDeclaration ("#typedData" ,
494
+ initializer: typedData,
495
+ type: InterfaceType (typedDataClass, Nullability .nonNullable))
496
+ ..fileOffset = fileOffset;
497
+ return Let (
498
+ typedDataVar,
499
+ MethodInvocation (
500
+ PropertyGet (VariableGet (typedDataVar), typedDataBufferGetter.name,
501
+ typedDataBufferGetter)
502
+ ..fileOffset = fileOffset,
503
+ byteBufferAsUint8List.name,
504
+ Arguments ([
505
+ MethodInvocation (
506
+ PropertyGet (
507
+ VariableGet (typedDataVar),
508
+ typedDataOffsetInBytesGetter.name,
509
+ typedDataOffsetInBytesGetter)
510
+ ..fileOffset = fileOffset,
511
+ numAddition.name,
512
+ Arguments ([offset]),
513
+ numAddition),
514
+ length
515
+ ]),
516
+ byteBufferAsUint8List));
517
+ }
518
+
519
+ /// Generates an expression that returns a new `TypedDataBase` offset
520
+ /// by [offset] from [typedDataBase] .
521
+ ///
522
+ /// If [typedDataBase] is a `Pointer` , returns a `Pointer<dartType>` .
523
+ /// If [typedDataBase] is a `TypedData` returns a `TypedData` .
524
+ ///
525
+ /// Sample output:
526
+ ///
527
+ /// ```
528
+ /// Object #typedDataBase = typedDataBase;
529
+ /// int #offset = offset;
530
+ /// #typedDataBase is Pointer ?
531
+ /// _pointerOffset<dartType>(#typedDataBase, #offset) :
532
+ /// _typedDataOffset((#typedDataBase as TypedData), #offset, length)
533
+ /// ```
534
+ Expression typedDataBaseOffset (Expression typedDataBase, Expression offset,
535
+ Expression length, DartType dartType, int fileOffset) {
536
+ final typedDataBaseVar = VariableDeclaration ("#typedDataBase" ,
537
+ initializer: typedDataBase, type: coreTypes.objectNonNullableRawType)
538
+ ..fileOffset = fileOffset;
539
+ final offsetVar = VariableDeclaration ("#offset" ,
540
+ initializer: offset, type: coreTypes.intNonNullableRawType)
541
+ ..fileOffset = fileOffset;
542
+ return BlockExpression (
543
+ Block ([typedDataBaseVar, offsetVar]),
544
+ ConditionalExpression (
545
+ IsExpression (VariableGet (typedDataBaseVar),
546
+ InterfaceType (pointerClass, Nullability .nonNullable)),
547
+ _pointerOffset (VariableGet (typedDataBaseVar),
548
+ VariableGet (offsetVar), dartType, fileOffset),
549
+ _typedDataOffset (
550
+ StaticInvocation (
551
+ unsafeCastMethod,
552
+ Arguments ([
553
+ VariableGet (typedDataBaseVar)
554
+ ], types: [
555
+ InterfaceType (typedDataClass, Nullability .nonNullable)
556
+ ])),
557
+ VariableGet (offsetVar),
558
+ length,
559
+ fileOffset),
560
+ coreTypes.objectNonNullableRawType));
561
+ }
444
562
}
445
563
446
564
/// Contains all information collected by _FfiDefinitionTransformer that is
0 commit comments