blob: 4a12b2b0560c6f399c3ce6260d7af01cc2f42ace [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.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.conversion.IRBuilder;
import java.util.Collections;
// Source code representing synthesized lambda constructor.
final class LambdaConstructorSourceCode extends SynthesizedLambdaSourceCode {
LambdaConstructorSourceCode(LambdaClass lambda, Position callerPosition) {
super(lambda, lambda.constructor, callerPosition);
}
@Override
protected void prepareInstructions() {
// Super constructor call (always java.lang.Object.<init>()).
DexMethod objectInitMethod = lambda.rewriter.objectInitMethod;
add(
builder -> {
assert builder.getReceiverValue() != null;
builder.addInvoke(
Invoke.Type.DIRECT,
objectInitMethod,
objectInitMethod.proto,
Collections.singletonList(builder.getReceiverValue()),
false /* isInterface */);
});
// Assign capture fields.
DexType[] capturedTypes = captures();
int capturedValues = capturedTypes.length;
if (capturedValues > 0) {
for (int i = 0; i < capturedValues; i++) {
DexField field = lambda.getCaptureField(i);
int idx = i;
add(builder -> builder.addInstancePut(getParamRegister(idx), getReceiverRegister(), field));
}
}
// Final return.
add(IRBuilder::addReturn);
}
@Override
public int hashCode() {
// We want all zero-parameter constructor source code instances to
// be treated as equal, since it only has one call to super constructor,
// which is always java.lang.Object.<init>().
return captures().length == 0
? System.identityHashCode(lambda.rewriter.objectInitMethod) : super.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LambdaConstructorSourceCode)) {
return false;
}
if (captures().length == 0) {
// See comment in hashCode().
return ((LambdaConstructorSourceCode) obj).captures().length == 0;
}
return super.equals(obj);
}
}