vineflower icon indicating copy to clipboard operation
vineflower copied to clipboard

A stack local isn't defined

Open Gaming32 opened this issue 2 years ago • 1 comments

It seems to happen when a class file passes an enclosed variable to a lambda where the enclosed variable isn't a variable. For example, when iconst_1; anewarray; is used instead of aload_0. QF output:

public class ModuleGeneratorTest {
   public static Iterable<String> exampleGen() {
      return InternalUtil.$createGenerator(var1 -> {
         switch(var1[0]) {
            case 0:
            default:
               var0[0] = "Hello";
               break;
            case 1:
               var0[0] = ((String)var0[0]).replace("el", "le");
         }

         if (!" ".isEmpty()) {
            String var10000 = (String)var0[0];
            var1[0] = 1;
            return var10000;
         } else {
            return InternalUtil.$generatorComplete();
         }
      });
   }
}

Expected output (or similar):

public class ModuleGeneratorTest {
   public static Iterable<String> exampleGen() {
      Object[] var10000 = new Object[1];
      return InternalUtil.$createGenerator(var1 -> {
         switch(var1[0]) {
            case 0:
            default:
               var10000[0] = "Hello";
               break;
            case 1:
               var10000[0] = ((String)var10000[0]).replace("el", "le");
         }

         if (!" ".isEmpty()) {
            String var10001 = (String)var10000[0];
            var1[0] = 1;
            return var10001;
         } else {
            return InternalUtil.$generatorComplete();
         }
      });
   }
}

Here's the class file (and a javap): ModuleGeneratorTest.class

Gaming32 avatar May 17 '22 22:05 Gaming32

Here's another example (generated from javayield this time, instead of a hand written class file). Input:

public static Iterable<Integer> generatorTest(int param) {
    while (param > 0) {
        yield_(param = param * 3);
    }
    yieldAll("hello".chars().iterator());
    return null;
}

Output:

public static Iterable<Integer> generatorTest(int param) {
   return GeneratorIterator.$createIterableGenerator(() -> {
      label24: {
         Object var10000;
         switch($state[0]) {
            case 0:
            case 1:
               if (paramx[0] > 0) {
                  Integer var4 = paramx[0] *= 3;
                  $state[0] = 1;
                  return var4;
               }

               var10000 = "hello".chars().iterator();
               break;
            case 2:
               var10000 = $yieldAll[0];
               break;
            case 3:
            default:
               break label24;
         }

         if (((Iterator)var10000).hasNext()) {
            $yieldAll[0] = (Iterator)var10000;
            var10000 = ((Iterator)var10000).next();
            $state[0] = 2;
            return var10000;
         }
      }

      $state[0] = 3;
      return GeneratorIterator.$COMPLETE;
   });
}

Additional files: OtherTest.zip (note that due to some of the files in this being on opposite sides of a refactor, the package names may not all match).

Gaming32 avatar Jun 03 '22 11:06 Gaming32