Skip to content

Commit 1b4a302

Browse files
committed
LiveConnect optional
1 parent 9abbdef commit 1b4a302

File tree

5 files changed

+177
-123
lines changed

5 files changed

+177
-123
lines changed

rhino-tools/src/main/java/org/mozilla/javascript/tools/shell/Environment.java

Lines changed: 76 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,95 +14,94 @@
1414

1515
package org.mozilla.javascript.tools.shell;
1616

17+
import java.util.Map;
1718
import org.mozilla.javascript.Context;
1819
import org.mozilla.javascript.LambdaConstructor;
1920
import org.mozilla.javascript.NativeArray;
2021
import org.mozilla.javascript.ScriptRuntime;
2122
import org.mozilla.javascript.Scriptable;
2223
import org.mozilla.javascript.ScriptableObject;
2324

24-
import java.util.Map;
25-
2625
/**
2726
* Environment, intended to be instantiated at global scope, provides a natural way to access System
2827
* properties from JavaScript.
2928
*
3029
* @author Patrick C. Beard
3130
*/
3231
public class Environment extends ScriptableObject {
33-
static final long serialVersionUID = -430727378460177065L;
34-
35-
private Environment thePrototypeInstance = null;
36-
private static final String CLASS_NAME = "Environment";
37-
38-
static Object init(Context cx, ScriptableObject scope, boolean sealed) {
39-
LambdaConstructor ctor = new LambdaConstructor(scope, CLASS_NAME, 1, Environment::new);
40-
41-
var proto = new NativeArray(0);
42-
ctor.setPrototypeScriptable(proto);
43-
Environment environment = new Environment(cx, scope, new Object[0]);
44-
scope.defineProperty("environment", environment, ScriptableObject.DONTENUM);
45-
if (sealed) {
46-
ctor.sealObject();
47-
((ScriptableObject) ctor.getPrototypeProperty()).sealObject();
48-
}
49-
return ctor;
50-
}
51-
52-
@Override
53-
public String getClassName() {
54-
return CLASS_NAME;
55-
}
56-
57-
public Environment() {
58-
if (thePrototypeInstance == null) thePrototypeInstance = this;
59-
}
60-
61-
public Environment(Context cx, Scriptable scope, Object[] args) {
62-
setParentScope(scope);
63-
Object ctor = ScriptRuntime.getTopLevelProp(scope, "Environment");
64-
if (ctor != null && ctor instanceof Scriptable) {
65-
Scriptable s = (Scriptable) ctor;
66-
setPrototype((Scriptable) s.get("prototype", s));
67-
}
68-
}
69-
70-
@Override
71-
public boolean has(String name, Scriptable start) {
72-
if (this == thePrototypeInstance) return super.has(name, start);
73-
74-
return (System.getProperty(name) != null);
75-
}
76-
77-
@Override
78-
public Object get(String name, Scriptable start) {
79-
if (this == thePrototypeInstance) return super.get(name, start);
80-
81-
String result = System.getProperty(name);
82-
if (result != null) return ScriptRuntime.toObject(getParentScope(), result);
83-
else return Scriptable.NOT_FOUND;
84-
}
85-
86-
@Override
87-
public void put(String name, Scriptable start, Object value) {
88-
if (this == thePrototypeInstance) super.put(name, start, value);
89-
else System.getProperties().put(name, ScriptRuntime.toString(value));
90-
}
91-
92-
private Object[] collectIds() {
93-
Map<Object, Object> props = System.getProperties();
94-
return props.keySet().toArray();
95-
}
96-
97-
@Override
98-
public Object[] getIds() {
99-
if (this == thePrototypeInstance) return super.getIds();
100-
return collectIds();
101-
}
102-
103-
@Override
104-
public Object[] getAllIds() {
105-
if (this == thePrototypeInstance) return super.getAllIds();
106-
return collectIds();
107-
}
32+
static final long serialVersionUID = -430727378460177065L;
33+
34+
private Environment thePrototypeInstance = null;
35+
private static final String CLASS_NAME = "Environment";
36+
37+
static Object init(Context cx, ScriptableObject scope, boolean sealed) {
38+
LambdaConstructor ctor = new LambdaConstructor(scope, CLASS_NAME, 1, Environment::new);
39+
40+
var proto = new NativeArray(0);
41+
ctor.setPrototypeScriptable(proto);
42+
Environment environment = new Environment(cx, scope, new Object[0]);
43+
scope.defineProperty("environment", environment, ScriptableObject.DONTENUM);
44+
if (sealed) {
45+
ctor.sealObject();
46+
((ScriptableObject) ctor.getPrototypeProperty()).sealObject();
47+
}
48+
return ctor;
49+
}
50+
51+
@Override
52+
public String getClassName() {
53+
return CLASS_NAME;
54+
}
55+
56+
public Environment() {
57+
if (thePrototypeInstance == null) thePrototypeInstance = this;
58+
}
59+
60+
public Environment(Context cx, Scriptable scope, Object[] args) {
61+
setParentScope(scope);
62+
Object ctor = ScriptRuntime.getTopLevelProp(scope, "Environment");
63+
if (ctor != null && ctor instanceof Scriptable) {
64+
Scriptable s = (Scriptable) ctor;
65+
setPrototype((Scriptable) s.get("prototype", s));
66+
}
67+
}
68+
69+
@Override
70+
public boolean has(String name, Scriptable start) {
71+
if (this == thePrototypeInstance) return super.has(name, start);
72+
73+
return (System.getProperty(name) != null);
74+
}
75+
76+
@Override
77+
public Object get(String name, Scriptable start) {
78+
if (this == thePrototypeInstance) return super.get(name, start);
79+
80+
String result = System.getProperty(name);
81+
if (result != null) return ScriptRuntime.toObject(getParentScope(), result);
82+
else return Scriptable.NOT_FOUND;
83+
}
84+
85+
@Override
86+
public void put(String name, Scriptable start, Object value) {
87+
if (this == thePrototypeInstance) super.put(name, start, value);
88+
else System.getProperties().put(name, ScriptRuntime.toString(value));
89+
}
90+
91+
private Object[] collectIds() {
92+
Map<Object, Object> props = System.getProperties();
93+
return props.keySet().toArray();
94+
}
95+
96+
@Override
97+
public Object[] getIds() {
98+
if (this == thePrototypeInstance) return super.getIds();
99+
return collectIds();
100+
}
101+
102+
@Override
103+
public Object[] getAllIds() {
104+
if (this == thePrototypeInstance) return super.getAllIds();
105+
return collectIds();
106+
}
108107
}

rhino-tools/src/main/java/org/mozilla/javascript/tools/shell/Global.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ public void init(Context cx) {
245245

246246
// Set up "environment" in the global scope to provide access to the
247247
// System environment variables.
248-
Environment.init(cx,this, false);
248+
Environment.init(cx, this, false);
249249

250250
history = (NativeArray) cx.newArray(this, 0);
251251
defineProperty("history", history, ScriptableObject.DONTENUM);

rhino/src/main/java/org/mozilla/javascript/Context.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,12 @@ public static Object javaToJS(Object value, Scriptable scope, Context cx) {
18361836
*/
18371837
@Deprecated
18381838
public static Object jsToJava(Object value, Class<?> desiredType) throws EvaluatorException {
1839+
if (desiredType == Object.class) {
1840+
return ScriptRuntime.jsToJavaObject(value);
1841+
}
1842+
if (desiredType == String.class) {
1843+
return ScriptRuntime.jsToJavaString(value);
1844+
}
18391845
return LcBridge.instance.jsToJava(value, desiredType);
18401846
}
18411847

rhino/src/main/java/org/mozilla/javascript/LazilyLoadedCtor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ private static Object buildUsingReflection(
144144
Class<? extends Scriptable> cl = cast(Kit.classOrNull(className));
145145
if (cl != null) {
146146
try {
147+
if (LcBridge.instance == null) {
148+
throw new IllegalStateException(
149+
"LiveConnect for " + className + "." + propertyName + " not present");
150+
}
147151
Object value = LcBridge.instance.buildClassCtor(scope, cl, sealed, false);
148152
if (value != null) {
149153
return value;

rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java

Lines changed: 90 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ public static ScriptableObject initSafeStandardObjects(
165165
}
166166

167167
scope.associateValue(LIBRARY_SCOPE_KEY, scope);
168-
LcBridge.instance.associateClassCache(scope);
168+
if (LcBridge.instance != null) {
169+
LcBridge.instance.associateClassCache(scope);
170+
}
169171

170172
LambdaConstructor function = BaseFunction.init(cx, scope, sealed);
171173
LambdaConstructor obj = NativeObject.init(scope, sealed);
@@ -211,13 +213,14 @@ public static ScriptableObject initSafeStandardObjects(
211213
NativeStringIterator.init(scope, sealed);
212214
registerRegExp(cx, scope, sealed);
213215

214-
LcBridge.instance.init(scope, sealed);
216+
if (LcBridge.instance != null) {
217+
LcBridge.instance.init(scope, sealed);
218+
}
215219

216220
// define lazy-loaded properties using their class name
217221
// Depends on the old reflection-based lazy loading mechanism
218222
// to property initialize the prototype.
219-
new LazilyLoadedCtor(
220-
scope, "Continuation", sealed, true, NativeContinuation::init);
223+
new LazilyLoadedCtor(scope, "Continuation", sealed, true, NativeContinuation::init);
221224

222225
if (cx.hasFeature(Context.FEATURE_E4X)) {
223226
if (xmlLoaderImpl != null) {
@@ -1052,6 +1055,43 @@ public static String jsToJavaString(Object val) {
10521055
}
10531056
}
10541057

1058+
public static Object jsToJavaObject(Object val) {
1059+
for (; ; ) {
1060+
if (val == null) {
1061+
return null;
1062+
}
1063+
if (Undefined.isUndefined(val)) {
1064+
return "undefined";
1065+
}
1066+
1067+
if (val instanceof Long) {
1068+
return val;
1069+
}
1070+
if (val instanceof BigInteger) {
1071+
return val;
1072+
}
1073+
if (val instanceof Number) {
1074+
double d = ((Number) val).doubleValue();
1075+
Context context = Context.getCurrentContext();
1076+
if ((context != null)
1077+
&& context.hasFeature(Context.FEATURE_INTEGER_WITHOUT_DECIMAL_PLACE)) {
1078+
// to process numbers like 2.0 as 2 without decimal place
1079+
long roundedValue = Math.round(d);
1080+
if (roundedValue == d) {
1081+
1082+
return Long.valueOf(roundedValue);
1083+
}
1084+
}
1085+
return Double.valueOf(d);
1086+
}
1087+
if (val instanceof Wrapper) {
1088+
val = ((Wrapper) val).unwrap();
1089+
} else {
1090+
return val;
1091+
}
1092+
}
1093+
}
1094+
10551095
static String defaultObjectToString(Scriptable obj) {
10561096
if (obj == null) return "[object Null]";
10571097
if (Undefined.isUndefined(obj)) return "[object Undefined]";
@@ -4723,7 +4763,10 @@ private static boolean compareTo(double d1, double d2, int op) {
47234763
// ------------------
47244764

47254765
public static ScriptableObject getGlobal(Context cx) {
4726-
return LcBridge.instance.getGlobal(cx);
4766+
if (LcBridge.instance != null) {
4767+
return LcBridge.instance.getGlobal(cx);
4768+
}
4769+
return new TopLevel();
47274770
}
47284771

47294772
public static boolean hasTopCall(Context cx) {
@@ -5084,26 +5127,27 @@ public static Scriptable newCatchScope(
50845127
if (errorObject instanceof NativeError) {
50855128
((NativeError) errorObject).setStackProvider(re);
50865129
}
5087-
5088-
if (javaException != null && isVisible(cx, javaException)) {
5089-
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
5090-
ScriptableObject.defineProperty(
5091-
errorObject,
5092-
"javaException",
5093-
wrap,
5094-
ScriptableObject.PERMANENT
5095-
| ScriptableObject.READONLY
5096-
| ScriptableObject.DONTENUM);
5097-
}
5098-
if (isVisible(cx, re)) {
5099-
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
5100-
ScriptableObject.defineProperty(
5101-
errorObject,
5102-
"rhinoException",
5103-
wrap,
5104-
ScriptableObject.PERMANENT
5105-
| ScriptableObject.READONLY
5106-
| ScriptableObject.DONTENUM);
5130+
if (LcBridge.instance != null) {
5131+
if (javaException != null && isVisible(cx, javaException)) {
5132+
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
5133+
ScriptableObject.defineProperty(
5134+
errorObject,
5135+
"javaException",
5136+
wrap,
5137+
ScriptableObject.PERMANENT
5138+
| ScriptableObject.READONLY
5139+
| ScriptableObject.DONTENUM);
5140+
}
5141+
if (isVisible(cx, re)) {
5142+
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
5143+
ScriptableObject.defineProperty(
5144+
errorObject,
5145+
"rhinoException",
5146+
wrap,
5147+
ScriptableObject.PERMANENT
5148+
| ScriptableObject.READONLY
5149+
| ScriptableObject.DONTENUM);
5150+
}
51075151
}
51085152
obj = errorObject;
51095153
}
@@ -5183,26 +5227,27 @@ public static Scriptable wrapException(Throwable t, Scriptable scope, Context cx
51835227
if (errorObject instanceof NativeError) {
51845228
((NativeError) errorObject).setStackProvider(re);
51855229
}
5186-
5187-
if (javaException != null && isVisible(cx, javaException)) {
5188-
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
5189-
ScriptableObject.defineProperty(
5190-
errorObject,
5191-
"javaException",
5192-
wrap,
5193-
ScriptableObject.PERMANENT
5194-
| ScriptableObject.READONLY
5195-
| ScriptableObject.DONTENUM);
5196-
}
5197-
if (isVisible(cx, re)) {
5198-
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
5199-
ScriptableObject.defineProperty(
5200-
errorObject,
5201-
"rhinoException",
5202-
wrap,
5203-
ScriptableObject.PERMANENT
5204-
| ScriptableObject.READONLY
5205-
| ScriptableObject.DONTENUM);
5230+
if (LcBridge.instance != null) {
5231+
if (javaException != null && isVisible(cx, javaException)) {
5232+
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
5233+
ScriptableObject.defineProperty(
5234+
errorObject,
5235+
"javaException",
5236+
wrap,
5237+
ScriptableObject.PERMANENT
5238+
| ScriptableObject.READONLY
5239+
| ScriptableObject.DONTENUM);
5240+
}
5241+
if (isVisible(cx, re)) {
5242+
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
5243+
ScriptableObject.defineProperty(
5244+
errorObject,
5245+
"rhinoException",
5246+
wrap,
5247+
ScriptableObject.PERMANENT
5248+
| ScriptableObject.READONLY
5249+
| ScriptableObject.DONTENUM);
5250+
}
52065251
}
52075252
return errorObject;
52085253
}

0 commit comments

Comments
 (0)