Class PcodeFrame
To distinguish the program counter of a p-code program from the program counter of the machine it models, we address p-code ops by "index." When derived from an instruction, the address and index together form the "sequence number." Because the executor cares not about the derivation of a p-code program, it counts through indices. The frame carries with it the p-code ops comprising its current p-code program.
A p-code emulator feeds p-code to an executor by decoding one instruction at a time. Thus, the "current p-code program" comprises only those ops generated by a single instruction. Or else, it is a user-supplied p-code program, e.g., to evaluate a Sleigh expression. The frame completes the program by falling-through, i.e., stepping past the final op, or by branching externally, i.e., to a different machine instruction. The emulator must then update its program counter accordingly and proceed to the next instruction.
Methods receiving a frame should use it only for the userop names, usually to fabricate a sub
frame. Other than the executor, things should generally not access its code. If a PcodeOp
is provided to the same method, generally that is the only op this frame is guaranteed to
contain. The execution engine is not required to provide the surrounding ops.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classprotected class -
Constructor Summary
ConstructorsConstructorDescriptionPcodeFrame(Language language, List<PcodeOp> code, PcodeUseropLibrary.PcodeUseropSymbolMap userops) Construct a frame of p-code execution -
Method Summary
Modifier and TypeMethodDescriptionintadvance()Advance the indexvoidbranch(int rel) Perform an internal branch, relative to the current op.PcodeOp[]copyCode()Copy the frame's code (shallow copy) into a new arrayvoidComplete the p-code program, indicating an external branchintGet the index of the last (branch) op executedgetCode()Get all the ops in the current p-code program.getUseropName(int userop) Get the name of the userop for the given numberReturns the map of userop symbols.intindex()The index of the next p-code op to be executedbooleanisBranch()Check if the p-code program has executed a branchbooleanCheck if the index has advanced past the end of the p-code programbooleanCheck if the p-code program is completely executednextOp()Get the op at the current index, and then advance that indexintGet and reset the number of p-code ops executedintstepBack()Step the index back onetoString()
-
Constructor Details
-
PcodeFrame
public PcodeFrame(Language language, List<PcodeOp> code, PcodeUseropLibrary.PcodeUseropSymbolMap userops) Construct a frame of p-code executionThe passed in code should be an immutable list. It is returned directly by
getCode(), which would otherwise allow mutation. The frame does not create its own immutable copy as a matter of efficiency. Instead, the provider of the code should create an immutable copy, probably once, e.g., when compiling aPcodeProgram.- Parameters:
language- the language to which the program appliescode- the program's p-codeuserops- a map of additional sleigh/p-code userops linked to the program
-
-
Method Details
-
toString
-
resetCount
public int resetCount()Get and reset the number of p-code ops executedContrast this to
index(), which marks the next op to be executed. This counts the number of ops executed, which will differ from index when an internal branch is taken.- Returns:
- the count
-
index
public int index()The index of the next p-code op to be executedIf the last p-code op resulted in a branch, this will instead return -1.
- Returns:
- the index, i.e, p-code "program counter."
- See Also:
-
nextOp
Get the op at the current index, and then advance that indexThis is used in the execution loop to retrieve each op to execute
- Returns:
- the op to execute
-
advance
public int advance()Advance the index- Returns:
- the value of the index before it was advanced
-
stepBack
public int stepBack()Step the index back one- Returns:
- the value of the index before it was stepped back
-
getUseropName
Get the name of the userop for the given number- Parameters:
userop- the userop number, as encoded in the first operand ofPcodeOp.CALLOTHER- Returns:
- the name of the userop, as expressed in the Sleigh source
-
getUserops
Returns the map of userop symbols.- Returns:
- the map of userop symbols
-
isFallThrough
public boolean isFallThrough()Check if the index has advanced past the end of the p-code programIf the index has advanced beyond the program, it implies the program has finished executing. In the case of instruction emulation, no branch was encountered. The machine should advance to the fall-through instruction.
- Returns:
- true if the program completed without branching
- See Also:
-
isBranch
public boolean isBranch()Check if the p-code program has executed a branchBranches can be internal, i.e., within the current program, or external, i.e., to another machine instructions. This refers strictly to the latter.
- Returns:
- true if the program completed with an external branch
- See Also:
-
isFinished
public boolean isFinished()Check if the p-code program is completely executed- Returns:
- true if execution finished, either in fall-through or an external branch
- See Also:
-
branch
public void branch(int rel) Perform an internal branch, relative to the current op.Because index advances before execution of each op, the index is adjusted by an extra -1.
- Parameters:
rel- the adjustment to the index
-
finishAsBranch
public void finishAsBranch()Complete the p-code program, indicating an external branch -
getCode
-
copyCode
Copy the frame's code (shallow copy) into a new array- Returns:
- the array of ops
-
getBranched
public int getBranched()Get the index of the last (branch) op executedThe behavior here is a bit strange for compatibility with
EmulateInstructionStateModifier. If the p-code program (likely derived from a machine instruction) completed with fall-through, then this will return -1. If it completed on a branch, then this will return the index of that branch.- Returns:
- the last index executed
-