@@ -230,18 +230,46 @@ class FfiNativeTransformer extends FfiTransformer {
230
230
initializer: initializer, type: wrappedType, isFinal: true );
231
231
}
232
232
233
- Expression _getTemporary (VariableDeclaration temporary,
234
- DartType dartParameterType, DartType ffiParameterType) {
233
+ Expression _getTemporary (
234
+ VariableDeclaration temporary,
235
+ DartType dartParameterType,
236
+ DartType ffiParameterType, {
237
+ required bool checkForNullptr,
238
+ }) {
235
239
if (_requiresPointerConversion (dartParameterType, ffiParameterType)) {
236
- // Pointer.fromAddress(_getNativeField(#t0))
237
- return StaticInvocation (
238
- fromAddressInternal,
239
- Arguments (< Expression > [
240
- StaticInvocation (getNativeFieldFunction,
241
- Arguments (< Expression > [VariableGet (temporary)]))
242
- ], types: < DartType > [
243
- voidType
244
- ]));
240
+ Expression pointerAddress = StaticInvocation (getNativeFieldFunction,
241
+ Arguments (< Expression > [VariableGet (temporary)]));
242
+
243
+ if (checkForNullptr) {
244
+ final pointerAddressVar = VariableDeclaration ("#pointerAddress" ,
245
+ initializer: pointerAddress, type: coreTypes.intNonNullableRawType);
246
+ pointerAddress = BlockExpression (
247
+ Block ([
248
+ pointerAddressVar,
249
+ IfStatement (
250
+ InstanceInvocation (
251
+ InstanceAccessKind .Instance ,
252
+ VariableGet (pointerAddressVar),
253
+ objectEquals.name,
254
+ Arguments ([ConstantExpression (IntConstant (0 ))]),
255
+ interfaceTarget: objectEquals,
256
+ functionType: objectEquals.getterType as FunctionType ,
257
+ ),
258
+ ExpressionStatement (StaticInvocation (
259
+ stateErrorThrowNewFunction,
260
+ Arguments ([
261
+ ConstantExpression (StringConstant ('Native field is nullptr.' ))
262
+ ]),
263
+ )),
264
+ EmptyStatement (),
265
+ )
266
+ ]),
267
+ VariableGet (pointerAddressVar),
268
+ );
269
+ }
270
+
271
+ return StaticInvocation (fromAddressInternal,
272
+ Arguments (< Expression > [pointerAddress], types: < DartType > [voidType]));
245
273
}
246
274
return VariableGet (temporary);
247
275
}
@@ -262,8 +290,12 @@ class FfiNativeTransformer extends FfiTransformer {
262
290
// final #t1 = passAsPointer(Pointer.fromAddress(_getNativeField(#t0)));
263
291
// reachabilityFence(#t0);
264
292
// } => #t1
265
- Expression _wrapArgumentsAndReturn (FunctionInvocation invocation,
266
- FunctionType dartFunctionType, FunctionType ffiFunctionType) {
293
+ Expression _wrapArgumentsAndReturn ({
294
+ required FunctionInvocation invocation,
295
+ required FunctionType dartFunctionType,
296
+ required FunctionType ffiFunctionType,
297
+ bool checkReceiverForNullptr = false ,
298
+ }) {
267
299
List <DartType > ffiParameters = ffiFunctionType.positionalParameters;
268
300
List <DartType > dartParameters = dartFunctionType.positionalParameters;
269
301
// Create lists of temporary variables for arguments potentially being
@@ -277,8 +309,12 @@ class FfiNativeTransformer extends FfiTransformer {
277
309
// Note: We also evaluate, and assign temporaries for, non-wrapped
278
310
// arguments as we need to preserve the original evaluation order.
279
311
temporariesForArguments.add (temporary);
280
- callArguments
281
- .add (_getTemporary (temporary, dartParameters[i], ffiParameters[i]));
312
+ callArguments.add (_getTemporary (
313
+ temporary,
314
+ dartParameters[i],
315
+ ffiParameters[i],
316
+ checkForNullptr: checkReceiverForNullptr && i == 0 ,
317
+ ));
282
318
if (_requiresPointerConversion (dartParameters[i], ffiParameters[i])) {
283
319
fencedArguments.add (temporary);
284
320
continue ;
@@ -392,13 +428,15 @@ class FfiNativeTransformer extends FfiTransformer {
392
428
}
393
429
394
430
Procedure _transformProcedure (
395
- Procedure node,
396
- StringConstant nativeFunctionName,
397
- bool isLeaf,
398
- int annotationOffset,
399
- FunctionType dartFunctionType,
400
- FunctionType ffiFunctionType,
401
- List <Expression > argumentList) {
431
+ Procedure node,
432
+ StringConstant nativeFunctionName,
433
+ bool isLeaf,
434
+ int annotationOffset,
435
+ FunctionType dartFunctionType,
436
+ FunctionType ffiFunctionType,
437
+ List <Expression > argumentList, {
438
+ required bool checkReceiverForNullptr,
439
+ }) {
402
440
if (! _verifySignatures (
403
441
node, dartFunctionType, ffiFunctionType, annotationOffset)) {
404
442
return node;
@@ -462,7 +500,11 @@ class FfiNativeTransformer extends FfiTransformer {
462
500
Expression result = (wrappedDartFunctionType == dartFunctionType
463
501
? functionPointerInvocation
464
502
: _wrapArgumentsAndReturn (
465
- functionPointerInvocation, dartFunctionType, ffiFunctionType));
503
+ invocation: functionPointerInvocation,
504
+ dartFunctionType: dartFunctionType,
505
+ ffiFunctionType: ffiFunctionType,
506
+ checkReceiverForNullptr: checkReceiverForNullptr,
507
+ ));
466
508
467
509
// => _myFunction$FfiNative$Ptr(
468
510
// Pointer<Void>.fromAddress(_getNativeField(obj)), x)
@@ -509,8 +551,16 @@ class FfiNativeTransformer extends FfiTransformer {
509
551
VariableGet (parameter)
510
552
];
511
553
512
- return _transformProcedure (node, nativeFunctionName, isLeaf,
513
- annotationOffset, dartFunctionType, ffiFunctionType, argumentList);
554
+ return _transformProcedure (
555
+ node,
556
+ nativeFunctionName,
557
+ isLeaf,
558
+ annotationOffset,
559
+ dartFunctionType,
560
+ ffiFunctionType,
561
+ argumentList,
562
+ checkReceiverForNullptr: true ,
563
+ );
514
564
}
515
565
516
566
// Transform FfiNative static functions.
@@ -536,8 +586,16 @@ class FfiNativeTransformer extends FfiTransformer {
536
586
VariableGet (parameter)
537
587
];
538
588
539
- return _transformProcedure (node, nativeFunctionName, isLeaf,
540
- annotationOffset, dartFunctionType, ffiFunctionType, argumentList);
589
+ return _transformProcedure (
590
+ node,
591
+ nativeFunctionName,
592
+ isLeaf,
593
+ annotationOffset,
594
+ dartFunctionType,
595
+ ffiFunctionType,
596
+ argumentList,
597
+ checkReceiverForNullptr: false ,
598
+ );
541
599
}
542
600
543
601
@override
0 commit comments