Commit Graph

30 Commits

Author SHA1 Message Date
Denis Zharkov cebe67d90c Fix default value generation after suspension point
Replace coercion from VOID with call 'pushDefaultValueOnStack'

It's necessary because coercion of VOID to java/lang/Object ends with Unit instance on stack
that makes variables spilling algorithm thinking that variable is Unit

 #KT-13409 Fixed
2016-09-01 15:03:31 +03:00
Denis Zharkov 1226d8fc2c Refine 'handleResult' calls generation within coroutines
Before this change everything works just fine for 'handleResult' methods
accepting non-Unit parameters

For other cases the same coercion-to-unit strategy is in plain lambdas:
- if last statement is not Unit type, execute it, pop from the stack, then put Unit instance
- for 'return@label' (no expression) just put Unit on the stack

 #KT-13531 Fixed
2016-09-01 15:03:31 +03:00
Denis Zharkov 1df9724c0c Refine stack frames markup calculation
It fixes VerifyError with coroutines on Dalvik happening because of
variables spilling before/after suspension point

BasicInterpreter from ASM does not distinct 'int' types from other
int-like types like 'byte' or 'boolean', neither do HotSpot and JVM spec.
But it seems like Dalvik does not follow it, and spilling
boolean value into an 'int' field fails with VerifyError on Android 4,
so it's necessary to distinct int types for variables spilling

 #KT-13289 Fixed
2016-08-09 16:36:52 +03:00
Denis Zharkov becb1f1f95 Make stack values for assignment-like operations lazy
As well as for other kinds of expressions

Within attached test they were generated twice in case of last expression of coroutine block,
because coroutine related codegen part is built upon assumption that all expressions should be generated lazily

Also add a test about unary postfix increment/decrement

 #KT-13156 Fixed
2016-07-25 13:56:43 +03:00
Denis Zharkov 18c2d3070d Refine variables liveness analysis
Do not treat var as alive just because current instruction belongs to an item range
in local variables table, but the item has different sort of type

As liveness analysis is mostly used in coroutines spilling,
not applying this change may lead that to problems on Android (see tests)
2016-07-12 12:52:03 +03:00
Denis Zharkov 3a59e1d222 Support suspending extension functions 2016-07-06 15:25:19 +03:00
Denis Zharkov a420fda825 Fix problem with missing handleResult call
At first we try to resolve 'handleResult' just as last expression
in a lambda is first argument, then if results are unsuccessful
try resolve 'handleResult' with fake Unit expression

 #KT-12969 Fixed
2016-07-05 15:36:06 +03:00
Denis Zharkov 888db4b3b5 Make 'controller' field package-private
To make it accessible from nested lambdas

 #KT-12974 Fixed
2016-07-05 15:36:06 +03:00
Denis Zharkov d657bc8110 Treat any coroutine as it has non-const closure
Because it's always does capture controller
2016-07-05 15:36:06 +03:00
Denis Zharkov df4bf61378 Refine types returned by OptimizationBasicInterpreter.newValue
#KT-12958 Fixed
2016-07-05 15:36:06 +03:00
Denis Zharkov 1c3db309e5 Support repeated 'invoke' calls on coroutines defined within inline lambdas
#KT-12782 Fixed
2016-06-30 20:22:39 +03:00
Denis Zharkov c2ac49ec96 Support repeated 'invoke' calls on coroutines
#KT-12782 In Progress
2016-06-30 20:22:39 +03:00
Denis Zharkov a25602c709 Fix spilling algorithm for double-sized coroutine parameters 2016-06-30 20:22:39 +03:00
Denis Zharkov 453ee55615 Fix coroutine generation in case of empty lambda
'handleResult' should be called in such case too
2016-06-21 15:52:44 +03:00
Denis Zharkov b6ccd03ef4 Make loops generation lazy
As well as all other kinds of expressions

While it's not necessary in a sense that 'for' loop can not be plain expression,
i.e. it can't be an argument for safe-call etc., but laziness is still very convenient property.

E.g. within attached test they were generated twice in case of last expression
of coroutine block, because coroutine related codegen part is built upon
assumption that all expressions should be generated lazy.
2016-06-21 15:52:44 +03:00
Denis Zharkov ad71934c55 Minor. Add 'operator' modifier in test for handleResult 2016-06-21 15:52:44 +03:00
Denis Zharkov 5ee33e6ad5 Generate last expression in coroutine block even for Unit expected type 2016-06-19 12:50:54 +03:00
Denis Zharkov 72eb87f5d0 Support inline suspend functions
A lot of additional work was required to support them:
- Suspension points are being identified by two markers
  instead of one pointing to suspend function call
- Approach with replacing return type of suspend function does not work anymore.
  So we decode suspension return type as an argument for begin marker
- It became necessary to perform variables liveness analysis
  (see comment in org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor.spillVariables)
2016-06-19 12:50:54 +03:00
Denis Zharkov e7b9564699 Support coroutine lambda parameters in JVM backend 2016-06-19 12:50:53 +03:00
Denis Zharkov 07dcc6c616 Support 'handleException' operator in JVM backend 2016-06-19 12:50:53 +03:00
Denis Zharkov 771cca9c23 Fix some try-catch block related problems in coroutine transformer
Split all try-catch blocks when they intersect suspension points
2016-06-08 18:53:16 +03:00
Denis Zharkov 692acc463a Fix handleResult call generation for statement-like last expression in a block 2016-06-08 18:53:16 +03:00
Denis Zharkov 0d01edb7f9 Adapt FixStackAnalyzer to code generated by coroutine transformation
Without this change internal error happens while inlining coroutine code with try/catch inside
Also get rid of hack with SKIP_MANDATORY_TRANSFORMATIONS_ANNOTATION_DESC
See comment within MethodAnalyzer for clarification
2016-06-08 18:53:16 +03:00
Denis Zharkov 678e8c2baa Setup label value in constructor to be invalid until 'invoke(Controller)' call 2016-06-08 18:53:16 +03:00
Denis Zharkov 2bdaec6eac Refine definition of whether call is suspension point
It's not about all calls to suspend functions, they may called from non-coroutine code
2016-06-08 18:53:16 +03:00
Denis Zharkov dddd7413a1 Fix generated code for suspending in the middle of object construction 2016-06-08 18:53:16 +03:00
Denis Zharkov b1189eff23 Make suspension calls generation more stable
Instead of performing signature change during transformation
it's convinient to make just when generating corresponding call,
for example there is no need to think about default parameters as they just work as is

See comment above replaceSuspensionFunctionViewWithRealDescriptor for clarification
2016-06-08 18:53:16 +03:00
Denis Zharkov 611490e080 Support non-local returns to coroutine label from inline lambda
- Use proper class descriptor when retreiving continuation object (see previous commit)
- Use return type as VOID for such cases
- Load correct labels related to coroutine lambda from outer context
2016-06-08 18:53:16 +03:00
Denis Zharkov 94bd6dcc82 Use proper coroutine class descriptor for extension receiver generation
Before this commit context.getThisDescriptor() has been used, that was quite correct
until suspension happens inside inlined lambda (it has different this-descriptor)
2016-06-08 18:53:16 +03:00
Denis Zharkov 75e112e752 Implement basic support for coroutines in JVM backend 2016-06-08 18:53:16 +03:00