Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the whole LiveConnect initializion in "initStandardObjects" #1677

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion rhino/src/main/java/org/mozilla/javascript/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -1749,7 +1749,8 @@ public static Object javaToJS(Object value, Scriptable scope, Context cx) {
if (value instanceof String
|| value instanceof Number
|| value instanceof Boolean
|| value instanceof Scriptable) {
|| value instanceof Scriptable
|| value instanceof Undefined) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not pass undefined to wrapperFactory

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on the 'why' of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined is already a js compatible object, so I think, it does not need a javaToJs conversion.

Background: I plan to make the wrapperFactory optional (no wrapperFactory == no liveConnect) and I found some failing tests, that have passed undefined here, although they do not use use liveConnect

If value is an instance of String, Number, Boolean, Function or Scriptable, it is returned
as it and will be treated as the corresponding JavaScript type of string, number, boolean,
function and object.

I will line up the code with the documentation. (Function mentioned in doc, but not handled in code) and maybe extract this in a separate commit.

return value;
} else if (value instanceof Character) {
return String.valueOf(((Character) value).charValue());
Expand Down
20 changes: 0 additions & 20 deletions rhino/src/main/java/org/mozilla/javascript/MemberBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,6 @@ Class<?> getDeclaringClass() {
return memberObject.getDeclaringClass();
}

String toJavaDeclaration() {
StringBuilder sb = new StringBuilder();
if (isMethod()) {
Method method = method();
sb.append(method.getReturnType());
sb.append(' ');
sb.append(method.getName());
} else {
Constructor<?> ctor = ctor();
String name = ctor.getDeclaringClass().getName();
int lastDot = name.lastIndexOf('.');
if (lastDot >= 0) {
name = name.substring(lastDot + 1);
}
sb.append(name);
}
sb.append(JavaMembers.liveConnectSignature(argTypes));
return sb.toString();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a liveconnect only thing, so I moved it away from here

}

@Override
public String toString() {
return memberObject.toString();
Expand Down
23 changes: 22 additions & 1 deletion rhino/src/main/java/org/mozilla/javascript/NativeJavaMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.mozilla.javascript;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.EnumSet;
Expand Down Expand Up @@ -424,7 +425,7 @@ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) {
bestFitIndex = extraBestFits[j];
}
buf.append("\n ");
buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration());
buf.append(toJavaDeclaration(methodsOrCtors[bestFitIndex]));
}

MemberBox firstFitMember = methodsOrCtors[firstBestFit];
Expand All @@ -443,6 +444,26 @@ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) {
buf.toString());
}

private static String toJavaDeclaration(MemberBox memberBox) {
StringBuilder sb = new StringBuilder();
if (memberBox.isMethod()) {
Method method = memberBox.method();
sb.append(method.getReturnType());
sb.append(' ');
sb.append(method.getName());
} else {
Constructor<?> ctor = memberBox.ctor();
String name = ctor.getDeclaringClass().getName();
int lastDot = name.lastIndexOf('.');
if (lastDot >= 0) {
name = name.substring(lastDot + 1);
}
sb.append(name);
}
sb.append(JavaMembers.liveConnectSignature(memberBox.argTypes));
return sb.toString();
}

/** Types are equal */
private static final int PREFERENCE_EQUAL = 0;

Expand Down
118 changes: 65 additions & 53 deletions rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ public static ScriptableObject initSafeStandardObjects(
}

scope.associateValue(LIBRARY_SCOPE_KEY, scope);
new ClassCache().associate(scope);

BaseFunction.init(cx, scope, sealed);
NativeObject.init(scope, sealed);
Expand Down Expand Up @@ -190,25 +189,13 @@ public static ScriptableObject initSafeStandardObjects(
NativeStringIterator.init(scope, sealed);

NativeJavaObject.init(scope, sealed);
NativeJavaMap.init(scope, sealed);

boolean withXml =
cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null;

// define lazy-loaded properties using their class name
new LazilyLoadedCtor(
scope, "RegExp", "org.mozilla.javascript.regexp.NativeRegExp", sealed, true);
new LazilyLoadedCtor(
scope, "Continuation", "org.mozilla.javascript.NativeContinuation", sealed, true);

if (withXml) {
String xmlImpl = cx.getE4xImplementationFactory().getImplementationClassName();
new LazilyLoadedCtor(scope, "XML", xmlImpl, sealed, true);
new LazilyLoadedCtor(scope, "XMLList", xmlImpl, sealed, true);
new LazilyLoadedCtor(scope, "Namespace", xmlImpl, sealed, true);
new LazilyLoadedCtor(scope, "QName", xmlImpl, sealed, true);
}

if (((cx.getLanguageVersion() >= Context.VERSION_1_8)
&& cx.hasFeature(Context.FEATURE_V8_EXTENSIONS))
|| (cx.getLanguageVersion() >= Context.VERSION_ES6)) {
Expand Down Expand Up @@ -299,10 +286,32 @@ public static ScriptableObject initSafeStandardObjects(
return scope;
}

public static boolean isLiveConnectEnabled(Scriptable scope) {
return Boolean.TRUE.equals(ScriptableObject.getTopScopeValue(scope, LIVE_CONNECT_ENABLED));
}

public static ScriptableObject initStandardObjects(
Context cx, ScriptableObject scope, boolean sealed) {
ScriptableObject s = initSafeStandardObjects(cx, scope, sealed);

// The following obects are "unsafe", as they allow access to java classes with reflection
s.associateValue(LIVE_CONNECT_ENABLED, Boolean.TRUE);
new ClassCache().associate(s);

NativeJavaObject.init(s, sealed);
NativeJavaMap.init(s, sealed);

boolean withXml =
cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null;

if (withXml) {
String xmlImpl = cx.getE4xImplementationFactory().getImplementationClassName();
new LazilyLoadedCtor(s, "XML", xmlImpl, sealed, true);
new LazilyLoadedCtor(s, "XMLList", xmlImpl, sealed, true);
new LazilyLoadedCtor(s, "Namespace", xmlImpl, sealed, true);
new LazilyLoadedCtor(s, "QName", xmlImpl, sealed, true);
}

new LazilyLoadedCtor(
s, "Packages", "org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
new LazilyLoadedCtor(
Expand Down Expand Up @@ -1453,6 +1462,7 @@ public static Optional<Double> canonicalNumericIndexString(String arg) {
// XXX: this is until setDefaultNamespace will learn how to store NS
// properly and separates namespace form Scriptable.get etc.
private static final String DEFAULT_NS_TAG = "__default_namespace__";
private static final String LIVE_CONNECT_ENABLED = "__live_connect_enabled__";

public static Object setDefaultNamespace(Object namespace, Context cx) {
Scriptable scope = cx.currentActivationCall;
Expand Down Expand Up @@ -4402,26 +4412,27 @@ public static Scriptable newCatchScope(
if (errorObject instanceof NativeError) {
((NativeError) errorObject).setStackProvider(re);
}

if (javaException != null && isVisible(cx, javaException)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
ScriptableObject.defineProperty(
errorObject,
"javaException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
if (isVisible(cx, re)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
ScriptableObject.defineProperty(
errorObject,
"rhinoException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
if (ScriptRuntime.isLiveConnectEnabled(scope)) {
if (javaException != null && isVisible(cx, javaException)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not declare these additional properties, when the scope does not support liveConnect

Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
ScriptableObject.defineProperty(
errorObject,
"javaException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
if (isVisible(cx, re)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
ScriptableObject.defineProperty(
errorObject,
"rhinoException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
}
obj = errorObject;
}
Expand Down Expand Up @@ -4501,26 +4512,27 @@ public static Scriptable wrapException(Throwable t, Scriptable scope, Context cx
if (errorObject instanceof NativeError) {
((NativeError) errorObject).setStackProvider(re);
}

if (javaException != null && isVisible(cx, javaException)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
ScriptableObject.defineProperty(
errorObject,
"javaException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
if (isVisible(cx, re)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
ScriptableObject.defineProperty(
errorObject,
"rhinoException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
if (ScriptRuntime.isLiveConnectEnabled(scope)) {
if (javaException != null && isVisible(cx, javaException)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null);
ScriptableObject.defineProperty(
errorObject,
"javaException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
if (isVisible(cx, re)) {
Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
ScriptableObject.defineProperty(
errorObject,
"rhinoException",
wrap,
ScriptableObject.PERMANENT
| ScriptableObject.READONLY
| ScriptableObject.DONTENUM);
}
}
return errorObject;
}
Expand Down
Loading