• D
    KT-19251 Process uninitialized stores in mandatory bytecode pass · c0a83c3c
    Dmitry Petrov 提交于
    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.
    c0a83c3c
inlineFunInLocalClassConstructorCall.kt 743 字节