Allow Kotlin generated bytecode to be compiled.
The Kotlin compiler inserts locals information for locals that are
unused in the code. This change allows us to compile the code.
It does *not* insert instructions that allocate a register for
these unused locals. Debug locals information is not emitted
at the end for these unused locals.
We should not let debug information influende our code generation.
We cannot trust debug information as it could be completely
invalid. We need to figure out how these variables are used for
Kotlin debugging and see what we can do to support full Kotlin
debugging.
R=shertz@google.com, zerny@google.com
Change-Id: I07446e96227e702d088433e69a7e0ec653e91759
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarState.java b/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
index a6b1f2c..2a3e431 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarState.java
@@ -339,12 +339,19 @@
}
private Local setLocalInfo(int index, Type type, DebugLocalInfo info) {
- return setLocalInfoForRegister(getLocalRegister(index, type), type, info);
+ return setLocalInfoForRegister(getLocalRegister(index, type), info);
}
- private Local setLocalInfoForRegister(int register, Type type, DebugLocalInfo info) {
+ private Local setLocalInfoForRegister(int register, DebugLocalInfo info) {
Local existingLocal = getLocalForRegister(register);
- Local local = new Local(existingLocal.slot, info);
+ // TODO(ager, zerny): Kotlin debug information contains locals that are not referenced.
+ // That seems broken and we currently do not retain that debug information because
+ // we do not let locals debug information influence code generation. Debug information can
+ // be completely malformed, so we shouldn't let it influence code generation. However, we
+ // need to deal with these unused locals in the debug information. For now we
+ // use a null type for the slot, but we should reconsider that.
+ Slot slot = existingLocal != null ? existingLocal.slot : new Slot(register, null);
+ Local local = new Local(slot, info);
locals[register] = local;
return local;
}