@@ -1285,8 +1285,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
12851285 throw 'Expected constant, got ${expr .runtimeType }' ;
12861286 }
12871287
1288- void _genPushConstExpr (Expression expr) {
1289- final constant = _getConstant (expr);
1288+ void _genPushConstant (Constant constant) {
12901289 if (constant is NullConstant ) {
12911290 asm.emitPushNull ();
12921291 } else if (constant is BoolConstant ) {
@@ -1298,6 +1297,20 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
12981297 }
12991298 }
13001299
1300+ void _genPushConstExpr (Expression expr) {
1301+ if (expr is ConstantExpression ) {
1302+ _genPushConstant (expr.constant);
1303+ } else if (expr is NullLiteral ) {
1304+ asm.emitPushNull ();
1305+ } else if (expr is BoolLiteral ) {
1306+ _genPushBool (expr.value);
1307+ } else if (expr is IntLiteral ) {
1308+ _genPushInt (expr.value);
1309+ } else {
1310+ _genPushConstant (_getConstant (expr));
1311+ }
1312+ }
1313+
13011314 void _genReturnTOS ([int yieldSourcePosition = null ]) {
13021315 if (options.causalAsyncStacks &&
13031316 parentFunction != null &&
@@ -1340,6 +1353,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
13401353 } else {
13411354 asm.emitDirectCall (cpIndex, totalArgCount);
13421355 }
1356+ if (inferredTypeMetadata != null && node != null ) {
1357+ _replaceWithConstantValue (node);
1358+ }
13431359 }
13441360
13451361 void _genDirectCallWithArgs (Member target, Arguments args,
@@ -1794,7 +1810,20 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
17941810 } else {
17951811 inferredTypesAttribute.add (NullConstant ());
17961812 }
1797- inferredTypesAttribute.add (IntConstant (md.flags));
1813+ // Inferred constant values are handled in bytecode generator
1814+ // (_replaceWithConstantValue, _initConstantParameters) and
1815+ // not propagated to VM.
1816+ final flags = md.flags & ~ InferredType .flagConstant;
1817+ inferredTypesAttribute.add (IntConstant (flags));
1818+ }
1819+
1820+ void _replaceWithConstantValue (TreeNode node) {
1821+ final InferredType md = inferredTypeMetadata[node];
1822+ if (md == null || md.constantValue == null || asm.isUnreachable) {
1823+ return ;
1824+ }
1825+ asm.emitDrop1 ();
1826+ _genPushConstant (md.constantValue);
17981827 }
17991828
18001829 // Generate additional code for 'operator ==' to handle nulls.
@@ -2030,6 +2059,10 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
20302059 asm.emitPopLocal (locals.functionTypeArgsVarIndexInFrame);
20312060 }
20322061 }
2062+
2063+ if (inferredTypeMetadata != null && function != null ) {
2064+ _initConstantParameters (function);
2065+ }
20332066 }
20342067
20352068 void _handleDelayedTypeArguments (Label doneCheckingTypeArguments) {
@@ -2073,6 +2106,21 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
20732106 asm.emitPopLocal (locals.functionTypeArgsVarIndexInFrame);
20742107 }
20752108
2109+ void _initConstantParameters (FunctionNode function) {
2110+ function.positionalParameters.forEach (_initParameterIfConstant);
2111+ locals.sortedNamedParameters.forEach (_initParameterIfConstant);
2112+ }
2113+
2114+ void _initParameterIfConstant (VariableDeclaration variable) {
2115+ final md = inferredTypeMetadata[variable];
2116+ if (md != null && md.constantValue != null ) {
2117+ _genPushConstant (md.constantValue);
2118+ asm.emitPopLocal (locals.isCaptured (variable)
2119+ ? locals.getOriginalParamSlotIndex (variable)
2120+ : locals.getVarIndexInFrame (variable));
2121+ }
2122+ }
2123+
20762124 void _setupInitialContext (FunctionNode function) {
20772125 _allocateContextIfNeeded ();
20782126
@@ -3279,25 +3327,32 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
32793327 _appendInferredType (node, asm.offset);
32803328 }
32813329
3330+ bool generated = false ;
32823331 if (invocationKind != InvocationKind .getter && ! isDynamic && ! isUnchecked) {
32833332 final staticReceiverType = getStaticType (receiver, staticTypeContext);
32843333 if (isInstantiatedInterfaceCall (interfaceTarget, staticReceiverType)) {
32853334 final callCpIndex = cp.addInstantiatedInterfaceCall (
32863335 invocationKind, interfaceTarget, argDesc, staticReceiverType);
32873336 asm.emitInstantiatedInterfaceCall (callCpIndex, totalArgCount);
3288- return ;
3337+ generated = true ;
32893338 }
32903339 }
32913340
3292- final callCpIndex = cp.addInstanceCall (
3293- invocationKind, interfaceTarget, targetName, argDesc);
3294- if (isDynamic) {
3295- assert (! isUnchecked);
3296- asm.emitDynamicCall (callCpIndex, totalArgCount);
3297- } else if (isUnchecked) {
3298- asm.emitUncheckedInterfaceCall (callCpIndex, totalArgCount);
3299- } else {
3300- asm.emitInterfaceCall (callCpIndex, totalArgCount);
3341+ if (! generated) {
3342+ final callCpIndex = cp.addInstanceCall (
3343+ invocationKind, interfaceTarget, targetName, argDesc);
3344+ if (isDynamic) {
3345+ assert (! isUnchecked);
3346+ asm.emitDynamicCall (callCpIndex, totalArgCount);
3347+ } else if (isUnchecked) {
3348+ asm.emitUncheckedInterfaceCall (callCpIndex, totalArgCount);
3349+ } else {
3350+ asm.emitInterfaceCall (callCpIndex, totalArgCount);
3351+ }
3352+ }
3353+
3354+ if (inferredTypeMetadata != null && node != null ) {
3355+ _replaceWithConstantValue (node);
33013356 }
33023357 }
33033358
@@ -3619,6 +3674,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
36193674 if (target.isConst) {
36203675 _genPushConstExpr (target.initializer);
36213676 } else if (! _needsGetter (target)) {
3677+ if (inferredTypeMetadata != null ) {
3678+ final InferredType md = inferredTypeMetadata[node];
3679+ if (md != null && md.constantValue != null ) {
3680+ _genPushConstant (md.constantValue);
3681+ return ;
3682+ }
3683+ }
36223684 asm.emitLoadStatic (cp.addStaticField (target));
36233685 } else {
36243686 _genDirectCall (target, objectTable.getArgDescHandle (0 ), 0 ,
@@ -4676,7 +4738,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
46764738
46774739 @override
46784740 visitConstantExpression (ConstantExpression node) {
4679- _genPushConstExpr (node);
4741+ _genPushConstant (node.constant );
46804742 }
46814743}
46824744
0 commit comments