This works in many cases, however, it is incomplete since there
are cases where classes are extracted to top-level and therefore
reparented. Therefore, we lose the information about the function
class are nested inside.
Two known issues with generateNonPartClassDeclarations that was here
before were the fact that we didn't sort sealed classes and its
subclasses which led to NoSuchMethodError (KT-27097), and the fact that
we didn't skip expect classes which led to incorrect duplicate JVM class
name diagnostic (KT-30843)
#KT-27097 Fixed
#KT-30843 Fixed
This directive generates TailCallOptimizationChecker in package helpers.
The check for tail call optimization is based on coroutine stack traces
bug (feature?): when tail call optimization hits, the continuation
object is not generated. Thus, there is no debug metadata for this
suspend function. Consequently, the coroutines stack trace does not
contain stack trace element for that function.
This check is performed by TailCallOptimizationChecker.
Since this is runtime check, unlike bytecode tests, it does not require
test data adjustments on each codegen or inliner change.
Since the check is based on debug metadata, which is JVM specific, there
is not support for other backends yet.
In SourceCompilerForInline we could enter ERASED_INLINE_CLASS context
from containing declaration context. That broke codegen context
hierarchy invariants assumed in accessor generation.
HeaderInfo object, and modifying the operator in the loop condition.
The "additional emptiness condition" is no longer necessary with this.
The open/closed property was removed from HeaderInfo in an earlier
commit, but bringing it back in to simplify the loop building makes
more sense.
Also expanded tests for evaluation order of range bounds.
Previously,
* Equals performs IEEE 754 equality check for floating points and
byte-to-byte checks for other types, including references.
* Ieee754Equals performs IEEE 754 for primitive types
* TotalOrderEquals performs total order equals to all types, including
floating points.
Now it is simplified,
* Equals performs total order checks for all types.
* Ieee754Equals performs IEEE 754 for primitive types.
* (TotalOrderEquals is removed.)
Since functionFromStdlibSingleFileFacade.kt was introduced, lazyOf was
also moved to a multifile class, so we're using another function to test
that reflection on a single file package facade from stdlib works
* In blocks, discard the result of any statement that has a return
type other than void. This was previously done by wrapping each
statement into an "implicit Unit conversion" that was actually
compiled down to a stack pop instead. If an expression happened to
already have type Unit, however, such a conversion was not inserted,
resulting in a stray reference on the stack. These conversions are
now redundant and should probably be removed.
* In assignments and non-exhaustive conditionals, materialize a Unit
on the stack to avoid depth mismatches that trip up the bytecode
validator. Because such expressions are generally used at block level
(and, indeed, the frontend will reject a non-exhaustive conditional
used as an expression), combined with the above change this results
in no additional GETSTATIC opcodes, as they are immediately removed
by the peephole optimizer.
In TopDownAnalyzerFacadeForJVM, we now always use the "load built-ins
from module dependencies" behavior that was previously only enabled with
the dedicated CLI argument -Xload-builtins-from-dependencies. However,
sometimes we compile code without kotlin-stdlib in the classpath, and we
don't want everything to crash because some standard type like
kotlin.Unit hasn't been found.
To mitigate this, we add another module at the end of the dependencies
list, namely a "fallback built-ins" module. This module loads all
built-in declarations from the compiler's class loader, as was done by
default previously. This prevents the compiler from crashing if any
built-in declaration is not found, but compiling the code against
built-ins found in the compiler is still discouraged, so we report an
error if anything is resolved to a declaration from this module, via a
new checker MissingBuiltInDeclarationChecker.
Also introduce a new CLI argument -Xsuppress-missing-builtins-error
specifically to suppress this error and to allow compiling code against
compiler's own built-ins.
#KT-19227 Fixed
#KT-28198 Fixed
Effectively, the following when structure:
when (s) {
s1, s2 -> e1,
s3 -> e2,
s4 -> e3,
...
else -> e
}
is implemented as:
when (s.hashCode()) {
h1 -> {
if (s == s1)
e1
else if (s == s2)
e1
else if (s == s3)
e2
else
e
}
h2 -> if (s == s3) e2 else e,
...
else -> e
}
where s1.hashCode() == s2.hashCode() == s3.hashCode() == h1,
s4.hashCode() == h2.
A tableswitch or lookupswitch is used for the hash code lookup.
Change-Id: I087bf623dbb4a41d3cc64399a1b42342a50757a6
Inner class constructors should use the argument instead of reading
outer `this` from a field because if such an access happens before a
delegating constructor call, e.g. when evaluating an argument, a JVM
bytecode validation error will be thrown. (The only operation on `this`
allowed before a delegating constructor call is SETFIELD, and only if
the field in question is declared in the same class.)
Specifically, defer the removal of hand-written "if (true|false)" from
JvmBuiltinOptimizationLowering into codegen so that appropriate debug
info (and a NOP) can be inserted.
Change-Id: Ia11af05ad8b4251946bd3e685fb7c3319f0f433f
This however makes testLocalFunctionName fail because currently
isSubclassOf (incorrectly) returns false and therefore an anonymous
class is generated and the name is taken from there. The name there is
"box$OK" which is incorrect. The isSubclassOf issue is KT-28198 and will
be fixed separately; the incorrect name issue will be investigated later
Follow-up of 9b3e17f0. There we decided to complete call if a type
variable from a return type has proper lower constraints, now we refine
this rule wrt `Nothing`-like constraints to avoid inferring type variables
to Nothing, which is quite useless
#KT-30370 Fixed