Support getValue/setValue/provideDelegate suspend functions in JVM backend

- Determine if there are non-tail calls to getValue/setValue simply
by existance of such a property
(it might be too strict, but implementing more granular check may be rather hard)

- Change in ExpressionCodegen is relevant for provideDelegate,
that in case of local variables uses OnStack as StackValue
(see the comment near these changes)

 #KT-15933 Fixed
This commit is contained in:
Denis Zharkov
2017-01-24 18:18:05 +03:00
parent 9ca9a988a6
commit 9ce3880ac6
9 changed files with 221 additions and 3 deletions
@@ -2912,9 +2912,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
boolean isSuspensionPoint,
boolean isConstructor
) {
boolean isSafeCall = receiver instanceof StackValue.SafeCall;
boolean isSafeCallOrOnStack = receiver instanceof StackValue.SafeCall || receiver instanceof StackValue.OnStack;
if (isSuspensionPoint && !isSafeCall) {
if (isSuspensionPoint && !isSafeCallOrOnStack) {
// Inline markers are used to spill the stack before coroutine suspension
addInlineMarker(v, true);
}
@@ -2941,7 +2941,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// The problem is that the stack before the call is not restored in case of null receiver.
// The solution is to spill stack just after receiver is loaded (after IFNULL) in case of safe call.
// But the problem is that we should leave the receiver itself on the stack, so we store it in a temporary variable.
if (isSuspensionPoint && isSafeCall) {
if (isSuspensionPoint && isSafeCallOrOnStack) {
int tmpVar = myFrameMap.enterTemp(receiver.type);
v.store(tmpVar, receiver.type);