@@ -92,6 +92,41 @@ class CoreTypesUtil {
92
92
final Class jsArrayBufferImplClass;
93
93
final Class byteBufferClass;
94
94
95
+ // NB. We rely on iteration ordering being insertion order to handle subtypes
96
+ // before supertypes to convert as `int` and `double` before `num`.
97
+ late final Map <Class , Procedure > _externRefConverterMap = {
98
+ coreTypes.boolClass: toJSBoolean,
99
+ coreTypes.intClass: jsifyInt,
100
+ coreTypes.doubleClass: toJSNumber,
101
+ coreTypes.numClass: jsifyNum,
102
+ jsValueClass: jsifyJSValue,
103
+ coreTypes.stringClass: jsifyString,
104
+ jsInt8ArrayImplClass: jsifyJSInt8ArrayImpl,
105
+ jsUint8ArrayImplClass: jsifyJSUint8ArrayImpl,
106
+ jsUint8ClampedArrayImplClass: jsifyJSUint8ClampedArrayImpl,
107
+ jsInt16ArrayImplClass: jsifyJSInt16ArrayImpl,
108
+ jsUint16ArrayImplClass: jsifyJSUint16ArrayImpl,
109
+ jsInt32ArrayImplClass: jsifyJSInt32ArrayImpl,
110
+ jsUint32ArrayImplClass: jsifyJSUint32ArrayImpl,
111
+ jsFloat32ArrayImplClass: jsifyJSFloat32ArrayImpl,
112
+ jsFloat64ArrayImplClass: jsifyJSFloat64ArrayImpl,
113
+ int8ListClass: jsInt8ArrayFromDartInt8List,
114
+ uint8ListClass: jsUint8ArrayFromDartUint8List,
115
+ uint8ClampedListClass: jsUint8ClampedArrayFromDartUint8ClampedList,
116
+ int16ListClass: jsInt16ArrayFromDartInt16List,
117
+ uint16ListClass: jsUint16ArrayFromDartUint16List,
118
+ int32ListClass: jsInt32ArrayFromDartInt32List,
119
+ uint32ListClass: jsUint32ArrayFromDartUint32List,
120
+ float32ListClass: jsFloat32ArrayFromDartFloat32List,
121
+ float64ListClass: jsFloat64ArrayFromDartFloat64List,
122
+ jsDataViewImplClass: jsifyJSDataViewImpl,
123
+ byteDataClass: jsifyByteData,
124
+ coreTypes.listClass: jsifyRawList,
125
+ jsArrayBufferImplClass: jsifyJSArrayBufferImpl,
126
+ byteBufferClass: jsArrayBufferFromDartByteBuffer,
127
+ coreTypes.functionClass: jsifyFunction,
128
+ };
129
+
95
130
CoreTypesUtil (this .coreTypes, this .extensionIndex)
96
131
: allowInteropTarget = coreTypes.index
97
132
.getTopLevelProcedure ('dart:js_util' , 'allowInterop' ),
@@ -367,6 +402,43 @@ class CoreTypesUtil {
367
402
}
368
403
return AsExpression (expression, staticType);
369
404
}
405
+
406
+ /// Return the function to convert a value with type [valueType] to Dart
407
+ /// interop type [expectedType] .
408
+ ///
409
+ /// [expectedType] can be any interop type, but for now this only handles the
410
+ /// interop types generated by [_Specializer._getRawInteropProcedure] .
411
+ ///
412
+ /// `null` return value means no conversion is needed, the value can be passed
413
+ /// to the interop function directly.
414
+ ///
415
+ /// The argument passed to the returned conversion function needs to be
416
+ /// non-nullable. This function does not check the nullability of [valueType]
417
+ /// and assume that the argument passed to the conversion function won't be
418
+ /// `null` .
419
+ Procedure ? _conversionProcedure (
420
+ DartType valueType, DartType expectedType, TypeEnvironment typeEnv) {
421
+ if (expectedType == coreTypes.doubleNonNullableRawType) {
422
+ assert (valueType is InterfaceType &&
423
+ valueType.classNode == coreTypes.doubleClass);
424
+ return null ;
425
+ }
426
+
427
+ assert (expectedType == nullableWasmExternRefType,
428
+ 'Unexpected expected type: $expectedType ' );
429
+
430
+ for (final entry in _externRefConverterMap.entries) {
431
+ if (typeEnv.isSubtypeOf (
432
+ valueType,
433
+ InterfaceType (entry.key, Nullability .nonNullable),
434
+ SubtypeCheckMode .withNullabilities)) {
435
+ return entry.value;
436
+ }
437
+ }
438
+
439
+ // `dynamic` or `Object?`, convert based on runtime type.
440
+ return jsifyRawTarget;
441
+ }
370
442
}
371
443
372
444
StaticInvocation invokeOneArg (Procedure target, Expression arg) =>
@@ -383,20 +455,22 @@ InstanceInvocation invokeMethod(VariableDeclaration receiver, Procedure target,
383
455
bool parametersNeedParens (List <String > parameters) =>
384
456
parameters.isEmpty || parameters.length > 1 ;
385
457
386
- Expression jsifyValue (VariableDeclaration variable, CoreTypesUtil coreTypes ,
387
- TypeEnvironment typeEnv) {
388
- final Procedure conversionProcedure;
458
+ Expression jsifyValue (VariableDeclaration variable, DartType expectedType ,
459
+ CoreTypesUtil coreTypes, TypeEnvironment typeEnv) {
460
+ final Procedure ? conversionProcedure;
389
461
390
462
if (coreTypes.extensionIndex.isStaticInteropType (variable.type) ||
391
463
coreTypes.extensionIndex.isExternalDartReferenceType (variable.type)) {
392
464
conversionProcedure = coreTypes.jsValueUnboxTarget;
393
465
} else {
394
466
conversionProcedure =
395
- _conversionProcedure (variable.type, coreTypes , typeEnv);
467
+ coreTypes. _conversionProcedure (variable.type, expectedType , typeEnv);
396
468
}
397
469
398
- final conversion =
399
- StaticInvocation (conversionProcedure, Arguments ([VariableGet (variable)]));
470
+ final conversion = conversionProcedure == null
471
+ ? VariableGet (variable)
472
+ : StaticInvocation (
473
+ conversionProcedure, Arguments ([VariableGet (variable)]));
400
474
401
475
if (variable.type.isPotentiallyNullable) {
402
476
return ConditionalExpression (
@@ -408,54 +482,3 @@ Expression jsifyValue(VariableDeclaration variable, CoreTypesUtil coreTypes,
408
482
return conversion;
409
483
}
410
484
}
411
-
412
- Procedure _conversionProcedure (
413
- DartType type, CoreTypesUtil util, TypeEnvironment typeEnv) {
414
- // NB. We rely on iteration ordering being insertion order to handle subtypes
415
- // before supertypes to convert as `int` and `double` before `num`.
416
- final Map <Class , Procedure > converterMap = {
417
- util.coreTypes.boolClass: util.toJSBoolean,
418
- util.coreTypes.intClass: util.jsifyInt,
419
- util.coreTypes.doubleClass: util.toJSNumber,
420
- util.coreTypes.numClass: util.jsifyNum,
421
- util.jsValueClass: util.jsifyJSValue,
422
- util.coreTypes.stringClass: util.jsifyString,
423
- util.jsInt8ArrayImplClass: util.jsifyJSInt8ArrayImpl,
424
- util.jsUint8ArrayImplClass: util.jsifyJSUint8ArrayImpl,
425
- util.jsUint8ClampedArrayImplClass: util.jsifyJSUint8ClampedArrayImpl,
426
- util.jsInt16ArrayImplClass: util.jsifyJSInt16ArrayImpl,
427
- util.jsUint16ArrayImplClass: util.jsifyJSUint16ArrayImpl,
428
- util.jsInt32ArrayImplClass: util.jsifyJSInt32ArrayImpl,
429
- util.jsUint32ArrayImplClass: util.jsifyJSUint32ArrayImpl,
430
- util.jsFloat32ArrayImplClass: util.jsifyJSFloat32ArrayImpl,
431
- util.jsFloat64ArrayImplClass: util.jsifyJSFloat64ArrayImpl,
432
- util.int8ListClass: util.jsInt8ArrayFromDartInt8List,
433
- util.uint8ListClass: util.jsUint8ArrayFromDartUint8List,
434
- util.uint8ClampedListClass:
435
- util.jsUint8ClampedArrayFromDartUint8ClampedList,
436
- util.int16ListClass: util.jsInt16ArrayFromDartInt16List,
437
- util.uint16ListClass: util.jsUint16ArrayFromDartUint16List,
438
- util.int32ListClass: util.jsInt32ArrayFromDartInt32List,
439
- util.uint32ListClass: util.jsUint32ArrayFromDartUint32List,
440
- util.float32ListClass: util.jsFloat32ArrayFromDartFloat32List,
441
- util.float64ListClass: util.jsFloat64ArrayFromDartFloat64List,
442
- util.jsDataViewImplClass: util.jsifyJSDataViewImpl,
443
- util.byteDataClass: util.jsifyByteData,
444
- util.coreTypes.listClass: util.jsifyRawList,
445
- util.jsArrayBufferImplClass: util.jsifyJSArrayBufferImpl,
446
- util.byteBufferClass: util.jsArrayBufferFromDartByteBuffer,
447
- util.coreTypes.functionClass: util.jsifyFunction,
448
- };
449
-
450
- for (final entry in converterMap.entries) {
451
- if (typeEnv.isSubtypeOf (
452
- type,
453
- InterfaceType (entry.key, Nullability .nonNullable),
454
- SubtypeCheckMode .withNullabilities)) {
455
- return entry.value;
456
- }
457
- }
458
-
459
- // `dynamic` or `Object?`, convert based on runtime type.
460
- return util.jsifyRawTarget;
461
- }
0 commit comments