aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/lookup
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/lookup')
-rw-r--r--src/jdk/nashorn/internal/lookup/Lookup.java56
-rw-r--r--src/jdk/nashorn/internal/lookup/MethodHandleFactory.java380
-rw-r--r--src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java25
3 files changed, 219 insertions, 242 deletions
diff --git a/src/jdk/nashorn/internal/lookup/Lookup.java b/src/jdk/nashorn/internal/lookup/Lookup.java
index 0dd2741e..57728509 100644
--- a/src/jdk/nashorn/internal/lookup/Lookup.java
+++ b/src/jdk/nashorn/internal/lookup/Lookup.java
@@ -68,6 +68,12 @@ public final class Lookup {
/** Method handle to the most generic of setters, the one that takes an Object */
public static final MethodType SET_OBJECT_TYPE = MH.type(void.class, Object.class, Object.class);
+ /** Method handle to the primitive getters, the one that returns an long/int/double */
+ public static final MethodType GET_PRIMITIVE_TYPE = MH.type(long.class, Object.class);
+
+ /** Method handle to the primitive getters, the one that returns an long/int/double */
+ public static final MethodType SET_PRIMITIVE_TYPE = MH.type(void.class, Object.class, long.class);
+
private Lookup() {
}
@@ -123,6 +129,53 @@ public final class Lookup {
}
/**
+ * This method filters primitive argument types using JavaScript semantics. For example,
+ * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
+ * If you are returning values to JavaScript that have to be of a specific type, this is
+ * the correct return value filter to use, as the explicitCastArguments just uses the
+ * Java boxing equivalents
+ *
+ * @param mh method handle for which to filter argument value
+ * @param n argument index
+ * @param from old argument type, the new one is given by the sent method handle
+ * @return method handle for appropriate argument type conversion
+ */
+ public static MethodHandle filterArgumentType(final MethodHandle mh, final int n, final Class<?> from) {
+ final Class<?> to = mh.type().parameterType(n);
+
+ if (from == int.class) {
+ //fallthru
+ } else if (from == long.class) {
+ if (to == int.class) {
+ return MH.filterArguments(mh, n, JSType.TO_INT32_L.methodHandle());
+ }
+ //fallthru
+ } else if (from == double.class) {
+ if (to == int.class) {
+ return MH.filterArguments(mh, n, JSType.TO_INT32_D.methodHandle());
+ } else if (to == long.class) {
+ return MH.filterArguments(mh, n, JSType.TO_UINT32_D.methodHandle());
+ }
+ //fallthru
+ } else if (!from.isPrimitive()) {
+ if (to == int.class) {
+ return MH.filterArguments(mh, n, JSType.TO_INT32.methodHandle());
+ } else if (to == long.class) {
+ return MH.filterArguments(mh, n, JSType.TO_UINT32.methodHandle());
+ } else if (to == double.class) {
+ return MH.filterArguments(mh, n, JSType.TO_NUMBER.methodHandle());
+ } else if (!to.isPrimitive()) {
+ return mh;
+ }
+
+ assert false : "unsupported Lookup.filterReturnType type " + from + " -> " + to;
+ }
+
+ //use a standard cast - we don't need to check JavaScript special cases
+ return MH.explicitCastArguments(mh, mh.type().changeParameterType(n, from));
+ }
+
+ /**
* This method filters primitive return types using JavaScript semantics. For example,
* an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
* If you are returning values to JavaScript that have to be of a specific type, this is
@@ -139,6 +192,9 @@ public final class Lookup {
if (retType == int.class) {
//fallthru
} else if (retType == long.class) {
+ if (type == int.class) {
+ return MH.filterReturnValue(mh, JSType.TO_INT32_L.methodHandle());
+ }
//fallthru
} else if (retType == double.class) {
if (type == int.class) {
diff --git a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
index 34fe2eb6..8ef13d79 100644
--- a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
+++ b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
@@ -37,9 +37,12 @@ import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug;
-import jdk.nashorn.internal.runtime.DebugLogger;
import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.options.Options;
/**
@@ -96,27 +99,9 @@ public final class MethodHandleFactory {
return obj.toString();
}
- private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
- private static final MethodHandleFunctionality FUNC;
-
- private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
- private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
-
- static {
- if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
- if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
- FUNC = new TraceCreateMethodHandleFunctionality();
- } else {
- FUNC = new TraceMethodHandleFunctionality();
- }
- } else {
- FUNC = STANDARD;
- }
- }
-
+ private static final MethodHandleFunctionality FUNC = new StandardMethodHandleFunctionality();
private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
-
/**
* Return the method handle functionality used for all method handle operations
* @return a method handle functionality implementation
@@ -125,8 +110,11 @@ public final class MethodHandleFactory {
return FUNC;
}
- private static final MethodHandle TRACE = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
- private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
+ private static final MethodHandle TRACE = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
+ private static final MethodHandle TRACE_RETURN = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
+ private static final MethodHandle TRACE_RETURN_VOID = FUNC.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturnVoid", MethodType.methodType(void.class, DebugLogger.class));
+
+ private static final String VOID_TAG = "[VOID]";
/**
* Tracer that is applied before a value is returned from the traced function. It will output the return
@@ -136,11 +124,20 @@ public final class MethodHandleFactory {
* @return return value unmodified
*/
static Object traceReturn(final DebugLogger logger, final Object value) {
- final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']');
- logger.log(TRACE_LEVEL, str);
+ if (logger.isEnabled()) {
+ final String str = " return" +
+ (VOID_TAG.equals(value) ?
+ ";" :
+ " " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
+ logger.log(TRACE_LEVEL, str);
+ }
return value;
}
+ static void traceReturnVoid(final DebugLogger logger) {
+ traceReturn(logger, VOID_TAG);
+ }
+
/**
* Tracer that is applied before a function is called, printing the arguments
*
@@ -203,7 +200,7 @@ public final class MethodHandleFactory {
if (arg instanceof ScriptObject) {
return arg.toString() +
- " (map=" + Debug.id((((ScriptObject)arg).getMap())) +
+ " (map=" + Debug.id(((ScriptObject)arg).getMap()) +
")";
}
@@ -214,29 +211,32 @@ public final class MethodHandleFactory {
* Add a debug printout to a method handle, tracing parameters and return values
*
* @param logger a specific logger to which to write the output
+ * @param level level over which to print
* @param mh method handle to trace
* @param tag start of trace message
* @return traced method handle
*/
- public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) {
- return addDebugPrintout(logger, mh, 0, true, tag);
+ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Level level, final MethodHandle mh, final Object tag) {
+ return addDebugPrintout(logger, level, mh, 0, true, tag);
}
-
/**
* Add a debug printout to a method handle, tracing parameters and return values
*
* @param logger a specific logger to which to write the output
+ * @param level level over which to print
* @param mh method handle to trace
* @param paramStart first param to print/trace
* @param printReturnValue should we print/trace return value if available?
* @param tag start of trace message
* @return traced method handle
*/
- public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
+ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
final MethodType type = mh.type();
- if (logger != null && logger.levelAbove(TRACE_LEVEL)) {
+ //if there is no logger, or if it's set to log only coarser events
+ //than the trace level, skip and return
+ if (logger != null && logger.levelCoarserThan(level)) {
return mh;
}
@@ -253,191 +253,49 @@ public final class MethodHandleFactory {
asType(type.changeReturnType(void.class)));
final Class<?> retType = type.returnType();
- if (retType != void.class && printReturnValue) {
- final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
- trace = MethodHandles.filterReturnValue(trace,
- traceReturn.asType(
- traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
+ if (printReturnValue) {
+ if (retType != void.class) {
+ final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
+ trace = MethodHandles.filterReturnValue(trace,
+ traceReturn.asType(
+ traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
+ } else {
+ trace = MethodHandles.filterReturnValue(trace, MethodHandles.insertArguments(TRACE_RETURN_VOID, 0, logger));
+ }
}
return trace;
}
/**
- * The standard class that marshalls all method handle operations to the java.lang.invoke
+ * Class that marshalls all method handle operations to the java.lang.invoke
* package. This exists only so that it can be subclassed and method handles created from
* Nashorn made possible to instrument.
*
* All Nashorn classes should use the MethodHandleFactory for their method handle operations
*/
- private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
-
- @Override
- public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
- return MethodHandles.filterArguments(target, pos, filters);
- }
-
- @Override
- public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
- return MethodHandles.filterReturnValue(target, filter);
- }
-
- @Override
- public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
- return MethodHandles.guardWithTest(test, target, fallback);
- }
-
- @Override
- public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
- return MethodHandles.insertArguments(target, pos, values);
- }
-
- @Override
- public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
- return MethodHandles.dropArguments(target, pos, valueTypes);
- }
-
- @Override
- public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
- return MethodHandles.dropArguments(target, pos, valueTypes);
- }
-
- @Override
- public MethodHandle asType(final MethodHandle handle, final MethodType type) {
- return handle.asType(type);
- }
-
- @Override
- public MethodHandle bindTo(final MethodHandle handle, final Object x) {
- return handle.bindTo(x);
- }
-
- @Override
- public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
- return MethodHandles.foldArguments(target, combiner);
- }
-
- @Override
- public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
- return MethodHandles.explicitCastArguments(target, type);
- }
-
- @Override
- public MethodHandle arrayElementGetter(final Class<?> type) {
- return MethodHandles.arrayElementGetter(type);
- }
-
- @Override
- public MethodHandle arrayElementSetter(final Class<?> type) {
- return MethodHandles.arrayElementSetter(type);
- }
-
- @Override
- public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
- return MethodHandles.throwException(returnType, exType);
- }
-
- @Override
- public MethodHandle constant(final Class<?> type, final Object value) {
- return MethodHandles.constant(type, value);
- }
-
- @Override
- public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- return handle.asCollector(arrayType, arrayLength);
- }
+ @Logger(name="methodhandles")
+ private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality, Loggable {
- @Override
- public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- return handle.asSpreader(arrayType, arrayLength);
- }
+ // for bootstrapping reasons, because a lot of static fields use MH for lookups, we
+ // need to set the logger when the Global object is finished. This means that we don't
+ // get instrumentation for public static final MethodHandle SOMETHING = MH... in the builtin
+ // classes, but that doesn't matter, because this is usually not where we want it
+ private DebugLogger log = DebugLogger.DISABLED_LOGGER;
- @Override
- public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findGetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
+ public StandardMethodHandleFunctionality() {
}
@Override
- public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findStaticGetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
+ public DebugLogger initLogger(final Context context) {
+ return this.log = context.getLogger(this.getClass());
}
-
@Override
- public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findSetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
+ public DebugLogger getLogger() {
+ return log;
}
- @Override
- public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- try {
- return explicitLookup.findStaticSetter(clazz, name, type);
- } catch (final NoSuchFieldException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle find(final Method method) {
- try {
- return PUBLIC_LOOKUP.unreflect(method);
- } catch (final IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- try {
- return explicitLookup.findStatic(clazz, name, type);
- } catch (final NoSuchMethodException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- try {
- return explicitLookup.findVirtual(clazz, name, type);
- } catch (final NoSuchMethodException | IllegalAccessException e) {
- throw new LookupException(e);
- }
- }
-
- @Override
- public SwitchPoint createSwitchPoint() {
- return new SwitchPoint();
- }
-
- @Override
- public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
- return sp.guardWithTest(before, after);
- }
-
- @Override
- public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
- return MethodType.methodType(returnType, paramTypes);
- }
-
- }
-
- /**
- * Class used for instrumenting and debugging Nashorn generated method handles
- */
- private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
-
protected static String describe(final Object... data) {
final StringBuilder sb = new StringBuilder();
@@ -470,177 +328,215 @@ public final class MethodHandleFactory {
}
public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
- return addDebugPrintout(LOG, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
+ if (log.isEnabled()) {
+ if (PRINT_STACKTRACE) {
+ stacktrace(log);
+ }
+ return addDebugPrintout(log, Level.INFO, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
+ }
+ return master;
}
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
- final MethodHandle mh = super.filterArguments(target, pos, filters);
+ final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
return debug(mh, "filterArguments", target, pos, filters);
}
@Override
public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
- final MethodHandle mh = super.filterReturnValue(target, filter);
+ final MethodHandle mh = MethodHandles.filterReturnValue(target, filter);
return debug(mh, "filterReturnValue", target, filter);
}
@Override
public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
- final MethodHandle mh = super.guardWithTest(test, target, fallback);
+ final MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
return debug(mh, "guardWithTest", test, target, fallback);
}
@Override
public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
- final MethodHandle mh = super.insertArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.insertArguments(target, pos, values);
return debug(mh, "insertArguments", target, pos, values);
}
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
- final MethodHandle mh = super.dropArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
return debug(mh, "dropArguments", target, pos, values);
}
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
- final MethodHandle mh = super.dropArguments(target, pos, values);
+ final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
return debug(mh, "dropArguments", target, pos, values);
}
@Override
public MethodHandle asType(final MethodHandle handle, final MethodType type) {
- final MethodHandle mh = super.asType(handle, type);
+ final MethodHandle mh = handle.asType(type);
return debug(mh, "asType", handle, type);
}
@Override
public MethodHandle bindTo(final MethodHandle handle, final Object x) {
- final MethodHandle mh = super.bindTo(handle, x);
+ final MethodHandle mh = handle.bindTo(x);
return debug(mh, "bindTo", handle, x);
}
@Override
public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
- final MethodHandle mh = super.foldArguments(target, combiner);
+ final MethodHandle mh = MethodHandles.foldArguments(target, combiner);
return debug(mh, "foldArguments", target, combiner);
}
@Override
public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
- final MethodHandle mh = super.explicitCastArguments(target, type);
+ final MethodHandle mh = MethodHandles.explicitCastArguments(target, type);
return debug(mh, "explicitCastArguments", target, type);
}
@Override
public MethodHandle arrayElementGetter(final Class<?> type) {
- final MethodHandle mh = super.arrayElementGetter(type);
+ final MethodHandle mh = MethodHandles.arrayElementGetter(type);
return debug(mh, "arrayElementGetter", type);
}
@Override
public MethodHandle arrayElementSetter(final Class<?> type) {
- final MethodHandle mh = super.arrayElementSetter(type);
+ final MethodHandle mh = MethodHandles.arrayElementSetter(type);
return debug(mh, "arrayElementSetter", type);
}
@Override
public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
- final MethodHandle mh = super.throwException(returnType, exType);
+ final MethodHandle mh = MethodHandles.throwException(returnType, exType);
return debug(mh, "throwException", returnType, exType);
}
@Override
+ public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler) {
+ final MethodHandle mh = MethodHandles.catchException(target, exType, handler);
+ return debug(mh, "catchException", exType);
+ }
+
+ @Override
public MethodHandle constant(final Class<?> type, final Object value) {
- final MethodHandle mh = super.constant(type, value);
+ final MethodHandle mh = MethodHandles.constant(type, value);
return debug(mh, "constant", type, value);
}
@Override
public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
+ final MethodHandle mh = handle.asCollector(arrayType, arrayLength);
return debug(mh, "asCollector", handle, arrayType, arrayLength);
}
@Override
public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
- final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength);
+ final MethodHandle mh = handle.asSpreader(arrayType, arrayLength);
return debug(mh, "asSpreader", handle, arrayType, arrayLength);
}
@Override
public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
- return debug(mh, "getter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findGetter(clazz, name, type);
+ return debug(mh, "getter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
- return debug(mh, "static getter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStaticGetter(clazz, name, type);
+ return debug(mh, "static getter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
- return debug(mh, "setter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findSetter(clazz, name, type);
+ return debug(mh, "setter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
- final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
- return debug(mh, "static setter", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStaticSetter(clazz, name, type);
+ return debug(mh, "static setter", explicitLookup, clazz, name, type);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle find(final Method method) {
- final MethodHandle mh = super.find(method);
- return debug(mh, "find", method);
+ try {
+ final MethodHandle mh = PUBLIC_LOOKUP.unreflect(method);
+ return debug(mh, "find", method);
+ } catch (final IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
- return debug(mh, "findStatic", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findStatic(clazz, name, type);
+ return debug(mh, "findStatic", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
+ }
+
+ @Override
+ public MethodHandle findSpecial(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type, final Class<?> thisClass) {
+ try {
+ final MethodHandle mh = explicitLookup.findSpecial(clazz, name, type, thisClass);
+ return debug(mh, "findSpecial", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
- final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
- return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
+ try {
+ final MethodHandle mh = explicitLookup.findVirtual(clazz, name, type);
+ return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
+ } catch (final NoSuchMethodException | IllegalAccessException e) {
+ throw new LookupException(e);
+ }
}
@Override
public SwitchPoint createSwitchPoint() {
- final SwitchPoint sp = super.createSwitchPoint();
- LOG.log(TRACE_LEVEL, "createSwitchPoint ", sp);
+ final SwitchPoint sp = new SwitchPoint();
+ log.log(TRACE_LEVEL, "createSwitchPoint ", sp);
return sp;
}
@Override
public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
- final MethodHandle mh = super.guardWithTest(sp, before, after);
+ final MethodHandle mh = sp.guardWithTest(before, after);
return debug(mh, "guardWithTest", sp, before, after);
}
@Override
public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
- final MethodType mt = super.type(returnType, paramTypes);
- LOG.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
+ final MethodType mt = MethodType.methodType(returnType, paramTypes);
+ log.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
return mt;
}
}
-
- /**
- * Class used for debugging Nashorn generated method handles
- */
- private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
- @Override
- public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
- LOG.log(TRACE_LEVEL, str, " ", describe(args));
- stacktrace(LOG);
- return master;
- }
- }
}
diff --git a/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java b/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
index c7dd83b2..756c0b7b 100644
--- a/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
+++ b/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
@@ -152,6 +152,17 @@ public interface MethodHandleFunctionality {
public MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType);
/**
+ * Wrapper for {@link java.lang.invoke.MethodHandles#catchException(MethodHandle, Class, MethodHandle)}
+ *
+ * @param target target method
+ * @param exType exception type
+ * @param handler the method handle to call when exception is thrown
+ *
+ * @return exception thrower method handle
+ */
+ public MethodHandle catchException(final MethodHandle target, final Class<? extends Throwable> exType, final MethodHandle handler);
+
+ /**
* Wrapper for {@link java.lang.invoke.MethodHandles#constant(Class, Object)}
*
* @param type type of constant
@@ -286,6 +297,19 @@ public interface MethodHandleFunctionality {
public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
/**
+ * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSpecial(Class, String, MethodType, Class)}
+ *
+ * @param explicitLookup explicit lookup to be used
+ * @param clazz class to look in
+ * @param name name of method
+ * @param type method type
+ * @param thisClass thisClass
+ *
+ * @return method handle for virtual method
+ */
+ public MethodHandle findSpecial(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type, final Class<?> thisClass);
+
+ /**
* Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
* tracked
*
@@ -313,5 +337,6 @@ public interface MethodHandleFunctionality {
* @return the method type
*/
public MethodType type(Class<?> returnType, Class<?>... paramTypes);
+
}