KT-19251 Process uninitialized stores in mandatory bytecode pass
See https://youtrack.jetbrains.com/issue/KT-19251 https://github.com/puniverse/quasar/issues/280 https://bugs.openjdk.java.net/browse/JDK-8046233 Inline function calls (as well as try/catch expressions) in constructor arguments produce bytecode that spills stack, and stores uninitialized objects (created by 'NEW C', but not initialized by 'C.<init>') to local variables. Such bytecode is valid according to the JVM spec, but confuses Quasar (and other bytecode postprocessing tools), and fails to verify under some (buggy) versions of JDK 8. In order to avoid that, we apply 'processUnitializedStores' already implemented for coroutines. It moves 'NEW' instructions after the constructor arguments evaluation, producing code like <initialize class C using Class.forName> <evaluate constructor arguments> <store constructor arguments to variables> NEW C DUP <load constructor arguments from variables> INVOKESPECIAL C.<init>(...) NB some other expressions, such as break/continue in the constructor arguments, also can produce "weird" bytecode: object is created by a 'NEW C' instruction, but later (conditionally) POPped from stack and left uninitialized. This, as we know, also can screw bytecode postprocessing. However, it looks like we can get away with it ATM. Otherwise it looks like we'd have to analyze constructor arguments, see if the evaluation can "jump out", and perform argument linearization in codegen.
Showing
文件已移动
想要评论请 注册 或 登录