
org.mozilla.javascript.optimizer.ConsStringLinker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhino Show documentation
Show all versions of rhino Show documentation
Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically
embedded into Java applications to provide scripting to end users.
The newest version!
package org.mozilla.javascript.optimizer;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import jdk.dynalink.StandardNamespace;
import jdk.dynalink.StandardOperation;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.LinkRequest;
import jdk.dynalink.linker.LinkerServices;
import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.dynalink.linker.support.Guards;
import org.mozilla.javascript.ConsString;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
/**
* This linker optimizes:
*
*
* - "+" operations when the LHS is a ConsString and the RHS is any kind of CharSequence object
* (either a String or ConsString)
*
- accesses to the "length" property of a ConsString.
*
*/
@SuppressWarnings("AndroidJdkLibsChecker")
class ConsStringLinker implements TypeBasedGuardingDynamicLinker {
@Override
public boolean canLinkType(Class> type) {
return ConsString.class.equals(type);
}
@Override
public GuardedInvocation getGuardedInvocation(LinkRequest req, LinkerServices svc)
throws Exception {
if (req.isCallSiteUnstable()) {
return null;
}
Object arg2 = null;
if (req.getArguments().length > 1) {
arg2 = req.getArguments()[1];
}
MethodHandles.Lookup lookup = MethodHandles.lookup();
ParsedOperation op = new ParsedOperation(req.getCallSiteDescriptor().getOperation());
MethodType mType = req.getCallSiteDescriptor().getMethodType();
MethodHandle mh = null;
MethodHandle guard = null;
if (op.isNamespace(RhinoNamespace.MATH)) {
if (op.isOperation(RhinoOperation.ADD)) {
MethodType guardType = mType.changeReturnType(Boolean.TYPE);
if (arg2 instanceof CharSequence) {
mh = lookup.findStatic(ConsStringLinker.class, "add", mType);
guard = lookup.findStatic(ConsStringLinker.class, "testAdd", guardType);
}
}
} else if (op.isNamespace(StandardNamespace.PROPERTY)) {
if (op.isOperation(StandardOperation.GET, RhinoOperation.GETNOWARN)
&& "length".equals(op.getName())) {
mh = lookup.findStatic(ConsStringLinker.class, "getLength", mType);
guard = Guards.getInstanceOfGuard(ConsString.class);
}
}
if (mh != null) {
assert guard != null;
if (DefaultLinker.DEBUG) {
System.out.println(op + " ConsString operation");
}
return new GuardedInvocation(mh, guard);
}
return null;
}
@SuppressWarnings("unused")
private static boolean testAdd(Object lval, Object rval, Context cx) {
return lval instanceof ConsString && rval instanceof CharSequence;
}
@SuppressWarnings("unused")
private static Object add(Object lval, Object rval, Context cx) {
return new ConsString((ConsString) lval, ((CharSequence) rval).toString());
}
@SuppressWarnings("unused")
private static Object getLength(Object o, Context cx, Scriptable scope) {
return ((ConsString) o).length();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy