Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CLOSED] Investigate ways of wrapping array object #33

Closed
aionbot opened this issue Dec 4, 2018 · 12 comments
Closed

[CLOSED] Investigate ways of wrapping array object #33

aionbot opened this issue Dec 4, 2018 · 12 comments

Comments

@aionbot
Copy link

aionbot commented Dec 4, 2018

Issue created by yulongaion (on Wednesday May 16, 2018 at 20:52 GMT)

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by jeff-aion (on Thursday May 17, 2018 at 13:59 GMT)

To flesh out this problem, a little, this is related to the fact that all array types descent from java.lang.Object, meaning that this is another path outside of our shadow runtime.
For the most part, we could just replace the array interaction bytecodes with calls into a helper to unwrap and re-call them on the underlying object. This should work although it is a little on the tedious side and we would probably need to generate fake classes for all the different array types used within the contract to make sure that the signatures don't collide (since the same method name taking long[] or long[][] or Object are all technically different method signatures and can coexist in the same object).

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Friday May 18, 2018 at 14:42 GMT)

https://github.com/aionnetworkp/aion_vm/wiki/Array-Wrapping
Wiki page created for tracking

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Friday May 18, 2018 at 15:02 GMT)

I will start with dealing with static type. Then move on to generic.

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Friday May 18, 2018 at 15:46 GMT)

Refactored arraywrapping class into ArrayWrappingClassAdapter and ArrayWrappingMethodAdapter

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Friday May 18, 2018 at 18:15 GMT)

Primitive type array wrapping done, working on unit test.

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by romaion (on Tuesday May 22, 2018 at 16:18 GMT)

Just came across the issue: if you try to instrument the code below with arraywrapping

public int increaseFirstElement() {
        int[] arr = new int[20];

        arr.hashCode();

        boolean x = arr instanceof Object;
        testFun(arr);
        return arr[0];
    }

    public void testFun(int[] arg){
        arg[1]=1;
        arg.getClass();
    }

it would be:

public int increaseFirstElement() {
        int[] arr = IntArray.initArray(20);
        arr.hashCode();
        boolean x = arr instanceof Object;
        this.testFun((int[])arr);
        return arr.get(0);
    }

    public void testFun(int[] arg) {
        arg.set(1, 1);
        arg.getClass();
    }

Which is not compilable

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by romaion (on Tuesday May 22, 2018 at 16:20 GMT)

Another case, try:

public boolean testCharArray(){
        boolean res = true;
        int i = 0;

        //newarray for char
        char[] a = new char[2];
        char[] b = new char[64];
        char[] c = new char[1024];

        //CASTORE
        for (i = 0; i < 1024; i++){
            c[i] = (char)(i & 0xffff);;
        }

        //CALOAD
        for (i = 0; i < 1024; i++){
            res = res && (c[i] == (char)(i & 0xffff));
        }
        return res;
    }

And you will get:

  public boolean testCharArray() {
        boolean res = true;
        int i = false;
        char[] a = CharArray.initArray(2);
        char[] b = CharArray.initArray(64);
        char[] c = CharArray.initArray(1024);

        int i;
        for(i = 0; i < 1024; ++i) {
            c.set(i, (char)(i & '\uffff'));
        }

        for(i = 0; i < 1024; ++i) {
            res = res && c.get(i) == (char)(i & '\uffff');
        }

        return res;
    }

where int i=false; //wrong type

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Tuesday May 22, 2018 at 16:42 GMT)

@romaion We don't need the Java code to be compilable. JAVAC compilation is finished before our wrapping.

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by romaion (on Tuesday May 22, 2018 at 17:45 GMT)

Have you tried to load that code?

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by romaion (on Tuesday May 22, 2018 at 18:34 GMT)

StackWatcher#exitMethod() potentially can throw Exception. Why do you need that? If depth exceeds a limit it would already be checked on enterMethod() ?

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by romaion (on Tuesday May 22, 2018 at 18:35 GMT)

OutOfStackError is checked exception. They are extremely slow, why not to make it unchecked?

@aionbot
Copy link
Author

aionbot commented Dec 4, 2018

Comment by JunhanHu-aion (on Monday May 28, 2018 at 20:20 GMT)

https://github.com/aionnetworkp/aion_vm/commit/969033f37d7f73008ffe8e1f497c7e4e8923124f
1D primitive array wrapping delivered. 1D Object[] wrapping delivered. Now all array reference byte code are replaced, all descriptor with array are updated. (Beside invokedynamic)
Note that class generator is not done yet. Please avoid passing non primitive non java.lang.Object array into our pipeline.
Start working on array wrapping class generator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants