Enum Class CallOtherOpGen

java.lang.Object
java.lang.Enum<CallOtherOpGen>
ghidra.pcode.emu.jit.gen.op.CallOtherOpGen
All Implemented Interfaces:
OpGen<JitCallOtherOpIf>, Serializable, Comparable<CallOtherOpGen>, Constable

public enum CallOtherOpGen extends Enum<CallOtherOpGen> implements OpGen<JitCallOtherOpIf>
The generator for a callother.

The checks if Direct invocation is possible. If so, it emits code using genRunDirectStrategy(Emitter, Local, JitCodeGenerator, JitCallOtherOpIf, JitBlock, Scope). If not, it emits code using genRunRetirementStrategy(Emitter, Local, JitCodeGenerator, PcodeOp, JitBlock, PcodeUseropDefinition). Direct invocation is possible when the userop is functional and all of its parameters and return type have a supported primitive type. (char is not supported.) Regarding the invocation strategies, see JitDataFlowUseropLibrary and note that the Inline strategy is already handled by this point.

For the Standard strategy, we emit code to retire the program counter, decode context, and all live variables. We then request a field to hold the PcodeOp.CALLOTHER p-code op and the userop, and emit code to load them. We then emit code to invoke JitCompiledPassage.invokeUserop(PcodeUseropDefinition, PcodeOp). The userop definition handles retrieving all of its inputs and writing the output, directly to the state. Thus, we now need only to emit code to re-birth all the live variables. If any errors occur, execution is interrupted as usual, and our state is consistent.

For the Direct strategy, we wish to avoid retirement and re-birth, so we request an ExceptionHandler. We request a field for the userop, just as in the Standard strategy, but we emit code to invoke PcodeUseropLibrary.PcodeUseropDefinition.getDefiningLibrary() instead. We can use PcodeUseropLibrary.PcodeUseropDefinition.getJavaMethod() at generation time to reflect its Java definition. We then emit code to cast the library and load each of the operands onto the JVM stack. We then emit the invocation of the Java method, guarded by the exception handler. We then have to consider whether the userop has an output operand and whether its definition returns a value. If both are true, we emit code to write the result. If neither is true, we're done. If a result is returned, but no output operand is provided, we must still emit a pop.