Giter VIP home page Giter VIP logo

Comments (19)

cyrille-artho avatar cyrille-artho commented on August 30, 2024

To throw an exception back to the caller (at JPF level), use env.ThrowException(String, String), the first string being the exception type, the second one the exception message.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Therefore, we want:

A unit test that calls findVarHandle with valid arguments (looking up an instance variable).
A unit test that calls findVarHandle with invalid arguments (looking up a static variable that exists with the specified name).
A unit test that calls findVarHandle with invalid arguments (no variable with a given name exists).

Below is the code :

package gov.nasa.jpf.test.java.concurrent;

import gov.nasa.jpf.util.test.TestJPF;
import org.junit.Test;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;

public class FindVarHandleTests extends TestJPF {
    static class TestClass {
        public int instanceField;
        public static int staticField;
    }

    @Test
    void testFindVarHandleInstanceField() throws NoSuchFieldException, IllegalAccessException {
        VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "instanceField", int.class);
        assertNotNull(handle);
    }

    @Test
    void testFindVarHandleStaticField() throws NoSuchFieldException, IllegalAccessException  {
        VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "staticField", int.class);
        assertNotNull(handle);
    }

    @Test
    void testFindVarHandleNoSuchField() throws NoSuchFieldException, IllegalAccessException  {
        VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "nonExistingField", int.class);
        assertNotNull(handle);
    }
}

But when we ran this test, from command line using ./gradlew clean test, it's not included in tests. Including there should be 1005 tests.
Running them independently we found error like below :

> Task :compileAnnotationsJava UP-TO-DATE
> Task :processAnnotationsResources NO-SOURCE
> Task :annotationsClasses UP-TO-DATE
> Task :copyLibs UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :generateBuildInfo
> Task :generateVersion
> Task :copyResources
> Task :compileExamplesJava UP-TO-DATE
> Task :compileClassesJava UP-TO-DATE
> Task :processClassesResources NO-SOURCE
> Task :classesClasses UP-TO-DATE
> Task :compilePeersJava UP-TO-DATE
> Task :processPeersResources NO-SOURCE
> Task :peersClasses UP-TO-DATE
> Task :compileTestJava UP-TO-DATE
> Task :compileModules UP-TO-DATE
> Task :compile UP-TO-DATE
> Task :createAnnotationsJar UP-TO-DATE
> Task :createClassloaderSpecificTestsJar UP-TO-DATE
> Task :createJpfClassesJar UP-TO-DATE
> Task :createJpfJar
> Task :createRunJpfJar UP-TO-DATE
> Task :createRunTestJar UP-TO-DATE
> Task :buildJars
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test FAILED
Test Execution: SUCCESS
Summary: 0 tests, 0 passed, 0 failed, 0 skipped
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> No tests found for given includes: [**/*Test.class](include rules) [**/SplitInputStreamTest.class, **/JPF_*.class](exclude rules) [gov.nasa.jpf.test.java.concurrent.FindVarHandleTests](--tests filter)
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Get more help at https://help.gradle.org.
BUILD FAILED in 1s
18 actionable tasks: 5 executed, 13 up-to-date

"Is there any mechanism to register our test?"

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Thanks. You need to encapsulate the code under test with if (verifyNoPropertyViolation(...)) or if (verifyUnhandledException(...)) to run the code in JPF and to check if no exception occurs in the successful case or the right exception occurs with invalid parameters:

https://github.com/javapathfinder/jpf-core/wiki/Writing-JPF-tests

I expect some of the tests to fail with the current version of JPF.

Not sure why no tests are found by Gradle, that's a different problem that is not easy to investigate without running the code locally.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

"You need to encapsulate the code under test with if (verifyNoPropertyViolation(...)) or if (verifyUnhandledException(...)) to run the code in JPF and to check if no exception occurs in the successful case or the right exception occurs with invalid parameters" -----> The problem remains the same. Still tests are not found by Gradle.

Link to produce result locally.
https://github.com/eklaDFF/jpf-core/tree/MethodHandlesBRANCH.

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Your test methods are package-private. Make sure they are public. The class name should also end with Test, not Tests. Finally, the test functions should not throw exceptions: By using verifyUnhandledException(), you instead use the right exception type to /ensure/ it occurs (and the test is supposed to fail if no exception or the wrong exception occurs).

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

UPDATE :

  1. Your test methods are package-private. Make sure they are public. -----> now they are public.
  2. The class name should also end with Test, not Tests. -----> now changed to FindVarHandleTest

Here is the code,

public class FindVarHandleTest extends TestJPF {
    static class TestClass {
        public int instanceField;
        public static int staticField;
    }

    @Test
    public void testFindVarHandleInstanceField() throws NoSuchFieldException, IllegalAccessException {
        if (verifyNoPropertyViolation()){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "instanceField", int.class);
            assertNotNull(handle);
        }
    }

    @Test
    public void testFindVarHandleStaticField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyNoPropertyViolation()){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "staticField", int.class);
            assertNotNull(handle);
        }
    }

    @Test
    public void testFindVarHandleNoSuchField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyNoPropertyViolation()){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "notExistingField", int.class);
            assertNotNull(handle);
        }
    }
}

Here, only third test testFindVarHandleNoSuchField() fails as it was supposed to do.

Is this in right direction ? So that we could move ahead to implement these tests for findStaticVarHandle.


Finally, the test functions should not throw exceptions: By using verifyUnhandledException(), you instead use the right exception type to /ensure/ it occurs (and the test is supposed to fail if no exception or the wrong exception occurs).

????

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Yes, and the third test should fail with NoSuchFieldException. The test method itself should not throw an exception; instead, verifyUnhandledException() should check it. (It is possible that the method still needs to be declared as potentially throwing an exception.)

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Are you talking about implementing verifyUnhandledException() in those three tests ? I mean, do we have to encapsulate the tests in this including verifyNoPropertyViolation() ?

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

See the wiki page I linked to above. We use verifyUnhandledException() if we expect a specific exception, instead of verifyNoPropertyViolation(). The last test accesses a non-existent field and thus should throw an exception.

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

With the tests (in your stash) now working as intended, you can work on fixing the exception behavior in the native peer of MethodHandles, in src/peers/gov/nasa/jpf/vm/JPF_java_lang_invoke_MethodHandles.java:
In the native peer of findVarHandle, in findVarHandle__Ljava_lang_Class_2Ljava_lang_String_2Ljava_lang_Class_2__Ljava_lang_invoke_VarHandle_2, there are several incorrect behaviors:

  1. A static field is accepted (and found and returned).
  2. If a field is not found, the exception should be thrown at the SUT level, not inside JPF:
env.throwException(NoSuchFieldException.class.getName(), "Field not found");

(This is if the last attempt to get a valid fi fails and fi == null in the second such if statement.)
The current code has a better exception message string, so I suggest using that message string instead of the one above.

You can:

  1. Ensure that the exceptions are thrown correctly (visible to the SUT/unit test).
  2. Once all three tests for findVarHandle pass, you can apply the same tests to findStaticVarHandle. The outcomes will be slightly different: an instance field lookup should fail (with IllegalAccessException), the static field lookup should succeed, and the non-existent field lookup is the same. Refactor the code into two variants, one for instance fields and one for static fields.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Hi, @cyrille-artho and @pparizek
Here is how I have improved the findVarHandle for Instance Variable only :

@MJI
    public int
    findVarHandle__Ljava_lang_Class_2Ljava_lang_String_2Ljava_lang_Class_2__Ljava_lang_invoke_VarHandle_2(
        MJIEnv env, int objRef, int classRef, int stringRef, int typeRef) {
      ClassInfo ci = env.getClassInfo(classRef);
      int nameCls = env.getReferenceField(classRef, "name");
      String clsName = env.getStringObject(nameCls);
      ci = env.getSystemClassLoaderInfo().loadClass(clsName);
      int nameType = env.getReferenceField(typeRef, "name");
      String typeName = env.getStringObject(nameType);
      String varName = env.getStringObject(stringRef);
//      FieldInfo fi = ci.getStaticField(varName);
//      if (fi == null) {
//        fi = ci.getInstanceField(varName);
//      }
      FieldInfo fi = ci.getInstanceField(varName);
      if (fi == null) {
        env.throwException(NoSuchFieldException.class.getName(), "Field not found");
      }
      int jpfFieldVarHandle = env.newObject("java.base$&$java.lang.invoke.JPFFieldVarHandle");
      env.setIntField(jpfFieldVarHandle, "fieldRef", fi.getFieldIndex());
      env.setIntField(jpfFieldVarHandle, "classRef", classRef);
      return jpfFieldVarHandle;
    }
  1. In case of static field testing, error is like below (important section) :
Caused by: java.lang.NullPointerException: Cannot invoke "gov.nasa.jpf.vm.FieldInfo.getFieldIndex()" because "fi" is null
	at gov.nasa.jpf.vm.JPF_java_lang_invoke_MethodHandles$Lookup

What's happening actually is that FieldInfo fi = ci.getInstanceField(varName); is null in this case (fi is null) which is obvious.

and then in env.setIntField(jpfFieldVarHandle, "fieldRef", fi.getFieldIndex());, fi.getFieldIndex() is being called.

  1. For Non-Existing Instance Field, the error is same as with static Fields. And it is also obvious.

So the here the next issue is, if fi == null then env.throwException(NoSuchFieldException.class.getName(), "Field not found");. Then why our programs gets executed after that in the same block ? How should we return the VarHandle Object in this case ?

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

You are right, the call to throwException should be followed up by return MJIEnv.NULL; to exit the function.
Also, please change "Field not found" to "Cannot find field: " + varName + " on class: " + clsName, so in case this exception occurs, the message is a bit more informative.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

This test also passed :

@Test
    public void testFindVarHandleNoSuchField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyUnhandledException("java.lang.NoSuchFieldException")){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "notExistingField", int.class);
            assertNotNull(handle);
        }
    }

Output :

====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.NoSuchFieldException: Cannot find field: notExistingField on class: gov.nasa.jpf.test.java.concurrent.FindVarHandleTest$TestClass
	at java.lang.invoke.MethodHandles$Lookup.findVarHandle(gov.nasa.jpf.vm.JPF_java_lang_invoke_MethodHandles$Lookup)
	at gov.nasa.jpf.test.java.concurrent.FindVarHandleTest.testFindVarHandleNoSuchField(FindVarHandleTest.java:34)
	at java.lang.reflect.Method.invoke(gov.nasa.jpf.vm.JPF_java_lang_reflect_Method)
	at gov.nasa.jpf.util.test.TestJPF.runTestMethod(TestJPF.java:648)


====================================================== snapshot #1
thread java.lang.Thread:{id:0,name:main,status:RUNNING,priority:5,isDaemon:false,lockCount:0,suspendCount:0}
  call stack:
	at gov.nasa.jpf.util.test.TestJPF.runTestMethod(TestJPF.java:650)


====================================================== results
error #1: gov.nasa.jpf.vm.NoUncaughtExceptionsProperty "java.lang.NoSuchFieldException: Cannot find field:..."

====================================================== search finished: 19/07/24, 4:44 pm
> Task :test
gov.nasa.jpf.test.java.concurrent.FindVarHandleTest > testFindVarHandleNoSuchField PASSED
Test Execution: SUCCESS
Summary: 1 tests, 1 passed, 0 failed, 0 skipped
BUILD SUCCESSFUL in 1s
18 actionable tasks: 5 executed, 13 up-to-date
4:44:07 pm: Execution finished ':test --tests "gov.nasa.jpf.test.java.concurrent.FindVarHandleTest.testFindVarHandleNoSuchField"'.

But, this one failed :

@Test
    public void testFindVarHandleStaticField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyUnhandledException("java.lang.IllegalAccessException")){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "staticField", int.class);
            assertNotNull(handle);
        }
    }

Output :

====================================================== error 1
gov.nasa.jpf.vm.NoUncaughtExceptionsProperty
java.lang.NoSuchFieldException: Cannot find field: staticField on class: gov.nasa.jpf.test.java.concurrent.FindVarHandleTest$TestClass
	at java.lang.invoke.MethodHandles$Lookup.findVarHandle(gov.nasa.jpf.vm.JPF_java_lang_invoke_MethodHandles$Lookup)
	at gov.nasa.jpf.test.java.concurrent.FindVarHandleTest.testFindVarHandleStaticField(FindVarHandleTest.java:26)
	at java.lang.reflect.Method.invoke(gov.nasa.jpf.vm.JPF_java_lang_reflect_Method)
	at gov.nasa.jpf.util.test.TestJPF.runTestMethod(TestJPF.java:648)


====================================================== snapshot #1
thread java.lang.Thread:{id:0,name:main,status:RUNNING,priority:5,isDaemon:false,lockCount:0,suspendCount:0}
  call stack:
	at gov.nasa.jpf.util.test.TestJPF.runTestMethod(TestJPF.java:650)


====================================================== results
error #1: gov.nasa.jpf.vm.NoUncaughtExceptionsProperty "java.lang.NoSuchFieldException: Cannot find field:..."

====================================================== search finished: 19/07/24, 4:46 pm

java.lang.AssertionError: JPF caught wrong exception: java.lang.NoSuchFieldException, expected: java.lang.IllegalAccessException
	at gov.nasa.jpf.util.test.TestJPF.fail(TestJPF.java:164)
	at gov.nasa.jpf.util.test.TestJPF.unhandledException(TestJPF.java:863)
	at gov.nasa.jpf.util.test.TestJPF.verifyUnhandledException(TestJPF.java:903)
	at gov.nasa.jpf.test.java.concurrent.FindVarHandleTest.testFindVarHandleStaticField(FindVarHandleTest.java:25)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:112)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:40)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:60)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)


> Task :test FAILED
gov.nasa.jpf.test.java.concurrent.FindVarHandleTest > testFindVarHandleStaticField FAILED
    java.lang.AssertionError at FindVarHandleTest.java:25
Test Execution: FAILURE
Summary: 1 tests, 0 passed, 1 failed, 0 skipped
1 test completed, 1 failed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/ekla/GSOC/JPFjava17/jpf-core/build/reports/tests/test/index.html
BUILD FAILED in 1s
18 actionable tasks: 5 executed, 13 up-to-date

From above error stack, it is showing that it caught wrong exception ?

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Yes, the test is written correctly, but the implementation currently does not check if a static field with the same name exists. In that case (in the code that's currently commented out), IllegalAccessException should be thrown (with env.throw followed by return MJI.null).

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

New modified code :

@MJI
    public int
    findVarHandle__Ljava_lang_Class_2Ljava_lang_String_2Ljava_lang_Class_2__Ljava_lang_invoke_VarHandle_2(
        MJIEnv env, int objRef, int classRef, int stringRef, int typeRef) {
      ClassInfo ci = env.getClassInfo(classRef);
      int nameCls = env.getReferenceField(classRef, "name");
      String clsName = env.getStringObject(nameCls);
      ci = env.getSystemClassLoaderInfo().loadClass(clsName);
      int nameType = env.getReferenceField(typeRef, "name");
      String typeName = env.getStringObject(nameType);
      String varName = env.getStringObject(stringRef);
      
      // Checking access to static field, if found we will throw IllegalAccessException
      FieldInfo fi = ci.getStaticField(varName);
      if (fi != null) {
        env.throwException(IllegalAccessException.class.getName(), "Cannot access field: " + varName + " on class: " + clsName);
        return MJIEnv.NULL;
      }
      
      fi = ci.getInstanceField(varName);
      if (fi == null) {
        env.throwException(NoSuchFieldException.class.getName(), "Cannot find field: " + varName + " on class: " + clsName);
        return MJIEnv.NULL;
      }
      int jpfFieldVarHandle = env.newObject("java.base$&$java.lang.invoke.JPFFieldVarHandle");
      env.setIntField(jpfFieldVarHandle, "fieldRef", fi.getFieldIndex());
      env.setIntField(jpfFieldVarHandle, "classRef", classRef);
      return jpfFieldVarHandle;
    }

Now all those three test passes with correct Exceptions .

Now I am going to implement for static counterpart .

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

Implementation for static counterpart

Here is the Tests (last 3 Tests are to test static ones) :

public class FindVarHandleTest extends TestJPF {
    static class TestClass {
        public int instanceField;
        public static int staticField;
    }

    @Test
    public void testFindVarHandleInstanceField() throws NoSuchFieldException, IllegalAccessException {
        if (verifyNoPropertyViolation()){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "instanceField", int.class);
            assertNotNull(handle);
        }
    }

    @Test
    public void testFindVarHandleStaticField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyUnhandledException("java.lang.IllegalAccessException")){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "staticField", int.class);
            assertNotNull(handle);
        }
    }

    @Test
    public void testFindVarHandleNoSuchField() throws NoSuchFieldException, IllegalAccessException  {
        if (verifyUnhandledException("java.lang.NoSuchFieldException")){
            VarHandle handle = MethodHandles.lookup().findVarHandle(TestClass.class, "notExistingField", int.class);
            assertNotNull(handle);
        }
    }

    @Test
    public void testFindStaticVarHandleInstanceField() throws NoSuchFieldException, IllegalAccessException {
        if (verifyUnhandledException("java.lang.IllegalAccessException")){
            VarHandle handle = MethodHandles.lookup().findStaticVarHandle(TestClass.class, "instanceField", int.class);
            assertNotNull(handle);
        }
    }


    @Test
    public void testFindStaticVarHandleStaticField() throws NoSuchFieldException, IllegalAccessException {
        if (verifyNoPropertyViolation()){
            VarHandle handle = MethodHandles.lookup().findStaticVarHandle(TestClass.class, "staticField", int.class);
            assertNotNull(handle);
        }
    }


    @Test
    public void testFindStaticVarHandleNoSuchField() throws NoSuchFieldException, IllegalAccessException {
        if (verifyUnhandledException("java.lang.NoSuchFieldException")){
            VarHandle handle = MethodHandles.lookup().findStaticVarHandle(TestClass.class, "notExistingField", int.class);
            assertNotNull(handle);
        }
    }
}

And here is the implementation for findStaticVarHandle__Ljava_lang_Class_2Ljava_lang_String_2Ljava_lang_Class_2__Ljava_lang_invoke_VarHandle_2(){.......} :

@MJI
    public int
    findStaticVarHandle__Ljava_lang_Class_2Ljava_lang_String_2Ljava_lang_Class_2__Ljava_lang_invoke_VarHandle_2(
            MJIEnv env, int objRef, int classRef, int stringRef, int typeRef) {
      ClassInfo ci = env.getClassInfo(classRef);
      int nameCls = env.getReferenceField(classRef, "name");
      String clsName = env.getStringObject(nameCls);
      ci = env.getSystemClassLoaderInfo().loadClass(clsName);
      int nameType = env.getReferenceField(typeRef, "name");
      String typeName = env.getStringObject(nameType);
      String varName = env.getStringObject(stringRef);

      // Checking access to non-static field, if found we will throw IllegalAccessException
      FieldInfo fi = ci.getInstanceField(varName);
      if (fi != null) {
        env.throwException(IllegalAccessException.class.getName(), "Cannot access field: " + varName + " on class: " + clsName);
        return MJIEnv.NULL;
      }

      fi = ci.getStaticField(varName);
      if (fi == null) {
        env.throwException(NoSuchFieldException.class.getName(), "Cannot find field: " + varName + " on class: " + clsName);
        return MJIEnv.NULL;
      }
      int jpfFieldVarHandle = env.newObject("java.base$&$java.lang.invoke.JPFFieldVarHandle");
      env.setIntField(jpfFieldVarHandle, "fieldRef", fi.getFieldIndex());
      env.setIntField(jpfFieldVarHandle, "classRef", classRef);
      return jpfFieldVarHandle;
    }

Implementing this (findStaticVarHandle) helped us to avoid MethodHandleNatives....

ALL OF 6 TESTS PASSED

After it's implementation, I ran './gradlew clean test` to ensure non of other tests got effected anyway.

Next sort of error, I am going to mention in issue #470

from jpf-core.

cyrille-artho avatar cyrille-artho commented on August 30, 2024

Looks good! I would change the exception message "Cannot access field: " for the case where static/non-static access is mismatched with the variable. Such as "Cannot access static field: " ... "on class" ... " as instance field" for findStaticVarHandle, and "Cannot access instance field: " ... "on class" ... " as static field" for findVarHandle.

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

I will change it before creating PR

from jpf-core.

eklaDFF avatar eklaDFF commented on August 30, 2024

@cyrille-artho Close this issue too. It was related to PR #478

from jpf-core.

Related Issues (20)

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.