Search code examples
graalvm

GraalVM/Polyglot: how to get SourceLocation programmatically


Is there a way to get the current source location (SourceSection) from java?

e.g. a js script executed via context.eval() calls a java method, the java method logs the current js script name+line

PolyglotException has a getSourceLocation() that provide this information. also stack traces from polyglot seems to contains information about the source location e.g. at :program(Unnamed:2:23-53)


Solution

  • I know you asked this a long time ago, but I have just seen it for the first time.

    Here is a way to get to the current location easily:

    static StackFrame getCurrentLocation() {
        PolyglotException e = Context.getCurrent().asValue(new RuntimeException()).as(PolyglotException.class);
        for (StackFrame frame: e.getPolyglotStackTrace()) {
            if (frame.isGuestFrame()) {
                return frame;
            }
        }
        return null;
    }
    

    Here is a full runnable example:

    public class Test {
    
        public static void main(String[] args) {
            try (Context context = Context.newBuilder().allowHostAccess(HostAccess.ALL).build()) {
                context.getBindings("js").putMember("test", new Test());
                
                Source source = Source.newBuilder("js", "test.callback()", "mysource.js").buildLiteral();
                context.eval(source);
            }
        }
        
        public void callback() {
            System.out.println(getCurrentLocation());
        }
        
        
        static StackFrame getCurrentLocation() {
            PolyglotException e = Context.getCurrent().asValue(new RuntimeException()).as(PolyglotException.class);
            for (StackFrame frame: e.getPolyglotStackTrace()) {
                if (frame.isGuestFrame()) {
                    return frame;
                }
            }
            return null;
        }
    }
    

    This prints:

    <js> :program(mysource.js:1:0-14)