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

ArrayStoreException for delegating object/function proxy #36

Closed
provegard opened this issue Aug 14, 2018 · 4 comments
Closed

ArrayStoreException for delegating object/function proxy #36

provegard opened this issue Aug 14, 2018 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@provegard
Copy link

In my Nashorn application, I have a piece of code that accepts a JavaScript function that comes from Jasmine (it's a spy function). The code creates a wrapper that delegates function execution as well as member access. The purpose is to process the return value of the spy function so that it mimics the "real world".

While converting this code to GraalJS, I ran into a problem - I get ArrayStoreException. I have created a minimal example that reproduces the problem.

My delegating function looks like this:

public class DelegatingFunction implements ProxyObject, ProxyExecutable {
    private final Value delegee;

    public DelegatingFunction(Value delegee) {
        this.delegee = delegee;
    }

    public Object execute(Value... arguments) {
        return delegee.execute(arguments);
    }

    public Object getMember(String key) {
        return delegee.getMember(key);
    }

    public Object getMemberKeys() {
        return delegee.getMemberKeys();
    }

    public boolean hasMember(String key) {
        return delegee.hasMember(key);
    }

    public void putMember(String key, Value value) {
        delegee.putMember(key, value);
    }

    public boolean removeMember(String key) {
        return delegee.removeMember(key);
    }
}

(It delegates member access since the spy function has identification properties.)

And my test code looks like this:

public class DelegatingFunctionTest {
    public static void main(String[] args) {
        Context context = Context.create("js");
        Value bindings = context.getBindings("js");


        bindings.putMember("main", new DelegatingFunctionTest());

        String src = "var original = function (arg) { print(arg); };\n" +
                "var wrapper = main.wrap(original);\n" +
                "wrapper('test');";
        context.eval("js", src);
    }

    public Object wrap(Value function) {
        assert function.canExecute() : "Not a function";
        return new DelegatingFunction(function);
    }
}

The error I get is:

Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.ArrayStoreException: java.lang.String
	at com.oracle.truffle.api.vm.PolyglotLanguageContext$ToGuestValuesNode.fastToGuestValuesUnroll(PolyglotLanguageContext.java:479)
	at com.oracle.truffle.api.vm.PolyglotLanguageContext$ToGuestValuesNode.apply(PolyglotLanguageContext.java:450)
	at com.oracle.truffle.api.vm.PolyglotValue$Interop$AbstractExecuteNode.executeShared(PolyglotValue.java:2166)
	at com.oracle.truffle.api.vm.PolyglotValue$Interop$ExecuteNode.executeImpl(PolyglotValue.java:2248)
	at com.oracle.truffle.api.vm.PolyglotValue$PolyglotNode.execute(PolyglotValue.java:551)
	at org.graalvm.polyglot.Value.execute(Value.java:312)
	at com.programmaticallyspeaking.gho.DelegatingFunction.execute(DelegatingFunction.java:16)
	at <js> :program(Unnamed:3:82-96)
	at org.graalvm.polyglot.Context.eval(Context.java:336)
	at com.programmaticallyspeaking.gho.DelegatingFunctionTest.main(DelegatingFunctionTest.java:17)
Original Internal Error: 
java.lang.ArrayStoreException: java.lang.String
	at com.oracle.truffle.api.vm.PolyglotLanguageContext$ToGuestValuesNode.fastToGuestValuesUnroll(PolyglotLanguageContext.java:479)
	at com.oracle.truffle.api.vm.PolyglotLanguageContext$ToGuestValuesNode.apply(PolyglotLanguageContext.java:450)
	at com.oracle.truffle.api.vm.PolyglotValue$Interop$AbstractExecuteNode.executeShared(PolyglotValue.java:2166)
	at com.oracle.truffle.api.vm.PolyglotValue$Interop$ExecuteNode.executeImpl(PolyglotValue.java:2248)
	at com.oracle.truffle.api.vm.PolyglotValue$PolyglotNode.execute(PolyglotValue.java:551)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:262)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:251)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:241)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:226)
	at org.graalvm.compiler.truffle.runtime.GraalTVMCI.callProfiled(GraalTVMCI.java:86)
	at com.oracle.truffle.api.impl.Accessor.callProfiled(Accessor.java:724)
	at com.oracle.truffle.api.vm.VMAccessor.callProfiled(VMAccessor.java:93)
	at com.oracle.truffle.api.vm.PolyglotValue$Interop.execute(PolyglotValue.java:1410)
	at org.graalvm.polyglot.Value.execute(Value.java:312)
	at com.programmaticallyspeaking.gho.DelegatingFunction.execute(DelegatingFunction.java:16)
	at com.oracle.truffle.api.vm.PolyglotProxy$ProxyExecuteNode.executeProxy(PolyglotProxy.java:137)
	at com.oracle.truffle.api.vm.PolyglotProxy$ProxyRootNode.execute(PolyglotProxy.java:96)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:262)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:251)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:241)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:226)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callDirect(OptimizedCallTarget.java:209)
	at org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode.callProxy(OptimizedDirectCallNode.java:86)
	at org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode.call(OptimizedDirectCallNode.java:70)
	at com.oracle.truffle.api.interop.InteropAccessNode.doCached(InteropAccessNode.java:186)
	at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeAndSpecialize(InteropAccessNodeGen.java:82)
	at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeImpl(InteropAccessNodeGen.java:45)
	at com.oracle.truffle.api.interop.InteropAccessNode.execute(InteropAccessNode.java:67)
	at com.oracle.truffle.api.interop.ForeignAccess.sendExecute(ForeignAccess.java:420)
	at com.oracle.truffle.js.runtime.truffleinterop.JSInteropNodeUtil.call(JSInteropNodeUtil.java:254)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$ForeignExecuteNode.executeCallImpl(JSFunctionCallNode.java:1043)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$ForeignExecuteNode.executeCall(JSFunctionCallNode.java:1035)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$CacheNode.executeCall(JSFunctionCallNode.java:665)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$UninitializedCacheNode.executeCall(JSFunctionCallNode.java:699)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeCall(JSFunctionCallNode.java:217)
	at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$CallNode.execute(JSFunctionCallNode.java:255)
	at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute_generic3(JSWriteCurrentFrameSlotNodeGen.java:149)
	at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute(JSWriteCurrentFrameSlotNodeGen.java:84)
	at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.executeVoid(JSWriteCurrentFrameSlotNodeGen.java:281)
	at com.oracle.truffle.js.nodes.control.ExprBlockNode.execute(ExprBlockNode.java:68)
	at com.oracle.truffle.js.nodes.function.FunctionBodyNode.execute(FunctionBodyNode.java:66)
	at com.oracle.truffle.js.nodes.function.FunctionRootNode.executeInRealm(FunctionRootNode.java:139)
	at com.oracle.truffle.js.runtime.JavaScriptRealmBoundaryRootNode.execute(JavaScriptRealmBoundaryRootNode.java:92)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:262)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:251)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:241)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:226)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callDirect(OptimizedCallTarget.java:209)
	at org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode.callProxy(OptimizedDirectCallNode.java:86)
	at org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode.call(OptimizedDirectCallNode.java:70)
	at com.oracle.truffle.js.parser.JavaScriptLanguage$1.execute(JavaScriptLanguage.java:211)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:262)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:251)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:241)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:226)
	at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.call(OptimizedCallTarget.java:202)
	at com.oracle.truffle.api.vm.PolyglotContextImpl.eval(PolyglotContextImpl.java:746)
	at org.graalvm.polyglot.Context.eval(Context.java:311)
	at org.graalvm.polyglot.Context.eval(Context.java:336)
	at com.programmaticallyspeaking.gho.DelegatingFunctionTest.main(DelegatingFunctionTest.java:17)
Caused by: Attached Guest Language Frames (4)

What am I doing wrong?

@chumer
Copy link
Member

chumer commented Aug 15, 2018

You have discovered a bug (internal errors are always a bug on our side). This should workaround the problem:

public static class DelegatingFunction implements ProxyObject, ProxyExecutable {
...

        @Override
        public Object execute(Value... arguments) {
            Object[] o = new Object[arguments.length];
            System.arraycopy(arguments, 0, o, 0, o.length);
            return delegee.execute(o);
        }

...
        
    }

Not 100% sure what causes this. Will investigate further.

@chumer chumer self-assigned this Aug 15, 2018
@provegard
Copy link
Author

Thanks, I'll try the workaround later today!

@provegard
Copy link
Author

The workaround worked, thanks!

@chumer chumer added the bug Something isn't working label Aug 15, 2018
@chumer
Copy link
Member

chumer commented Aug 16, 2018

Fixed in oracle/graal@cf94eb3.
Will be part of RC6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants