blob: d1a4bf3a4ccb0e85085cd368a7db0919190c2b71 [file] [log] [blame]
// Copyright (c) 2022, 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.synthetic.apiconverter;
import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfGoto;
import com.android.tools.r8.cf.code.CfIf;
import com.android.tools.r8.cf.code.CfInstanceFieldRead;
import com.android.tools.r8.cf.code.CfInstanceOf;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.frame.FrameType;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.synthetic.SyntheticCfCodeProvider;
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.objectweb.asm.Opcodes;
public class EqualsCfCodeProvider extends SyntheticCfCodeProvider {
private final DexField wrapperField;
public EqualsCfCodeProvider(AppView<?> appView, DexType holder, DexField wrapperField) {
super(appView, holder);
this.wrapperField = wrapperField;
}
@Override
public CfCode generateCfCode() {
// return wrapperField.equals(
// other instanceof WrapperType ? ((WrapperType) other).wrapperField : other);
CfLabel label1 = new CfLabel();
CfLabel label2 = new CfLabel();
List<CfInstruction> instructions = new ArrayList<>();
instructions.add(new CfLoad(ValueType.OBJECT, 0));
instructions.add(new CfInstanceFieldRead(wrapperField));
instructions.add(new CfLoad(ValueType.OBJECT, 1));
DexType wrapperType = wrapperField.getHolderType();
instructions.add(new CfInstanceOf(wrapperType));
instructions.add(new CfIf(If.Type.EQ, ValueType.INT, label1));
instructions.add(new CfLoad(ValueType.OBJECT, 1));
instructions.add(new CfCheckCast(wrapperType));
instructions.add(new CfInstanceFieldRead(wrapperField));
instructions.add(new CfGoto(label2));
instructions.add(label1);
instructions.add(
new CfFrame(
new Int2ObjectAVLTreeMap<>(
new int[] {0, 1},
new FrameType[] {
FrameType.initialized(wrapperType),
FrameType.initialized(appView.dexItemFactory().objectType)
}),
new ArrayDeque<>(Arrays.asList(FrameType.initialized(wrapperType)))));
instructions.add(new CfLoad(ValueType.OBJECT, 1));
instructions.add(label2);
instructions.add(
new CfFrame(
new Int2ObjectAVLTreeMap<>(
new int[] {0, 1},
new FrameType[] {
FrameType.initialized(wrapperType),
FrameType.initialized(appView.dexItemFactory().objectType)
}),
new ArrayDeque<>(
Arrays.asList(
FrameType.initialized(wrapperType),
FrameType.initialized(appView.dexItemFactory().objectType)))));
instructions.add(
new CfInvoke(Opcodes.INVOKEVIRTUAL, appView.dexItemFactory().objectMembers.equals, false));
instructions.add(new CfReturn(ValueType.INT));
return standardCfCodeFromInstructions(instructions);
}
}