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

nullPointer while running test262 in non-interpreted mode #1074

Closed
p-bakker opened this issue Oct 22, 2021 · 14 comments · Fixed by #1553
Closed

nullPointer while running test262 in non-interpreted mode #1074

p-bakker opened this issue Oct 22, 2021 · 14 comments · Fixed by #1553
Labels
bug Issues considered a bug compilation Java Exception Leaking Issues related to Java Exceptions leaking into JavaScript test262 Issues related to passage of test262 TestSuite

Comments

@p-bakker
Copy link
Collaborator

This is a followup of #988, as one of th ementioned nullPointers wasn't fixed by #1073

org.mozilla.javascript.tests.Test262SuiteTest > test262Case[js=language\statements\for-of\dstr\array-elem-iter-thrw-close-err.js, opt=0, strict=false] STANDARD_ERROR
    java.lang.NullPointerException: Cannot invoke "org.mozilla.javascript.Node.getNext()" because "child" is null
        at org.mozilla.javascript.optimizer.BodyCodegen.visitStandardCall(BodyCodegen.java:2258)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:980)
        at org.mozilla.javascript.optimizer.BodyCodegen.visitSetElem(BodyCodegen.java:4072)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1393)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1084)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1089)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1089)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1084)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1089)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1089)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:823)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:643)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:643)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:659)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:643)
        at org.mozilla.javascript.optimizer.BodyCodegen.generateBodyCode(BodyCodegen.java:61)
        at org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:289)
        at org.mozilla.javascript.optimizer.Codegen.compileToClassFile(Codegen.java:175)
        at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:95)
        at org.mozilla.javascript.Context.compileImpl(Context.java:2368)
        at org.mozilla.javascript.Context.compileString(Context.java:1368)
        at org.mozilla.javascript.Context.compileString(Context.java:1356)
        at org.mozilla.javascript.tests.Test262SuiteTest.test262Case(Test262SuiteTest.java:509)
        at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        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.run(ParentRunner.java:413)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
        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:110)
        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:38)
        at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        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 com.sun.proxy.$Proxy5.processTestClass(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:121)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.base/java.lang.Thread.run(Thread.java:832)
@p-bakker p-bakker added bug Issues considered a bug test262 Issues related to passage of test262 TestSuite Java Exception Leaking Issues related to Java Exceptions leaking into JavaScript compilation labels Oct 22, 2021
@gbrail
Copy link
Collaborator

gbrail commented Oct 25, 2021

I did some initial investigation and this one isn't a simple fix. The code generator is getting into a bad state. It shouldn't be too hard to turn the NullPointerException into some exception that can be caught in JavaScript code, but anything else will take some deeper changes.

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 1, 2024

Examples of JS code that throws exceptions:
for ([ {}[''] ] of [[1,2,3]]) {}
for ([ {}[(function(){})()] ] of [[1,2,3]]) {}
for ([ {}[new Error()] ] of [[1,2,3]]) {}
for ([ {}[Date.now()] ] of ['test']) {}

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 1, 2024

Would be very nice to get rid of this nullPointer, because then we can uncomment the printing of unexpected exceptions in the test262TestSuite, so things like this become more obvious

@p-bakker
Copy link
Collaborator Author

@tuchida just wondering: you've been fixing a bunch of internal errors to be properly handled the last couple of days. Would this one be up your alley as well?

If we'd be able to fix this one, we could enable the printing of unexpected exceptions in the Test262 TestSuite runner, as to get earlier feedback if something is amiss

@tuchida
Copy link
Contributor

tuchida commented Jul 23, 2024

ref. #1187, fbcbb5a
I probably fixed it with this.

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 23, 2024

Does seem like this exact nullPointer is gone now!

But now seeing this one, but only on language\expressions\object\accessor-name-computed-yield-expr

java.lang.NullPointerException: Cannot invoke "java.util.List.indexOf(Object)" because the return value of "org.mozilla.javascript.ast.FunctionNode.getResumptionPoints()" is null
	at org.mozilla.javascript.optimizer.BodyCodegen.getNextGeneratorState(BodyCodegen.java:962)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateLocalYieldPoint(BodyCodegen.java:1749)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateYieldPoint(BodyCodegen.java:1710)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1619)
	at org.mozilla.javascript.optimizer.BodyCodegen.addLoadPropertyId(BodyCodegen.java:2179)
	at org.mozilla.javascript.optimizer.BodyCodegen.addLoadProperty(BodyCodegen.java:2102)
	at org.mozilla.javascript.optimizer.BodyCodegen.visitObjectLiteral(BodyCodegen.java:2225)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1150)
	at org.mozilla.javascript.optimizer.BodyCodegen.visitStrictSetName(BodyCodegen.java:3899)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateExpression(BodyCodegen.java:1408)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:853)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateStatement(BodyCodegen.java:666)
	at org.mozilla.javascript.optimizer.BodyCodegen.generateBodyCode(BodyCodegen.java:61)
	at org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:289)
	at org.mozilla.javascript.optimizer.Codegen.compileToClassFile(Codegen.java:175)
	at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:95)
	at org.mozilla.javascript.Context.compileImpl(Context.java:2458)
	at org.mozilla.javascript.Context.compileString(Context.java:1406)
	at org.mozilla.javascript.Context.compileString(Context.java:1394)

@tuchida
Copy link
Contributor

tuchida commented Jul 23, 2024

I haven't looked at it too closely, but this fixed the nullPointer.
I also fixed Node.toString because I also got an error when I set Token.printTrees to true.

diff --git a/rhino/src/main/java/org/mozilla/javascript/Node.java b/rhino/src/main/java/org/mozilla/javascript/Node.java
index 49a30d8..e8c2b5a 100644
--- a/rhino/src/main/java/org/mozilla/javascript/Node.java
+++ b/rhino/src/main/java/org/mozilla/javascript/Node.java
@@ -1165,11 +1165,16 @@ public class Node implements Iterable<Node> {
                         }
                         break;
                     case OBJECT_IDS_PROP:
+                    case OBJECT_IDS_COMPUTED_PROP:
                         {
                             Object[] a = (Object[]) x.objectValue;
                             sb.append("[");
                             for (int i = 0; i < a.length; i++) {
-                                sb.append(a[i].toString());
+                                if (a[i] != null) {
+                                    sb.append(a[i].toString());
+                                } else {
+                                    sb.append("null");
+                                }
                                 if (i + 1 < a.length) sb.append(", ");
                             }
                             sb.append("]");
diff --git a/rhino/src/main/java/org/mozilla/javascript/NodeTransformer.java b/rhino/src/main/java/org/mozilla/javascript/NodeTransformer.java
index 8b73b09..a787d11 100644
--- a/rhino/src/main/java/org/mozilla/javascript/NodeTransformer.java
+++ b/rhino/src/main/java/org/mozilla/javascript/NodeTransformer.java
@@ -389,6 +389,23 @@ public class NodeTransformer {
                         }
                         break;
                     }
+
+                case Token.OBJECTLIT:
+                    {
+                        Object[] computedPropertyIds =
+                                (Object[]) node.getProp(Node.OBJECT_IDS_COMPUTED_PROP);
+                        if (computedPropertyIds != null) {
+                            for (Object computedPropertyId : computedPropertyIds) {
+                                if (computedPropertyId == null) continue;
+                                transformCompilationUnit_r(
+                                        tree,
+                                        (Node) computedPropertyId,
+                                        node instanceof Scope ? (Scope) node : scope,
+                                        createScopeObjects,
+                                        inStrictMode);
+                            }
+                        }
+                    }
             }
 
             transformCompilationUnit_r(
diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties
index ff092f3..7c36334 100644
--- a/tests/testsrc/test262.properties
+++ b/tests/testsrc/test262.properties
@@ -4279,7 +4279,7 @@ language/expressions/new 41/59 (69.49%)
 
 ~language/expressions/new.target
 
-language/expressions/object 818/1081 (75.67%)
+language/expressions/object 817/1081 (75.58%)
     dstr/async-gen-meth-ary-init-iter-close.js {unsupported: [async-iteration, async]}
     dstr/async-gen-meth-ary-init-iter-get-err.js {unsupported: [async-iteration]}
     dstr/async-gen-meth-ary-init-iter-get-err-array-prototype.js {unsupported: [async-iteration]}
@@ -5037,7 +5037,6 @@ language/expressions/object 818/1081 (75.67%)
     __proto__-permitted-dup.js {unsupported: [async-iteration, async-functions]}
     __proto__-permitted-dup-shorthand.js
     accessor-name-computed-in.js
-    accessor-name-computed-yield-expr.js non-interpreted
     accessor-name-computed-yield-id.js non-strict
     accessor-name-literal-numeric-binary.js {strict: [-1], non-strict: [-1]}
     accessor-name-literal-numeric-exponent.js {strict: [-1], non-strict: [-1]}

@p-bakker
Copy link
Collaborator Author

Great work @tuchida

Are you gonna put this up as a PR?

@tuchida
Copy link
Contributor

tuchida commented Jul 24, 2024

@p-bakker If you see this as a Computed Properties issue, I would like to think about it in more detail.

If we'd be able to fix this one, we could enable the printing of unexpected exceptions in the Test262 TestSuite runner, as to get earlier feedback if something is amiss

I am interested in this. If you need to fix for this, feel to use the diff.

@p-bakker
Copy link
Collaborator Author

If you see this as a Computed Properties issue, I would like to think about it in more detail.

Not exactly sure what you mean by that, I'm afraid.

The test that currently throws the nullPointer didn't seem to use computed properties, but computed assessor using yield as namen inside a generator function. Whether that falls under 'Computer Priperties' I'm not sure

@tuchida
Copy link
Contributor

tuchida commented Jul 24, 2024

The test that currently throws the nullPointer

How can I check this? Did you make any changes to Test262SuiteTest.java when you checked #1074 (comment)?

@p-bakker
Copy link
Collaborator Author

I just ran the Test262 Test Suite on the latest master, containing you other fixes. Note that this new nullPointer only happens in non-interpreted mode

@tuchida
Copy link
Contributor

tuchida commented Jul 25, 2024

@p-bakker What is the goal of this issue? If it is just a problem with accessor-name-computed-yield-expr.js, the comment will fix it. However, it does not guarantee that Test262SuiteTest will not raise a NullPointerException.

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 31, 2024

@tuchida if I run the full Ttest262 suite, the only test that throws this nullPoiter is the accessor-name-computed-yield-expr.js test in non-interpreted mode.

With your patch applied, the nullPointer guess away and the test passed.

To see the nullPointer when running the test262 testsuite, uncomment this line

The goal in eliminating the nullPointer, making the test pass.

If you think there are other ways to trigger the nullPointer, but that existing tests just don't hit that scenario, I'd still think it's preferred to fix it as just for the currently broken test and then make a follow-up case with a failing testcase to fix afterwards

Makes sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issues considered a bug compilation Java Exception Leaking Issues related to Java Exceptions leaking into JavaScript test262 Issues related to passage of test262 TestSuite
Projects
None yet
3 participants