Package ghidra.pcode.emu.jit.gen.op

# 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`, `org.objectweb.asm.Opcodes`

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 `generateRunCodeUsingDirectStrategy(JitCodeGenerator, JitCallOtherOpIf, JitBlock, MethodVisitor)`. If not, it emits code using `generateRunCodeUsingRetirementStrategy(JitCodeGenerator, PcodeOp, JitBlock, PcodeUseropDefinition, MethodVisitor)`. 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 userop and emit code to load it. We then emit code to prepare its arguments and place them on the stack, namely the output varnode and an array for the input varnodes. We request a field for each varnode and emit code to load them as needed. For the array, we emit code to construct and fill it. We then emit code to invoke `JitCompiledPassage.invokeUserop(PcodeUseropDefinition, Varnode, Varnode[])`. 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`.

- ## Nested Class Summary

  ## Nested classes/interfaces inherited from class java.lang.Enum

  `Enum.EnumDesc<E extends Enum<E>>`

- ## Enum Constant Summary

  Enum Constants
  Enum Constant
  Description
  `GEN`
  The generator singleton

- ## Field Summary

  ### Fields inherited from interface org.objectweb.asm.Opcodes

  `AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, 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, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V9`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static boolean`
  `canDoDirectInvocation(JitCallOtherOpIf op)`
  Check if the Direct invocation strategy is applicable (see class documentation)
  `void`
  `generateRunCode(JitCodeGenerator gen, JitCallOtherOpIf op, JitControlFlowModel.JitBlock block, org.objectweb.asm.MethodVisitor rv)`
  Emit bytecode into the `run` method.
  `static void`
  `generateRunCodeUsingDirectStrategy(JitCodeGenerator gen, JitCallOtherOpIf op, JitControlFlowModel.JitBlock block, org.objectweb.asm.MethodVisitor rv)`
  Emit code to implement the Direct strategy (see the class documentation)
  `static void`
  `generateRunCodeUsingRetirementStrategy(JitCodeGenerator gen, PcodeOp op, JitControlFlowModel.JitBlock block, PcodeUseropLibrary.PcodeUseropDefinition<?> userop, org.objectweb.asm.MethodVisitor rv)`
  Emit code to implement the Standard strategy (see the class documentation)
  `static CallOtherOpGen`
  `valueOf(String name)`
  Returns the enum constant of this class with the specified name.
  `static CallOtherOpGen[]`
  `values()`
  Returns an array containing the constants of this enum class, in the order they are declared.

  ### Methods inherited from class java.lang.Enum

  `clone, compareTo, describeConstable, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf`

  ### Methods inherited from class java.lang.Object

  `getClass, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface ghidra.pcode.emu.jit.gen.op.OpGen

  `generateInitCode`

- ## Enum Constant Details

  - ### GEN

    public static final CallOtherOpGen GEN
    The generator singleton

- ## Method Details

  - ### values

    public static CallOtherOpGen[] values()
    Returns an array containing the constants of this enum class, in the order they are declared.
    Returns:
      an array containing the constants of this enum class, in the order they are declared

  - ### valueOf

    public static CallOtherOpGen valueOf(String name)
    Returns the enum constant of this class with the specified name. The string must match exactly an identifier used to declare an enum constant in this class. (Extraneous whitespace characters are not permitted.)
    Parameters:
      `name` - the name of the enum constant to be returned.
    Returns:
      the enum constant with the specified name
    Throws:
      `IllegalArgumentException` - if this enum class has no constant with the specified name
      `NullPointerException` - if the argument is null

  - ### generateRunCodeUsingRetirementStrategy

    public static void generateRunCodeUsingRetirementStrategy(JitCodeGenerator gen, PcodeOp op, JitControlFlowModel.JitBlock block, PcodeUseropLibrary.PcodeUseropDefinition<?> userop, org.objectweb.asm.MethodVisitor rv)
    Emit code to implement the Standard strategy (see the class documentation)
    Parameters:
      `gen` - the code generator
      `op` - the p-code op
      `block` - the block containing the op
      `userop` - the userop definition, wrapped by the `JitDataFlowUseropLibrary`
      `rv` - the visitor for the `run` method

  - ### generateRunCodeUsingDirectStrategy

    public static void generateRunCodeUsingDirectStrategy(JitCodeGenerator gen, JitCallOtherOpIf op, JitControlFlowModel.JitBlock block, org.objectweb.asm.MethodVisitor rv)
    Emit code to implement the Direct strategy (see the class documentation)
    Parameters:
      `gen` - the code generator
      `op` - the p-code op use-def node
      `block` - the block containing the op
      `rv` - the visitor for the `run` method

  - ### canDoDirectInvocation

    public static boolean canDoDirectInvocation(JitCallOtherOpIf op)
    Check if the Direct invocation strategy is applicable (see class documentation)
    Parameters:
      `op` - the p-code op use-def node
    Returns:
      true if applicable

  - ### generateRunCode

    public void generateRunCode(JitCodeGenerator gen, JitCallOtherOpIf op, JitControlFlowModel.JitBlock block, org.objectweb.asm.MethodVisitor rv)
    Description copied from interface: `OpGen`
    Emit bytecode into the `run` method.

    This method must emit the code needed to load any input operands, convert them to the appropriate type, perform the actual operation, and then if applicable, store the output operand. The implementations should delegate to `JitCodeGenerator.generateValReadCode(JitVal, JitTypeBehavior, Ext)`, `JitCodeGenerator.generateVarWriteCode(JitVar, JitType, Ext)`, and `TypeConversions` appropriately.

    Specified by:
      `generateRunCode` in interface `OpGen<JitCallOtherOpIf>`
    Parameters:
      `gen` - the code generator
      `op` - the p-code op (use-def node) to translate
      `block` - the basic block containing the p-code op
      `rv` - the visitor for the `run` method.