Giter Site home page Giter Site logo

usethesource / flybytes Goto Github PK

View Code? Open in Web Editor NEW
16.0 16.0 6.0 2.23 MB

Flybytes is an intermediate language between JVM bytecode and software languages (DSLs, PLs), for compilation and decompilation.

License: Other

Rascal 31.98% Java 67.42% RouterOS Script 0.60%

flybytes's People

Contributors

bys1 avatar davylandman avatar dependabot[bot] avatar jurgenvinju avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

flybytes's Issues

LinkageError / java.lang.ClassFormatError: Illegal class name "Ljava/lang/String;"

I am compiling a Test.class file by calling the following function:

void compileF() {
    str vl = "io.usethesource.vallang.";
    Class cl = class(
        object("Test"),
        modifiers = {\public(), \final()},
        methods = [
            constructor(
                \public(),
                [],
                [
                    invokeSuper([], []),
                    \decl(array(string()), "args", init = newArray(
                        array(string()),
                        iconst(3)
                    )),
                    \return()
                ]
            )
        ]
    );
    compileClass(cl, |cwd:///Test.class|);
}

When running this using java Test I get the following error in the terminal:

Error: LinkageError occurred while loading main class Test
	java.lang.ClassFormatError: Illegal class name "Ljava/lang/String;" in class file Test

In case it helps you: I got a stack trace in the Rascal shell when I tried loading a bigger class file using a classloader:

|file:///Users/bys1/Documents/RUG/FBEG/flybytes-evalgen/src/main/rascal/Proto.rsc|(1159,62,<42,0>,<44,35>): Java("ClassFormatError","Illegal class name \"Ljava/lang/String;\" in class file FuncEnv")
	at java.lang.ClassLoader.defineClass1(|unknown:///ClassLoader.java|(0,0,<0,0>,<0,0>))
	at java.lang.ClassLoader.defineClass(|unknown:///ClassLoader.java|(0,0,<1012,0>,<1012,0>))
	at java.security.SecureClassLoader.defineClass(|unknown:///SecureClassLoader.java|(0,0,<150,0>,<150,0>))
	at jdk.internal.loader.BuiltinClassLoader.defineClass(|unknown:///BuiltinClassLoader.java|(0,0,<862,0>,<862,0>))
	at jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(|unknown:///BuiltinClassLoader.java|(0,0,<760,0>,<760,0>))
	at jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(|unknown:///BuiltinClassLoader.java|(0,0,<681,0>,<681,0>))
	at jdk.internal.loader.BuiltinClassLoader.loadClass(|unknown:///BuiltinClassLoader.java|(0,0,<639,0>,<639,0>))
	at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(|unknown:///ClassLoaders.java|(0,0,<188,0>,<188,0>))
	at java.lang.ClassLoader.loadClass(|unknown:///ClassLoader.java|(0,0,<520,0>,<520,0>))
	at java.lang.Class.getDeclaredConstructors0(|unknown:///Class.java|(0,0,<0,0>,<0,0>))
	at java.lang.Class.privateGetDeclaredConstructors(|unknown:///Class.java|(0,0,<3373,0>,<3373,0>))
	at java.lang.Class.getConstructor0(|unknown:///Class.java|(0,0,<3578,0>,<3578,0>))
	at java.lang.Class.getConstructor(|unknown:///Class.java|(0,0,<2271,0>,<2271,0>))
	at Proto.genEval(|unknown:///Proto.java|(0,0,<49,0>,<49,0>))
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
	at genEval(|prompt:///|(13,4,<1,13>,<1,17>)ok
rascal>:quit
)

The error does not appear when removing the decl part from the code above.

Null tests in Flybytes

In the ClassCompiler class, I found references to the Exp constructors null and nonnull, with the former having a check for getArity() == 0 to return a null expression in that case and a null check otherwise. However, in the syntax, the null() constructor always has an arity of 0 and the nonnull constructor does not exist.
Are these missing constructors in the syntax?

NullPointerException: Cannot read field "inputLocals" because "dstFrame" is null

I am trying to compile the following:

Method getAdd() {
    return staticMethod(\public(), string(), "add", [
        var(string(), "x")
    ], [
        \asm([LABEL("LALALA"), GOTO("STERF")]),
        \block([\return(load("x"))], label = "STERF"),
        \return(load("x"))
    ]);
}

I am messing around with labels (final goal: making a string switch). Compiling the above works fine if I remove the GOTO from the asm part. However, with the GOTO, I get the following error:

|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Compiler.rsc|(1637,272,<25,0>,<27,123>): Java(
  "RuntimeException",
  "java.lang.NullPointerException: Cannot read field \"inputLocals\" because \"dstFrame\" is null",
  Java("NullPointerException","Cannot read field \"inputLocals\" because \"dstFrame\" is null"))
	at lang.flybytes.internal.ClassCompiler.compileClass(|unknown:///ClassCompiler.java|(0,0,<109,0>,<109,0>))
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
	at compileClass(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Compiler.rsc|(1902,5,<27,116>,<27,121>))
	at $shell$(|prompt:///|(0,10,<1,0>,<1,10>)ok
rascal>

Am I doing something wrong, or is this a bug in Flybytes? The error is not very descriptive to me.

decompiling lambdas fails due to missing local variable declarations

This is a disassembled lambda where you can see that there are no LOCALVARIABLE instructions for stack location 0 and 1. This stops their LOAD instructions from being decompiled and that blocks further decompilation steps downstream.

My guess is that the creating scope is captured by the 0 and 1 stack locations in lambda's, and so we need to add rules for recovering expressions for these LOADs somehow.

methodDesc(
      void(),
      "lambda$11",
      [
        object("java.lang.Object"),
        object("java.lang.Object"),
        object("io.usethesource.vallang.IConstructor"),
        object("java.lang.Integer")
      ]),
    [
      var(
        object("java.lang.Object"),
        "arg_0"),
      var(
        object("java.lang.Object"),
        "arg_0"),
      var(
        object("io.usethesource.vallang.IConstructor"),
        "arg_0"),
      var(
        object("java.lang.Integer"),
        "arg_0")
    ],
    [asm([
          LABEL("L20804602"),
          LINENUMBER(589,"L20804602"),
          ALOAD(0),
          ALOAD(3),
          INVOKEVIRTUAL(
            object("java.lang.Integer"),
            methodDesc(
              integer(),
              "intValue",
              []),
            false),
          ALOAD(1),
          INVOKESTATIC(
            object("java.lang.reflect.Array"),
            methodDesc(
              void(),
              "set",
              [
                object("java.lang.Object"),
                integer(),
                object("java.lang.Object")
              ]),
            false),
          RETURN(),
          LABEL("L1344519051"),
          LOCALVARIABLE(
            "S",
            object("io.usethesource.vallang.IConstructor"),
            "L20804602",
            "L1344519051",
            2),
          LOCALVARIABLE(
            "ind",
            object("java.lang.Integer"),
            "L20804602",
            "L1344519051",
            3)
        ])])

flybytes compiled

when we have the Rascal compiler, we should invest in compiling and deploying the compiled code of flybytes

decompilation of null tests fails

an issue reported by Fransisco Handrick; this includes his examples files.

Lines 25, 26 and 27 in Bank.java trigger a problem, while the other code works fine.

Count.java:

package business;

public class Count {

	protected String     number;
    protected double    balance;
    protected String    name;
    
    void credit (double value) {
        balance = balance + value;
    }
    
    void debit (double value){
    	balance = balance - value;
    }
    
    public String getNumber() {return number;}
    public double getBalance() {return balance;}
    public String getName() {return  name;}
    
    public Count (String n, String na) {number = n; name = na; balance = 0;}
}

Bank.java:

package business;

public class Bank {
    public Count[] counts;
    public int index = 0;

    public void register(Count c) {
        counts[index] = c;
        index = index + 1;
    }
    
    public Count find(String n) {
        int i = 0;
        boolean find = false;
        while ((! find) && (i < index)) {
            if (counts[i].getNumber().equals(n)) find = true;
            else i = i + 1;
        }
        if (find == true) return counts[i];
        else return null;
    }
    public double balance(String num){
        Count c;
        c = this.find(num);
        //if (c != null)
        	return c.getBalance();
        //else
        //    return 0;
    }
    public void debit(String num, double val) {
        Count c;
        c = this.find(num);
        //if (c != null)
            c.debit(val);
        //else
           // System.out.println("ERROR");
    }
    public void credit(String num, double val) {
        Count c;
        c = this.find(num);
        //if (c != null)
            c.credit(val);
        //else
        //    System.out.println("ERROR");
    }
    public Bank() {
        counts=new Count[50];
    }
}

add SSA form to flybytes ASTs

  1. the definition of a format for representing SSA form
  2. the transformation of high-level flybytes to SSA form
  3. the transformation of SSA form down to JVM bytecodes

classpath is ignored in Compiler::loadClass and Compiler::loadClasses

  • this prevents testing generated classes which depend on third-party jars
  • it can be fixed using the SourceLocationClassloader class from the Rascal project, which turns a list of source locations to jar files and class folders into a ClassLoader instance.
  • Mirror::classMirror could also use a list[loc] classpath parameter with similar functionality.

many tests are failing after port to new IFunction API

[ERROR] testBreakNested: <5749,70>(lang.flybytes.tests.RunTests)  Time elapsed: 0.001 s  <<< ERROR!
org.rascalmpl.interpreter.staticErrors.UnsupportedOperation: 
A value of type Mirror (Signature method, list[Mirror] args) is not something you can call like a function, a constructor or a closure.
Advice: |http://tutor.rascal-mpl.org/Errors/Static/UnsupportedOperation/UnsupportedOperation.html|

roundtrip dissassemble/compile for |lib://rascal/org/rascalmpl/util/VersionInfo.class| fails with exception

rascal>compileClass(cl, |home:///test.class|)
io.usethesource.vallang.exceptions.UndeclaredFieldException: tuple[list[Type] formals] does not have a field with label name declared for it
        at io.usethesource.vallang.type.TupleTypeWithFieldNames.getFieldIndex(TupleTypeWithFieldNames.java:66)
        at io.usethesource.vallang.type.ConstructorType.getFieldIndex(ConstructorType.java:248)
        at io.usethesource.vallang.impl.persistent.Constructor$AbstractConstructor.get(Constructor.java:172)

the disassembled class:

class(object("org.rascalmpl.util.VersionInfo"),methods=[procedure(constructorDesc([]),[],[LABEL("L770815263"),LINENUMBER(3,"L770815263"),ALOAD(0),INVOKESPECIAL(object("java.lang.Object"),constructorDesc([]),false),RETURN(),LABEL("L1611169594"),LOCALVARIABLE("this",object("org.rascalmpl.util.VersionInfo"),"L770815263","L1611169594",0)])],fields=[field(string(),"RASCAL_VERSION",init=const(string(),"0.0.0"),modifiers={final(),static(),public()}),field(string(),"RASCAL_RUNTIME_VERSION",init=const(string(),"0.0.0"),modifiers={final(),static(),public()}),field(string(),"RASCAL_COMPILER_VERSION",init=const(string(),"0.0.0"),modifiers={final(),static(),public()})],interfaces=[],super=object("java.lang.Object"),modifiers={synchronized(),public()})

I suspect the INVOKESPECIAL is not implemented correctly for constructors in the compiler.

could use a simple peephole optimizer

If you look at what we generate for the FuncFactorial demo:

class(
  object("FuncFactorial"),
  methods=[
    method(
      methodDesc(
        integer(),
        "fact",
        [integer()]),
      [var(
          integer(),
          "n")],
      [asm([
            LABEL("L554752372"),
            LINENUMBER(1,"L554752372"),
            ILOAD(0),
            ICONST_1(),
            IF_ICMPGT("L82634714"),
            LABEL("L1444851469"),
            LINENUMBER(2,"L1444851469"),
            ICONST_1(),
            GOTO("L1932743161"),
            LABEL("L82634714"),
            LINENUMBER(4,"L82634714"),
            ILOAD(0),
            ILOAD(0),
            ICONST_1(),
            ISUB(),
            INVOKESTATIC(
              object("FuncFactorial"),
              methodDesc(
                integer(),
                "fact",
                [integer()]),
              false),
            IMUL(),
            LABEL("L1932743161"),
            LINENUMBER(1,"L1932743161"),
            IRETURN(),
            LABEL("L1422917010"),
            LOCALVARIABLE(
              "n",
              integer(),
              "L554752372",
              "L1422917010",
              0)
          ])]),
    method(
      methodDesc(
        integer(),
        "main",
        []),
      [],
      [asm([
            LABEL("L939397862"),
            LINENUMBER(7,"L939397862"),
            ICONST_4(),
            INVOKESTATIC(
              object("FuncFactorial"),
              methodDesc(
                integer(),
                "fact",
                [integer()]),
              false),
            IRETURN()
          ])]),
    method(
      methodDesc(
        void(),
        "main",
        [array(string())]),
      [var(
          array(string()),
          "args")],
      [asm([
            LABEL("L339453395"),
            LINENUMBER(1,"L339453395"),
            GETSTATIC(
              object("java.lang.System"),
              "out",
              object("java.io.PrintStream")),
            INVOKESTATIC(
              object("FuncFactorial"),
              methodDesc(
                integer(),
                "main",
                []),
              false),
            INVOKESTATIC(
              object("java.lang.Integer"),
              methodDesc(
                string(),
                "toString",
                [integer()]),
              false),
            INVOKEVIRTUAL(
              object("java.io.PrintStream"),
              methodDesc(
                void(),
                "println",
                [object("java.lang.Object")]),
              false),
            RETURN(),
            LABEL("L2104394292"),
            LOCALVARIABLE(
              "args",
              array(string()),
              "L339453395",
              "L2104394292",
              0)
          ])]),
    method(
      constructorDesc([]),
      [],
      [asm([
            LABEL("L1449579366"),
            ALOAD(0),
            INVOKESPECIAL(
              object("java.lang.Object"),
              constructorDesc([]),
              false),
            RETURN(),
            LABEL("L289964654"),
            LOCALVARIABLE(
              "this",
              object("FuncFactorial"),
              "L1449579366",
              "L289964654",
              0)
          ])])
  ],
  fields=[],
  interfaces=[],
  super=object("java.lang.Object"),
  modifiers={public()})

You see the consecutive ILOAD(0), ILOAD(0) which is much faster as ILOAD(0), DUP. A simple peephole optimizer in the back-end, written as a ASM visitor wrapper could do the trick.

increment operator in loop tests blocks decompilation of loops

For example, this loop is not recognized because the condition is not rewritten first to an expression, since it has side-effects with the x++. Special cases have to be detected for expressions with increment side-effects.

int whileWithContinue(int x) {
	    while (x++ < 10) { 
	        if (x % 2 == 0) {
	            continue;
	        }
	        else {
	            println(x);
	        }
        }
        
        return x;
	}

Bug: Error when decompiling method with one argument

I have compiled the following class with javac:

public class Test {

    public int test1() {
        return 3;
    }

    public int test2(int x) {
        return 5;
    }

}

When decompiling this using Flybytes (decompile from lang::flybytes::Decompiler), it throws an error:

|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Disassembler.rsc|(1465,237,<18,0>,<20,75>): Java("IndexOutOfBoundsException","Index 1 out of bounds for length 0")
	at jdk.internal.util.Preconditions.outOfBounds(|unknown:///Preconditions.java|(0,0,<64,0>,<64,0>))
	at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(|unknown:///Preconditions.java|(0,0,<70,0>,<70,0>))
	at jdk.internal.util.Preconditions.checkIndex(|unknown:///Preconditions.java|(0,0,<266,0>,<266,0>))
	at java.util.Objects.checkIndex(|unknown:///Objects.java|(0,0,<359,0>,<359,0>))
	at java.util.ArrayList.get(|unknown:///ArrayList.java|(0,0,<427,0>,<427,0>))
	at lang.flybytes.internal.ClassDisassembler.formals(|unknown:///ClassDisassembler.java|(0,0,<229,0>,<229,0>))
	at lang.flybytes.internal.ClassDisassembler.method(|unknown:///ClassDisassembler.java|(0,0,<205,0>,<205,0>))
	at lang.flybytes.internal.ClassDisassembler.methods(|unknown:///ClassDisassembler.java|(0,0,<178,0>,<178,0>))
	at lang.flybytes.internal.ClassDisassembler.readClass(|unknown:///ClassDisassembler.java|(0,0,<105,0>,<105,0>))
	at lang.flybytes.internal.ClassDisassembler.disassemble(|unknown:///ClassDisassembler.java|(0,0,<92,0>,<92,0>))
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
	at disassemble(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Disassembler.rsc|(1685,5,<20,58>,<20,63>))
	at $shell$(|prompt:///|(0,48,<1,0>,<1,48>)ok
rascal>

This happens whenever the class contains a method with exactly one argument. When I remove the method test2, or remove the argument x from test2, the class decompiles fine. When I add another argument to test2, such as int y, it also decompiles without errors. However, with one argument, it throws the above error. Since I would expect Flybytes to be able to decompile such a simple Java class, I am assuming that this is a bug.

Array with double as size; motivations for an intermediate AST type-checker

Got another error when trying to compile a class. This stuff is horrible to debug, but after messing around for a while I came up with a small example that can reproduce the error:

void compileTest() {
    loc l = |cwd:///src/main/rascal/Test.rsc|(314, 16, <18, 5>, <18, 21>);
    str  mcl = "io.usethesource.capsule.Map$Immutable";
    Class cl = class(
        object("Test"),
        modifiers = {\public(), \final()},
        methods = [
            main(
                "args",
                [
                    decl(double(), "i", init = dconst(0.)),
                    \while(
                        lt(
                            load("i"),
                            dconst(5.)
                        ),
                        [
                            decl(array(double()), "u", init = newArray(
                                array(double()),
                                dconst(3.)
                            ))
                        ]
                    ),
                    \return()
                ]
            )
        ],
        src=l
    );
    compileClass(cl, |cwd:///Test.class|);
}

The error does not occur when removing the while loop (moving the body of the while loop out of the loop). So the following program compiles without errors:

void compileTest() {
    loc l = |cwd:///src/main/rascal/Test.rsc|(314, 16, <18, 5>, <18, 21>);
    str  mcl = "io.usethesource.capsule.Map$Immutable";
    Class cl = class(
        object("Test"),
        modifiers = {\public(), \final()},
        methods = [
            main(
                "args",
                [
                    decl(array(double()), "u", init = newArray(
                        array(double()),
                        dconst(3.)
                    )),
                    \return()
                ]
            )
        ],
        src=l
    );
    compileClass(cl, |cwd:///Test.class|);
}

After my brain cells had recovered a bit from debugging, they discovered that this was an error on my side - Of course, using a double as array length (or index) is not possible, and an integer should be used. Using iconst instead worked.
What is weird, though, is that the decl in the loop gives the following error:

|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.2.0/flybytes-0.2.0.jar!/src/lang/flybytes/Compiler.rsc|(1637,272,<25,0>,<27,123>): Java("ArrayIndexOutOfBoundsException","")
	at compileClass(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.2.0/flybytes-0.2.0.jar!/src/lang/flybytes/Compiler.rsc|(1902,5,<27,116>,<27,121>))
	at $shell$(|prompt:///|(0,14,<1,0>,<1,14>)ok

However, the decl without loop in the second code snippet compiles fine, although it is equally as wrong as the first one. Why is this the case? Maybe this is not really a bug, but it is certainly weird, because it made me think that the loop itself was problematic, while that was not the case at all.

Second question: Would it be possible in any way to give more descriptive errors in situations like this? Something like "type double cannot be used for array size/index" or even a more general error like "integer expected, double given" would be much more useful than a Java ArrayIndexOutOfBoundsException with no Java stack trace.

Bug: Errors when compiling/decompiling arrays

I have the following module:

module Test

//imports

void compileTest() {
    Class cl = class(
        object("Test"),
        modifiers = {\public(), \final()},
        methods = [
            method(
                \public(),
                \void(),
                "test",
                [],
                [
                    \decl(
                        array(integer()),
                        "arr",
                        init = newInitArray(
                            array(integer()),
                            [
                                iconst(10),
                                iconst(20),
                                iconst(30)
                            ]
                        )
                    ),
                    \return()
                ]
            )
        ]
    );
    compileClass(cl, |cwd:///Test.class|);
}

Class decompileTest() {
    return decompile(|cwd:///Test.class|);
}

I have a simple method where I declare an array of integers and initialize it with the values 10, 20, 30. When calling compileTest, Flybytes gives the following error:

compileTest();
|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Compiler.rsc|(1637,272,<25,0>,<27,123>): Java(
  "RuntimeException",
  "java.lang.IllegalArgumentException: unknown expression: newInitArray(array(integer()),[const(integer(),10),const(integer(),20),const(integer(),30)])",
  Java("IllegalArgumentException","unknown expression: newInitArray(array(integer()),[const(integer(),10),const(integer(),20),const(integer(),30)])"))
	at lang.flybytes.internal.ClassCompiler.compileClass(|unknown:///ClassCompiler.java|(0,0,<109,0>,<109,0>))
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
	at compileClass(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Compiler.rsc|(1902,5,<27,116>,<27,121>))
	at $shell$(|prompt:///|(0,14,<1,0>,<1,14>)ok
rascal>import Test;

I have tried this with an int array and with a java.lang.Integer array. Both give this error.
When I change the array to simply initialize it without values, it compiles properly:

init = newArray(
    array(integer()),
    iconst(3)
)

However, when decompiling this, I get another error:

compileTest();
ok
rascal>decompileTest();
)
|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Disassembler.rsc|(1465,237,<18,0>,<20,75>): Java("ClassCastException","class org.objectweb.asm.tree.IntInsnNode cannot be cast to class org.objectweb.asm.tree.TypeInsnNode (org.objectweb.asm.tree.IntInsnNode and org.objectweb.asm.tree.TypeInsnNode are in unnamed module of loader \'app\')")
	at lang.flybytes.internal.ClassDisassembler.instruction(|unknown:///ClassDisassembler.java|(0,0,<588,0>,<588,0>))
	at lang.flybytes.internal.ClassDisassembler.instructions(|unknown:///ClassDisassembler.java|(0,0,<250,0>,<250,0>))
	at lang.flybytes.internal.ClassDisassembler.method(|unknown:///ClassDisassembler.java|(0,0,<190,0>,<190,0>))
	at lang.flybytes.internal.ClassDisassembler.methods(|unknown:///ClassDisassembler.java|(0,0,<178,0>,<178,0>))
	at lang.flybytes.internal.ClassDisassembler.readClass(|unknown:///ClassDisassembler.java|(0,0,<105,0>,<105,0>))
	at lang.flybytes.internal.ClassDisassembler.disassemble(|unknown:///ClassDisassembler.java|(0,0,<92,0>,<92,0>))
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(|unknown:///NativeMethodAccessorImpl.java|(0,0,<0,0>,<0,0>))
	at disassemble(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.7/flybytes-0.1.7.jar!/src/lang/flybytes/Disassembler.rsc|(1685,5,<20,58>,<20,63>))
	at decompileTest(|file:///Users/bys1/Documents/RUG/FBEG/flybytes-evalgen/src/main/rascal/Test.rsc|(920,31,<39,11>,<39,42>))
	at $shell$(|prompt:///|(0,16,<1,0>,<1,16>)ok

This error only happens with an int array. When I change the type to array(object("java.lang.Integer")), decompilation works fine. I think this error happens with arrays of primitive types only.

Issues with doubles

I have a big ass class that compiled fine with integers and starts spitting tons of errors after changing all integer types to doubles. The errors are very helpful (not), so I'm currently fighting a war with Flybytes to find out what's wrong.

I just produced the following small class that gives me an error:

void compileTest() {
    loc l = |cwd:///src/main/rascal/Test.rsc|(314, 16, <18, 5>, <18, 21>);
    str  mcl = "io.usethesource.capsule.Map$Immutable";
    Class cl = class(
        object("Test"),
        modifiers = {\public(), \final()},
        methods = [
            main(
                "args",
                [
                    decl(double(), "d", init = dconst(2.0)),
                    decl(integer(), "i", init = coerce(double(), integer(), load("d"))),
                    \return()
                ]
            )
        ],
        src=l
    );
    compileClass(cl, |cwd:///Test.class|);
}

I simply want to convert a double to an integer. The coerce doesn't seem to work:

|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.10/flybytes-0.1.10.jar!/src/lang/flybytes/Compiler.rsc|(1637,272,<25,0>,<27,123>): Java("NegativeArraySizeException","-2")
	at org.objectweb.asm.Frame.merge(|unknown:///Frame.java|(0,0,<1222,0>,<1222,0>))
	at org.objectweb.asm.MethodWriter.computeAllFrames(|unknown:///MethodWriter.java|(0,0,<1610,0>,<1610,0>))
	at org.objectweb.asm.MethodWriter.visitMaxs(|unknown:///MethodWriter.java|(0,0,<1546,0>,<1546,0>))
	at org.objectweb.asm.tree.MethodNode.accept(|unknown:///MethodNode.java|(0,0,<769,0>,<769,0>))
	at org.objectweb.asm.tree.MethodNode.accept(|unknown:///MethodNode.java|(0,0,<649,0>,<649,0>))
	at org.objectweb.asm.tree.ClassNode.accept(|unknown:///ClassNode.java|(0,0,<452,0>,<452,0>))
	at lang.flybytes.internal.ClassCompiler$Compile.compileClass(|unknown:///ClassCompiler.java|(0,0,<360,0>,<360,0>))
	at lang.flybytes.internal.ClassCompiler.compileClass(|unknown:///ClassCompiler.java|(0,0,<104,0>,<104,0>))
	at compileClass(|jar+file:///Users/bys1/.m2/repository/org/rascalmpl/flybytes/0.1.10/flybytes-0.1.10.jar!/src/lang/flybytes/Compiler.rsc|(1902,5,<27,116>,<27,121>))
	at $shell$(|prompt:///|(0,14,<1,0>,<1,14>)ok
rascal>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.