Pseudocode: Generate fake values for Unit/Nothing-typed expressions

This commit is contained in:
Alexey Sedunov
2014-07-23 12:56:21 +04:00
parent 2d3ac9109b
commit 77bbf8f73b
72 changed files with 851 additions and 592 deletions
@@ -98,6 +98,8 @@ public interface JetControlFlowBuilder {
@Nullable
PseudoValue getBoundValue(@Nullable JetElement element);
void bindValue(@NotNull PseudoValue value, @NotNull JetElement element);
@NotNull
PseudoValue newValue(@Nullable JetElement element);
void loadUnit(@NotNull JetExpression expression);
@@ -288,6 +288,12 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
getDelegateBuilder().bindValue(value, element);
}
@NotNull
@Override
public PseudoValue newValue(@Nullable JetElement element) {
return getDelegateBuilder().newValue(element);
}
@Override
public void enterLexicalScope(@NotNull JetElement element) {
getDelegateBuilder().enterLexicalScope(element);
@@ -22,7 +22,6 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.SmartFMap;
import com.intellij.util.containers.ContainerUtil;
import jet.runtime.typeinfo.JetValueParameter;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.KotlinPackage;
@@ -235,12 +234,20 @@ public class JetControlFlowProcessor {
}
private void copyValue(@Nullable JetElement from, @NotNull JetElement to) {
PseudoValue value = builder.getBoundValue(from);
PseudoValue value = getBoundOrUnreachableValue(from);
if (value != null) {
builder.bindValue(value, to);
}
}
@Nullable
private PseudoValue getBoundOrUnreachableValue(@Nullable JetElement element) {
if (element == null) return null;
PseudoValue value = builder.getBoundValue(element);
return value != null || element instanceof JetDeclaration ? value : builder.newValue(element);
}
private List<PseudoValue> elementsToValues(List<? extends JetElement> from) {
if (from.isEmpty()) return Collections.emptyList();
return KotlinPackage.filterNotNull(
@@ -249,7 +256,7 @@ public class JetControlFlowProcessor {
new Function1<JetElement, PseudoValue>() {
@Override
public PseudoValue invoke(JetElement element) {
return builder.getBoundValue(element);
return getBoundOrUnreachableValue(element);
}
}
)
@@ -427,7 +434,7 @@ public class JetControlFlowProcessor {
@Override
public PseudoValue invoke() {
generateInstructions(expression);
return builder.getBoundValue(expression);
return getBoundOrUnreachableValue(expression);
}
};
}
@@ -1234,7 +1241,7 @@ public class JetControlFlowProcessor {
JetExpression left = expression.getLeft();
if (operationType == JetTokens.COLON || operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) {
generateInstructions(left);
if (builder.getBoundValue(left) != null) {
if (getBoundOrUnreachableValue(left) != null) {
createNonSyntheticValue(expression, MagicKind.CAST, left);
}
}
@@ -1428,7 +1435,8 @@ public class JetControlFlowProcessor {
List<PseudoValue> arguments = ContainerUtil.createMaybeSingletonList(builder.getBoundValue(specifier.getDelegateExpression()));
JetType jetType = trace.get(BindingContext.TYPE, specifier.getTypeReference());
TypePredicate expectedTypePredicate = jetType != null ? PseudocodePackage.getSubtypesPredicate(jetType) : AllTypes.INSTANCE$;
builder.magic(specifier, null, arguments, PseudocodePackage.expectedTypeFor(expectedTypePredicate, arguments), MagicKind.VALUE_CONSUMER);
builder.magic(specifier, null, arguments, PseudocodePackage.expectedTypeFor(expectedTypePredicate, arguments),
MagicKind.VALUE_CONSUMER);
}
@Override
@@ -1539,7 +1547,7 @@ public class JetControlFlowProcessor {
generateInstructions(expression);
}
PseudoValue receiverPseudoValue = builder.getBoundValue(expression);
PseudoValue receiverPseudoValue = getBoundOrUnreachableValue(expression);
if (receiverPseudoValue != null) {
receiverValues = receiverValues.plus(receiverPseudoValue, receiver);
}
@@ -1578,7 +1586,7 @@ public class JetControlFlowProcessor {
generateInstructions(expression);
}
PseudoValue argValue = builder.getBoundValue(expression);
PseudoValue argValue = getBoundOrUnreachableValue(expression);
if (argValue != null) {
parameterValues = parameterValues.plus(argValue, parameterDescriptor);
}
@@ -106,7 +106,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private final PseudoValueFactory valueFactory = new PseudoValueFactoryImpl() {
@NotNull
@Override
public PseudoValue newValue(@Nullable JetElement element, @NotNull InstructionWithValue instruction) {
public PseudoValue newValue(@Nullable JetElement element, @Nullable InstructionWithValue instruction) {
PseudoValue value = super.newValue(element, instruction);
if (element != null) {
bindValue(value, element);
@@ -283,6 +283,12 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
pseudocode.bindElementToValue(element, value);
}
@NotNull
@Override
public PseudoValue newValue(@Nullable JetElement element) {
return valueFactory.newValue(element, null);
}
@Override
public void returnValue(@NotNull JetExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull JetElement subroutine) {
Label exitPoint = getExitPoint(subroutine);
@@ -22,9 +22,9 @@ import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.InstructionWithVa
public trait PseudoValue {
public val debugName: String
public val element: JetElement?
public val createdAt: InstructionWithValue
public val createdAt: InstructionWithValue?
}
public trait PseudoValueFactory {
public fun newValue(element: JetElement?, instruction: InstructionWithValue): PseudoValue
public fun newValue(element: JetElement?, instruction: InstructionWithValue?): PseudoValue
}
@@ -22,7 +22,7 @@ import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.InstructionWithVa
class PseudoValueImpl(
override val debugName: String,
override val element: JetElement?,
override val createdAt: InstructionWithValue
override val createdAt: InstructionWithValue?
) : PseudoValue {
override fun toString(): String = debugName
}
@@ -30,7 +30,7 @@ class PseudoValueImpl(
open class PseudoValueFactoryImpl: PseudoValueFactory {
private var lastIndex: Int = 0
override fun newValue(element: JetElement?, instruction: InstructionWithValue): PseudoValue {
return PseudoValueImpl("<v${lastIndex++}>", element, instruction)
override fun newValue(element: JetElement?, instruction: InstructionWithValue?): PseudoValue {
return PseudoValueImpl((instruction?.let { "" } ?: "!") + "<v${lastIndex++}>", element, instruction)
}
}
@@ -54,7 +54,9 @@ fun getReceiverTypePredicate(resolvedCall: ResolvedCall<*>, receiverValue: Recei
}
fun getExpectedTypePredicate(value: PseudoValue, bindingContext: BindingContext): TypePredicate {
val pseudocode = value.createdAt.owner
val pseudocode = value.createdAt?.owner
if (pseudocode == null) return AllTypes
val typePredicates = LinkedHashSet<TypePredicate?>()
fun addSubtypesOf(jetType: JetType?) = typePredicates.add(jetType?.getSubtypesPredicate())
@@ -66,7 +68,7 @@ fun getExpectedTypePredicate(value: PseudoValue, bindingContext: BindingContext)
val returnElement = it.element
val functionDescriptor = when(returnElement) {
is JetReturnExpression -> returnElement.getTargetFunctionDescriptor(bindingContext)
else -> bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, value.createdAt.owner.getCorrespondingElement()]
else -> bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, pseudocode.getCorrespondingElement()]
}
addSubtypesOf((functionDescriptor as? CallableDescriptor)?.getReturnType())
}
@@ -10,31 +10,32 @@ fun foo() {
}
---------------------
L0:
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
2 mark({ val b: Boolean if (1 < 2) { use(b) } else { b = true } })
v(val b: Boolean) INIT: in: {} out: {b=D}
mark(if (1 < 2) { use(b) } else { b = true }) INIT: in: {b=D} out: {b=D}
v(val b: Boolean) INIT: in: {} out: {b=D}
mark(if (1 < 2) { use(b) } else { b = true }) INIT: in: {b=D} out: {b=D}
r(1) -> <v0>
r(2) -> <v1>
mark(1 < 2)
call(1 < 2, compareTo|<v0>, <v1>) -> <v2>
jf(L2|<v2>)
3 mark({ use(b) }) USE: in: {b=READ} out: {b=READ}
r(b) -> <v3> USE: in: {} out: {b=READ}
3 mark({ use(b) }) USE: in: {b=READ} out: {b=READ}
r(b) -> <v3> USE: in: {} out: {b=READ}
mark(use(b))
call(use(b), use|<v3>) -> <v4>
2 jmp(L3) USE: in: {} out: {}
2 jmp(L3) USE: in: {} out: {}
L2:
3 mark({ b = true })
r(true) -> <v5> USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
w(b|<v5>) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
L1:
r(true) -> <v5> USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
w(b|<v5>) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
L3:
1 <END> INIT: in: {} out: {}
2 merge(if (1 < 2) { use(b) } else { b = true }|<v4>, !<v6>) -> <v7> INIT: in: {b=D} out: {b=D}
L1:
1 <END> INIT: in: {} out: {}
error:
<ERROR>
sink:
<SINK> USE: in: {} out: {}
<SINK> USE: in: {} out: {}
=====================
== use ==
fun use(vararg a: Any?) = a
@@ -9,15 +9,17 @@ fun foo() {
}
}
---------------------
1 <v0>: {<: Comparable<Int>} NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1 < 2 <v2>: Boolean NEW: call(1 < 2, compareTo|<v0>, <v1>) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
use(b) <v4>: * NEW: call(use(b), use|<v3>) -> <v4>
{ use(b) } <v4>: * COPY
true <v5>: Boolean NEW: r(true) -> <v5>
if (1 < 2) { use(b) } else { b = true } <v4>: * COPY
{ val b: Boolean if (1 < 2) { use(b) } else { b = true } } <v4>: * COPY
1 <v0>: {<: Comparable<Int>} NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1 < 2 <v2>: Boolean NEW: call(1 < 2, compareTo|<v0>, <v1>) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
use(b) <v4>: * NEW: call(use(b), use|<v3>) -> <v4>
{ use(b) } <v4>: * COPY
true <v5>: Boolean NEW: r(true) -> <v5>
b = true !<v6>: *
{ b = true } !<v6>: * COPY
if (1 < 2) { use(b) } else { b = true } <v7>: * NEW: merge(if (1 < 2) { use(b) } else { b = true }|<v4>, !<v6>) -> <v7>
{ val b: Boolean if (1 < 2) { use(b) } else { b = true } } <v7>: * COPY
=====================
== use ==
fun use(vararg a: Any?) = a
@@ -6,6 +6,8 @@ class A {
val x: Int
}
---------------------
<v0>: A NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
<v0>: A NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
x = 1 !<v2>: *
{ x = 1 } !<v2>: * COPY
=====================
@@ -20,7 +20,7 @@ fun foo() {
x <v1>: Int NEW: r(x) -> <v1>
a <v2>: Int NEW: r(a) -> <v2>
x + a <v3>: Int NEW: call(x + a, plus|<v1>, <v2>) -> <v3>
a <v4>: * NEW: r(a) -> <v4>
a <v4>: * NEW: r(a) -> <v4>
use(a) <v5>: {<: Array<Any?>} NEW: call(use(a), use|<v4>) -> <v5>
val y = x + a use(a) <v5>: {<: Array<Any?>} COPY
=====================
@@ -20,7 +20,9 @@ fun bar() {
b = 3
}
---------------------
3 <v0>: Int NEW: r(3) -> <v0>
3 <v0>: Int NEW: r(3) -> <v0>
b = 3 !<v1>: *
{ val b: Int b = 3 } !<v1>: * COPY
=====================
== use ==
fun use(a: Int) = a
@@ -26,14 +26,15 @@ L0:
2 jmp(L3) INIT: in: {b=ID} out: {b=ID} USE: in: {b=READ} out: {b=READ}
L2:
3 mark({ b = true }) INIT: in: {b=D} out: {b=D}
r(true) -> <v4> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
w(b|<v4>) INIT: in: {b=D} out: {b=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
r(true) -> <v5> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
w(b|<v5>) INIT: in: {b=D} out: {b=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
L3:
2 error(use(b), No resolved call) INIT: in: {b=ID} out: {b=ID} USE: in: {b=READ} out: {b=READ}
r(b) -> <v5> USE: in: {} out: {b=READ}
2 merge(if (1 < 2) { b = false } else { b = true }|!<v4>, !<v6>) -> <v7> INIT: in: {b=ID} out: {b=ID}
error(use(b), No resolved call) USE: in: {b=READ} out: {b=READ}
r(b) -> <v8> USE: in: {} out: {b=READ}
error(use, No resolved call)
mark(use(b))
magic[UNRESOLVED_CALL](use(b)|<v5>) -> <v6>
magic[UNRESOLVED_CALL](use(b)|<v8>, !<v9>) -> <v10>
L1:
1 <END> INIT: in: {} out: {}
error:
@@ -10,12 +10,18 @@ fun foo() {
use(b)
}
---------------------
1 <v0>: {<: Comparable<Int>} NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1 < 2 <v2>: Boolean NEW: call(1 < 2, compareTo|<v0>, <v1>) -> <v2>
false <v3>: Boolean NEW: r(false) -> <v3>
true <v4>: Boolean NEW: r(true) -> <v4>
b <v5>: * NEW: r(b) -> <v5>
use(b) <v6>: * NEW: magic[UNRESOLVED_CALL](use(b)|<v5>) -> <v6>
{ val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) } <v6>: * COPY
1 <v0>: {<: Comparable<Int>} NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1 < 2 <v2>: Boolean NEW: call(1 < 2, compareTo|<v0>, <v1>) -> <v2>
false <v3>: Boolean NEW: r(false) -> <v3>
b = false !<v4>: *
{ b = false } !<v4>: * COPY
true <v5>: Boolean NEW: r(true) -> <v5>
b = true !<v6>: *
{ b = true } !<v6>: * COPY
if (1 < 2) { b = false } else { b = true } <v7>: * NEW: merge(if (1 < 2) { b = false } else { b = true }|!<v4>, !<v6>) -> <v7>
use !<v9>: *
b <v8>: * NEW: r(b) -> <v8>
use(b) <v10>: * NEW: magic[UNRESOLVED_CALL](use(b)|<v8>, !<v9>) -> <v10>
{ val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) } <v10>: * COPY
=====================
@@ -42,12 +42,13 @@ L5 [body entry point]:
4 jmp(L7) INIT: in: {b=ID, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=READ}
L6:
5 mark({ b = true }) INIT: in: {b=D, i=ID, numbers=ID} out: {b=D, i=ID, numbers=ID}
r(true) -> <v7> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
w(b|<v7>) INIT: in: {b=D, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
r(true) -> <v8> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
w(b|<v8>) INIT: in: {b=D, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
L7:
4 r(b) -> <v8> INIT: in: {b=ID, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {} out: {b=READ}
4 merge(if (1 < 2) { b = false } else { b = true }|!<v7>, !<v9>) -> <v10> INIT: in: {b=ID, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=READ}
r(b) -> <v11> USE: in: {} out: {b=READ}
mark(use(b))
call(use(b), use|<v8>) -> <v9>
call(use(b), use|<v11>) -> <v12>
jmp(L4 [loop entry point]) USE: in: {} out: {}
- 3 jmp?(L4 [loop entry point])
L2:
@@ -13,16 +13,25 @@ fun foo(numbers: Collection<Int>) {
}
}
---------------------
<v0>: {<: Collection<Int>} NEW: magic[FAKE_INITIALIZER](numbers: Collection<Int>) -> <v0>
<v2>: Int NEW: magic[LOOP_RANGE_ITERATION](numbers|<v1>) -> <v2>
numbers <v1>: {<: Iterable<Int>} NEW: r(numbers) -> <v1>
1 <v3>: {<: Comparable<Int>} NEW: r(1) -> <v3>
2 <v4>: Int NEW: r(2) -> <v4>
1 < 2 <v5>: Boolean NEW: call(1 < 2, compareTo|<v3>, <v4>) -> <v5>
false <v6>: Boolean NEW: r(false) -> <v6>
true <v7>: Boolean NEW: r(true) -> <v7>
b <v8>: * NEW: r(b) -> <v8>
use(b) <v9>: * NEW: call(use(b), use|<v8>) -> <v9>
<v0>: {<: Collection<Int>} NEW: magic[FAKE_INITIALIZER](numbers: Collection<Int>) -> <v0>
<v2>: Int NEW: magic[LOOP_RANGE_ITERATION](numbers|<v1>) -> <v2>
numbers <v1>: {<: Iterable<Int>} NEW: r(numbers) -> <v1>
1 <v3>: {<: Comparable<Int>} NEW: r(1) -> <v3>
2 <v4>: Int NEW: r(2) -> <v4>
1 < 2 <v5>: Boolean NEW: call(1 < 2, compareTo|<v3>, <v4>) -> <v5>
false <v6>: Boolean NEW: r(false) -> <v6>
b = false !<v7>: *
{ b = false } !<v7>: * COPY
true <v8>: Boolean NEW: r(true) -> <v8>
b = true !<v9>: *
{ b = true } !<v9>: * COPY
if (1 < 2) { b = false } else { b = true } <v10>: * NEW: merge(if (1 < 2) { b = false } else { b = true }|!<v7>, !<v9>) -> <v10>
b <v11>: * NEW: r(b) -> <v11>
use(b) <v12>: * NEW: call(use(b), use|<v11>) -> <v12>
continue !<v13>: *
{ val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue } !<v13>: * COPY
for (i in numbers) { val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue } !<v14>: *
{ for (i in numbers) { val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue } } !<v14>: * COPY
=====================
== use ==
fun use(vararg a: Any?) = a
@@ -7,11 +7,11 @@ fun foo() {
"after"
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
a <v2>: {<: Comparable<Int>} NEW: r(a) -> <v2>
0 <v3>: Int NEW: r(0) -> <v3>
"before" <v0>: * NEW: r("before") -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
a <v2>: {<: Comparable<Int>} NEW: r(a) -> <v2>
0 <v3>: Int NEW: r(0) -> <v3>
a > 0 <v4>: Boolean NEW: call(a > 0, compareTo|<v2>, <v3>) -> <v4>
"after" <v5>: * NEW: r("after") -> <v5>
{ "before" do { var a = 2 } while (a > 0) "after" } <v5>: * COPY
=====================
"after" <v5>: * NEW: r("after") -> <v5>
{ "before" do { var a = 2 } while (a > 0) "after" } <v5>: * COPY
=====================
@@ -8,11 +8,11 @@ fun foo() {
}
---------------------
<v4>: Int NEW: magic[LOOP_RANGE_ITERATION](1..10|<v3>) -> <v4>
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
10 <v2>: Int NEW: r(10) -> <v2>
1..10 <v3>: {<: Iterable<Int>} NEW: call(1..10, rangeTo|<v1>, <v2>) -> <v3>
i <v5>: Int NEW: r(i) -> <v5>
"after" <v6>: * NEW: r("after") -> <v6>
{ "before" for (i in 1..10) { val a = i } "after" } <v6>: * COPY
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
10 <v2>: Int NEW: r(10) -> <v2>
1..10 <v3>: {<: Iterable<Int>} NEW: call(1..10, rangeTo|<v1>, <v2>) -> <v3>
i <v5>: Int NEW: r(i) -> <v5>
"after" <v6>: * NEW: r("after") -> <v6>
{ "before" for (i in 1..10) { val a = i } "after" } <v6>: * COPY
=====================
@@ -8,11 +8,11 @@ fun foo() {
"after"
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
{ (x: Int) -> val a = x + b } <v2>: {<: (Int) -> Unit} NEW: r({ (x: Int) -> val a = x + b }) -> <v2>
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" val b = 1 val f = { (x: Int) -> val a = x + b } "after" } <v3>: * COPY
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" val b = 1 val f = { (x: Int) -> val a = x + b } "after" } <v3>: * COPY
=====================
== anonymous_0 ==
{ (x: Int) ->
@@ -20,7 +20,7 @@ fun foo() {
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](x: Int) -> <v0>
x <v1>: Int NEW: r(x) -> <v1>
b <v2>: Int NEW: r(b) -> <v2>
x + b <v3>: Int NEW: call(x + b, plus|<v1>, <v2>) -> <v3>
x <v1>: Int NEW: r(x) -> <v1>
b <v2>: Int NEW: r(b) -> <v2>
x + b <v3>: Int NEW: call(x + b, plus|<v1>, <v2>) -> <v3>
=====================
@@ -11,7 +11,7 @@ fun foo() {
}
---------------------
L0:
1 <START> INIT: in: {} out: {}
1 <START> INIT: in: {} out: {}
2 mark({ "before" if (true) { val a = 1 } else { val b = 2 } "after" })
mark("before")
r("before") -> <v0>
@@ -19,22 +19,23 @@ L0:
r(true) -> <v1>
jf(L2|<v1>)
3 mark({ val a = 1 })
v(val a = 1) INIT: in: {} out: {a=D}
r(1) -> <v2> INIT: in: {a=D} out: {a=D}
w(a|<v2>) INIT: in: {a=D} out: {a=ID}
2 jmp(L3) INIT: in: {} out: {}
v(val a = 1) INIT: in: {} out: {a=D}
r(1) -> <v2> INIT: in: {a=D} out: {a=D}
w(a|<v2>) INIT: in: {a=D} out: {a=ID}
2 jmp(L3) INIT: in: {} out: {}
L2:
3 mark({ val b = 2 })
v(val b = 2) INIT: in: {} out: {b=D}
r(2) -> <v3> INIT: in: {b=D} out: {b=D}
w(b|<v3>) INIT: in: {b=D} out: {b=ID}
v(val b = 2) INIT: in: {} out: {b=D}
r(2) -> <v3> INIT: in: {b=D} out: {b=D}
w(b|<v3>) INIT: in: {b=D} out: {b=ID}
L3:
2 mark("after") INIT: in: {} out: {}
r("after") -> <v4>
2 merge(if (true) { val a = 1 } else { val b = 2 }|!<v4>, !<v5>) -> <v6> INIT: in: {} out: {}
mark("after")
r("after") -> <v7>
L1:
1 <END>
error:
<ERROR>
sink:
<SINK> USE: in: {} out: {}
<SINK> USE: in: {} out: {}
=====================
@@ -10,10 +10,13 @@ fun foo() {
"after"
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
true <v1>: Boolean NEW: r(true) -> <v1>
1 <v2>: Int NEW: r(1) -> <v2>
2 <v3>: Int NEW: r(2) -> <v3>
"after" <v4>: * NEW: r("after") -> <v4>
{ "before" if (true) { val a = 1 } else { val b = 2 } "after" } <v4>: * COPY
=====================
"before" <v0>: * NEW: r("before") -> <v0>
true <v1>: Boolean NEW: r(true) -> <v1>
1 <v2>: Int NEW: r(1) -> <v2>
{ val a = 1 } !<v4>: *
2 <v3>: Int NEW: r(2) -> <v3>
{ val b = 2 } !<v5>: *
if (true) { val a = 1 } else { val b = 2 } <v6>: * NEW: merge(if (true) { val a = 1 } else { val b = 2 }|!<v4>, !<v5>) -> <v6>
"after" <v7>: * NEW: r("after") -> <v7>
{ "before" if (true) { val a = 1 } else { val b = 2 } "after" } <v7>: * COPY
=====================
@@ -13,11 +13,11 @@ fun foo() {
}
---------------------
<v1>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v1>
<v2>: A NEW: magic[IMPLICIT_RECEIVER](x) -> <v2>
"before" <v0>: * NEW: r("before") -> <v0>
x <v3>: Int NEW: r(x|<v2>) -> <v3>
"after" <v4>: * NEW: r("after") -> <v4>
{ "before" class A(val x: Int) { { val a = x } fun foo() { val b = x } } "after" } <v4>: * COPY
<v2>: A NEW: magic[IMPLICIT_RECEIVER](x) -> <v2>
"before" <v0>: * NEW: r("before") -> <v0>
x <v3>: Int NEW: r(x|<v2>) -> <v3>
"after" <v4>: * NEW: r("after") -> <v4>
{ "before" class A(val x: Int) { { val a = x } fun foo() { val b = x } } "after" } <v4>: * COPY
=====================
== foo ==
fun foo() {
@@ -25,5 +25,5 @@ fun foo() {
}
---------------------
<v0>: A NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
x <v1>: Int NEW: r(x|<v0>) -> <v1>
x <v1>: Int NEW: r(x|<v0>) -> <v1>
=====================
@@ -9,9 +9,9 @@ fun foo() {
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
"after" <v2>: * NEW: r("after") -> <v2>
{ "before" val b = 1 fun local(x: Int) { val a = x + b } "after" } <v2>: * COPY
1 <v1>: Int NEW: r(1) -> <v1>
"after" <v2>: * NEW: r("after") -> <v2>
{ "before" val b = 1 fun local(x: Int) { val a = x + b } "after" } <v2>: * COPY
=====================
== local ==
fun local(x: Int) {
@@ -19,7 +19,7 @@ fun local(x: Int) {
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](x: Int) -> <v0>
x <v1>: Int NEW: r(x) -> <v1>
b <v2>: Int NEW: r(b) -> <v2>
x + b <v3>: Int NEW: call(x + b, plus|<v1>, <v2>) -> <v3>
x <v1>: Int NEW: r(x) -> <v1>
b <v2>: Int NEW: r(b) -> <v2>
x + b <v3>: Int NEW: call(x + b, plus|<v1>, <v2>) -> <v3>
=====================
@@ -13,9 +13,9 @@ fun foo() {
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
"after" <v2>: * NEW: r("after") -> <v2>
{ "before" object A { { val a = 1 } fun foo() { val b = 2 } } "after" } <v2>: * COPY
1 <v1>: Int NEW: r(1) -> <v1>
"after" <v2>: * NEW: r("after") -> <v2>
{ "before" object A { { val a = 1 } fun foo() { val b = 2 } } "after" } <v2>: * COPY
=====================
== foo ==
fun foo() {
@@ -23,4 +23,4 @@ fun foo() {
}
---------------------
2 <v0>: Int NEW: r(2) -> <v0>
=====================
=====================
@@ -12,11 +12,11 @@ fun foo() {
"after"
}
---------------------
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
"before" <v0>: * NEW: r("before") -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
object { { val x = 1 } fun foo() { val a = 2 } } <v2>: <no name provided> NEW: r(object { { val x = 1 } fun foo() { val a = 2 } }) -> <v2>
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" val bar = object { { val x = 1 } fun foo() { val a = 2 } } "after" } <v3>: * COPY
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" val bar = object { { val x = 1 } fun foo() { val a = 2 } } "after" } <v3>: * COPY
=====================
== foo ==
fun foo() {
@@ -24,4 +24,4 @@ fun foo() {
}
---------------------
2 <v0>: Int NEW: r(2) -> <v0>
=====================
=====================
@@ -17,15 +17,19 @@ get() {
return $a
}
---------------------
<v0>: A NEW: magic[IMPLICIT_RECEIVER]($a) -> <v0>
$a <v1>: Int NEW: r($a|<v0>) -> <v1>
<v0>: A NEW: magic[IMPLICIT_RECEIVER]($a) -> <v0>
$a <v1>: Int NEW: r($a|<v0>) -> <v1>
return $a !<v2>: *
{ return $a } !<v2>: * COPY
=====================
== set_a ==
set(v: Int) {
$a = v
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](v: Int) -> <v0>
<v1>: A NEW: magic[IMPLICIT_RECEIVER]($a) -> <v1>
v <v2>: Int NEW: r(v) -> <v2>
<v0>: Int NEW: magic[FAKE_INITIALIZER](v: Int) -> <v0>
<v1>: A NEW: magic[IMPLICIT_RECEIVER]($a) -> <v1>
v <v2>: Int NEW: r(v) -> <v2>
$a = v !<v3>: *
{ $a = v } !<v3>: * COPY
=====================
@@ -49,8 +49,9 @@ L5 [skipFinallyToErrorBlock]:
v(val a = 1) INIT: in: {} out: {a=D}
r(1) -> <v4> INIT: in: {a=D} out: {a=D}
w(a|<v4>) INIT: in: {a=D} out: {a=ID}
2 mark("after") INIT: in: {} out: {}
r("after") -> <v5>
2 merge(try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 }|<v1>, !<v5>) -> <v6> INIT: in: {} out: {}
mark("after")
r("after") -> <v7>
L1:
1 <END>
error:
@@ -13,13 +13,14 @@ fun foo() {
"after"
}
---------------------
<v2>: {<: Exception} NEW: magic[FAKE_INITIALIZER](e: Exception) -> <v2>
"before" <v0>: * NEW: r("before") -> <v0>
foo() <v1>: * NEW: call(foo(), foo) -> <v1>
{ foo() } <v1>: * COPY
e <v3>: {<: Exception} NEW: r(e) -> <v3>
1 <v4>: Int NEW: r(1) -> <v4>
try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 } <v1>: * COPY
"after" <v5>: * NEW: r("after") -> <v5>
{ "before" try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 } "after" } <v5>: * COPY
<v2>: {<: Exception} NEW: magic[FAKE_INITIALIZER](e: Exception) -> <v2>
"before" <v0>: * NEW: r("before") -> <v0>
foo() <v1>: * NEW: call(foo(), foo) -> <v1>
{ foo() } <v1>: * COPY
e <v3>: {<: Exception} NEW: r(e) -> <v3>
{ val a = e } !<v5>: *
1 <v4>: Int NEW: r(1) -> <v4>
try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 } <v6>: * NEW: merge(try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 }|<v1>, !<v5>) -> <v6>
"after" <v7>: * NEW: r("after") -> <v7>
{ "before" try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 } "after" } <v7>: * COPY
=====================
@@ -22,9 +22,9 @@ L4 [body entry point]:
v(val a: Int) INIT: in: {} out: {a=D}
2 jmp(L2 [loop entry point]) INIT: in: {} out: {} USE: in: {} out: {}
L3 [loop exit point]:
- read (Unit) -> <v3>
- read (Unit)
- mark("after")
- r("after") -> <v4>
- r("after") -> <v3>
L1:
1 <END> INIT: in: {} out: {}
error:
@@ -10,6 +10,6 @@ fun foo() {
<v2>: * NEW: magic[VALUE_CONSUMER](true|<v1>) -> <v2>
"before" <v0>: * NEW: r("before") -> <v0>
true <v1>: Boolean NEW: r(true) -> <v1>
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" while (true) { val a: Int } "after" } <v3>: * COPY
"after" <v3>: * NEW: r("after") -> <v3>
{ "before" while (true) { val a: Int } "after" } <v3>: * COPY
=====================
@@ -46,11 +46,12 @@ sink:
L7:
5 <START>
6 mark(break)
jmp(L2) NEXT:[read (Unit)]
jmp(L2) NEXT:[read (Unit)]
- 5 ret(*|!<v0>) L8 PREV:[]
L8:
5 <END> NEXT:[<SINK>] PREV:[]
<END> NEXT:[<SINK>] PREV:[]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -7,15 +7,19 @@ fun foo(c: Collection<Int>) {
}
}
---------------------
<v0>: {<: Collection<Int>} NEW: magic[FAKE_INITIALIZER](c: Collection<Int>) -> <v0>
<v2>: Int NEW: magic[LOOP_RANGE_ITERATION](c|<v1>) -> <v2>
c <v1>: {<: Iterable<Int>} NEW: r(c) -> <v1>
{ break } <v3>: * NEW: r({ break }) -> <v3>
{ { break } } <v3>: * COPY
<v0>: {<: Collection<Int>} NEW: magic[FAKE_INITIALIZER](c: Collection<Int>) -> <v0>
<v2>: Int NEW: magic[LOOP_RANGE_ITERATION](c|<v1>) -> <v2>
c <v1>: {<: Iterable<Int>} NEW: r(c) -> <v1>
{ break } <v3>: * NEW: r({ break }) -> <v3>
{ { break } } <v3>: * COPY
for (e in c) { { break } } !<v4>: *
{ for (e in c) { { break } } } !<v4>: * COPY
=====================
== anonymous_0 ==
{
break
}
---------------------
break !<v0>: *
break !<v0>: * COPY
=====================
@@ -143,12 +143,13 @@ L4:
jf(L6|<v2>) NEXT:[read (Unit), mark({ return@l })]
6 mark({ return@l })
ret L5 NEXT:[<END>]
- 5 jmp(L7) NEXT:[<END>] PREV:[]
- 5 jmp(L7) NEXT:[ret(*|!<v3>) L5] PREV:[]
L6:
read (Unit) PREV:[jf(L6|<v2>)]
L5:
L7:
4 <END> NEXT:[<SINK>] PREV:[ret L5, read (Unit)]
4 ret(*|!<v3>) L5
L5:
<END> NEXT:[<SINK>] PREV:[ret L5, ret(*|!<v3>) L5]
error:
<ERROR> PREV:[]
sink:
@@ -227,8 +228,9 @@ L5 [onExceptionToFinallyBlock]:
L10 [skipFinallyToErrorBlock]:
7 mark({ 2 }) PREV:[jmp(L10 [skipFinallyToErrorBlock])]
r(2) -> <v4>
3 ret(*|!<v5>) L4
L4:
3 <END> NEXT:[<SINK>] PREV:[ret L4, r(2) -> <v4>]
<END> NEXT:[<SINK>] PREV:[ret L4, ret(*|!<v5>) L4]
error:
<ERROR> PREV:[jmp(error)]
sink:
@@ -342,17 +344,17 @@ L8:
3 jmp(L3 [loop entry point]) NEXT:[r(true) -> <v0>]
L4 [loop exit point]:
read (Unit) PREV:[jmp(L4 [loop exit point])]
r(5) -> <v6>
r(5) -> <v8>
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L10 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
r(2) -> <v7>
r(2) -> <v9>
L11 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
L9 [skipFinallyToErrorBlock]:
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
r(2) -> <v7>
r(2) -> <v9>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -408,12 +410,12 @@ L4 [loop exit point]:
L2 [onExceptionToFinallyBlock]:
L10 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
r(2) -> <v6>
r(2) -> <v8>
L11 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
L9 [skipFinallyToErrorBlock]:
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
r(2) -> <v6>
r(2) -> <v8>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -547,17 +549,17 @@ L8:
4 jmp?(L5 [loop entry point]) NEXT:[magic[LOOP_RANGE_ITERATION](1..a|<v3>) -> <v4>, read (Unit)]
L3:
read (Unit) PREV:[jmp?(L3), jmp?(L5 [loop entry point])]
3 r(5) -> <v9>
3 r(5) -> <v11>
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
L2 [onExceptionToFinallyBlock]:
L10 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
r(2) -> <v10>
r(2) -> <v12>
L11 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
L9 [skipFinallyToErrorBlock]:
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
r(2) -> <v10>
r(2) -> <v12>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -622,12 +624,12 @@ L3:
L2 [onExceptionToFinallyBlock]:
L10 [start finally]:
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
r(2) -> <v9>
r(2) -> <v11>
L11 [finish finally]:
2 jmp(error) NEXT:[<ERROR>]
L9 [skipFinallyToErrorBlock]:
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
r(2) -> <v9>
r(2) -> <v11>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -735,8 +737,8 @@ L0:
1 <START>
2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } })
mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) })
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
3 mark({ return 1 })
r(1) -> <v0>
L4 [start finally]:
@@ -745,36 +747,37 @@ L4 [start finally]:
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
L5 [finish finally]:
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])] PREV:[]
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v3>
w(e|<v3>)
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
w(e|<v4>)
4 mark({ doSmth(2) })
r(2) -> <v4>
r(2) -> <v5>
mark(doSmth(2))
call(doSmth(2), doSmth|<v4>) -> <v5>
call(doSmth(2), doSmth|<v5>) -> <v6>
3 jmp(L6 [afterCatches])
L6 [afterCatches]:
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })]
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })]
L3 [onExceptionToFinallyBlock]:
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
2 jmp(error) NEXT:[<ERROR>]
2 jmp(error) NEXT:[<ERROR>]
L7 [skipFinallyToErrorBlock]:
4 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
4 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
2 merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }|!<v3>, <v6>) -> <v7>
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, call(doSmth(3), doSmth|<v1>) -> <v2>]
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }|!<v3>, <v6>) -> <v7>]
error:
<ERROR> PREV:[jmp(error)]
<ERROR> PREV:[jmp(error)]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
== t14 ==
fun t14() : Int {
@@ -790,27 +793,28 @@ L0:
1 <START>
2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } })
mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) })
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), mark({ return 1 })]
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), mark({ return 1 })]
3 mark({ return 1 })
r(1) -> <v0>
ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L3 [afterCatches]) NEXT:[<END>] PREV:[]
ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L3 [afterCatches]) NEXT:[merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v1>
w(e|<v1>)
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
w(e|<v2>)
4 mark({ doSmth(2) })
r(2) -> <v2>
r(2) -> <v3>
mark(doSmth(2))
call(doSmth(2), doSmth|<v2>) -> <v3>
call(doSmth(2), doSmth|<v3>) -> <v4>
3 jmp(L3 [afterCatches])
L1:
L3 [afterCatches]:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, jmp(L3 [afterCatches])]
2 merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
== t15 ==
fun t15() : Int {
@@ -829,8 +833,8 @@ L0:
1 <START>
2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } })
mark(try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) })
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
3 mark({ return 1 })
r(1) -> <v0>
L4 [start finally]:
@@ -839,39 +843,40 @@ L4 [start finally]:
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
L5 [finish finally]:
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])] PREV:[]
3 ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L6 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])] PREV:[]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v3>
w(e|<v3>)
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
w(e|<v4>)
4 mark({ return 2 })
r(2) -> <v4>
r(2) -> <v5>
mark({ doSmth(3) })
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
ret(*|<v4>) L1 NEXT:[<END>]
- 3 jmp(L6 [afterCatches]) PREV:[]
ret(*|<v5>) L1 NEXT:[<END>]
- 3 jmp(L6 [afterCatches]) PREV:[]
L6 [afterCatches]:
- 2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[]
- 2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[]
L3 [onExceptionToFinallyBlock]:
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
r(3) -> <v1>
mark(doSmth(3))
call(doSmth(3), doSmth|<v1>) -> <v2>
2 jmp(error) NEXT:[<ERROR>]
2 jmp(error) NEXT:[<ERROR>]
L7 [skipFinallyToErrorBlock]:
- 4 mark({ doSmth(3) }) PREV:[]
- r(3) -> <v1> PREV:[]
- mark(doSmth(3)) PREV:[]
- call(doSmth(3), doSmth|<v1>) -> <v2> PREV:[]
- 4 mark({ doSmth(3) }) PREV:[]
- r(3) -> <v1> PREV:[]
- mark(doSmth(3)) PREV:[]
- call(doSmth(3), doSmth|<v1>) -> <v2> PREV:[]
- 2 merge(try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|!<v3>, !<v6>) -> <v7> PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v4>) L1]
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v5>) L1]
error:
<ERROR> PREV:[jmp(error)]
<ERROR> PREV:[jmp(error)]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
== t16 ==
fun t16() : Int {
@@ -890,15 +895,15 @@ L0:
1 <START>
2 mark({ try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } })
mark(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) })
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ doSmth(1) })]
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), jmp?(L3 [onExceptionToFinallyBlock])]
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ doSmth(1) })]
3 mark({ doSmth(1) })
r(1) -> <v0>
mark(doSmth(1))
call(doSmth(1), doSmth|<v0>) -> <v1>
2 jmp(L4 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])]
2 jmp(L4 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])]
L2 [onException]:
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
w(e|<v2>)
4 mark({ return 2 })
@@ -909,27 +914,28 @@ L5 [start finally]:
mark(doSmth(3))
call(doSmth(3), doSmth|<v4>) -> <v5>
L6 [finish finally]:
4 ret(*|<v3>) L1 NEXT:[<END>]
- 3 jmp(L4 [afterCatches]) PREV:[]
4 ret(*|<v3>) L1 NEXT:[<END>]
- 3 jmp(L4 [afterCatches]) PREV:[]
L4 [afterCatches]:
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[jmp(L4 [afterCatches])]
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[jmp(L4 [afterCatches])]
L3 [onExceptionToFinallyBlock]:
5 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
5 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
r(3) -> <v4>
mark(doSmth(3))
call(doSmth(3), doSmth|<v4>) -> <v5>
2 jmp(error) NEXT:[<ERROR>]
2 jmp(error) NEXT:[<ERROR>]
L7 [skipFinallyToErrorBlock]:
5 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
5 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
r(3) -> <v4>
mark(doSmth(3))
call(doSmth(3), doSmth|<v4>) -> <v5>
2 merge(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|<v1>, !<v6>) -> <v7>
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v3>) L1, call(doSmth(3), doSmth|<v4>) -> <v5>]
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v3>) L1, merge(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|<v1>, !<v6>) -> <v7>]
error:
<ERROR> PREV:[jmp(error)]
<ERROR> PREV:[jmp(error)]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
== doSmth ==
fun doSmth(i: Int) {
@@ -26,12 +26,18 @@ fun t2() {
}
}
---------------------
1 <v0>: * NEW: r(1) -> <v0>
2 <v1>: {<: Comparable<Int>} NEW: r(2) -> <v1>
3 <v2>: Int NEW: r(3) -> <v2>
2 > 3 <v3>: Boolean NEW: call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
2 <v4>: * NEW: r(2) -> <v4>
{ 2 } <v4>: * COPY
1 <v0>: * NEW: r(1) -> <v0>
2 <v1>: {<: Comparable<Int>} NEW: r(2) -> <v1>
3 <v2>: Int NEW: r(3) -> <v2>
2 > 3 <v3>: Boolean NEW: call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
return !<v5>: *
{ return } !<v5>: * COPY
if (2 > 3) { return } !<v5>: * COPY
{ 1 if (2 > 3) { return } } !<v5>: * COPY
2 <v4>: * NEW: r(2) -> <v4>
{ 2 } <v4>: * COPY
try { 1 if (2 > 3) { return } } finally { 2 } !<v5>: * COPY
{ try { 1 if (2 > 3) { return } } finally { 2 } } !<v5>: * COPY
=====================
== t3 ==
fun t3() {
@@ -63,9 +69,13 @@ try { 1 @l{ () -> if (2 > 3) { return@l } } } finally { 2 } <v1>: * COPY
}
}
---------------------
2 <v0>: {<: Comparable<Int>} NEW: r(2) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
2 > 3 <v2>: Boolean NEW: call(2 > 3, compareTo|<v0>, <v1>) -> <v2>
2 <v0>: {<: Comparable<Int>} NEW: r(2) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
2 > 3 <v2>: Boolean NEW: call(2 > 3, compareTo|<v0>, <v1>) -> <v2>
return@l !<v3>: *
{ return@l } !<v3>: * COPY
if (2 > 3) { return@l } !<v3>: * COPY
if (2 > 3) { return@l } !<v3>: * COPY
=====================
== t4 ==
fun t4() {
@@ -97,12 +107,18 @@ fun t4() {
}
}
---------------------
1 <v0>: * NEW: r(1) -> <v0>
2 <v1>: {<: Comparable<Int>} NEW: r(2) -> <v1>
3 <v2>: Int NEW: r(3) -> <v2>
2 > 3 <v3>: Boolean NEW: call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
2 <v4>: * NEW: r(2) -> <v4>
{ 2 } <v4>: * COPY
1 <v0>: * NEW: r(1) -> <v0>
2 <v1>: {<: Comparable<Int>} NEW: r(2) -> <v1>
3 <v2>: Int NEW: r(3) -> <v2>
2 > 3 <v3>: Boolean NEW: call(2 > 3, compareTo|<v1>, <v2>) -> <v3>
return@l !<v5>: *
{ return@l } !<v5>: * COPY
if (2 > 3) { return@l } !<v5>: * COPY
{ 1 if (2 > 3) { return@l } } !<v5>: * COPY
2 <v4>: * NEW: r(2) -> <v4>
{ 2 } <v4>: * COPY
try { 1 if (2 > 3) { return@l } } finally { 2 } !<v5>: * COPY
try { 1 if (2 > 3) { return@l } } finally { 2 } !<v5>: * COPY
=====================
== t5 ==
fun t5() {
@@ -118,14 +134,23 @@ fun t5() {
}
}
---------------------
<v1>: * NEW: magic[VALUE_CONSUMER](true|<v0>) -> <v1>
true <v0>: Boolean NEW: r(true) -> <v0>
1 <v2>: * NEW: r(1) -> <v2>
2 <v3>: {<: Comparable<Int>} NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
2 > 3 <v5>: Boolean NEW: call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
2 <v6>: * NEW: r(2) -> <v6>
{ 2 } <v6>: * COPY
<v1>: * NEW: magic[VALUE_CONSUMER](true|<v0>) -> <v1>
true <v0>: Boolean NEW: r(true) -> <v0>
1 <v2>: * NEW: r(1) -> <v2>
2 <v3>: {<: Comparable<Int>} NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
2 > 3 <v5>: Boolean NEW: call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
break @l !<v7>: *
{ break @l } !<v7>: * COPY
if (2 > 3) { break @l } !<v7>: * COPY
{ 1 if (2 > 3) { break @l } } !<v7>: * COPY
2 <v6>: * NEW: r(2) -> <v6>
{ 2 } <v6>: * COPY
try { 1 if (2 > 3) { break @l } } finally { 2 } !<v7>: * COPY
{ try { 1 if (2 > 3) { break @l } } finally { 2 } } !<v7>: * COPY
while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } } !<v8>: *
@l while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } } !<v8>: * COPY
{ @l while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } } } !<v8>: * COPY
=====================
== t6 ==
fun t6() {
@@ -148,12 +173,18 @@ true <v0>:
2 <v3>: {<: Comparable<Int>} NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
2 > 3 <v5>: Boolean NEW: call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
5 <v6>: * NEW: r(5) -> <v6>
{ @l while(true) { 1 if (2 > 3) { break @l } } 5 } <v6>: * COPY
2 <v7>: * NEW: r(2) -> <v7>
{ 2 } <v7>: * COPY
try { @l while(true) { 1 if (2 > 3) { break @l } } 5 } finally { 2 } <v6>: * COPY
{ try { @l while(true) { 1 if (2 > 3) { break @l } } 5 } finally { 2 } } <v6>: * COPY
break @l !<v6>: *
{ break @l } !<v6>: * COPY
if (2 > 3) { break @l } !<v6>: * COPY
{ 1 if (2 > 3) { break @l } } !<v6>: * COPY
while(true) { 1 if (2 > 3) { break @l } } !<v7>: *
@l while(true) { 1 if (2 > 3) { break @l } } !<v7>: * COPY
5 <v8>: * NEW: r(5) -> <v8>
{ @l while(true) { 1 if (2 > 3) { break @l } } 5 } <v8>: * COPY
2 <v9>: * NEW: r(2) -> <v9>
{ 2 } <v9>: * COPY
try { @l while(true) { 1 if (2 > 3) { break @l } } 5 } finally { 2 } <v8>: * COPY
{ try { @l while(true) { 1 if (2 > 3) { break @l } } 5 } finally { 2 } } <v8>: * COPY
=====================
== t7 ==
fun t7() {
@@ -169,14 +200,23 @@ fun t7() {
}
}
---------------------
<v1>: * NEW: magic[VALUE_CONSUMER](true|<v0>) -> <v1>
true <v0>: Boolean NEW: r(true) -> <v0>
1 <v2>: * NEW: r(1) -> <v2>
2 <v3>: {<: Comparable<Int>} NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
2 > 3 <v5>: Boolean NEW: call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
2 <v6>: * NEW: r(2) -> <v6>
{ 2 } <v6>: * COPY
<v1>: * NEW: magic[VALUE_CONSUMER](true|<v0>) -> <v1>
true <v0>: Boolean NEW: r(true) -> <v0>
1 <v2>: * NEW: r(1) -> <v2>
2 <v3>: {<: Comparable<Int>} NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
2 > 3 <v5>: Boolean NEW: call(2 > 3, compareTo|<v3>, <v4>) -> <v5>
break @l !<v6>: *
{ break @l } !<v6>: * COPY
if (2 > 3) { break @l } !<v6>: * COPY
{ 1 if (2 > 3) { break @l } } !<v6>: * COPY
while(true) { 1 if (2 > 3) { break @l } } !<v7>: *
@l while(true) { 1 if (2 > 3) { break @l } } !<v7>: * COPY
{ @l while(true) { 1 if (2 > 3) { break @l } } } !<v7>: * COPY
2 <v8>: * NEW: r(2) -> <v8>
{ 2 } <v8>: * COPY
try { @l while(true) { 1 if (2 > 3) { break @l } } } finally { 2 } !<v7>: * COPY
{ try { @l while(true) { 1 if (2 > 3) { break @l } } } finally { 2 } } !<v7>: * COPY
=====================
== t8 ==
fun t8(a : Int) {
@@ -192,17 +232,26 @@ fun t8(a : Int) {
}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a : Int) -> <v0>
<v4>: Int NEW: magic[LOOP_RANGE_ITERATION](1..a|<v3>) -> <v4>
1 <v1>: Int NEW: r(1) -> <v1>
a <v2>: Int NEW: r(a) -> <v2>
1..a <v3>: {<: Iterable<Int>} NEW: call(1..a, rangeTo|<v1>, <v2>) -> <v3>
1 <v5>: * NEW: r(1) -> <v5>
2 <v6>: {<: Comparable<Int>} NEW: r(2) -> <v6>
3 <v7>: Int NEW: r(3) -> <v7>
2 > 3 <v8>: Boolean NEW: call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
2 <v9>: * NEW: r(2) -> <v9>
{ 2 } <v9>: * COPY
<v0>: Int NEW: magic[FAKE_INITIALIZER](a : Int) -> <v0>
<v4>: Int NEW: magic[LOOP_RANGE_ITERATION](1..a|<v3>) -> <v4>
1 <v1>: Int NEW: r(1) -> <v1>
a <v2>: Int NEW: r(a) -> <v2>
1..a <v3>: {<: Iterable<Int>} NEW: call(1..a, rangeTo|<v1>, <v2>) -> <v3>
1 <v5>: * NEW: r(1) -> <v5>
2 <v6>: {<: Comparable<Int>} NEW: r(2) -> <v6>
3 <v7>: Int NEW: r(3) -> <v7>
2 > 3 <v8>: Boolean NEW: call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
continue @l !<v10>: *
{ continue @l } !<v10>: * COPY
if (2 > 3) { continue @l } !<v10>: * COPY
{ 1 if (2 > 3) { continue @l } } !<v10>: * COPY
2 <v9>: * NEW: r(2) -> <v9>
{ 2 } <v9>: * COPY
try { 1 if (2 > 3) { continue @l } } finally { 2 } !<v10>: * COPY
{ try { 1 if (2 > 3) { continue @l } } finally { 2 } } !<v10>: * COPY
for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } } !<v11>: *
@l for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } } !<v11>: * COPY
{ @l for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } } } !<v11>: * COPY
=====================
== t9 ==
fun t9(a : Int) {
@@ -228,12 +277,18 @@ a
2 <v6>: {<: Comparable<Int>} NEW: r(2) -> <v6>
3 <v7>: Int NEW: r(3) -> <v7>
2 > 3 <v8>: Boolean NEW: call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
5 <v9>: * NEW: r(5) -> <v9>
{ @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } <v9>: * COPY
2 <v10>: * NEW: r(2) -> <v10>
{ 2 } <v10>: * COPY
try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 } <v9>: * COPY
{ try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 } } <v9>: * COPY
continue @l !<v9>: *
{ continue @l } !<v9>: * COPY
if (2 > 3) { continue @l } !<v9>: * COPY
{ 1 if (2 > 3) { continue @l } } !<v9>: * COPY
for (i in 1..a) { 1 if (2 > 3) { continue @l } } !<v10>: *
@l for (i in 1..a) { 1 if (2 > 3) { continue @l } } !<v10>: * COPY
5 <v11>: * NEW: r(5) -> <v11>
{ @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } <v11>: * COPY
2 <v12>: * NEW: r(2) -> <v12>
{ 2 } <v12>: * COPY
try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 } <v11>: * COPY
{ try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 } } <v11>: * COPY
=====================
== t10 ==
fun t10(a : Int) {
@@ -249,17 +304,26 @@ fun t10(a : Int) {
}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a : Int) -> <v0>
<v4>: Int NEW: magic[LOOP_RANGE_ITERATION](1..a|<v3>) -> <v4>
1 <v1>: Int NEW: r(1) -> <v1>
a <v2>: Int NEW: r(a) -> <v2>
1..a <v3>: {<: Iterable<Int>} NEW: call(1..a, rangeTo|<v1>, <v2>) -> <v3>
1 <v5>: * NEW: r(1) -> <v5>
2 <v6>: {<: Comparable<Int>} NEW: r(2) -> <v6>
3 <v7>: Int NEW: r(3) -> <v7>
2 > 3 <v8>: Boolean NEW: call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
2 <v9>: * NEW: r(2) -> <v9>
{ 2 } <v9>: * COPY
<v0>: Int NEW: magic[FAKE_INITIALIZER](a : Int) -> <v0>
<v4>: Int NEW: magic[LOOP_RANGE_ITERATION](1..a|<v3>) -> <v4>
1 <v1>: Int NEW: r(1) -> <v1>
a <v2>: Int NEW: r(a) -> <v2>
1..a <v3>: {<: Iterable<Int>} NEW: call(1..a, rangeTo|<v1>, <v2>) -> <v3>
1 <v5>: * NEW: r(1) -> <v5>
2 <v6>: {<: Comparable<Int>} NEW: r(2) -> <v6>
3 <v7>: Int NEW: r(3) -> <v7>
2 > 3 <v8>: Boolean NEW: call(2 > 3, compareTo|<v6>, <v7>) -> <v8>
continue @l !<v9>: *
{ continue @l } !<v9>: * COPY
if (2 > 3) { continue @l } !<v9>: * COPY
{ 1 if (2 > 3) { continue @l } } !<v9>: * COPY
for (i in 1..a) { 1 if (2 > 3) { continue @l } } !<v10>: *
@l for (i in 1..a) { 1 if (2 > 3) { continue @l } } !<v10>: * COPY
{ @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } } !<v10>: * COPY
2 <v11>: * NEW: r(2) -> <v11>
{ 2 } <v11>: * COPY
try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } } finally { 2 } !<v10>: * COPY
{ try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } } finally { 2 } } !<v10>: * COPY
=====================
== t11 ==
fun t11() {
@@ -271,8 +335,14 @@ fun t11() {
}
}
---------------------
1 <v0>: {<: Unit} NEW: r(1) -> <v0>
2 <v1>: {<: Unit} NEW: r(2) -> <v1>
1 <v0>: Unit NEW: r(1) -> <v0>
return 1 !<v3>: *
{ return 1 } !<v3>: * COPY
2 <v1>: Unit NEW: r(2) -> <v1>
return 2 !<v2>: *
{ return 2 } !<v2>: * COPY
try { return 1 } finally { return 2 } !<v3>: * COPY
{ try { return 1 } finally { return 2 } } !<v3>: * COPY
=====================
== t12 ==
fun t12() : Int {
@@ -284,10 +354,14 @@ fun t12() : Int {
}
}
---------------------
1 <v0>: Int NEW: r(1) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
1 <v0>: Int NEW: r(1) -> <v0>
return 1 !<v3>: *
{ return 1 } !<v3>: * COPY
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
try { return 1 } finally { doSmth(3) } !<v3>: * COPY
{ try { return 1 } finally { doSmth(3) } } !<v3>: * COPY
=====================
== t13 ==
fun t13() : Int {
@@ -302,16 +376,18 @@ fun t13() : Int {
}
}
---------------------
<v3>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v3>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v4>: Int NEW: r(2) -> <v4>
doSmth(2) <v5>: * NEW: call(doSmth(2), doSmth|<v4>) -> <v5>
{ doSmth(2) } <v5>: * COPY
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } <v5>: * COPY
{ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } } <v5>: * COPY
<v4>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
1 <v0>: Int NEW: r(1) -> <v0>
return 1 !<v3>: *
{ return 1 } !<v3>: * COPY
2 <v5>: Int NEW: r(2) -> <v5>
doSmth(2) <v6>: * NEW: call(doSmth(2), doSmth|<v5>) -> <v6>
{ doSmth(2) } <v6>: * COPY
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } <v7>: * NEW: merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }|!<v3>, <v6>) -> <v7>
{ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } } <v7>: * COPY
=====================
== t14 ==
fun t14() : Int {
@@ -323,13 +399,15 @@ fun t14() : Int {
}
}
---------------------
<v1>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v1>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v2>: Int NEW: r(2) -> <v2>
doSmth(2) <v3>: * NEW: call(doSmth(2), doSmth|<v2>) -> <v3>
{ doSmth(2) } <v3>: * COPY
try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } <v3>: * COPY
{ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } } <v3>: * COPY
<v2>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
1 <v0>: Int NEW: r(1) -> <v0>
return 1 !<v1>: *
{ return 1 } !<v1>: * COPY
2 <v3>: Int NEW: r(2) -> <v3>
doSmth(2) <v4>: * NEW: call(doSmth(2), doSmth|<v3>) -> <v4>
{ doSmth(2) } <v4>: * COPY
try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } <v5>: * NEW: merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>
{ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } } <v5>: * COPY
=====================
== t15 ==
fun t15() : Int {
@@ -344,12 +422,18 @@ fun t15() : Int {
}
}
---------------------
<v3>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v3>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v4>: Int NEW: r(2) -> <v4>
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
<v4>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4>
1 <v0>: Int NEW: r(1) -> <v0>
return 1 !<v3>: *
{ return 1 } !<v3>: * COPY
2 <v5>: Int NEW: r(2) -> <v5>
return 2 !<v6>: *
{ return 2 } !<v6>: * COPY
3 <v1>: Int NEW: r(3) -> <v1>
doSmth(3) <v2>: * NEW: call(doSmth(3), doSmth|<v1>) -> <v2>
{ doSmth(3) } <v2>: * COPY
try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } <v7>: * NEW: merge(try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|!<v3>, !<v6>) -> <v7>
{ try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } } <v7>: * COPY
=====================
== t16 ==
fun t16() : Int {
@@ -364,16 +448,18 @@ fun t16() : Int {
}
}
---------------------
<v2>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
1 <v0>: Int NEW: r(1) -> <v0>
doSmth(1) <v1>: * NEW: call(doSmth(1), doSmth|<v0>) -> <v1>
{ doSmth(1) } <v1>: * COPY
2 <v3>: Int NEW: r(2) -> <v3>
3 <v4>: Int NEW: r(3) -> <v4>
doSmth(3) <v5>: * NEW: call(doSmth(3), doSmth|<v4>) -> <v5>
{ doSmth(3) } <v5>: * COPY
try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } <v1>: * COPY
{ try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } } <v1>: * COPY
<v2>: {<: UnsupportedOperationException} NEW: magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2>
1 <v0>: Int NEW: r(1) -> <v0>
doSmth(1) <v1>: * NEW: call(doSmth(1), doSmth|<v0>) -> <v1>
{ doSmth(1) } <v1>: * COPY
2 <v3>: Int NEW: r(2) -> <v3>
return 2 !<v6>: *
{ return 2 } !<v6>: * COPY
3 <v4>: Int NEW: r(3) -> <v4>
doSmth(3) <v5>: * NEW: call(doSmth(3), doSmth|<v4>) -> <v5>
{ doSmth(3) } <v5>: * COPY
try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } <v7>: * NEW: merge(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|<v1>, !<v6>) -> <v7>
{ try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } } <v7>: * COPY
=====================
== doSmth ==
fun doSmth(i: Int) {
@@ -110,7 +110,7 @@ L6 [skipFinallyToErrorBlock]:
3 mark({ return 1 }) PREV:[jmp(L6 [skipFinallyToErrorBlock])]
r(1) -> <v5>
ret(*|<v5>) L1 NEXT:[<END>]
- 2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|<v0>, <v2>, <v4>) -> <v6> PREV:[]
- 2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|<v0>, <v2>, <v4>) -> <v7> PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v5>) L1, ret(*|<v5>) L1]
error:
@@ -142,30 +142,30 @@ L0:
2 mark({ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } })
L2 [loop entry point]:
L5 [condition entry point]:
mark(cond()) PREV:[mark({ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } }), jmp(L2 [loop entry point]), jmp(L2 [loop entry point])]
mark(cond()) PREV:[mark({ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } }), jmp(L2 [loop entry point]), jmp(L2 [loop entry point])]
call(cond(), cond) -> <v0>
mark(while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })
jf(L3 [loop exit point]|<v0>) NEXT:[read (Unit), mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })]
jf(L3 [loop exit point]|<v0>) NEXT:[read (Unit), mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })]
L4 [body entry point]:
3 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })
mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue })
jmp?(L6 [onException]) NEXT:[jmp?(L9 [catch 0]), jmp?(L7 [onExceptionToFinallyBlock])]
jmp?(L7 [onExceptionToFinallyBlock]) NEXT:[mark({ if (cond()) return else continue }), mark({ doSmth() })]
jmp?(L6 [onException]) NEXT:[jmp?(L9 [catch 0]), jmp?(L7 [onExceptionToFinallyBlock])]
jmp?(L7 [onExceptionToFinallyBlock]) NEXT:[mark({ if (cond()) return else continue }), mark({ doSmth() })]
4 mark({ doSmth() })
mark(doSmth())
call(doSmth(), doSmth) -> <v1>
3 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
3 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
L6 [onException]:
jmp?(L9 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L6 [onException])]
jmp?(L9 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L6 [onException])]
4 v(e: NullPointerException)
magic[FAKE_INITIALIZER](e: NullPointerException) -> <v2>
w(e|<v2>)
5 mark({ doSmth1() })
mark(doSmth1())
call(doSmth1(), doSmth1) -> <v3>
4 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
4 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
L9 [catch 0]:
v(e: Exception) PREV:[jmp?(L9 [catch 0])]
v(e: Exception) PREV:[jmp?(L9 [catch 0])]
magic[FAKE_INITIALIZER](e: Exception) -> <v4>
w(e|<v4>)
5 mark({ doSmth2() })
@@ -173,40 +173,42 @@ L9 [catch 0]:
call(doSmth2(), doSmth2) -> <v5>
4 jmp(L8 [afterCatches])
L8 [afterCatches]:
3 jmp(L10 [skipFinallyToErrorBlock]) NEXT:[mark({ if (cond()) return else continue })] PREV:[jmp(L8 [afterCatches]), jmp(L8 [afterCatches]), jmp(L8 [afterCatches])]
3 jmp(L10 [skipFinallyToErrorBlock]) NEXT:[mark({ if (cond()) return else continue })] PREV:[jmp(L8 [afterCatches]), jmp(L8 [afterCatches]), jmp(L8 [afterCatches])]
L7 [onExceptionToFinallyBlock]:
L11 [start finally]:
4 mark({ if (cond()) return else continue }) PREV:[jmp?(L7 [onExceptionToFinallyBlock])]
4 mark({ if (cond()) return else continue }) PREV:[jmp?(L7 [onExceptionToFinallyBlock])]
mark(if (cond()) return else continue)
mark(cond())
call(cond(), cond) -> <v6>
jf(L12|<v6>) NEXT:[jmp(L2 [loop entry point]), ret L1]
ret L1 NEXT:[<END>]
- jmp(L13) NEXT:[jmp(error)] PREV:[]
jf(L12|<v6>) NEXT:[jmp(L2 [loop entry point]), ret L1]
ret L1 NEXT:[<END>]
- jmp(L13) NEXT:[merge(if (cond()) return else continue|!<v7>, !<v8>) -> <v9>] PREV:[]
L12:
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(L12|<v6>)]
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(L12|<v6>)]
L13:
- merge(if (cond()) return else continue|!<v7>, !<v8>) -> <v9> PREV:[]
L14 [finish finally]:
- 3 jmp(error) NEXT:[<ERROR>] PREV:[]
- 3 jmp(error) NEXT:[<ERROR>] PREV:[]
L10 [skipFinallyToErrorBlock]:
4 mark({ if (cond()) return else continue }) PREV:[jmp(L10 [skipFinallyToErrorBlock])]
4 mark({ if (cond()) return else continue }) PREV:[jmp(L10 [skipFinallyToErrorBlock])]
mark(if (cond()) return else continue)
mark(cond())
call(cond(), cond) -> <v6>
jf(copy L12|<v6>) NEXT:[jmp(L2 [loop entry point]), ret L1]
ret L1 NEXT:[<END>]
- jmp(copy L13) NEXT:[merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|<v1>, <v3>, <v5>) -> <v7>] PREV:[]
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(copy L12|<v6>)]
- 3 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|<v1>, <v3>, <v5>) -> <v7> PREV:[]
- 2 jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[]
jf(copy L12|<v6>) NEXT:[jmp(L2 [loop entry point]), ret L1]
ret L1 NEXT:[<END>]
- jmp(copy L13) NEXT:[merge(if (cond()) return else continue|!<v7>, !<v8>) -> <v9>] PREV:[]
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(copy L12|<v6>)]
- merge(if (cond()) return else continue|!<v7>, !<v8>) -> <v9> PREV:[]
- 3 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|<v1>, <v3>, <v5>) -> <v10> PREV:[]
- 2 jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[]
L3 [loop exit point]:
read (Unit) PREV:[jf(L3 [loop exit point]|<v0>)]
read (Unit) PREV:[jf(L3 [loop exit point]|<v0>)]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret L1, ret L1, read (Unit)]
1 <END> NEXT:[<SINK>] PREV:[ret L1, ret L1, read (Unit)]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
== testCopy3 ==
fun testCopy3() {
@@ -276,7 +278,7 @@ L6 [skipFinallyToErrorBlock]:
jf(copy L9 [loop exit point]|<v5>) NEXT:[read (Unit), jmp(copy L8 [loop entry point])]
jmp(copy L8 [loop entry point]) NEXT:[mark(cond())]
read (Unit) PREV:[jf(copy L9 [loop exit point]|<v5>)]
2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|<v0>, <v2>, <v4>) -> <v6>
2 merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|<v0>, <v2>, <v4>) -> <v7>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -39,8 +39,10 @@ doSmth1()
doSmth2() <v4>: * NEW: call(doSmth2(), doSmth2) -> <v4>
{ doSmth2() } <v4>: * COPY
1 <v5>: Int NEW: r(1) -> <v5>
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } <v6>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|<v0>, <v2>, <v4>) -> <v6>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } } <v6>: * COPY
return 1 !<v6>: *
{ return 1 } !<v6>: * COPY
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } <v7>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|<v0>, <v2>, <v4>) -> <v7>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } } <v7>: * COPY
=====================
== testCopy2 ==
fun testCopy2() {
@@ -61,18 +63,24 @@ fun testCopy2() {
}
}
---------------------
<v2>: {<: NullPointerException} NEW: magic[FAKE_INITIALIZER](e: NullPointerException) -> <v2>
<v4>: {<: Exception} NEW: magic[FAKE_INITIALIZER](e: Exception) -> <v4>
cond() <v0>: Boolean NEW: call(cond(), cond) -> <v0>
doSmth() <v1>: * NEW: call(doSmth(), doSmth) -> <v1>
{ doSmth() } <v1>: * COPY
doSmth1() <v3>: * NEW: call(doSmth1(), doSmth1) -> <v3>
{ doSmth1() } <v3>: * COPY
doSmth2() <v5>: * NEW: call(doSmth2(), doSmth2) -> <v5>
{ doSmth2() } <v5>: * COPY
cond() <v6>: Boolean NEW: call(cond(), cond) -> <v6>
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } <v7>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|<v1>, <v3>, <v5>) -> <v7>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } <v7>: * COPY
<v2>: {<: NullPointerException} NEW: magic[FAKE_INITIALIZER](e: NullPointerException) -> <v2>
<v4>: {<: Exception} NEW: magic[FAKE_INITIALIZER](e: Exception) -> <v4>
cond() <v0>: Boolean NEW: call(cond(), cond) -> <v0>
doSmth() <v1>: * NEW: call(doSmth(), doSmth) -> <v1>
{ doSmth() } <v1>: * COPY
doSmth1() <v3>: * NEW: call(doSmth1(), doSmth1) -> <v3>
{ doSmth1() } <v3>: * COPY
doSmth2() <v5>: * NEW: call(doSmth2(), doSmth2) -> <v5>
{ doSmth2() } <v5>: * COPY
cond() <v6>: Boolean NEW: call(cond(), cond) -> <v6>
return !<v7>: *
continue !<v8>: *
if (cond()) return else continue <v9>: * NEW: merge(if (cond()) return else continue|!<v7>, !<v8>) -> <v9>
{ if (cond()) return else continue } <v9>: * COPY
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } <v10>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|<v1>, <v3>, <v5>) -> <v10>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } <v10>: * COPY
while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } !<v11>: *
{ while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } } !<v11>: * COPY
=====================
== testCopy3 ==
fun testCopy3() {
@@ -99,8 +107,10 @@ doSmth1()
doSmth2() <v4>: * NEW: call(doSmth2(), doSmth2) -> <v4>
{ doSmth2() } <v4>: * COPY
cond() <v5>: Boolean NEW: call(cond(), cond) -> <v5>
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } <v6>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|<v0>, <v2>, <v4>) -> <v6>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } } <v6>: * COPY
while (cond()) !<v6>: *
{ while (cond()); } !<v6>: * COPY
try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } <v7>: * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|<v0>, <v2>, <v4>) -> <v7>
{ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } } <v7>: * COPY
=====================
== doTestCopy4 ==
fun doTestCopy4(list: List<String>?) : Int {
@@ -116,9 +126,12 @@ fun doTestCopy4(list: List<String>?) : Int {
<v0>: {<: List<String>?} NEW: magic[FAKE_INITIALIZER](list: List<String>?) -> <v0>
doSmth() <v1>: * NEW: call(doSmth(), doSmth) -> <v1>
{ doSmth() } <v1>: * COPY
list <v2>: * NEW: r(list) -> <v2>
null <v3>: * NEW: r(null) -> <v3>
list <v2>: * NEW: r(list) -> <v2>
null <v3>: * NEW: r(null) -> <v3>
list != null <v4>: Boolean NEW: call(list != null, equals|<v2>, <v3>) -> <v4>
{ } !<v5>: *
if(list != null) { } !<v5>: * COPY
{ if(list != null) { } } !<v5>: * COPY
try { doSmth() } finally { if(list != null) { } } <v1>: * COPY
{ try { doSmth() } finally { if(list != null) { } } } <v1>: * COPY
=====================
@@ -5,13 +5,15 @@ fun t1() {
}
}
---------------------
<v3>: Int NEW: magic[LOOP_RANGE_ITERATION](1..2|<v2>) -> <v3>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1..2 <v2>: {<: Iterable<Int>} NEW: call(1..2, rangeTo|<v0>, <v1>) -> <v2>
i <v4>: Int NEW: r(i) -> <v4>
doSmth(i) <v5>: * NEW: call(doSmth(i), doSmth|<v4>) -> <v5>
{ doSmth(i) } <v5>: * COPY
<v3>: Int NEW: magic[LOOP_RANGE_ITERATION](1..2|<v2>) -> <v3>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v1>: Int NEW: r(2) -> <v1>
1..2 <v2>: {<: Iterable<Int>} NEW: call(1..2, rangeTo|<v0>, <v1>) -> <v2>
i <v4>: Int NEW: r(i) -> <v4>
doSmth(i) <v5>: * NEW: call(doSmth(i), doSmth|<v4>) -> <v5>
{ doSmth(i) } <v5>: * COPY
for (i in 1..2) { doSmth(i) } !<v6>: *
{ for (i in 1..2) { doSmth(i) } } !<v6>: * COPY
=====================
== doSmth ==
fun doSmth(i: Int) {}
@@ -30,31 +30,32 @@ L0:
mark("s")
r("s") -> <v2>
w(u|<v2>)
2 jmp(L3) NEXT:[r(u) -> <v3>]
2 jmp(L3) NEXT:[r(u) -> <v4>]
L2:
read (Unit) PREV:[jf(L2|<v1>)]
L3:
r(u) -> <v3> PREV:[jmp(L3), read (Unit)]
r(u) -> <v4> PREV:[jmp(L3), read (Unit)]
mark(doSmth(u))
call(doSmth(u), doSmth|<v3>) -> <v4>
call(doSmth(u), doSmth|<v4>) -> <v5>
v(var r: String)
mark(if (b) { r = "s" } else { r = "t" })
r(b) -> <v5>
jf(L4|<v5>) NEXT:[mark({ r = "t" }), mark({ r = "s" })]
r(b) -> <v6>
jf(L4|<v6>) NEXT:[mark({ r = "t" }), mark({ r = "s" })]
3 mark({ r = "s" })
mark("s")
r("s") -> <v6>
w(r|<v6>)
2 jmp(L5) NEXT:[r(r) -> <v8>]
L4:
3 mark({ r = "t" }) PREV:[jf(L4|<v5>)]
mark("t")
r("t") -> <v7>
r("s") -> <v7>
w(r|<v7>)
2 jmp(L5) NEXT:[merge(if (b) { r = "s" } else { r = "t" }|!<v8>, !<v10>) -> <v11>]
L4:
3 mark({ r = "t" }) PREV:[jf(L4|<v6>)]
mark("t")
r("t") -> <v9>
w(r|<v9>)
L5:
2 r(r) -> <v8> PREV:[jmp(L5), w(r|<v7>)]
2 merge(if (b) { r = "s" } else { r = "t" }|!<v8>, !<v10>) -> <v11> PREV:[jmp(L5), w(r|<v9>)]
r(r) -> <v12>
mark(doSmth(r))
call(doSmth(r), doSmth|<v8>) -> <v9>
call(doSmth(r), doSmth|<v12>) -> <v13>
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -88,23 +89,23 @@ L0:
jf(L2|<v2>) NEXT:[read (Unit), mark({ return; })]
3 mark({ return; })
ret L1 NEXT:[<END>]
- 2 jmp(L3) NEXT:[r(i) -> <v3>] PREV:[]
- 2 jmp(L3) NEXT:[r(i) -> <v4>] PREV:[]
L2:
read (Unit) PREV:[jf(L2|<v2>)]
L3:
r(i) -> <v3>
r(i) -> <v4>
mark(doSmth(i))
call(doSmth(i), doSmth|<v3>) -> <v4>
call(doSmth(i), doSmth|<v4>) -> <v5>
mark(if (i is Int) { return; })
mark(i is Int)
r(i) -> <v5>
magic[IS](i is Int|<v5>) -> <v6>
jf(L4|<v6>) NEXT:[read (Unit), mark({ return; })]
r(i) -> <v6>
magic[IS](i is Int|<v6>) -> <v7>
jf(L4|<v7>) NEXT:[read (Unit), mark({ return; })]
3 mark({ return; })
ret L1 NEXT:[<END>]
- 2 jmp(L5) NEXT:[<END>] PREV:[]
L4:
read (Unit) PREV:[jf(L4|<v6>)]
read (Unit) PREV:[jf(L4|<v7>)]
L1:
L5:
1 <END> NEXT:[<SINK>] PREV:[ret L1, ret L1, read (Unit)]
@@ -16,17 +16,25 @@ fun t1(b: Boolean) {
doSmth(r)
}
---------------------
<v0>: Boolean NEW: magic[FAKE_INITIALIZER](b: Boolean) -> <v0>
b <v1>: Boolean NEW: r(b) -> <v1>
"s" <v2>: String NEW: r("s") -> <v2>
u <v3>: String NEW: r(u) -> <v3>
doSmth(u) <v4>: * NEW: call(doSmth(u), doSmth|<v3>) -> <v4>
b <v5>: Boolean NEW: r(b) -> <v5>
"s" <v6>: String NEW: r("s") -> <v6>
"t" <v7>: String NEW: r("t") -> <v7>
r <v8>: String NEW: r(r) -> <v8>
doSmth(r) <v9>: * NEW: call(doSmth(r), doSmth|<v8>) -> <v9>
{ var u: String if (b) { u = "s" } doSmth(u) var r: String if (b) { r = "s" } else { r = "t" } doSmth(r) } <v9>: * COPY
<v0>: Boolean NEW: magic[FAKE_INITIALIZER](b: Boolean) -> <v0>
b <v1>: Boolean NEW: r(b) -> <v1>
"s" <v2>: String NEW: r("s") -> <v2>
u = "s" !<v3>: *
{ u = "s" } !<v3>: * COPY
if (b) { u = "s" } !<v3>: * COPY
u <v4>: String NEW: r(u) -> <v4>
doSmth(u) <v5>: * NEW: call(doSmth(u), doSmth|<v4>) -> <v5>
b <v6>: Boolean NEW: r(b) -> <v6>
"s" <v7>: String NEW: r("s") -> <v7>
r = "s" !<v8>: *
{ r = "s" } !<v8>: * COPY
"t" <v9>: String NEW: r("t") -> <v9>
r = "t" !<v10>: *
{ r = "t" } !<v10>: * COPY
if (b) { r = "s" } else { r = "t" } <v11>: * NEW: merge(if (b) { r = "s" } else { r = "t" }|!<v8>, !<v10>) -> <v11>
r <v12>: String NEW: r(r) -> <v12>
doSmth(r) <v13>: * NEW: call(doSmth(r), doSmth|<v12>) -> <v13>
{ var u: String if (b) { u = "s" } doSmth(u) var r: String if (b) { r = "s" } else { r = "t" } doSmth(r) } <v13>: * COPY
=====================
== t2 ==
fun t2(b: Boolean) {
@@ -40,13 +48,20 @@ fun t2(b: Boolean) {
}
}
---------------------
<v0>: Boolean NEW: magic[FAKE_INITIALIZER](b: Boolean) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
b <v2>: Boolean NEW: r(b) -> <v2>
i <v3>: String NEW: r(i) -> <v3>
doSmth(i) <v4>: * NEW: call(doSmth(i), doSmth|<v3>) -> <v4>
i <v5>: * NEW: r(i) -> <v5>
i is Int <v6>: Boolean NEW: magic[IS](i is Int|<v5>) -> <v6>
<v0>: Boolean NEW: magic[FAKE_INITIALIZER](b: Boolean) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
b <v2>: Boolean NEW: r(b) -> <v2>
return !<v3>: *
{ return; } !<v3>: * COPY
if (b) { return; } !<v3>: * COPY
i <v4>: String NEW: r(i) -> <v4>
doSmth(i) <v5>: * NEW: call(doSmth(i), doSmth|<v4>) -> <v5>
i <v6>: * NEW: r(i) -> <v6>
i is Int <v7>: Boolean NEW: magic[IS](i is Int|<v6>) -> <v7>
return !<v8>: *
{ return; } !<v8>: * COPY
if (i is Int) { return; } !<v8>: * COPY
{ val i = 3 if (b) { return; } doSmth(i) if (i is Int) { return; } } !<v8>: * COPY
=====================
== doSmth ==
fun doSmth(s: String) {}
@@ -44,11 +44,11 @@ L4 [body entry point]:
mark({return})
ret L1 NEXT:[<END>]
L5 [condition entry point]:
- r(0) -> <v0> PREV:[]
- r(1) -> <v1> PREV:[]
- r(0) -> <v1> PREV:[]
- r(1) -> <v2> PREV:[]
- mark(0 > 1) PREV:[]
- call(0 > 1, compareTo|<v0>, <v1>) -> <v2> PREV:[]
- jt(L2 [loop entry point]|<v2>) NEXT:[read (Unit), mark({return})] PREV:[]
- call(0 > 1, compareTo|<v1>, <v2>) -> <v3> PREV:[]
- jt(L2 [loop entry point]|<v3>) NEXT:[read (Unit), mark({return})] PREV:[]
L3 [loop exit point]:
- read (Unit) PREV:[]
L1:
@@ -5,11 +5,13 @@ fun main() {
}
}
---------------------
0 <v0>: {<: Comparable<Int>} NEW: r(0) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
0 > 1 <v2>: Boolean NEW: call(0 > 1, compareTo|<v0>, <v1>) -> <v2>
2 <v3>: * NEW: r(2) -> <v3>
{ 2 } <v3>: * COPY
0 <v0>: {<: Comparable<Int>} NEW: r(0) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
0 > 1 <v2>: Boolean NEW: call(0 > 1, compareTo|<v0>, <v1>) -> <v2>
2 <v3>: * NEW: r(2) -> <v3>
{ 2 } <v3>: * COPY
while(0 > 1) { 2 } !<v4>: *
{ while(0 > 1) { 2 } } !<v4>: * COPY
=====================
== dowhile ==
fun dowhile() {
@@ -17,7 +19,11 @@ fun dowhile() {
while(0 > 1)
}
---------------------
0 <v0>: {<: Comparable<Int>} NEW: r(0) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
0 > 1 <v2>: Boolean NEW: call(0 > 1, compareTo|<v0>, <v1>) -> <v2>
return !<v0>: *
{return} !<v0>: * COPY
0 <v1>: {<: Comparable<Int>} NEW: r(0) -> <v1>
1 <v2>: Int NEW: r(1) -> <v2>
0 > 1 <v3>: Boolean NEW: call(0 > 1, compareTo|<v1>, <v2>) -> <v3>
do {return} while(0 > 1) !<v4>: *
{ do {return} while(0 > 1) } !<v4>: * COPY
=====================
@@ -5,8 +5,11 @@ fun illegalWhenBlock(a: Any): Any {
}
}
---------------------
<v0>: {<: Any} NEW: magic[FAKE_INITIALIZER](a: Any) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
is Int <v2>: * NEW: magic[IS](is Int|<v1>) -> <v2>
a <v3>: {<: Any} NEW: r(a) -> <v3>
<v0>: {<: Any} NEW: magic[FAKE_INITIALIZER](a: Any) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
is Int <v2>: * NEW: magic[IS](is Int|<v1>) -> <v2>
a <v3>: {<: Any} NEW: r(a) -> <v3>
return a !<v4>: *
when(a) { is Int -> return a } !<v4>: * COPY
{ when(a) { is Int -> return a } } !<v4>: * COPY
=====================
@@ -11,7 +11,7 @@ fun foo(a: Number) {
}
---------------------
<v0>: {<: Number} NEW: magic[FAKE_INITIALIZER](a: Number) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
a <v1>: * NEW: r(a) -> <v1>
1 <v2>: * NEW: r(1) -> <v2>
1 <v3>: * NEW: magic[EQUALS_IN_WHEN_CONDITION](1|<v1>, <v2>) -> <v3>
"1" <v4>: {<: String?} NEW: r("1") -> <v4>
@@ -4,9 +4,12 @@ fun foo(a: Int, b: Int) {
}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a == b <v4>: Boolean NEW: call(a == b, equals|<v2>, <v3>) -> <v4>
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a == b <v4>: Boolean NEW: call(a == b, equals|<v2>, <v3>) -> <v4>
{ } !<v5>: *
if (a == b) { } !<v5>: * COPY
{ if (a == b) { } } !<v5>: * COPY
=====================
@@ -3,9 +3,12 @@ fun neq(a: Int, b: Int) {
if (a != b) {}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a != b <v4>: Boolean NEW: call(a != b, equals|<v2>, <v3>) -> <v4>
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a != b <v4>: Boolean NEW: call(a != b, equals|<v2>, <v3>) -> <v4>
{} !<v5>: *
if (a != b) {} !<v5>: * COPY
{ if (a != b) {} } !<v5>: * COPY
=====================
@@ -6,15 +6,16 @@ fun foo() {
L0:
1 <START>
2 mark({ return ?: null })
ret L1 NEXT:[<END>]
- mark(return ?: null) PREV:[]
- jt(L2) NEXT:[r(null) -> <v0>, <END>] PREV:[]
- r(null) -> <v0> PREV:[]
L1:
ret L1 NEXT:[<END>]
- mark(return ?: null) PREV:[]
- jt(L2) NEXT:[r(null) -> <v0>, merge(return ?: null|!<v1>, <v0>) -> <v2>] PREV:[]
- r(null) -> <v0> PREV:[]
L2:
1 <END> NEXT:[<SINK>] PREV:[ret L1]
- merge(return ?: null|!<v1>, <v0>) -> <v2> PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret L1]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,7 +3,8 @@ fun foo() {
return ?: null
}
---------------------
null <v0>: * NEW: r(null) -> <v0>
return ?: null <v0>: * COPY
{ return ?: null } <v0>: * COPY
return !<v1>: *
null <v0>: * NEW: r(null) -> <v0>
return ?: null <v2>: * NEW: merge(return ?: null|!<v1>, <v0>) -> <v2>
{ return ?: null } <v2>: * COPY
=====================
@@ -10,13 +10,13 @@ L0:
mark(throw Exception())
mark(Exception())
call(Exception(), <init>) -> <v0>
throw (throw Exception()|<v0>) NEXT:[<ERROR>]
- r(1) -> <v1> PREV:[]
- magic[STRING_TEMPLATE]("${throw Exception()} ${1}"|<v1>) -> <v2> PREV:[]
throw (throw Exception()|<v0>) NEXT:[<ERROR>]
- r(1) -> <v1> PREV:[]
- magic[STRING_TEMPLATE]("${throw Exception()} ${1}"|!<v2>, <v1>) -> <v3> PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[]
1 <END> NEXT:[<SINK>] PREV:[]
error:
<ERROR> PREV:[throw (throw Exception()|<v0>)]
<ERROR> PREV:[throw (throw Exception()|<v0>)]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,8 +3,9 @@ fun test() {
"${throw Exception()} ${1}"
}
---------------------
Exception() <v0>: {<: Throwable} NEW: call(Exception(), <init>) -> <v0>
1 <v1>: * NEW: r(1) -> <v1>
"${throw Exception()} ${1}" <v2>: * NEW: magic[STRING_TEMPLATE]("${throw Exception()} ${1}"|<v1>) -> <v2>
{ "${throw Exception()} ${1}" } <v2>: * COPY
Exception() <v0>: {<: Throwable} NEW: call(Exception(), <init>) -> <v0>
throw Exception() !<v2>: *
1 <v1>: * NEW: r(1) -> <v1>
"${throw Exception()} ${1}" <v3>: * NEW: magic[STRING_TEMPLATE]("${throw Exception()} ${1}"|!<v2>, <v1>) -> <v3>
{ "${throw Exception()} ${1}" } <v3>: * COPY
=====================
@@ -27,9 +27,9 @@ L0:
w($i|<v1>, <v2>)
1 v(val j: Int get() = 20)
2 mark({ $i = 13 })
magic[IMPLICIT_RECEIVER]($i) -> <v3>
r(13) -> <v4>
w($i|<v3>, <v4>)
magic[IMPLICIT_RECEIVER]($i) -> <v4>
r(13) -> <v5>
w($i|<v4>, <v5>)
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -15,9 +15,13 @@ class AnonymousInitializers() {
}
}
---------------------
<v1>: AnonymousInitializers NEW: magic[IMPLICIT_RECEIVER]($i) -> <v1>
<v3>: AnonymousInitializers NEW: magic[IMPLICIT_RECEIVER]($i) -> <v3>
34 <v0>: Int NEW: r(34) -> <v0>
12 <v2>: Int NEW: r(12) -> <v2>
13 <v4>: Int NEW: r(13) -> <v4>
<v1>: AnonymousInitializers NEW: magic[IMPLICIT_RECEIVER]($i) -> <v1>
<v4>: AnonymousInitializers NEW: magic[IMPLICIT_RECEIVER]($i) -> <v4>
34 <v0>: Int NEW: r(34) -> <v0>
12 <v2>: Int NEW: r(12) -> <v2>
$i = 12 !<v3>: *
{ $i = 12 } !<v3>: * COPY
13 <v5>: Int NEW: r(13) -> <v5>
$i = 13 !<v6>: *
{ $i = 13 } !<v6>: * COPY
=====================
@@ -3,6 +3,8 @@ fun fail() : Nothing {
throw java.lang.RuntimeException()
}
---------------------
RuntimeException() <v0>: {<: Throwable} NEW: call(RuntimeException(), <init>) -> <v0>
java.lang.RuntimeException() <v0>: {<: Throwable} COPY
RuntimeException() <v0>: {<: Throwable} NEW: call(RuntimeException(), <init>) -> <v0>
java.lang.RuntimeException() <v0>: {<: Throwable} COPY
throw java.lang.RuntimeException() !<v1>: *
{ throw java.lang.RuntimeException() } !<v1>: * COPY
=====================
@@ -66,8 +66,8 @@ L0:
magic[IMPLICIT_RECEIVER]($x) -> <v0>
r(1) -> <v1>
w($x|<v0>, <v1>)
2 r(object { val x : Int { $x = 1 } }) -> <v2>
w(a|<v2>)
2 r(object { val x : Int { $x = 1 } }) -> <v3>
w(a|<v3>)
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -196,11 +196,11 @@ L0:
magic[IMPLICIT_RECEIVER]($x) -> <v0>
r(1) -> <v1>
w($x|<v0>, <v1>)
2 jmp?(L2) NEXT:[r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v2>, d(fun ggg() { y = 10 })]
2 jmp?(L2) NEXT:[r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v3>, d(fun ggg() { y = 10 })]
d(fun ggg() { y = 10 }) NEXT:[<SINK>]
L2:
r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v2> PREV:[jmp?(L2)]
w(a|<v2>)
r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v3> PREV:[jmp?(L2)]
w(a|<v3>)
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -257,11 +257,11 @@ L0:
2 jmp?(L2) NEXT:[jmp?(L5), d(fun foo() { x = 3 })]
d(fun foo() { x = 3 }) NEXT:[<SINK>]
L2:
jmp?(L5) NEXT:[r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v3>, d(fun bar() { x = 4 })] PREV:[jmp?(L2)]
jmp?(L5) NEXT:[r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v4>, d(fun bar() { x = 4 })] PREV:[jmp?(L2)]
d(fun bar() { x = 4 }) NEXT:[<SINK>]
L5:
r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v3> PREV:[jmp?(L5)]
w(a|<v3>)
r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v4> PREV:[jmp?(L5)]
w(a|<v4>)
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -36,7 +36,9 @@ fun test1() {
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER]($x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
object { val x : Int { $x = 1 } } <v2>: <no name provided> NEW: r(object { val x : Int { $x = 1 } }) -> <v2>
$x = 1 !<v2>: *
{ $x = 1 } !<v2>: * COPY
object { val x : Int { $x = 1 } } <v3>: <no name provided> NEW: r(object { val x : Int { $x = 1 } }) -> <v3>
=====================
== O ==
object O {
@@ -46,8 +48,10 @@ object O {
}
}
---------------------
<v0>: O NEW: magic[IMPLICIT_RECEIVER]($x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
<v0>: O NEW: magic[IMPLICIT_RECEIVER]($x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
$x = 1 !<v2>: *
{ $x = 1 } !<v2>: * COPY
=====================
== test2 ==
fun test2() {
@@ -78,8 +82,10 @@ fun inner_bar() {
y = 10
}
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](y) -> <v0>
10 <v1>: Int NEW: r(10) -> <v1>
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](y) -> <v0>
10 <v1>: Int NEW: r(10) -> <v1>
y = 10 !<v2>: *
{ y = 10 } !<v2>: * COPY
=====================
== test4 ==
fun test4() {
@@ -97,15 +103,19 @@ fun test4() {
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER]($x) -> <v0>
1 <v1>: Int NEW: r(1) -> <v1>
object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } } <v2>: <no name provided> NEW: r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v2>
$x = 1 !<v2>: *
{ $x = 1 } !<v2>: * COPY
object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } } <v3>: <no name provided> NEW: r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v3>
=====================
== ggg ==
fun ggg() {
y = 10
}
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](y) -> <v0>
10 <v1>: Int NEW: r(10) -> <v1>
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](y) -> <v0>
10 <v1>: Int NEW: r(10) -> <v1>
y = 10 !<v2>: *
{ y = 10 } !<v2>: * COPY
=====================
== test5 ==
fun test5() {
@@ -126,21 +136,27 @@ fun test5() {
<v1>: <no name provided> NEW: magic[IMPLICIT_RECEIVER]($x) -> <v1>
1 <v0>: Int NEW: r(1) -> <v0>
2 <v2>: Int NEW: r(2) -> <v2>
object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } } <v3>: <no name provided> NEW: r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v3>
$x = 2 !<v3>: *
{ $x = 2 } !<v3>: * COPY
object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } } <v4>: <no name provided> NEW: r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v4>
=====================
== foo ==
fun foo() {
x = 3
}
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
3 <v1>: Int NEW: r(3) -> <v1>
x = 3 !<v2>: *
{ x = 3 } !<v2>: * COPY
=====================
== bar ==
fun bar() {
x = 4
}
---------------------
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
4 <v1>: Int NEW: r(4) -> <v1>
<v0>: <no name provided> NEW: magic[IMPLICIT_RECEIVER](x) -> <v0>
4 <v1>: Int NEW: r(4) -> <v1>
x = 4 !<v2>: *
{ x = 4 } !<v2>: * COPY
=====================
@@ -25,11 +25,13 @@ fun foo(b: B) : Int {
return o.foo()
}
---------------------
<v0>: B NEW: magic[FAKE_INITIALIZER](b: B) -> <v0>
<v2>: * NEW: magic[VALUE_CONSUMER](A by b|<v1>) -> <v2>
b <v1>: {<: A} NEW: r(b) -> <v1>
object : A by b {} <v3>: <no name provided> NEW: r(object : A by b {}) -> <v3>
o <v4>: {<: A} NEW: r(o) -> <v4>
foo() <v5>: Int NEW: call(foo(), foo|<v4>) -> <v5>
o.foo() <v5>: Int COPY
<v0>: B NEW: magic[FAKE_INITIALIZER](b: B) -> <v0>
<v2>: * NEW: magic[VALUE_CONSUMER](A by b|<v1>) -> <v2>
b <v1>: {<: A} NEW: r(b) -> <v1>
object : A by b {} <v3>: <no name provided> NEW: r(object : A by b {}) -> <v3>
o <v4>: {<: A} NEW: r(o) -> <v4>
foo() <v5>: Int NEW: call(foo(), foo|<v4>) -> <v5>
o.foo() <v5>: Int COPY
return o.foo() !<v6>: *
{ val o = object : A by b {} return o.foo() } !<v6>: * COPY
=====================
@@ -16,5 +16,7 @@ get() {
return b
}
---------------------
b <v0>: Int NEW: r(b) -> <v0>
b <v0>: Int NEW: r(b) -> <v0>
return b !<v1>: *
{ val b: Int return b } !<v1>: * COPY
=====================
@@ -7,16 +7,16 @@ L0:
1 <START>
2 mark({ false || (return false) })
r(false) -> <v0>
jt(L2|<v0>) NEXT:[mark((return false)), magic[OR](false || (return false)|<v0>) -> <v2>]
jt(L2|<v0>) NEXT:[mark((return false)), magic[OR](false || (return false)|<v0>, !<v2>) -> <v3>]
mark((return false))
r(false) -> <v1>
ret(*|<v1>) L1 NEXT:[<END>]
ret(*|<v1>) L1 NEXT:[<END>]
L2:
magic[OR](false || (return false)|<v0>) -> <v2> PREV:[jt(L2|<v0>)]
magic[OR](false || (return false)|<v0>, !<v2>) -> <v3> PREV:[jt(L2|<v0>)]
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v1>) L1, magic[OR](false || (return false)|<v0>) -> <v2>]
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v1>) L1, magic[OR](false || (return false)|<v0>, !<v2>) -> <v3>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,8 +3,10 @@ fun blockAndAndMismatch() : Boolean {
false || (return false)
}
---------------------
false <v0>: Boolean NEW: r(false) -> <v0>
false <v1>: Boolean NEW: r(false) -> <v1>
false || (return false) <v2>: * NEW: magic[OR](false || (return false)|<v0>) -> <v2>
{ false || (return false) } <v2>: * COPY
false <v0>: Boolean NEW: r(false) -> <v0>
false <v1>: Boolean NEW: r(false) -> <v1>
return false !<v2>: *
(return false) !<v2>: * COPY
false || (return false) <v3>: * NEW: magic[OR](false || (return false)|<v0>, !<v2>) -> <v3>
{ false || (return false) } <v3>: * COPY
=====================
@@ -48,7 +48,7 @@ L0:
- call(bar(), bar) PREV:[]
- jmp(error) NEXT:[<ERROR>] PREV:[]
- mark(doSomething) PREV:[]
- call(doSomething, doSomething) -> <v3> PREV:[]
- call(doSomething, doSomething|!<v3>) -> <v4> PREV:[]
L1:
1 <END> NEXT:[<SINK>] PREV:[]
error:
@@ -13,11 +13,12 @@ fun foo() {
bar().doSomething
}
---------------------
null <v0>: * NEW: r(null) -> <v0>
null!! <v1>: * NEW: magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
doSomething() <v2>: * NEW: call(doSomething(), doSomething|<v1>) -> <v2>
null!!.doSomething() <v2>: * COPY
doSomething <v3>: * NEW: call(doSomething, doSomething) -> <v3>
bar().doSomething <v3>: * COPY
{ null!!.doSomething() bar().doSomething } <v3>: * COPY
null <v0>: * NEW: r(null) -> <v0>
null!! <v1>: * NEW: magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
doSomething() <v2>: * NEW: call(doSomething(), doSomething|<v1>) -> <v2>
null!!.doSomething() <v2>: * COPY
bar() !<v3>: *
doSomething <v4>: * NEW: call(doSomething, doSomething|!<v3>) -> <v4>
bar().doSomething <v4>: * COPY
{ null!!.doSomething() bar().doSomething } <v4>: * COPY
=====================
@@ -7,11 +7,11 @@ L0:
1 <START>
2 mark({ this() })
mark(this())
call(this(), invoke) -> <v0>
call(this(), invoke|!<v0>) -> <v1>
L1:
1 <END> NEXT:[<SINK>]
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,6 +3,8 @@ fun Function0<Unit>.foo() {
this()
}
---------------------
this() <v0>: * NEW: call(this(), invoke) -> <v0>
{ this() } <v0>: * COPY
=====================
this !<v0>: * COPY
this !<v0>: *
this() <v1>: * NEW: call(this(), invoke|!<v0>) -> <v1>
{ this() } <v1>: * COPY
=====================
@@ -14,11 +14,11 @@ L0:
error(foo, No resolved call)
r(a) -> <v1>
mark(foo())
magic[UNRESOLVED_CALL](foo()|<v1>) -> <v2>
magic[UNRESOLVED_CALL](foo()|!<v2>, <v1>) -> <v3>
L1:
1 <END> NEXT:[<SINK>]
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -3,9 +3,10 @@ fun test(a: Any) {
a.foo()
}
---------------------
<v0>: {<: Any} NEW: magic[FAKE_INITIALIZER](a: Any) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
foo() <v2>: * NEW: magic[UNRESOLVED_CALL](foo()|<v1>) -> <v2>
a.foo() <v2>: * COPY
{ a.foo() } <v2>: * COPY
<v0>: {<: Any} NEW: magic[FAKE_INITIALIZER](a: Any) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
foo !<v2>: *
foo() <v3>: * NEW: magic[UNRESOLVED_CALL](foo()|!<v2>, <v1>) -> <v3>
a.foo() <v3>: * COPY
{ a.foo() } <v3>: * COPY
=====================
@@ -7,6 +7,9 @@ tailRecursive fun test() : Int {
}
}
---------------------
test() <v0>: * NEW: call(test(), test) -> <v0>
{ test() } <v0>: * COPY
=====================
{ // do nothing } !<v1>: *
test() <v0>: * NEW: call(test(), test) -> <v0>
{ test() } <v0>: * COPY
try { // do nothing } finally { test() } !<v1>: * COPY
{ try { // do nothing } finally { test() } } !<v1>: * COPY
=====================
@@ -7,5 +7,10 @@ tailRecursive fun test() : Int {
}
}
---------------------
test() <v0>: Int NEW: call(test(), test) -> <v0>
=====================
{ // do nothing } !<v2>: *
test() <v0>: Int NEW: call(test(), test) -> <v0>
return test() !<v1>: *
{ return test() } !<v1>: * COPY
try { // do nothing } finally { return test() } !<v2>: * COPY
{ try { // do nothing } finally { return test() } } !<v2>: * COPY
=====================
@@ -24,23 +24,23 @@ L0:
jf(L2|<v5>) NEXT:[read (Unit), r(sum) -> <v6>]
r(sum) -> <v6>
ret(*|<v6>) L1 NEXT:[<END>]
- jmp(L3) NEXT:[r(x) -> <v7>] PREV:[]
- jmp(L3) NEXT:[r(x) -> <v8>] PREV:[]
L2:
read (Unit) PREV:[jf(L2|<v5>)]
L3:
r(x) -> <v7>
r(1) -> <v8>
r(x) -> <v8>
r(1) -> <v9>
mark(x - 1)
call(x - 1, minus|<v7>, <v8>) -> <v9>
r(sum) -> <v10>
r(x) -> <v11>
call(x - 1, minus|<v8>, <v9>) -> <v10>
r(sum) -> <v11>
r(x) -> <v12>
mark(sum + x)
call(sum + x, plus|<v10>, <v11>) -> <v12>
call(sum + x, plus|<v11>, <v12>) -> <v13>
mark(sum(x - 1, sum + x))
call(sum(x - 1, sum + x), sum|<v9>, <v12>) -> <v13>
ret(*|<v13>) L1
call(sum(x - 1, sum + x), sum|<v10>, <v13>) -> <v14>
ret(*|<v14>) L1
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v6>) L1, ret(*|<v13>) L1]
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v6>) L1, ret(*|<v14>) L1]
error:
<ERROR> PREV:[]
sink:
+19 -15
View File
@@ -4,19 +4,23 @@ tailRecursive fun sum(x: Long, sum: Long): Long {
return sum(x - 1, sum + x)
}
---------------------
<v0>: Long NEW: magic[FAKE_INITIALIZER](x: Long) -> <v0>
<v1>: Long NEW: magic[FAKE_INITIALIZER](sum: Long) -> <v1>
x <v2>: OR{{<: Any}, {<: Any}} NEW: r(x) -> <v2>
0 <v3>: {<: Number} NEW: r(0) -> <v3>
toLong() <v4>: * NEW: call(toLong(), toLong|<v3>) -> <v4>
0.toLong() <v4>: * COPY
x == 0.toLong() <v5>: Boolean NEW: call(x == 0.toLong(), equals|<v2>, <v4>) -> <v5>
sum <v6>: Long NEW: r(sum) -> <v6>
x <v7>: Long NEW: r(x) -> <v7>
1 <v8>: Int NEW: r(1) -> <v8>
x - 1 <v9>: Long NEW: call(x - 1, minus|<v7>, <v8>) -> <v9>
sum <v10>: Long NEW: r(sum) -> <v10>
x <v11>: Long NEW: r(x) -> <v11>
sum + x <v12>: Long NEW: call(sum + x, plus|<v10>, <v11>) -> <v12>
sum(x - 1, sum + x) <v13>: Long NEW: call(sum(x - 1, sum + x), sum|<v9>, <v12>) -> <v13>
<v0>: Long NEW: magic[FAKE_INITIALIZER](x: Long) -> <v0>
<v1>: Long NEW: magic[FAKE_INITIALIZER](sum: Long) -> <v1>
x <v2>: OR{{<: Any}, {<: Any}} NEW: r(x) -> <v2>
0 <v3>: {<: Number} NEW: r(0) -> <v3>
toLong() <v4>: * NEW: call(toLong(), toLong|<v3>) -> <v4>
0.toLong() <v4>: * COPY
x == 0.toLong() <v5>: Boolean NEW: call(x == 0.toLong(), equals|<v2>, <v4>) -> <v5>
sum <v6>: Long NEW: r(sum) -> <v6>
return sum !<v7>: *
if (x == 0.toLong()) return sum !<v7>: * COPY
x <v8>: Long NEW: r(x) -> <v8>
1 <v9>: Int NEW: r(1) -> <v9>
x - 1 <v10>: Long NEW: call(x - 1, minus|<v8>, <v9>) -> <v10>
sum <v11>: Long NEW: r(sum) -> <v11>
x <v12>: Long NEW: r(x) -> <v12>
sum + x <v13>: Long NEW: call(sum + x, plus|<v11>, <v12>) -> <v13>
sum(x - 1, sum + x) <v14>: Long NEW: call(sum(x - 1, sum + x), sum|<v10>, <v13>) -> <v14>
return sum(x - 1, sum + x) !<v15>: *
{ if (x == 0.toLong()) return sum return sum(x - 1, sum + x) } !<v15>: * COPY
=====================
@@ -11,24 +11,25 @@ L0:
1 <START>
2 mark({ try { return foo() } catch (e: Throwable) { } })
mark(try { return foo() } catch (e: Throwable) { })
jmp?(L2 [onException]) NEXT:[v(e: Throwable), mark({ return foo() })]
jmp?(L2 [onException]) NEXT:[v(e: Throwable), mark({ return foo() })]
3 mark({ return foo() })
mark(foo())
call(foo(), foo) -> <v0>
ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L3 [afterCatches]) NEXT:[<END>] PREV:[]
ret(*|<v0>) L1 NEXT:[<END>]
- 2 jmp(L3 [afterCatches]) NEXT:[merge(try { return foo() } catch (e: Throwable) { }|!<v1>, !<v3>) -> <v4>] PREV:[]
L2 [onException]:
3 v(e: Throwable) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: Throwable) -> <v1>
w(e|<v1>)
3 v(e: Throwable) PREV:[jmp?(L2 [onException])]
magic[FAKE_INITIALIZER](e: Throwable) -> <v2>
w(e|<v2>)
4 mark({ })
read (Unit)
3 jmp(L3 [afterCatches])
L1:
L3 [afterCatches]:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, jmp(L3 [afterCatches])]
2 merge(try { return foo() } catch (e: Throwable) { }|!<v1>, !<v3>) -> <v4>
L1:
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, merge(try { return foo() } catch (e: Throwable) { }|!<v1>, !<v3>) -> <v4>]
error:
<ERROR> PREV:[]
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
<SINK> PREV:[<ERROR>, <END>]
=====================
+7 -2
View File
@@ -7,6 +7,11 @@ tailRecursive fun foo() {
}
}
---------------------
<v1>: {<: Throwable} NEW: magic[FAKE_INITIALIZER](e: Throwable) -> <v1>
foo() <v0>: Unit NEW: call(foo(), foo) -> <v0>
<v2>: {<: Throwable} NEW: magic[FAKE_INITIALIZER](e: Throwable) -> <v2>
foo() <v0>: Unit NEW: call(foo(), foo) -> <v0>
return foo() !<v1>: *
{ return foo() } !<v1>: * COPY
{ } !<v3>: *
try { return foo() } catch (e: Throwable) { } <v4>: * NEW: merge(try { return foo() } catch (e: Throwable) { }|!<v1>, !<v3>) -> <v4>
{ try { return foo() } catch (e: Throwable) { } } <v4>: * COPY
=====================
@@ -1,6 +1,6 @@
fun test() {
run1 @f{(): Int ->
(return@f 1): Nothing
(return@f 1)<!UNREACHABLE_CODE!>: Nothing<!>
}
}
@@ -54,7 +54,10 @@ public abstract class AbstractPseudoValueTest : AbstractPseudocodeTest() {
}
fun valueDescription(element: JetElement?, value: PseudoValue): String {
return if (value.element != element) "COPY" else "NEW: ${value.createdAt}"
return when {
value.element != element -> "COPY"
else -> value.createdAt?.let { "NEW: $it" } ?: ""
}
}
val elementToValues = getElementToValueMap(pseudocode)