blob: 65ead7722249451de2e703693daf766a8aa7e12e [file] [log] [blame]
// Copyright (c) 2017, 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.desugar;
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
// Source code representing synthesized lambda constructor.
import com.android.tools.r8.ir.code.ValueType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import org.objectweb.asm.Opcodes;
final class LambdaConstructorSourceCode {
public static CfCode build(LambdaClass lambda) {
int maxStack = 1;
ImmutableList<CfTryCatch> tryCatchRanges = ImmutableList.of();
ImmutableList<CfCode.LocalVariableInfo> localVariables = ImmutableList.of();
Builder<CfInstruction> instructions = ImmutableList.builder();
// Super constructor call (always java.lang.Object.<init>()).
instructions.add(new CfLoad(ValueType.OBJECT, 0));
instructions.add(
new CfInvoke(
Opcodes.INVOKESPECIAL,
lambda.appView.dexItemFactory().objectMembers.constructor,
false));
// Assign capture fields.
DexType[] capturedTypes = lambda.descriptor.captures.values;
int maxLocals = 1;
for (int i = 0; i < capturedTypes.length; i++) {
DexField field = lambda.getCaptureField(i);
assert field.type == capturedTypes[i];
ValueType type = ValueType.fromDexType(field.type);
instructions.add(new CfLoad(ValueType.OBJECT, 0));
instructions.add(new CfLoad(type, maxLocals));
instructions.add(new CfFieldInstruction(Opcodes.PUTFIELD, field, field));
maxLocals += type.requiredRegisters();
maxStack += type.requiredRegisters();
}
// Final return.
instructions.add(new CfReturnVoid());
return new CfCode(
lambda.constructor.holder,
maxStack,
maxLocals,
instructions.build(),
tryCatchRanges,
localVariables);
}
}