[java-support] branch master updated: JSPT-95 Make Graal ScriptEngine "Compilable"

Rod Widdowson rdw at steadingsoftware.com
Mon Mar 30 05:49:56 EDT 2020


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch master
in repository java-support.

View the commit online:
http://git.shibboleth.net/view/?p=java-support.git;a=commit;h=3e5f660f9f2e322bd89ba0cdbd0ec2685f68281f

The following commit(s) were added to refs/heads/master by this push:
       new  3e5f660   JSPT-95 Make Graal ScriptEngine "Compilable"
3e5f660 is described below

commit 3e5f660f9f2e322bd89ba0cdbd0ec2685f68281f
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sun Mar 29 13:54:54 2020 +0100

    JSPT-95 Make Graal ScriptEngine "Compilable"
    
    https://issues.shibboleth.net/jira/browse/JSPT-95
    
    By making the script a "Source" we make it more likely that
    GraalBM will decide to compile the language - at least it
    won't see the script as new each time it is invoked.
---
 .../java/support/scripting/EngineTests.java        | 23 ++++++++-
 .../java/support/scripting/GraalEngine.java        | 58 ++++++++++++++++++++--
 2 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/src/test/java/net/shibboleth/utilities/java/support/scripting/EngineTests.java b/src/test/java/net/shibboleth/utilities/java/support/scripting/EngineTests.java
index 34cab3c..529ba31 100644
--- a/src/test/java/net/shibboleth/utilities/java/support/scripting/EngineTests.java
+++ b/src/test/java/net/shibboleth/utilities/java/support/scripting/EngineTests.java
@@ -22,6 +22,8 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.Map;
 
+import javax.script.Compilable;
+import javax.script.CompiledScript;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
@@ -60,11 +62,30 @@ public class EngineTests {
         ctx.setAttribute("b", this, ScriptContext.ENGINE_SCOPE);
         
         final Object o = scriptEngine.eval(script, ctx);
-        
+
         assertTrue(o instanceof Map);
         final Map map = (Map) o;
         assertEquals(map.size(), 1);
         assertEquals(map.get("a"), this);
     }
 
+    @Test public void testGraalCompiled() throws ScriptException {
+        final ScriptEngineManager engineManager = new ScriptEngineManager();
+        final ScriptEngine scriptEngine = engineManager.getEngineByName("shibboleth-nashorn");
+        final Compilable compiler = (Compilable) scriptEngine;
+
+        final ScriptContext ctx = new SimpleScriptContext();
+        ctx.setAttribute("b", this, ScriptContext.ENGINE_SCOPE);
+
+        final String script = "var map = Java.type('java.util.HashMap');"
+                + "var s = new map(2); s.put('a',b); s";
+
+        final CompiledScript compiled = compiler.compile(script);
+        final Object o = compiled.eval(ctx);
+
+        assertTrue(o instanceof Map);
+        final Map map = (Map) o;
+        assertEquals(map.size(), 1);
+        assertEquals(map.get("a"), this);
+    }
 }
diff --git a/src/test/java/net/shibboleth/utilities/java/support/scripting/GraalEngine.java b/src/test/java/net/shibboleth/utilities/java/support/scripting/GraalEngine.java
index c96b10b..07f3a86 100644
--- a/src/test/java/net/shibboleth/utilities/java/support/scripting/GraalEngine.java
+++ b/src/test/java/net/shibboleth/utilities/java/support/scripting/GraalEngine.java
@@ -17,11 +17,17 @@
 
 package net.shibboleth.utilities.java.support.scripting;
 
+import java.io.Reader;
+
 import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 
 import org.graalvm.polyglot.Context;
+import org.graalvm.polyglot.Source;
 import org.graalvm.polyglot.Value;
 
 /**
@@ -30,20 +36,21 @@ import org.graalvm.polyglot.Value;
  * 
  * NOTE that this does not (currently) implement {@link javax.script.Compilable}.
  */
-public class GraalEngine extends AbstractScriptEngine implements ScriptEngine {
+public class GraalEngine extends AbstractScriptEngine implements ScriptEngine, Compilable {
 
     /** {@inheritDoc} */
-    public Object eval(final String script, final Bindings binding) throws ScriptException {
+    public Object eval(final String script, final Bindings scriptBindings) throws ScriptException {
         try (final Context context = Context.newBuilder().allowExperimentalOptions(true).
                 option("js.nashorn-compat", "true").
                 allowAllAccess(true).
                 build()) {
             
             final Value bindings  = context.getBindings("js");
-            for (final String name: binding.keySet()) {
-                bindings.putMember(name, binding.get(name));
+            for (final String name: scriptBindings.keySet()) {
+                bindings.putMember(name, scriptBindings.get(name));
             }
-            final Value v = context.eval("js", script);
+            final Source s = Source.newBuilder("js", script, "embedded").buildLiteral();
+            final Value v = context.eval(s);
             if (v.isHostObject()) {
                 return v.asHostObject();
             } else if (v.isProxyObject()) { 
@@ -55,4 +62,45 @@ public class GraalEngine extends AbstractScriptEngine implements ScriptEngine {
         }
     }
 
+    /** {@inheritDoc} */
+    public CompiledScript compile(String script) throws ScriptException {
+
+        final ScriptEngine parent = this;
+        return new CompiledScript() {
+            final Source source = Source.newBuilder("js", script, "embedded").buildLiteral();
+
+            public ScriptEngine getEngine() {
+                return parent;
+            }
+
+            public Object eval(ScriptContext scriptContext) throws ScriptException {
+
+                try (final Context context = Context.newBuilder().allowExperimentalOptions(true).
+                        option("js.nashorn-compat", "true").
+                        allowAllAccess(true).
+                        build()) {
+
+                    final Bindings scriptBindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+                    final Value bindings  = context.getBindings("js");
+                    for (final String name: scriptBindings.keySet()) {
+                        bindings.putMember(name, scriptBindings.get(name));
+                    }
+                    final Value v = context.eval(source);
+                    if (v.isHostObject()) {
+                        return v.asHostObject();
+                    } else if (v.isProxyObject()) {
+                        return v.asProxyObject();
+                    }
+                    return v.as(Object.class);
+                }  catch (final RuntimeException e) {
+                    throw new ScriptException(e);
+                }
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    public CompiledScript compile(Reader script) throws ScriptException {
+       throw new ScriptException("Cannot compile from a reader");
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list