blob: 0eec9af7bbae71e9baae8bc6d970f2c2d2c6c740 [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize.lambda.kotlin;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.synthetic.SyntheticSourceCode;
import com.google.common.collect.Lists;
import java.util.List;
final class ClassInitializerSourceCode extends SyntheticSourceCode {
private final DexItemFactory factory;
private final KotlinLambdaGroup group;
ClassInitializerSourceCode(
DexMethod method, DexItemFactory factory, KotlinLambdaGroup group, Position callerPosition) {
super(null, method, callerPosition);
assert method.proto.returnType == factory.voidType;
assert method.proto.parameters == DexTypeList.empty();
this.factory = factory;
this.group = group;
}
@Override
protected void prepareInstructions() {
DexType groupClassType = group.getGroupClassType();
DexMethod lambdaConstructorMethod = factory.createMethod(groupClassType,
factory.createProto(factory.voidType, factory.intType), factory.constructorMethodName);
int instance = nextRegister(ValueType.OBJECT);
int lambdaId = nextRegister(ValueType.INT);
List<ValueType> argTypes = Lists.newArrayList(ValueType.OBJECT, ValueType.INT);
List<Integer> argRegisters = Lists.newArrayList(instance, lambdaId);
group.forEachLambda(
info -> {
DexType lambda = info.clazz.type;
if (group.isSingletonLambda(lambda)) {
int id = group.lambdaId(lambda);
add(builder -> builder.addNewInstance(instance, groupClassType));
add(builder -> builder.addConst(TypeElement.getInt(), lambdaId, id));
add(
builder ->
builder.addInvoke(
Type.DIRECT,
lambdaConstructorMethod,
lambdaConstructorMethod.proto,
argTypes,
argRegisters,
false /* isInterface*/));
add(
builder ->
builder.addStaticPut(instance, group.getSingletonInstanceField(factory, id)));
}
});
assert this.nextInstructionIndex() > 0 : "no single field initialized";
add(IRBuilder::addReturn);
}
}