public final class DmoAsmWorker extends AbstractConversionWorker implements DmoAsmTypes, JavaTokenTypes, org.objectweb.asm.Opcodes
The rule-sets which generate those Java ASTs behave differently, depending on whether they are executed at server runtime or in batch mode for static conversion. In runtime mode, some adjustments are made to the ASTs to make them more amenable to assembing class files directly. In batch mode, the ASTs are optimized for downstream anti-parsing into source code. For example, in runtime mode, nodes are rearranged into a structure more suitable for bytecode assembly, some different token types are used to give better assembly cues, class names are fully qualified, and assembly hints are added.
This work was designed not to be a general-purpose assembler/compiler, but rather to provide a pragmatic solution for DMO interface/class assembly, using TRPL to walk the Java ASTs and this worker's service library to bridge to services in ASM which are not easily accessible from TRPL. This specialization allows us to make some assumptions about the purpose of the bytecode being assembled. As such, the service APIs in this worker are only as granular as required to meet the needs of the AST structure, but are as coarse as possible. In the TRPL code, we do not interpret every AST node, but rather use a combination of hints left behind during the AST creation and simple patterns of token types to recognize a feature (e.g., initializing a DMO field within a loop). We extract the information necessary for that feature from the AST, then call into this worker with that information, and let this worker assemble the bytecode instructions needed to implement that feature. This often assumes knowledge of the context of that feature within the broader context of its method or class, such as the state of runtime operand stack and local variable pool. This approach allows us to dispense with a much more complicated state machine that would be necessary to implement a more general-purpose compiler, enhancing the simplicity and performance of the service.
The solution replaces the use of an in-memory compiler implementation based on the use of
javax.tools.JavaCompiler
. While effective and correct, that solution had several
drawbacks and needed to be replaced. It was considerably slower and created memory problems
through its internal use of an ever-growing character array to manage source code text; and
with a dubious use of soft references, which required a workaround of disabling them entirely.
It also required the somewhat expensive, intermediate step of source code generation, which is
bypassed now by assembling directly from the Java ASTs.
This worker does not finally generate the class files or load them into the JVM. The byte
arrays representing the finished interface and implementation classes are stored by the TRPL
code into the current pattern engine. The DynamicTablesHelper
retrieves them from
the pattern engine and then uses a custom class
loader
to load them into the JVM.
Modifier and Type | Class and Description |
---|---|
static class |
DmoAsmWorker.Library
An API of library functions available to TRPL to provide services to assemble DMO interface
and implementation classes using ASM.
|
Modifier and Type | Field and Description |
---|---|
private static java.util.Map<java.lang.String,java.lang.String> |
assignMethSigs
Map of field types to the signatures of their associated
assign methods |
private static java.util.Map<java.lang.String,java.lang.String> |
copyCtorTypes
Map of field types to the descriptors used in their associated copy c'tor signatures
|
private static java.util.logging.Logger |
log
Logger.
|
private static java.util.Map<java.lang.String,java.lang.String> |
setterTypes
Map of field types to the types used in their associated setter method signatures
|
PEER_ID
resolver
ANNOTATION_DESC_PREFIX, BUF, BUF_SUFFIX, BUFFER_IFACE, DESC_ARRAYLIST, DESC_DATE, DESC_JAVA_INTEGER, DESC_JAVA_STRING, DESC_LIST, FLD_MULTIPLEX, METH_ADD, METH_ASSIGN, METH_CHKXRNG, METH_GET, METH_INIT, METH_INTVALUE, METH_ISUNK, METH_MIN, METH_OOBE, METH_SETUNK, METH_SIZE, PKG_PERSIST, PKG_UTIL, SIG_ADD, SIG_CHKXRNG, SIG_DEF_INIT, SIG_DMO_ASSIGN, SIG_GET, SIG_INT_INIT, SIG_INTVALUE, SIG_ISUNK, SIG_MIN, SIG_OOBE, SIG_SETUNK, SIG_SIZE, TYPE_ARRAYLIST, TYPE_BINARYDATA, TYPE_BUFFERIMPL, TYPE_CHARACTER, TYPE_DATE, TYPE_DATETIME, TYPE_DATETIMETZ, TYPE_DECIMAL, TYPE_HANDLE, TYPE_INT64, TYPE_INTEGER, TYPE_LIST, TYPE_LOGICAL, TYPE_LONGCHAR, TYPE_MATH, TYPE_MEMPTR, TYPE_NUMBERTYPE, TYPE_OBJECT, TYPE_PERSISTABLE, TYPE_RAW, TYPE_RECID, TYPE_ROWID, TYPE_SERIALIZABLE, TYPE_TEMPORARY, TYPE_TEXT, TYPE_UNDOABLE
ANNOTATION, ANON_CTOR, ASSIGN, BEGIN_DOCTAGS, BITWISE_AND, BITWISE_OR, BITWISE_XOR, BLOCK, BLOCK_DEF, BOGUS, BOOL_FALSE, BOOL_TRUE, CAST, CHAR_LITERAL, CLASS_REFERENCE, COMPILE_UNIT, COMPLEMENT, CONSTRUCTOR, CS_BEGIN, CS_CONSTANTS, CS_CONSTRUCTORS, CS_END, CS_INNER_CLASSES, CS_INSTANCE_METHODS, CS_INSTANCE_VARS, CS_STATIC_INITS, CS_STATIC_METHODS, CS_STATIC_VARS, DEC_LITERAL, DECREMENT, DIVIDE, DO_WHILE, DOC_COMMENT, DOC_HTML, DOC_PARAGRAPH, DOC_TEXTRUN, DOCTAG_LINK, DOCTAG_PARAM, DOCTAG_RETURN, ELSE_IF, END_DOCTAGS, EQUALS, EXPRESSION, GT, GTE, INCREMENT, INDENT_GRP, INITIALIZER, KW_ABSTRACT, KW_ASSERT, KW_BOOLEAN, KW_BREAK, KW_BYTE, KW_CASE, KW_CATCH, KW_CHAR, KW_CLASS, KW_CONST, KW_CONTINUE, KW_DEFAULT, KW_DO, KW_DOUBLE, KW_ELSE, KW_ENUM, KW_EXTENDS, KW_FINAL, KW_FINALLY, KW_FLOAT, KW_FOR, KW_GOTO, KW_IF, KW_IMPLEMENTS, KW_IMPORT, KW_INSTANCEOF, KW_INT, KW_INTERFACE, KW_LONG, KW_NATIVE, KW_NEW, KW_PACKAGE, KW_PRIVATE, KW_PROTECTED, KW_PUBLIC, KW_RETURN, KW_SHORT, KW_STATIC, KW_STRICTFP, KW_SUPER, KW_SWITCH, KW_SYNCHRONIZED, KW_THIS, KW_THROW, KW_THROWS, KW_TRANSIENT, KW_TRY, KW_VOID, KW_VOLATILE, KW_WHILE, LABEL, LABEL_DEF, LAMBDA, LBRACKET, LOGICAL_AND, LOGICAL_NOT, LOGICAL_OR, LPARENS, LSHIFT, LT, LTE, MEMBER, METHOD_CALL, METHOD_DECL, METHOD_DEF, MINUS, MINUS_ASSIGN, MODULO, MULTIPLY, NOT_EQ, NULL_LITERAL, NUM_LITERAL, OR_ELSE_IF, PLACEHOLDER, PLUS, PLUS_ASSIGN, REFERENCE, REFERENCE_DEF, RSHIFT, SKIP, SLASH_COMMENT, STAR_COMMENT, STATIC_IMPORT, STATIC_METHOD_CALL, STRING, SYMBOL, TERN_IF_ELSE, THEN, UN_MINUS, UN_PLUS, UNRECOGNIZED, ZERO_RSHIFT
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM4, ASM5, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8
Constructor and Description |
---|
DmoAsmWorker()
Default constructor which defines the symbol library to be registered.
|
Modifier and Type | Method and Description |
---|---|
private static org.objectweb.asm.ClassWriter |
createClassWriter()
Create an ASM
ClassWriter which computes frame and max stack depth information
automatically. |
private static java.lang.String |
loadComposite(org.objectweb.asm.MethodVisitor mv,
java.lang.String classType,
java.lang.String compFieldName,
java.lang.String compClassName)
Implement the loading of a composite element from its ArrayList and casting it to the
appropriate inner class type.
|
private static void |
loadIndexParameter(org.objectweb.asm.MethodVisitor mv)
Implement the loading of a
NumberType object and extracting its int value. |
private static java.lang.String |
makeAnnotationDescriptor(java.lang.String name)
Make a fully qualified, internal type descriptor from the given, short annotation name.
|
private static java.lang.String |
makeIndexedSetterSignature(java.lang.String fieldType)
Given the internal type name of a DMO field, compose an indexed setter method signature of
the form
(IL<type name>;)V . |
crossReferencePeerAsts, getClosestPeerId, getParentPeer, initializeAst, initializeAst, initializeRootAst, initializeRootAst
finish, getCopy, getLibrary, getSource, initialize, registerTree, resolveConstant, setLibrary, visitAst
private static final java.util.logging.Logger log
private static final java.util.Map<java.lang.String,java.lang.String> assignMethSigs
assign
methodsprivate static final java.util.Map<java.lang.String,java.lang.String> setterTypes
private static final java.util.Map<java.lang.String,java.lang.String> copyCtorTypes
public DmoAsmWorker()
private static org.objectweb.asm.ClassWriter createClassWriter()
ClassWriter
which computes frame and max stack depth information
automatically.private static java.lang.String makeAnnotationDescriptor(java.lang.String name)
name
- Unqualified annotation name.private static java.lang.String makeIndexedSetterSignature(java.lang.String fieldType)
(IL<type name>;)V
.fieldType
- Internal type name of a DMO field.private static java.lang.String loadComposite(org.objectweb.asm.MethodVisitor mv, java.lang.String classType, java.lang.String compFieldName, java.lang.String compClassName)
mv
- ASM method visitor.classType
- Fully qualified internal type name of enclosing class.compFieldName
- Short name of field in enclosing class which contains the array list of
composites we need to access.compClassName
- Short name of composite inner class.private static void loadIndexParameter(org.objectweb.asm.MethodVisitor mv)
NumberType
object and extracting its int value.mv
- ASM method visitor.