Pseudocode: Introduce pseudo-value analysis
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudoValue;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
@@ -64,16 +65,16 @@ public interface JetControlFlowBuilder {
|
||||
|
||||
// Jumps
|
||||
void jump(@NotNull Label label, @NotNull JetElement element);
|
||||
void jumpOnFalse(@NotNull Label label, @NotNull JetElement element);
|
||||
void jumpOnTrue(@NotNull Label label, @NotNull JetElement element);
|
||||
void nondeterministicJump(@NotNull Label label, @NotNull JetElement element); // Maybe, jump to label
|
||||
void jumpOnFalse(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue);
|
||||
void jumpOnTrue(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue);
|
||||
void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue); // Maybe, jump to label
|
||||
void nondeterministicJump(@NotNull List<Label> label, @NotNull JetElement element);
|
||||
void jumpToError(@NotNull JetElement element);
|
||||
|
||||
void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine);
|
||||
void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine);
|
||||
void returnValue(@NotNull JetReturnExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull JetElement subroutine);
|
||||
void returnNoValue(@NotNull JetReturnExpression returnExpression, @NotNull JetElement subroutine);
|
||||
|
||||
void throwException(@NotNull JetThrowExpression throwExpression);
|
||||
void throwException(@NotNull JetThrowExpression throwExpression, @NotNull PseudoValue thrownValue);
|
||||
|
||||
// Loops
|
||||
LoopInfo enterLoop(@NotNull JetExpression expression, @Nullable Label loopExitPoint, @Nullable Label conditionEntryPoint);
|
||||
@@ -91,27 +92,54 @@ public interface JetControlFlowBuilder {
|
||||
// Reading values
|
||||
void mark(@NotNull JetElement element);
|
||||
|
||||
@Nullable
|
||||
PseudoValue getBoundValue(@Nullable JetElement element);
|
||||
void bindValue(@NotNull PseudoValue value, @NotNull JetElement element);
|
||||
|
||||
void loadUnit(@NotNull JetExpression expression);
|
||||
void loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant);
|
||||
void createAnonymousObject(@NotNull JetObjectLiteralExpression expression);
|
||||
void createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression);
|
||||
void loadStringTemplate(@NotNull JetStringTemplateExpression expression);
|
||||
|
||||
void readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor);
|
||||
void readVariable(@NotNull JetExpression expression, @Nullable VariableDescriptor variableDescriptor);
|
||||
@NotNull
|
||||
PseudoValue loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant);
|
||||
@NotNull
|
||||
PseudoValue createAnonymousObject(@NotNull JetObjectLiteralExpression expression);
|
||||
@NotNull
|
||||
PseudoValue createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression);
|
||||
@NotNull
|
||||
PseudoValue loadStringTemplate(@NotNull JetStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues);
|
||||
|
||||
void call(@NotNull JetExpression expression, @NotNull ResolvedCall<?> resolvedCall);
|
||||
@NotNull
|
||||
PseudoValue magic(
|
||||
@NotNull JetElement instructionElement,
|
||||
@Nullable JetElement valueElement,
|
||||
@NotNull List<PseudoValue> inputValues,
|
||||
boolean synthetic
|
||||
);
|
||||
|
||||
@NotNull
|
||||
PseudoValue readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor);
|
||||
@NotNull
|
||||
PseudoValue readVariable(
|
||||
@NotNull JetExpression expression, @Nullable VariableDescriptor variableDescriptor, @Nullable PseudoValue receiverValue
|
||||
);
|
||||
|
||||
@Nullable
|
||||
PseudoValue call(@NotNull JetExpression expression, @NotNull ResolvedCall<?> resolvedCall, @NotNull List<PseudoValue> inputValues);
|
||||
|
||||
enum PredefinedOperation {
|
||||
AND,
|
||||
OR,
|
||||
NOT_NULL_ASSERTION
|
||||
}
|
||||
void predefinedOperation(@NotNull JetExpression expression, @Nullable PredefinedOperation operation);
|
||||
@NotNull
|
||||
PseudoValue predefinedOperation(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull PredefinedOperation operation,
|
||||
@NotNull List<PseudoValue> inputValues
|
||||
);
|
||||
|
||||
void compilationError(@NotNull JetElement element, @NotNull String message);
|
||||
|
||||
void write(@NotNull JetElement assignment, @NotNull JetElement lValue);
|
||||
void write(@NotNull JetElement assignment, @NotNull JetElement lValue, @NotNull PseudoValue rValue, @Nullable PseudoValue receiverValue);
|
||||
|
||||
// Other
|
||||
void unsupported(JetElement element);
|
||||
|
||||
+71
-29
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudoValue;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
@@ -37,44 +38,70 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
getDelegateBuilder().loadUnit(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant) {
|
||||
getDelegateBuilder().loadConstant(expression, constant);
|
||||
public PseudoValue loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant) {
|
||||
return getDelegateBuilder().loadConstant(expression, constant);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void createAnonymousObject(@NotNull JetObjectLiteralExpression expression) {
|
||||
getDelegateBuilder().createAnonymousObject(expression);
|
||||
public PseudoValue createAnonymousObject(@NotNull JetObjectLiteralExpression expression) {
|
||||
return getDelegateBuilder().createAnonymousObject(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression) {
|
||||
getDelegateBuilder().createFunctionLiteral(expression);
|
||||
public PseudoValue createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression) {
|
||||
return getDelegateBuilder().createFunctionLiteral(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void loadStringTemplate(@NotNull JetStringTemplateExpression expression) {
|
||||
getDelegateBuilder().loadStringTemplate(expression);
|
||||
public PseudoValue loadStringTemplate(@NotNull JetStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues) {
|
||||
return getDelegateBuilder().loadStringTemplate(expression, inputValues);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor) {
|
||||
getDelegateBuilder().readThis(expression, parameterDescriptor);
|
||||
public PseudoValue magic(
|
||||
@NotNull JetElement instructionElement,
|
||||
@Nullable JetElement valueElement,
|
||||
@NotNull List<PseudoValue> inputValues,
|
||||
boolean synthetic
|
||||
) {
|
||||
return getDelegateBuilder().magic(instructionElement, valueElement, inputValues, synthetic);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void readVariable(@NotNull JetExpression expression, @Nullable VariableDescriptor variableDescriptor) {
|
||||
getDelegateBuilder().readVariable(expression, variableDescriptor);
|
||||
public PseudoValue readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor) {
|
||||
return getDelegateBuilder().readThis(expression, parameterDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void call(@NotNull JetExpression expression, @NotNull ResolvedCall<?> resolvedCall) {
|
||||
getDelegateBuilder().call(expression, resolvedCall);
|
||||
public PseudoValue readVariable(
|
||||
@NotNull JetExpression expression,
|
||||
@Nullable VariableDescriptor variableDescriptor,
|
||||
@Nullable PseudoValue receiverValue) {
|
||||
return getDelegateBuilder().readVariable(expression, variableDescriptor, receiverValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void predefinedOperation(@NotNull JetExpression expression, @Nullable PredefinedOperation operation) {
|
||||
getDelegateBuilder().predefinedOperation(expression, operation);
|
||||
public PseudoValue call(@NotNull JetExpression expression, @NotNull ResolvedCall<?> resolvedCall, @NotNull List<PseudoValue> inputValues) {
|
||||
return getDelegateBuilder().call(expression, resolvedCall, inputValues);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PseudoValue predefinedOperation(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull PredefinedOperation operation,
|
||||
@NotNull List<PseudoValue> inputValues
|
||||
) {
|
||||
return getDelegateBuilder().predefinedOperation(expression, operation, inputValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,18 +132,18 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().jumpOnFalse(label, element);
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue) {
|
||||
getDelegateBuilder().jumpOnFalse(label, element, conditionValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().jumpOnTrue(label, element);
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue) {
|
||||
getDelegateBuilder().jumpOnTrue(label, element, conditionValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element) {
|
||||
getDelegateBuilder().nondeterministicJump(label, element);
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue) {
|
||||
getDelegateBuilder().nondeterministicJump(label, element, inputValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,8 +157,8 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
}
|
||||
|
||||
@Override
|
||||
public void throwException(@NotNull JetThrowExpression throwExpression) {
|
||||
getDelegateBuilder().throwException(throwExpression);
|
||||
public void throwException(@NotNull JetThrowExpression throwExpression, @NotNull PseudoValue thrownValue) {
|
||||
getDelegateBuilder().throwException(throwExpression, thrownValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,12 +223,12 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
getDelegateBuilder().returnValue(returnExpression, subroutine);
|
||||
public void returnValue(@NotNull JetReturnExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull JetElement subroutine) {
|
||||
getDelegateBuilder().returnValue(returnExpression, returnValue, subroutine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine) {
|
||||
public void returnNoValue(@NotNull JetReturnExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
getDelegateBuilder().returnNoValue(returnExpression, subroutine);
|
||||
}
|
||||
|
||||
@@ -211,8 +238,12 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull JetElement assignment, @NotNull JetElement lValue) {
|
||||
getDelegateBuilder().write(assignment, lValue);
|
||||
public void write(
|
||||
@NotNull JetElement assignment,
|
||||
@NotNull JetElement lValue,
|
||||
@NotNull PseudoValue rValue,
|
||||
@Nullable PseudoValue receiverValue) {
|
||||
getDelegateBuilder().write(assignment, lValue, rValue, receiverValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -240,6 +271,17 @@ public abstract class JetControlFlowBuilderAdapter implements JetControlFlowBuil
|
||||
getDelegateBuilder().mark(element);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PseudoValue getBoundValue(@Nullable JetElement element) {
|
||||
return getDelegateBuilder().getBoundValue(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindValue(@NotNull PseudoValue value, @NotNull JetElement element) {
|
||||
getDelegateBuilder().bindValue(value, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterLexicalScope(@NotNull JetElement element) {
|
||||
getDelegateBuilder().enterLexicalScope(element);
|
||||
|
||||
@@ -21,9 +21,13 @@ import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.Function0;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowInstructionsGenerator;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudoValue;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -47,9 +51,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.cfg.JetControlFlowBuilder.PredefinedOperation.*;
|
||||
import static org.jetbrains.jet.lang.cfg.JetControlFlowProcessor.CFPContext.IN_CONDITION;
|
||||
@@ -100,7 +102,7 @@ public class JetControlFlowProcessor {
|
||||
|
||||
Label afterDeclaration = builder.createUnboundLabel();
|
||||
|
||||
builder.nondeterministicJump(afterDeclaration, parent);
|
||||
builder.nondeterministicJump(afterDeclaration, parent, null);
|
||||
generate(subroutine);
|
||||
builder.bindLabel(afterDeclaration);
|
||||
}
|
||||
@@ -119,7 +121,7 @@ public class JetControlFlowProcessor {
|
||||
return inCondition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class CFPVisitor extends JetVisitorVoidWithParameter<CFPContext> {
|
||||
private final JetControlFlowBuilder builder;
|
||||
|
||||
@@ -129,7 +131,9 @@ public class JetControlFlowProcessor {
|
||||
public void visitWhenConditionInRangeVoid(@NotNull JetWhenConditionInRange condition, CFPContext context) {
|
||||
generateInstructions(condition.getRangeExpression(), context);
|
||||
generateInstructions(condition.getOperationReference(), context);
|
||||
|
||||
// TODO : read the call to contains()...
|
||||
createNonSyntheticValue(Arrays.asList(condition.getRangeExpression(), condition.getOperationReference()), condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,6 +144,7 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitWhenConditionWithExpressionVoid(@NotNull JetWhenConditionWithExpression condition, CFPContext context) {
|
||||
generateInstructions(condition.getExpression(), context);
|
||||
copyValue(condition.getExpression(), condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,12 +184,59 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PseudoValue createSyntheticValue(@NotNull JetElement instructionElement) {
|
||||
return builder.magic(instructionElement, null, Collections.<PseudoValue>emptyList(), true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PseudoValue createNonSyntheticValue(@NotNull List<? extends JetElement> from, @NotNull JetElement to) {
|
||||
return builder.magic(to, to, elementsToValues(from), false);
|
||||
}
|
||||
|
||||
private void mergeValues(@NotNull List<JetExpression> from, @NotNull JetExpression to) {
|
||||
List<PseudoValue> values = elementsToValues(from);
|
||||
switch (values.size()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
builder.bindValue(values.get(0), to);
|
||||
break;
|
||||
default:
|
||||
builder.magic(to, to, values, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void copyValue(@Nullable JetElement from, @NotNull JetElement to) {
|
||||
PseudoValue value = builder.getBoundValue(from);
|
||||
if (value != null) {
|
||||
builder.bindValue(value, to);
|
||||
}
|
||||
}
|
||||
|
||||
private List<PseudoValue> elementsToValues(List<? extends JetElement> from) {
|
||||
return KotlinPackage.filterNotNull(
|
||||
KotlinPackage.mapTo(
|
||||
from,
|
||||
new LinkedHashSet<PseudoValue>(),
|
||||
new Function1<JetElement, PseudoValue>() {
|
||||
@Override
|
||||
public PseudoValue invoke(JetElement element) {
|
||||
return builder.getBoundValue(element);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedExpressionVoid(@NotNull JetParenthesizedExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
JetExpression innerExpression = expression.getExpression();
|
||||
if (innerExpression != null) {
|
||||
generateInstructions(innerExpression, context);
|
||||
copyValue(innerExpression, expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +245,7 @@ public class JetControlFlowProcessor {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
if (baseExpression != null) {
|
||||
generateInstructions(baseExpression, context);
|
||||
copyValue(baseExpression, expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +276,8 @@ public class JetControlFlowProcessor {
|
||||
VariableAsFunctionResolvedCall variableAsFunctionResolvedCall = (VariableAsFunctionResolvedCall) resolvedCall;
|
||||
generateCall(expression, variableAsFunctionResolvedCall.getVariableCall());
|
||||
}
|
||||
else {
|
||||
generateCall(expression);
|
||||
else if (!generateCall(expression) && !(expression.getParent() instanceof JetCallExpression)) {
|
||||
createNonSyntheticValue(Collections.singletonList(generateAndGetReceiverIfAny(expression)), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,43 +287,47 @@ public class JetControlFlowProcessor {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
if (baseExpression != null) {
|
||||
generateInstructions(baseExpression, context);
|
||||
copyValue(baseExpression, expression);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousMethodCalls") @Override
|
||||
@SuppressWarnings("SuspiciousMethodCalls")
|
||||
@Override
|
||||
public void visitBinaryExpressionVoid(@NotNull JetBinaryExpression expression, CFPContext context) {
|
||||
JetSimpleNameExpression operationReference = expression.getOperationReference();
|
||||
IElementType operationType = operationReference.getReferencedNameElementType();
|
||||
if (!ImmutableSet.of(ANDAND, OROR, EQ, ELVIS).contains(operationType)) {
|
||||
mark(expression);
|
||||
}
|
||||
|
||||
JetExpression left = expression.getLeft();
|
||||
JetExpression right = expression.getRight();
|
||||
if (operationType == ANDAND) {
|
||||
generateInstructions(expression.getLeft(), IN_CONDITION);
|
||||
generateInstructions(left, IN_CONDITION);
|
||||
Label resultLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnFalse(resultLabel, expression);
|
||||
builder.jumpOnFalse(resultLabel, expression, builder.getBoundValue(left));
|
||||
if (right != null) {
|
||||
generateInstructions(right, IN_CONDITION);
|
||||
}
|
||||
builder.bindLabel(resultLabel);
|
||||
if (!context.inCondition()) {
|
||||
builder.predefinedOperation(expression, AND);
|
||||
predefinedOperation(expression, AND);
|
||||
}
|
||||
}
|
||||
else if (operationType == OROR) {
|
||||
generateInstructions(expression.getLeft(), IN_CONDITION);
|
||||
generateInstructions(left, IN_CONDITION);
|
||||
Label resultLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnTrue(resultLabel, expression);
|
||||
builder.jumpOnTrue(resultLabel, expression, builder.getBoundValue(left));
|
||||
if (right != null) {
|
||||
generateInstructions(right, IN_CONDITION);
|
||||
}
|
||||
builder.bindLabel(resultLabel);
|
||||
if (!context.inCondition()) {
|
||||
builder.predefinedOperation(expression, OR);
|
||||
predefinedOperation(expression, OR);
|
||||
}
|
||||
}
|
||||
else if (operationType == EQ) {
|
||||
visitAssignment(expression.getLeft(), right, expression);
|
||||
visitAssignment(left, getDeferredValue(right, true), expression);
|
||||
}
|
||||
else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) {
|
||||
if (generateCall(operationReference)) {
|
||||
@@ -280,7 +337,7 @@ public class JetControlFlowProcessor {
|
||||
Name assignMethodName = OperatorConventions.getNameForOperationSymbol((JetToken) expression.getOperationToken());
|
||||
if (!descriptor.getName().equals(assignMethodName)) {
|
||||
// plus() called, assignment needed
|
||||
visitAssignment(expression.getLeft(), null, expression);
|
||||
visitAssignment(left, getDeferredValue(operationReference, false), expression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -288,21 +345,43 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
}
|
||||
else if (operationType == ELVIS) {
|
||||
generateInstructions(expression.getLeft(), NOT_IN_CONDITION);
|
||||
generateInstructions(left, NOT_IN_CONDITION);
|
||||
Label afterElvis = builder.createUnboundLabel();
|
||||
builder.jumpOnTrue(afterElvis, expression);
|
||||
builder.jumpOnTrue(afterElvis, expression, builder.getBoundValue(left));
|
||||
if (right != null) {
|
||||
generateInstructions(right, NOT_IN_CONDITION);
|
||||
}
|
||||
builder.bindLabel(afterElvis);
|
||||
mergeValues(Arrays.asList(left, right), expression);
|
||||
}
|
||||
else {
|
||||
if (!generateCall(operationReference)) {
|
||||
if (generateCall(operationReference)) {
|
||||
copyValue(operationReference, expression);
|
||||
}
|
||||
else {
|
||||
generateBothArguments(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Function0<PseudoValue> getDeferredValue(final JetExpression right, final boolean generate) {
|
||||
return new Function0<PseudoValue>() {
|
||||
@Override
|
||||
public PseudoValue invoke() {
|
||||
if (generate) {
|
||||
generateInstructions(right, NOT_IN_CONDITION);
|
||||
}
|
||||
return builder.getBoundValue(right);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void predefinedOperation(JetBinaryExpression expression, JetControlFlowBuilder.PredefinedOperation operation) {
|
||||
builder.predefinedOperation(
|
||||
expression, operation, elementsToValues(Arrays.asList(expression.getLeft(), expression.getRight()))
|
||||
);
|
||||
}
|
||||
|
||||
private void generateBothArguments(JetBinaryExpression expression) {
|
||||
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
|
||||
if (left != null) {
|
||||
@@ -312,9 +391,10 @@ public class JetControlFlowProcessor {
|
||||
if (right != null) {
|
||||
generateInstructions(right, NOT_IN_CONDITION);
|
||||
}
|
||||
createNonSyntheticValue(Arrays.asList(left, right), expression);
|
||||
}
|
||||
|
||||
private void visitAssignment(JetExpression lhs, @Nullable JetExpression rhs, JetExpression parentExpression) {
|
||||
private void visitAssignment(JetExpression lhs, @NotNull Function0<PseudoValue> rhsDeferredValue, JetExpression parentExpression) {
|
||||
JetExpression left = JetPsiUtil.deparenthesize(lhs);
|
||||
if (left == null) {
|
||||
builder.compilationError(lhs, "No lValue in assignment");
|
||||
@@ -322,44 +402,90 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
if (left instanceof JetArrayAccessExpression) {
|
||||
ResolvedCall<FunctionDescriptor> setResolvedCall = trace.get(BindingContext.INDEXED_LVALUE_SET, left);
|
||||
generateArrayAccess((JetArrayAccessExpression) left, setResolvedCall);
|
||||
recordWrite(left, parentExpression);
|
||||
generateArrayAssignment((JetArrayAccessExpression) left, rhsDeferredValue, parentExpression);
|
||||
return;
|
||||
}
|
||||
|
||||
generateInstructions(rhs, NOT_IN_CONDITION);
|
||||
PseudoValue rhsValue = rhsDeferredValue.invoke();
|
||||
PseudoValue receiverValue = null;
|
||||
if (left instanceof JetSimpleNameExpression || left instanceof JetProperty) {
|
||||
// Do nothing, just record write below
|
||||
}
|
||||
else if (left instanceof JetQualifiedExpression) {
|
||||
generateInstructions(((JetQualifiedExpression) left).getReceiverExpression(), NOT_IN_CONDITION);
|
||||
JetExpression receiverExpression = ((JetQualifiedExpression) left).getReceiverExpression();
|
||||
generateInstructions(receiverExpression, NOT_IN_CONDITION);
|
||||
receiverValue = builder.getBoundValue(receiverExpression);
|
||||
}
|
||||
else {
|
||||
builder.unsupported(parentExpression); // TODO
|
||||
}
|
||||
|
||||
recordWrite(left, parentExpression);
|
||||
recordWrite(left, rhsValue, receiverValue, parentExpression);
|
||||
}
|
||||
|
||||
private void recordWrite(JetExpression left, JetExpression parentExpression) {
|
||||
private void generateArrayAssignment(
|
||||
JetArrayAccessExpression lhs, @NotNull Function0<PseudoValue> rhsDeferredValue, JetExpression parentExpression
|
||||
) {
|
||||
ResolvedCall<FunctionDescriptor> setResolvedCall = trace.get(BindingContext.INDEXED_LVALUE_SET, lhs);
|
||||
|
||||
if (setResolvedCall == null) {
|
||||
generateArrayAccess(lhs, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// In case of simple ('=') array assignment mark instruction is not generated yet, so we put it before generating "set" call
|
||||
if (((JetOperationExpression) parentExpression).getOperationReference().getReferencedNameElementType() == EQ) {
|
||||
mark(lhs);
|
||||
}
|
||||
|
||||
generateArrayAccessArguments(lhs);
|
||||
|
||||
List<JetExpression> inputExpressions = new ArrayList<JetExpression>();
|
||||
inputExpressions.add(lhs.getArrayExpression());
|
||||
inputExpressions.addAll(lhs.getIndexExpressions());
|
||||
|
||||
List<PseudoValue> inputValues = elementsToValues(inputExpressions);
|
||||
PseudoValue rhsValue = rhsDeferredValue.invoke();
|
||||
if (rhsValue != null) {
|
||||
inputValues.add(rhsValue);
|
||||
}
|
||||
|
||||
builder.call(parentExpression, setResolvedCall, inputValues);
|
||||
}
|
||||
|
||||
private void recordWrite(JetExpression left, PseudoValue rightValue, PseudoValue receiverValue, JetExpression parentExpression) {
|
||||
VariableDescriptor descriptor = BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), left, false);
|
||||
if (descriptor != null) {
|
||||
builder.write(parentExpression, left);
|
||||
builder.write(parentExpression, left, rightValue != null ? rightValue : createSyntheticValue(parentExpression), receiverValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateArrayAccess(JetArrayAccessExpression arrayAccessExpression, @Nullable ResolvedCall<?> resolvedCall) {
|
||||
mark(arrayAccessExpression);
|
||||
if (!checkAndGenerateCall(arrayAccessExpression, resolvedCall)) {
|
||||
for (JetExpression index : arrayAccessExpression.getIndexExpressions()) {
|
||||
generateInstructions(index, NOT_IN_CONDITION);
|
||||
}
|
||||
|
||||
generateInstructions(arrayAccessExpression.getArrayExpression(), NOT_IN_CONDITION);
|
||||
generateArrayAccessWithoutCall(arrayAccessExpression);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateArrayAccessWithoutCall(JetArrayAccessExpression arrayAccessExpression) {
|
||||
createNonSyntheticValue(generateArrayAccessArguments(arrayAccessExpression), arrayAccessExpression);
|
||||
}
|
||||
|
||||
private List<JetExpression> generateArrayAccessArguments(JetArrayAccessExpression arrayAccessExpression) {
|
||||
List<JetExpression> inputExpressions = new ArrayList<JetExpression>();
|
||||
|
||||
JetExpression arrayExpression = arrayAccessExpression.getArrayExpression();
|
||||
inputExpressions.add(arrayExpression);
|
||||
generateInstructions(arrayExpression, NOT_IN_CONDITION);
|
||||
|
||||
for (JetExpression index : arrayAccessExpression.getIndexExpressions()) {
|
||||
generateInstructions(index, NOT_IN_CONDITION);
|
||||
inputExpressions.add(index);
|
||||
}
|
||||
|
||||
return inputExpressions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitUnaryExpressionVoid(@NotNull JetUnaryExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
@@ -369,17 +495,23 @@ public class JetControlFlowProcessor {
|
||||
if (baseExpression == null) return;
|
||||
if (JetTokens.EXCLEXCL == operationType) {
|
||||
generateInstructions(baseExpression, NOT_IN_CONDITION);
|
||||
builder.predefinedOperation(expression, NOT_NULL_ASSERTION);
|
||||
builder.predefinedOperation(expression, NOT_NULL_ASSERTION, elementsToValues(Collections.singletonList(baseExpression)));
|
||||
}
|
||||
else {
|
||||
if (!generateCall(expression.getOperationReference())) {
|
||||
boolean resolved = generateCall(operationSign);
|
||||
if (!resolved) {
|
||||
generateInstructions(baseExpression, NOT_IN_CONDITION);
|
||||
}
|
||||
|
||||
boolean incrementOrDecrement = isIncrementOrDecrement(operationType);
|
||||
if (incrementOrDecrement) {
|
||||
if (isIncrementOrDecrement(operationType)) {
|
||||
// We skip dup's and other subtleties here
|
||||
visitAssignment(baseExpression, null, expression);
|
||||
visitAssignment(baseExpression, getDeferredValue(operationSign, false), expression);
|
||||
}
|
||||
else if (resolved) {
|
||||
copyValue(operationSign, expression);
|
||||
}
|
||||
else {
|
||||
createNonSyntheticValue(Collections.singletonList(baseExpression), expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,18 +520,19 @@ public class JetControlFlowProcessor {
|
||||
return operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitIfExpressionVoid(@NotNull JetIfExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
List<JetExpression> branches = new ArrayList<JetExpression>(2);
|
||||
JetExpression condition = expression.getCondition();
|
||||
if (condition != null) {
|
||||
generateInstructions(condition, IN_CONDITION);
|
||||
}
|
||||
Label elseLabel = builder.createUnboundLabel();
|
||||
builder.jumpOnFalse(elseLabel, expression);
|
||||
builder.jumpOnFalse(elseLabel, expression, builder.getBoundValue(condition));
|
||||
JetExpression thenBranch = expression.getThen();
|
||||
if (thenBranch != null) {
|
||||
branches.add(thenBranch);
|
||||
generateInstructions(thenBranch, context);
|
||||
}
|
||||
else {
|
||||
@@ -410,12 +543,14 @@ public class JetControlFlowProcessor {
|
||||
builder.bindLabel(elseLabel);
|
||||
JetExpression elseBranch = expression.getElse();
|
||||
if (elseBranch != null) {
|
||||
branches.add(elseBranch);
|
||||
generateInstructions(elseBranch, context);
|
||||
}
|
||||
else {
|
||||
builder.loadUnit(expression);
|
||||
}
|
||||
builder.bindLabel(resultLabel);
|
||||
mergeValues(branches, expression);
|
||||
}
|
||||
|
||||
private class FinallyBlockGenerator {
|
||||
@@ -444,14 +579,15 @@ public class JetControlFlowProcessor {
|
||||
builder.bindLabel(finishFinally);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitTryExpressionVoid(@NotNull JetTryExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
|
||||
JetFinallySection finallyBlock = expression.getFinallyBlock();
|
||||
final FinallyBlockGenerator finallyBlockGenerator = new FinallyBlockGenerator(finallyBlock, context);
|
||||
if (finallyBlock != null) {
|
||||
boolean hasFinally = finallyBlock != null;
|
||||
if (hasFinally) {
|
||||
builder.enterTryFinally(new GenerationTrigger() {
|
||||
private boolean working = false;
|
||||
|
||||
@@ -466,19 +602,51 @@ public class JetControlFlowProcessor {
|
||||
});
|
||||
}
|
||||
|
||||
Label onExceptionToFinallyBlock = generateTryAndCatches(expression, context);
|
||||
|
||||
if (hasFinally) {
|
||||
assert onExceptionToFinallyBlock != null : "No finally lable generated: " + expression.getText();
|
||||
|
||||
builder.exitTryFinally();
|
||||
|
||||
Label skipFinallyToErrorBlock = builder.createUnboundLabel("skipFinallyToErrorBlock");
|
||||
builder.jump(skipFinallyToErrorBlock, expression);
|
||||
builder.bindLabel(onExceptionToFinallyBlock);
|
||||
finallyBlockGenerator.generate();
|
||||
builder.jumpToError(expression);
|
||||
builder.bindLabel(skipFinallyToErrorBlock);
|
||||
|
||||
finallyBlockGenerator.generate();
|
||||
}
|
||||
|
||||
List<JetExpression> branches = new ArrayList<JetExpression>();
|
||||
branches.add(expression.getTryBlock());
|
||||
for (JetCatchClause catchClause : expression.getCatchClauses()) {
|
||||
branches.add(catchClause.getCatchBody());
|
||||
}
|
||||
mergeValues(branches, expression);
|
||||
}
|
||||
|
||||
// Returns label for 'finally' block
|
||||
@Nullable
|
||||
private Label generateTryAndCatches(@NotNull JetTryExpression expression, CFPContext context) {
|
||||
List<JetCatchClause> catchClauses = expression.getCatchClauses();
|
||||
boolean hasCatches = !catchClauses.isEmpty();
|
||||
|
||||
Label onException = null;
|
||||
if (hasCatches) {
|
||||
onException = builder.createUnboundLabel("onException");
|
||||
builder.nondeterministicJump(onException, expression);
|
||||
builder.nondeterministicJump(onException, expression, null);
|
||||
}
|
||||
|
||||
Label onExceptionToFinallyBlock = null;
|
||||
if (finallyBlock != null) {
|
||||
if (expression.getFinallyBlock() != null) {
|
||||
onExceptionToFinallyBlock = builder.createUnboundLabel("onExceptionToFinallyBlock");
|
||||
builder.nondeterministicJump(onExceptionToFinallyBlock, expression);
|
||||
builder.nondeterministicJump(onExceptionToFinallyBlock, expression, null);
|
||||
}
|
||||
generateInstructions(expression.getTryBlock(), context);
|
||||
|
||||
JetBlockExpression tryBlock = expression.getTryBlock();
|
||||
generateInstructions(tryBlock, context);
|
||||
|
||||
if (hasCatches) {
|
||||
Label afterCatches = builder.createUnboundLabel("afterCatches");
|
||||
@@ -505,7 +673,7 @@ public class JetControlFlowProcessor {
|
||||
JetParameter catchParameter = catchClause.getCatchParameter();
|
||||
if (catchParameter != null) {
|
||||
builder.declareParameter(catchParameter);
|
||||
builder.write(catchParameter, catchParameter);
|
||||
builder.write(catchParameter, catchParameter, createSyntheticValue(catchParameter), null);
|
||||
}
|
||||
JetExpression catchBody = catchClause.getCatchBody();
|
||||
if (catchBody != null) {
|
||||
@@ -518,18 +686,7 @@ public class JetControlFlowProcessor {
|
||||
builder.bindLabel(afterCatches);
|
||||
}
|
||||
|
||||
if (finallyBlock != null) {
|
||||
builder.exitTryFinally();
|
||||
|
||||
Label skipFinallyToErrorBlock = builder.createUnboundLabel("skipFinallyToErrorBlock");
|
||||
builder.jump(skipFinallyToErrorBlock, expression);
|
||||
builder.bindLabel(onExceptionToFinallyBlock);
|
||||
finallyBlockGenerator.generate();
|
||||
builder.jumpToError(expression);
|
||||
builder.bindLabel(skipFinallyToErrorBlock);
|
||||
|
||||
finallyBlockGenerator.generate();
|
||||
}
|
||||
return onExceptionToFinallyBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -544,7 +701,7 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
boolean conditionIsTrueConstant = CompileTimeConstantUtils.canBeReducedToBooleanConstant(condition, trace, true);
|
||||
if (!conditionIsTrueConstant) {
|
||||
builder.jumpOnFalse(loopInfo.getExitPoint(), expression);
|
||||
builder.jumpOnFalse(loopInfo.getExitPoint(), expression, builder.getBoundValue(condition));
|
||||
}
|
||||
|
||||
builder.bindLabel(loopInfo.getBodyEntryPoint());
|
||||
@@ -573,7 +730,7 @@ public class JetControlFlowProcessor {
|
||||
if (condition != null) {
|
||||
generateInstructions(condition, IN_CONDITION);
|
||||
}
|
||||
builder.jumpOnTrue(loopInfo.getEntryPoint(), expression);
|
||||
builder.jumpOnTrue(loopInfo.getEntryPoint(), expression, builder.getBoundValue(condition));
|
||||
builder.exitLoop(expression);
|
||||
builder.loadUnit(expression);
|
||||
builder.exitLexicalScope(expression);
|
||||
@@ -583,6 +740,7 @@ public class JetControlFlowProcessor {
|
||||
public void visitForExpressionVoid(@NotNull JetForExpression expression, CFPContext context) {
|
||||
builder.enterLexicalScope(expression);
|
||||
mark(expression);
|
||||
|
||||
JetExpression loopRange = expression.getLoopRange();
|
||||
if (loopRange != null) {
|
||||
generateInstructions(loopRange, NOT_IN_CONDITION);
|
||||
@@ -594,7 +752,7 @@ public class JetControlFlowProcessor {
|
||||
Label conditionEntryPoint = builder.createUnboundLabel();
|
||||
|
||||
builder.bindLabel(conditionEntryPoint);
|
||||
builder.nondeterministicJump(loopExitPoint, expression);
|
||||
builder.nondeterministicJump(loopExitPoint, expression, null);
|
||||
|
||||
LoopInfo loopInfo = builder.enterLoop(expression, loopExitPoint, conditionEntryPoint);
|
||||
|
||||
@@ -606,7 +764,8 @@ public class JetControlFlowProcessor {
|
||||
generateInstructions(body, NOT_IN_CONDITION);
|
||||
}
|
||||
|
||||
builder.nondeterministicJump(loopInfo.getEntryPoint(), expression);
|
||||
builder.nondeterministicJump(loopInfo.getEntryPoint(), expression, null);
|
||||
|
||||
builder.exitLoop(expression);
|
||||
builder.loadUnit(expression);
|
||||
builder.exitLexicalScope(expression);
|
||||
@@ -626,12 +785,21 @@ public class JetControlFlowProcessor {
|
||||
private void writeLoopParameterAssignment(JetForExpression expression) {
|
||||
JetParameter loopParameter = expression.getLoopParameter();
|
||||
JetMultiDeclaration multiDeclaration = expression.getMultiParameter();
|
||||
|
||||
JetExpression loopRange = expression.getLoopRange();
|
||||
PseudoValue value = builder.magic(
|
||||
loopRange != null ? loopRange : expression,
|
||||
null,
|
||||
Collections.singletonList(builder.getBoundValue(loopRange)),
|
||||
true
|
||||
);
|
||||
|
||||
if (loopParameter != null) {
|
||||
builder.write(loopParameter, loopParameter);
|
||||
builder.write(loopParameter, loopParameter, value, null);
|
||||
}
|
||||
else if (multiDeclaration != null) {
|
||||
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
builder.write(entry, entry);
|
||||
builder.write(entry, entry, value, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,11 +881,12 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
if (subroutine instanceof JetFunction || subroutine instanceof JetPropertyAccessor) {
|
||||
if (returnedExpression == null) {
|
||||
PseudoValue returnValue = returnedExpression != null ? builder.getBoundValue(returnedExpression) : null;
|
||||
if (returnValue == null) {
|
||||
builder.returnNoValue(expression, subroutine);
|
||||
}
|
||||
else {
|
||||
builder.returnValue(expression, subroutine);
|
||||
builder.returnValue(expression, returnValue, subroutine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,7 +898,7 @@ public class JetControlFlowProcessor {
|
||||
if (defaultValue != null) {
|
||||
generateInstructions(defaultValue, context);
|
||||
}
|
||||
builder.write(parameter, parameter);
|
||||
builder.write(parameter, parameter, createSyntheticValue(parameter), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -746,6 +915,9 @@ public class JetControlFlowProcessor {
|
||||
if (statements.isEmpty()) {
|
||||
builder.loadUnit(expression);
|
||||
}
|
||||
else {
|
||||
copyValue((JetExpression) KotlinPackage.lastOrNull(statements), expression);
|
||||
}
|
||||
if (declareLexicalScope) {
|
||||
builder.exitLexicalScope(expression);
|
||||
}
|
||||
@@ -774,38 +946,59 @@ public class JetControlFlowProcessor {
|
||||
public void visitQualifiedExpressionVoid(@NotNull JetQualifiedExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||
|
||||
if (selectorExpression == null) {
|
||||
generateInstructions(expression.getReceiverExpression(), NOT_IN_CONDITION);
|
||||
return;
|
||||
// todo: replace with selectorExpresion != null after parser is fixed
|
||||
if (selectorExpression instanceof JetCallExpression || selectorExpression instanceof JetSimpleNameExpression) {
|
||||
generateInstructions(selectorExpression, NOT_IN_CONDITION);
|
||||
copyValue(selectorExpression, expression);
|
||||
}
|
||||
|
||||
generateInstructions(selectorExpression, NOT_IN_CONDITION);
|
||||
|
||||
// receiver was generated for resolvedCall
|
||||
JetExpression calleeExpression = JetPsiUtil.getCalleeExpressionIfAny(selectorExpression);
|
||||
if (calleeExpression == null || getResolvedCall(calleeExpression) == null) {
|
||||
generateInstructions(expression.getReceiverExpression(), NOT_IN_CONDITION);
|
||||
else {
|
||||
generateInstructions(receiverExpression, NOT_IN_CONDITION);
|
||||
createNonSyntheticValue(Collections.singletonList(receiverExpression), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpressionVoid(@NotNull JetCallExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
if (!generateCall(expression.getCalleeExpression())) {
|
||||
|
||||
JetExpression calleeExpression = expression.getCalleeExpression();
|
||||
if (!generateCall(calleeExpression)) {
|
||||
List<JetExpression> inputExpressions = new ArrayList<JetExpression>();
|
||||
for (ValueArgument argument : expression.getValueArguments()) {
|
||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
||||
if (argumentExpression != null) {
|
||||
generateInstructions(argumentExpression, NOT_IN_CONDITION);
|
||||
inputExpressions.add(argumentExpression);
|
||||
}
|
||||
}
|
||||
|
||||
for (JetExpression functionLiteral : expression.getFunctionLiteralArguments()) {
|
||||
generateInstructions(functionLiteral, NOT_IN_CONDITION);
|
||||
inputExpressions.add(functionLiteral);
|
||||
}
|
||||
generateInstructions(calleeExpression, NOT_IN_CONDITION);
|
||||
inputExpressions.add(calleeExpression);
|
||||
inputExpressions.add(generateAndGetReceiverIfAny(expression));
|
||||
|
||||
generateInstructions(expression.getCalleeExpression(), NOT_IN_CONDITION);
|
||||
createNonSyntheticValue(inputExpressions, calleeExpression != null ? calleeExpression : expression);
|
||||
}
|
||||
|
||||
copyValue(calleeExpression, expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetExpression generateAndGetReceiverIfAny(JetExpression expression) {
|
||||
PsiElement parent = expression.getParent();
|
||||
if (!(parent instanceof JetQualifiedExpression)) return null;
|
||||
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
|
||||
if (qualifiedExpression.getSelectorExpression() != expression) return null;
|
||||
|
||||
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
||||
generateInstructions(receiverExpression, NOT_IN_CONDITION);
|
||||
|
||||
return receiverExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -813,8 +1006,7 @@ public class JetControlFlowProcessor {
|
||||
builder.declareVariable(property);
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
generateInstructions(initializer, NOT_IN_CONDITION);
|
||||
visitAssignment(property, null, property);
|
||||
visitAssignment(property, getDeferredValue(initializer, true), property);
|
||||
}
|
||||
JetExpression delegate = property.getDelegateExpression();
|
||||
if (delegate != null) {
|
||||
@@ -833,16 +1025,17 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
private void visitMultiDeclaration(@NotNull JetMultiDeclaration declaration, boolean generateWriteForEntries) {
|
||||
generateInstructions(declaration.getInitializer(), NOT_IN_CONDITION);
|
||||
|
||||
JetExpression initializer = declaration.getInitializer();
|
||||
generateInstructions(initializer, NOT_IN_CONDITION);
|
||||
List<PseudoValue> inputValues = elementsToValues(Collections.singletonList(initializer));
|
||||
for (JetMultiDeclarationEntry entry : declaration.getEntries()) {
|
||||
builder.declareVariable(entry);
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = trace.get(BindingContext.COMPONENT_RESOLVED_CALL, entry);
|
||||
if (resolvedCall != null) {
|
||||
builder.call(entry, resolvedCall);
|
||||
}
|
||||
PseudoValue writtenValue = resolvedCall != null
|
||||
? builder.call(entry, resolvedCall, inputValues)
|
||||
: builder.magic(entry, null, inputValues, true);
|
||||
if (generateWriteForEntries) {
|
||||
builder.write(entry, entry);
|
||||
builder.write(entry, entry, writtenValue != null ? writtenValue : createSyntheticValue(entry), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -855,23 +1048,32 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitBinaryWithTypeRHSExpressionVoid(@NotNull JetBinaryExpressionWithTypeRHS expression, CFPContext context) {
|
||||
mark(expression);
|
||||
|
||||
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
|
||||
JetExpression left = expression.getLeft();
|
||||
if (operationType == JetTokens.COLON || operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) {
|
||||
generateInstructions(expression.getLeft(), NOT_IN_CONDITION);
|
||||
generateInstructions(left, NOT_IN_CONDITION);
|
||||
copyValue(left, expression);
|
||||
}
|
||||
else {
|
||||
visitJetElementVoid(expression, context);
|
||||
createNonSyntheticValue(Collections.singletonList(left), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThrowExpressionVoid(@NotNull JetThrowExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
|
||||
JetExpression thrownExpression = expression.getThrownExpression();
|
||||
if (thrownExpression != null) {
|
||||
generateInstructions(thrownExpression, NOT_IN_CONDITION);
|
||||
}
|
||||
builder.throwException(expression);
|
||||
if (thrownExpression == null) return;
|
||||
|
||||
generateInstructions(thrownExpression, NOT_IN_CONDITION);
|
||||
|
||||
PseudoValue thrownValue = builder.getBoundValue(thrownExpression);
|
||||
if (thrownValue == null) return;
|
||||
|
||||
builder.throwException(expression, thrownValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -886,18 +1088,24 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitIsExpressionVoid(@NotNull JetIsExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
generateInstructions(expression.getLeftHandSide(), context);
|
||||
JetExpression left = expression.getLeftHandSide();
|
||||
generateInstructions(left, context);
|
||||
createNonSyntheticValue(Collections.singletonList(left), expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenExpressionVoid(@NotNull JetWhenExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
|
||||
JetExpression subjectExpression = expression.getSubjectExpression();
|
||||
if (subjectExpression != null) {
|
||||
generateInstructions(subjectExpression, context);
|
||||
}
|
||||
|
||||
boolean hasElse = false;
|
||||
|
||||
List<JetExpression> branches = new ArrayList<JetExpression>();
|
||||
|
||||
Label doneLabel = builder.createUnboundLabel();
|
||||
|
||||
Label nextLabel = null;
|
||||
@@ -919,17 +1127,31 @@ public class JetControlFlowProcessor {
|
||||
JetWhenCondition condition = conditions[i];
|
||||
condition.accept(conditionVisitor, context);
|
||||
if (i + 1 < conditions.length) {
|
||||
builder.nondeterministicJump(bodyLabel, expression);
|
||||
PseudoValue conditionValue = builder.magic(
|
||||
condition, null, elementsToValues(Arrays.asList(subjectExpression, condition)), true
|
||||
);
|
||||
builder.nondeterministicJump(bodyLabel, expression, conditionValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isElse) {
|
||||
nextLabel = builder.createUnboundLabel();
|
||||
builder.nondeterministicJump(nextLabel, expression);
|
||||
PseudoValue conditionValue = null;
|
||||
JetWhenCondition lastCondition = KotlinPackage.lastOrNull(conditions);
|
||||
if (lastCondition != null) {
|
||||
conditionValue = builder.magic(
|
||||
lastCondition, null, elementsToValues(Arrays.asList(subjectExpression, lastCondition)), true
|
||||
);
|
||||
}
|
||||
builder.nondeterministicJump(nextLabel, expression, conditionValue);
|
||||
}
|
||||
|
||||
builder.bindLabel(bodyLabel);
|
||||
generateInstructions(whenEntry.getExpression(), context);
|
||||
JetExpression whenEntryExpression = whenEntry.getExpression();
|
||||
if (whenEntryExpression != null) {
|
||||
generateInstructions(whenEntryExpression, context);
|
||||
branches.add(whenEntryExpression);
|
||||
}
|
||||
builder.jump(doneLabel, expression);
|
||||
|
||||
if (!isElse) {
|
||||
@@ -940,6 +1162,8 @@ public class JetControlFlowProcessor {
|
||||
if (!hasElse && WhenChecker.mustHaveElse(expression, trace)) {
|
||||
trace.report(NO_ELSE_IN_WHEN.on(expression));
|
||||
}
|
||||
|
||||
mergeValues(branches, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -959,13 +1183,16 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitStringTemplateExpressionVoid(@NotNull JetStringTemplateExpression expression, CFPContext context) {
|
||||
mark(expression);
|
||||
|
||||
List<JetExpression> inputExpressions = new ArrayList<JetExpression>();
|
||||
for (JetStringTemplateEntry entry : expression.getEntries()) {
|
||||
if (entry instanceof JetStringTemplateEntryWithExpression) {
|
||||
JetStringTemplateEntryWithExpression entryWithExpression = (JetStringTemplateEntryWithExpression) entry;
|
||||
generateInstructions(entryWithExpression.getExpression(), NOT_IN_CONDITION);
|
||||
JetExpression entryExpression = entry.getExpression();
|
||||
generateInstructions(entryExpression, NOT_IN_CONDITION);
|
||||
inputExpressions.add(entryExpression);
|
||||
}
|
||||
}
|
||||
builder.loadStringTemplate(expression);
|
||||
builder.loadStringTemplate(expression, elementsToValues(inputExpressions));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1059,33 +1286,42 @@ public class JetControlFlowProcessor {
|
||||
return;
|
||||
}
|
||||
|
||||
List<PseudoValue> inputValues = new ArrayList<PseudoValue>();
|
||||
|
||||
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
generateReceiver(resolvedCall.getThisObject());
|
||||
generateReceiver(resolvedCall.getReceiverArgument());
|
||||
generateReceiver(resolvedCall.getThisObject(), inputValues);
|
||||
generateReceiver(resolvedCall.getReceiverArgument(), inputValues);
|
||||
|
||||
for (ValueParameterDescriptor parameterDescriptor : resultingDescriptor.getValueParameters()) {
|
||||
ResolvedValueArgument argument = resolvedCall.getValueArguments().get(parameterDescriptor);
|
||||
if (argument == null) continue;
|
||||
|
||||
generateValueArgument(argument);
|
||||
generateValueArgument(argument, inputValues);
|
||||
}
|
||||
|
||||
if (resultingDescriptor instanceof VariableDescriptor) {
|
||||
builder.readVariable(calleeExpression, (VariableDescriptor) resultingDescriptor);
|
||||
assert inputValues.size() <= 1 : "Wrong input values for variable-based call (must be at most 1): " + resolvedCall.getCall().getCallElement();
|
||||
builder.readVariable(calleeExpression, (VariableDescriptor) resultingDescriptor, KotlinPackage.firstOrNull(inputValues));
|
||||
}
|
||||
else {
|
||||
builder.call(calleeExpression, resolvedCall);
|
||||
builder.call(calleeExpression, resolvedCall, inputValues);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateReceiver(ReceiverValue receiver) {
|
||||
private void generateReceiver(ReceiverValue receiver, List<PseudoValue> values) {
|
||||
if (!receiver.exists()) return;
|
||||
if (receiver instanceof ThisReceiver) {
|
||||
// TODO: Receiver is passed implicitly: no expression to tie the read to
|
||||
}
|
||||
else if (receiver instanceof ExpressionReceiver) {
|
||||
generateInstructions(((ExpressionReceiver) receiver).getExpression(), NOT_IN_CONDITION);
|
||||
JetExpression expression = ((ExpressionReceiver) receiver).getExpression();
|
||||
generateInstructions(expression, NOT_IN_CONDITION);
|
||||
|
||||
PseudoValue receiverValue = builder.getBoundValue(expression);
|
||||
if (receiverValue != null) {
|
||||
values.add(receiverValue);
|
||||
}
|
||||
}
|
||||
else if (receiver instanceof TransientReceiver) {
|
||||
// Do nothing
|
||||
@@ -1095,11 +1331,16 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateValueArgument(ResolvedValueArgument argument) {
|
||||
private void generateValueArgument(ResolvedValueArgument argument, List<PseudoValue> values) {
|
||||
for (ValueArgument valueArgument : argument.getArguments()) {
|
||||
JetExpression expression = valueArgument.getArgumentExpression();
|
||||
if (expression != null) {
|
||||
generateInstructions(expression, NOT_IN_CONDITION);
|
||||
|
||||
PseudoValue argValue = builder.getBoundValue(expression);
|
||||
if (argValue != null) {
|
||||
values.add(argValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ import kotlin.Function3;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.Edges;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.PseudocodeTraverserPackage;
|
||||
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitState;
|
||||
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.Edges;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.PseudocodeTraverserPackage;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
@@ -225,10 +225,12 @@ public class JetFlowInformationProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(@NotNull JetExpression expression) {
|
||||
public void visitJetElement(@NotNull JetElement element) {
|
||||
if (!(element instanceof JetExpression || element instanceof JetWhenCondition)) return;
|
||||
|
||||
if (blockBody && !noExpectedType(expectedReturnType)
|
||||
&& !KotlinBuiltIns.getInstance().isUnit(expectedReturnType)
|
||||
&& !rootUnreachableElements.contains(expression)) {
|
||||
&& !rootUnreachableElements.contains(element)) {
|
||||
noReturnError[0] = true;
|
||||
}
|
||||
}
|
||||
@@ -242,7 +244,9 @@ public class JetFlowInformationProvider {
|
||||
private Set<JetElement> collectUnreachableCode() {
|
||||
Collection<JetElement> unreachableElements = Lists.newArrayList();
|
||||
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
|
||||
if (!(deadInstruction instanceof JetElementInstruction) || deadInstruction instanceof LoadUnitValueInstruction) continue;
|
||||
if (!(deadInstruction instanceof JetElementInstruction)
|
||||
|| deadInstruction instanceof LoadUnitValueInstruction
|
||||
|| (deadInstruction instanceof MagicInstruction && ((MagicInstruction) deadInstruction).getSynthetic())) continue;
|
||||
|
||||
JetElement element = ((JetElementInstruction) deadInstruction).getElement();
|
||||
|
||||
@@ -643,16 +647,18 @@ public class JetFlowInformationProvider {
|
||||
pseudocode, FORWARD, new FunctionVoid1<Instruction>() {
|
||||
@Override
|
||||
public void execute(@NotNull Instruction instruction) {
|
||||
if (!(instruction instanceof ReadValueInstruction)) return;
|
||||
VariableContext ctxt = new VariableContext(instruction, reportedDiagnosticMap);
|
||||
JetElement element =
|
||||
((ReadValueInstruction) instruction).getElement();
|
||||
if (!(instruction instanceof ReadValueInstruction || instruction instanceof MagicInstruction)) return;
|
||||
|
||||
JetElement element = ((JetElementInstruction) instruction).getElement();
|
||||
if (!(element instanceof JetFunctionLiteralExpression
|
||||
|| element instanceof JetConstantExpression
|
||||
|| element instanceof JetStringTemplateExpression
|
||||
|| element instanceof JetSimpleNameExpression)) {
|
||||
return;
|
||||
}
|
||||
|| element instanceof JetSimpleNameExpression)) return;
|
||||
|
||||
if (!(element instanceof JetStringTemplateExpression || instruction instanceof ReadValueInstruction)) return;
|
||||
|
||||
VariableContext ctxt = new VariableContext(instruction, reportedDiagnosticMap);
|
||||
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof JetBlockExpression) {
|
||||
if (!JetPsiUtil.isImplicitlyUsed(element)) {
|
||||
|
||||
@@ -64,4 +64,9 @@ public class TailRecursionDetector extends InstructionVisitorWithResult<Boolean>
|
||||
public Boolean visitMarkInstruction(MarkInstruction instruction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitMagic(MagicInstruction instruction) {
|
||||
return instruction.getSynthetic();
|
||||
}
|
||||
}
|
||||
|
||||
+19
-3
@@ -16,21 +16,36 @@
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
private final boolean onTrue;
|
||||
private Instruction nextOnTrue;
|
||||
private Instruction nextOnFalse;
|
||||
private final PseudoValue conditionValue;
|
||||
|
||||
public ConditionalJumpInstruction(@NotNull JetElement element, boolean onTrue, LexicalScope lexicalScope, Label targetLabel) {
|
||||
public ConditionalJumpInstruction(
|
||||
@NotNull JetElement element,
|
||||
boolean onTrue,
|
||||
LexicalScope lexicalScope,
|
||||
Label targetLabel,
|
||||
PseudoValue conditionValue) {
|
||||
super(element, targetLabel, lexicalScope);
|
||||
this.onTrue = onTrue;
|
||||
this.conditionValue = conditionValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return ContainerUtil.createMaybeSingletonList(conditionValue);
|
||||
}
|
||||
|
||||
public boolean onTrue() {
|
||||
@@ -72,11 +87,12 @@ public class ConditionalJumpInstruction extends AbstractJumpInstruction {
|
||||
@Override
|
||||
public String toString() {
|
||||
String instr = onTrue ? "jt" : "jf";
|
||||
return instr + "(" + getTargetLabel().getName() + ")";
|
||||
String inValue = conditionValue != null ? "|" + conditionValue : "";
|
||||
return instr + "(" + getTargetLabel().getName() + inValue + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel);
|
||||
return new ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel, conditionValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import kotlin.jvm.KotlinSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface Instruction {
|
||||
@NotNull
|
||||
@@ -40,4 +44,11 @@ public interface Instruction {
|
||||
|
||||
@NotNull
|
||||
LexicalScope getLexicalScope();
|
||||
|
||||
@ReadOnly
|
||||
@NotNull
|
||||
List<PseudoValue> getInputValues();
|
||||
|
||||
@Nullable
|
||||
PseudoValue getOutputValue();
|
||||
}
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import kotlin.jvm.KotlinSignature;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class InstructionImpl implements Instruction {
|
||||
private Pseudocode owner;
|
||||
@@ -110,4 +113,16 @@ public abstract class InstructionImpl implements Instruction {
|
||||
((InstructionImpl)instruction).setOriginal(this);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PseudoValue getOutputValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -17,10 +17,14 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
public class InstructionVisitor {
|
||||
public void visitReadValue(ReadValueInstruction instruction) {
|
||||
public void visitInstructionWithReceiver(InstructionWithReceiver instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitReadValue(ReadValueInstruction instruction) {
|
||||
visitInstructionWithReceiver(instruction);
|
||||
}
|
||||
|
||||
public void visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
@@ -81,17 +85,21 @@ public class InstructionVisitor {
|
||||
}
|
||||
|
||||
public void visitWriteValue(WriteValueInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
visitInstructionWithReceiver(instruction);
|
||||
}
|
||||
|
||||
public void visitLoadUnitValue(LoadUnitValueInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitCallInstruction(CallInstruction instruction) {
|
||||
public void visitOperation(OperationInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitCallInstruction(CallInstruction instruction) {
|
||||
visitOperation(instruction);
|
||||
}
|
||||
|
||||
public void visitCompilationErrorInstruction(CompilationErrorInstruction instruction) {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
@@ -100,4 +108,7 @@ public class InstructionVisitor {
|
||||
visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public void visitMagic(MagicInstruction instruction) {
|
||||
visitOperation(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-3
@@ -19,10 +19,14 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
public abstract class InstructionVisitorWithResult<R> {
|
||||
public abstract R visitInstruction(Instruction instruction);
|
||||
|
||||
public R visitReadValue(ReadValueInstruction instruction) {
|
||||
public R visitInstructionWithReceiver(InstructionWithReceiver instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public R visitReadValue(ReadValueInstruction instruction) {
|
||||
return visitInstructionWithReceiver(instruction);
|
||||
}
|
||||
|
||||
public R visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
@@ -80,17 +84,21 @@ public abstract class InstructionVisitorWithResult<R> {
|
||||
}
|
||||
|
||||
public R visitWriteValue(WriteValueInstruction instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
return visitInstructionWithReceiver(instruction);
|
||||
}
|
||||
|
||||
public R visitLoadUnitValue(LoadUnitValueInstruction instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public R visitCallInstruction(CallInstruction instruction) {
|
||||
public R visitOperation(OperationInstruction instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public R visitCallInstruction(CallInstruction instruction) {
|
||||
return visitOperation(instruction);
|
||||
}
|
||||
|
||||
public R visitCompilationErrorInstruction(CompilationErrorInstruction instruction) {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
@@ -99,4 +107,7 @@ public abstract class InstructionVisitorWithResult<R> {
|
||||
return visitInstructionWithNext(instruction);
|
||||
}
|
||||
|
||||
public R visitMagic(MagicInstruction instruction) {
|
||||
return visitOperation(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;/**/
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class InstructionWithReceiver extends InstructionWithNext {
|
||||
protected final PseudoValue receiverValue;
|
||||
|
||||
public InstructionWithReceiver(
|
||||
@NotNull JetElement element,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@Nullable PseudoValue receiverValue) {
|
||||
super(element, lexicalScope);
|
||||
this.receiverValue = receiverValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return receiverValue != null ? Collections.singletonList(receiverValue) : Collections.<PseudoValue>emptyList();
|
||||
}
|
||||
}
|
||||
+111
-35
@@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -32,7 +34,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
||||
|
||||
private JetControlFlowBuilder builder = null;
|
||||
|
||||
private final Stack<BreakableBlockInfo> loopInfo = new Stack<BreakableBlockInfo>();
|
||||
@@ -101,6 +102,18 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
private final Label sink;
|
||||
private final JetElement returnSubroutine;
|
||||
|
||||
private final PseudoValueFactory valueFactory = new PseudoValueFactoryImpl() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PseudoValue newValue(@Nullable JetElement element, @NotNull Instruction instruction) {
|
||||
PseudoValue value = super.newValue(element, instruction);
|
||||
if (element != null) {
|
||||
bindValue(value, element);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement returnSubroutine) {
|
||||
this.pseudocode = new PseudocodeImpl(scopingElement);
|
||||
this.error = pseudocode.createLabel("error");
|
||||
@@ -258,23 +271,40 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
add(new MarkInstruction(element, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void returnValue(@NotNull JetExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
Label exitPoint = getExitPoint(subroutine);
|
||||
handleJumpInsideTryFinally(exitPoint);
|
||||
add(new ReturnValueInstruction(returnExpression, getCurrentScope(), exitPoint));
|
||||
public PseudoValue getBoundValue(@Nullable JetElement element) {
|
||||
return pseudocode.getElementValue(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetElement returnExpression, @NotNull JetElement subroutine) {
|
||||
public void bindValue(@NotNull PseudoValue value, @NotNull JetElement element) {
|
||||
pseudocode.bindElementToValue(element, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnValue(
|
||||
@NotNull JetReturnExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull JetElement subroutine
|
||||
) {
|
||||
Label exitPoint = getExitPoint(subroutine);
|
||||
handleJumpInsideTryFinally(exitPoint);
|
||||
add(new ReturnValueInstruction(returnExpression, getCurrentScope(), exitPoint, returnValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnNoValue(@NotNull JetReturnExpression returnExpression, @NotNull JetElement subroutine) {
|
||||
Label exitPoint = getExitPoint(subroutine);
|
||||
handleJumpInsideTryFinally(exitPoint);
|
||||
add(new ReturnNoValueInstruction(returnExpression, getCurrentScope(), exitPoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull JetElement assignment, @NotNull JetElement lValue) {
|
||||
add(new WriteValueInstruction(assignment, lValue, getCurrentScope()));
|
||||
public void write(
|
||||
@NotNull JetElement assignment,
|
||||
@NotNull JetElement lValue,
|
||||
@NotNull PseudoValue rValue,
|
||||
@Nullable PseudoValue receiverValue) {
|
||||
add(new WriteValueInstruction(assignment, lValue, rValue, receiverValue, getCurrentScope()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,15 +334,15 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element) {
|
||||
public void jumpOnFalse(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(element, false, getCurrentScope(), label));
|
||||
add(new ConditionalJumpInstruction(element, false, getCurrentScope(), label, conditionValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element) {
|
||||
public void jumpOnTrue(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new ConditionalJumpInstruction(element, true, getCurrentScope(), label));
|
||||
add(new ConditionalJumpInstruction(element, true, getCurrentScope(), label, conditionValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,16 +351,16 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element) {
|
||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue) {
|
||||
handleJumpInsideTryFinally(label);
|
||||
add(new NondeterministicJumpInstruction(element, label, getCurrentScope()));
|
||||
add(new NondeterministicJumpInstruction(element, label, getCurrentScope(), inputValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nondeterministicJump(@NotNull List<Label> labels, @NotNull JetElement element) {
|
||||
//todo
|
||||
//handleJumpInsideTryFinally(label);
|
||||
add(new NondeterministicJumpInstruction(element, labels, getCurrentScope()));
|
||||
add(new NondeterministicJumpInstruction(element, labels, getCurrentScope(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -345,9 +375,9 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
}
|
||||
|
||||
@Override
|
||||
public void throwException(@NotNull JetThrowExpression expression) {
|
||||
public void throwException(@NotNull JetThrowExpression expression, @NotNull PseudoValue thrownValue) {
|
||||
handleJumpInsideTryFinally(error);
|
||||
add(new ThrowExceptionInstruction(expression, getCurrentScope(), error));
|
||||
add(new ThrowExceptionInstruction(expression, getCurrentScope(), error, thrownValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -366,44 +396,87 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
pseudocode.repeatPart(startLabel, finishLabel);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant) {
|
||||
read(expression);
|
||||
public PseudoValue loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant) {
|
||||
return read(expression, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void createAnonymousObject(@NotNull JetObjectLiteralExpression expression) {
|
||||
read(expression);
|
||||
public PseudoValue createAnonymousObject(@NotNull JetObjectLiteralExpression expression) {
|
||||
return read(expression, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression) {
|
||||
read(expression);
|
||||
public PseudoValue createFunctionLiteral(@NotNull JetFunctionLiteralExpression expression) {
|
||||
return read(expression, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void loadStringTemplate(@NotNull JetStringTemplateExpression expression) {
|
||||
read(expression);
|
||||
public PseudoValue loadStringTemplate(@NotNull JetStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues) {
|
||||
return inputValues.isEmpty() ? read(expression, null) : magic(expression, expression, inputValues, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor) {
|
||||
read(expression);
|
||||
public PseudoValue magic(
|
||||
@NotNull JetElement instructionElement,
|
||||
@Nullable JetElement valueElement,
|
||||
@NotNull List<PseudoValue> inputValues,
|
||||
boolean synthetic
|
||||
) {
|
||||
MagicInstruction instruction =
|
||||
MagicInstruction.object$.create(instructionElement, valueElement, getCurrentScope(), synthetic, inputValues, valueFactory);
|
||||
add(instruction);
|
||||
return instruction.getOutputValue();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void readVariable(@NotNull JetExpression expression, @Nullable VariableDescriptor variableDescriptor) {
|
||||
read(expression);
|
||||
public PseudoValue readThis(@NotNull JetExpression expression, @Nullable ReceiverParameterDescriptor parameterDescriptor) {
|
||||
return read(expression, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void call(@NotNull JetExpression expression, @NotNull ResolvedCall<?> resolvedCall) {
|
||||
add(new CallInstruction(expression, getCurrentScope(), resolvedCall));
|
||||
public PseudoValue readVariable(
|
||||
@NotNull JetExpression expression,
|
||||
@Nullable VariableDescriptor variableDescriptor,
|
||||
@Nullable PseudoValue receiverValue
|
||||
) {
|
||||
return read(expression, receiverValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void predefinedOperation(@NotNull JetExpression expression, @Nullable PredefinedOperation operation) {
|
||||
read(expression);
|
||||
public PseudoValue call(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@NotNull List<PseudoValue> inputValues
|
||||
) {
|
||||
JetType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
OperationInstruction instruction = CallInstruction.object$.create(
|
||||
expression,
|
||||
getCurrentScope(),
|
||||
resolvedCall,
|
||||
inputValues,
|
||||
returnType != null && KotlinBuiltIns.getInstance().isNothing(returnType) ? null : valueFactory
|
||||
);
|
||||
add(instruction);
|
||||
return instruction.getOutputValue();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PseudoValue predefinedOperation(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull PredefinedOperation operation,
|
||||
@NotNull List<PseudoValue> inputValues
|
||||
) {
|
||||
return magic(expression, expression, inputValues, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -411,8 +484,11 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
add(new CompilationErrorInstruction(element, getCurrentScope(), message));
|
||||
}
|
||||
|
||||
private void read(@NotNull JetElement element) {
|
||||
add(new ReadValueInstruction(element, getCurrentScope()));
|
||||
@NotNull
|
||||
private PseudoValue read(@NotNull JetExpression expression, @Nullable PseudoValue receiverValue) {
|
||||
ReadValueInstruction instruction = new ReadValueInstruction(expression, getCurrentScope(), receiverValue, valueFactory);
|
||||
add(instruction);
|
||||
return instruction.getOutputValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ public abstract class JetElementInstructionImpl extends InstructionImpl implemen
|
||||
return element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String render(PsiElement element) {
|
||||
return element.getText().replaceAll("\\s+", " ");
|
||||
}
|
||||
|
||||
+26
-4
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
@@ -28,15 +29,33 @@ public class NondeterministicJumpInstruction extends JetElementInstructionImpl i
|
||||
private Instruction next;
|
||||
private final List<Label> targetLabels;
|
||||
private final Map<Label, Instruction> resolvedTargets;
|
||||
private final PseudoValue inputValue;
|
||||
|
||||
public NondeterministicJumpInstruction(@NotNull JetElement element, List<Label> targetLabels, LexicalScope lexicalScope) {
|
||||
public NondeterministicJumpInstruction(
|
||||
@NotNull JetElement element,
|
||||
List<Label> targetLabels,
|
||||
LexicalScope lexicalScope,
|
||||
@Nullable PseudoValue inputValue
|
||||
) {
|
||||
super(element, lexicalScope);
|
||||
this.targetLabels = Lists.newArrayList(targetLabels);
|
||||
resolvedTargets = Maps.newLinkedHashMap();
|
||||
this.inputValue = inputValue;
|
||||
}
|
||||
|
||||
public NondeterministicJumpInstruction(@NotNull JetElement element, Label targetLabel, LexicalScope lexicalScope) {
|
||||
this(element, Lists.newArrayList(targetLabel), lexicalScope);
|
||||
public NondeterministicJumpInstruction(
|
||||
@NotNull JetElement element,
|
||||
Label targetLabel,
|
||||
LexicalScope lexicalScope,
|
||||
@Nullable PseudoValue inputValue
|
||||
) {
|
||||
this(element, Lists.newArrayList(targetLabel), lexicalScope, inputValue);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return Collections.singletonList(inputValue);
|
||||
}
|
||||
|
||||
public List<Label> getTargetLabels() {
|
||||
@@ -88,6 +107,9 @@ public class NondeterministicJumpInstruction extends JetElementInstructionImpl i
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
if (inputValue != null) {
|
||||
sb.append("|").append(inputValue);
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -104,6 +126,6 @@ public class NondeterministicJumpInstruction extends JetElementInstructionImpl i
|
||||
}
|
||||
|
||||
private Instruction createCopy(@NotNull List<Label> newTargetLabels) {
|
||||
return new NondeterministicJumpInstruction(getElement(), newTargetLabels, lexicalScope);
|
||||
return new NondeterministicJumpInstruction(getElement(), newTargetLabels, lexicalScope, inputValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode
|
||||
|
||||
import java.util.Collections
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
import kotlin.properties.Delegates
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
|
||||
public trait PseudoValue {
|
||||
public val debugName: String
|
||||
public val element: JetElement?
|
||||
public val createdAt: Instruction
|
||||
}
|
||||
|
||||
public trait PseudoValueFactory {
|
||||
public fun newValue(element: JetElement?, instruction: Instruction): PseudoValue
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
|
||||
class PseudoValueImpl(
|
||||
public override val debugName: String,
|
||||
public override val element: JetElement?,
|
||||
public override val createdAt: Instruction
|
||||
) : PseudoValue {
|
||||
override fun toString(): String = debugName
|
||||
}
|
||||
|
||||
open class PseudoValueFactoryImpl: PseudoValueFactory {
|
||||
private var lastIndex: Int = 0
|
||||
|
||||
override fun newValue(element: JetElement?, instruction: Instruction): PseudoValue {
|
||||
return PseudoValueImpl("<v${lastIndex++}>", element, instruction)
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -50,4 +51,7 @@ public interface Pseudocode {
|
||||
|
||||
@NotNull
|
||||
SubroutineEnterInstruction getEnterInstruction();
|
||||
|
||||
@Nullable
|
||||
PseudoValue getElementValue(@Nullable JetElement element);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ public class PseudocodeImpl implements Pseudocode {
|
||||
private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
|
||||
private final List<Instruction> instructions = new ArrayList<Instruction>();
|
||||
|
||||
private final Map<JetElement, PseudoValue> elementsToValues = new HashMap<JetElement, PseudoValue>();
|
||||
|
||||
private Pseudocode parent = null;
|
||||
private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
|
||||
//todo getters
|
||||
@@ -254,6 +256,16 @@ public class PseudocodeImpl implements Pseudocode {
|
||||
return (SubroutineEnterInstruction) mutableInstructionList.get(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PseudoValue getElementValue(@Nullable JetElement element) {
|
||||
return elementsToValues.get(element);
|
||||
}
|
||||
|
||||
/*package*/ void bindElementToValue(@NotNull JetElement element, @NotNull PseudoValue value) {
|
||||
elementsToValues.put(element, value);
|
||||
}
|
||||
|
||||
/*package*/ void bindLabel(Label label) {
|
||||
((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
|
||||
}
|
||||
|
||||
+27
-5
@@ -17,12 +17,34 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
|
||||
public class ReadValueInstruction extends InstructionWithNext {
|
||||
public class ReadValueInstruction extends InstructionWithReceiver {
|
||||
private final PseudoValue resultValue;
|
||||
|
||||
public ReadValueInstruction(@NotNull JetElement element, @NotNull LexicalScope lexicalScope) {
|
||||
super(element, lexicalScope);
|
||||
private ReadValueInstruction(
|
||||
@NotNull JetElement element,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@Nullable PseudoValue receiverValue,
|
||||
@NotNull PseudoValue resultValue) {
|
||||
super(element, lexicalScope, receiverValue);
|
||||
this.resultValue = resultValue;
|
||||
}
|
||||
|
||||
public ReadValueInstruction(
|
||||
@NotNull JetElement element,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@Nullable PseudoValue receiverValue,
|
||||
@NotNull PseudoValueFactory valueFactory) {
|
||||
super(element, lexicalScope, receiverValue);
|
||||
this.resultValue = valueFactory.newValue(element, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PseudoValue getOutputValue() {
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,12 +59,12 @@ public class ReadValueInstruction extends InstructionWithNext {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "r(" + render(element) + ")";
|
||||
return "r(" + render(element) + (receiverValue != null ? ("|" + receiverValue) : "") + ") -> " + resultValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Instruction createCopy() {
|
||||
return new ReadValueInstruction(element, lexicalScope);
|
||||
return new ReadValueInstruction(element, lexicalScope, receiverValue, resultValue);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -20,12 +20,25 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ReturnValueInstruction extends AbstractJumpInstruction {
|
||||
private final PseudoValue usedValue;
|
||||
|
||||
public ReturnValueInstruction(
|
||||
@NotNull JetExpression returnExpression,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@NotNull Label targetLabel) {
|
||||
@NotNull Label targetLabel,
|
||||
@NotNull PseudoValue usedValue) {
|
||||
super(returnExpression, targetLabel, lexicalScope);
|
||||
this.usedValue = usedValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return Collections.singletonList(usedValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,11 +53,11 @@ public class ReturnValueInstruction extends AbstractJumpInstruction {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ret(*) " + getTargetLabel();
|
||||
return "ret(*|" + usedValue + ") " + getTargetLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ReturnValueInstruction((JetExpression) element, lexicalScope, newLabel);
|
||||
return new ReturnValueInstruction((JetExpression) element, lexicalScope, newLabel, usedValue);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -20,18 +20,31 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.Label;
|
||||
import org.jetbrains.jet.lang.psi.JetThrowExpression;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ThrowExceptionInstruction extends AbstractJumpInstruction {
|
||||
private final PseudoValue usedValue;
|
||||
|
||||
public ThrowExceptionInstruction(
|
||||
@NotNull JetThrowExpression expression,
|
||||
@NotNull LexicalScope lexicalScope,
|
||||
@NotNull Label errorLabel
|
||||
@NotNull Label errorLabel,
|
||||
@NotNull PseudoValue usedValue
|
||||
) {
|
||||
super(expression, errorLabel, lexicalScope);
|
||||
this.usedValue = usedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "throw (" + element.getText() + ")";
|
||||
return "throw (" + element.getText() + "|" + usedValue + ")";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return Collections.singletonList(usedValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,6 +59,6 @@ public class ThrowExceptionInstruction extends AbstractJumpInstruction {
|
||||
|
||||
@Override
|
||||
protected AbstractJumpInstruction createCopy(@NotNull Label newLabel, @NotNull LexicalScope lexicalScope) {
|
||||
return new ThrowExceptionInstruction((JetThrowExpression) element, lexicalScope, newLabel);
|
||||
return new ThrowExceptionInstruction((JetThrowExpression) element, lexicalScope, newLabel, usedValue);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-9
@@ -17,16 +17,30 @@
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
||||
|
||||
public class WriteValueInstruction extends InstructionWithNext {
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class WriteValueInstruction extends InstructionWithReceiver {
|
||||
@NotNull
|
||||
private final JetElement lValue;
|
||||
|
||||
public WriteValueInstruction(@NotNull JetElement assignment, @NotNull JetElement lValue, @NotNull LexicalScope lexicalScope) {
|
||||
super(assignment, lexicalScope);
|
||||
@NotNull
|
||||
private final PseudoValue rValue;
|
||||
|
||||
public WriteValueInstruction(
|
||||
@NotNull JetElement assignment,
|
||||
@NotNull JetElement lValue,
|
||||
@NotNull PseudoValue rValue,
|
||||
@Nullable PseudoValue receiverValue,
|
||||
@NotNull LexicalScope lexicalScope) {
|
||||
super(assignment, lexicalScope, receiverValue);
|
||||
this.lValue = lValue;
|
||||
this.rValue = rValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -34,6 +48,12 @@ public class WriteValueInstruction extends InstructionWithNext {
|
||||
return lValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PseudoValue> getInputValues() {
|
||||
return receiverValue != null ? Arrays.asList(rValue, receiverValue) : Collections.singletonList(rValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull InstructionVisitor visitor) {
|
||||
visitor.visitWriteValue(this);
|
||||
@@ -46,16 +66,13 @@ public class WriteValueInstruction extends InstructionWithNext {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (lValue instanceof JetNamedDeclaration) {
|
||||
JetNamedDeclaration value = (JetNamedDeclaration) lValue;
|
||||
return "w(" + value.getName() + ")";
|
||||
}
|
||||
return "w(" + render(lValue) + ")";
|
||||
String lhs = lValue instanceof JetNamedDeclaration ? lValue.getName() : render(lValue);
|
||||
return "w(" + lhs + "|" + (receiverValue != null ? (receiverValue + ", ") : "") + rValue.toString() + ")";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Instruction createCopy() {
|
||||
return new WriteValueInstruction(element, lValue, lexicalScope);
|
||||
return new WriteValueInstruction(element, lValue, rValue, receiverValue, lexicalScope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,41 @@
|
||||
|
||||
package org.jetbrains.jet.lang.cfg.pseudocode
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class CallInstruction(
|
||||
abstract class OperationInstruction protected(
|
||||
element: JetElement,
|
||||
lexicalScope: LexicalScope,
|
||||
val resolvedCall: ResolvedCall<*>
|
||||
val usedValues: List<PseudoValue>
|
||||
) : InstructionWithNext(element, lexicalScope) {
|
||||
protected var resultValue: PseudoValue? = null
|
||||
|
||||
override fun getInputValues(): List<PseudoValue> = usedValues
|
||||
override fun getOutputValue(): PseudoValue? = resultValue
|
||||
|
||||
protected fun renderInstruction(name: String, desc: String): String =
|
||||
"$name($desc" +
|
||||
(if (usedValues.notEmpty) "|${usedValues.makeString(", ")})" else ")") +
|
||||
(if (resultValue != null) " -> $resultValue" else "")
|
||||
|
||||
protected fun setResult(value: PseudoValue?): OperationInstruction {
|
||||
this.resultValue = value
|
||||
return this
|
||||
}
|
||||
|
||||
protected fun setResult(factory: PseudoValueFactory?, valueElement: JetElement? = element): OperationInstruction {
|
||||
return setResult(factory?.newValue(valueElement, this))
|
||||
}
|
||||
}
|
||||
|
||||
class CallInstruction private(
|
||||
element: JetElement,
|
||||
lexicalScope: LexicalScope,
|
||||
val resolvedCall: ResolvedCall<*>,
|
||||
usedValues: List<PseudoValue>
|
||||
) : OperationInstruction(element, lexicalScope, usedValues) {
|
||||
override fun accept(visitor: InstructionVisitor) {
|
||||
visitor.visitCallInstruction(this)
|
||||
}
|
||||
@@ -34,9 +59,61 @@ class CallInstruction(
|
||||
return visitor.visitCallInstruction(this)
|
||||
}
|
||||
|
||||
override fun createCopy() = CallInstruction(element, lexicalScope, resolvedCall)
|
||||
override fun createCopy() =
|
||||
CallInstruction(element, lexicalScope, resolvedCall, usedValues).setResult(resultValue)
|
||||
|
||||
override fun toString() = "call(${render(element)}, ${resolvedCall.getResultingDescriptor()!!.getName()})"
|
||||
override fun toString() =
|
||||
renderInstruction("call", "${render(element)}, ${resolvedCall.getResultingDescriptor()!!.getName()}")
|
||||
|
||||
class object {
|
||||
fun create (
|
||||
element: JetElement,
|
||||
lexicalScope: LexicalScope,
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
usedValues: List<PseudoValue>,
|
||||
factory: PseudoValueFactory?
|
||||
): CallInstruction = CallInstruction(element, lexicalScope, resolvedCall, usedValues).setResult(factory) as CallInstruction
|
||||
}
|
||||
}
|
||||
|
||||
// Introduces black-box operation
|
||||
// Used to:
|
||||
// consume input values (so that they aren't considered unused)
|
||||
// denote value transformation which can't be expressed by other instructions (such as call or read)
|
||||
// pass more than one value to instruction which formally requires only one (e.g. jump)
|
||||
// "Synthetic" means that the instruction does not correspond to some operation explicitly expressed by PSI element
|
||||
// Examples: merging branches of 'if', 'when' and 'try' expressions, providing initial values for parameters, etc.
|
||||
class MagicInstruction(
|
||||
element: JetElement,
|
||||
lexicalScope: LexicalScope,
|
||||
val synthetic: Boolean,
|
||||
usedValues: List<PseudoValue>
|
||||
) : OperationInstruction(element, lexicalScope, usedValues) {
|
||||
override fun getOutputValue(): PseudoValue = resultValue!!
|
||||
|
||||
override fun accept(visitor: InstructionVisitor) {
|
||||
visitor.visitMagic(this)
|
||||
}
|
||||
|
||||
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
|
||||
return visitor.visitMagic(this)
|
||||
}
|
||||
|
||||
override fun createCopy() =
|
||||
MagicInstruction(element, lexicalScope, synthetic, usedValues).setResult(resultValue)
|
||||
|
||||
override fun toString() = renderInstruction("magic", render(element))
|
||||
|
||||
class object {
|
||||
fun create(
|
||||
element: JetElement,
|
||||
valueElement: JetElement?,
|
||||
lexicalScope: LexicalScope,
|
||||
synthetic: Boolean,
|
||||
usedValues: List<PseudoValue>,
|
||||
factory: PseudoValueFactory
|
||||
): MagicInstruction = MagicInstruction(element, lexicalScope, synthetic, usedValues).setResult(factory, valueElement) as MagicInstruction
|
||||
}
|
||||
}
|
||||
|
||||
class CompilationErrorInstruction(
|
||||
@@ -65,7 +142,6 @@ class MarkInstruction(
|
||||
element: JetElement,
|
||||
lexicalScope: LexicalScope
|
||||
) : InstructionWithNext(element, lexicalScope) {
|
||||
|
||||
override fun accept(visitor: InstructionVisitor) {
|
||||
visitor.visitMarkInstruction(this)
|
||||
}
|
||||
|
||||
@@ -15,19 +15,19 @@ L0:
|
||||
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}
|
||||
mark(1 < 2)
|
||||
r(1)
|
||||
r(2)
|
||||
call(<, compareTo)
|
||||
jf(L2)
|
||||
r(1) -> <v0>
|
||||
r(2) -> <v1>
|
||||
call(<, compareTo|<v0>, <v1>) -> <v2>
|
||||
jf(L2|<v2>)
|
||||
3 mark({ use(b) })
|
||||
mark(use(b)) USE: in: {b=READ} out: {b=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
call(use, use)
|
||||
r(b) -> <v3> USE: in: {} out: {b=READ}
|
||||
call(use, use|<v3>) -> <v4>
|
||||
2 jmp(L3) USE: in: {} out: {}
|
||||
L2:
|
||||
3 mark({ b = true })
|
||||
r(true) USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
w(b) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
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:
|
||||
L3:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
@@ -40,14 +40,15 @@ sink:
|
||||
fun use(vararg a: Any?) = a
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
magic(vararg a: Any?) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v1> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
L1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -9,8 +9,8 @@ class A {
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ x = 1 })
|
||||
r(1) USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||
w(x) INIT: in: {} out: {x=I} USE: in: {} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||
r(1) -> <v0> USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||
w(x|<v0>) INIT: in: {} out: {x=I} USE: in: {} out: {x=ONLY_WRITTEN_NEVER_READ}
|
||||
1 v(val x: Int) INIT: in: {x=I} out: {x=ID}
|
||||
L1:
|
||||
<END> INIT: in: {x=ID} out: {x=ID}
|
||||
|
||||
@@ -11,15 +11,15 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ val a = 1 val f = { (x: Int) -> val y = x + a use(a) } })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(1) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID}
|
||||
v(val f = { (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID} out: {a=ID, f=D}
|
||||
mark({ (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID, f=D} out: {a=ID, f=D}
|
||||
jmp?(L2)
|
||||
d({ (x: Int) -> val y = x + a use(a) }) USE: in: {a=READ} out: {a=READ}
|
||||
L2:
|
||||
r({ (x: Int) -> val y = x + a use(a) })
|
||||
w(f) INIT: in: {a=ID, f=D} out: {a=ID, f=ID}
|
||||
r({ (x: Int) -> val y = x + a use(a) }) -> <v1>
|
||||
w(f|<v1>) INIT: in: {a=ID, f=D} out: {a=ID, f=ID}
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -34,38 +34,40 @@ sink:
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark(val y = x + a use(a)) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val y = x + a) INIT: in: {x=ID} out: {x=ID, y=D}
|
||||
mark(x + a) INIT: in: {x=ID, y=D} out: {x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ}
|
||||
r(x) USE: in: {a=READ} out: {a=READ, x=READ}
|
||||
r(a)
|
||||
call(+, plus)
|
||||
w(y) INIT: in: {x=ID, y=D} out: {x=ID, y=ID}
|
||||
mark(use(a)) INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) USE: in: {} out: {a=READ}
|
||||
call(use, use)
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
magic(x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark(val y = x + a use(a)) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val y = x + a) INIT: in: {x=ID} out: {x=ID, y=D}
|
||||
mark(x + a) INIT: in: {x=ID, y=D} out: {x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ}
|
||||
r(x) -> <v1> USE: in: {a=READ} out: {a=READ, x=READ}
|
||||
r(a) -> <v2>
|
||||
call(+, plus|<v1>, <v2>) -> <v3>
|
||||
w(y|<v3>) INIT: in: {x=ID, y=D} out: {x=ID, y=ID}
|
||||
mark(use(a)) INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v4> USE: in: {} out: {a=READ}
|
||||
call(use, use|<v4>) -> <v5>
|
||||
L4:
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
== use ==
|
||||
fun use(vararg a: Any?) = a
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
magic(vararg a: Any?) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v1> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
L1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -10,12 +10,12 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ val a = 1 val b: Int b = 2 42 })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(1) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID}
|
||||
v(val b: Int) INIT: in: {a=ID} out: {a=ID, b=D}
|
||||
r(2) INIT: in: {a=ID, b=D} out: {a=ID, b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
w(b) INIT: in: {a=ID, b=D} out: {a=ID, b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
r(42) INIT: in: {a=ID, b=ID} out: {a=ID, b=ID}
|
||||
r(2) -> <v1> INIT: in: {a=ID, b=D} out: {a=ID, b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
w(b|<v1>) INIT: in: {a=ID, b=D} out: {a=ID, b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
r(42) -> <v2> INIT: in: {a=ID, b=ID} out: {a=ID, b=ID}
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -33,15 +33,16 @@ fun bar(foo: Foo) {
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(foo: Foo) INIT: in: {} out: {foo=D}
|
||||
w(foo) INIT: in: {foo=D} out: {foo=ID}
|
||||
magic(foo: Foo) -> <v0> INIT: in: {foo=D} out: {foo=D}
|
||||
w(foo|<v0>) INIT: in: {foo=D} out: {foo=ID}
|
||||
2 mark({ foo.c foo.c = 2 42 }) INIT: in: {foo=ID} out: {foo=ID}
|
||||
mark(foo.c)
|
||||
r(foo) USE: in: {c=READ, foo=READ} out: {c=READ, foo=READ}
|
||||
r(c) USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=READ, foo=READ}
|
||||
r(2) USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ}
|
||||
r(foo) USE: in: {c=ONLY_WRITTEN_NEVER_READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ}
|
||||
w(foo.c) INIT: in: {foo=ID} out: {c=I, foo=ID} USE: in: {} out: {c=ONLY_WRITTEN_NEVER_READ}
|
||||
r(42) INIT: in: {c=I, foo=ID} out: {c=I, foo=ID}
|
||||
r(foo) -> <v1> USE: in: {c=READ, foo=READ} out: {c=READ, foo=READ}
|
||||
r(c|<v1>) -> <v2> USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=READ, foo=READ}
|
||||
r(2) -> <v3> USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ}
|
||||
r(foo) -> <v4> USE: in: {c=ONLY_WRITTEN_NEVER_READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ}
|
||||
w(foo.c|<v4>, <v3>) INIT: in: {foo=ID} out: {c=I, foo=ID} USE: in: {} out: {c=ONLY_WRITTEN_NEVER_READ}
|
||||
r(42) -> <v5> INIT: in: {c=I, foo=ID} out: {c=I, foo=ID}
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
|
||||
@@ -10,16 +10,16 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ var a = 1 use(a) a = 2 use(a) })
|
||||
v(var a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(1) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID}
|
||||
mark(use(a)) INIT: in: {a=ID} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) USE: in: {a=WRITTEN_AFTER_READ} out: {a=READ}
|
||||
call(use, use)
|
||||
r(2) USE: in: {a=WRITTEN_AFTER_READ} out: {a=WRITTEN_AFTER_READ}
|
||||
w(a) USE: in: {a=READ} out: {a=WRITTEN_AFTER_READ}
|
||||
r(a) -> <v1> USE: in: {a=WRITTEN_AFTER_READ} out: {a=READ}
|
||||
call(use, use|<v1>) -> <v2>
|
||||
r(2) -> <v3> USE: in: {a=WRITTEN_AFTER_READ} out: {a=WRITTEN_AFTER_READ}
|
||||
w(a|<v3>) USE: in: {a=READ} out: {a=WRITTEN_AFTER_READ}
|
||||
mark(use(a)) USE: in: {a=READ} out: {a=READ}
|
||||
r(a) USE: in: {} out: {a=READ}
|
||||
call(use, use)
|
||||
r(a) -> <v4> USE: in: {} out: {a=READ}
|
||||
call(use, use|<v4>) -> <v5>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -37,8 +37,8 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ val b: Int b = 3 })
|
||||
v(val b: Int) INIT: in: {} out: {b=D}
|
||||
r(3) INIT: in: {b=D} out: {b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
w(b) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
r(3) -> <v0> INIT: in: {b=D} out: {b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
w(b|<v0>) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ}
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -50,14 +50,15 @@ sink:
|
||||
fun use(a: Int) = a
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(a: Int) INIT: in: {} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(a: Int) INIT: in: {} out: {a=D}
|
||||
magic(a: Int) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v1> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
L1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -12,8 +12,8 @@ L0:
|
||||
jmp?(L2)
|
||||
d({ (x: Int) -> sum(x - 1) + x }) USE: in: {sum=READ} out: {sum=READ}
|
||||
L2:
|
||||
r({ (x: Int) -> sum(x - 1) + x })
|
||||
w(sum) INIT: in: {sum=D} out: {sum=ID}
|
||||
r({ (x: Int) -> sum(x - 1) + x }) -> <v0>
|
||||
w(sum|<v0>) INIT: in: {sum=D} out: {sum=ID}
|
||||
L1:
|
||||
<END> INIT: in: {sum=ID} out: {sum=ID}
|
||||
error:
|
||||
@@ -27,40 +27,42 @@ sink:
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
2 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
3 mark(sum(x - 1) + x) INIT: in: {x=ID} out: {x=ID}
|
||||
2 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
magic(x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||
3 mark(sum(x - 1) + x) INIT: in: {x=ID} out: {x=ID}
|
||||
mark(sum(x - 1) + x)
|
||||
mark(sum(x - 1)) USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ}
|
||||
r(sum) USE: in: {x=READ} out: {sum=READ, x=READ}
|
||||
mark(sum(x - 1)) USE: in: {sum=READ, x=READ} out: {sum=READ, x=READ}
|
||||
r(sum) -> <v1> USE: in: {x=READ} out: {sum=READ, x=READ}
|
||||
mark(x - 1)
|
||||
r(x)
|
||||
r(1)
|
||||
call(-, minus)
|
||||
call(sum, invoke) USE: in: {x=READ} out: {x=READ}
|
||||
r(x) USE: in: {} out: {x=READ}
|
||||
call(+, plus)
|
||||
r(x) -> <v2>
|
||||
r(1) -> <v3>
|
||||
call(-, minus|<v2>, <v3>) -> <v4>
|
||||
call(sum, invoke|<v1>, <v4>) -> <v5> USE: in: {x=READ} out: {x=READ}
|
||||
r(x) -> <v6> USE: in: {} out: {x=READ}
|
||||
call(+, plus|<v5>, <v6>) -> <v7>
|
||||
L4:
|
||||
2 <END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
== A ==
|
||||
open class A(val a: A)
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(val a: A) INIT: in: {} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(val a: A) INIT: in: {} out: {a=D}
|
||||
magic(val a: A) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID}
|
||||
L1:
|
||||
<END> INIT: in: {a=ID} out: {a=ID}
|
||||
<END> INIT: in: {a=ID} out: {a=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
== TestObjectLiteral ==
|
||||
class TestObjectLiteral {
|
||||
@@ -78,16 +80,16 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(val obj: A = object: A(obj) { { val x = obj } fun foo() { val y = obj } }) INIT: in: {} out: {obj=D}
|
||||
mark(object: A(obj) { { val x = obj } fun foo() { val y = obj } }) INIT: in: {obj=D} out: {obj=D}
|
||||
r(obj)
|
||||
r(obj) -> <v0>
|
||||
2 mark({ val x = obj })
|
||||
v(val x = obj) INIT: in: {obj=D} out: {obj=D, x=D}
|
||||
r(obj) INIT: in: {obj=D, x=D} out: {obj=D, x=D}
|
||||
w(x) INIT: in: {obj=D, x=D} out: {obj=D, x=ID}
|
||||
r(obj) -> <v1> INIT: in: {obj=D, x=D} out: {obj=D, x=D}
|
||||
w(x|<v1>) INIT: in: {obj=D, x=D} out: {obj=D, x=ID}
|
||||
1 jmp?(L2) INIT: in: {obj=D} out: {obj=D}
|
||||
d(fun foo() { val y = obj }) USE: in: {obj=READ} out: {obj=READ}
|
||||
L2:
|
||||
r(object: A(obj) { { val x = obj } fun foo() { val y = obj } })
|
||||
w(obj) INIT: in: {obj=D} out: {obj=ID}
|
||||
r(object: A(obj) { { val x = obj } fun foo() { val y = obj } }) -> <v2>
|
||||
w(obj|<v2>) INIT: in: {obj=D} out: {obj=ID}
|
||||
L1:
|
||||
<END> INIT: in: {obj=ID} out: {obj=ID}
|
||||
error:
|
||||
@@ -104,8 +106,8 @@ L3:
|
||||
2 <START> INIT: in: {} out: {}
|
||||
3 mark({ val y = obj })
|
||||
v(val y = obj) INIT: in: {} out: {y=D} USE: in: {obj=READ} out: {obj=READ}
|
||||
r(obj) INIT: in: {y=D} out: {y=D} USE: in: {} out: {obj=READ}
|
||||
w(y) INIT: in: {y=D} out: {y=ID}
|
||||
r(obj) -> <v0> INIT: in: {y=D} out: {y=D} USE: in: {} out: {obj=READ}
|
||||
w(y|<v0>) INIT: in: {y=D} out: {y=ID}
|
||||
L4:
|
||||
2 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -119,17 +121,17 @@ class TestOther {
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(val x: Int = x + 1) INIT: in: {} out: {x=D}
|
||||
mark(x + 1) INIT: in: {x=D} out: {x=D} USE: in: {x=READ} out: {x=READ}
|
||||
r(x) USE: in: {} out: {x=READ}
|
||||
r(1)
|
||||
call(+, plus)
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(val x: Int = x + 1) INIT: in: {} out: {x=D}
|
||||
mark(x + 1) INIT: in: {x=D} out: {x=D} USE: in: {x=READ} out: {x=READ}
|
||||
r(x) -> <v0> USE: in: {} out: {x=READ}
|
||||
r(1) -> <v1>
|
||||
call(+, plus|<v0>, <v1>) -> <v2>
|
||||
w(x|<v2>) INIT: in: {x=D} out: {x=ID}
|
||||
L1:
|
||||
<END> INIT: in: {x=ID} out: {x=ID}
|
||||
<END> INIT: in: {x=ID} out: {x=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -16,23 +16,24 @@ L0:
|
||||
v(val b: Boolean) INIT: in: {} out: {b=D}
|
||||
mark(if (1 < 2) { b = false } else { b = true }) INIT: in: {b=D} out: {b=D}
|
||||
mark(1 < 2)
|
||||
r(1)
|
||||
r(2)
|
||||
call(<, compareTo)
|
||||
jf(L2)
|
||||
r(1) -> <v0>
|
||||
r(2) -> <v1>
|
||||
call(<, compareTo|<v0>, <v1>) -> <v2>
|
||||
jf(L2|<v2>)
|
||||
3 mark({ b = false })
|
||||
r(false) USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b) INIT: in: {b=D} out: {b=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
|
||||
r(false) -> <v3> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b|<v3>) INIT: in: {b=D} out: {b=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
|
||||
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) USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b) INIT: in: {b=D} out: {b=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
|
||||
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}
|
||||
L3:
|
||||
2 mark(use(b)) INIT: in: {b=ID} out: {b=ID}
|
||||
error(use, No resolved call) USE: in: {b=READ} out: {b=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
r(b) -> <v5> USE: in: {} out: {b=READ}
|
||||
error(use, No resolved call)
|
||||
magic(use|<v5>) -> <v6>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
|
||||
@@ -16,36 +16,38 @@ fun foo(numbers: Collection<Int>) {
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(numbers: Collection<Int>) INIT: in: {} out: {numbers=D}
|
||||
w(numbers) INIT: in: {numbers=D} out: {numbers=ID}
|
||||
magic(numbers: Collection<Int>) -> <v0> INIT: in: {numbers=D} out: {numbers=D}
|
||||
w(numbers|<v0>) INIT: in: {numbers=D} out: {numbers=ID}
|
||||
2 mark({ for (i in numbers) { val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue } }) INIT: in: {numbers=ID} out: {numbers=ID}
|
||||
3 mark(for (i in numbers) { val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue }) USE: in: {numbers=READ} out: {numbers=READ}
|
||||
r(numbers) USE: in: {} out: {numbers=READ}
|
||||
r(numbers) -> <v1> USE: in: {} out: {numbers=READ}
|
||||
v(i) INIT: in: {numbers=ID} out: {i=D, numbers=ID}
|
||||
L3:
|
||||
jmp?(L2) INIT: in: {i=D, numbers=ID} out: {i=D, numbers=ID}
|
||||
L4 [loop entry point]:
|
||||
L5 [body entry point]:
|
||||
w(i) INIT: in: {i=D, numbers=ID} out: {i=ID, numbers=ID} USE: in: {} out: {}
|
||||
magic(numbers|<v1>) -> <v2>
|
||||
w(i|<v2>) INIT: in: {i=D, numbers=ID} out: {i=ID, numbers=ID} USE: in: {} out: {}
|
||||
4 mark({ val b: Boolean if (1 < 2) { b = false } else { b = true } use(b) continue }) INIT: in: {i=ID, numbers=ID} out: {i=ID, numbers=ID}
|
||||
v(val b: Boolean) INIT: in: {i=ID, numbers=ID} out: {b=D, i=ID, numbers=ID}
|
||||
mark(if (1 < 2) { b = false } else { b = true }) INIT: in: {b=D, i=ID, numbers=ID} out: {b=D, i=ID, numbers=ID}
|
||||
mark(1 < 2)
|
||||
r(1)
|
||||
r(2)
|
||||
call(<, compareTo)
|
||||
jf(L6)
|
||||
r(1) -> <v3>
|
||||
r(2) -> <v4>
|
||||
call(<, compareTo|<v3>, <v4>) -> <v5>
|
||||
jf(L6|<v5>)
|
||||
5 mark({ b = false })
|
||||
r(false) USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b) 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(false) -> <v6> USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b|<v6>) INIT: in: {b=D, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=WRITTEN_AFTER_READ}
|
||||
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) USE: in: {b=WRITTEN_AFTER_READ} out: {b=WRITTEN_AFTER_READ}
|
||||
w(b) 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) -> <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}
|
||||
L7:
|
||||
4 mark(use(b)) INIT: in: {b=ID, i=ID, numbers=ID} out: {b=ID, i=ID, numbers=ID} USE: in: {b=READ} out: {b=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
call(use, use)
|
||||
r(b) -> <v8> USE: in: {} out: {b=READ}
|
||||
call(use, use|<v8>) -> <v9>
|
||||
jmp(L4 [loop entry point]) USE: in: {} out: {}
|
||||
- 3 jmp?(L4 [loop entry point])
|
||||
L2:
|
||||
@@ -61,14 +63,15 @@ sink:
|
||||
fun use(vararg a: Any?) = a
|
||||
---------------------
|
||||
L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
1 <START> INIT: in: {} out: {}
|
||||
v(vararg a: Any?) INIT: in: {} out: {a=D}
|
||||
magic(vararg a: Any?) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v1> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ}
|
||||
L1:
|
||||
<END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -11,24 +11,24 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" do { var a = 2 } while (a > 0) "after" })
|
||||
mark("before")
|
||||
r("before") USE: in: {} out: {}
|
||||
r("before") -> <v0> USE: in: {} out: {}
|
||||
3 mark(do { var a = 2 } while (a > 0))
|
||||
L2 [loop entry point]:
|
||||
L4 [body entry point]:
|
||||
mark({ var a = 2 }) INIT: in: {a=ID} out: {a=ID}
|
||||
v(var a = 2)
|
||||
r(2)
|
||||
w(a)
|
||||
r(2) -> <v1>
|
||||
w(a|<v1>)
|
||||
L5 [condition entry point]:
|
||||
mark(a > 0)
|
||||
r(a)
|
||||
r(0)
|
||||
call(>, compareTo)
|
||||
jt(L2 [loop entry point]) USE: in: {a=READ} out: {a=READ}
|
||||
r(a) -> <v2>
|
||||
r(0) -> <v3>
|
||||
call(>, compareTo|<v2>, <v3>) -> <v4>
|
||||
jt(L2 [loop entry point]|<v4>) USE: in: {a=READ} out: {a=READ}
|
||||
L3 [loop exit point]:
|
||||
read (Unit)
|
||||
2 mark("after") INIT: in: {} out: {}
|
||||
r("after")
|
||||
r("after") -> <v5>
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
|
||||
@@ -11,27 +11,28 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" for (i in 1..10) { val a = i } "after" })
|
||||
mark("before")
|
||||
r("before") USE: in: {} out: {}
|
||||
r("before") -> <v0> USE: in: {} out: {}
|
||||
3 mark(for (i in 1..10) { val a = i })
|
||||
mark(1..10)
|
||||
r(1)
|
||||
r(10)
|
||||
call(.., rangeTo)
|
||||
r(1) -> <v1>
|
||||
r(10) -> <v2>
|
||||
call(.., rangeTo|<v1>, <v2>) -> <v3>
|
||||
v(i) INIT: in: {} out: {i=D}
|
||||
L3:
|
||||
jmp?(L2) INIT: in: {i=D} out: {i=D}
|
||||
L4 [loop entry point]:
|
||||
L5 [body entry point]:
|
||||
w(i) INIT: in: {i=D} out: {i=ID}
|
||||
magic(1..10|<v3>) -> <v4>
|
||||
w(i|<v4>) INIT: in: {i=D} out: {i=ID}
|
||||
4 mark({ val a = i }) INIT: in: {i=ID} out: {i=ID}
|
||||
v(val a = i) INIT: in: {i=ID} out: {a=D, i=ID}
|
||||
r(i) INIT: in: {a=D, i=ID} out: {a=D, i=ID}
|
||||
w(a) INIT: in: {a=D, i=ID} out: {a=ID, i=ID}
|
||||
r(i) -> <v5> INIT: in: {a=D, i=ID} out: {a=D, i=ID}
|
||||
w(a|<v5>) INIT: in: {a=D, i=ID} out: {a=ID, i=ID}
|
||||
3 jmp?(L4 [loop entry point]) INIT: in: {i=ID} out: {i=ID} USE: in: {i=READ} out: {i=READ}
|
||||
L2:
|
||||
read (Unit) INIT: in: {i=D} out: {i=D}
|
||||
2 mark("after") INIT: in: {} out: {}
|
||||
r("after")
|
||||
r("after") -> <v6>
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
|
||||
@@ -12,19 +12,19 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ "before" val b = 1 val f = { (x: Int) -> val a = x + b } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
v(val b = 1) INIT: in: {} out: {b=D}
|
||||
r(1) INIT: in: {b=D} out: {b=D}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
||||
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
||||
v(val f = { (x: Int) -> val a = x + b }) INIT: in: {b=ID} out: {b=ID, f=D}
|
||||
mark({ (x: Int) -> val a = x + b }) INIT: in: {b=ID, f=D} out: {b=ID, f=D}
|
||||
jmp?(L2)
|
||||
d({ (x: Int) -> val a = x + b }) USE: in: {b=READ} out: {b=READ}
|
||||
L2:
|
||||
r({ (x: Int) -> val a = x + b })
|
||||
w(f) INIT: in: {b=ID, f=D} out: {b=ID, f=ID}
|
||||
r({ (x: Int) -> val a = x + b }) -> <v2>
|
||||
w(f|<v2>) INIT: in: {b=ID, f=D} out: {b=ID, f=ID}
|
||||
mark("after") INIT: in: {b=ID, f=ID} out: {b=ID, f=ID}
|
||||
r("after")
|
||||
r("after") -> <v3>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -38,20 +38,21 @@ sink:
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark(val a = x + b) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID}
|
||||
mark(x + b) INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
call(+, plus)
|
||||
w(a) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
magic(x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark(val a = x + b) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID}
|
||||
mark(x + b) INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) -> <v1> USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) -> <v2> USE: in: {} out: {b=READ}
|
||||
call(+, plus|<v1>, <v2>) -> <v3>
|
||||
w(a|<v3>) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
L4:
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -14,23 +14,23 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" if (true) { val a = 1 } else { val b = 2 } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
mark(if (true) { val a = 1 } else { val b = 2 })
|
||||
r(true)
|
||||
jf(L2)
|
||||
r(true) -> <v1>
|
||||
jf(L2|<v1>)
|
||||
3 mark({ val a = 1 })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
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) INIT: in: {b=D} out: {b=D}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
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")
|
||||
r("after") -> <v4>
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
|
||||
@@ -16,18 +16,19 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" class A(val x: Int) { { val a = x } fun foo() { val b = x } } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
v(val x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
magic(val x: Int) -> <v1> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v1>) INIT: in: {x=D} out: {x=ID}
|
||||
3 mark({ val a = x }) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val a = x) INIT: in: {x=ID} out: {a=D, x=ID}
|
||||
r(x) INIT: in: {a=D, x=ID} out: {a=D, x=ID}
|
||||
w(a) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
r(x) -> <v2> INIT: in: {a=D, x=ID} out: {a=D, x=ID}
|
||||
w(a|<v2>) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
2 jmp?(L2) INIT: in: {x=ID} out: {x=ID}
|
||||
d(fun foo() { val b = x }) USE: in: {x=READ} out: {x=READ}
|
||||
L2:
|
||||
mark("after")
|
||||
r("after")
|
||||
r("after") -> <v3>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -44,8 +45,8 @@ L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
4 mark({ val b = x })
|
||||
v(val b = x) INIT: in: {} out: {b=D} USE: in: {x=READ} out: {x=READ}
|
||||
r(x) INIT: in: {b=D} out: {b=D} USE: in: {} out: {x=READ}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
r(x) -> <v0> INIT: in: {b=D} out: {b=D} USE: in: {} out: {x=READ}
|
||||
w(b|<v0>) INIT: in: {b=D} out: {b=ID}
|
||||
L4:
|
||||
3 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
|
||||
@@ -12,15 +12,15 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ "before" val b = 1 fun local(x: Int) { val a = x + b } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
v(val b = 1) INIT: in: {} out: {b=D}
|
||||
r(1) INIT: in: {b=D} out: {b=D}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
||||
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
||||
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
||||
d(fun local(x: Int) { val a = x + b }) USE: in: {b=READ} out: {b=READ}
|
||||
L2:
|
||||
mark("after")
|
||||
r("after")
|
||||
r("after") -> <v2>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -34,20 +34,21 @@ fun local(x: Int) {
|
||||
}
|
||||
---------------------
|
||||
L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark({ val a = x + b }) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID}
|
||||
mark(x + b) INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
call(+, plus)
|
||||
w(a) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
magic(x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||
4 mark({ val a = x + b }) INIT: in: {x=ID} out: {x=ID}
|
||||
v(val a = x + b) INIT: in: {x=ID} out: {a=D, x=ID}
|
||||
mark(x + b) INIT: in: {a=D, x=ID} out: {a=D, x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) -> <v1> USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) -> <v2> USE: in: {} out: {b=READ}
|
||||
call(+, plus|<v1>, <v2>) -> <v3>
|
||||
w(a|<v3>) INIT: in: {a=D, x=ID} out: {a=ID, x=ID}
|
||||
L4:
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
3 <END> INIT: in: {x=ID} out: {x=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
+14
-13
@@ -10,15 +10,15 @@ L0:
|
||||
1 <START> INIT: in: {} out: {} USE: in: {} out: {}
|
||||
2 mark({ "before" val b = 1 fun local(x: Int) = x + b "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
v(val b = 1) INIT: in: {} out: {b=D}
|
||||
r(1) INIT: in: {b=D} out: {b=D}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
r(1) -> <v1> INIT: in: {b=D} out: {b=D}
|
||||
w(b|<v1>) INIT: in: {b=D} out: {b=ID}
|
||||
jmp?(L2) INIT: in: {b=ID} out: {b=ID}
|
||||
d(fun local(x: Int) = x + b) USE: in: {b=READ} out: {b=READ}
|
||||
L2:
|
||||
mark("after")
|
||||
r("after")
|
||||
r("after") -> <v2>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -30,17 +30,18 @@ sink:
|
||||
fun local(x: Int) = x + b
|
||||
---------------------
|
||||
L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
w(x) INIT: in: {x=D} out: {x=ID}
|
||||
mark(x + b) INIT: in: {x=ID} out: {x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) USE: in: {} out: {b=READ}
|
||||
call(+, plus)
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(x: Int) INIT: in: {} out: {x=D}
|
||||
magic(x: Int) -> <v0> INIT: in: {x=D} out: {x=D}
|
||||
w(x|<v0>) INIT: in: {x=D} out: {x=ID}
|
||||
mark(x + b) INIT: in: {x=ID} out: {x=ID} USE: in: {b=READ, x=READ} out: {b=READ, x=READ}
|
||||
r(x) -> <v1> USE: in: {b=READ} out: {b=READ, x=READ}
|
||||
r(b) -> <v2> USE: in: {} out: {b=READ}
|
||||
call(+, plus|<v1>, <v2>) -> <v3>
|
||||
L4:
|
||||
<END>
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -16,16 +16,16 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" object A { { val a = 1 } fun foo() { val b = 2 } } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
3 mark({ val a = 1 })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(1) -> <v1> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v1>) INIT: in: {a=D} out: {a=ID}
|
||||
2 jmp?(L2) INIT: in: {} out: {}
|
||||
d(fun foo() { val b = 2 })
|
||||
L2:
|
||||
mark("after")
|
||||
r("after")
|
||||
r("after") -> <v2>
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
@@ -42,8 +42,8 @@ L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
4 mark({ val b = 2 })
|
||||
v(val b = 2) INIT: in: {} out: {b=D}
|
||||
r(2) INIT: in: {b=D} out: {b=D}
|
||||
w(b) INIT: in: {b=D} out: {b=ID}
|
||||
r(2) -> <v0> INIT: in: {b=D} out: {b=D}
|
||||
w(b|<v0>) INIT: in: {b=D} out: {b=ID}
|
||||
L4:
|
||||
3 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
|
||||
@@ -16,20 +16,20 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" val bar = object { { val x = 1 } fun foo() { val a = 2 } } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
v(val bar = object { { val x = 1 } fun foo() { val a = 2 } }) INIT: in: {} out: {bar=D}
|
||||
mark(object { { val x = 1 } fun foo() { val a = 2 } }) INIT: in: {bar=D} out: {bar=D}
|
||||
3 mark({ val x = 1 })
|
||||
v(val x = 1) INIT: in: {bar=D} out: {bar=D, x=D}
|
||||
r(1) INIT: in: {bar=D, x=D} out: {bar=D, x=D}
|
||||
w(x) INIT: in: {bar=D, x=D} out: {bar=D, x=ID}
|
||||
r(1) -> <v1> INIT: in: {bar=D, x=D} out: {bar=D, x=D}
|
||||
w(x|<v1>) INIT: in: {bar=D, x=D} out: {bar=D, x=ID}
|
||||
2 jmp?(L2) INIT: in: {bar=D} out: {bar=D}
|
||||
d(fun foo() { val a = 2 })
|
||||
L2:
|
||||
r(object { { val x = 1 } fun foo() { val a = 2 } })
|
||||
w(bar) INIT: in: {bar=D} out: {bar=ID}
|
||||
r(object { { val x = 1 } fun foo() { val a = 2 } }) -> <v2>
|
||||
w(bar|<v2>) INIT: in: {bar=D} out: {bar=ID}
|
||||
mark("after") INIT: in: {bar=ID} out: {bar=ID}
|
||||
r("after")
|
||||
r("after") -> <v3>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
@@ -46,8 +46,8 @@ L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
4 mark({ val a = 2 })
|
||||
v(val a = 2) INIT: in: {} out: {a=D}
|
||||
r(2) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(2) -> <v0> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v0>) INIT: in: {a=D} out: {a=ID}
|
||||
L4:
|
||||
3 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
|
||||
@@ -36,8 +36,8 @@ get() {
|
||||
L3:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
4 mark({ return $a }) USE: in: {a=READ} out: {a=READ}
|
||||
r($a) USE: in: {} out: {a=READ}
|
||||
ret(*) L4
|
||||
r($a) -> <v0> USE: in: {} out: {a=READ}
|
||||
ret(*|<v0>) L4
|
||||
L4:
|
||||
3 <END>
|
||||
error:
|
||||
@@ -51,16 +51,17 @@ set(v: Int) {
|
||||
}
|
||||
---------------------
|
||||
L6:
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(v: Int) INIT: in: {} out: {v=D}
|
||||
w(v) INIT: in: {v=D} out: {v=ID}
|
||||
4 mark({ $a = v }) INIT: in: {v=ID} out: {v=ID} USE: in: {a=ONLY_WRITTEN_NEVER_READ, v=READ} out: {a=ONLY_WRITTEN_NEVER_READ, v=READ}
|
||||
r(v) USE: in: {a=ONLY_WRITTEN_NEVER_READ} out: {a=ONLY_WRITTEN_NEVER_READ, v=READ}
|
||||
w($a) INIT: in: {v=ID} out: {a=I, v=ID} USE: in: {} out: {a=ONLY_WRITTEN_NEVER_READ}
|
||||
3 <START> INIT: in: {} out: {}
|
||||
v(v: Int) INIT: in: {} out: {v=D}
|
||||
magic(v: Int) -> <v0> INIT: in: {v=D} out: {v=D}
|
||||
w(v|<v0>) INIT: in: {v=D} out: {v=ID}
|
||||
4 mark({ $a = v }) INIT: in: {v=ID} out: {v=ID} USE: in: {a=ONLY_WRITTEN_NEVER_READ, v=READ} out: {a=ONLY_WRITTEN_NEVER_READ, v=READ}
|
||||
r(v) -> <v1> USE: in: {a=ONLY_WRITTEN_NEVER_READ} out: {a=ONLY_WRITTEN_NEVER_READ, v=READ}
|
||||
w($a|<v1>) INIT: in: {v=ID} out: {a=I, v=ID} USE: in: {} out: {a=ONLY_WRITTEN_NEVER_READ}
|
||||
L7:
|
||||
3 <END> INIT: in: {a=I, v=ID} out: {a=I, v=ID}
|
||||
3 <END> INIT: in: {a=I, v=ID} out: {a=I, v=ID}
|
||||
error:
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
<ERROR> INIT: in: {} out: {}
|
||||
sink:
|
||||
<SINK> INIT: in: {a=I, v=ID} out: {a=I, v=ID} USE: in: {} out: {}
|
||||
<SINK> INIT: in: {a=I, v=ID} out: {a=I, v=ID} USE: in: {} out: {}
|
||||
=====================
|
||||
|
||||
@@ -17,21 +17,22 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
mark(try { foo() } catch (e: Exception) { val a = e } finally { val a = 1 })
|
||||
jmp?(L2 [onException])
|
||||
jmp?(L3 [onExceptionToFinallyBlock])
|
||||
3 mark({ foo() })
|
||||
mark(foo())
|
||||
call(foo, foo)
|
||||
call(foo, foo) -> <v1>
|
||||
2 jmp(L4 [afterCatches]) USE: in: {} out: {}
|
||||
L2 [onException]:
|
||||
3 v(e: Exception) INIT: in: {} out: {e=D}
|
||||
w(e) INIT: in: {e=D} out: {e=ID}
|
||||
magic(e: Exception) -> <v2> INIT: in: {e=D} out: {e=D}
|
||||
w(e|<v2>) INIT: in: {e=D} out: {e=ID}
|
||||
4 mark({ val a = e }) INIT: in: {e=ID} out: {e=ID}
|
||||
v(val a = e) INIT: in: {e=ID} out: {a=D, e=ID} USE: in: {e=READ} out: {e=READ}
|
||||
r(e) INIT: in: {a=D, e=ID} out: {a=D, e=ID} USE: in: {} out: {e=READ}
|
||||
w(a) INIT: in: {a=D, e=ID} out: {a=ID, e=ID}
|
||||
r(e) -> <v3> INIT: in: {a=D, e=ID} out: {a=D, e=ID} USE: in: {} out: {e=READ}
|
||||
w(a|<v3>) INIT: in: {a=D, e=ID} out: {a=ID, e=ID}
|
||||
3 jmp(L4 [afterCatches]) INIT: in: {e=ID} out: {e=ID}
|
||||
L4 [afterCatches]:
|
||||
2 jmp(L5 [skipFinallyToErrorBlock]) INIT: in: {} out: {}
|
||||
@@ -39,17 +40,17 @@ L3 [onExceptionToFinallyBlock]:
|
||||
L6 [start finally]:
|
||||
3 mark({ val a = 1 })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
r(1) -> <v4> INIT: in: {a=D} out: {a=D}
|
||||
w(a|<v4>) INIT: in: {a=D} out: {a=ID}
|
||||
L7 [finish finally]:
|
||||
2 jmp(error) INIT: in: {} out: {}
|
||||
L5 [skipFinallyToErrorBlock]:
|
||||
3 mark({ val a = 1 })
|
||||
v(val a = 1) INIT: in: {} out: {a=D}
|
||||
r(1) INIT: in: {a=D} out: {a=D}
|
||||
w(a) INIT: in: {a=D} out: {a=ID}
|
||||
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")
|
||||
r("after") -> <v5>
|
||||
L1:
|
||||
1 <END>
|
||||
error:
|
||||
|
||||
@@ -11,11 +11,11 @@ L0:
|
||||
1 <START> INIT: in: {} out: {}
|
||||
2 mark({ "before" while (true) { val a: Int } "after" })
|
||||
mark("before")
|
||||
r("before")
|
||||
r("before") -> <v0>
|
||||
mark(while (true) { val a: Int })
|
||||
L2 [loop entry point]:
|
||||
L5 [condition entry point]:
|
||||
r(true)
|
||||
r(true) -> <v1>
|
||||
L4 [body entry point]:
|
||||
3 mark({ val a: Int })
|
||||
v(val a: Int) INIT: in: {} out: {a=D}
|
||||
@@ -23,7 +23,7 @@ L4 [body entry point]:
|
||||
L3 [loop exit point]:
|
||||
- read (Unit)
|
||||
- mark("after")
|
||||
- r("after")
|
||||
- r("after") -> <v2>
|
||||
L1:
|
||||
1 <END> INIT: in: {} out: {}
|
||||
error:
|
||||
|
||||
@@ -14,32 +14,30 @@ L0:
|
||||
2 mark({ val a = Array<Int> 3 a[10] = 4 2 a[10] 100 a[10] += 1 })
|
||||
v(val a = Array<Int>)
|
||||
mark(Array<Int>)
|
||||
call(Array, <init>)
|
||||
w(a)
|
||||
r(3)
|
||||
call(Array, <init>) -> <v0>
|
||||
w(a|<v0>)
|
||||
r(3) -> <v1>
|
||||
mark(a[10])
|
||||
r(a)
|
||||
r(10)
|
||||
r(4)
|
||||
call(a[10], set)
|
||||
r(2)
|
||||
r(a) -> <v2>
|
||||
r(10) -> <v3>
|
||||
r(4) -> <v4>
|
||||
call(a[10] = 4, set|<v2>, <v3>, <v4>) -> <v5>
|
||||
r(2) -> <v6>
|
||||
mark(a[10])
|
||||
r(a)
|
||||
r(10)
|
||||
call(a[10], get)
|
||||
r(100)
|
||||
r(a) -> <v7>
|
||||
r(10) -> <v8>
|
||||
call(a[10], get|<v7>, <v8>) -> <v9>
|
||||
r(100) -> <v10>
|
||||
mark(a[10] += 1)
|
||||
mark(a[10])
|
||||
r(a)
|
||||
r(10)
|
||||
call(a[10], get)
|
||||
r(1)
|
||||
call(+=, plus)
|
||||
mark(a[10])
|
||||
r(a)
|
||||
r(10)
|
||||
r(1)
|
||||
call(a[10], set)
|
||||
r(a) -> <v11>
|
||||
r(10) -> <v12>
|
||||
call(a[10], get|<v11>, <v12>) -> <v13>
|
||||
r(1) -> <v14>
|
||||
call(+=, plus|<v13>, <v14>) -> <v15>
|
||||
r(a) -> <v16>
|
||||
r(10) -> <v17>
|
||||
call(a[10] += 1, set|<v16>, <v17>, <v15>) -> <v18>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -6,19 +6,20 @@ fun test(array: Array<(Int)->Unit>) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(array: Array<(Int)->Unit>)
|
||||
w(array)
|
||||
magic(array: Array<(Int)->Unit>) -> <v0>
|
||||
w(array|<v0>)
|
||||
2 mark({ array[11](3) })
|
||||
mark(array[11](3))
|
||||
mark(array[11])
|
||||
r(array)
|
||||
r(11)
|
||||
call(array[11], get)
|
||||
r(3)
|
||||
call(array[11], invoke)
|
||||
r(array) -> <v1>
|
||||
r(11) -> <v2>
|
||||
call(array[11], get|<v1>, <v2>) -> <v3>
|
||||
r(3) -> <v4>
|
||||
call(array[11], invoke|<v3>, <v4>) -> <v5>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -32,19 +32,20 @@ fun test(ab: Ab) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(ab: Ab)
|
||||
w(ab)
|
||||
magic(ab: Ab) -> <v0>
|
||||
w(ab|<v0>)
|
||||
2 mark({ ab.getArray()[1] })
|
||||
mark(ab.getArray()[1])
|
||||
mark(ab.getArray())
|
||||
mark(getArray())
|
||||
r(ab)
|
||||
call(getArray, getArray)
|
||||
r(1)
|
||||
call(ab.getArray()[1], get)
|
||||
r(ab) -> <v1>
|
||||
call(getArray, getArray|<v1>) -> <v2>
|
||||
r(1) -> <v3>
|
||||
call(ab.getArray()[1], get|<v2>, <v3>) -> <v4>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
== foo ==
|
||||
fun foo(a: Array<Int>) {
|
||||
a[0]++
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Array<Int>)
|
||||
magic(a: Array<Int>) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ a[0]++ })
|
||||
mark(a[0]++)
|
||||
mark(a[0])
|
||||
r(a) -> <v1>
|
||||
r(0) -> <v2>
|
||||
call(a[0], get|<v1>, <v2>) -> <v3>
|
||||
call(++, inc|<v3>) -> <v4>
|
||||
r(a) -> <v5>
|
||||
r(0) -> <v6>
|
||||
call(a[0]++, set|<v5>, <v6>, <v4>) -> <v7>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(a: Array<Int>) {
|
||||
a[0]++
|
||||
}
|
||||
@@ -6,17 +6,18 @@ fun foo(a: Array<Int>) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Array<Int>)
|
||||
w(a)
|
||||
magic(a: Array<Int>) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ a[1] = 2 })
|
||||
mark(a[1])
|
||||
r(a)
|
||||
r(1)
|
||||
r(2)
|
||||
call(a[1], set)
|
||||
r(a) -> <v1>
|
||||
r(1) -> <v2>
|
||||
r(2) -> <v3>
|
||||
call(a[1] = 2, set|<v1>, <v2>, <v3>) -> <v4>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -6,24 +6,23 @@ fun foo(a: Array<Int>) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Array<Int>)
|
||||
w(a)
|
||||
magic(a: Array<Int>) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ a[0] += 1 })
|
||||
mark(a[0] += 1)
|
||||
mark(a[0])
|
||||
r(a)
|
||||
r(0)
|
||||
call(a[0], get)
|
||||
r(1)
|
||||
call(+=, plus)
|
||||
mark(a[0])
|
||||
r(a)
|
||||
r(0)
|
||||
r(1)
|
||||
call(a[0], set)
|
||||
r(a) -> <v1>
|
||||
r(0) -> <v2>
|
||||
call(a[0], get|<v1>, <v2>) -> <v3>
|
||||
r(1) -> <v4>
|
||||
call(+=, plus|<v3>, <v4>) -> <v5>
|
||||
r(a) -> <v6>
|
||||
r(0) -> <v7>
|
||||
call(a[0] += 1, set|<v6>, <v7>, <v5>) -> <v8>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -20,50 +20,51 @@ fun f(a : Boolean) : Unit {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Boolean)
|
||||
w(a)
|
||||
magic(a : Boolean) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ 1 a 2.toLong() foo(a, 3) genfun<Any>() flfun {1} 3.equals(4) 3 equals 4 1 + 2 a && true a || false })
|
||||
r(1)
|
||||
r(a)
|
||||
r(1) -> <v1>
|
||||
r(a) -> <v2>
|
||||
mark(2.toLong())
|
||||
mark(toLong())
|
||||
r(2)
|
||||
call(toLong, toLong)
|
||||
r(2) -> <v3>
|
||||
call(toLong, toLong|<v3>) -> <v4>
|
||||
mark(foo(a, 3))
|
||||
r(a)
|
||||
r(3)
|
||||
call(foo, foo)
|
||||
r(a) -> <v5>
|
||||
r(3) -> <v6>
|
||||
call(foo, foo|<v5>, <v6>) -> <v7>
|
||||
mark(genfun<Any>())
|
||||
call(genfun, genfun)
|
||||
call(genfun, genfun) -> <v8>
|
||||
mark(flfun {1})
|
||||
mark({1})
|
||||
jmp?(L2) NEXT:[r({1}), d({1})]
|
||||
jmp?(L2) NEXT:[r({1}) -> <v9>, d({1})]
|
||||
d({1}) NEXT:[<SINK>]
|
||||
L2:
|
||||
r({1}) PREV:[jmp?(L2)]
|
||||
call(flfun, flfun)
|
||||
r({1}) -> <v9> PREV:[jmp?(L2)]
|
||||
call(flfun, flfun|<v9>) -> <v10>
|
||||
mark(3.equals(4))
|
||||
mark(equals(4))
|
||||
r(3)
|
||||
r(4)
|
||||
call(equals, equals)
|
||||
r(3) -> <v11>
|
||||
r(4) -> <v12>
|
||||
call(equals, equals|<v11>, <v12>) -> <v13>
|
||||
mark(3 equals 4)
|
||||
r(3)
|
||||
r(4)
|
||||
call(equals, equals)
|
||||
r(3) -> <v14>
|
||||
r(4) -> <v15>
|
||||
call(equals, equals|<v14>, <v15>) -> <v16>
|
||||
mark(1 + 2)
|
||||
r(1)
|
||||
r(2)
|
||||
call(+, plus)
|
||||
r(a)
|
||||
jf(L5) NEXT:[r(a && true), r(true)]
|
||||
r(true)
|
||||
r(1) -> <v17>
|
||||
r(2) -> <v18>
|
||||
call(+, plus|<v17>, <v18>) -> <v19>
|
||||
r(a) -> <v20>
|
||||
jf(L5|<v20>) NEXT:[magic(a && true|<v20>, <v21>) -> <v22>, r(true) -> <v21>]
|
||||
r(true) -> <v21>
|
||||
L5:
|
||||
r(a && true) PREV:[jf(L5), r(true)]
|
||||
r(a)
|
||||
jt(L6) NEXT:[r(false), r(a || false)]
|
||||
r(false)
|
||||
magic(a && true|<v20>, <v21>) -> <v22> PREV:[jf(L5|<v20>), r(true) -> <v21>]
|
||||
r(a) -> <v23>
|
||||
jt(L6|<v23>) NEXT:[r(false) -> <v24>, magic(a || false|<v23>, <v24>) -> <v25>]
|
||||
r(false) -> <v24>
|
||||
L6:
|
||||
r(a || false) PREV:[jt(L6), r(false)]
|
||||
magic(a || false|<v23>, <v24>) -> <v25> PREV:[jt(L6|<v23>), r(false) -> <v24>]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -77,13 +78,13 @@ sink:
|
||||
L3:
|
||||
3 <START>
|
||||
4 mark(1)
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== foo ==
|
||||
fun foo(a : Boolean, b : Int) : Unit {}
|
||||
@@ -91,17 +92,19 @@ fun foo(a : Boolean, b : Int) : Unit {}
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Boolean)
|
||||
w(a)
|
||||
magic(a : Boolean) -> <v0>
|
||||
w(a|<v0>)
|
||||
v(b : Int)
|
||||
w(b)
|
||||
magic(b : Int) -> <v1>
|
||||
w(b|<v1>)
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== genfun ==
|
||||
fun genfun<T>() : Unit {}
|
||||
@@ -123,13 +126,14 @@ fun flfun(f : () -> Any) : Unit {}
|
||||
L0:
|
||||
1 <START>
|
||||
v(f : () -> Any)
|
||||
w(f)
|
||||
magic(f : () -> Any) -> <v0>
|
||||
w(f|<v0>)
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -3,11 +3,11 @@ fun short() = 1
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -10,23 +10,25 @@ fun foo(c: Collection<Int>) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(c: Collection<Int>)
|
||||
w(c)
|
||||
magic(c: Collection<Int>) -> <v0>
|
||||
w(c|<v0>)
|
||||
2 mark({ for (e in c) { { break } } })
|
||||
3 mark(for (e in c) { { break } })
|
||||
r(c)
|
||||
r(c) -> <v1>
|
||||
v(e)
|
||||
L3:
|
||||
jmp?(L2) NEXT:[read (Unit), w(e)]
|
||||
jmp?(L2) NEXT:[read (Unit), magic(c|<v1>) -> <v2>]
|
||||
L4 [loop entry point]:
|
||||
L5 [body entry point]:
|
||||
w(e) PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
magic(c|<v1>) -> <v2> PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
w(e|<v2>)
|
||||
4 mark({ { break } })
|
||||
mark({ break })
|
||||
jmp?(L6) NEXT:[r({ break }), d({ break })]
|
||||
jmp?(L6) NEXT:[r({ break }) -> <v3>, d({ break })]
|
||||
d({ break }) NEXT:[<SINK>]
|
||||
L6:
|
||||
r({ break }) PREV:[jmp?(L6)]
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[w(e), read (Unit)]
|
||||
r({ break }) -> <v3> PREV:[jmp?(L6)]
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[magic(c|<v1>) -> <v2>, read (Unit)]
|
||||
L2:
|
||||
read (Unit) PREV:[jmp?(L2), jmp(L2), jmp?(L4 [loop entry point])]
|
||||
L1:
|
||||
|
||||
@@ -13,17 +13,17 @@ L0:
|
||||
mark(try { 1 } finally { 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 })]
|
||||
3 mark({ 1 })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
2 jmp(L3 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L4 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v1>
|
||||
L5 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L3 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L3 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v1>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -49,33 +49,33 @@ L0:
|
||||
mark(try { 1 if (2 > 3) { return } } finally { 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { return } })]
|
||||
3 mark({ 1 if (2 > 3) { return } })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
mark(if (2 > 3) { return })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L3) NEXT:[read (Unit), mark({ return })]
|
||||
r(2) -> <v1>
|
||||
r(3) -> <v2>
|
||||
call(>, compareTo|<v1>, <v2>) -> <v3>
|
||||
jf(L3|<v3>) NEXT:[read (Unit), mark({ return })]
|
||||
4 mark({ return })
|
||||
L4 [start finally]:
|
||||
5 mark({ 2 })
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
L5 [finish finally]:
|
||||
4 ret L1 NEXT:[<END>]
|
||||
- 3 jmp(L6) NEXT:[jmp(L7 [skipFinallyToErrorBlock])] PREV:[]
|
||||
L3:
|
||||
read (Unit) PREV:[jf(L3)]
|
||||
read (Unit) PREV:[jf(L3|<v3>)]
|
||||
L6:
|
||||
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
5 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L7 [skipFinallyToErrorBlock]:
|
||||
5 mark({ 2 }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1, r(2)]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1, r(2) -> <v4>]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -101,23 +101,23 @@ L0:
|
||||
mark(try { 1 @l{ () -> if (2 > 3) { return@l } } } finally { 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 @l{ () -> if (2 > 3) { return@l } } })]
|
||||
3 mark({ 1 @l{ () -> if (2 > 3) { return@l } } })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
mark(@l{ () -> if (2 > 3) { return@l } })
|
||||
mark({ () -> if (2 > 3) { return@l } })
|
||||
jmp?(L3) NEXT:[r({ () -> if (2 > 3) { return@l } }), d({ () -> if (2 > 3) { return@l } })]
|
||||
jmp?(L3) NEXT:[r({ () -> if (2 > 3) { return@l } }) -> <v1>, d({ () -> if (2 > 3) { return@l } })]
|
||||
d({ () -> if (2 > 3) { return@l } }) NEXT:[<SINK>]
|
||||
L3:
|
||||
r({ () -> if (2 > 3) { return@l } }) PREV:[jmp?(L3)]
|
||||
r({ () -> if (2 > 3) { return@l } }) -> <v1> PREV:[jmp?(L3)]
|
||||
2 jmp(L8 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L9 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v2>
|
||||
L10 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L8 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L8 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -137,22 +137,22 @@ L4:
|
||||
5 mark(if (2 > 3) { return@l })
|
||||
mark(if (2 > 3) { return@l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L6) NEXT:[read (Unit), mark({ return@l })]
|
||||
r(2) -> <v0>
|
||||
r(3) -> <v1>
|
||||
call(>, compareTo|<v0>, <v1>) -> <v2>
|
||||
jf(L6|<v2>) NEXT:[read (Unit), mark({ return@l })]
|
||||
6 mark({ return@l })
|
||||
ret L5 NEXT:[<END>]
|
||||
- 5 jmp(L7) NEXT:[<END>] PREV:[]
|
||||
ret L5 NEXT:[<END>]
|
||||
- 5 jmp(L7) NEXT:[<END>] PREV:[]
|
||||
L6:
|
||||
read (Unit) PREV:[jf(L6)]
|
||||
read (Unit) PREV:[jf(L6|<v2>)]
|
||||
L5:
|
||||
L7:
|
||||
4 <END> NEXT:[<SINK>] PREV:[ret L5, read (Unit)]
|
||||
4 <END> NEXT:[<SINK>] PREV:[ret L5, read (Unit)]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== t4 ==
|
||||
fun t4() {
|
||||
@@ -173,10 +173,10 @@ L0:
|
||||
2 mark({ @l{ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } } })
|
||||
mark(@l{ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } })
|
||||
mark({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } })
|
||||
jmp?(L2) NEXT:[r({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } }), d({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } })]
|
||||
jmp?(L2) NEXT:[r({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) -> <v0>, d({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } })]
|
||||
d({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) NEXT:[<SINK>]
|
||||
L2:
|
||||
r({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) PREV:[jmp?(L2)]
|
||||
r({ () -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) -> <v0> PREV:[jmp?(L2)]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -202,33 +202,33 @@ L3:
|
||||
mark(try { 1 if (2 > 3) { return@l } } finally { 2 })
|
||||
jmp?(L5 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { return@l } })]
|
||||
5 mark({ 1 if (2 > 3) { return@l } })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
mark(if (2 > 3) { return@l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L6) NEXT:[read (Unit), mark({ return@l })]
|
||||
r(2) -> <v1>
|
||||
r(3) -> <v2>
|
||||
call(>, compareTo|<v1>, <v2>) -> <v3>
|
||||
jf(L6|<v3>) NEXT:[read (Unit), mark({ return@l })]
|
||||
6 mark({ return@l })
|
||||
L7 [start finally]:
|
||||
7 mark({ 2 })
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
L8 [finish finally]:
|
||||
6 ret L4 NEXT:[<END>]
|
||||
- 5 jmp(L9) NEXT:[jmp(L10 [skipFinallyToErrorBlock])] PREV:[]
|
||||
L6:
|
||||
read (Unit) PREV:[jf(L6)]
|
||||
read (Unit) PREV:[jf(L6|<v3>)]
|
||||
L9:
|
||||
4 jmp(L10 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L5 [onExceptionToFinallyBlock]:
|
||||
7 mark({ 2 }) PREV:[jmp?(L5 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
4 jmp(error) NEXT:[<ERROR>]
|
||||
L10 [skipFinallyToErrorBlock]:
|
||||
7 mark({ 2 }) PREV:[jmp(L10 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>] PREV:[ret L4, r(2)]
|
||||
3 <END> NEXT:[<SINK>] PREV:[ret L4, r(2) -> <v4>]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -255,38 +255,38 @@ L0:
|
||||
mark(while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } })
|
||||
L2 [loop entry point]:
|
||||
L5 [condition entry point]:
|
||||
r(true) PREV:[mark(while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } }), jmp(L2 [loop entry point])]
|
||||
r(true) -> <v0> PREV:[mark(while(true) { try { 1 if (2 > 3) { break @l } } finally { 2 } }), jmp(L2 [loop entry point])]
|
||||
L4 [body entry point]:
|
||||
3 mark({ try { 1 if (2 > 3) { break @l } } finally { 2 } })
|
||||
mark(try { 1 if (2 > 3) { break @l } } finally { 2 })
|
||||
jmp?(L6 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { break @l } })]
|
||||
4 mark({ 1 if (2 > 3) { break @l } })
|
||||
r(1)
|
||||
r(1) -> <v1>
|
||||
mark(if (2 > 3) { break @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ break @l })]
|
||||
r(2) -> <v2>
|
||||
r(3) -> <v3>
|
||||
call(>, compareTo|<v2>, <v3>) -> <v4>
|
||||
jf(L7|<v4>) NEXT:[read (Unit), mark({ break @l })]
|
||||
5 mark({ break @l })
|
||||
L8 [start finally]:
|
||||
6 mark({ 2 })
|
||||
r(2)
|
||||
r(2) -> <v5>
|
||||
L9 [finish finally]:
|
||||
5 jmp(L3 [loop exit point]) NEXT:[read (Unit)]
|
||||
- 4 jmp(L10) NEXT:[jmp(L11 [skipFinallyToErrorBlock])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v4>)]
|
||||
L10:
|
||||
3 jmp(L11 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L6 [onExceptionToFinallyBlock]:
|
||||
6 mark({ 2 }) PREV:[jmp?(L6 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v5>
|
||||
3 jmp(error) NEXT:[<ERROR>]
|
||||
L11 [skipFinallyToErrorBlock]:
|
||||
6 mark({ 2 }) PREV:[jmp(L11 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
2 jmp(L2 [loop entry point]) NEXT:[r(true)]
|
||||
r(2) -> <v5>
|
||||
2 jmp(L2 [loop entry point]) NEXT:[r(true) -> <v0>]
|
||||
L3 [loop exit point]:
|
||||
read (Unit) PREV:[jmp(L3 [loop exit point])]
|
||||
L1:
|
||||
@@ -321,36 +321,36 @@ L0:
|
||||
mark(while(true) { 1 if (2 > 3) { break @l } })
|
||||
L3 [loop entry point]:
|
||||
L6 [condition entry point]:
|
||||
r(true) PREV:[mark(while(true) { 1 if (2 > 3) { break @l } }), jmp(L3 [loop entry point])]
|
||||
r(true) -> <v0> PREV:[mark(while(true) { 1 if (2 > 3) { break @l } }), jmp(L3 [loop entry point])]
|
||||
L5 [body entry point]:
|
||||
4 mark({ 1 if (2 > 3) { break @l } })
|
||||
r(1)
|
||||
r(1) -> <v1>
|
||||
mark(if (2 > 3) { break @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ break @l })]
|
||||
r(2) -> <v2>
|
||||
r(3) -> <v3>
|
||||
call(>, compareTo|<v2>, <v3>) -> <v4>
|
||||
jf(L7|<v4>) NEXT:[read (Unit), mark({ break @l })]
|
||||
5 mark({ break @l })
|
||||
jmp(L4 [loop exit point]) NEXT:[read (Unit)]
|
||||
- 4 jmp(L8) NEXT:[jmp(L3 [loop entry point])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v4>)]
|
||||
L8:
|
||||
3 jmp(L3 [loop entry point]) NEXT:[r(true)]
|
||||
3 jmp(L3 [loop entry point]) NEXT:[r(true) -> <v0>]
|
||||
L4 [loop exit point]:
|
||||
read (Unit) PREV:[jmp(L4 [loop exit point])]
|
||||
r(5)
|
||||
r(5) -> <v5>
|
||||
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L10 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v6>
|
||||
L11 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L9 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v6>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -382,35 +382,35 @@ L0:
|
||||
mark(while(true) { 1 if (2 > 3) { break @l } })
|
||||
L3 [loop entry point]:
|
||||
L6 [condition entry point]:
|
||||
r(true) PREV:[mark(while(true) { 1 if (2 > 3) { break @l } }), jmp(L3 [loop entry point])]
|
||||
r(true) -> <v0> PREV:[mark(while(true) { 1 if (2 > 3) { break @l } }), jmp(L3 [loop entry point])]
|
||||
L5 [body entry point]:
|
||||
4 mark({ 1 if (2 > 3) { break @l } })
|
||||
r(1)
|
||||
r(1) -> <v1>
|
||||
mark(if (2 > 3) { break @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ break @l })]
|
||||
r(2) -> <v2>
|
||||
r(3) -> <v3>
|
||||
call(>, compareTo|<v2>, <v3>) -> <v4>
|
||||
jf(L7|<v4>) NEXT:[read (Unit), mark({ break @l })]
|
||||
5 mark({ break @l })
|
||||
jmp(L4 [loop exit point]) NEXT:[read (Unit)]
|
||||
- 4 jmp(L8) NEXT:[jmp(L3 [loop entry point])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v4>)]
|
||||
L8:
|
||||
3 jmp(L3 [loop entry point]) NEXT:[r(true)]
|
||||
3 jmp(L3 [loop entry point]) NEXT:[r(true) -> <v0>]
|
||||
L4 [loop exit point]:
|
||||
read (Unit) PREV:[jmp(L4 [loop exit point])]
|
||||
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L10 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v5>
|
||||
L11 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L9 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v5>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -435,50 +435,52 @@ fun t8(a : Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Int)
|
||||
w(a)
|
||||
magic(a : Int) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ @l for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } } })
|
||||
mark(@l for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } })
|
||||
3 mark(for (i in 1..a) { try { 1 if (2 > 3) { continue @l } } finally { 2 } })
|
||||
mark(1..a)
|
||||
r(1)
|
||||
r(a)
|
||||
call(.., rangeTo)
|
||||
r(1) -> <v1>
|
||||
r(a) -> <v2>
|
||||
call(.., rangeTo|<v1>, <v2>) -> <v3>
|
||||
v(i)
|
||||
L3:
|
||||
jmp?(L2) NEXT:[read (Unit), w(i)]
|
||||
jmp?(L2) NEXT:[read (Unit), magic(1..a|<v3>) -> <v4>]
|
||||
L4 [loop entry point]:
|
||||
L5 [body entry point]:
|
||||
w(i) PREV:[jmp?(L2), jmp(L4 [loop entry point]), jmp?(L4 [loop entry point])]
|
||||
magic(1..a|<v3>) -> <v4> PREV:[jmp?(L2), jmp(L4 [loop entry point]), jmp?(L4 [loop entry point])]
|
||||
w(i|<v4>)
|
||||
4 mark({ try { 1 if (2 > 3) { continue @l } } finally { 2 } })
|
||||
mark(try { 1 if (2 > 3) { continue @l } } finally { 2 })
|
||||
jmp?(L6 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { continue @l } })]
|
||||
5 mark({ 1 if (2 > 3) { continue @l } })
|
||||
r(1)
|
||||
r(1) -> <v5>
|
||||
mark(if (2 > 3) { continue @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ continue @l })]
|
||||
r(2) -> <v6>
|
||||
r(3) -> <v7>
|
||||
call(>, compareTo|<v6>, <v7>) -> <v8>
|
||||
jf(L7|<v8>) NEXT:[read (Unit), mark({ continue @l })]
|
||||
6 mark({ continue @l })
|
||||
L8 [start finally]:
|
||||
7 mark({ 2 })
|
||||
r(2)
|
||||
r(2) -> <v9>
|
||||
L9 [finish finally]:
|
||||
6 jmp(L4 [loop entry point]) NEXT:[w(i)]
|
||||
6 jmp(L4 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>]
|
||||
- 5 jmp(L10) NEXT:[jmp(L11 [skipFinallyToErrorBlock])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v8>)]
|
||||
L10:
|
||||
4 jmp(L11 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L6 [onExceptionToFinallyBlock]:
|
||||
7 mark({ 2 }) PREV:[jmp?(L6 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v9>
|
||||
4 jmp(error) NEXT:[<ERROR>]
|
||||
L11 [skipFinallyToErrorBlock]:
|
||||
7 mark({ 2 }) PREV:[jmp(L11 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[w(i), read (Unit)]
|
||||
r(2) -> <v9>
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>, read (Unit)]
|
||||
L2:
|
||||
read (Unit) PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
L1:
|
||||
@@ -506,7 +508,8 @@ fun t9(a : Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Int)
|
||||
w(a)
|
||||
magic(a : Int) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 } })
|
||||
mark(try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 } finally { 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } 5 })]
|
||||
@@ -514,43 +517,44 @@ L0:
|
||||
mark(@l for (i in 1..a) { 1 if (2 > 3) { continue @l } })
|
||||
4 mark(for (i in 1..a) { 1 if (2 > 3) { continue @l } })
|
||||
mark(1..a)
|
||||
r(1)
|
||||
r(a)
|
||||
call(.., rangeTo)
|
||||
r(1) -> <v1>
|
||||
r(a) -> <v2>
|
||||
call(.., rangeTo|<v1>, <v2>) -> <v3>
|
||||
v(i)
|
||||
L4:
|
||||
jmp?(L3) NEXT:[read (Unit), w(i)]
|
||||
jmp?(L3) NEXT:[read (Unit), magic(1..a|<v3>) -> <v4>]
|
||||
L5 [loop entry point]:
|
||||
L6 [body entry point]:
|
||||
w(i) PREV:[jmp?(L3), jmp(L5 [loop entry point]), jmp?(L5 [loop entry point])]
|
||||
magic(1..a|<v3>) -> <v4> PREV:[jmp?(L3), jmp(L5 [loop entry point]), jmp?(L5 [loop entry point])]
|
||||
w(i|<v4>)
|
||||
5 mark({ 1 if (2 > 3) { continue @l } })
|
||||
r(1)
|
||||
r(1) -> <v5>
|
||||
mark(if (2 > 3) { continue @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ continue @l })]
|
||||
r(2) -> <v6>
|
||||
r(3) -> <v7>
|
||||
call(>, compareTo|<v6>, <v7>) -> <v8>
|
||||
jf(L7|<v8>) NEXT:[read (Unit), mark({ continue @l })]
|
||||
6 mark({ continue @l })
|
||||
jmp(L5 [loop entry point]) NEXT:[w(i)]
|
||||
jmp(L5 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>]
|
||||
- 5 jmp(L8) NEXT:[jmp?(L5 [loop entry point])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v8>)]
|
||||
L8:
|
||||
4 jmp?(L5 [loop entry point]) NEXT:[w(i), read (Unit)]
|
||||
4 jmp?(L5 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>, read (Unit)]
|
||||
L3:
|
||||
read (Unit) PREV:[jmp?(L3), jmp?(L5 [loop entry point])]
|
||||
3 r(5)
|
||||
3 r(5) -> <v9>
|
||||
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L10 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v10>
|
||||
L11 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L9 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v10>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -575,7 +579,8 @@ fun t10(a : Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Int)
|
||||
w(a)
|
||||
magic(a : Int) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } } finally { 2 } })
|
||||
mark(try { @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } } finally { 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ 2 }), mark({ @l for (i in 1..a) { 1 if (2 > 3) { continue @l } } })]
|
||||
@@ -583,42 +588,43 @@ L0:
|
||||
mark(@l for (i in 1..a) { 1 if (2 > 3) { continue @l } })
|
||||
4 mark(for (i in 1..a) { 1 if (2 > 3) { continue @l } })
|
||||
mark(1..a)
|
||||
r(1)
|
||||
r(a)
|
||||
call(.., rangeTo)
|
||||
r(1) -> <v1>
|
||||
r(a) -> <v2>
|
||||
call(.., rangeTo|<v1>, <v2>) -> <v3>
|
||||
v(i)
|
||||
L4:
|
||||
jmp?(L3) NEXT:[read (Unit), w(i)]
|
||||
jmp?(L3) NEXT:[read (Unit), magic(1..a|<v3>) -> <v4>]
|
||||
L5 [loop entry point]:
|
||||
L6 [body entry point]:
|
||||
w(i) PREV:[jmp?(L3), jmp(L5 [loop entry point]), jmp?(L5 [loop entry point])]
|
||||
magic(1..a|<v3>) -> <v4> PREV:[jmp?(L3), jmp(L5 [loop entry point]), jmp?(L5 [loop entry point])]
|
||||
w(i|<v4>)
|
||||
5 mark({ 1 if (2 > 3) { continue @l } })
|
||||
r(1)
|
||||
r(1) -> <v5>
|
||||
mark(if (2 > 3) { continue @l })
|
||||
mark(2 > 3)
|
||||
r(2)
|
||||
r(3)
|
||||
call(>, compareTo)
|
||||
jf(L7) NEXT:[read (Unit), mark({ continue @l })]
|
||||
r(2) -> <v6>
|
||||
r(3) -> <v7>
|
||||
call(>, compareTo|<v6>, <v7>) -> <v8>
|
||||
jf(L7|<v8>) NEXT:[read (Unit), mark({ continue @l })]
|
||||
6 mark({ continue @l })
|
||||
jmp(L5 [loop entry point]) NEXT:[w(i)]
|
||||
jmp(L5 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>]
|
||||
- 5 jmp(L8) NEXT:[jmp?(L5 [loop entry point])] PREV:[]
|
||||
L7:
|
||||
read (Unit) PREV:[jf(L7)]
|
||||
read (Unit) PREV:[jf(L7|<v8>)]
|
||||
L8:
|
||||
4 jmp?(L5 [loop entry point]) NEXT:[w(i), read (Unit)]
|
||||
4 jmp?(L5 [loop entry point]) NEXT:[magic(1..a|<v3>) -> <v4>, read (Unit)]
|
||||
L3:
|
||||
read (Unit) PREV:[jmp?(L3), jmp?(L5 [loop entry point])]
|
||||
2 jmp(L9 [skipFinallyToErrorBlock]) NEXT:[mark({ 2 })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L10 [start finally]:
|
||||
3 mark({ 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
r(2) -> <v9>
|
||||
L11 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L9 [skipFinallyToErrorBlock]:
|
||||
3 mark({ 2 }) PREV:[jmp(L9 [skipFinallyToErrorBlock])]
|
||||
r(2)
|
||||
r(2) -> <v9>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -642,25 +648,25 @@ L0:
|
||||
mark(try { return 1 } finally { return 2 })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ return 2 }), mark({ return 1 })]
|
||||
3 mark({ return 1 })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
L3 [start finally]:
|
||||
4 mark({ return 2 })
|
||||
r(2)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(2) -> <v1>
|
||||
ret(*|<v1>) L1 NEXT:[<END>]
|
||||
L4 [finish finally]:
|
||||
- 3 ret(*) L1 NEXT:[<END>] PREV:[]
|
||||
- 3 ret(*|<v0>) L1 NEXT:[<END>] PREV:[]
|
||||
- 2 jmp(L5 [skipFinallyToErrorBlock]) NEXT:[mark({ return 2 })] PREV:[]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
4 mark({ return 2 }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
r(2)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(2) -> <v1>
|
||||
ret(*|<v1>) L1 NEXT:[<END>]
|
||||
- 2 jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||
L5 [skipFinallyToErrorBlock]:
|
||||
- 4 mark({ return 2 }) PREV:[]
|
||||
- r(2) PREV:[]
|
||||
- ret(*) L1 PREV:[]
|
||||
- r(2) -> <v1> PREV:[]
|
||||
- ret(*|<v1>) L1 PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v1>) L1, ret(*|<v1>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
@@ -682,28 +688,28 @@ L0:
|
||||
mark(try { return 1 } finally { doSmth(3) })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ return 1 })]
|
||||
3 mark({ return 1 })
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
L3 [start finally]:
|
||||
4 mark({ doSmth(3) })
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
L4 [finish finally]:
|
||||
3 ret(*) L1 NEXT:[<END>]
|
||||
3 ret(*|<v0>) L1 NEXT:[<END>]
|
||||
- 2 jmp(L5 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
4 mark({ doSmth(3) }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L5 [skipFinallyToErrorBlock]:
|
||||
- 4 mark({ doSmth(3) }) PREV:[]
|
||||
- mark(doSmth(3)) PREV:[]
|
||||
- r(3) PREV:[]
|
||||
- call(doSmth, doSmth) PREV:[]
|
||||
- r(3) -> <v1> PREV:[]
|
||||
- call(doSmth, doSmth|<v1>) -> <v2> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -729,38 +735,39 @@ L0:
|
||||
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)
|
||||
r(1) -> <v0>
|
||||
L4 [start finally]:
|
||||
4 mark({ doSmth(3) })
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
L5 [finish finally]:
|
||||
3 ret(*) L1 NEXT:[<END>]
|
||||
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])]
|
||||
w(e)
|
||||
magic(e: UnsupportedOperationException) -> <v3>
|
||||
w(e|<v3>)
|
||||
4 mark({ doSmth(2) })
|
||||
mark(doSmth(2))
|
||||
r(2)
|
||||
call(doSmth, doSmth)
|
||||
r(2) -> <v4>
|
||||
call(doSmth, doSmth|<v4>) -> <v5>
|
||||
3 jmp(L6 [afterCatches])
|
||||
L6 [afterCatches]:
|
||||
2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })]
|
||||
L3 [onExceptionToFinallyBlock]:
|
||||
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L7 [skipFinallyToErrorBlock]:
|
||||
4 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, call(doSmth, doSmth)]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, call(doSmth, doSmth|<v1>) -> <v2>]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -782,20 +789,21 @@ L0:
|
||||
mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) })
|
||||
jmp?(L2 [onException]) NEXT:[v(e: UnsupportedOperationException), mark({ return 1 })]
|
||||
3 mark({ return 1 })
|
||||
r(1)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(1) -> <v0>
|
||||
ret(*|<v0>) L1 NEXT:[<END>]
|
||||
- 2 jmp(L3 [afterCatches]) NEXT:[<END>] PREV:[]
|
||||
L2 [onException]:
|
||||
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
|
||||
w(e)
|
||||
magic(e: UnsupportedOperationException) -> <v1>
|
||||
w(e|<v1>)
|
||||
4 mark({ doSmth(2) })
|
||||
mark(doSmth(2))
|
||||
r(2)
|
||||
call(doSmth, doSmth)
|
||||
r(2) -> <v2>
|
||||
call(doSmth, doSmth|<v2>) -> <v3>
|
||||
3 jmp(L3 [afterCatches])
|
||||
L1:
|
||||
L3 [afterCatches]:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, jmp(L3 [afterCatches])]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, jmp(L3 [afterCatches])]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
@@ -821,41 +829,42 @@ L0:
|
||||
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)
|
||||
r(1) -> <v0>
|
||||
L4 [start finally]:
|
||||
4 mark({ doSmth(3) })
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
L5 [finish finally]:
|
||||
3 ret(*) L1 NEXT:[<END>]
|
||||
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])]
|
||||
w(e)
|
||||
magic(e: UnsupportedOperationException) -> <v3>
|
||||
w(e|<v3>)
|
||||
4 mark({ return 2 })
|
||||
r(2)
|
||||
r(2) -> <v4>
|
||||
mark({ doSmth(3) })
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
ret(*|<v4>) L1 NEXT:[<END>]
|
||||
- 3 jmp(L6 [afterCatches]) PREV:[]
|
||||
L6 [afterCatches]:
|
||||
- 2 jmp(L7 [skipFinallyToErrorBlock]) NEXT:[mark({ doSmth(3) })] PREV:[]
|
||||
L3 [onExceptionToFinallyBlock]:
|
||||
4 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v1>
|
||||
call(doSmth, doSmth|<v1>) -> <v2>
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L7 [skipFinallyToErrorBlock]:
|
||||
- 4 mark({ doSmth(3) }) PREV:[]
|
||||
- mark(doSmth(3)) PREV:[]
|
||||
- r(3) PREV:[]
|
||||
- call(doSmth, doSmth) PREV:[]
|
||||
- r(3) -> <v1> PREV:[]
|
||||
- call(doSmth, doSmth|<v1>) -> <v2> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v4>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -882,37 +891,38 @@ L0:
|
||||
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ doSmth(3) }), mark({ doSmth(1) })]
|
||||
3 mark({ doSmth(1) })
|
||||
mark(doSmth(1))
|
||||
r(1)
|
||||
call(doSmth, doSmth)
|
||||
r(1) -> <v0>
|
||||
call(doSmth, doSmth|<v0>) -> <v1>
|
||||
2 jmp(L4 [afterCatches]) NEXT:[jmp(L7 [skipFinallyToErrorBlock])]
|
||||
L2 [onException]:
|
||||
3 v(e: UnsupportedOperationException) PREV:[jmp?(L2 [onException])]
|
||||
w(e)
|
||||
magic(e: UnsupportedOperationException) -> <v2>
|
||||
w(e|<v2>)
|
||||
4 mark({ return 2 })
|
||||
r(2)
|
||||
r(2) -> <v3>
|
||||
L5 [start finally]:
|
||||
5 mark({ doSmth(3) })
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v4>
|
||||
call(doSmth, doSmth|<v4>) -> <v5>
|
||||
L6 [finish finally]:
|
||||
4 ret(*) L1 NEXT:[<END>]
|
||||
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])]
|
||||
L3 [onExceptionToFinallyBlock]:
|
||||
5 mark({ doSmth(3) }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v4>
|
||||
call(doSmth, doSmth|<v4>) -> <v5>
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L7 [skipFinallyToErrorBlock]:
|
||||
5 mark({ doSmth(3) }) PREV:[jmp(L7 [skipFinallyToErrorBlock])]
|
||||
mark(doSmth(3))
|
||||
r(3)
|
||||
call(doSmth, doSmth)
|
||||
r(3) -> <v4>
|
||||
call(doSmth, doSmth|<v4>) -> <v5>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, call(doSmth, doSmth)]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v3>) L1, call(doSmth, doSmth|<v4>) -> <v5>]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
@@ -925,13 +935,14 @@ fun doSmth(i: Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(i: Int)
|
||||
w(i)
|
||||
magic(i: Int) -> <v0>
|
||||
w(i|<v0>)
|
||||
2 mark({ })
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -74,46 +74,49 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } })
|
||||
mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 })
|
||||
jmp?(L2 [onException]) NEXT:[jmp?(L5 [catch 0]), jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ return 1 }), mark({ doSmth() })]
|
||||
jmp?(L2 [onException]) NEXT:[jmp?(L5 [catch 0]), jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ return 1 }), mark({ doSmth() })]
|
||||
3 mark({ doSmth() })
|
||||
mark(doSmth())
|
||||
call(doSmth, doSmth)
|
||||
2 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
call(doSmth, doSmth) -> <v0>
|
||||
2 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
L2 [onException]:
|
||||
jmp?(L5 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2 [onException])]
|
||||
jmp?(L5 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2 [onException])]
|
||||
3 v(e: NullPointerException)
|
||||
w(e)
|
||||
magic(e: NullPointerException) -> <v1>
|
||||
w(e|<v1>)
|
||||
4 mark({ doSmth1() })
|
||||
mark(doSmth1())
|
||||
call(doSmth1, doSmth1)
|
||||
3 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
call(doSmth1, doSmth1) -> <v2>
|
||||
3 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
L5 [catch 0]:
|
||||
v(e: Exception) PREV:[jmp?(L5 [catch 0])]
|
||||
w(e)
|
||||
v(e: Exception) PREV:[jmp?(L5 [catch 0])]
|
||||
magic(e: Exception) -> <v3>
|
||||
w(e|<v3>)
|
||||
4 mark({ doSmth2() })
|
||||
mark(doSmth2())
|
||||
call(doSmth2, doSmth2)
|
||||
call(doSmth2, doSmth2) -> <v4>
|
||||
3 jmp(L4 [afterCatches])
|
||||
L4 [afterCatches]:
|
||||
2 jmp(L6 [skipFinallyToErrorBlock]) NEXT:[mark({ return 1 })] PREV:[jmp(L4 [afterCatches]), jmp(L4 [afterCatches]), jmp(L4 [afterCatches])]
|
||||
2 jmp(L6 [skipFinallyToErrorBlock]) NEXT:[mark({ return 1 })] PREV:[jmp(L4 [afterCatches]), jmp(L4 [afterCatches]), jmp(L4 [afterCatches])]
|
||||
L3 [onExceptionToFinallyBlock]:
|
||||
L7 [start finally]:
|
||||
3 mark({ return 1 }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
r(1)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
3 mark({ return 1 }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
r(1) -> <v5>
|
||||
ret(*|<v5>) L1 NEXT:[<END>]
|
||||
L8 [finish finally]:
|
||||
- 2 jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||
- 2 jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||
L6 [skipFinallyToErrorBlock]:
|
||||
3 mark({ return 1 }) PREV:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
r(1)
|
||||
ret(*) L1
|
||||
3 mark({ return 1 }) PREV:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
r(1) -> <v5>
|
||||
ret(*|<v5>) L1 NEXT:[<END>]
|
||||
- 2 magic(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|<v0>, <v2>, <v4>) -> <v6> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v5>) L1, ret(*|<v5>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== testCopy2 ==
|
||||
fun testCopy2() {
|
||||
@@ -140,67 +143,70 @@ L0:
|
||||
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])]
|
||||
call(cond, cond)
|
||||
jf(L3 [loop exit point]) NEXT:[read (Unit), mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } })]
|
||||
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>
|
||||
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)
|
||||
3 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
|
||||
call(doSmth, doSmth) -> <v1>
|
||||
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)
|
||||
w(e)
|
||||
magic(e: NullPointerException) -> <v2>
|
||||
w(e|<v2>)
|
||||
5 mark({ doSmth1() })
|
||||
mark(doSmth1())
|
||||
call(doSmth1, doSmth1)
|
||||
4 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
|
||||
call(doSmth1, doSmth1) -> <v3>
|
||||
4 jmp(L8 [afterCatches]) NEXT:[jmp(L10 [skipFinallyToErrorBlock])]
|
||||
L9 [catch 0]:
|
||||
v(e: Exception) PREV:[jmp?(L9 [catch 0])]
|
||||
w(e)
|
||||
v(e: Exception) PREV:[jmp?(L9 [catch 0])]
|
||||
magic(e: Exception) -> <v4>
|
||||
w(e|<v4>)
|
||||
5 mark({ doSmth2() })
|
||||
mark(doSmth2())
|
||||
call(doSmth2, doSmth2)
|
||||
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)
|
||||
jf(L12) NEXT:[jmp(L2 [loop entry point]), ret L1]
|
||||
ret L1 NEXT:[<END>]
|
||||
- jmp(L13) NEXT:[jmp(error)] PREV:[]
|
||||
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:[]
|
||||
L12:
|
||||
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(L12)]
|
||||
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(L12|<v6>)]
|
||||
L13:
|
||||
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)
|
||||
jf(copy L12) NEXT:[jmp(L2 [loop entry point]), ret L1]
|
||||
ret L1 NEXT:[<END>]
|
||||
- jmp(copy L13) NEXT:[jmp(L2 [loop entry point])] PREV:[]
|
||||
jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[jf(copy L12)]
|
||||
- 2 jmp(L2 [loop entry point]) NEXT:[mark(cond())] PREV:[]
|
||||
call(cond, cond) -> <v6>
|
||||
jf(copy L12|<v6>) NEXT:[jmp(L2 [loop entry point]), ret L1]
|
||||
ret L1 NEXT:[<END>]
|
||||
- jmp(copy L13) NEXT:[magic(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 magic(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:[]
|
||||
L3 [loop exit point]:
|
||||
read (Unit) PREV:[jf(L3 [loop exit point])]
|
||||
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() {
|
||||
@@ -222,58 +228,61 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } })
|
||||
mark(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); })
|
||||
jmp?(L2 [onException]) NEXT:[jmp?(L5 [catch 0]), jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ while (cond()); }), mark({ doSmth() })]
|
||||
jmp?(L2 [onException]) NEXT:[jmp?(L5 [catch 0]), jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
jmp?(L3 [onExceptionToFinallyBlock]) NEXT:[mark({ while (cond()); }), mark({ doSmth() })]
|
||||
3 mark({ doSmth() })
|
||||
mark(doSmth())
|
||||
call(doSmth, doSmth)
|
||||
2 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
call(doSmth, doSmth) -> <v0>
|
||||
2 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
L2 [onException]:
|
||||
jmp?(L5 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2 [onException])]
|
||||
jmp?(L5 [catch 0]) NEXT:[v(e: Exception), v(e: NullPointerException)] PREV:[jmp?(L2 [onException])]
|
||||
3 v(e: NullPointerException)
|
||||
w(e)
|
||||
magic(e: NullPointerException) -> <v1>
|
||||
w(e|<v1>)
|
||||
4 mark({ doSmth1() })
|
||||
mark(doSmth1())
|
||||
call(doSmth1, doSmth1)
|
||||
3 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
call(doSmth1, doSmth1) -> <v2>
|
||||
3 jmp(L4 [afterCatches]) NEXT:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
L5 [catch 0]:
|
||||
v(e: Exception) PREV:[jmp?(L5 [catch 0])]
|
||||
w(e)
|
||||
v(e: Exception) PREV:[jmp?(L5 [catch 0])]
|
||||
magic(e: Exception) -> <v3>
|
||||
w(e|<v3>)
|
||||
4 mark({ doSmth2() })
|
||||
mark(doSmth2())
|
||||
call(doSmth2, doSmth2)
|
||||
call(doSmth2, doSmth2) -> <v4>
|
||||
3 jmp(L4 [afterCatches])
|
||||
L4 [afterCatches]:
|
||||
2 jmp(L6 [skipFinallyToErrorBlock]) NEXT:[mark({ while (cond()); })] PREV:[jmp(L4 [afterCatches]), jmp(L4 [afterCatches]), jmp(L4 [afterCatches])]
|
||||
2 jmp(L6 [skipFinallyToErrorBlock]) NEXT:[mark({ while (cond()); })] PREV:[jmp(L4 [afterCatches]), jmp(L4 [afterCatches]), jmp(L4 [afterCatches])]
|
||||
L3 [onExceptionToFinallyBlock]:
|
||||
L7 [start finally]:
|
||||
3 mark({ while (cond()); }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
3 mark({ while (cond()); }) PREV:[jmp?(L3 [onExceptionToFinallyBlock])]
|
||||
mark(while (cond()))
|
||||
L8 [loop entry point]:
|
||||
L11 [condition entry point]:
|
||||
mark(cond()) PREV:[mark(while (cond())), jmp(L8 [loop entry point])]
|
||||
call(cond, cond)
|
||||
jf(L9 [loop exit point]) NEXT:[read (Unit), jmp(L8 [loop entry point])]
|
||||
mark(cond()) PREV:[mark(while (cond())), jmp(L8 [loop entry point])]
|
||||
call(cond, cond) -> <v5>
|
||||
jf(L9 [loop exit point]|<v5>) NEXT:[read (Unit), jmp(L8 [loop entry point])]
|
||||
L10 [body entry point]:
|
||||
jmp(L8 [loop entry point]) NEXT:[mark(cond())]
|
||||
jmp(L8 [loop entry point]) NEXT:[mark(cond())]
|
||||
L9 [loop exit point]:
|
||||
read (Unit) PREV:[jf(L9 [loop exit point])]
|
||||
read (Unit) PREV:[jf(L9 [loop exit point]|<v5>)]
|
||||
L12 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L6 [skipFinallyToErrorBlock]:
|
||||
3 mark({ while (cond()); }) PREV:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
3 mark({ while (cond()); }) PREV:[jmp(L6 [skipFinallyToErrorBlock])]
|
||||
mark(while (cond()))
|
||||
mark(cond()) PREV:[mark(while (cond())), jmp(copy L8 [loop entry point])]
|
||||
call(cond, cond)
|
||||
jf(copy L9 [loop exit point]) 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])]
|
||||
mark(cond()) PREV:[mark(while (cond())), jmp(copy L8 [loop entry point])]
|
||||
call(cond, cond) -> <v5>
|
||||
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 magic(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|<v0>, <v2>, <v4>) -> <v6>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== doTestCopy4 ==
|
||||
fun doTestCopy4(list: List<String>?) : Int {
|
||||
@@ -289,28 +298,29 @@ fun doTestCopy4(list: List<String>?) : Int {
|
||||
L0:
|
||||
1 <START>
|
||||
v(list: List<String>?)
|
||||
w(list)
|
||||
magic(list: List<String>?) -> <v0>
|
||||
w(list|<v0>)
|
||||
2 mark({ try { doSmth() } finally { if(list != null) { } } })
|
||||
mark(try { doSmth() } finally { if(list != null) { } })
|
||||
jmp?(L2 [onExceptionToFinallyBlock]) NEXT:[mark({ if(list != null) { } }), mark({ doSmth() })]
|
||||
3 mark({ doSmth() })
|
||||
mark(doSmth())
|
||||
call(doSmth, doSmth)
|
||||
call(doSmth, doSmth) -> <v1>
|
||||
2 jmp(L3 [skipFinallyToErrorBlock]) NEXT:[mark({ if(list != null) { } })]
|
||||
L2 [onExceptionToFinallyBlock]:
|
||||
L4 [start finally]:
|
||||
3 mark({ if(list != null) { } }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
mark(if(list != null) { })
|
||||
mark(list != null)
|
||||
r(list)
|
||||
r(null)
|
||||
call(!=, equals)
|
||||
jf(L5) NEXT:[read (Unit), mark({ })]
|
||||
r(list) -> <v2>
|
||||
r(null) -> <v3>
|
||||
call(!=, equals|<v2>, <v3>) -> <v4>
|
||||
jf(L5|<v4>) NEXT:[read (Unit), mark({ })]
|
||||
4 mark({ })
|
||||
read (Unit)
|
||||
3 jmp(L6) NEXT:[jmp(error)]
|
||||
L5:
|
||||
read (Unit) PREV:[jf(L5)]
|
||||
read (Unit) PREV:[jf(L5|<v4>)]
|
||||
L6:
|
||||
L7 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>] PREV:[jmp(L6), read (Unit)]
|
||||
@@ -318,14 +328,14 @@ L3 [skipFinallyToErrorBlock]:
|
||||
3 mark({ if(list != null) { } }) PREV:[jmp(L3 [skipFinallyToErrorBlock])]
|
||||
mark(if(list != null) { })
|
||||
mark(list != null)
|
||||
r(list)
|
||||
r(null)
|
||||
call(!=, equals)
|
||||
jf(copy L5) NEXT:[read (Unit), mark({ })]
|
||||
r(list) -> <v2>
|
||||
r(null) -> <v3>
|
||||
call(!=, equals|<v2>, <v3>) -> <v4>
|
||||
jf(copy L5|<v4>) NEXT:[read (Unit), mark({ })]
|
||||
4 mark({ })
|
||||
read (Unit)
|
||||
3 jmp(copy L6) NEXT:[<END>]
|
||||
read (Unit) PREV:[jf(copy L5)]
|
||||
read (Unit) PREV:[jf(copy L5|<v4>)]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp(copy L6), read (Unit)]
|
||||
error:
|
||||
|
||||
@@ -10,20 +10,21 @@ L0:
|
||||
2 mark({ for (i in 1..2) { doSmth(i) } })
|
||||
3 mark(for (i in 1..2) { doSmth(i) })
|
||||
mark(1..2)
|
||||
r(1)
|
||||
r(2)
|
||||
call(.., rangeTo)
|
||||
r(1) -> <v0>
|
||||
r(2) -> <v1>
|
||||
call(.., rangeTo|<v0>, <v1>) -> <v2>
|
||||
v(i)
|
||||
L3:
|
||||
jmp?(L2) NEXT:[read (Unit), w(i)]
|
||||
jmp?(L2) NEXT:[read (Unit), magic(1..2|<v2>) -> <v3>]
|
||||
L4 [loop entry point]:
|
||||
L5 [body entry point]:
|
||||
w(i) PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
magic(1..2|<v2>) -> <v3> PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
w(i|<v3>)
|
||||
4 mark({ doSmth(i) })
|
||||
mark(doSmth(i))
|
||||
r(i)
|
||||
call(doSmth, doSmth)
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[w(i), read (Unit)]
|
||||
r(i) -> <v4>
|
||||
call(doSmth, doSmth|<v4>) -> <v5>
|
||||
3 jmp?(L4 [loop entry point]) NEXT:[magic(1..2|<v2>) -> <v3>, read (Unit)]
|
||||
L2:
|
||||
read (Unit) PREV:[jmp?(L2), jmp?(L4 [loop entry point])]
|
||||
L1:
|
||||
@@ -39,13 +40,14 @@ fun doSmth(i: Int) {}
|
||||
L0:
|
||||
1 <START>
|
||||
v(i: Int)
|
||||
w(i)
|
||||
magic(i: Int) -> <v0>
|
||||
w(i|<v0>)
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -19,41 +19,42 @@ fun t1(b: Boolean) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(b: Boolean)
|
||||
w(b)
|
||||
magic(b: Boolean) -> <v0>
|
||||
w(b|<v0>)
|
||||
2 mark({ var u: String if (b) { u = "s" } doSmth(u) var r: String if (b) { r = "s" } else { r = "t" } doSmth(r) })
|
||||
v(var u: String)
|
||||
mark(if (b) { u = "s" })
|
||||
r(b)
|
||||
jf(L2) NEXT:[read (Unit), mark({ u = "s" })]
|
||||
r(b) -> <v1>
|
||||
jf(L2|<v1>) NEXT:[read (Unit), mark({ u = "s" })]
|
||||
3 mark({ u = "s" })
|
||||
mark("s")
|
||||
r("s")
|
||||
w(u)
|
||||
r("s") -> <v2>
|
||||
w(u|<v2>)
|
||||
2 jmp(L3) NEXT:[mark(doSmth(u))]
|
||||
L2:
|
||||
read (Unit) PREV:[jf(L2)]
|
||||
read (Unit) PREV:[jf(L2|<v1>)]
|
||||
L3:
|
||||
mark(doSmth(u)) PREV:[jmp(L3), read (Unit)]
|
||||
r(u)
|
||||
call(doSmth, doSmth)
|
||||
r(u) -> <v3>
|
||||
call(doSmth, doSmth|<v3>) -> <v4>
|
||||
v(var r: String)
|
||||
mark(if (b) { r = "s" } else { r = "t" })
|
||||
r(b)
|
||||
jf(L4) NEXT:[mark({ r = "t" }), mark({ r = "s" })]
|
||||
r(b) -> <v5>
|
||||
jf(L4|<v5>) NEXT:[mark({ r = "t" }), mark({ r = "s" })]
|
||||
3 mark({ r = "s" })
|
||||
mark("s")
|
||||
r("s")
|
||||
w(r)
|
||||
r("s") -> <v6>
|
||||
w(r|<v6>)
|
||||
2 jmp(L5) NEXT:[mark(doSmth(r))]
|
||||
L4:
|
||||
3 mark({ r = "t" }) PREV:[jf(L4)]
|
||||
3 mark({ r = "t" }) PREV:[jf(L4|<v5>)]
|
||||
mark("t")
|
||||
r("t")
|
||||
w(r)
|
||||
r("t") -> <v7>
|
||||
w(r|<v7>)
|
||||
L5:
|
||||
2 mark(doSmth(r)) PREV:[jmp(L5), w(r)]
|
||||
r(r)
|
||||
call(doSmth, doSmth)
|
||||
2 mark(doSmth(r)) PREV:[jmp(L5), w(r|<v7>)]
|
||||
r(r) -> <v8>
|
||||
call(doSmth, doSmth|<v8>) -> <v9>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -76,32 +77,34 @@ fun t2(b: Boolean) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(b: Boolean)
|
||||
w(b)
|
||||
magic(b: Boolean) -> <v0>
|
||||
w(b|<v0>)
|
||||
2 mark({ val i = 3 if (b) { return; } doSmth(i) if (i is Int) { return; } })
|
||||
v(val i = 3)
|
||||
r(3)
|
||||
w(i)
|
||||
r(3) -> <v1>
|
||||
w(i|<v1>)
|
||||
mark(if (b) { return; })
|
||||
r(b)
|
||||
jf(L2) NEXT:[read (Unit), mark({ return; })]
|
||||
r(b) -> <v2>
|
||||
jf(L2|<v2>) NEXT:[read (Unit), mark({ return; })]
|
||||
3 mark({ return; })
|
||||
ret L1 NEXT:[<END>]
|
||||
- 2 jmp(L3) NEXT:[mark(doSmth(i))] PREV:[]
|
||||
L2:
|
||||
read (Unit) PREV:[jf(L2)]
|
||||
read (Unit) PREV:[jf(L2|<v2>)]
|
||||
L3:
|
||||
mark(doSmth(i))
|
||||
r(i)
|
||||
call(doSmth, doSmth)
|
||||
r(i) -> <v3>
|
||||
call(doSmth, doSmth|<v3>) -> <v4>
|
||||
mark(if (i is Int) { return; })
|
||||
mark(i is Int)
|
||||
r(i)
|
||||
jf(L4) NEXT:[read (Unit), mark({ return; })]
|
||||
r(i) -> <v5>
|
||||
magic(i is Int|<v5>) -> <v6>
|
||||
jf(L4|<v6>) NEXT:[read (Unit), mark({ return; })]
|
||||
3 mark({ return; })
|
||||
ret L1 NEXT:[<END>]
|
||||
- 2 jmp(L5) NEXT:[<END>] PREV:[]
|
||||
L4:
|
||||
read (Unit) PREV:[jf(L4)]
|
||||
read (Unit) PREV:[jf(L4|<v6>)]
|
||||
L1:
|
||||
L5:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1, ret L1, read (Unit)]
|
||||
@@ -116,13 +119,14 @@ fun doSmth(s: String) {}
|
||||
L0:
|
||||
1 <START>
|
||||
v(s: String)
|
||||
w(s)
|
||||
magic(s: String) -> <v0>
|
||||
w(s|<v0>)
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -11,23 +11,23 @@ L0:
|
||||
mark(while(0 > 1) { 2 })
|
||||
L2 [loop entry point]:
|
||||
L5 [condition entry point]:
|
||||
mark(0 > 1) PREV:[mark(while(0 > 1) { 2 }), jmp(L2 [loop entry point])]
|
||||
r(0)
|
||||
r(1)
|
||||
call(>, compareTo)
|
||||
jf(L3 [loop exit point]) NEXT:[read (Unit), mark({ 2 })]
|
||||
mark(0 > 1) PREV:[mark(while(0 > 1) { 2 }), jmp(L2 [loop entry point])]
|
||||
r(0) -> <v0>
|
||||
r(1) -> <v1>
|
||||
call(>, compareTo|<v0>, <v1>) -> <v2>
|
||||
jf(L3 [loop exit point]|<v2>) NEXT:[read (Unit), mark({ 2 })]
|
||||
L4 [body entry point]:
|
||||
3 mark({ 2 })
|
||||
r(2)
|
||||
2 jmp(L2 [loop entry point]) NEXT:[mark(0 > 1)]
|
||||
r(2) -> <v3>
|
||||
2 jmp(L2 [loop entry point]) NEXT:[mark(0 > 1)]
|
||||
L3 [loop exit point]:
|
||||
read (Unit) PREV:[jf(L3 [loop exit point])]
|
||||
read (Unit) PREV:[jf(L3 [loop exit point]|<v2>)]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== dowhile ==
|
||||
fun dowhile() {
|
||||
@@ -42,19 +42,19 @@ L0:
|
||||
L2 [loop entry point]:
|
||||
L4 [body entry point]:
|
||||
mark({return})
|
||||
ret L1 NEXT:[<END>]
|
||||
ret L1 NEXT:[<END>]
|
||||
L5 [condition entry point]:
|
||||
- mark(0 > 1) PREV:[]
|
||||
- r(0) PREV:[]
|
||||
- r(1) PREV:[]
|
||||
- call(>, compareTo) PREV:[]
|
||||
- jt(L2 [loop entry point]) NEXT:[read (Unit), mark({return})] PREV:[]
|
||||
- mark(0 > 1) PREV:[]
|
||||
- r(0) -> <v0> PREV:[]
|
||||
- r(1) -> <v1> PREV:[]
|
||||
- call(>, compareTo|<v0>, <v1>) -> <v2> PREV:[]
|
||||
- jt(L2 [loop entry point]|<v2>) NEXT:[read (Unit), mark({return})] PREV:[]
|
||||
L3 [loop exit point]:
|
||||
- read (Unit) PREV:[]
|
||||
- read (Unit) PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -8,20 +8,22 @@ fun illegalWhenBlock(a: Any): Any {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Any)
|
||||
w(a)
|
||||
magic(a: Any) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ when(a) { is Int -> return a } })
|
||||
mark(when(a) { is Int -> return a })
|
||||
r(a)
|
||||
r(a) -> <v1>
|
||||
mark(is Int -> return a)
|
||||
jmp?(L4) NEXT:[<END>, r(a)]
|
||||
magic(is Int|<v1>) -> <v2>
|
||||
jmp?(L4|<v2>) NEXT:[<END>, r(a) -> <v3>]
|
||||
L3:
|
||||
r(a)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(a) -> <v3>
|
||||
ret(*|<v3>) L1 NEXT:[<END>]
|
||||
- jmp(L2) PREV:[]
|
||||
L1:
|
||||
L2:
|
||||
L4:
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp?(L4), ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp?(L4|<v2>), ret(*|<v3>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
|
||||
@@ -7,26 +7,28 @@ fun foo(a: Int, b: Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Int)
|
||||
w(a)
|
||||
magic(a: Int) -> <v0>
|
||||
w(a|<v0>)
|
||||
v(b: Int)
|
||||
w(b)
|
||||
magic(b: Int) -> <v1>
|
||||
w(b|<v1>)
|
||||
2 mark({ if (a == b) { } })
|
||||
mark(if (a == b) { })
|
||||
mark(a == b)
|
||||
r(a)
|
||||
r(b)
|
||||
call(==, equals)
|
||||
jf(L2) NEXT:[read (Unit), mark({ })]
|
||||
r(a) -> <v2>
|
||||
r(b) -> <v3>
|
||||
call(==, equals|<v2>, <v3>) -> <v4>
|
||||
jf(L2|<v4>) NEXT:[read (Unit), mark({ })]
|
||||
3 mark({ })
|
||||
read (Unit)
|
||||
2 jmp(L3) NEXT:[<END>]
|
||||
2 jmp(L3) NEXT:[<END>]
|
||||
L2:
|
||||
read (Unit) PREV:[jf(L2)]
|
||||
read (Unit) PREV:[jf(L2|<v4>)]
|
||||
L1:
|
||||
L3:
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp(L3), read (Unit)]
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp(L3), read (Unit)]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -8,16 +8,16 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ var i = 1 i++ })
|
||||
v(var i = 1)
|
||||
r(1)
|
||||
w(i)
|
||||
r(1) -> <v0>
|
||||
w(i|<v0>)
|
||||
mark(i++)
|
||||
r(i)
|
||||
call(++, inc)
|
||||
w(i)
|
||||
r(i) -> <v1>
|
||||
call(++, inc|<v1>) -> <v2>
|
||||
w(i|<v2>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -6,15 +6,16 @@ fun foo(f: () -> Unit) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(f: () -> Unit)
|
||||
w(f)
|
||||
magic(f: () -> Unit) -> <v0>
|
||||
w(f|<v0>)
|
||||
2 mark({ f() })
|
||||
mark(f())
|
||||
r(f)
|
||||
call(f, invoke)
|
||||
r(f) -> <v1>
|
||||
call(f, invoke|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -6,26 +6,28 @@ fun neq(a: Int, b: Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Int)
|
||||
w(a)
|
||||
magic(a: Int) -> <v0>
|
||||
w(a|<v0>)
|
||||
v(b: Int)
|
||||
w(b)
|
||||
magic(b: Int) -> <v1>
|
||||
w(b|<v1>)
|
||||
2 mark({ if (a != b) {} })
|
||||
mark(if (a != b) {})
|
||||
mark(a != b)
|
||||
r(a)
|
||||
r(b)
|
||||
call(!=, equals)
|
||||
jf(L2) NEXT:[read (Unit), mark({})]
|
||||
r(a) -> <v2>
|
||||
r(b) -> <v3>
|
||||
call(!=, equals|<v2>, <v3>) -> <v4>
|
||||
jf(L2|<v4>) NEXT:[read (Unit), mark({})]
|
||||
3 mark({})
|
||||
read (Unit)
|
||||
2 jmp(L3) NEXT:[<END>]
|
||||
2 jmp(L3) NEXT:[<END>]
|
||||
L2:
|
||||
read (Unit) PREV:[jf(L2)]
|
||||
read (Unit) PREV:[jf(L2|<v4>)]
|
||||
L1:
|
||||
L3:
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp(L3), read (Unit)]
|
||||
1 <END> NEXT:[<SINK>] PREV:[jmp(L3), read (Unit)]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -9,14 +9,14 @@ L0:
|
||||
2 mark({ throw Exception() test() })
|
||||
mark(throw Exception())
|
||||
mark(Exception())
|
||||
call(Exception, <init>)
|
||||
throw (throw Exception()) NEXT:[<ERROR>]
|
||||
call(Exception, <init>) -> <v0>
|
||||
throw (throw Exception()|<v0>) NEXT:[<ERROR>]
|
||||
- mark(test()) PREV:[]
|
||||
- call(test, test) PREV:[]
|
||||
- call(test, test) -> <v1> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[throw (throw Exception())]
|
||||
<ERROR> PREV:[throw (throw Exception()|<v0>)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -7,8 +7,8 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ return ?: null })
|
||||
ret L1 NEXT:[<END>]
|
||||
- jt(L2) NEXT:[r(null), <END>] PREV:[]
|
||||
- r(null) PREV:[]
|
||||
- jt(L2) NEXT:[r(null) -> <v0>, <END>] PREV:[]
|
||||
- r(null) -> <v0> PREV:[]
|
||||
L1:
|
||||
L2:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret L1]
|
||||
|
||||
@@ -9,14 +9,14 @@ L0:
|
||||
mark("${throw Exception()} ${1}")
|
||||
mark(throw Exception())
|
||||
mark(Exception())
|
||||
call(Exception, <init>)
|
||||
throw (throw Exception()) NEXT:[<ERROR>]
|
||||
- r(1) PREV:[]
|
||||
- r("${throw Exception()} ${1}") PREV:[]
|
||||
call(Exception, <init>) -> <v0>
|
||||
throw (throw Exception()|<v0>) NEXT:[<ERROR>]
|
||||
- r(1) -> <v1> PREV:[]
|
||||
- magic("${throw Exception()} ${1}"|<v1>) -> <v2> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[throw (throw Exception())]
|
||||
<ERROR> PREV:[throw (throw Exception()|<v0>)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
+6
-6
@@ -18,16 +18,16 @@ class AnonymousInitializers() {
|
||||
L0:
|
||||
1 <START>
|
||||
v(val k = 34)
|
||||
r(34)
|
||||
w(k)
|
||||
r(34) -> <v0>
|
||||
w(k|<v0>)
|
||||
v(val i: Int)
|
||||
2 mark({ $i = 12 })
|
||||
r(12)
|
||||
w($i)
|
||||
r(12) -> <v1>
|
||||
w($i|<v1>)
|
||||
1 v(val j: Int get() = 20)
|
||||
2 mark({ $i = 13 })
|
||||
r(13)
|
||||
w($i)
|
||||
r(13) -> <v2>
|
||||
w($i|<v2>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
+6
-6
@@ -7,16 +7,16 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ {} })
|
||||
mark({})
|
||||
jmp?(L2) NEXT:[r({}), d({})]
|
||||
d({}) NEXT:[<SINK>]
|
||||
jmp?(L2) NEXT:[r({}) -> <v0>, d({})]
|
||||
d({}) NEXT:[<SINK>]
|
||||
L2:
|
||||
r({}) PREV:[jmp?(L2)]
|
||||
r({}) -> <v0> PREV:[jmp?(L2)]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>, d({})]
|
||||
<SINK> PREV:[<ERROR>, <END>, d({})]
|
||||
=====================
|
||||
== anonymous_0 ==
|
||||
{}
|
||||
|
||||
@@ -9,12 +9,12 @@ L0:
|
||||
mark(throw java.lang.RuntimeException())
|
||||
mark(java.lang.RuntimeException())
|
||||
mark(RuntimeException())
|
||||
call(RuntimeException, <init>)
|
||||
throw (throw java.lang.RuntimeException()) NEXT:[<ERROR>]
|
||||
call(RuntimeException, <init>) -> <v0>
|
||||
throw (throw java.lang.RuntimeException()|<v0>) NEXT:[<ERROR>]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[throw (throw java.lang.RuntimeException())]
|
||||
<ERROR> PREV:[throw (throw java.lang.RuntimeException()|<v0>)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -7,6 +7,7 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ T })
|
||||
error(T, No resolved call)
|
||||
magic(T) -> <v0>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -20,8 +20,8 @@ class C() {
|
||||
L0:
|
||||
1 <START>
|
||||
v(val a: Int = 1)
|
||||
r(1)
|
||||
w(a)
|
||||
r(1) -> <v0>
|
||||
w(a|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -35,15 +35,16 @@ fun doSmth(i: Int) {}
|
||||
L0:
|
||||
1 <START>
|
||||
v(i: Int)
|
||||
w(i)
|
||||
magic(i: Int) -> <v0>
|
||||
w(i|<v0>)
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== test1 ==
|
||||
fun test1() {
|
||||
@@ -62,10 +63,10 @@ L0:
|
||||
mark(object { val x : Int { $x = 1 } })
|
||||
v(val x : Int)
|
||||
3 mark({ $x = 1 })
|
||||
r(1)
|
||||
w($x)
|
||||
2 r(object { val x : Int { $x = 1 } })
|
||||
w(a)
|
||||
r(1) -> <v0>
|
||||
w($x|<v0>)
|
||||
2 r(object { val x : Int { $x = 1 } }) -> <v1>
|
||||
w(a|<v1>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -85,8 +86,8 @@ L0:
|
||||
1 <START>
|
||||
v(val x : Int)
|
||||
2 mark({ $x = 1 })
|
||||
r(1)
|
||||
w($x)
|
||||
r(1) -> <v0>
|
||||
w($x|<v0>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -106,15 +107,15 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ val b = 1 val a = object { val x = b } })
|
||||
v(val b = 1)
|
||||
r(1)
|
||||
w(b)
|
||||
r(1) -> <v0>
|
||||
w(b|<v0>)
|
||||
v(val a = object { val x = b })
|
||||
mark(object { val x = b })
|
||||
v(val x = b)
|
||||
r(b)
|
||||
w(x)
|
||||
r(object { val x = b })
|
||||
w(a)
|
||||
r(b) -> <v1>
|
||||
w(x|<v1>)
|
||||
r(object { val x = b }) -> <v2>
|
||||
w(a|<v2>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -138,11 +139,11 @@ L0:
|
||||
v(val a = object { val y : Int fun inner_bar() { y = 10 } })
|
||||
mark(object { val y : Int fun inner_bar() { y = 10 } })
|
||||
v(val y : Int)
|
||||
jmp?(L2) NEXT:[r(object { val y : Int fun inner_bar() { y = 10 } }), d(fun inner_bar() { y = 10 })]
|
||||
jmp?(L2) NEXT:[r(object { val y : Int fun inner_bar() { y = 10 } }) -> <v0>, d(fun inner_bar() { y = 10 })]
|
||||
d(fun inner_bar() { y = 10 }) NEXT:[<SINK>]
|
||||
L2:
|
||||
r(object { val y : Int fun inner_bar() { y = 10 } }) PREV:[jmp?(L2)]
|
||||
w(a)
|
||||
r(object { val y : Int fun inner_bar() { y = 10 } }) -> <v0> PREV:[jmp?(L2)]
|
||||
w(a|<v0>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -158,8 +159,8 @@ fun inner_bar() {
|
||||
L3:
|
||||
3 <START>
|
||||
4 mark({ y = 10 })
|
||||
r(10)
|
||||
w(y)
|
||||
r(10) -> <v0>
|
||||
w(y|<v0>)
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -189,13 +190,13 @@ L0:
|
||||
v(val x : Int)
|
||||
v(val y : Int)
|
||||
3 mark({ $x = 1 })
|
||||
r(1)
|
||||
w($x)
|
||||
2 jmp?(L2) NEXT:[r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }), d(fun ggg() { y = 10 })]
|
||||
r(1) -> <v0>
|
||||
w($x|<v0>)
|
||||
2 jmp?(L2) NEXT:[r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v1>, 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 } }) PREV:[jmp?(L2)]
|
||||
w(a)
|
||||
r(object { val x : Int val y : Int { $x = 1 } fun ggg() { y = 10 } }) -> <v1> PREV:[jmp?(L2)]
|
||||
w(a|<v1>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -211,8 +212,8 @@ fun ggg() {
|
||||
L3:
|
||||
3 <START>
|
||||
4 mark({ y = 10 })
|
||||
r(10)
|
||||
w(y)
|
||||
r(10) -> <v0>
|
||||
w(y|<v0>)
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -242,19 +243,19 @@ L0:
|
||||
v(val a = object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } })
|
||||
mark(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } })
|
||||
v(var x = 1)
|
||||
r(1)
|
||||
w(x)
|
||||
r(1) -> <v0>
|
||||
w(x|<v0>)
|
||||
3 mark({ $x = 2 })
|
||||
r(2)
|
||||
w($x)
|
||||
r(2) -> <v1>
|
||||
w($x|<v1>)
|
||||
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 } }), 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 } }) -> <v2>, 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 } }) PREV:[jmp?(L5)]
|
||||
w(a)
|
||||
r(object { var x = 1 { $x = 2 } fun foo() { x = 3 } fun bar() { x = 4 } }) -> <v2> PREV:[jmp?(L5)]
|
||||
w(a|<v2>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -270,8 +271,8 @@ fun foo() {
|
||||
L3:
|
||||
3 <START>
|
||||
4 mark({ x = 3 })
|
||||
r(3)
|
||||
w(x)
|
||||
r(3) -> <v0>
|
||||
w(x|<v0>)
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -287,8 +288,8 @@ fun bar() {
|
||||
L6:
|
||||
3 <START>
|
||||
4 mark({ x = 4 })
|
||||
r(4)
|
||||
w(x)
|
||||
r(4) -> <v0>
|
||||
w(x|<v0>)
|
||||
L7:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -44,13 +44,13 @@ override fun foo() = 10
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
r(10)
|
||||
r(10) -> <v0>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== foo ==
|
||||
fun foo(b: B) : Int {
|
||||
@@ -61,18 +61,19 @@ fun foo(b: B) : Int {
|
||||
L0:
|
||||
1 <START>
|
||||
v(b: B)
|
||||
w(b)
|
||||
magic(b: B) -> <v0>
|
||||
w(b|<v0>)
|
||||
2 mark({ val o = object : A by b {} return o.foo() })
|
||||
v(val o = object : A by b {})
|
||||
mark(object : A by b {})
|
||||
r(b)
|
||||
r(object : A by b {})
|
||||
w(o)
|
||||
r(b) -> <v1>
|
||||
r(object : A by b {}) -> <v2>
|
||||
w(o|<v2>)
|
||||
mark(o.foo())
|
||||
mark(foo())
|
||||
r(o)
|
||||
call(foo, foo)
|
||||
ret(*) L1
|
||||
r(o) -> <v3>
|
||||
call(foo, foo|<v3>) -> <v4>
|
||||
ret(*|<v4>) L1
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -38,8 +38,8 @@ L3:
|
||||
4 mark({ val x = "" fun loc() { val x3 = "" } })
|
||||
v(val x = "")
|
||||
mark("")
|
||||
r("")
|
||||
w(x)
|
||||
r("") -> <v0>
|
||||
w(x|<v0>)
|
||||
jmp?(L5) NEXT:[<END>, d(fun loc() { val x3 = "" })]
|
||||
d(fun loc() { val x3 = "" }) NEXT:[<SINK>]
|
||||
L4:
|
||||
@@ -60,8 +60,8 @@ L6:
|
||||
6 mark({ val x3 = "" })
|
||||
v(val x3 = "")
|
||||
mark("")
|
||||
r("")
|
||||
w(x3)
|
||||
r("") -> <v0>
|
||||
w(x3|<v0>)
|
||||
L7:
|
||||
5 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -33,8 +33,8 @@ L3:
|
||||
3 <START>
|
||||
4 mark({ val b: Int return b })
|
||||
v(val b: Int)
|
||||
r(b)
|
||||
ret(*) L4
|
||||
r(b) -> <v0>
|
||||
ret(*|<v0>) L4
|
||||
L4:
|
||||
3 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -18,26 +18,26 @@ fun component1() = 1
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
r(1)
|
||||
r(1) -> <v0>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== component2 ==
|
||||
fun component2() = 2
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
r(2)
|
||||
r(2) -> <v0>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== test ==
|
||||
fun test(c: C) {
|
||||
@@ -48,18 +48,19 @@ fun test(c: C) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(c: C)
|
||||
w(c)
|
||||
magic(c: C) -> <v0>
|
||||
w(c|<v0>)
|
||||
2 mark({ val (a, b) = c val d = 1 })
|
||||
r(c)
|
||||
r(c) -> <v1>
|
||||
v(a)
|
||||
call(a, component1)
|
||||
w(a)
|
||||
call(a, component1|<v1>) -> <v2>
|
||||
w(a|<v2>)
|
||||
v(b)
|
||||
call(b, component2)
|
||||
w(b)
|
||||
call(b, component2|<v1>) -> <v3>
|
||||
w(b|<v3>)
|
||||
v(val d = 1)
|
||||
r(1)
|
||||
w(d)
|
||||
r(1) -> <v4>
|
||||
w(d|<v4>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
+8
-5
@@ -7,14 +7,17 @@ fun foo(x: Int) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(x: Int)
|
||||
w(x)
|
||||
magic(x: Int) -> <v0>
|
||||
w(x|<v0>)
|
||||
2 mark({ val (a, b) = x a })
|
||||
r(x)
|
||||
r(x) -> <v1>
|
||||
v(a)
|
||||
w(a)
|
||||
magic(a|<v1>) -> <v2>
|
||||
w(a|<v2>)
|
||||
v(b)
|
||||
w(b)
|
||||
r(a)
|
||||
magic(b|<v1>) -> <v3>
|
||||
w(b|<v3>)
|
||||
r(a) -> <v4>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -18,16 +18,18 @@ fun get(_this: Any, p: PropertyMetadata): Int = 0
|
||||
L0:
|
||||
1 <START>
|
||||
v(_this: Any)
|
||||
w(_this)
|
||||
magic(_this: Any) -> <v0>
|
||||
w(_this|<v0>)
|
||||
v(p: PropertyMetadata)
|
||||
w(p)
|
||||
r(0)
|
||||
magic(p: PropertyMetadata) -> <v1>
|
||||
w(p|<v1>)
|
||||
r(0) -> <v2>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== a ==
|
||||
val a = Delegate()
|
||||
@@ -36,14 +38,14 @@ L0:
|
||||
1 <START>
|
||||
v(val a = Delegate())
|
||||
mark(Delegate())
|
||||
call(Delegate, <init>)
|
||||
w(a)
|
||||
call(Delegate, <init>) -> <v0>
|
||||
w(a|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== b ==
|
||||
val b by a
|
||||
@@ -51,7 +53,7 @@ val b by a
|
||||
L0:
|
||||
1 <START>
|
||||
v(val b by a)
|
||||
r(a)
|
||||
r(a) -> <v0>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -12,7 +12,7 @@ L0:
|
||||
1 <START>
|
||||
v(val a: Int get() = 1)
|
||||
2 mark({ $a })
|
||||
r($a)
|
||||
r($a) -> <v0>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
+7
-7
@@ -21,15 +21,15 @@ L0:
|
||||
1 <START>
|
||||
mark("foo" + this.$bar)
|
||||
mark("foo")
|
||||
r("foo")
|
||||
r("foo") -> <v0>
|
||||
mark(this.$bar)
|
||||
r(this)
|
||||
r($bar)
|
||||
call(+, plus)
|
||||
r(this) -> <v1>
|
||||
r($bar|<v1>) -> <v2>
|
||||
call(+, plus|<v0>, <v2>) -> <v3>
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -26,55 +26,65 @@ fun assignments() : Unit {
|
||||
|
||||
val t = Test();
|
||||
t.x = 1
|
||||
t.x += 1
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
2 mark({ var x = 1 x = 2 x += 2 x = if (true) 1 else 2 val y = true && false val z = false && true val t = Test(); t.x = 1 })
|
||||
2 mark({ var x = 1 x = 2 x += 2 x = if (true) 1 else 2 val y = true && false val z = false && true val t = Test(); t.x = 1 t.x += 1 })
|
||||
v(var x = 1)
|
||||
r(1)
|
||||
w(x)
|
||||
r(2)
|
||||
w(x)
|
||||
r(1) -> <v0>
|
||||
w(x|<v0>)
|
||||
r(2) -> <v1>
|
||||
w(x|<v1>)
|
||||
mark(x += 2)
|
||||
r(x)
|
||||
r(2)
|
||||
call(+=, plus)
|
||||
w(x)
|
||||
r(x) -> <v2>
|
||||
r(2) -> <v3>
|
||||
call(+=, plus|<v2>, <v3>) -> <v4>
|
||||
w(x|<v4>)
|
||||
mark(if (true) 1 else 2)
|
||||
r(true)
|
||||
jf(L2) NEXT:[r(2), r(1)]
|
||||
r(1)
|
||||
jmp(L3) NEXT:[w(x)]
|
||||
r(true) -> <v5>
|
||||
jf(L2|<v5>) NEXT:[r(2) -> <v7>, r(1) -> <v6>]
|
||||
r(1) -> <v6>
|
||||
jmp(L3) NEXT:[magic(if (true) 1 else 2|<v6>, <v7>) -> <v8>]
|
||||
L2:
|
||||
r(2) PREV:[jf(L2)]
|
||||
r(2) -> <v7> PREV:[jf(L2|<v5>)]
|
||||
L3:
|
||||
w(x) PREV:[jmp(L3), r(2)]
|
||||
magic(if (true) 1 else 2|<v6>, <v7>) -> <v8> PREV:[jmp(L3), r(2) -> <v7>]
|
||||
w(x|<v8>)
|
||||
v(val y = true && false)
|
||||
r(true)
|
||||
jf(L4) NEXT:[r(true && false), r(false)]
|
||||
r(false)
|
||||
r(true) -> <v9>
|
||||
jf(L4|<v9>) NEXT:[magic(true && false|<v9>, <v10>) -> <v11>, r(false) -> <v10>]
|
||||
r(false) -> <v10>
|
||||
L4:
|
||||
r(true && false) PREV:[jf(L4), r(false)]
|
||||
w(y)
|
||||
magic(true && false|<v9>, <v10>) -> <v11> PREV:[jf(L4|<v9>), r(false) -> <v10>]
|
||||
w(y|<v11>)
|
||||
v(val z = false && true)
|
||||
r(false)
|
||||
jf(L5) NEXT:[r(false && true), r(true)]
|
||||
r(true)
|
||||
r(false) -> <v12>
|
||||
jf(L5|<v12>) NEXT:[magic(false && true|<v12>, <v13>) -> <v14>, r(true) -> <v13>]
|
||||
r(true) -> <v13>
|
||||
L5:
|
||||
r(false && true) PREV:[jf(L5), r(true)]
|
||||
w(z)
|
||||
magic(false && true|<v12>, <v13>) -> <v14> PREV:[jf(L5|<v12>), r(true) -> <v13>]
|
||||
w(z|<v14>)
|
||||
v(val t = Test())
|
||||
mark(Test())
|
||||
call(Test, <init>)
|
||||
w(t)
|
||||
r(1)
|
||||
r(t)
|
||||
w(t.x)
|
||||
call(Test, <init>) -> <v15>
|
||||
w(t|<v15>)
|
||||
r(1) -> <v16>
|
||||
r(t) -> <v17>
|
||||
w(t.x|<v17>, <v16>)
|
||||
mark(t.x += 1)
|
||||
mark(t.x)
|
||||
r(t) -> <v18>
|
||||
r(x|<v18>) -> <v19>
|
||||
r(1) -> <v20>
|
||||
call(+=, plus|<v19>, <v20>) -> <v21>
|
||||
r(t) -> <v22>
|
||||
w(t.x|<v22>, <v21>)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -14,4 +14,5 @@ fun assignments() : Unit {
|
||||
|
||||
val t = Test();
|
||||
t.x = 1
|
||||
t.x += 1
|
||||
}
|
||||
@@ -20,63 +20,68 @@ fun lazyBooleans(a : Boolean, b : Boolean) : Unit {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a : Boolean)
|
||||
w(a)
|
||||
magic(a : Boolean) -> <v0>
|
||||
w(a|<v0>)
|
||||
v(b : Boolean)
|
||||
w(b)
|
||||
magic(b : Boolean) -> <v1>
|
||||
w(b|<v1>)
|
||||
2 mark({ if (a) { 1 } else { 2 } 3 if (a && b) 5 else 6 7 if (a || b) 8 else 9 10 if (a) 11 12 if (a) else 13 14 })
|
||||
mark(if (a) { 1 } else { 2 })
|
||||
r(a)
|
||||
jf(L2) NEXT:[mark({ 2 }), mark({ 1 })]
|
||||
r(a) -> <v2>
|
||||
jf(L2|<v2>) NEXT:[mark({ 2 }), mark({ 1 })]
|
||||
3 mark({ 1 })
|
||||
r(1)
|
||||
2 jmp(L3) NEXT:[r(3)]
|
||||
r(1) -> <v3>
|
||||
2 jmp(L3) NEXT:[magic(if (a) { 1 } else { 2 }|<v3>, <v4>) -> <v5>]
|
||||
L2:
|
||||
3 mark({ 2 }) PREV:[jf(L2)]
|
||||
r(2)
|
||||
3 mark({ 2 }) PREV:[jf(L2|<v2>)]
|
||||
r(2) -> <v4>
|
||||
L3:
|
||||
2 r(3) PREV:[jmp(L3), r(2)]
|
||||
2 magic(if (a) { 1 } else { 2 }|<v3>, <v4>) -> <v5> PREV:[jmp(L3), r(2) -> <v4>]
|
||||
r(3) -> <v6>
|
||||
mark(if (a && b) 5 else 6)
|
||||
r(a)
|
||||
jf(L4) NEXT:[jf(L5), r(b)]
|
||||
r(b)
|
||||
r(a) -> <v7>
|
||||
jf(L4|<v7>) NEXT:[jf(L5), r(b) -> <v8>]
|
||||
r(b) -> <v8>
|
||||
L4:
|
||||
jf(L5) NEXT:[r(6), r(5)] PREV:[jf(L4), r(b)]
|
||||
r(5)
|
||||
jmp(L6) NEXT:[r(7)]
|
||||
jf(L5) NEXT:[r(6) -> <v10>, r(5) -> <v9>] PREV:[jf(L4|<v7>), r(b) -> <v8>]
|
||||
r(5) -> <v9>
|
||||
jmp(L6) NEXT:[magic(if (a && b) 5 else 6|<v9>, <v10>) -> <v11>]
|
||||
L5:
|
||||
r(6) PREV:[jf(L5)]
|
||||
r(6) -> <v10> PREV:[jf(L5)]
|
||||
L6:
|
||||
r(7) PREV:[jmp(L6), r(6)]
|
||||
magic(if (a && b) 5 else 6|<v9>, <v10>) -> <v11> PREV:[jmp(L6), r(6) -> <v10>]
|
||||
r(7) -> <v12>
|
||||
mark(if (a || b) 8 else 9)
|
||||
r(a)
|
||||
jt(L7) NEXT:[r(b), jf(L8)]
|
||||
r(b)
|
||||
r(a) -> <v13>
|
||||
jt(L7|<v13>) NEXT:[r(b) -> <v14>, jf(L8)]
|
||||
r(b) -> <v14>
|
||||
L7:
|
||||
jf(L8) NEXT:[r(9), r(8)] PREV:[jt(L7), r(b)]
|
||||
r(8)
|
||||
jmp(L9) NEXT:[r(10)]
|
||||
jf(L8) NEXT:[r(9) -> <v16>, r(8) -> <v15>] PREV:[jt(L7|<v13>), r(b) -> <v14>]
|
||||
r(8) -> <v15>
|
||||
jmp(L9) NEXT:[magic(if (a || b) 8 else 9|<v15>, <v16>) -> <v17>]
|
||||
L8:
|
||||
r(9) PREV:[jf(L8)]
|
||||
r(9) -> <v16> PREV:[jf(L8)]
|
||||
L9:
|
||||
r(10) PREV:[jmp(L9), r(9)]
|
||||
magic(if (a || b) 8 else 9|<v15>, <v16>) -> <v17> PREV:[jmp(L9), r(9) -> <v16>]
|
||||
r(10) -> <v18>
|
||||
mark(if (a) 11)
|
||||
r(a)
|
||||
jf(L10) NEXT:[read (Unit), r(11)]
|
||||
r(11)
|
||||
jmp(L11) NEXT:[r(12)]
|
||||
r(a) -> <v19>
|
||||
jf(L10|<v19>) NEXT:[read (Unit), r(11) -> <v20>]
|
||||
r(11) -> <v20>
|
||||
jmp(L11) NEXT:[r(12) -> <v21>]
|
||||
L10:
|
||||
read (Unit) PREV:[jf(L10)]
|
||||
read (Unit) PREV:[jf(L10|<v19>)]
|
||||
L11:
|
||||
r(12) PREV:[jmp(L11), read (Unit)]
|
||||
r(12) -> <v21> PREV:[jmp(L11), read (Unit)]
|
||||
mark(if (a) else 13)
|
||||
r(a)
|
||||
jf(L12) NEXT:[r(13), read (Unit)]
|
||||
r(a) -> <v22>
|
||||
jf(L12|<v22>) NEXT:[r(13) -> <v23>, read (Unit)]
|
||||
read (Unit)
|
||||
jmp(L13) NEXT:[r(14)]
|
||||
jmp(L13) NEXT:[r(14) -> <v24>]
|
||||
L12:
|
||||
r(13) PREV:[jf(L12)]
|
||||
r(13) -> <v23> PREV:[jf(L12|<v22>)]
|
||||
L13:
|
||||
r(14) PREV:[jmp(L13), r(13)]
|
||||
r(14) -> <v24> PREV:[jmp(L13), r(13) -> <v23>]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -6,17 +6,17 @@ fun blockAndAndMismatch() : Boolean {
|
||||
L0:
|
||||
1 <START>
|
||||
2 mark({ false || (return false) })
|
||||
r(false)
|
||||
jt(L2) NEXT:[mark((return false)), r(false || (return false))]
|
||||
r(false) -> <v0>
|
||||
jt(L2|<v0>) NEXT:[mark((return false)), magic(false || (return false)|<v0>) -> <v2>]
|
||||
mark((return false))
|
||||
r(false)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(false) -> <v1>
|
||||
ret(*|<v1>) L1 NEXT:[<END>]
|
||||
L2:
|
||||
r(false || (return false)) PREV:[jt(L2)]
|
||||
magic(false || (return false)|<v0>) -> <v2> PREV:[jt(L2|<v0>)]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, r(false || (return false))]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v1>) L1, magic(false || (return false)|<v0>) -> <v2>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -6,9 +6,10 @@ fun Int.bar(c: C) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(c: C)
|
||||
w(c)
|
||||
magic(c: C) -> <v0>
|
||||
w(c|<v0>)
|
||||
2 mark({ this = c })
|
||||
r(c)
|
||||
r(c) -> <v1>
|
||||
unsupported(BINARY_EXPRESSION : this = c)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
|
||||
@@ -62,8 +62,8 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ val inTopLevel = 1.0 BunchKeywordRegister() .add(ABSTRACT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FINAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(OPEN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(INTERNAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PRIVATE_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PROTECTED_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PUBLIC_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(CLASS_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(ENUM_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FUN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(GET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(SET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TRAIT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAR_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TYPE_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(IMPORT_KEYWORD, inTopLevel) .add(PACKAGE_KEYWORD, inTopLevel) .add(OVERRIDE_KEYWORD, inTopLevel) .add(IN_KEYWORD, inTopLevel, inTopLevel) .add(OUT_KEYWORD, inTopLevel) .add(OBJECT_KEYWORD, unresolvedCode) .registerAll() })
|
||||
v(val inTopLevel = 1.0)
|
||||
r(1.0)
|
||||
w(inTopLevel)
|
||||
r(1.0) -> <v0>
|
||||
w(inTopLevel|<v0>)
|
||||
mark(BunchKeywordRegister() .add(ABSTRACT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FINAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(OPEN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(INTERNAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PRIVATE_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PROTECTED_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PUBLIC_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(CLASS_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(ENUM_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FUN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(GET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(SET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TRAIT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAR_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TYPE_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(IMPORT_KEYWORD, inTopLevel) .add(PACKAGE_KEYWORD, inTopLevel) .add(OVERRIDE_KEYWORD, inTopLevel) .add(IN_KEYWORD, inTopLevel, inTopLevel) .add(OUT_KEYWORD, inTopLevel) .add(OBJECT_KEYWORD, unresolvedCode) .registerAll())
|
||||
mark(registerAll())
|
||||
mark(BunchKeywordRegister() .add(ABSTRACT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FINAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(OPEN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(INTERNAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PRIVATE_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PROTECTED_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(PUBLIC_KEYWORD, inTopLevel, inTopLevel, inTopLevel, inTopLevel) .add(CLASS_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(ENUM_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(FUN_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(GET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(SET_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TRAIT_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAL_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(VAR_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(TYPE_KEYWORD, inTopLevel, inTopLevel, inTopLevel) .add(IMPORT_KEYWORD, inTopLevel) .add(PACKAGE_KEYWORD, inTopLevel) .add(OVERRIDE_KEYWORD, inTopLevel) .add(IN_KEYWORD, inTopLevel, inTopLevel) .add(OUT_KEYWORD, inTopLevel) .add(OBJECT_KEYWORD, unresolvedCode))
|
||||
@@ -111,111 +111,112 @@ L0:
|
||||
mark(BunchKeywordRegister() .add(ABSTRACT_KEYWORD, inTopLevel, inTopLevel, inTopLevel))
|
||||
mark(add(ABSTRACT_KEYWORD, inTopLevel, inTopLevel, inTopLevel))
|
||||
mark(BunchKeywordRegister())
|
||||
call(BunchKeywordRegister, <init>)
|
||||
r(ABSTRACT_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(FINAL_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(OPEN_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(INTERNAL_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(PRIVATE_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(PROTECTED_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(PUBLIC_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(CLASS_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(ENUM_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(FUN_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(GET_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(SET_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(TRAIT_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(VAL_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(VAR_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(TYPE_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(IMPORT_KEYWORD)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(PACKAGE_KEYWORD)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(OVERRIDE_KEYWORD)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(IN_KEYWORD)
|
||||
r(inTopLevel)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(OUT_KEYWORD)
|
||||
r(inTopLevel)
|
||||
call(add, add)
|
||||
r(OBJECT_KEYWORD)
|
||||
call(BunchKeywordRegister, <init>) -> <v1>
|
||||
r(ABSTRACT_KEYWORD) -> <v2>
|
||||
r(inTopLevel) -> <v3>
|
||||
r(inTopLevel) -> <v4>
|
||||
r(inTopLevel) -> <v5>
|
||||
call(add, add|<v1>, <v2>, <v3>, <v4>, <v5>) -> <v6>
|
||||
r(FINAL_KEYWORD) -> <v7>
|
||||
r(inTopLevel) -> <v8>
|
||||
r(inTopLevel) -> <v9>
|
||||
r(inTopLevel) -> <v10>
|
||||
call(add, add|<v6>, <v7>, <v8>, <v9>, <v10>) -> <v11>
|
||||
r(OPEN_KEYWORD) -> <v12>
|
||||
r(inTopLevel) -> <v13>
|
||||
r(inTopLevel) -> <v14>
|
||||
r(inTopLevel) -> <v15>
|
||||
call(add, add|<v11>, <v12>, <v13>, <v14>, <v15>) -> <v16>
|
||||
r(INTERNAL_KEYWORD) -> <v17>
|
||||
r(inTopLevel) -> <v18>
|
||||
r(inTopLevel) -> <v19>
|
||||
r(inTopLevel) -> <v20>
|
||||
r(inTopLevel) -> <v21>
|
||||
call(add, add|<v16>, <v17>, <v18>, <v19>, <v20>, <v21>) -> <v22>
|
||||
r(PRIVATE_KEYWORD) -> <v23>
|
||||
r(inTopLevel) -> <v24>
|
||||
r(inTopLevel) -> <v25>
|
||||
r(inTopLevel) -> <v26>
|
||||
r(inTopLevel) -> <v27>
|
||||
call(add, add|<v22>, <v23>, <v24>, <v25>, <v26>, <v27>) -> <v28>
|
||||
r(PROTECTED_KEYWORD) -> <v29>
|
||||
r(inTopLevel) -> <v30>
|
||||
r(inTopLevel) -> <v31>
|
||||
r(inTopLevel) -> <v32>
|
||||
r(inTopLevel) -> <v33>
|
||||
call(add, add|<v28>, <v29>, <v30>, <v31>, <v32>, <v33>) -> <v34>
|
||||
r(PUBLIC_KEYWORD) -> <v35>
|
||||
r(inTopLevel) -> <v36>
|
||||
r(inTopLevel) -> <v37>
|
||||
r(inTopLevel) -> <v38>
|
||||
r(inTopLevel) -> <v39>
|
||||
call(add, add|<v34>, <v35>, <v36>, <v37>, <v38>, <v39>) -> <v40>
|
||||
r(CLASS_KEYWORD) -> <v41>
|
||||
r(inTopLevel) -> <v42>
|
||||
r(inTopLevel) -> <v43>
|
||||
r(inTopLevel) -> <v44>
|
||||
call(add, add|<v40>, <v41>, <v42>, <v43>, <v44>) -> <v45>
|
||||
r(ENUM_KEYWORD) -> <v46>
|
||||
r(inTopLevel) -> <v47>
|
||||
r(inTopLevel) -> <v48>
|
||||
r(inTopLevel) -> <v49>
|
||||
call(add, add|<v45>, <v46>, <v47>, <v48>, <v49>) -> <v50>
|
||||
r(FUN_KEYWORD) -> <v51>
|
||||
r(inTopLevel) -> <v52>
|
||||
r(inTopLevel) -> <v53>
|
||||
r(inTopLevel) -> <v54>
|
||||
call(add, add|<v50>, <v51>, <v52>, <v53>, <v54>) -> <v55>
|
||||
r(GET_KEYWORD) -> <v56>
|
||||
r(inTopLevel) -> <v57>
|
||||
r(inTopLevel) -> <v58>
|
||||
r(inTopLevel) -> <v59>
|
||||
call(add, add|<v55>, <v56>, <v57>, <v58>, <v59>) -> <v60>
|
||||
r(SET_KEYWORD) -> <v61>
|
||||
r(inTopLevel) -> <v62>
|
||||
r(inTopLevel) -> <v63>
|
||||
r(inTopLevel) -> <v64>
|
||||
call(add, add|<v60>, <v61>, <v62>, <v63>, <v64>) -> <v65>
|
||||
r(TRAIT_KEYWORD) -> <v66>
|
||||
r(inTopLevel) -> <v67>
|
||||
r(inTopLevel) -> <v68>
|
||||
r(inTopLevel) -> <v69>
|
||||
call(add, add|<v65>, <v66>, <v67>, <v68>, <v69>) -> <v70>
|
||||
r(VAL_KEYWORD) -> <v71>
|
||||
r(inTopLevel) -> <v72>
|
||||
r(inTopLevel) -> <v73>
|
||||
r(inTopLevel) -> <v74>
|
||||
call(add, add|<v70>, <v71>, <v72>, <v73>, <v74>) -> <v75>
|
||||
r(VAR_KEYWORD) -> <v76>
|
||||
r(inTopLevel) -> <v77>
|
||||
r(inTopLevel) -> <v78>
|
||||
r(inTopLevel) -> <v79>
|
||||
call(add, add|<v75>, <v76>, <v77>, <v78>, <v79>) -> <v80>
|
||||
r(TYPE_KEYWORD) -> <v81>
|
||||
r(inTopLevel) -> <v82>
|
||||
r(inTopLevel) -> <v83>
|
||||
r(inTopLevel) -> <v84>
|
||||
call(add, add|<v80>, <v81>, <v82>, <v83>, <v84>) -> <v85>
|
||||
r(IMPORT_KEYWORD) -> <v86>
|
||||
r(inTopLevel) -> <v87>
|
||||
call(add, add|<v85>, <v86>, <v87>) -> <v88>
|
||||
r(PACKAGE_KEYWORD) -> <v89>
|
||||
r(inTopLevel) -> <v90>
|
||||
call(add, add|<v88>, <v89>, <v90>) -> <v91>
|
||||
r(OVERRIDE_KEYWORD) -> <v92>
|
||||
r(inTopLevel) -> <v93>
|
||||
call(add, add|<v91>, <v92>, <v93>) -> <v94>
|
||||
r(IN_KEYWORD) -> <v95>
|
||||
r(inTopLevel) -> <v96>
|
||||
r(inTopLevel) -> <v97>
|
||||
call(add, add|<v94>, <v95>, <v96>, <v97>) -> <v98>
|
||||
r(OUT_KEYWORD) -> <v99>
|
||||
r(inTopLevel) -> <v100>
|
||||
call(add, add|<v98>, <v99>, <v100>) -> <v101>
|
||||
r(OBJECT_KEYWORD) -> <v102>
|
||||
error(unresolvedCode, No resolved call)
|
||||
call(add, add)
|
||||
call(registerAll, registerAll)
|
||||
magic(unresolvedCode) -> <v103>
|
||||
call(add, add|<v101>, <v102>, <v103>) -> <v104>
|
||||
call(registerAll, registerAll|<v104>) -> <v105>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -230,8 +231,8 @@ L0:
|
||||
1 <START>
|
||||
v(val ABSTRACT_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(ABSTRACT_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(ABSTRACT_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -259,8 +260,8 @@ L0:
|
||||
1 <START>
|
||||
v(val OPEN_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(OPEN_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(OPEN_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -275,8 +276,8 @@ L0:
|
||||
1 <START>
|
||||
v(val INTERNAL_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(INTERNAL_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(INTERNAL_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -291,8 +292,8 @@ L0:
|
||||
1 <START>
|
||||
v(val PRIVATE_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(PRIVATE_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(PRIVATE_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -307,8 +308,8 @@ L0:
|
||||
1 <START>
|
||||
v(val PROTECTED_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(PROTECTED_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(PROTECTED_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -323,8 +324,8 @@ L0:
|
||||
1 <START>
|
||||
v(val PUBLIC_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(PUBLIC_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(PUBLIC_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -339,8 +340,8 @@ L0:
|
||||
1 <START>
|
||||
v(val CLASS_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(CLASS_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(CLASS_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -355,8 +356,8 @@ L0:
|
||||
1 <START>
|
||||
v(val ENUM_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(ENUM_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(ENUM_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -371,8 +372,8 @@ L0:
|
||||
1 <START>
|
||||
v(val FUN_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(FUN_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(FUN_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -387,8 +388,8 @@ L0:
|
||||
1 <START>
|
||||
v(val GET_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(GET_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(GET_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -403,8 +404,8 @@ L0:
|
||||
1 <START>
|
||||
v(val SET_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(SET_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(SET_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -419,8 +420,8 @@ L0:
|
||||
1 <START>
|
||||
v(val TRAIT_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(TRAIT_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(TRAIT_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -435,8 +436,8 @@ L0:
|
||||
1 <START>
|
||||
v(val VAL_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(VAL_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(VAL_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -451,8 +452,8 @@ L0:
|
||||
1 <START>
|
||||
v(val VAR_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(VAR_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(VAR_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -467,8 +468,8 @@ L0:
|
||||
1 <START>
|
||||
v(val TYPE_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(TYPE_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(TYPE_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -483,8 +484,8 @@ L0:
|
||||
1 <START>
|
||||
v(val IMPORT_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(IMPORT_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(IMPORT_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -499,8 +500,8 @@ L0:
|
||||
1 <START>
|
||||
v(val PACKAGE_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(PACKAGE_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(PACKAGE_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -515,8 +516,8 @@ L0:
|
||||
1 <START>
|
||||
v(val OVERRIDE_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(OVERRIDE_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(OVERRIDE_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -531,8 +532,8 @@ L0:
|
||||
1 <START>
|
||||
v(val IN_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(IN_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(IN_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -547,8 +548,8 @@ L0:
|
||||
1 <START>
|
||||
v(val OUT_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(OUT_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(OUT_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -563,8 +564,8 @@ L0:
|
||||
1 <START>
|
||||
v(val OBJECT_KEYWORD = JetToken())
|
||||
mark(JetToken())
|
||||
call(JetToken, <init>)
|
||||
w(OBJECT_KEYWORD)
|
||||
call(JetToken, <init>) -> <v0>
|
||||
w(OBJECT_KEYWORD|<v0>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -6,16 +6,17 @@ fun invoke(f: () -> Unit) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(f: () -> Unit)
|
||||
w(f)
|
||||
magic(f: () -> Unit) -> <v0>
|
||||
w(f|<v0>)
|
||||
2 mark({ (f)() })
|
||||
mark((f)())
|
||||
mark((f))
|
||||
r(f)
|
||||
call((f), invoke)
|
||||
r(f) -> <v1>
|
||||
call((f), invoke|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
== doSomething ==
|
||||
fun Any?.doSomething() {}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
2 mark({})
|
||||
read (Unit)
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== bar ==
|
||||
fun bar(): Nothing = throw Exception()
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
mark(throw Exception())
|
||||
mark(Exception())
|
||||
call(Exception, <init>) -> <v0>
|
||||
throw (throw Exception()|<v0>) NEXT:[<ERROR>]
|
||||
L1:
|
||||
<END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[throw (throw Exception()|<v0>)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
== foo ==
|
||||
fun foo() {
|
||||
null!!.doSomething()
|
||||
bar().doSomething
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
2 mark({ null!!.doSomething() bar().doSomething })
|
||||
mark(null!!.doSomething())
|
||||
mark(doSomething())
|
||||
mark(null!!)
|
||||
r(null) -> <v0>
|
||||
magic(null!!|<v0>) -> <v1>
|
||||
jmp(error) NEXT:[<ERROR>]
|
||||
- call(doSomething, doSomething|<v1>) -> <v2> PREV:[]
|
||||
- mark(bar().doSomething) PREV:[]
|
||||
- mark(bar()) PREV:[]
|
||||
- call(bar, bar) PREV:[]
|
||||
- jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||
- call(doSomething, doSomething) -> <v3> PREV:[]
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[]
|
||||
error:
|
||||
<ERROR> PREV:[jmp(error)]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
@@ -0,0 +1,8 @@
|
||||
fun Any?.doSomething() {}
|
||||
|
||||
fun bar(): Nothing = throw Exception()
|
||||
|
||||
fun foo() {
|
||||
null!!.doSomething()
|
||||
bar().doSomething
|
||||
}
|
||||
@@ -6,15 +6,16 @@ fun test(s: String?) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(s: String?)
|
||||
w(s)
|
||||
magic(s: String?) -> <v0>
|
||||
w(s|<v0>)
|
||||
2 mark({ s?.length })
|
||||
mark(s?.length)
|
||||
r(s)
|
||||
r(length)
|
||||
r(s) -> <v1>
|
||||
r(length|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -6,14 +6,16 @@ fun foo(s: String) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(s: String)
|
||||
w(s)
|
||||
magic(s: String) -> <v0>
|
||||
w(s|<v0>)
|
||||
2 mark({ s. })
|
||||
mark(s.)
|
||||
r(s)
|
||||
r(s) -> <v1>
|
||||
magic(s.|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -7,11 +7,11 @@ L0:
|
||||
1 <START>
|
||||
2 mark({ this() })
|
||||
mark(this())
|
||||
call(this, invoke)
|
||||
call(this, invoke) -> <v0>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
+4
-2
@@ -6,13 +6,15 @@ fun test(a: Any) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Any)
|
||||
w(a)
|
||||
magic(a: Any) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ a.foo() })
|
||||
mark(a.foo())
|
||||
mark(foo())
|
||||
error(foo, No resolved call)
|
||||
error(foo, No resolved call)
|
||||
r(a)
|
||||
r(a) -> <v1>
|
||||
magic(foo|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
@@ -0,0 +1,22 @@
|
||||
== test ==
|
||||
fun test(a: Any) {
|
||||
a.foo
|
||||
}
|
||||
---------------------
|
||||
L0:
|
||||
1 <START>
|
||||
v(a: Any)
|
||||
magic(a: Any) -> <v0>
|
||||
w(a|<v0>)
|
||||
2 mark({ a.foo })
|
||||
mark(a.foo)
|
||||
error(foo, No resolved call)
|
||||
r(a) -> <v1>
|
||||
magic(foo|<v1>) -> <v2>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
@@ -0,0 +1,3 @@
|
||||
fun test(a: Any) {
|
||||
a.foo
|
||||
}
|
||||
@@ -6,13 +6,15 @@ fun main(arg : Array<String>) {
|
||||
L0:
|
||||
1 <START>
|
||||
v(arg : Array<String>)
|
||||
w(arg)
|
||||
magic(arg : Array<String>) -> <v0>
|
||||
w(arg|<v0>)
|
||||
2 mark({ a })
|
||||
error(a, No resolved call)
|
||||
magic(a) -> <v1>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
<SINK> PREV:[<ERROR>, <END>]
|
||||
=====================
|
||||
|
||||
@@ -19,13 +19,13 @@ L2 [onExceptionToFinallyBlock]:
|
||||
L4 [start finally]:
|
||||
3 mark({ test() }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
mark(test())
|
||||
call(test, test)
|
||||
call(test, test) -> <v0>
|
||||
L5 [finish finally]:
|
||||
2 jmp(error) NEXT:[<ERROR>]
|
||||
L3 [skipFinallyToErrorBlock]:
|
||||
3 mark({ test() }) PREV:[jmp(L3 [skipFinallyToErrorBlock])]
|
||||
mark(test())
|
||||
call(test, test)
|
||||
call(test, test) -> <v0>
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>]
|
||||
error:
|
||||
|
||||
@@ -19,17 +19,17 @@ L2 [onExceptionToFinallyBlock]:
|
||||
L4 [start finally]:
|
||||
3 mark({ return test() }) PREV:[jmp?(L2 [onExceptionToFinallyBlock])]
|
||||
mark(test())
|
||||
call(test, test)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
call(test, test) -> <v0>
|
||||
ret(*|<v0>) L1 NEXT:[<END>]
|
||||
L5 [finish finally]:
|
||||
- 2 jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||
L3 [skipFinallyToErrorBlock]:
|
||||
3 mark({ return test() }) PREV:[jmp(L3 [skipFinallyToErrorBlock])]
|
||||
mark(test())
|
||||
call(test, test)
|
||||
ret(*) L1
|
||||
call(test, test) -> <v0>
|
||||
ret(*|<v0>) L1
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v0>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
|
||||
@@ -7,38 +7,40 @@ tailRecursive fun sum(x: Long, sum: Long): Long {
|
||||
L0:
|
||||
1 <START>
|
||||
v(x: Long)
|
||||
w(x)
|
||||
magic(x: Long) -> <v0>
|
||||
w(x|<v0>)
|
||||
v(sum: Long)
|
||||
w(sum)
|
||||
magic(sum: Long) -> <v1>
|
||||
w(sum|<v1>)
|
||||
2 mark({ if (x == 0.toLong()) return sum return sum(x - 1, sum + x) })
|
||||
mark(if (x == 0.toLong()) return sum)
|
||||
mark(x == 0.toLong())
|
||||
r(x)
|
||||
r(x) -> <v2>
|
||||
mark(0.toLong())
|
||||
mark(toLong())
|
||||
r(0)
|
||||
call(toLong, toLong)
|
||||
call(==, equals)
|
||||
jf(L2) NEXT:[read (Unit), r(sum)]
|
||||
r(sum)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
r(0) -> <v3>
|
||||
call(toLong, toLong|<v3>) -> <v4>
|
||||
call(==, equals|<v2>, <v4>) -> <v5>
|
||||
jf(L2|<v5>) NEXT:[read (Unit), r(sum) -> <v6>]
|
||||
r(sum) -> <v6>
|
||||
ret(*|<v6>) L1 NEXT:[<END>]
|
||||
- jmp(L3) NEXT:[mark(sum(x - 1, sum + x))] PREV:[]
|
||||
L2:
|
||||
read (Unit) PREV:[jf(L2)]
|
||||
read (Unit) PREV:[jf(L2|<v5>)]
|
||||
L3:
|
||||
mark(sum(x - 1, sum + x))
|
||||
mark(x - 1)
|
||||
r(x)
|
||||
r(1)
|
||||
call(-, minus)
|
||||
r(x) -> <v7>
|
||||
r(1) -> <v8>
|
||||
call(-, minus|<v7>, <v8>) -> <v9>
|
||||
mark(sum + x)
|
||||
r(sum)
|
||||
r(x)
|
||||
call(+, plus)
|
||||
call(sum, sum)
|
||||
ret(*) L1
|
||||
r(sum) -> <v10>
|
||||
r(x) -> <v11>
|
||||
call(+, plus|<v10>, <v11>) -> <v12>
|
||||
call(sum, sum|<v9>, <v12>) -> <v13>
|
||||
ret(*|<v13>) L1
|
||||
L1:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, ret(*) L1]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v6>) L1, ret(*|<v13>) L1]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
|
||||
@@ -14,18 +14,19 @@ L0:
|
||||
jmp?(L2 [onException]) NEXT:[v(e: Throwable), mark({ return foo() })]
|
||||
3 mark({ return foo() })
|
||||
mark(foo())
|
||||
call(foo, foo)
|
||||
ret(*) L1 NEXT:[<END>]
|
||||
call(foo, foo) -> <v0>
|
||||
ret(*|<v0>) L1 NEXT:[<END>]
|
||||
- 2 jmp(L3 [afterCatches]) NEXT:[<END>] PREV:[]
|
||||
L2 [onException]:
|
||||
3 v(e: Throwable) PREV:[jmp?(L2 [onException])]
|
||||
w(e)
|
||||
magic(e: Throwable) -> <v1>
|
||||
w(e|<v1>)
|
||||
4 mark({ })
|
||||
read (Unit)
|
||||
3 jmp(L3 [afterCatches])
|
||||
L1:
|
||||
L3 [afterCatches]:
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*) L1, jmp(L3 [afterCatches])]
|
||||
1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, jmp(L3 [afterCatches])]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
sink:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user