oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.4k stars 1.64k forks source link

Cannot pass a host date to an Espresso method #5041

Closed radeusgd closed 1 year ago

radeusgd commented 2 years ago

Describe GraalVM and your environment :

Have you verified this issue still happens when using the latest snapshot? Yes

Describe the issue When trying to create a nice repro for another issue, I've got blocked by the fact that I cannot even pass a Java date from host to the Espresso side through interop.

I minimized the example to the following:

Create the two following files (taking into consideration correct directory structure to match the package declarations): Foo.java:

package org.enso.base.repro;

import java.time.*;

public class Foo {
    public static void printDateTime(ZonedDateTime date) {
        System.out.println("printDateTime: " + date + " @ " + date.toEpochSecond());
    }

    public static void printDate(LocalDate date) {
        System.out.println("printDate: " + date);
    }
}

and Espressotest.java:

package org.enso.base.repro;

import java.time.*;
import java.util.concurrent.Executors;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.enso.base.repro.Foo;

public class Espressotest {
    public static void main(String[] args) {
        var ctx = Context.newBuilder("java")
            .option("java.Polyglot", "true")
            .allowAllAccess(true)
            .build();
        compareDateTimeHandling(ctx);
        compareDateHandling(ctx);
    }

    private static void compareDateTimeHandling(Context ctx) {
        var fooHost = ctx.asValue(Foo.class);
        var fooEspresso = ctx.getBindings("java").getMember("org.enso.base.repro.Foo");
    System.out.println("Running Host:");
        runZDTTest(fooHost);
    System.out.println("Running Espresso:");
    try {
            runZDTTest(fooEspresso);
    } catch (Exception e) {
            e.printStackTrace();
    }
    }

    private static void compareDateHandling(Context ctx) {
        var fooHost = ctx.asValue(Foo.class);
        var fooEspresso = ctx.getBindings("java").getMember("org.enso.base.repro.Foo");
    System.out.println("Running Host:");
        runLDTest(fooHost);
    System.out.println("Running Espresso:");
    try {
            runLDTest(fooEspresso);
    } catch (Exception e) {
            e.printStackTrace();
    }
    }

    private static void runZDTTest(Value klass) {
    var tz = ZoneId.of("Europe/Warsaw");
        ZonedDateTime date = ZonedDateTime.of(2022, 9, 22, 12, 0, 0, 0, tz);
        klass.getMember("static").invokeMember("printDateTime", date);
    }

    private static void runLDTest(Value klass) {
        LocalDate date = LocalDate.of(2022, 9, 22);
        klass.getMember("static").invokeMember("printDate", date);
    }
}

Steps to reproduce the issue

Build the two files using javac and run java org.enso.base.repro.Espressotest. My exact commands are:

javac org/enso/base/repro/Foo.java
javac org/enso/base/repro/Espressotest.java
java org.enso.base.repro.Espresssotest

Expected behavior

I'd expect both to work, instead host invocations work ok, but Espresso ones fail to convert the Host Java date to Espresso.

The output I'd expect would be:

Running Host:
printDateTime: 2022-09-22T12:00+02:00[Europe/Warsaw] @ 1663840800
Running Espresso:
printDateTime: 2022-09-22T12:00+02:00[Europe/Warsaw] @ 1663840800
Running Host:
printDate: 2022-09-22
Running Espresso:
printDate: 2022-09-22

Instead, the Espresso invocations fail with IllegalArgumentException, see the traces below.

Additional context See the full output of the run below.

Details ``` Running Host: printDateTime: 2022-09-22T12:00+02:00[Europe/Warsaw] @ 1663840800 Running Espresso: java.lang.IllegalArgumentException: Invalid argument when invoking 'printDateTime' on 'Klass'(language: Java, type: com.oracle.truffle.polyglot.PolyglotMapAndFunction). Could not cast foreign object to java/time/ZonedDateTime: due to: Missing field: dateTimeProvided arguments: ['2022-09-22T12:00+02:00[Europe/Warsaw]'(language: Java, type: java.time.ZonedDateTime)]. at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineException.illegalArgument(PolyglotEngineException.java:131) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch.invalidInvokeArgumentType(PolyglotValueDispatch.java:1432) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue$AbstractInvokeNode.executeShared(PolyglotValueDispatch.java:4455) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue$InvokeNode.executeImpl(PolyglotValueDispatch.java:4486) at org.graalvm.truffle/com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:709) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:632) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:565) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:549) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.GraalRuntimeSupport.callProfiled(GraalRuntimeSupport.java:256) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue.invoke(PolyglotValueDispatch.java:2421) at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:973) at org.enso.base.repro.Espressotest.runZDTTest(Espressotest.java:49) at org.enso.base.repro.Espressotest.compareDateTimeHandling(Espressotest.java:27) at org.enso.base.repro.Espressotest.main(Espressotest.java:16) Caused by: Attached Guest Language Frames (1) Running Host: printDate: 2022-09-22 Running Espresso: java.lang.IllegalArgumentException: Invalid argument when invoking 'printDate' on 'Klass'(language: Java, type: com.oracle.truffle.polyglot.PolyglotMapAndFunction). Could not cast foreign object to java/time/LocalDate: due to: Missing field: yearProvided arguments: ['2022-09-22'(language: Java, type: java.time.LocalDate)]. at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineException.illegalArgument(PolyglotEngineException.java:131) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch.invalidInvokeArgumentType(PolyglotValueDispatch.java:1432) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue$AbstractInvokeNode.executeShared(PolyglotValueDispatch.java:4455) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue$InvokeNode.executeImpl(PolyglotValueDispatch.java:4486) at org.graalvm.truffle/com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:709) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:632) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:565) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:549) at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.GraalRuntimeSupport.callProfiled(GraalRuntimeSupport.java:256) at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotValueDispatch$InteropValue.invoke(PolyglotValueDispatch.java:2421) at org.graalvm.sdk/org.graalvm.polyglot.Value.invokeMember(Value.java:973) at org.enso.base.repro.Espressotest.runLDTest(Espressotest.java:55) at org.enso.base.repro.Espressotest.compareDateHandling(Espressotest.java:40) at org.enso.base.repro.Espressotest.main(Espressotest.java:17) Caused by: Attached Guest Language Frames (1) ```
radeusgd commented 2 years ago

I'm not sure how to get the java on truffle label onto this issue.

gilles-duboscq commented 2 years ago

Thanks for the report! I have added the label. @javeleon, i suppose it's about supporting foreign objects that answer to isDate and isInstant in ToEspressoNode.

javeleon commented 1 year ago

A fix for this issue has been integrated into master.