L1Translator

The L1Translator transliterates a sequence of level one instructions into one or more simple level two instructions, under the assumption that further optimization steps will be able to transform this code into something much more efficient – without altering the level one semantics.

Author

Mark van Gulik

Todd L Smith

Parameters

generator

The L2Generator for which I'm producing an initial translation from L1.

interpreter

The Interpreter that tripped the translation request.

code

The A_RawFunction which is the source of the chunk being created.

Types

Link copied to clipboard
inner class CallSiteHelper

A helper that aggregates parameters for polymorphic dispatch inlining.

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

The raw function to transliterate into level two code.

Link copied to clipboard

The current L2ValueManifest, which tracks which L2Synonyms hold which L2SemanticValues at the current code generation point.

Link copied to clipboard

The L2Generator for which I'm producing an initial translation.

Link copied to clipboard

The current level one nybblecode position during naive translation to level two.

Link copied to clipboard
val pc: Int

Get the program counter for the next instruction to be decoded.

Link copied to clipboard
var stackp: Int

The current stack depth during naive translation to level two.

Functions

Link copied to clipboard
fun addInstruction(instruction: L2Instruction)
fun addInstruction(operation: L2Operation, vararg operands: L2Operand)

Create and add an L2Instruction with the given L2Operation and variable number of L2Operands.

Link copied to clipboard
fun createSemanticSlot(index: Int, afterPc: Int): L2SemanticValue

Create a semantic slot for the given one-based index, representing the state just before reaching the specified afterPc.

Link copied to clipboard
fun emitGetVariableOffRamp(getOperation: L2Operation, variable: L2ReadBoxedOperand, targetSemanticValue: L2SemanticValue, makeImmutable: Boolean): L2ReadBoxedOperand

Emit the specified variable-reading instruction, and an off-ramp to deal with the case that the variable is unassigned.

Link copied to clipboard
fun forceSlotRegister(slotIndex: Int, effectivePc: Int, registerRead: L2ReadBoxedOperand)

Associate the specified L2ReadBoxedOperand with the semantic slot having the given index and effective pc. Restrict the type based on the register-read's TypeRestriction.

Link copied to clipboard
fun generateGeneralFunctionInvocation(functionToCallReg: L2ReadBoxedOperand, arguments: List<L2ReadBoxedOperand>, tryToGenerateSpecialPrimitiveInvocation: Boolean, callSiteHelper: L1Translator.CallSiteHelper)

Generate code to invoke a function in a register with arguments in registers. Also branch to the appropriate reification and return clauses depending on whether the returned value is guaranteed to satisfy the expectedType or not.

Link copied to clipboard
open override fun L1_doCall()

n,m - Send the message at index n in the compiledCode's literals. Pop the arguments for this message off the stack (the message itself knows how many to expect). The first argument was pushed first, and is the deepest on the stack. Use these arguments to look up the method dynamically. Before invoking the method, push nil onto the stack. Its presence will help distinguish continuations produced by the pushLabel instruction from their senders. When the call completes (if ever) by using an implicit return instruction, it will replace this nil with the result of the call.

Link copied to clipboard
open override fun L1_doClose()

n,m - Pop the top n items off the stack, and use them as outer variables in the construction of a function based on the compiledCode that's the literal at index m of the current compiledCode.

Link copied to clipboard
open override fun L1_doExtension()

The extension nybblecode was encountered. Read another nybble and dispatch it as an extended instruction.

Link copied to clipboard
open override fun L1_doGetLocal()

n - Push the value of the local variable (not an argument) indexed by n (index 1 is first argument).

Link copied to clipboard
open override fun L1_doGetLocalClearing()

n - Push the value of the local variable (not an argument) indexed by n (index 1 is first argument). If the variable itself is mutable, clear it now - nobody will know.

Link copied to clipboard
open override fun L1_doGetOuter()

n - Push the value of the outer variable indexed by n in the current function.

Link copied to clipboard
open override fun L1_doGetOuterClearing()

n - Push the value of the outer variable indexed by n in the current function. If the variable itself is mutable, clear it at this time - nobody will know.

Link copied to clipboard
open override fun L1_doMakeTuple()

n - Make a tuple from n values popped from the stack. Push the tuple.

Link copied to clipboard
open override fun L1_doPop()

Remove the top item from the stack.

Link copied to clipboard
open override fun L1_doPushLastLocal()

n - Push the argument (actual value) or local variable (the variable itself) indexed by n. Since this is known to be the last use (non-debugger) of the argument or local, void that slot of the current continuation.

Link copied to clipboard
open override fun L1_doPushLastOuter()

n - Push the outer variable indexed by n in the current function. If the variable is mutable, clear it (no one will know). If the variable and function are both mutable, remove the variable from the function by voiding it.

Link copied to clipboard
open override fun L1_doPushLiteral()

n - Push the literal indexed by n in the current compiledCode.

Link copied to clipboard
open override fun L1_doPushLocal()

n - Push the argument (actual value) or local variable (the variable itself) indexed by n.

Link copied to clipboard
open override fun L1_doPushOuter()

n - Push the outer variable indexed by n in the current function.

Link copied to clipboard
open override fun L1_doSetLocal()

n - Pop the stack and assign this value to the local variable (not an argument) indexed by n (index 1 is first argument).

Link copied to clipboard
open override fun L1_doSetOuter()

n - Pop the stack and assign this value to the outer variable indexed by n in the current function.

Link copied to clipboard
open override fun L1Ext_doDuplicate()

Duplicate the element at the top of the stack. Make the element immutable since there are now at least two references.

Link copied to clipboard
open override fun L1Ext_doGetLiteral()

n - Push the value of the variable that's literal number n in the current compiledCode.

Link copied to clipboard
open override fun L1Ext_doPermute()

n - Permute the top n stack elements as specified by a literal permutation tuple. For example, if A, B, and C have been pushed, in that order, a permute tuple of &lt;2, 3, 1&gt; indicates the stack should have A in the 2nd slot, B in the 3rd, and C in the 1st. It has the same effect as having pushed C, and A, and B, in that order.

Link copied to clipboard
open override fun L1Ext_doPushLabel()

Build a continuation which, when restarted, will be just like restarting the current continuation.

Link copied to clipboard
open override fun L1Ext_doSetLiteral()

n - Pop the stack and assign this value to the variable that's the literal indexed by n in the current compiledCode.

Link copied to clipboard
open override fun L1Ext_doSetLocalSlot()

Pop the stack, writing the value directly into the indicated local slot. This is how local constants become initialized.

Link copied to clipboard
open override fun L1Ext_doSuperCall()

Invoke a method with a supercall.

Link copied to clipboard

Given an L2WriteBoxedOperand, produce an L2ReadBoxedOperand of the same value, but with the current manifest's TypeRestriction applied.

Link copied to clipboard

Answer the register holding the latest assigned version of the specified continuation slot. The slots are the arguments, then the locals, then the stack entries. The slots are numbered starting at 1.

Link copied to clipboard
fun reify(expectedValueOrNull: A_Type?, typeOfEntryPoint: L2JVMChunk.ChunkEntryPoint)

Generate code to create the current continuation, with a nil caller, then L2_RETURN_FROM_REIFICATION_HANDLER – so the calling frames will also get a chance to add their own nil-caller continuations to the current StackReifier. The execution machinery will then assemble the chain of continuations, connecting them to any already reified continuations in the interpreter.