@@ -56,6 +56,8 @@ import 'source_positions.dart' show LineStarts, SourcePositions;
56
56
import '../metadata/bytecode.dart' ;
57
57
import '../metadata/direct_call.dart'
58
58
show DirectCallMetadata, DirectCallMetadataRepository;
59
+ import '../metadata/inferred_type.dart'
60
+ show InferredType, InferredTypeMetadataRepository;
59
61
import '../metadata/procedure_attributes.dart'
60
62
show ProcedureAttributesMetadata, ProcedureAttributesMetadataRepository;
61
63
@@ -126,6 +128,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
126
128
Map <TreeNode , DirectCallMetadata > directCallMetadata;
127
129
ProcedureAttributesMetadataRepository procedureAttributesMetadataRepository;
128
130
ProcedureAttributesMetadata procedureAttributesMetadata;
131
+ Map <TreeNode , InferredType > inferredTypeMetadata;
132
+ List <Constant > inferredTypesAttribute;
129
133
130
134
List <ClassDeclaration > classDeclarations;
131
135
List <FieldDeclaration > fieldDeclarations;
@@ -182,6 +186,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
182
186
183
187
procedureAttributesMetadataRepository =
184
188
component.metadata[ProcedureAttributesMetadataRepository .repositoryTag];
189
+
190
+ inferredTypeMetadata = component
191
+ .metadata[InferredTypeMetadataRepository .repositoryTag]? .mapping;
185
192
}
186
193
187
194
@override
@@ -410,17 +417,23 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
410
417
}
411
418
412
419
ObjectHandle getMemberAttributes (Member member) {
413
- if (procedureAttributesMetadata == null ) {
420
+ if (procedureAttributesMetadata == null && inferredTypesAttribute == null ) {
414
421
return null ;
415
422
}
416
- final procedureAttributes = procedureAttributesMetadataRepository
417
- .getBytecodeAttribute (procedureAttributesMetadata);
418
423
// List of pairs (tag, value).
419
- final attrs = ListConstant (const DynamicType (), < Constant > [
420
- StringConstant (ProcedureAttributesMetadataRepository .repositoryTag),
421
- procedureAttributes,
422
- ]);
423
- return objectTable.getHandle (attrs);
424
+ final attrs = < Constant > [];
425
+ if (procedureAttributesMetadata != null ) {
426
+ final attribute = procedureAttributesMetadataRepository
427
+ .getBytecodeAttribute (procedureAttributesMetadata);
428
+ attrs.add (
429
+ StringConstant (ProcedureAttributesMetadataRepository .repositoryTag));
430
+ attrs.add (attribute);
431
+ }
432
+ if (inferredTypesAttribute != null ) {
433
+ attrs.add (StringConstant (InferredTypeMetadataRepository .repositoryTag));
434
+ attrs.add (ListConstant (const DynamicType (), inferredTypesAttribute));
435
+ }
436
+ return objectTable.getHandle (ListConstant (const DynamicType (), attrs));
424
437
}
425
438
426
439
// Insert annotations for the function and its parameters into the annotations
@@ -1180,15 +1193,18 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1180
1193
bool isSet: false ,
1181
1194
bool isDynamicForwarder: false ,
1182
1195
bool isUnchecked: false ,
1183
- TreeNode context }) {
1196
+ TreeNode node }) {
1184
1197
assert (! isGet || ! isSet);
1185
1198
final kind = isGet
1186
1199
? InvocationKind .getter
1187
1200
: (isSet ? InvocationKind .setter : InvocationKind .method);
1188
1201
final cpIndex = cp.addDirectCall (kind, target, argDesc, isDynamicForwarder);
1189
1202
1190
1203
if (totalArgCount >= argumentsLimit) {
1191
- throw new TooManyArgumentsException (context.fileOffset);
1204
+ throw new TooManyArgumentsException (node.fileOffset);
1205
+ }
1206
+ if (inferredTypeMetadata != null && node != null ) {
1207
+ _appendInferredType (node, asm.offset);
1192
1208
}
1193
1209
if (isUnchecked) {
1194
1210
asm.emitUncheckedDirectCall (cpIndex, totalArgCount);
@@ -1201,7 +1217,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1201
1217
{bool hasReceiver: false ,
1202
1218
bool isFactory: false ,
1203
1219
bool isUnchecked: false ,
1204
- TreeNode context }) {
1220
+ TreeNode node }) {
1205
1221
final argDesc = objectTable.getArgDescHandleByArguments (args,
1206
1222
hasReceiver: hasReceiver, isFactory: isFactory);
1207
1223
@@ -1216,7 +1232,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1216
1232
}
1217
1233
1218
1234
_genDirectCall (target, argDesc, totalArgCount,
1219
- isUnchecked: isUnchecked, context : context );
1235
+ isUnchecked: isUnchecked, node : node );
1220
1236
}
1221
1237
1222
1238
void _genTypeArguments (List <DartType > typeArgs, {Class instantiatingClass}) {
@@ -1553,6 +1569,28 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1553
1569
procedureAttributesMetadata = procedureAttributesMetadataRepository != null
1554
1570
? procedureAttributesMetadataRepository.mapping[node]
1555
1571
: null ;
1572
+
1573
+ if (inferredTypeMetadata != null ) {
1574
+ if (node is Field ) {
1575
+ // Field type is at PC = -1.
1576
+ _appendInferredType (node, - 1 );
1577
+ } else if (enclosingFunction != null && hasCode) {
1578
+ assert (node is Procedure || node is Constructor );
1579
+ // Parameter types are at PC = -N,..,-1 where N - number of declared
1580
+ // (explicit) parameters.
1581
+ int i = - (enclosingFunction.positionalParameters.length +
1582
+ enclosingFunction.namedParameters.length);
1583
+ for (var v in enclosingFunction.positionalParameters) {
1584
+ _appendInferredType (v, i);
1585
+ ++ i;
1586
+ }
1587
+ for (var v in enclosingFunction.namedParameters) {
1588
+ _appendInferredType (v, i);
1589
+ ++ i;
1590
+ }
1591
+ }
1592
+ }
1593
+
1556
1594
if (! hasCode) {
1557
1595
return ;
1558
1596
}
@@ -1596,6 +1634,32 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1596
1634
_genEqualsOperatorNullHandling (node);
1597
1635
}
1598
1636
1637
+ void _appendInferredType (TreeNode node, int pc) {
1638
+ final InferredType md = inferredTypeMetadata[node];
1639
+ if (md == null ) {
1640
+ return ;
1641
+ }
1642
+ inferredTypesAttribute ?? = < Constant > [];
1643
+ // List of triplets (PC, concreteClass, flags).
1644
+ // Verify that PCs are monotonically increasing.
1645
+ assert (inferredTypesAttribute.isEmpty ||
1646
+ (inferredTypesAttribute[inferredTypesAttribute.length - 3 ]
1647
+ as IntConstant )
1648
+ .value <
1649
+ pc);
1650
+ inferredTypesAttribute.add (IntConstant (pc));
1651
+ Class concreteClass = md.concreteClass;
1652
+ // VM uses more specific function type and doesn't expect to
1653
+ // see inferred _Closure class.
1654
+ if (concreteClass != null && concreteClass != closureClass) {
1655
+ inferredTypesAttribute
1656
+ .add (TypeLiteralConstant (coreTypes.legacyRawType (concreteClass)));
1657
+ } else {
1658
+ inferredTypesAttribute.add (NullConstant ());
1659
+ }
1660
+ inferredTypesAttribute.add (IntConstant (md.flags));
1661
+ }
1662
+
1599
1663
// Generate additional code for 'operator ==' to handle nulls.
1600
1664
void _genEqualsOperatorNullHandling (Member member) {
1601
1665
if (member.name.name != '==' ||
@@ -1693,6 +1757,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
1693
1757
savedAssemblers = null ;
1694
1758
hasErrors = false ;
1695
1759
procedureAttributesMetadata = null ;
1760
+ inferredTypeMetadata = null ;
1761
+ inferredTypesAttribute = null ;
1696
1762
}
1697
1763
1698
1764
SourcePositions finalizeSourcePositions () {
@@ -2767,7 +2833,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
2767
2833
new Arguments (node.arguments.positional, named: node.arguments.named)
2768
2834
..parent = node;
2769
2835
_genArguments (null , args);
2770
- _genDirectCallWithArgs (node.target, args, hasReceiver: true , context : node);
2836
+ _genDirectCallWithArgs (node.target, args, hasReceiver: true , node : node);
2771
2837
asm.emitDrop1 ();
2772
2838
}
2773
2839
@@ -2777,7 +2843,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
2777
2843
_genArguments (node.receiver, args);
2778
2844
final target = node.target;
2779
2845
if (target is Procedure && ! target.isGetter && ! target.isSetter) {
2780
- _genDirectCallWithArgs (target, args, hasReceiver: true , context : node);
2846
+ _genDirectCallWithArgs (target, args, hasReceiver: true , node : node);
2781
2847
} else {
2782
2848
throw new UnsupportedOperationError (
2783
2849
'Unsupported DirectMethodInvocation with target ${target .runtimeType } $target ' );
@@ -2789,7 +2855,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
2789
2855
_generateNode (node.receiver);
2790
2856
final target = node.target;
2791
2857
if (target is Field || (target is Procedure && target.isGetter)) {
2792
- _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 , isGet: true );
2858
+ _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 ,
2859
+ isGet: true , node: node);
2793
2860
} else {
2794
2861
throw new UnsupportedOperationError (
2795
2862
'Unsupported DirectPropertyGet with ${target .runtimeType } $target ' );
@@ -2810,7 +2877,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
2810
2877
2811
2878
final target = node.target;
2812
2879
assert (target is Field || (target is Procedure && target.isSetter));
2813
- _genDirectCall (target, objectTable.getArgDescHandle (2 ), 2 , isSet: true );
2880
+ _genDirectCall (target, objectTable.getArgDescHandle (2 ), 2 ,
2881
+ isSet: true , node: node);
2814
2882
asm.emitDrop1 ();
2815
2883
2816
2884
if (hasResult) {
@@ -3031,7 +3099,14 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3031
3099
asm.emitSpecializedBytecode (opcode);
3032
3100
}
3033
3101
3102
+ bool _isUncheckedCall (
3103
+ Node node, Member interfaceTarget, Expression receiver) =>
3104
+ isUncheckedCall (interfaceTarget, receiver, typeEnvironment) ||
3105
+ (inferredTypeMetadata != null &&
3106
+ inferredTypeMetadata[node]? .skipCheck == true );
3107
+
3034
3108
void _genInstanceCall (
3109
+ Node node,
3035
3110
InvocationKind invocationKind,
3036
3111
Member interfaceTarget,
3037
3112
Name targetName,
@@ -3040,7 +3115,11 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3040
3115
ObjectHandle argDesc) {
3041
3116
final isDynamic = interfaceTarget == null ;
3042
3117
final isUnchecked = invocationKind != InvocationKind .getter &&
3043
- isUncheckedCall (interfaceTarget, receiver, typeEnvironment);
3118
+ _isUncheckedCall (node, interfaceTarget, receiver);
3119
+
3120
+ if (inferredTypeMetadata != null ) {
3121
+ _appendInferredType (node, asm.offset);
3122
+ }
3044
3123
3045
3124
if (invocationKind != InvocationKind .getter && ! isDynamic && ! isUnchecked) {
3046
3125
final staticReceiverType = getStaticType (receiver, typeEnvironment);
@@ -3118,11 +3197,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3118
3197
if (directCall != null ) {
3119
3198
final isDynamicForwarder = (interfaceTarget == null );
3120
3199
final isUnchecked =
3121
- isUncheckedCall ( interfaceTarget, node.receiver, typeEnvironment );
3200
+ _isUncheckedCall (node, interfaceTarget, node.receiver);
3122
3201
_genDirectCall (directCall.target, argDesc, totalArgCount,
3123
- isDynamicForwarder: isDynamicForwarder, isUnchecked: isUnchecked);
3202
+ isDynamicForwarder: isDynamicForwarder,
3203
+ isUnchecked: isUnchecked,
3204
+ node: node);
3124
3205
} else {
3125
- _genInstanceCall (InvocationKind .method, interfaceTarget, node.name,
3206
+ _genInstanceCall (node, InvocationKind .method, interfaceTarget, node.name,
3126
3207
node.receiver, totalArgCount, argDesc);
3127
3208
}
3128
3209
}
@@ -3142,10 +3223,10 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3142
3223
asm.emitCheckReceiverForNull (
3143
3224
cp.addSelectorName (node.name, InvocationKind .getter));
3144
3225
}
3145
- _genDirectCall (directCall.target, argDesc, 1 , isGet: true );
3226
+ _genDirectCall (directCall.target, argDesc, 1 , isGet: true , node : node );
3146
3227
} else {
3147
- _genInstanceCall (InvocationKind .getter, node.interfaceTarget, node.name ,
3148
- node.receiver, 1 , argDesc);
3228
+ _genInstanceCall (node, InvocationKind .getter, node.interfaceTarget,
3229
+ node.name, node. receiver, 1 , argDesc);
3149
3230
}
3150
3231
}
3151
3232
@@ -3178,14 +3259,15 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3178
3259
if (directCall != null ) {
3179
3260
final isDynamicForwarder = (node.interfaceTarget == null );
3180
3261
final isUnchecked =
3181
- isUncheckedCall (node.interfaceTarget, node.receiver, typeEnvironment );
3262
+ _isUncheckedCall (node, node .interfaceTarget, node.receiver);
3182
3263
_genDirectCall (directCall.target, argDesc, numArguments,
3183
3264
isSet: true ,
3184
3265
isDynamicForwarder: isDynamicForwarder,
3185
- isUnchecked: isUnchecked);
3266
+ isUnchecked: isUnchecked,
3267
+ node: node);
3186
3268
} else {
3187
- _genInstanceCall (InvocationKind .setter, node.interfaceTarget, node.name ,
3188
- node.receiver, numArguments, argDesc);
3269
+ _genInstanceCall (node, InvocationKind .setter, node.interfaceTarget,
3270
+ node.name, node. receiver, numArguments, argDesc);
3189
3271
}
3190
3272
3191
3273
asm.emitDrop1 ();
@@ -3214,7 +3296,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3214
3296
}
3215
3297
_genArguments (new ThisExpression (), args);
3216
3298
_genDirectCallWithArgs (target, args,
3217
- hasReceiver: true , isUnchecked: true , context : node);
3299
+ hasReceiver: true , isUnchecked: true , node : node);
3218
3300
}
3219
3301
3220
3302
@override
@@ -3228,7 +3310,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3228
3310
return ;
3229
3311
}
3230
3312
_genPushReceiver ();
3231
- _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 , isGet: true );
3313
+ _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 ,
3314
+ isGet: true , node: node);
3232
3315
}
3233
3316
3234
3317
@override
@@ -3252,7 +3335,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3252
3335
3253
3336
assert (target is Field || (target is Procedure && target.isSetter));
3254
3337
_genDirectCall (target, objectTable.getArgDescHandle (2 ), 2 ,
3255
- isSet: true , isUnchecked: true );
3338
+ isSet: true , isUnchecked: true , node : node );
3256
3339
}
3257
3340
3258
3341
asm.emitDrop1 ();
@@ -3321,11 +3404,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3321
3404
} else if (_hasTrivialInitializer (target)) {
3322
3405
asm.emitLoadStatic (cp.addStaticField (target));
3323
3406
} else {
3324
- _genDirectCall (target, objectTable.getArgDescHandle (0 ), 0 , isGet: true );
3407
+ _genDirectCall (target, objectTable.getArgDescHandle (0 ), 0 ,
3408
+ isGet: true , node: node);
3325
3409
}
3326
3410
} else if (target is Procedure ) {
3327
3411
if (target.isGetter) {
3328
- _genDirectCall (target, objectTable.getArgDescHandle (0 ), 0 , isGet: true );
3412
+ _genDirectCall (target, objectTable.getArgDescHandle (0 ), 0 ,
3413
+ isGet: true , node: node);
3329
3414
} else if (target.isFactory || target.isRedirectingFactoryConstructor) {
3330
3415
throw 'Unexpected target for StaticGet: factory $target ' ;
3331
3416
} else {
@@ -3367,7 +3452,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3367
3452
}
3368
3453
_genArguments (null , args);
3369
3454
_genDirectCallWithArgs (target, args,
3370
- isFactory: target.isFactory, context : node);
3455
+ isFactory: target.isFactory, node : node);
3371
3456
}
3372
3457
3373
3458
@override
@@ -3389,7 +3474,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
3389
3474
int cpIndex = cp.addStaticField (target);
3390
3475
asm.emitStoreStaticTOS (cpIndex);
3391
3476
} else {
3392
- _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 , isSet: true );
3477
+ _genDirectCall (target, objectTable.getArgDescHandle (1 ), 1 ,
3478
+ isSet: true , node: node);
3393
3479
asm.emitDrop1 ();
3394
3480
}
3395
3481
}
@@ -4242,7 +4328,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
4242
4328
final args = node.arguments;
4243
4329
assert (args.types.isEmpty);
4244
4330
_genArguments (new ThisExpression (), args);
4245
- _genDirectCallWithArgs (node.target, args, hasReceiver: true , context : node);
4331
+ _genDirectCallWithArgs (node.target, args, hasReceiver: true , node : node);
4246
4332
asm.emitDrop1 ();
4247
4333
}
4248
4334
@@ -4260,7 +4346,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
4260
4346
}
4261
4347
}
4262
4348
assert (target != null );
4263
- _genDirectCallWithArgs (target, args, hasReceiver: true , context : node);
4349
+ _genDirectCallWithArgs (target, args, hasReceiver: true , node : node);
4264
4350
asm.emitDrop1 ();
4265
4351
}
4266
4352
0 commit comments