diff -Nru rhino-1.7.7.1/build.gradle rhino-1.7.7.2/build.gradle
--- rhino-1.7.7.1/build.gradle 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/build.gradle 2017-09-27 22:57:34.000000000 +0000
@@ -3,6 +3,7 @@
apply plugin: 'maven-publish'
apply plugin: 'jacoco'
apply plugin: 'distribution'
+apply plugin: 'checkstyle'
sourceCompatibility = 1.6
targetCompatibility = 1.6
@@ -43,6 +44,15 @@
dependencies {
testCompile "junit:junit:4.12"
testCompile "org.yaml:snakeyaml:1.15"
+ testCompile "net.trajano.caliper:caliper:1.2.1"
+}
+
+if (JavaVersion.current().isJava8Compatible()) {
+ allprojects {
+ tasks.withType(Javadoc) {
+ options.addStringOption('Xdoclint:none', '-quiet')
+ }
+ }
}
test {
@@ -58,8 +68,18 @@
testLogging.showStandardStreams = true
}
+task sunSpiderBenchmark(type: JavaExec) {
+ main "com.google.caliper.runner.CaliperMain"
+ systemProperty 'rhino.benchmark.report', "${buildDir.absolutePath}"
+ args "-Cresults.upload.class=org.mozilla.javascript.benchmarks.ResultPlotter", "-i", "runtime", "org.mozilla.javascript.benchmarks.CaliperSpiderBenchmark.Spider"
+ classpath sourceSets.test.runtimeClasspath
+}
+
task testBenchmark(type: Test) {
- include "**/benchmarks/*Benchmark*"
+ jacoco {
+ enabled = false
+ }
+ include "**/benchmarks/V8Benchmark*"
systemProperty 'rhino.benchmark.report', "${buildDir.absolutePath}"
systemProperty 'file.encoding', 'UTF-8'
workingDir = file("testsrc/benchmarks")
@@ -67,6 +87,15 @@
testLogging.showStandardStreams = true
forkEvery = 1
}
+testBenchmark.dependsOn sunSpiderBenchmark
+
+task microBenchmark(type: JavaExec) {
+ main "com.google.caliper.runner.CaliperMain"
+ args "-i", "runtime", "org.mozilla.javascript.benchmarks.CaliperObjectBenchmark.FieldAccess", "-DstringKeys=100,1000", "-DintKeys=0,10,1000"
+ classpath sourceSets.test.runtimeClasspath
+}
+
+
idea {
module {
@@ -181,24 +210,36 @@
}
}
+checkstyle {
+ configFile = file("${projectDir}/checkstyle.xml")
+ sourceSets = [project.sourceSets.main]
+}
+
distributions {
main {
contents {
- from(sourceSets.main.allSource) {
+ from(sourceSets.main.java) {
exclude 'man'
- into '/src'
+ into 'rhino' + project.version + '/src'
+ }
+ from(sourceSets.main.resources) {
+ exclude '**/*.java'
+ into 'rhino' + project.version + '/src'
}
from(javadoc.destinationDir) {
- into '/docs'
+ into 'rhino' + project.version + '/docs'
}
from(jar.outputs.files) {
- into '/lib'
+ into 'rhino' + project.version + '/lib'
}
from(sourceSets.main.allSource) {
include 'man/*.1'
+ into 'rhino' + project.version
}
from(file(".")) {
- include '*.txt'
+ include '*.txt', '*.md', 'build.gradle', 'build.properties', 'gradle.properties',
+ 'gradle/**', 'gradlew'
+ into 'rhino' + project.version
}
into "/"
}
diff -Nru rhino-1.7.7.1/build.properties rhino-1.7.7.2/build.properties
--- rhino-1.7.7.1/build.properties 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/build.properties 2017-09-27 22:57:34.000000000 +0000
@@ -4,9 +4,9 @@
name: rhino
Name: Rhino
-version: 1.7.7.1
+version: 1.7.7.2
# See Context#getImplementationVersion() for format of this!
-implementation.version: Rhino 1.7.7 ${implementation.date}
+implementation.version: Rhino 1.7.7.2 ${implementation.date}
build.dir: build
rhino.jar: js.jar
diff -Nru rhino-1.7.7.1/checkstyle.xml rhino-1.7.7.2/checkstyle.xml
--- rhino-1.7.7.1/checkstyle.xml 1970-01-01 00:00:00.000000000 +0000
+++ rhino-1.7.7.2/checkstyle.xml 2017-09-27 22:57:34.000000000 +0000
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru rhino-1.7.7.1/debian/changelog rhino-1.7.7.2/debian/changelog
--- rhino-1.7.7.1/debian/changelog 2017-01-20 10:04:18.000000000 +0000
+++ rhino-1.7.7.2/debian/changelog 2021-02-08 10:39:29.000000000 +0000
@@ -1,3 +1,32 @@
+rhino (1.7.7.2-3) unstable; urgency=medium
+
+ * Team upload.
+ * Backported the JSR 223 script engine to use Rhino as a replacement
+ for Nashorn with OpenJDK 17
+ * Standards-Version updated to 4.5.1
+ * Switch to debhelper level 13
+
+ -- Emmanuel Bourg Mon, 08 Feb 2021 11:39:29 +0100
+
+rhino (1.7.7.2-2) UNRELEASED; urgency=medium
+
+ * Team upload.
+ * Add patch to install JAR as 1.7.7.2 (not 1.7.7.1)
+
+ -- tony mancill Wed, 25 Nov 2020 12:02:51 -0800
+
+rhino (1.7.7.2-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release
+ - Refreshed the patches
+ * Removed Damien Raude-Morvan from the uploaders (Closes: #889449)
+ * Track the releases > 1.7.7.1
+ * Standards-Version updated to 4.5.0
+ * Use salsa.debian.org Vcs-* URLs
+
+ -- Emmanuel Bourg Thu, 03 Sep 2020 13:59:51 +0200
+
rhino (1.7.7.1-1) unstable; urgency=medium
* Team upload.
diff -Nru rhino-1.7.7.1/debian/compat rhino-1.7.7.2/debian/compat
--- rhino-1.7.7.1/debian/compat 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/compat 1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-10
diff -Nru rhino-1.7.7.1/debian/control rhino-1.7.7.2/debian/control
--- rhino-1.7.7.1/debian/control 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/control 2021-02-08 10:39:26.000000000 +0000
@@ -2,25 +2,27 @@
Section: interpreters
Priority: optional
Maintainer: Debian Java Maintainers
-Uploaders: Marcus Better ,
- Damien Raude-Morvan ,
- Jakub Adam
-Build-Depends: ant,
- debhelper (>= 10),
- default-jdk,
- javahelper,
- maven-repo-helper
-Standards-Version: 3.9.8
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/rhino.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/rhino.git
+Uploaders:
+ Marcus Better ,
+ Jakub Adam
+Build-Depends:
+ ant,
+ debhelper-compat (= 13),
+ default-jdk,
+ javahelper,
+ maven-repo-helper
+Standards-Version: 4.5.1
+Vcs-Git: https://salsa.debian.org/java-team/rhino.git
+Vcs-Browser: https://salsa.debian.org/java-team/rhino
Homepage: http://www.mozilla.org/rhino/
Package: rhino
Architecture: all
-Depends: default-jre-headless (>= 1:1.6) | java6-runtime-headless,
- libjline-java,
- librhino-java (= ${source:Version}),
- ${misc:Depends}
+Depends:
+ default-jre-headless (>= 1:1.6) | java6-runtime-headless,
+ libjline-java,
+ librhino-java (= ${source:Version}),
+ ${misc:Depends}
Suggests: librhino-java-doc
Description: JavaScript engine written in Java
Rhino is an implementation of the JavaScript language written
diff -Nru rhino-1.7.7.1/debian/librhino-java.links rhino-1.7.7.2/debian/librhino-java.links
--- rhino-1.7.7.1/debian/librhino-java.links 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/librhino-java.links 2020-09-03 11:36:47.000000000 +0000
@@ -1 +1 @@
-usr/share/java/js.jar usr/share/java/rhino.jar
\ No newline at end of file
+usr/share/java/js.jar usr/share/java/rhino.jar
diff -Nru rhino-1.7.7.1/debian/patches/03_public_getSourcePositionFromStack.patch rhino-1.7.7.2/debian/patches/03_public_getSourcePositionFromStack.patch
--- rhino-1.7.7.1/debian/patches/03_public_getSourcePositionFromStack.patch 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/03_public_getSourcePositionFromStack.patch 2020-09-03 11:38:39.000000000 +0000
@@ -7,7 +7,7 @@
--- a/src/org/mozilla/javascript/Context.java
+++ b/src/org/mozilla/javascript/Context.java
-@@ -2568,7 +2568,7 @@
+@@ -2592,7 +2592,7 @@
return (Evaluator)Kit.newInstanceOrNull(interpreterClass);
}
diff -Nru rhino-1.7.7.1/debian/patches/06_preserve-backward-compatibility.patch rhino-1.7.7.2/debian/patches/06_preserve-backward-compatibility.patch
--- rhino-1.7.7.1/debian/patches/06_preserve-backward-compatibility.patch 2017-01-20 09:04:51.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/06_preserve-backward-compatibility.patch 2020-09-03 11:38:43.000000000 +0000
@@ -51,7 +51,7 @@
}
--- a/src/org/mozilla/javascript/ast/FunctionNode.java
+++ b/src/org/mozilla/javascript/ast/FunctionNode.java
-@@ -329,14 +329,26 @@
+@@ -330,14 +330,26 @@
return functionForm == Form.GETTER || functionForm == Form.SETTER || functionForm == Form.METHOD;
}
@@ -78,7 +78,7 @@
public boolean isNormalMethod() {
return functionForm == Form.METHOD;
}
-@@ -345,10 +357,18 @@
+@@ -346,10 +358,18 @@
functionForm = Form.GETTER;
}
diff -Nru rhino-1.7.7.1/debian/patches/07_fix-context-implementation-version.patch rhino-1.7.7.2/debian/patches/07_fix-context-implementation-version.patch
--- rhino-1.7.7.1/debian/patches/07_fix-context-implementation-version.patch 2017-01-20 10:02:17.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/07_fix-context-implementation-version.patch 2020-09-03 11:38:45.000000000 +0000
@@ -4,7 +4,7 @@
Forwarded: https://github.com/mozilla/rhino/commit/f575445cbe5e245#commitcomment-20551124
--- a/src/org/mozilla/javascript/Context.java
+++ b/src/org/mozilla/javascript/Context.java
-@@ -704,9 +704,9 @@
+@@ -729,9 +729,9 @@
is = metaUrl.openStream();
Manifest mf = new Manifest(is);
Attributes attrs = mf.getMainAttributes();
diff -Nru rhino-1.7.7.1/debian/patches/08_fix-jar-version-number.patch rhino-1.7.7.2/debian/patches/08_fix-jar-version-number.patch
--- rhino-1.7.7.1/debian/patches/08_fix-jar-version-number.patch 1970-01-01 00:00:00.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/08_fix-jar-version-number.patch 2020-12-16 15:45:16.000000000 +0000
@@ -0,0 +1,14 @@
+Description: update POM to match upstream version
+Author: tony mancill
+
+--- a/maven/maven-pom.xml
++++ b/maven/maven-pom.xml
+@@ -12,7 +12,7 @@
+ org.mozilla
+ rhino
+ Mozilla Rhino
+- 1.7.7.1
++ 1.7.7.2
+
+ jar
+
diff -Nru rhino-1.7.7.1/debian/patches/script-engine.patch rhino-1.7.7.2/debian/patches/script-engine.patch
--- rhino-1.7.7.1/debian/patches/script-engine.patch 1970-01-01 00:00:00.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/script-engine.patch 2021-02-08 10:03:36.000000000 +0000
@@ -0,0 +1,1303 @@
+From f195514ffee1b759ba088883732e77b026b3a694 Mon Sep 17 00:00:00 2001
+From: Gregory Brail
+Date: Fri, 5 Jun 2020 14:38:28 -0700
+Subject: [PATCH] Implement standard Java ScriptEngine
+
+This is not based on the now-removed JDK code but instead does a
+few things in a more modern way. See the comments for supported
+parameters (you can set language and optimization level via
+properties) and built-in functions (only print is supported right now.)
+
+This is built into a separate JAR called "rhino-engine" because
+otherwise, including it in any Java 8 JDK would break scripts that
+are expecting to see Nashorn instead.
+---
+ .circleci/config.yml | 2 +-
+ build.gradle | 86 ++++-
+ .../services/javax.script.ScriptEngineFactory | 1 +
+ .../javascript/engine/BindingsObject.java | 60 +++
+ .../mozilla/javascript/engine/Builtins.java | 59 +++
+ .../engine/RhinoCompiledScript.java | 33 ++
+ .../engine/RhinoInvocationHandler.java | 25 ++
+ .../javascript/engine/RhinoScriptEngine.java | 363 ++++++++++++++++++
+ .../engine/RhinoScriptEngineFactory.java | 140 +++++++
+ .../tests/scriptengine/BuiltinsTest.java | 54 +++
+ .../tests/scriptengine/FactoryTest.java | 56 +++
+ .../tests/scriptengine/InvocableTest.java | 158 ++++++++
+ .../tests/scriptengine/ScriptEngineTest.java | 276 +++++++++++++
+ 13 files changed, 1305 insertions(+), 8 deletions(-)
+ create mode 100644 src/META-INF/services/javax.script.ScriptEngineFactory
+ create mode 100644 src/org/mozilla/javascript/engine/BindingsObject.java
+ create mode 100644 src/org/mozilla/javascript/engine/Builtins.java
+ create mode 100644 src/org/mozilla/javascript/engine/RhinoCompiledScript.java
+ create mode 100644 src/org/mozilla/javascript/engine/RhinoInvocationHandler.java
+ create mode 100644 src/org/mozilla/javascript/engine/RhinoScriptEngine.java
+ create mode 100644 src/org/mozilla/javascript/engine/RhinoScriptEngineFactory.java
+ create mode 100644 testsrc/org/mozilla/javascript/tests/scriptengine/BuiltinsTest.java
+ create mode 100644 testsrc/org/mozilla/javascript/tests/scriptengine/FactoryTest.java
+ create mode 100644 testsrc/org/mozilla/javascript/tests/scriptengine/InvocableTest.java
+ create mode 100644 testsrc/org/mozilla/javascript/tests/scriptengine/ScriptEngineTest.java
+
+--- /dev/null
++++ b/src/META-INF/services/javax.script.ScriptEngineFactory
+@@ -0,0 +1 @@
++org.mozilla.javascript.engine.RhinoScriptEngineFactory
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/BindingsObject.java
+@@ -0,0 +1,60 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import org.mozilla.javascript.Context;
++import org.mozilla.javascript.Scriptable;
++import org.mozilla.javascript.ScriptableObject;
++import javax.script.Bindings;
++
++/**
++ * This class makes the Bindings object into a Scriptable. That way, we can query and modify
++ * the contents of the Bindings on demand.
++ */
++public class BindingsObject
++ extends ScriptableObject {
++ private final Bindings bindings;
++
++ BindingsObject(Bindings bindings) {
++ if (bindings == null) {
++ throw new IllegalArgumentException("Bindings must not be null");
++ }
++ this.bindings = bindings;
++ }
++
++ @Override
++ public String getClassName() {
++ return "BindingsObject";
++ }
++
++ @Override
++ public Object get(String name, Scriptable start) {
++ Object ret = bindings.get(name);
++ if (ret == null) {
++ return Scriptable.NOT_FOUND;
++ }
++ return Context.jsToJava(ret, Object.class);
++ }
++
++ @Override
++ public void put(String name, Scriptable start, Object value) {
++ bindings.put(name, Context.javaToJS(value, start));
++ }
++
++ @Override
++ public void delete(String name) {
++ bindings.remove(name);
++ }
++
++ @Override
++ public boolean has(String name, Scriptable start) {
++ return bindings.containsKey(name);
++ }
++
++ @Override
++ public Object[] getIds() {
++ return bindings.keySet().toArray();
++ }
++}
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/Builtins.java
+@@ -0,0 +1,59 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import java.io.IOException;
++import java.io.OutputStreamWriter;
++import java.io.Writer;
++import javax.script.ScriptContext;
++import org.mozilla.javascript.Context;
++import org.mozilla.javascript.Function;
++import org.mozilla.javascript.ScriptRuntime;
++import org.mozilla.javascript.Scriptable;
++import org.mozilla.javascript.ScriptableObject;
++
++/**
++ *
++ * This class defines the following built-in functions for the RhinoScriptEngine.
++ *
++ *
++ *
print(arg, arg, ...): Write each argument, concatenated to the ScriptEngine's
++ * "standard output" as a string.
++ *
++ */
++public class Builtins {
++
++ static final Object BUILTIN_KEY = new Object();
++
++ private Writer stdout;
++
++ void register(Context cx, ScriptableObject scope, ScriptContext sc) {
++ if (sc.getWriter() == null) {
++ stdout = new OutputStreamWriter(System.out);
++ } else {
++ stdout = sc.getWriter();
++ }
++
++ scope.defineFunctionProperties(new String[]{"print"},
++ Builtins.class,
++ ScriptableObject.PERMANENT | ScriptableObject.DONTENUM);
++ }
++
++ public static void print(Context cx, Scriptable thisObj, Object[] args, Function f)
++ throws IOException {
++ Builtins self = getSelf(thisObj);
++ for (Object arg : args) {
++ self.stdout.write(ScriptRuntime.toString(arg));
++ }
++ self.stdout.write('\n');
++ }
++
++ private static Builtins getSelf(Scriptable scope) {
++ // Since this class is invoked as a set of anonymous functions, "this"
++ // in JavaScript does not point to "this" in Java. We set a key on the
++ // top-level scope to address this.
++ return (Builtins) ScriptableObject.getTopScopeValue(scope, BUILTIN_KEY);
++ }
++}
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/RhinoCompiledScript.java
+@@ -0,0 +1,33 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import javax.script.CompiledScript;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptException;
++import org.mozilla.javascript.Script;
++
++public class RhinoCompiledScript
++ extends CompiledScript {
++
++ private final RhinoScriptEngine engine;
++ private final Script script;
++
++ RhinoCompiledScript(RhinoScriptEngine engine, Script script) {
++ this.engine = engine;
++ this.script = script;
++ }
++
++ @Override
++ public Object eval(ScriptContext context) throws ScriptException {
++ return engine.eval(script, context);
++ }
++
++ @Override
++ public ScriptEngine getEngine() {
++ return engine;
++ }
++}
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/RhinoInvocationHandler.java
+@@ -0,0 +1,25 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import java.lang.reflect.InvocationHandler;
++import java.lang.reflect.Method;
++
++public class RhinoInvocationHandler
++ implements InvocationHandler {
++
++ private final Object thiz;
++ private final RhinoScriptEngine engine;
++
++ RhinoInvocationHandler(RhinoScriptEngine engine, Object thiz) {
++ this.engine = engine;
++ this.thiz = thiz;
++ }
++
++ @Override
++ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
++ return engine.invokeMethodRaw(thiz, method.getName(), method.getReturnType(), args);
++ }
++}
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/RhinoScriptEngine.java
+@@ -0,0 +1,355 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import java.io.IOException;
++import java.io.Reader;
++import java.lang.reflect.Method;
++import java.lang.reflect.Proxy;
++import javax.script.AbstractScriptEngine;
++import javax.script.Bindings;
++import javax.script.Compilable;
++import javax.script.CompiledScript;
++import javax.script.Invocable;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineFactory;
++import javax.script.ScriptException;
++import javax.script.SimpleBindings;
++import org.mozilla.javascript.Callable;
++import org.mozilla.javascript.Context;
++import org.mozilla.javascript.ContextFactory;
++import org.mozilla.javascript.RhinoException;
++import org.mozilla.javascript.Script;
++import org.mozilla.javascript.Scriptable;
++import org.mozilla.javascript.ScriptableObject;
++
++/**
++ *
++ * This is the implementation of the standard ScriptEngine interface for Rhino.
++ *
++ *
++ * An instance of the Rhino ScriptEngine is fully self-contained. Bindings at the GLOBAL_SCOPE may
++ * be set, but there is nothing special about them -- if both global and ENGINE_SCOPE bindings are
++ * set then the "engine" bindings override the global ones.
++ *
++ *
++ * The Rhino engine is not thread safe. Rhino does no synchronization of ScriptEngine instances and
++ * no synchronization of Bindings instances. It is up to the caller to ensure that the ScriptEngine
++ * and all its Bindings are used by a single thread at a time.
++ *
++ *
++ * The Rhino script engine includes some top-level built-in functions. See the Builtins class for
++ * more documentation.
++ *
++ *
++ * The engine supports a few configuration parameters that may be set at the "engine scope". Both
++ * are numbers that may be set to a String or Number object.
++ *
++ *
++ *
javax.script.language_version: The version of the JavaScript language supported,
++ * which is an integer defined in the Context class. The default is the latest "ES6"
++ * version, defined as 200.
++ *
org.mozilla.javascript.optimization_level: The level of optimization Rhino performs
++ * on the generated bytecode. Default is 9, which is the most. Set to -1 to use interpreted
++ * mode.
++ *
++ */
++public class RhinoScriptEngine
++ extends AbstractScriptEngine
++ implements Compilable, Invocable {
++
++ /**
++ * Reserved key for the Rhino optimization level. Default is "9," for optimized and compiled code.
++ * Set this to "-1" to run Rhino in interpreted mode -- this is much much slower but the only
++ * option on platforms like Android that don't support class files.
++ */
++ public static final String OPTIMIZATION_LEVEL = "org.mozilla.javascript.optimization_level";
++
++ static final int DEFAULT_LANGUAGE_VERSION = Context.VERSION_ES6;
++ private static final int DEFAULT_OPT = 9;
++ private static final boolean DEFAULT_DEBUG = true;
++ private static final String DEFAULT_FILENAME = "eval";
++
++ private static final CtxFactory ctxFactory = new CtxFactory();
++
++ private final RhinoScriptEngineFactory factory;
++ private final Builtins builtins;
++ private ScriptableObject topLevelScope = null;
++
++ RhinoScriptEngine(RhinoScriptEngineFactory factory) {
++ this.factory = factory;
++ this.builtins = new Builtins();
++ }
++
++ private Scriptable initScope(Context cx, ScriptContext sc) throws ScriptException {
++ configureContext(cx);
++
++ if (topLevelScope == null) {
++ topLevelScope = cx.initStandardObjects();
++ // We need to stash this away so that the built in functions can find
++ // this engine's specific stuff that they need to work.
++ topLevelScope.associateValue(Builtins.BUILTIN_KEY, builtins);
++ builtins.register(cx, topLevelScope, sc);
++ }
++
++ Scriptable engineScope = new BindingsObject(
++ sc.getBindings(ScriptContext.ENGINE_SCOPE));
++ engineScope.setParentScope(null);
++ engineScope.setPrototype(topLevelScope);
++
++ if (sc.getBindings(ScriptContext.GLOBAL_SCOPE) != null) {
++ Scriptable globalScope = new BindingsObject(
++ sc.getBindings(ScriptContext.GLOBAL_SCOPE));
++ globalScope.setParentScope(null);
++ globalScope.setPrototype(topLevelScope);
++ engineScope.setPrototype(globalScope);
++ }
++
++ return engineScope;
++ }
++
++ @Override
++ public Object eval(String script, ScriptContext context) throws ScriptException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, context);
++ Object ret = cx.evaluateString(scope, script, getFilename(), 0, null);
++ return Context.jsToJava(ret, Object.class);
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public Object eval(Reader reader, ScriptContext context) throws ScriptException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, context);
++ Object ret = cx.evaluateReader(scope, reader, getFilename(), 0, null);
++ return Context.jsToJava(ret, Object.class);
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } catch (IOException ioe) {
++ throw new ScriptException(ioe);
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public CompiledScript compile(String script) throws ScriptException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ configureContext(cx);
++ Script s =
++ cx.compileString(script, getFilename(), 1, null);
++ return new RhinoCompiledScript(this, s);
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public CompiledScript compile(Reader script) throws ScriptException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ configureContext(cx);
++ Script s =
++ cx.compileReader(script, getFilename(), 1, null);
++ return new RhinoCompiledScript(this, s);
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } catch (IOException ioe) {
++ throw new ScriptException(ioe);
++ } finally {
++ Context.exit();
++ }
++ }
++
++ Object eval(Script script, ScriptContext sc) throws ScriptException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, sc);
++ Object ret = script.exec(cx, scope);
++ return Context.jsToJava(ret, Object.class);
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public Object invokeFunction(String name, Object... args)
++ throws ScriptException, NoSuchMethodException {
++ return invokeMethod(null, name, args);
++ }
++
++ @Override
++ public Object invokeMethod(Object thiz, String name, Object... args)
++ throws ScriptException, NoSuchMethodException {
++ return invokeMethodRaw(thiz, name, Object.class, args);
++ }
++
++ Object invokeMethodRaw(Object thiz, String name, Class> returnType, Object... args)
++ throws ScriptException, NoSuchMethodException {
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, context);
++
++ Scriptable localThis;
++ if (thiz == null) {
++ localThis = scope;
++ } else {
++ localThis = Context.toObject(thiz, scope);
++ }
++
++ Object f = ScriptableObject.getProperty(localThis, name);
++ if (f == Scriptable.NOT_FOUND) {
++ throw new NoSuchMethodException(name);
++ }
++ if (!(f instanceof Callable)) {
++ throw new ScriptException("\"" + name + "\" is not a function");
++ }
++ Callable func = (Callable) f;
++
++ if (args != null) {
++ for (int i = 0; i < args.length; i++) {
++ args[i] = Context.javaToJS(args[i], scope);
++ }
++ }
++
++ Object ret = func.call(cx, scope, localThis, args);
++ if (returnType == Void.TYPE) {
++ return null;
++ }
++ return Context.jsToJava(ret, returnType);
++
++ } catch (RhinoException re) {
++ throw new ScriptException(re.getMessage(), re.sourceName(), re.lineNumber(),
++ re.columnNumber());
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public T getInterface(Class clasz) {
++ if ((clasz == null) || !clasz.isInterface()) {
++ throw new IllegalArgumentException("Not an interface");
++ }
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, context);
++ if (methodsMissing(scope, clasz)) {
++ return null;
++ }
++ } catch (ScriptException se) {
++ return null;
++ } finally {
++ Context.exit();
++ }
++ return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
++ new Class>[]{clasz}, new RhinoInvocationHandler(this, null));
++ }
++
++ @Override
++ public T getInterface(Object thiz, Class clasz) {
++ if ((clasz == null) || !clasz.isInterface()) {
++ throw new IllegalArgumentException("Not an interface");
++ }
++ Context cx = ctxFactory.enterContext();
++ try {
++ Scriptable scope = initScope(cx, context);
++ Scriptable thisObj = Context.toObject(thiz, scope);
++ if (methodsMissing(thisObj, clasz)) {
++ return null;
++ }
++ } catch (ScriptException se) {
++ return null;
++ } finally {
++ Context.exit();
++ }
++ return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
++ new Class>[]{clasz}, new RhinoInvocationHandler(this, thiz));
++ }
++
++ @Override
++ public Bindings createBindings() {
++ return new SimpleBindings();
++ }
++
++ @Override
++ public ScriptEngineFactory getFactory() {
++ return factory;
++ }
++
++ private void configureContext(Context cx) throws ScriptException {
++ Object lv = get(ScriptEngine.LANGUAGE_VERSION);
++ if (lv != null) {
++ cx.setLanguageVersion(parseInteger(lv));
++ }
++ Object ol = get(OPTIMIZATION_LEVEL);
++ if (ol != null) {
++ cx.setOptimizationLevel(parseInteger(ol));
++ }
++ }
++
++ private int parseInteger(Object v) throws ScriptException {
++ if (v instanceof String) {
++ try {
++ return Integer.parseInt((String) v);
++ } catch (NumberFormatException nfe) {
++ throw new ScriptException("Invalid number " + v);
++ }
++ } else if (v instanceof Integer) {
++ return (Integer) v;
++ } else {
++ throw new ScriptException("Value must be a string or number");
++ }
++ }
++
++ private String getFilename() {
++ Object fn = get(ScriptEngine.FILENAME);
++ if (fn instanceof String) {
++ return (String) fn;
++ }
++ return DEFAULT_FILENAME;
++ }
++
++ private boolean methodsMissing(Scriptable scope, Class> clasz) {
++ for (Method m : clasz.getMethods()) {
++ if (m.getDeclaringClass() == Object.class) {
++ continue;
++ }
++ Object methodObj = ScriptableObject.getProperty(scope, m.getName());
++ if (!(methodObj instanceof Callable)) {
++ return true;
++ }
++ }
++ return false;
++ }
++
++ private static final class CtxFactory
++ extends ContextFactory {
++
++ @Override
++ protected void onContextCreated(Context cx) {
++ cx.setLanguageVersion(Context.VERSION_ES6);
++ cx.setOptimizationLevel(DEFAULT_OPT);
++ cx.setGeneratingDebug(DEFAULT_DEBUG);
++ }
++ }
++}
+--- /dev/null
++++ b/src/org/mozilla/javascript/engine/RhinoScriptEngineFactory.java
+@@ -0,0 +1,140 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++package org.mozilla.javascript.engine;
++
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.List;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineFactory;
++import org.mozilla.javascript.Context;
++
++/**
++ *
++ * This is an implementation of the standard Java "ScriptEngine" for Rhino. If the Rhino engine
++ * (typically in the form of the "rhino-engine" JAR) is in the classpath, then this script
++ * engine will be activated.
++ *
++ *
++ * See the list of constants in this class for the list of language names, file extensions, and
++ * MIME types that this engine supports. This list is essentially the same as the list supported
++ * in the Nashorn script engine that was included in Java 8.
++ *
++ *
++ * Since this engine and Nashorn support the same language and file extensions, then unless
++ * you are sure you are running in an environment that has Nashorn, the best way to get this
++ * engine is to call ScriptEngine.getEngineByName("rhino") to ask for Rhino directly.
++ *
++ */
++public class RhinoScriptEngineFactory
++ implements ScriptEngineFactory {
++
++ public static final String NAME = "rhino";
++ public static final String LANGUAGE = "javascript";
++ public static final List NAMES =
++ Arrays.asList("rhino", "Rhino", "javascript", "JavaScript");
++ public static final List EXTENSIONS =
++ Collections.singletonList("js");
++ public static final List MIME_TYPES =
++ Arrays.asList("application/javascript", "application/ecmascript",
++ "text/javascript", "text/ecmascript");
++ public static final String LANGUAGE_VERSION =
++ String.valueOf(RhinoScriptEngine.DEFAULT_LANGUAGE_VERSION);
++
++ @Override
++ public String getEngineName() {
++ return NAME;
++ }
++
++ @Override
++ public String getEngineVersion() {
++ Context cx = Context.enter();
++ try {
++ String v = cx.getImplementationVersion();
++ return (v == null ? "unknown" : v);
++ } finally {
++ Context.exit();
++ }
++ }
++
++ @Override
++ public List getExtensions() {
++ return EXTENSIONS;
++ }
++
++ @Override
++ public List getMimeTypes() {
++ return MIME_TYPES;
++ }
++
++ @Override
++ public List getNames() {
++ return NAMES;
++ }
++
++ @Override
++ public String getLanguageName() {
++ return LANGUAGE;
++ }
++
++ @Override
++ public String getLanguageVersion() {
++ return LANGUAGE_VERSION;
++ }
++
++ @Override
++ public Object getParameter(String key) {
++ switch (key) {
++ case ScriptEngine.ENGINE:
++ return getEngineName();
++ case ScriptEngine.ENGINE_VERSION:
++ return getEngineVersion();
++ case ScriptEngine.LANGUAGE:
++ return getLanguageName();
++ case ScriptEngine.LANGUAGE_VERSION:
++ return getLanguageVersion();
++ case ScriptEngine.NAME:
++ return NAME;
++ case "THREADING":
++ // Engines are explicitly not thread-safe
++ return null;
++ default:
++ return null;
++ }
++ }
++
++ @Override
++ public String getMethodCallSyntax(String obj, String m, String... args) {
++ StringBuilder sb = new StringBuilder();
++ sb.append(obj).append('.').append(m).append('(');
++ for (int i = 0; i < args.length; i++) {
++ if (i > 0) {
++ sb.append(',');
++ }
++ sb.append(args[i]);
++ }
++ sb.append(");");
++ return sb.toString();
++ }
++
++ @Override
++ public String getOutputStatement(String toDisplay) {
++ return "print('" + toDisplay + "');";
++ }
++
++ @Override
++ public String getProgram(String... statements) {
++ StringBuilder sb = new StringBuilder();
++ for (String stmt : statements) {
++ sb.append(stmt).append(";\n");
++ }
++ return sb.toString();
++ }
++
++ @Override
++ public ScriptEngine getScriptEngine() {
++ return new RhinoScriptEngine(this);
++ }
++}
+--- /dev/null
++++ b/testsrc/org/mozilla/javascript/tests/scriptengine/BuiltinsTest.java
+@@ -0,0 +1,54 @@
++package org.mozilla.javascript.tests.scriptengine;
++
++import java.io.StringWriter;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
++import javax.script.ScriptException;
++import javax.script.SimpleScriptContext;
++import org.junit.Before;
++import org.junit.BeforeClass;
++import org.junit.Test;
++import org.mozilla.javascript.engine.RhinoScriptEngineFactory;
++
++import static org.junit.Assert.*;
++
++public class BuiltinsTest {
++
++ private static ScriptEngineManager manager;
++
++ private ScriptEngine engine;
++
++ @BeforeClass
++ public static void init() {
++ manager = new ScriptEngineManager();
++ manager.registerEngineName("rhino", new RhinoScriptEngineFactory());
++ }
++
++ @Before
++ public void setup() {
++ engine = manager.getEngineByName("rhino");
++ }
++
++ @Test
++ public void testPrintStdout() throws ScriptException {
++ engine.eval("print('Hello, World!');");
++ }
++
++ @Test
++ public void testPrintWriter() throws ScriptException {
++ StringWriter sw = new StringWriter();
++ ScriptContext sc = new SimpleScriptContext();
++ sc.setWriter(sw);
++ engine.eval("print('one', 2, true);", sc);
++ assertEquals(sw.toString(), "one2true\n");
++ }
++
++ @Test
++ public void testPrintWriterGeneric() throws ScriptException {
++ StringWriter sw = new StringWriter();
++ engine.getContext().setWriter(sw);
++ engine.eval(engine.getFactory().getOutputStatement("Display This!"));
++ assertEquals(sw.toString(), "Display This!\n");
++ }
++}
+--- /dev/null
++++ b/testsrc/org/mozilla/javascript/tests/scriptengine/FactoryTest.java
+@@ -0,0 +1,56 @@
++package org.mozilla.javascript.tests.scriptengine;
++
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineFactory;
++import javax.script.ScriptEngineManager;
++import org.junit.Test;
++import org.mozilla.javascript.engine.RhinoScriptEngine;
++import org.mozilla.javascript.engine.RhinoScriptEngineFactory;
++
++import static org.junit.Assert.*;
++
++/*
++ * A series of tests that depend on us having our engine registered with the
++ * ScriptEngineManager by default.
++ */
++public class FactoryTest {
++
++ @Test
++ public void findRhinoFactory() {
++ ScriptEngineManager manager = new ScriptEngineManager();
++ for (ScriptEngineFactory factory : manager.getEngineFactories()) {
++ if (factory instanceof RhinoScriptEngineFactory) {
++ assertEquals("rhino", factory.getEngineName());
++ assertEquals("rhino", factory.getParameter(ScriptEngine.ENGINE));
++ assertEquals("rhino", factory.getParameter(ScriptEngine.NAME));
++ // This could be "unknown" if we're not running from a regular JAR
++ assertFalse(factory.getEngineVersion().isEmpty());
++ assertEquals("javascript", factory.getLanguageName());
++ assertEquals("javascript", factory.getParameter(ScriptEngine.LANGUAGE));
++ assertEquals("200", factory.getLanguageVersion());
++ assertEquals("200", factory.getParameter(ScriptEngine.LANGUAGE_VERSION));
++ assertNull(factory.getParameter("THREADING"));
++ assertTrue(factory.getExtensions().contains("js"));
++ assertTrue(factory.getMimeTypes().contains("application/javascript"));
++ assertTrue(factory.getMimeTypes().contains("application/ecmascript"));
++ assertTrue(factory.getMimeTypes().contains("text/javascript"));
++ assertTrue(factory.getMimeTypes().contains("text/ecmascript"));
++ assertTrue(factory.getNames().contains("rhino"));
++ assertTrue(factory.getNames().contains("Rhino"));
++ assertTrue(factory.getNames().contains("javascript"));
++ assertTrue(factory.getNames().contains("JavaScript"));
++ return;
++ }
++ }
++ fail("Expected to find Rhino script engine");
++ }
++
++ @Test
++ public void testRhinoFactory() {
++ // This will always uniquely return our engine.
++ // In Java 8, other ways to find it may return Nashorn.
++ ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
++ assertTrue(engine instanceof RhinoScriptEngine);
++
++ }
++}
+--- /dev/null
++++ b/testsrc/org/mozilla/javascript/tests/scriptengine/InvocableTest.java
+@@ -0,0 +1,158 @@
++package org.mozilla.javascript.tests.scriptengine;
++
++import java.io.FileNotFoundException;
++import java.io.FileReader;
++import javax.script.Invocable;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineManager;
++import javax.script.ScriptException;
++import org.junit.Before;
++import org.junit.BeforeClass;
++import org.junit.Test;
++import org.mozilla.javascript.engine.RhinoScriptEngineFactory;
++
++import static org.junit.Assert.*;
++
++public class InvocableTest {
++
++ private static ScriptEngineManager manager;
++
++ private ScriptEngine engine;
++ private Invocable iEngine;
++
++ @BeforeClass
++ public static void init() {
++ manager = new ScriptEngineManager();
++ manager.registerEngineName("rhino", new RhinoScriptEngineFactory());
++ }
++
++ @Before
++ public void setup() {
++ engine = manager.getEngineByName("rhino");
++ iEngine = (Invocable) engine;
++ }
++
++ @Test
++ public void invokeFunctionTest() throws ScriptException, NoSuchMethodException {
++ engine.eval("function foo(a, b) { return a + b; }");
++ Object result = iEngine.invokeFunction("foo", 2, 2);
++ assertEquals(result, 4L);
++ }
++
++ @Test
++ public void invokeScriptFunctionTest() throws ScriptException, NoSuchMethodException {
++ Object scriptObj = engine.eval("let o = {};\n"
++ + "o.test = function(x) { return x + 2; }\n"
++ + "o;");
++ assertEquals(4L, iEngine.invokeMethod(scriptObj, "test", 2));
++ }
++
++ @Test
++ public void invokeGenericFunctionTest() throws ScriptException, NoSuchMethodException {
++ engine.eval("let o = {};\n"
++ + "o.test = function(x) { return x + 2; }\n");
++ Object result = engine.eval(engine.getFactory().getMethodCallSyntax("o", "test", "1"));
++ assertEquals(3L, result);
++ }
++
++ @Test
++ public void invokeGenericFunctionTest2() throws ScriptException, NoSuchMethodException {
++ engine.eval("let o = {};\n"
++ + "o.test = function(x, y) { return x + y; }\n");
++ Object result = engine.eval(engine.getFactory().getMethodCallSyntax("o", "test", "1", "7"));
++ assertEquals(8L, result);
++ }
++
++ @Test
++ public void invokeMethodTest()
++ throws ScriptException, NoSuchMethodException, FileNotFoundException {
++ engine.eval(new FileReader("testsrc/assert.js"));
++ engine.eval("function FooObj() { this.x = 0; }\n"
++ + "FooObj.prototype.set = function(a, b) { this.x = a + b; }");
++ engine.eval("let f = new FooObj();\n"
++ + "assertEquals(f.x, 0);\n"
++ + "f.set(2, 2);\n"
++ + "assertEquals(f.x, 4);");
++
++ Object fooObj = engine.eval("let y = new FooObj(); y");
++ assertNotNull(fooObj);
++ iEngine.invokeMethod(fooObj, "set", 3, 3);
++ Object result = engine.eval("y.x");
++ assertEquals(result, 6L);
++ }
++
++ @Test
++ public void interfaceFunctionTest()
++ throws ScriptException, FileNotFoundException {
++ engine.eval(new FileReader("testsrc/assert.js"));
++ engine.eval("var foo = 'initialized';\n"
++ + "function setFoo(v) { foo = v; }\n"
++ + "function getFoo() { return foo; }\n"
++ + "function addItUp(a, b) { return a + b; }");
++ I tester = iEngine.getInterface(I.class);
++ assertEquals(tester.getFoo(), "initialized");
++ tester.setFoo("tested");
++ assertEquals(tester.getFoo(), "tested");
++ assertEquals(tester.addItUp(100, 1), 101);
++ }
++
++ @Test
++ public void interfaceMethodTest()
++ throws ScriptException, FileNotFoundException {
++ engine.eval(new FileReader("testsrc/assert.js"));
++ Object foo = engine.eval("function Foo() { this.foo = 'initialized' }\n"
++ + "Foo.prototype.setFoo = function(v) { this.foo = v; };\n"
++ + "Foo.prototype.getFoo = function() { return this.foo; };\n"
++ + "Foo.prototype.addItUp = function(a, b) { return a + b; };\n"
++ + "new Foo();");
++ I tester = iEngine.getInterface(foo, I.class);
++ assertEquals(tester.getFoo(), "initialized");
++ tester.setFoo("tested");
++ assertEquals(tester.getFoo(), "tested");
++ assertEquals(tester.addItUp(100, 1), 101);
++ }
++
++ @Test
++ public void interfaceFunctionMissingTest() {
++ I tester = iEngine.getInterface(I.class);
++ assertNull(tester);
++ }
++
++ @Test
++ public void interfaceMethodMissingTest()
++ throws ScriptException {
++ // Functions defined, but not on the right object
++ Object foo = engine.eval("var foo = 'initialized';\n"
++ + "function setFoo(v) { foo = v; }\n"
++ + "function getFoo() { return foo; }\n"
++ + "function addItUp(a, b) { return a + b; }\n"
++ + "function Foo() {}\n"
++ + "new Foo();");
++ I tester = iEngine.getInterface(foo, I.class);
++ assertNull(tester);
++ }
++
++ @Test
++ public void invokeNotFoundTest() {
++ assertThrows(NoSuchMethodException.class, () -> {
++ iEngine.invokeFunction("foo", 2, 2);
++ });
++ }
++
++ @Test
++ public void invokeNotFunctionTest() {
++ assertThrows(ScriptException.class, () -> {
++ engine.eval("foo = 'bar';");
++ iEngine.invokeFunction("foo", 2, 2);
++ });
++ }
++
++ interface I {
++
++ void setFoo(String v);
++
++ String getFoo();
++
++ int addItUp(int a, int b);
++ }
++}
+--- /dev/null
++++ b/testsrc/org/mozilla/javascript/tests/scriptengine/ScriptEngineTest.java
+@@ -0,0 +1,276 @@
++package org.mozilla.javascript.tests.scriptengine;
++
++import java.io.File;
++import java.io.FileReader;
++import java.io.IOException;
++import java.io.StringReader;
++import javax.script.Bindings;
++import javax.script.Compilable;
++import javax.script.CompiledScript;
++import javax.script.ScriptContext;
++import javax.script.ScriptEngine;
++import javax.script.ScriptEngineFactory;
++import javax.script.ScriptEngineManager;
++import javax.script.ScriptException;
++import javax.script.SimpleBindings;
++import javax.script.SimpleScriptContext;
++import org.junit.Before;
++import org.junit.BeforeClass;
++import org.junit.Test;
++import org.mozilla.javascript.engine.RhinoScriptEngine;
++import org.mozilla.javascript.engine.RhinoScriptEngineFactory;
++
++import static org.junit.Assert.*;
++
++public class ScriptEngineTest {
++
++ private static ScriptEngineManager manager;
++ private ScriptEngine engine;
++ private Compilable cEngine;
++
++ @BeforeClass
++ public static void initManager() {
++ manager = new ScriptEngineManager();
++ manager.registerEngineName("rhino", new RhinoScriptEngineFactory());
++ }
++
++ @Before
++ public void init() {
++ engine = manager.getEngineByName("rhino");
++ cEngine = (Compilable) engine;
++ }
++
++ @Test
++ public void testHello() throws ScriptException {
++ Object result = engine.eval("'Hello, World!';");
++ assertEquals(result, "Hello, World!");
++ }
++
++ @Test
++ public void testHelloInterpreted() throws ScriptException {
++ engine.put(RhinoScriptEngine.OPTIMIZATION_LEVEL, -1);
++ Object result = engine.eval("'Hello, World!';");
++ assertEquals(result, "Hello, World!");
++ }
++
++
++ @Test
++ public void testHelloReader() throws ScriptException {
++ String src = "1 + 1;";
++ StringReader sr = new StringReader(src);
++ Object result = engine.eval(sr);
++ assertEquals(result, 2L);
++ }
++
++ @Test
++ public void testGenericStatements() throws ScriptException {
++ Object result = engine.eval(engine.getFactory().getProgram(
++ "let x = 1;",
++ "let y = 2",
++ "x + y"
++ ));
++ assertEquals(3L, result);
++ }
++
++ @Test
++ public void testThrows() {
++ assertThrows(ScriptException.class, () -> {
++ engine.eval("throw 'This is an error'");
++ });
++ }
++
++ @Test
++ public void testEngineBindings() throws IOException, ScriptException {
++ engine.put("string", "Hello");
++ engine.put("integer", 123);
++ engine.put("a", "a");
++ engine.put("b", "b");
++ engine.put("c", "c");
++
++ // Ensure that stuff we just stuck in bindings made it to a global
++ engine.eval(new FileReader("testsrc/assert.js"));
++ engine.eval("assertEquals(string, 'Hello');\n"
++ + "assertEquals(integer, 123);\n"
++ + "string = 'Goodbye';\n"
++ + "assertEquals(string, 'Goodbye');");
++ assertEquals(engine.get("string"), "Goodbye");
++
++ // Make sure we can delete
++ engine.getBindings(ScriptContext.ENGINE_SCOPE).remove("string");
++ // This will throw because string is undefined
++ assertThrows(ScriptException.class, () -> {
++ engine.eval("let failing = string + '123';");
++ });
++ }
++
++ @Test
++ public void testEngineScope() throws IOException, ScriptException {
++ engine.put("string", "Hello");
++ engine.put("integer", 123);
++ engine.eval(new FileReader("testsrc/assert.js"));
++ engine.eval("assertEquals(string, 'Hello');"
++ + "assertEquals(integer, 123);");
++
++ // Additional things added to the context but old stuff still there
++ engine.put("second", true);
++ engine.put("integer", 99);
++ engine.eval("assertEquals(string, 'Hello');"
++ + "assertEquals(integer, 99);"
++ + "assertTrue(second);");
++ }
++
++ @Test
++ public void testScopedBindings() throws IOException, ScriptException {
++ ScriptContext sc = new SimpleScriptContext();
++
++ // We treat engine and global scope the same -- if the user actually
++ // uses both, then engine scope overrides global scope.
++ Bindings eb = new SimpleBindings();
++ sc.setBindings(eb, ScriptContext.ENGINE_SCOPE);
++ eb.put("engine", Boolean.TRUE);
++ eb.put("level", 2);
++
++ Bindings gb = new SimpleBindings();
++ sc.setBindings(gb, ScriptContext.GLOBAL_SCOPE);
++ gb.put("global", Boolean.TRUE);
++ gb.put("level", 0);
++
++ engine.eval(new FileReader("testsrc/assert.js"), sc);
++ engine.eval("assertTrue(engine);"
++ + "assertTrue(global);"
++ + "assertEquals(level, 2);", sc);
++ }
++
++ @Test
++ public void testReservedBindings() throws ScriptException {
++ engine.put(ScriptEngine.ENGINE, "engine");
++ engine.put(ScriptEngine.ENGINE_VERSION, "123");
++ engine.put(ScriptEngine.LANGUAGE, "foo");
++ engine.put(ScriptEngine.NAME, "nothing");
++
++ // Can't actually test for those invalid property names -- but
++ // at least they didn't break the script.
++ assertEquals(engine.eval("'success'"), "success");
++ }
++
++ @Test
++ public void testCompiled() throws ScriptException, IOException {
++ CompiledScript asserts =
++ cEngine.compile(new FileReader("testsrc/assert.js"));
++ CompiledScript tests =
++ cEngine.compile("assertEquals(compiled, true);");
++
++ // Fails because asserts have not been loaded
++ assertThrows(ScriptException.class, tests::eval);
++
++ asserts.eval();
++ // Fails because value has not been set
++ assertThrows(ScriptException.class, tests::eval);
++
++ engine.put("compiled", Boolean.TRUE);
++ tests.eval();
++ }
++
++ @Test
++ public void testCompiled2() throws ScriptException, IOException {
++ CompiledScript asserts =
++ cEngine.compile(new FileReader("testsrc/assert.js"));
++ CompiledScript init =
++ cEngine.compile("value = 0;");
++ CompiledScript tests =
++ cEngine.compile("assertEquals(value, expectedValue);"
++ + "value += 1;");
++
++ asserts.eval();
++ init.eval();
++ for (int i = 0; i <= 10; i++) {
++ engine.put("expectedValue", i);
++ tests.eval();
++ }
++ }
++
++ @Test
++ public void testCompiledThrows() throws ScriptException {
++ engine.put(ScriptEngine.FILENAME, "throws1.js");
++ CompiledScript throw1 = cEngine.compile("throw 'one';");
++ engine.put(ScriptEngine.FILENAME, "throws2.js");
++ CompiledScript throw2 = cEngine.compile("throw 'two';");
++
++ try {
++ throw1.eval();
++ fail("Expected a throw");
++ } catch (ScriptException se) {
++ assertTrue(se.getMessage().startsWith("one"));
++ assertEquals("throws1.js", se.getFileName());
++ assertEquals(1, se.getLineNumber());
++ }
++
++ try {
++ throw2.eval();
++ fail("Expected a throw");
++ } catch (ScriptException se) {
++ assertTrue(se.getMessage().startsWith("two"));
++ assertEquals("throws2.js", se.getFileName());
++ assertEquals(1, se.getLineNumber());
++ }
++ }
++
++ @Test
++ public void testCantCompile() {
++ assertThrows(ScriptException.class, () -> {
++ cEngine.compile("This is not JavaScript at all!");
++ });
++ }
++
++ @Test
++ public void testLanguageVersion() throws ScriptException {
++ // Default language version is modernish
++ ScriptEngine newEngine = manager.getEngineByName("rhino");
++ assertEquals(newEngine.eval("Symbol() == Symbol()"), Boolean.FALSE);
++
++ // Older language versions
++ ScriptEngine oldEngine = manager.getEngineByName("rhino");
++ oldEngine.put(ScriptEngine.LANGUAGE_VERSION, 120);
++ assertThrows(ScriptException.class, () -> {
++ oldEngine.eval("Symbol() == Symbol()");
++ });
++
++ // The same with a string
++ ScriptEngine olderEngine = manager.getEngineByName("rhino");
++ olderEngine.put(ScriptEngine.LANGUAGE_VERSION, "100");
++ assertThrows(ScriptException.class, () -> {
++ olderEngine.eval("Symbol() == Symbol()");
++ });
++ }
++
++ @Test
++ public void testBadLanguageVersion() {
++ assertThrows(ScriptException.class, () -> {
++ engine.put(ScriptEngine.LANGUAGE_VERSION, "Not a number");
++ engine.eval("print('Hi!');");
++ });
++ assertThrows(ScriptException.class, () -> {
++ engine.put(ScriptEngine.LANGUAGE_VERSION, 3.14);
++ engine.eval("print('Hi!');");
++ });
++ }
++
++ @Test
++ public void testFilename() {
++ engine.put(ScriptEngine.FILENAME, "test.js");
++ try {
++ engine.eval("throw 'This is an exception';");
++ } catch (ScriptException se) {
++ assertEquals(se.getFileName(), "test.js");
++ }
++ }
++
++ @Test
++ public void testJavaObject() throws ScriptException {
++ File f = new File("testsrc/assert.js");
++ String absVal = f.getAbsolutePath();
++ engine.put("file", f);
++ Object result = engine.eval("file.getAbsolutePath();");
++ assertEquals(absVal, result);
++ }
++}
+--- a/build.xml
++++ b/build.xml
+@@ -87,7 +87,9 @@
+ basedir="${classes}"
+ manifest="src/manifest"
+ compress="${jar-compression}"
+- />
++ >
++
++
+
+
+
diff -Nru rhino-1.7.7.1/debian/patches/series rhino-1.7.7.2/debian/patches/series
--- rhino-1.7.7.1/debian/patches/series 2017-01-20 09:53:06.000000000 +0000
+++ rhino-1.7.7.2/debian/patches/series 2021-02-08 09:51:49.000000000 +0000
@@ -2,3 +2,6 @@
05_modify-usage.patch
06_preserve-backward-compatibility.patch
07_fix-context-implementation-version.patch
+08_fix-jar-version-number.patch
+script-engine.patch
+
diff -Nru rhino-1.7.7.1/debian/rhino.manpages rhino-1.7.7.2/debian/rhino.manpages
--- rhino-1.7.7.1/debian/rhino.manpages 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/rhino.manpages 2020-09-03 11:36:47.000000000 +0000
@@ -1,3 +1,3 @@
-debian/rhino.1
-debian/rhino-jsc.1
debian/rhino-debugger.1
+debian/rhino-jsc.1
+debian/rhino.1
diff -Nru rhino-1.7.7.1/debian/rules rhino-1.7.7.2/debian/rules
--- rhino-1.7.7.1/debian/rules 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/rules 2021-02-08 10:39:26.000000000 +0000
@@ -7,7 +7,7 @@
dh $@ --with javahelper --with maven-repo-helper
override_dh_auto_build:
- dh_auto_build -- jar javadoc
+ dh_auto_build -- jar javadoc -Dsource-level=7 -Dtarget-jvm=7
override_dh_installchangelogs:
dh_installchangelogs -- RELEASE-NOTES.md
@@ -21,6 +21,3 @@
mv $(BUILDDIR)/javadoc $(BUILDDIR)/api
dh_install -plibrhino-java-doc $(BUILDDIR)/api /usr/share/doc/rhino/
-
-get-orig-source:
- uscan --force-download
diff -Nru rhino-1.7.7.1/debian/watch rhino-1.7.7.2/debian/watch
--- rhino-1.7.7.1/debian/watch 2017-01-19 17:45:23.000000000 +0000
+++ rhino-1.7.7.2/debian/watch 2020-09-03 11:36:47.000000000 +0000
@@ -1,3 +1,3 @@
version=4
opts=mode=git,compression=xz,uversionmangle=s/-RC/~RC/;s/pre/~pre/;s/_/./g;s/14R/1.4R/;s/140R/1.4.0R/;s/150R/1.5.0R/ \
-https://github.com/mozilla/rhino refs/tags/Rhino([\d_.R]+)_RELEASE
+https://github.com/mozilla/rhino refs/tags/Rhino([\d_.R]+)_(?:RELEASE|Release)
diff -Nru rhino-1.7.7.1/.gitignore rhino-1.7.7.2/.gitignore
--- rhino-1.7.7.1/.gitignore 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/.gitignore 2017-09-27 22:57:34.000000000 +0000
@@ -21,3 +21,4 @@
# eclipse
.classpath
.project
+test262
diff -Nru rhino-1.7.7.1/.gitmodules rhino-1.7.7.2/.gitmodules
--- rhino-1.7.7.1/.gitmodules 1970-01-01 00:00:00.000000000 +0000
+++ rhino-1.7.7.2/.gitmodules 2017-09-27 22:57:34.000000000 +0000
@@ -0,0 +1,3 @@
+[submodule "test262"]
+ path = test262
+ url = https://github.com/tc39/test262.git
diff -Nru rhino-1.7.7.1/gradle.properties rhino-1.7.7.2/gradle.properties
--- rhino-1.7.7.1/gradle.properties 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/gradle.properties 2017-09-27 22:57:34.000000000 +0000
@@ -1,7 +1,7 @@
#Sun, 26 Apr 2015 10:43:55 +0300
rootProject.name=rhino
group=org.mozilla
-version=1.7.7.1
+version=1.7.7.2
buildDir=buildGradle
mavenSnapshotRepo=https://oss.sonatype.org/content/repositories/snapshots
mavenReleaseRepo=https://oss.sonatype.org/service/local/staging/deploy/maven
diff -Nru rhino-1.7.7.1/maven/maven-snapshot-deploy.sh rhino-1.7.7.2/maven/maven-snapshot-deploy.sh
--- rhino-1.7.7.1/maven/maven-snapshot-deploy.sh 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/maven/maven-snapshot-deploy.sh 2017-09-27 22:57:34.000000000 +0000
@@ -1,7 +1,15 @@
#!/bin/sh
+deployFile=`ls ../buildGradle/libs/rhino*.jar`
+
+if [ ! -f $deployFile ]
+then
+ echo "File cannot be found in $deployFile"
+ exit 2
+fi
+
mvn deploy:deploy-file \
- -Dfile=../build/rhino1.7.7/js.jar \
+ -Dfile=${deployFile} \
-DpomFile=maven-pom.xml \
-DrepositoryId=sonatype-nexus-snapshots \
-Durl=https://oss.sonatype.org/content/repositories/snapshots/
diff -Nru rhino-1.7.7.1/maven/maven-staging-deploy.sh rhino-1.7.7.2/maven/maven-staging-deploy.sh
--- rhino-1.7.7.1/maven/maven-staging-deploy.sh 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/maven/maven-staging-deploy.sh 2017-09-27 22:57:34.000000000 +0000
@@ -7,9 +7,9 @@
pom=maven-pom.xml
jsjar=../buildGradle/libs/rhino-${vers}.jar
echo "Installing ${jsjar}"
-srczip=../rhino${vers}-sources.zip
+srczip=../buildGradle/libs/rhino-${vers}-sources.jar
echo "Sources are ${srczip}"
-doczip=../build/rhino${vers}/javadoc.zip
+doczip=../buildGradle/libs/rhino-${vers}-javadoc.jar
echo "Javadoc is ${doczip}"
if [ ! -f $jsjar ]
@@ -20,7 +20,7 @@
if [ ! -f $srczip ]
then
- echo "Missing rhino${vers}-sources.zip. Run \"ant source-zip\"."
+ echo "Missing rhino-${vers}-sources.zip. Run \"ant source-zip\"."
exit 2
fi
diff -Nru rhino-1.7.7.1/README.md rhino-1.7.7.2/README.md
--- rhino-1.7.7.1/README.md 2016-02-01 18:15:28.000000000 +0000
+++ rhino-1.7.7.2/README.md 2017-09-27 22:57:34.000000000 +0000
@@ -15,6 +15,7 @@