/*
 * 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:
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); } }