| // Copyright (c) 2023, 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.lightir; |
| |
| import com.android.tools.r8.errors.Unimplemented; |
| import com.android.tools.r8.graph.DexCallSite; |
| import com.android.tools.r8.graph.DexField; |
| import com.android.tools.r8.graph.DexMethod; |
| import com.android.tools.r8.graph.DexMethodHandle; |
| import com.android.tools.r8.graph.DexProto; |
| import com.android.tools.r8.graph.DexReference; |
| import com.android.tools.r8.graph.DexString; |
| import com.android.tools.r8.graph.DexType; |
| import com.android.tools.r8.graph.UseRegistry; |
| import com.android.tools.r8.graph.UseRegistry.MethodHandleUse; |
| import com.android.tools.r8.graph.bytecodemetadata.BytecodeInstructionMetadata; |
| import com.android.tools.r8.ir.code.IfType; |
| import com.android.tools.r8.ir.code.NumericType; |
| import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo; |
| import java.util.List; |
| |
| public class LirUseRegistryCallback<EV> extends LirParsedInstructionCallback<EV> { |
| |
| private final UseRegistry registry; |
| private BytecodeInstructionMetadata currentMetadata; |
| |
| public LirUseRegistryCallback(LirCode<EV> code, UseRegistry registry) { |
| super(code); |
| this.registry = registry; |
| } |
| |
| public void setCurrentMetadata(BytecodeInstructionMetadata metadata) { |
| currentMetadata = metadata; |
| } |
| |
| @Override |
| public int getCurrentValueIndex() { |
| // The registry of instructions does not require knowledge of value indexes. |
| return 0; |
| } |
| |
| @Override |
| public void onInstruction() { |
| // TODO(b/225838009): Consider defining an abstract base class for the parsed exception so that |
| // missing a callback is a compile-time error. |
| boolean debug = false; |
| if (debug) { |
| throw new Unimplemented(); |
| } |
| } |
| |
| @Override |
| public void onFallthrough() { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onConstString(DexString string) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onThrow(EV exception) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onMoveException(DexType exceptionType) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onReturnVoid() { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onReturn(EV value) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onGoto(int blockIndex) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onPhi(List<EV> operands) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onConstNumber(NumericType type, long value) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onCmpInstruction(int opcode, EV leftValue, EV rightValue) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onIf(IfType ifKind, int blockIndex, EV valueIndex) { |
| // Nothing to register. |
| } |
| |
| @Override |
| public void onCheckCast(DexType type, EV value, boolean ignoreCompatRules) { |
| registry.registerCheckCast(type, ignoreCompatRules); |
| } |
| |
| @Override |
| public void onSafeCheckCast(DexType type, EV value) { |
| registry.registerSafeCheckCast(type); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public void onConstClass(DexType type, boolean ignoreCompatRules) { |
| registry.registerConstClass(type, null, ignoreCompatRules); |
| } |
| |
| @Override |
| public void onConstMethodHandle(DexMethodHandle methodHandle) { |
| registry.registerMethodHandle(methodHandle, MethodHandleUse.NOT_ARGUMENT_TO_LAMBDA_METAFACTORY); |
| } |
| |
| @Override |
| public void onConstMethodType(DexProto methodType) { |
| registry.registerProto(methodType); |
| } |
| |
| @Override |
| public void onDexItemBasedConstString( |
| DexReference item, NameComputationInfo<?> nameComputationInfo) { |
| if (nameComputationInfo.needsToRegisterReference()) { |
| assert item.isDexType(); |
| registry.registerTypeReference(item.asDexType()); |
| } |
| } |
| |
| @Override |
| public void onInitClass(DexType clazz) { |
| registry.registerInitClass(clazz); |
| } |
| |
| @Override |
| public void onInstanceGet(DexField field, EV object) { |
| registry.registerInstanceFieldReadWithMetadata(field, currentMetadata); |
| } |
| |
| @Override |
| public void onInstancePut(DexField field, EV object, EV value) { |
| registry.registerInstanceFieldWrite(field); |
| } |
| |
| @Override |
| public void onStaticGet(DexField field) { |
| registry.registerStaticFieldReadWithMetadata(field, currentMetadata); |
| } |
| |
| @Override |
| public void onStaticPut(DexField field, EV value) { |
| registry.registerStaticFieldWrite(field); |
| } |
| |
| @Override |
| public void onInstanceOf(DexType type, EV value) { |
| registry.registerInstanceOf(type); |
| } |
| |
| @Override |
| public void onInvokeCustom(DexCallSite callSite, List<EV> arguments) { |
| registry.registerCallSite(callSite); |
| } |
| |
| @Override |
| public void onInvokeDirect(DexMethod method, List<EV> arguments, boolean isInterface) { |
| registry.registerInvokeDirect(method); |
| } |
| |
| @Override |
| public void onInvokeInterface(DexMethod method, List<EV> arguments) { |
| registry.registerInvokeInterface(method); |
| } |
| |
| @Override |
| public void onInvokeStatic(DexMethod method, List<EV> arguments, boolean isInterface) { |
| registry.registerInvokeStatic(method); |
| } |
| |
| @Override |
| public void onInvokeSuper(DexMethod method, List<EV> arguments, boolean isInterface) { |
| registry.registerInvokeSuper(method); |
| } |
| |
| @Override |
| public void onInvokeVirtual(DexMethod method, List<EV> arguments) { |
| registry.registerInvokeVirtual(method); |
| } |
| |
| @Override |
| public void onInvokeMultiNewArray(DexType type, List<EV> arguments) { |
| registry.registerTypeReference(type); |
| } |
| |
| @Override |
| public void onNewArrayFilled(DexType type, List<EV> arguments) { |
| registry.registerTypeReference(type); |
| } |
| |
| @Override |
| public void onNewArrayEmpty(DexType type, EV size) { |
| registry.registerTypeReference(type); |
| } |
| |
| @Override |
| public void onNewInstance(DexType clazz) { |
| registry.registerNewInstance(clazz); |
| } |
| |
| @Override |
| public void onNewUnboxedEnumInstance(DexType type, int ordinal) { |
| registry.registerNewUnboxedEnumInstance(type); |
| } |
| |
| @Override |
| public void onConstResourceNumber(int value) { |
| registry.registerConstResourceNumber(value); |
| } |
| |
| @Override |
| public void onRecordFieldValues(DexField[] fields, List<EV> values) { |
| registry.registerRecordFieldValues(fields); |
| } |
| } |