JVMTranslator
A JVMTranslator converts a single L2Chunk into a JVMChunk in a naive fashion. Instruction selection is optimized, but no other optimizations are attempted; all significant optimizations should occur on the L2Chunk's control flow graph and be reflected in the L2Chunk to be translated.
Author
Todd L Smith
Parameters
The source L1 code, or null for the unoptimized chunk.
The descriptive (non-unique) name of the chunk being translated.
The name of the Avail source file that produced the code. Use null if no such file exists.
The L2ControlFlowGraph which produced the sequence of instructions.
The source L2Instructions to translate to JVM bytecodes.
Constructors
Construct a new JVMTranslator to translate the specified array of L2Instructions to a JVMChunk.
Properties
The internal name of the generated class.
The source L1 code.
An entry point near the end of the method, which jumps back to the methodHead for the purpose of performing a jump to a specified L2 offset without having the Fernflower Java decompiler produce tons of spurious nested blocks, breaks, and duplicated code. It's not very good.
The L2PcOperand's encapsulated program counters, mapped to their labels.
As the code is being generated and we encounter an L2_SAVE_ALL_AND_PC_TO_INT, we examine its corresponding target block to figure out which registers actually have to be captured at the save, and restored at the L2_ENTER_L2_CHUNK. At that point, we look up the local numbers from the JVMTranslator and record them by RegisterKind in this field.
The mapping of registers to locals, partitioned by kind.
The start of the runChunk method, where the offset is used to jump to the start of the control flow graph, or the specified entry point.
Functions
Emit code to conditionally branch to one of the specified program counters.
The final phase of JVM code generation.
Populate classBytes, dumping to a file for debugging if indicated.
Emit the effect of loading a constant double to the specified MethodVisitor.
Emit the effect of loading a constant float to the specified MethodVisitor.
Generate the default constructor `()V` of the target JVMChunk.
Generate the JVMChunk.name method of the target JVMChunk.
We're at a point where reification has been requested. A StackReifier has already been stashed in the Interpreter, and already-popped calls may have already queued actions in the reifier, to be executed in reverse order.
Generate the JVMChunk.runChunk method of the target JVMChunk.
Generate the static initializer of the target JVMChunk. The static initializer is responsible for moving any of the parameters of the JVMChunk subclass's JVMChunkClassLoader into appropriate private static final fields.
Emit the effect of loading a constant int to the specified MethodVisitor.
Emit code to unconditionally branch to the specified program counter.
Emit code to unconditionally branch to the specified program counter. Skip if the edge indicates it follows the given instruction.
Emit code to jump to the target of the supplied edge conditionally, based on the supplied JVM branch opcode and the value on top of the stack. program counter. If condition is not satisfied, control continues at the next JVM instruction.
Answer the Label for the specified L2InstructionL2Instruction.offset.
Emit code to push the specified literal on top of the stack.
Throw an UnsupportedOperationException. It is never valid to treat an L2Operand as a JVM literal, so this method is marked as Deprecated to protect against code cloning and refactoring errors by a programmer.
Throw an UnsupportedOperationException. It is never valid to treat an L2Register as a Java literal, so this method is marked as Deprecated to protect against code cloning and refactoring errors by a programmer.
Generate a load of the local associated with the specified L2Register.
Actually load the generated class into the running JVM. Note that a special JVMChunkClassLoader must be used, so that the static initialization has access to the necessary constants referenced from the bytecodes.
Generate access to the JVM local for the Interpreter formal parameter of a generated implementation of JVMChunk.runChunk.
Generate access of the receiver (i.e., this).
Answer the JVM local number for this register. This is the position within the actual JVM stack frame layout.
Emit the effect of loading a constant long to the specified MethodVisitor.
Answer the next JVM local for use within generated code produced by generateRunChunk.
Emit code to store each of the L2BoxedRegisters into a new array. Leave the new array on top of the stack.
Answer the JVM local for the offset formal parameter of a generated implementation of JVMChunk.runChunk.
Prepare for JVM translation by visiting each of the L2Instructions to be translated.
Answer the JVM local for the StackReifier local variable of a generated implementation of JVMChunk.runChunk.
Answer the JVM branch opcode with the reversed sense.
Generate a store into the local associated with the specified L2Register. The value to be stored should already be on top of the stack and correctly typed.