/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.codegen;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Source;
This class represents constant names of variables, methods and fields in
the compiler
/**
* This class represents constant names of variables, methods and fields in
* the compiler
*/
public enum CompilerConstants {
the __FILE__ variable /** the __FILE__ variable */
__FILE__,
the __DIR__ variable /** the __DIR__ variable */
__DIR__,
the __LINE__ variable /** the __LINE__ variable */
__LINE__,
constructor name /** constructor name */
INIT("<init>"),
static initializer name /** static initializer name */
CLINIT("<clinit>"),
eval name /** eval name */
EVAL("eval"),
source name and class /** source name and class */
SOURCE("source", Source.class),
constants name and class /** constants name and class */
CONSTANTS("constants", Object[].class),
strict mode field name and type /** strict mode field name and type */
STRICT_MODE("strictMode", boolean.class),
default script name /** default script name */
DEFAULT_SCRIPT_NAME("Script"),
function prefix for anonymous functions /** function prefix for anonymous functions */
ANON_FUNCTION_PREFIX("L:"),
separator for method names of nested functions /** separator for method names of nested functions */
NESTED_FUNCTION_SEPARATOR("#"),
separator for making method names unique by appending numeric ids /** separator for making method names unique by appending numeric ids */
ID_FUNCTION_SEPARATOR("-"),
method name for Java method that is the program entry point /** method name for Java method that is the program entry point */
PROGRAM(":program"),
method name for Java method that creates the script function for the program /** method name for Java method that creates the script function for the program */
CREATE_PROGRAM_FUNCTION(":createProgramFunction"),
"this" name symbol for a parameter representing ECMAScript "this" in static methods that are compiled
representations of ECMAScript functions. It is not assigned a slot, as its position in the method signature is
dependent on other factors (most notably, callee can precede it).
/**
* "this" name symbol for a parameter representing ECMAScript "this" in static methods that are compiled
* representations of ECMAScript functions. It is not assigned a slot, as its position in the method signature is
* dependent on other factors (most notably, callee can precede it).
*/
THIS("this", Object.class),
this debugger symbol /** this debugger symbol */
THIS_DEBUGGER(":this"),
scope name, type and slot /** scope name, type and slot */
SCOPE(":scope", ScriptObject.class, 2),
the return value variable name were intermediate results are stored for scripts /** the return value variable name were intermediate results are stored for scripts */
RETURN(":return"),
the callee value variable when necessary /** the callee value variable when necessary */
CALLEE(":callee", ScriptFunction.class),
the varargs variable when necessary /** the varargs variable when necessary */
VARARGS(":varargs", Object[].class),
the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in
the function body./** the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in
* the function body.*/
ARGUMENTS_VAR("arguments", Object.class),
the internal arguments object, when necessary (not visible to scripts, can't be reassigned). /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */
ARGUMENTS(":arguments", ScriptObject.class),
prefix for apply-to-call exploded arguments /** prefix for apply-to-call exploded arguments */
EXPLODED_ARGUMENT_PREFIX(":xarg"),
prefix for iterators for for (x in ...) /** prefix for iterators for for (x in ...) */
ITERATOR_PREFIX(":i", Iterator.class),
prefix for tag variable used for switch evaluation /** prefix for tag variable used for switch evaluation */
SWITCH_TAG_PREFIX(":s"),
prefix for JVM exceptions /** prefix for JVM exceptions */
EXCEPTION_PREFIX(":e", Throwable.class),
prefix for quick slots generated in Store /** prefix for quick slots generated in Store */
QUICK_PREFIX(":q"),
prefix for temporary variables /** prefix for temporary variables */
TEMP_PREFIX(":t"),
prefix for literals /** prefix for literals */
LITERAL_PREFIX(":l"),
prefix for regexps /** prefix for regexps */
REGEX_PREFIX(":r"),
"this" used in non-static Java methods; always in slot 0 /** "this" used in non-static Java methods; always in slot 0 */
JAVA_THIS(null, 0),
Map parameter in scope object constructors; always in slot 1 /** Map parameter in scope object constructors; always in slot 1 */
INIT_MAP(null, 1),
Parent scope parameter in scope object constructors; always in slot 2 /** Parent scope parameter in scope object constructors; always in slot 2 */
INIT_SCOPE(null, 2),
Arguments parameter in scope object constructors; in slot 3 when present /** Arguments parameter in scope object constructors; in slot 3 when present */
INIT_ARGUMENTS(null, 3),
prefix for all ScriptObject subclasses with dual object/primitive fields, see ObjectClassGenerator
/** prefix for all ScriptObject subclasses with dual object/primitive fields, see {@link ObjectClassGenerator} */
JS_OBJECT_DUAL_FIELD_PREFIX("JD"),
prefix for all ScriptObject subclasses with object fields only, see ObjectClassGenerator
/** prefix for all ScriptObject subclasses with object fields only, see {@link ObjectClassGenerator} */
JS_OBJECT_SINGLE_FIELD_PREFIX("JO"),
name for allocate method in JO objects /** name for allocate method in JO objects */
ALLOCATE("allocate"),
prefix for split methods, @see Splitter /** prefix for split methods, @see Splitter */
SPLIT_PREFIX(":split"),
prefix for split array method and slot /** prefix for split array method and slot */
SPLIT_ARRAY_ARG(":split_array", 3),
get string from constant pool /** get string from constant pool */
GET_STRING(":getString"),
get map /** get map */
GET_MAP(":getMap"),
set map /** set map */
SET_MAP(":setMap"),
get array prefix /** get array prefix */
GET_ARRAY_PREFIX(":get"),
get array suffix /** get array suffix */
GET_ARRAY_SUFFIX("$array");
To save memory - intern the compiler constant symbol names, as they are frequently reused /** To save memory - intern the compiler constant symbol names, as they are frequently reused */
static {
for (final CompilerConstants c : values()) {
final String symbolName = c.symbolName();
if (symbolName != null) {
symbolName.intern();
}
}
}
private static Set<String> symbolNames;
Prefix used for internal methods generated in script classes.
/**
* Prefix used for internal methods generated in script classes.
*/
private static final String INTERNAL_METHOD_PREFIX = ":";
private final String symbolName;
private final Class<?> type;
private final int slot;
private CompilerConstants() {
this.symbolName = name();
this.type = null;
this.slot = -1;
}
private CompilerConstants(final String symbolName) {
this(symbolName, -1);
}
private CompilerConstants(final String symbolName, final int slot) {
this(symbolName, null, slot);
}
private CompilerConstants(final String symbolName, final Class<?> type) {
this(symbolName, type, -1);
}
private CompilerConstants(final String symbolName, final Class<?> type, final int slot) {
this.symbolName = symbolName;
this.type = type;
this.slot = slot;
}
Check whether a name is that of a reserved compiler constant
Params: - name – name
Returns: true if compiler constant name
/**
* Check whether a name is that of a reserved compiler constant
* @param name name
* @return true if compiler constant name
*/
public static boolean isCompilerConstant(final String name) {
ensureSymbolNames();
return symbolNames.contains(name);
}
private static void ensureSymbolNames() {
if(symbolNames == null) {
symbolNames = new HashSet<>();
for(final CompilerConstants cc: CompilerConstants.values()) {
symbolNames.add(cc.symbolName);
}
}
}
Return the tag for this compile constant. Deliberately avoiding "name" here
not to conflate with enum implementation. This is the master string for the
constant - every constant has one.
Returns: the tag
/**
* Return the tag for this compile constant. Deliberately avoiding "name" here
* not to conflate with enum implementation. This is the master string for the
* constant - every constant has one.
*
* @return the tag
*/
public final String symbolName() {
return symbolName;
}
Return the type for this compile constant
Returns: type for this constant's instances, or null if N/A
/**
* Return the type for this compile constant
*
* @return type for this constant's instances, or null if N/A
*/
public final Class<?> type() {
return type;
}
Return the slot for this compile constant
Returns: byte code slot where constant is stored or -1 if N/A
/**
* Return the slot for this compile constant
*
* @return byte code slot where constant is stored or -1 if N/A
*/
public final int slot() {
return slot;
}
Return a descriptor for this compile constant. Only relevant if it has
a type
Returns: descriptor the descriptor
/**
* Return a descriptor for this compile constant. Only relevant if it has
* a type
*
* @return descriptor the descriptor
*/
public final String descriptor() {
assert type != null : " asking for descriptor of typeless constant";
return typeDescriptor(type);
}
Get the internal class name for a type
Params: - type – a type
Returns: the internal name for this type
/**
* Get the internal class name for a type
*
* @param type a type
* @return the internal name for this type
*/
public static String className(final Class<?> type) {
return Type.getInternalName(type);
}
Get the method descriptor for a given method type collection
Params: - rtype – return type
- ptypes – parameter types
Returns: internal descriptor for this method
/**
* Get the method descriptor for a given method type collection
*
* @param rtype return type
* @param ptypes parameter types
*
* @return internal descriptor for this method
*/
public static String methodDescriptor(final Class<?> rtype, final Class<?>... ptypes) {
return Type.getMethodDescriptor(rtype, ptypes);
}
Get the type descriptor for a type
Params: - clazz – a type
Returns: the internal descriptor for this type
/**
* Get the type descriptor for a type
*
* @param clazz a type
*
* @return the internal descriptor for this type
*/
public static String typeDescriptor(final Class<?> clazz) {
return Type.typeFor(clazz).getDescriptor();
}
Create a call representing a void constructor for a given type. Don't
attempt to look this up at compile time
Params: - clazz – the class
Returns: Call representing void constructor for type
/**
* Create a call representing a void constructor for a given type. Don't
* attempt to look this up at compile time
*
* @param clazz the class
*
* @return Call representing void constructor for type
*/
public static Call constructorNoLookup(final Class<?> clazz) {
return specialCallNoLookup(clazz, INIT.symbolName(), void.class);
}
Create a call representing a constructor for a given type. Don't
attempt to look this up at compile time
Params: - className – the type class name
- ptypes – the parameter types for the constructor
Returns: Call representing constructor for type
/**
* Create a call representing a constructor for a given type. Don't
* attempt to look this up at compile time
*
* @param className the type class name
* @param ptypes the parameter types for the constructor
*
* @return Call representing constructor for type
*/
public static Call constructorNoLookup(final String className, final Class<?>... ptypes) {
return specialCallNoLookup(className, INIT.symbolName(), methodDescriptor(void.class, ptypes));
}
Create a call representing a constructor for a given type. Don't
attempt to look this up at compile time
Params: - clazz – the class name
- ptypes – the parameter types for the constructor
Returns: Call representing constructor for type
/**
* Create a call representing a constructor for a given type. Don't
* attempt to look this up at compile time
*
* @param clazz the class name
* @param ptypes the parameter types for the constructor
*
* @return Call representing constructor for type
*/
public static Call constructorNoLookup(final Class<?> clazz, final Class<?>... ptypes) {
return specialCallNoLookup(clazz, INIT.symbolName(), void.class, ptypes);
}
Create a call representing an invokespecial to a given method. Don't
attempt to look this up at compile time
Params: - className – the class name
- name – the method name
- desc – the descriptor
Returns: Call representing specified invokespecial call
/**
* Create a call representing an invokespecial to a given method. Don't
* attempt to look this up at compile time
*
* @param className the class name
* @param name the method name
* @param desc the descriptor
*
* @return Call representing specified invokespecial call
*/
public static Call specialCallNoLookup(final String className, final String name, final String desc) {
return new Call(null, className, name, desc) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokespecial(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, desc, false);
}
};
}
Create a call representing an invokespecial to a given method. Don't
attempt to look this up at compile time
Params: - clazz – the class
- name – the method name
- rtype – the return type
- ptypes – the parameter types
Returns: Call representing specified invokespecial call
/**
* Create a call representing an invokespecial to a given method. Don't
* attempt to look this up at compile time
*
* @param clazz the class
* @param name the method name
* @param rtype the return type
* @param ptypes the parameter types
*
* @return Call representing specified invokespecial call
*/
public static Call specialCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return specialCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
}
Create a call representing an invokestatic to a given method. Don't
attempt to look this up at compile time
Params: - className – the class name
- name – the method name
- desc – the descriptor
Returns: Call representing specified invokestatic call
/**
* Create a call representing an invokestatic to a given method. Don't
* attempt to look this up at compile time
*
* @param className the class name
* @param name the method name
* @param desc the descriptor
*
* @return Call representing specified invokestatic call
*/
public static Call staticCallNoLookup(final String className, final String name, final String desc) {
return new Call(null, className, name, desc) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokestatic(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, desc, false);
}
};
}
Create a call representing an invokestatic to a given method. Don't
attempt to look this up at compile time
Params: - clazz – the class
- name – the method name
- rtype – the return type
- ptypes – the parameter types
Returns: Call representing specified invokestatic call
/**
* Create a call representing an invokestatic to a given method. Don't
* attempt to look this up at compile time
*
* @param clazz the class
* @param name the method name
* @param rtype the return type
* @param ptypes the parameter types
*
* @return Call representing specified invokestatic call
*/
public static Call staticCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return staticCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
}
Create a call representing an invokevirtual to a given method. Don't
attempt to look this up at compile time
Params: - clazz – the class
- name – the method name
- rtype – the return type
- ptypes – the parameter types
Returns: Call representing specified invokevirtual call
/**
* Create a call representing an invokevirtual to a given method. Don't
* attempt to look this up at compile time
*
* @param clazz the class
* @param name the method name
* @param rtype the return type
* @param ptypes the parameter types
*
* @return Call representing specified invokevirtual call
*/
public static Call virtualCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokevirtual(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
}
};
}
Create a call representing an invokeinterface to a given method. Don't
attempt to look this up at compile time
Params: - clazz – the class
- name – the method name
- rtype – the return type
- ptypes – the parameter types
Returns: Call representing specified invokeinterface call
/**
* Create a call representing an invokeinterface to a given method. Don't
* attempt to look this up at compile time
*
* @param clazz the class
* @param name the method name
* @param rtype the return type
* @param ptypes the parameter types
*
* @return Call representing specified invokeinterface call
*/
public static Call interfaceCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokeinterface(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, className, name, descriptor, true);
}
};
}
Create a FieldAccess representing a virtual field, that can be subject to put
or get operations
Params: - className – name of the class where the field is a member
- name – name of the field
- desc – type descriptor of the field
Returns: a field access object giving access code generation method for the virtual field
/**
* Create a FieldAccess representing a virtual field, that can be subject to put
* or get operations
*
* @param className name of the class where the field is a member
* @param name name of the field
* @param desc type descriptor of the field
*
* @return a field access object giving access code generation method for the virtual field
*/
public static FieldAccess virtualField(final String className, final String name, final String desc) {
return new FieldAccess(className, name, desc) {
@Override
public MethodEmitter get(final MethodEmitter method) {
return method.getField(className, name, descriptor);
}
@Override
public void put(final MethodEmitter method) {
method.putField(className, name, descriptor);
}
};
}
Create a FieldAccess representing a virtual field, that can be subject to put
or get operations
Params: - clazz – class where the field is a member
- name – name of the field
- type – type of the field
Returns: a field access object giving access code generation method for the virtual field
/**
* Create a FieldAccess representing a virtual field, that can be subject to put
* or get operations
*
* @param clazz class where the field is a member
* @param name name of the field
* @param type type of the field
*
* @return a field access object giving access code generation method for the virtual field
*/
public static FieldAccess virtualField(final Class<?> clazz, final String name, final Class<?> type) {
return virtualField(className(clazz), name, typeDescriptor(type));
}
Create a FieldAccess representing a static field, that can be subject to put
or get operations
Params: - className – name of the class where the field is a member
- name – name of the field
- desc – type descriptor of the field
Returns: a field access object giving access code generation method for the static field
/**
* Create a FieldAccess representing a static field, that can be subject to put
* or get operations
*
* @param className name of the class where the field is a member
* @param name name of the field
* @param desc type descriptor of the field
*
* @return a field access object giving access code generation method for the static field
*/
public static FieldAccess staticField(final String className, final String name, final String desc) {
return new FieldAccess(className, name, desc) {
@Override
public MethodEmitter get(final MethodEmitter method) {
return method.getStatic(className, name, descriptor);
}
@Override
public void put(final MethodEmitter method) {
method.putStatic(className, name, descriptor);
}
};
}
Create a FieldAccess representing a static field, that can be subject to put
or get operations
Params: - clazz – class where the field is a member
- name – name of the field
- type – type of the field
Returns: a field access object giving access code generation method for the virtual field
/**
* Create a FieldAccess representing a static field, that can be subject to put
* or get operations
*
* @param clazz class where the field is a member
* @param name name of the field
* @param type type of the field
*
* @return a field access object giving access code generation method for the virtual field
*/
public static FieldAccess staticField(final Class<?> clazz, final String name, final Class<?> type) {
return staticField(className(clazz), name, typeDescriptor(type));
}
Create a static call, given an explicit lookup, looking up the method handle for it at the same time
Params: - lookup – the lookup
- clazz – the class
- name – the name of the method
- rtype – the return type
- ptypes – the parameter types
Returns: the call object representing the static call
/**
* Create a static call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
* @param clazz the class
* @param name the name of the method
* @param rtype the return type
* @param ptypes the parameter types
*
* @return the call object representing the static call
*/
public static Call staticCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return new Call(MH.findStatic(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokestatic(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, descriptor, false);
}
};
}
Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
Params: - lookup – the lookup
- clazz – the class
- name – the name of the method
- rtype – the return type
- ptypes – the parameter types
Returns: the call object representing the virtual call
/**
* Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
* @param clazz the class
* @param name the name of the method
* @param rtype the return type
* @param ptypes the parameter types
*
* @return the call object representing the virtual call
*/
public static Call virtualCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return new Call(MH.findVirtual(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokevirtual(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
}
};
}
Create a special call, given an explicit lookup, looking up the method handle for it at the same time.
clazz is used as this class
Params: - lookup – the lookup
- clazz – the class
- name – the name of the method
- rtype – the return type
- ptypes – the parameter types
Returns: the call object representing the virtual call
/**
* Create a special call, given an explicit lookup, looking up the method handle for it at the same time.
* clazz is used as this class
*
* @param lookup the lookup
* @param clazz the class
* @param name the name of the method
* @param rtype the return type
* @param ptypes the parameter types
*
* @return the call object representing the virtual call
*/
public static Call specialCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
return new Call(MH.findSpecial(lookup, clazz, name, MH.type(rtype, ptypes), clazz), className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
MethodEmitter invoke(final MethodEmitter method) {
return method.invokespecial(className, name, descriptor);
}
@Override
public void invoke(final MethodVisitor mv) {
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, descriptor, false);
}
};
}
Returns true if the passed string looks like a method name of an internally generated Nashorn method. Basically, if it starts with a colon character :
but is not the name of the program method :program
. Program function is not considered internal as we want it to show up in exception stack traces. Params: - methodName – the name of a method
Throws: - NullPointerException – if passed null
Returns: true if it looks like an internal Nashorn method name.
/**
* Returns true if the passed string looks like a method name of an internally generated Nashorn method. Basically,
* if it starts with a colon character {@code :} but is not the name of the program method {@code :program}.
* Program function is not considered internal as we want it to show up in exception stack traces.
* @param methodName the name of a method
* @return true if it looks like an internal Nashorn method name.
* @throws NullPointerException if passed null
*/
public static boolean isInternalMethodName(final String methodName) {
return methodName.startsWith(INTERNAL_METHOD_PREFIX) && !methodName.equals(PROGRAM.symbolName);
}
Private class representing an access. This can generate code into a method code or
a field access.
/**
* Private class representing an access. This can generate code into a method code or
* a field access.
*/
private abstract static class Access {
protected final MethodHandle methodHandle;
protected final String className;
protected final String name;
protected final String descriptor;
Constructor
Params: - methodHandle – methodHandle or null if none
- className – class name for access
- name – field or method name for access
- descriptor – descriptor for access field or method
/**
* Constructor
*
* @param methodHandle methodHandle or null if none
* @param className class name for access
* @param name field or method name for access
* @param descriptor descriptor for access field or method
*/
protected Access(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
this.methodHandle = methodHandle;
this.className = className;
this.name = name;
this.descriptor = descriptor;
}
Get the method handle, or null if access hasn't been looked up
Returns: method handle
/**
* Get the method handle, or null if access hasn't been looked up
*
* @return method handle
*/
public MethodHandle methodHandle() {
return methodHandle;
}
Get the class name of the access
Returns: the class name
/**
* Get the class name of the access
*
* @return the class name
*/
public String className() {
return className;
}
Get the field name or method name of the access
Returns: the name
/**
* Get the field name or method name of the access
*
* @return the name
*/
public String name() {
return name;
}
Get the descriptor of the method or field of the access
Returns: the descriptor
/**
* Get the descriptor of the method or field of the access
*
* @return the descriptor
*/
public String descriptor() {
return descriptor;
}
}
Field access - this can be used for generating code for static or
virtual field accesses
/**
* Field access - this can be used for generating code for static or
* virtual field accesses
*/
public abstract static class FieldAccess extends Access {
Constructor
Params: - className – name of the class where the field is
- name – name of the field
- descriptor – descriptor of the field
/**
* Constructor
*
* @param className name of the class where the field is
* @param name name of the field
* @param descriptor descriptor of the field
*/
protected FieldAccess(final String className, final String name, final String descriptor) {
super(null, className, name, descriptor);
}
Generate get code for the field
Params: - emitter – a method emitter
Returns: the method emitter
/**
* Generate get code for the field
*
* @param emitter a method emitter
*
* @return the method emitter
*/
protected abstract MethodEmitter get(final MethodEmitter emitter);
Generate put code for the field
Params: - emitter – a method emitter
/**
* Generate put code for the field
*
* @param emitter a method emitter
*/
protected abstract void put(final MethodEmitter emitter);
}
Call - this can be used for generating code for different types of calls
/**
* Call - this can be used for generating code for different types of calls
*/
public abstract static class Call extends Access {
Constructor
Params: - className – class name for the method of the call
- name – method name
- descriptor – method descriptor
/**
* Constructor
*
* @param className class name for the method of the call
* @param name method name
* @param descriptor method descriptor
*/
protected Call(final String className, final String name, final String descriptor) {
super(null, className, name, descriptor);
}
Constructor
Params: - methodHandle – method handle for the call if resolved
- className – class name for the method of the call
- name – method name
- descriptor – method descriptor
/**
* Constructor
*
* @param methodHandle method handle for the call if resolved
* @param className class name for the method of the call
* @param name method name
* @param descriptor method descriptor
*/
protected Call(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
super(methodHandle, className, name, descriptor);
}
Generate invocation code for the method
Params: - emitter – a method emitter
Returns: the method emitter
/**
* Generate invocation code for the method
*
* @param emitter a method emitter
*
* @return the method emitter
*/
abstract MethodEmitter invoke(final MethodEmitter emitter);
Generate invocation code for the method
Params: - mv – a method visitor
/**
* Generate invocation code for the method
*
* @param mv a method visitor
*/
public abstract void invoke(final MethodVisitor mv);
}
}