@@ -6,12 +6,13 @@ import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart'
66 show ExtensionIndex;
77import 'package:kernel/ast.dart' ;
88import 'package:kernel/core_types.dart' ;
9+ import 'package:kernel/type_environment.dart' ;
910
1011enum AnnotationType { import, export, weakExport }
1112
1213/// A utility wrapper for [CoreTypes] .
1314class CoreTypesUtil {
14- final ExtensionIndex _extensionIndex ;
15+ final ExtensionIndex extensionIndex ;
1516 final CoreTypes coreTypes;
1617 final Procedure allowInteropTarget;
1718 final Procedure dartifyRawTarget;
@@ -31,8 +32,65 @@ class CoreTypesUtil {
3132 final Class wasmArrayRefClass;
3233 final Procedure wrapDartFunctionTarget;
3334 final Procedure exportWasmFunctionTarget;
35+ final Member wasmExternRefNullRef;
3436
35- CoreTypesUtil (this .coreTypes, this ._extensionIndex)
37+ // Dart value to JS converters.
38+ final Procedure toJSBoolean;
39+ final Procedure jsifyInt;
40+ final Procedure toJSNumber;
41+ final Procedure jsifyNum;
42+ final Procedure jsifyJSValue;
43+ final Procedure jsifyString;
44+ final Procedure jsifyJSInt8ArrayImpl;
45+ final Procedure jsifyJSUint8ArrayImpl;
46+ final Procedure jsifyJSUint8ClampedArrayImpl;
47+ final Procedure jsifyJSInt16ArrayImpl;
48+ final Procedure jsifyJSUint16ArrayImpl;
49+ final Procedure jsifyJSInt32ArrayImpl;
50+ final Procedure jsifyJSUint32ArrayImpl;
51+ final Procedure jsifyJSFloat32ArrayImpl;
52+ final Procedure jsifyJSFloat64ArrayImpl;
53+ final Procedure jsInt8ArrayFromDartInt8List;
54+ final Procedure jsUint8ArrayFromDartUint8List;
55+ final Procedure jsUint8ClampedArrayFromDartUint8ClampedList;
56+ final Procedure jsInt16ArrayFromDartInt16List;
57+ final Procedure jsUint16ArrayFromDartUint16List;
58+ final Procedure jsInt32ArrayFromDartInt32List;
59+ final Procedure jsUint32ArrayFromDartUint32List;
60+ final Procedure jsFloat32ArrayFromDartFloat32List;
61+ final Procedure jsFloat64ArrayFromDartFloat64List;
62+ final Procedure jsifyJSDataViewImpl; // JS ByteData
63+ final Procedure jsifyByteData; // Wasm ByteData
64+ final Procedure jsifyRawList;
65+ final Procedure jsifyJSArrayBufferImpl; // JS ByteBuffer
66+ final Procedure jsArrayBufferFromDartByteBuffer; // Wasm ByteBuffer
67+ final Procedure jsifyFunction;
68+
69+ // Classes used in type tests for the converters.
70+ final Class jsInt8ArrayImplClass;
71+ final Class jsUint8ArrayImplClass;
72+ final Class jsUint8ClampedArrayImplClass;
73+ final Class jsInt16ArrayImplClass;
74+ final Class jsUint16ArrayImplClass;
75+ final Class jsInt32ArrayImplClass;
76+ final Class jsUint32ArrayImplClass;
77+ final Class jsFloat32ArrayImplClass;
78+ final Class jsFloat64ArrayImplClass;
79+ final Class int8ListClass;
80+ final Class uint8ListClass;
81+ final Class uint8ClampedListClass;
82+ final Class int16ListClass;
83+ final Class uint16ListClass;
84+ final Class int32ListClass;
85+ final Class uint32ListClass;
86+ final Class float32ListClass;
87+ final Class float64ListClass;
88+ final Class jsDataViewImplClass;
89+ final Class byteDataClass;
90+ final Class jsArrayBufferImplClass;
91+ final Class byteBufferClass;
92+
93+ CoreTypesUtil (this .coreTypes, this .extensionIndex)
3694 : allowInteropTarget = coreTypes.index
3795 .getTopLevelProcedure ('dart:js_util' , 'allowInterop' ),
3896 dartifyRawTarget = coreTypes.index
@@ -61,13 +119,120 @@ class CoreTypesUtil {
61119 coreTypes.index.getProcedure ('dart:_js_helper' , 'JSValue' , 'unbox' ),
62120 wasmExternRefClass =
63121 coreTypes.index.getClass ('dart:_wasm' , 'WasmExternRef' ),
122+ wasmExternRefNullRef = coreTypes.index
123+ .getMember ('dart:_wasm' , 'WasmExternRef' , 'get:nullRef' ),
64124 wasmArrayClass = coreTypes.index.getClass ('dart:_wasm' , 'WasmArray' ),
65125 wasmArrayRefClass =
66126 coreTypes.index.getClass ('dart:_wasm' , 'WasmArrayRef' ),
67127 wrapDartFunctionTarget = coreTypes.index
68128 .getTopLevelProcedure ('dart:_js_helper' , '_wrapDartFunction' ),
69129 exportWasmFunctionTarget = coreTypes.index
70- .getTopLevelProcedure ('dart:_internal' , 'exportWasmFunction' );
130+ .getTopLevelProcedure ('dart:_internal' , 'exportWasmFunction' ),
131+ toJSBoolean = coreTypes.index
132+ .getTopLevelProcedure ('dart:_js_helper' , 'toJSBoolean' ),
133+ jsifyInt =
134+ coreTypes.index.getTopLevelProcedure ('dart:_js_helper' , 'jsifyInt' ),
135+ toJSNumber = coreTypes.index
136+ .getTopLevelProcedure ('dart:_js_helper' , 'toJSNumber' ),
137+ jsifyNum =
138+ coreTypes.index.getTopLevelProcedure ('dart:_js_helper' , 'jsifyNum' ),
139+ jsifyJSValue = coreTypes.index
140+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSValue' ),
141+ jsifyString = coreTypes.index
142+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyString' ),
143+ jsifyJSInt8ArrayImpl = coreTypes.index
144+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSInt8ArrayImpl' ),
145+ jsifyJSUint8ArrayImpl = coreTypes.index
146+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSUint8ArrayImpl' ),
147+ jsifyJSUint8ClampedArrayImpl = coreTypes.index.getTopLevelProcedure (
148+ 'dart:_js_helper' , 'jsifyJSUint8ClampedArrayImpl' ),
149+ jsifyJSInt16ArrayImpl = coreTypes.index
150+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSInt16ArrayImpl' ),
151+ jsifyJSUint16ArrayImpl = coreTypes.index
152+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSUint16ArrayImpl' ),
153+ jsifyJSInt32ArrayImpl = coreTypes.index
154+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSInt32ArrayImpl' ),
155+ jsifyJSUint32ArrayImpl = coreTypes.index
156+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSUint32ArrayImpl' ),
157+ jsifyJSFloat32ArrayImpl = coreTypes.index
158+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSFloat32ArrayImpl' ),
159+ jsifyJSFloat64ArrayImpl = coreTypes.index
160+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSFloat64ArrayImpl' ),
161+ jsInt8ArrayFromDartInt8List = coreTypes.index.getTopLevelProcedure (
162+ 'dart:_js_helper' , 'jsInt8ArrayFromDartInt8List' ),
163+ jsUint8ArrayFromDartUint8List = coreTypes.index.getTopLevelProcedure (
164+ 'dart:_js_helper' , 'jsUint8ArrayFromDartUint8List' ),
165+ jsUint8ClampedArrayFromDartUint8ClampedList = coreTypes.index
166+ .getTopLevelProcedure ('dart:_js_helper' ,
167+ 'jsUint8ClampedArrayFromDartUint8ClampedList' ),
168+ jsInt16ArrayFromDartInt16List = coreTypes.index.getTopLevelProcedure (
169+ 'dart:_js_helper' , 'jsInt16ArrayFromDartInt16List' ),
170+ jsUint16ArrayFromDartUint16List = coreTypes.index.getTopLevelProcedure (
171+ 'dart:_js_helper' , 'jsUint16ArrayFromDartUint16List' ),
172+ jsInt32ArrayFromDartInt32List = coreTypes.index.getTopLevelProcedure (
173+ 'dart:_js_helper' , 'jsInt32ArrayFromDartInt32List' ),
174+ jsUint32ArrayFromDartUint32List = coreTypes.index.getTopLevelProcedure (
175+ 'dart:_js_helper' , 'jsUint32ArrayFromDartUint32List' ),
176+ jsFloat32ArrayFromDartFloat32List = coreTypes.index
177+ .getTopLevelProcedure (
178+ 'dart:_js_helper' , 'jsFloat32ArrayFromDartFloat32List' ),
179+ jsFloat64ArrayFromDartFloat64List = coreTypes.index
180+ .getTopLevelProcedure (
181+ 'dart:_js_helper' , 'jsFloat64ArrayFromDartFloat64List' ),
182+ jsifyJSDataViewImpl = coreTypes.index
183+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSDataViewImpl' ),
184+ jsifyByteData = coreTypes.index
185+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyByteData' ),
186+ jsifyRawList = coreTypes.index
187+ .getTopLevelProcedure ('dart:_js_helper' , '_jsifyRawList' ),
188+ jsifyJSArrayBufferImpl = coreTypes.index
189+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyJSArrayBufferImpl' ),
190+ jsArrayBufferFromDartByteBuffer = coreTypes.index.getTopLevelProcedure (
191+ 'dart:_js_helper' , 'jsArrayBufferFromDartByteBuffer' ),
192+ jsifyFunction = coreTypes.index
193+ .getTopLevelProcedure ('dart:_js_helper' , 'jsifyFunction' ),
194+ jsInt8ArrayImplClass =
195+ coreTypes.index.getClass ('dart:_js_types' , 'JSInt8ArrayImpl' ),
196+ jsUint8ArrayImplClass =
197+ coreTypes.index.getClass ('dart:_js_types' , 'JSUint8ArrayImpl' ),
198+ jsUint8ClampedArrayImplClass = coreTypes.index
199+ .getClass ('dart:_js_types' , 'JSUint8ClampedArrayImpl' ),
200+ jsInt16ArrayImplClass =
201+ coreTypes.index.getClass ('dart:_js_types' , 'JSInt16ArrayImpl' ),
202+ jsUint16ArrayImplClass =
203+ coreTypes.index.getClass ('dart:_js_types' , 'JSUint16ArrayImpl' ),
204+ jsInt32ArrayImplClass =
205+ coreTypes.index.getClass ('dart:_js_types' , 'JSInt32ArrayImpl' ),
206+ jsUint32ArrayImplClass =
207+ coreTypes.index.getClass ('dart:_js_types' , 'JSUint32ArrayImpl' ),
208+ jsFloat32ArrayImplClass =
209+ coreTypes.index.getClass ('dart:_js_types' , 'JSFloat32ArrayImpl' ),
210+ jsFloat64ArrayImplClass =
211+ coreTypes.index.getClass ('dart:_js_types' , 'JSFloat64ArrayImpl' ),
212+ int8ListClass = coreTypes.index.getClass ('dart:typed_data' , 'Int8List' ),
213+ uint8ListClass =
214+ coreTypes.index.getClass ('dart:typed_data' , 'Uint8List' ),
215+ uint8ClampedListClass =
216+ coreTypes.index.getClass ('dart:typed_data' , 'Uint8ClampedList' ),
217+ int16ListClass =
218+ coreTypes.index.getClass ('dart:typed_data' , 'Int16List' ),
219+ uint16ListClass =
220+ coreTypes.index.getClass ('dart:typed_data' , 'Uint16List' ),
221+ int32ListClass =
222+ coreTypes.index.getClass ('dart:typed_data' , 'Int32List' ),
223+ uint32ListClass =
224+ coreTypes.index.getClass ('dart:typed_data' , 'Uint32List' ),
225+ float32ListClass =
226+ coreTypes.index.getClass ('dart:typed_data' , 'Float32List' ),
227+ float64ListClass =
228+ coreTypes.index.getClass ('dart:typed_data' , 'Float64List' ),
229+ jsDataViewImplClass =
230+ coreTypes.index.getClass ('dart:_js_types' , 'JSDataViewImpl' ),
231+ byteDataClass = coreTypes.index.getClass ('dart:typed_data' , 'ByteData' ),
232+ byteBufferClass =
233+ coreTypes.index.getClass ('dart:typed_data' , 'ByteBuffer' ),
234+ jsArrayBufferImplClass =
235+ coreTypes.index.getClass ('dart:_js_types' , 'JSArrayBufferImpl' );
71236
72237 DartType get nonNullableObjectType =>
73238 coreTypes.objectRawType (Nullability .nonNullable);
@@ -81,13 +246,10 @@ class CoreTypesUtil {
81246 DartType get nullableWasmExternRefType =>
82247 wasmExternRefClass.getThisType (coreTypes, Nullability .nullable);
83248
84- Procedure jsifyTarget (DartType type) =>
85- isJSValueType (type) ? jsValueUnboxTarget : jsifyRawTarget;
86-
87249 /// Whether [type] erases to a `JSValue` or `JSValue?` .
88250 bool isJSValueType (DartType type) =>
89- _extensionIndex .isStaticInteropType (type) ||
90- _extensionIndex .isExternalDartReferenceType (type);
251+ extensionIndex .isStaticInteropType (type) ||
252+ extensionIndex .isExternalDartReferenceType (type);
91253
92254 void annotateProcedure (
93255 Procedure procedure, String pragmaOptionString, AnnotationType type) {
@@ -215,3 +377,80 @@ InstanceInvocation invokeMethod(VariableDeclaration receiver, Procedure target,
215377
216378bool parametersNeedParens (List <String > parameters) =>
217379 parameters.isEmpty || parameters.length > 1 ;
380+
381+ Expression jsifyValue (VariableDeclaration variable, CoreTypesUtil coreTypes,
382+ TypeEnvironment typeEnv) {
383+ final Procedure conversionProcedure;
384+
385+ if (coreTypes.extensionIndex.isStaticInteropType (variable.type) ||
386+ coreTypes.extensionIndex.isExternalDartReferenceType (variable.type)) {
387+ conversionProcedure = coreTypes.jsValueUnboxTarget;
388+ } else {
389+ conversionProcedure =
390+ _conversionProcedure (variable.type, coreTypes, typeEnv);
391+ }
392+
393+ final conversion =
394+ StaticInvocation (conversionProcedure, Arguments ([VariableGet (variable)]));
395+
396+ if (variable.type.isPotentiallyNullable) {
397+ return ConditionalExpression (
398+ EqualsNull (VariableGet (variable)),
399+ StaticGet (coreTypes.wasmExternRefNullRef),
400+ conversion,
401+ InterfaceType (coreTypes.wasmExternRefClass, Nullability .nullable));
402+ } else {
403+ return conversion;
404+ }
405+ }
406+
407+ Procedure _conversionProcedure (
408+ DartType type, CoreTypesUtil util, TypeEnvironment typeEnv) {
409+ // NB. We rely on iteration ordering being insertion order to handle subtypes
410+ // before supertypes to convert as `int` and `double` before `num`.
411+ final Map <Class , Procedure > converterMap = {
412+ util.coreTypes.boolClass: util.toJSBoolean,
413+ util.coreTypes.intClass: util.jsifyInt,
414+ util.coreTypes.doubleClass: util.toJSNumber,
415+ util.coreTypes.numClass: util.jsifyNum,
416+ util.jsValueClass: util.jsifyJSValue,
417+ util.coreTypes.stringClass: util.jsifyString,
418+ util.jsInt8ArrayImplClass: util.jsifyJSInt8ArrayImpl,
419+ util.jsUint8ArrayImplClass: util.jsifyJSUint8ArrayImpl,
420+ util.jsUint8ClampedArrayImplClass: util.jsifyJSUint8ClampedArrayImpl,
421+ util.jsInt16ArrayImplClass: util.jsifyJSInt16ArrayImpl,
422+ util.jsUint16ArrayImplClass: util.jsifyJSUint16ArrayImpl,
423+ util.jsInt32ArrayImplClass: util.jsifyJSInt32ArrayImpl,
424+ util.jsUint32ArrayImplClass: util.jsifyJSUint32ArrayImpl,
425+ util.jsFloat32ArrayImplClass: util.jsifyJSFloat32ArrayImpl,
426+ util.jsFloat64ArrayImplClass: util.jsifyJSFloat64ArrayImpl,
427+ util.int8ListClass: util.jsInt8ArrayFromDartInt8List,
428+ util.uint8ListClass: util.jsUint8ArrayFromDartUint8List,
429+ util.uint8ClampedListClass:
430+ util.jsUint8ClampedArrayFromDartUint8ClampedList,
431+ util.int16ListClass: util.jsInt16ArrayFromDartInt16List,
432+ util.uint16ListClass: util.jsUint16ArrayFromDartUint16List,
433+ util.int32ListClass: util.jsInt32ArrayFromDartInt32List,
434+ util.uint32ListClass: util.jsUint32ArrayFromDartUint32List,
435+ util.float32ListClass: util.jsFloat32ArrayFromDartFloat32List,
436+ util.float64ListClass: util.jsFloat64ArrayFromDartFloat64List,
437+ util.jsDataViewImplClass: util.jsifyJSDataViewImpl,
438+ util.byteDataClass: util.jsifyByteData,
439+ util.coreTypes.listClass: util.jsifyRawList,
440+ util.jsArrayBufferImplClass: util.jsifyJSArrayBufferImpl,
441+ util.byteBufferClass: util.jsArrayBufferFromDartByteBuffer,
442+ util.coreTypes.functionClass: util.jsifyFunction,
443+ };
444+
445+ for (final entry in converterMap.entries) {
446+ if (typeEnv.isSubtypeOf (
447+ type,
448+ InterfaceType (entry.key, Nullability .nonNullable),
449+ SubtypeCheckMode .withNullabilities)) {
450+ return entry.value;
451+ }
452+ }
453+
454+ // `dynamic` or `Object?`, convert based on runtime type.
455+ return util.jsifyRawTarget;
456+ }
0 commit comments