Pseudocode: Do not regenerate receiver values
This commit is contained in:
@@ -316,7 +316,7 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
|
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
|
||||||
if (resultingDescriptor instanceof ReceiverParameterDescriptor) {
|
if (resultingDescriptor instanceof ReceiverParameterDescriptor) {
|
||||||
builder.readVariable(expression, resolvedCall, getReceiverValues(resolvedCall, true));
|
builder.readVariable(expression, resolvedCall, getReceiverValues(resolvedCall));
|
||||||
}
|
}
|
||||||
|
|
||||||
copyValue(expression, expression.getInstanceReference());
|
copyValue(expression, expression.getInstanceReference());
|
||||||
@@ -452,7 +452,11 @@ public class JetControlFlowProcessor {
|
|||||||
mark(expression);
|
mark(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitAssignment(JetExpression lhs, @NotNull Function0<PseudoValue> rhsDeferredValue, JetExpression parentExpression) {
|
private void visitAssignment(
|
||||||
|
JetExpression lhs,
|
||||||
|
@NotNull Function0<PseudoValue> rhsDeferredValue,
|
||||||
|
JetExpression parentExpression
|
||||||
|
) {
|
||||||
JetExpression left = JetPsiUtil.deparenthesize(lhs);
|
JetExpression left = JetPsiUtil.deparenthesize(lhs);
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
builder.compilationError(lhs, "No lValue in assignment");
|
builder.compilationError(lhs, "No lValue in assignment");
|
||||||
@@ -469,7 +473,7 @@ public class JetControlFlowProcessor {
|
|||||||
if (left instanceof JetSimpleNameExpression || left instanceof JetQualifiedExpression) {
|
if (left instanceof JetSimpleNameExpression || left instanceof JetQualifiedExpression) {
|
||||||
accessTarget = getResolvedCallAccessTarget(PsiUtilPackage.getQualifiedElementSelector(left));
|
accessTarget = getResolvedCallAccessTarget(PsiUtilPackage.getQualifiedElementSelector(left));
|
||||||
if (accessTarget instanceof AccessTarget.Call) {
|
if (accessTarget instanceof AccessTarget.Call) {
|
||||||
receiverValues = getReceiverValues(((AccessTarget.Call) accessTarget).getResolvedCall(), true);
|
receiverValues = getReceiverValues(((AccessTarget.Call) accessTarget).getResolvedCall());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (left instanceof JetProperty) {
|
else if (left instanceof JetProperty) {
|
||||||
@@ -498,7 +502,7 @@ public class JetControlFlowProcessor {
|
|||||||
|
|
||||||
generateInstructions(lhs.getArrayExpression());
|
generateInstructions(lhs.getArrayExpression());
|
||||||
|
|
||||||
Map<PseudoValue, ReceiverValue> receiverValues = getReceiverValues(setResolvedCall, false);
|
Map<PseudoValue, ReceiverValue> receiverValues = getReceiverValues(setResolvedCall);
|
||||||
SmartFMap<PseudoValue, ValueParameterDescriptor> argumentValues =
|
SmartFMap<PseudoValue, ValueParameterDescriptor> argumentValues =
|
||||||
getArraySetterArguments(rhsDeferredValue, setResolvedCall);
|
getArraySetterArguments(rhsDeferredValue, setResolvedCall);
|
||||||
|
|
||||||
@@ -1214,7 +1218,7 @@ public class JetControlFlowProcessor {
|
|||||||
writtenValue = builder.call(
|
writtenValue = builder.call(
|
||||||
entry,
|
entry,
|
||||||
resolvedCall,
|
resolvedCall,
|
||||||
getReceiverValues(resolvedCall, false),
|
getReceiverValues(resolvedCall),
|
||||||
Collections.<PseudoValue, ValueParameterDescriptor>emptyMap()
|
Collections.<PseudoValue, ValueParameterDescriptor>emptyMap()
|
||||||
).getOutputValue();
|
).getOutputValue();
|
||||||
}
|
}
|
||||||
@@ -1493,7 +1497,7 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
|
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
|
||||||
Map<PseudoValue, ReceiverValue> receivers = getReceiverValues(resolvedCall, true);
|
Map<PseudoValue, ReceiverValue> receivers = getReceiverValues(resolvedCall);
|
||||||
SmartFMap<PseudoValue, ValueParameterDescriptor> parameterValues = SmartFMap.emptyMap();
|
SmartFMap<PseudoValue, ValueParameterDescriptor> parameterValues = SmartFMap.emptyMap();
|
||||||
for (ValueParameterDescriptor parameterDescriptor : resultingDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor parameterDescriptor : resultingDescriptor.getValueParameters()) {
|
||||||
ResolvedValueArgument argument = resolvedCall.getValueArguments().get(parameterDescriptor);
|
ResolvedValueArgument argument = resolvedCall.getValueArguments().get(parameterDescriptor);
|
||||||
@@ -1517,13 +1521,11 @@ public class JetControlFlowProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<PseudoValue, ReceiverValue> getReceiverValues(
|
private Map<PseudoValue, ReceiverValue> getReceiverValues(ResolvedCall<?> resolvedCall) {
|
||||||
ResolvedCall<?> resolvedCall,
|
|
||||||
boolean generateInstructions) {
|
|
||||||
SmartFMap<PseudoValue, ReceiverValue> receiverValues = SmartFMap.emptyMap();
|
SmartFMap<PseudoValue, ReceiverValue> receiverValues = SmartFMap.emptyMap();
|
||||||
JetElement callElement = resolvedCall.getCall().getCallElement();
|
JetElement callElement = resolvedCall.getCall().getCallElement();
|
||||||
receiverValues = getReceiverValues(callElement, resolvedCall.getThisObject(), generateInstructions, receiverValues);
|
receiverValues = getReceiverValues(callElement, resolvedCall.getThisObject(), receiverValues);
|
||||||
receiverValues = getReceiverValues(callElement, resolvedCall.getReceiverArgument(), generateInstructions, receiverValues);
|
receiverValues = getReceiverValues(callElement, resolvedCall.getReceiverArgument(), receiverValues);
|
||||||
return receiverValues;
|
return receiverValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1531,19 +1533,16 @@ public class JetControlFlowProcessor {
|
|||||||
private SmartFMap<PseudoValue, ReceiverValue> getReceiverValues(
|
private SmartFMap<PseudoValue, ReceiverValue> getReceiverValues(
|
||||||
JetElement callElement,
|
JetElement callElement,
|
||||||
ReceiverValue receiver,
|
ReceiverValue receiver,
|
||||||
boolean generateInstructions,
|
|
||||||
SmartFMap<PseudoValue, ReceiverValue> receiverValues
|
SmartFMap<PseudoValue, ReceiverValue> receiverValues
|
||||||
) {
|
) {
|
||||||
if (!receiver.exists()) return receiverValues;
|
if (!receiver.exists()) return receiverValues;
|
||||||
|
|
||||||
if (receiver instanceof ThisReceiver) {
|
if (receiver instanceof ThisReceiver) {
|
||||||
if (generateInstructions) {
|
receiverValues = receiverValues.plus(createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER), receiver);
|
||||||
receiverValues = receiverValues.plus(createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER), receiver);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (receiver instanceof ExpressionReceiver) {
|
else if (receiver instanceof ExpressionReceiver) {
|
||||||
JetExpression expression = ((ExpressionReceiver) receiver).getExpression();
|
JetExpression expression = ((ExpressionReceiver) receiver).getExpression();
|
||||||
if (generateInstructions) {
|
if (builder.getBoundValue(expression) == null) {
|
||||||
generateInstructions(expression);
|
generateInstructions(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ L5:
|
|||||||
r(1) -> <v20>
|
r(1) -> <v20>
|
||||||
mark(t.x += 1)
|
mark(t.x += 1)
|
||||||
call(t.x += 1, plus|<v19>, <v20>) -> <v21>
|
call(t.x += 1, plus|<v19>, <v20>) -> <v21>
|
||||||
r(t) -> <v22>
|
w(t.x|<v18>, <v21>)
|
||||||
w(t.x|<v22>, <v21>)
|
|
||||||
L1:
|
L1:
|
||||||
1 <END> NEXT:[<SINK>]
|
1 <END> NEXT:[<SINK>]
|
||||||
error:
|
error:
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ false && true
|
|||||||
Test() <v15>: Test NEW: call(Test(), <init>) -> <v15>
|
Test() <v15>: Test NEW: call(Test(), <init>) -> <v15>
|
||||||
t <v16>: Test NEW: r(t) -> <v16>
|
t <v16>: Test NEW: r(t) -> <v16>
|
||||||
1 <v17>: Int NEW: r(1) -> <v17>
|
1 <v17>: Int NEW: r(1) -> <v17>
|
||||||
t <v22>: Test NEW: r(t) -> <v22>
|
t <v18>: Test NEW: r(t) -> <v18>
|
||||||
x <v19>: Int NEW: r(x|<v18>) -> <v19>
|
x <v19>: Int NEW: r(x|<v18>) -> <v19>
|
||||||
t.x <v19>: Int COPY
|
t.x <v19>: Int COPY
|
||||||
1 <v20>: Int NEW: r(1) -> <v20>
|
1 <v20>: Int NEW: r(1) -> <v20>
|
||||||
|
|||||||
@@ -31,28 +31,28 @@ sink:
|
|||||||
== foo ==
|
== foo ==
|
||||||
fun foo() {
|
fun foo() {
|
||||||
null!!.doSomething()
|
null!!.doSomething()
|
||||||
bar().doSomething
|
bar().doSomething()
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
L0:
|
L0:
|
||||||
1 <START>
|
1 <START>
|
||||||
2 mark({ null!!.doSomething() bar().doSomething })
|
2 mark({ null!!.doSomething() bar().doSomething() })
|
||||||
mark(null!!.doSomething())
|
mark(null!!.doSomething())
|
||||||
r(null) -> <v0>
|
r(null) -> <v0>
|
||||||
magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
|
magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
|
||||||
jmp(error) NEXT:[<ERROR>]
|
jmp(error) NEXT:[<ERROR>]
|
||||||
- mark(doSomething()) PREV:[]
|
- mark(doSomething()) PREV:[]
|
||||||
- call(doSomething(), doSomething|<v1>) -> <v2> PREV:[]
|
- call(doSomething(), doSomething|<v1>) -> <v2> PREV:[]
|
||||||
- mark(bar().doSomething) PREV:[]
|
- mark(bar().doSomething()) PREV:[]
|
||||||
- mark(bar()) PREV:[]
|
- mark(bar()) PREV:[]
|
||||||
- call(bar(), bar) PREV:[]
|
- call(bar(), bar) PREV:[]
|
||||||
- jmp(error) NEXT:[<ERROR>] PREV:[]
|
- jmp(error) NEXT:[<ERROR>] PREV:[]
|
||||||
- mark(doSomething) PREV:[]
|
- mark(doSomething()) PREV:[]
|
||||||
- call(doSomething, doSomething|!<v3>) -> <v4> PREV:[]
|
- call(doSomething(), doSomething|!<v3>) -> <v4> PREV:[]
|
||||||
L1:
|
L1:
|
||||||
1 <END> NEXT:[<SINK>] PREV:[]
|
1 <END> NEXT:[<SINK>] PREV:[]
|
||||||
error:
|
error:
|
||||||
<ERROR> PREV:[jmp(error)]
|
<ERROR> PREV:[jmp(error)]
|
||||||
sink:
|
sink:
|
||||||
<SINK> PREV:[<ERROR>, <END>]
|
<SINK> PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ fun bar(): Nothing = throw Exception()
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
null!!.doSomething()
|
null!!.doSomething()
|
||||||
bar().doSomething
|
bar().doSomething()
|
||||||
}
|
}
|
||||||
@@ -10,15 +10,15 @@ Exception() <v0>: {<: Throwable} NEW: call(Exception(), <init>) -> <v0>
|
|||||||
== foo ==
|
== foo ==
|
||||||
fun foo() {
|
fun foo() {
|
||||||
null!!.doSomething()
|
null!!.doSomething()
|
||||||
bar().doSomething
|
bar().doSomething()
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
null <v0>: * NEW: r(null) -> <v0>
|
null <v0>: * NEW: r(null) -> <v0>
|
||||||
null!! <v1>: * NEW: magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
|
null!! <v1>: * NEW: magic[NOT_NULL_ASSERTION](null!!|<v0>) -> <v1>
|
||||||
doSomething() <v2>: * NEW: call(doSomething(), doSomething|<v1>) -> <v2>
|
doSomething() <v2>: * NEW: call(doSomething(), doSomething|<v1>) -> <v2>
|
||||||
null!!.doSomething() <v2>: * COPY
|
null!!.doSomething() <v2>: * COPY
|
||||||
bar() !<v3>: *
|
bar() !<v3>: *
|
||||||
doSomething <v4>: * NEW: call(doSomething, doSomething|!<v3>) -> <v4>
|
doSomething() <v4>: * NEW: call(doSomething(), doSomething|!<v3>) -> <v4>
|
||||||
bar().doSomething <v4>: * COPY
|
bar().doSomething() <v4>: * COPY
|
||||||
{ null!!.doSomething() bar().doSomething } <v4>: * COPY
|
{ null!!.doSomething() bar().doSomething() } <v4>: * COPY
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
Reference in New Issue
Block a user