This patch takes into account a corner case available for loops
over a progression (see backend.native/tests/external/codegen/box/
ranges/forInUntil/forInUntilMinint.kt test):
for (i in 0 until Int.MIN_VALUE) { ... }
Here we cannot use subtraction to obtain a right bound of the loop
due to an overflow. Instead we consider any loop with MIN_VALUE in
it's right bound as empty loop. Such behaviour is similar to the one
of 'until' method.
So now the empty check for a loops with 'until' call:
for (i in first until bound) { ... }
is as follows:
val last = getProgressionLast(first, bound, step) // Only if step==1
if (first <= last && bound > <Int|Long|Char>.MIN_VALUE) {
do { ... } while(i != last)
}
Further improvements: We can generate a simpler IR for some simple
frequent cases (e.g. for until calls without steps) and eliminate
loops if we can prove that they are empty.
This patch optimizes the following pattern:
for (i in first..last step st) { ... }
In this case we need to create a Progression object and then call its
iterator() method causing at least 2 allocation per loop. This change
replaces such loops with the following constuction:
var inductionVar = first
checkProgressionStep(step) // check if step > 0
last = getProgressionLastElement(first, last, step)
if (first <= last) {
do {
i = inductionVar
inductionVar += step
...
} while(i != last)
}
The problem was observed in the follwing code:
enum class A(one: Int, val two: Int = one) ...
The problem is in the `two` default value. Here the enum constructor
lowering used an old (not lowered) symbol for `one`. Also the lowering
didn't copy the default expression for DEFAULT class.
The patch fixes both problems.
- Split up enum lowering into two stages: descriptors creation and IR creation.
- Added link stage test.
- Enum.valueOf() uses binary search instead of linear.
Now closure builder can contain includes. Includes
are another builders which closures must be added
to the building one.
Includes are:
For function closure:
call targets (including constructors)
callable reference targets
For class:
all children declarations
call targets (including constructors)
callable reference targets
For constructor:
call and callable reference targets
delegating constructor call target
constructing class closure
* captured values are stored in corresponding fields before call to super constructor
* preserving the order of initializers
* tests
* refactoring
* - test fix
- workaround of IR bug
* refactoring
* review fix