Annotation Interface ShortCircuitOperation


@Retention(SOURCE) @Target(TYPE) @Repeatable(ShortCircuitOperation.Repeat.class) public @interface ShortCircuitOperation
Declares a short-circuiting operation. A short-circuiting operation serves as a specification for a short-circuiting bytecode instruction in the generated interpreter. Whereas regular operations evaluate all of their operands eagerly, short-circuiting operations evaluate them one at a time.

A short-circuiting operation converts each operand to a boolean to determine whether to continue execution. An OR operation continues until it encounters true; an AND operation continues until it encounters false.

A short-circuiting operation produces either the last operand evaluated, or the boolean it converted to. Both the boolean operator and the return semantics are specified by the operator().

For example, the following code declares a short-circuiting "Or" operation that continues to evaluate operands as long as they coerce to false:

 @GenerateBytecode(...)
 @ShortCircuitOperation(name = "Or", operator=Operator.OR_RETURN_VALUE, booleanConverter = CoerceBoolean.class)
 public static final class MyBytecodeNode extends RootNode implements BytecodeRootNode {
   @Operation
   public static final class CoerceBoolean {
     @Specialization
     public static boolean fromInt(int x) { return x != 0; }
     @Specialization
     public static boolean fromBool(boolean x) { return x; }
     @Specialization
     public static boolean fromObject(Object x) { return x != null; }
   }

   ...
 }
 
In pseudocode, the Or operation declared above has the following semantics:
 value_1 = // compute operand_1
 if CoerceBoolean(value_1) != false
   return value_1

 value_2 = // compute operand_2
 if CoerceBoolean(value_2) != false
   return value_2

 ...

 value_n = // compute operand_n
 return value_n
 
Since the operand value itself is returned, this operation can be used to implement null-coalescing operations (e.g., someArray or [] in Python).
Since:
24.2
  • Element Details

    • name

      String name
      The name of this operation.
      Since:
      24.2
    • operator

      The short-circuit operator to use for this operation. The operator decides whether to perform a boolean AND or OR. It also determines whether the operation produces the original operand or the boolean that results from conversion.

      An OR operation will execute children until a true value; an AND operation will execute children until a false value. Note that this means booleanConverter() can be negated by changing an OR to an AND (or vice-versa) and then inverting the result. For example, !convert(A) OR !convert(B) OR ... can be implemented using !(convert(A) AND convert(B) AND ...).

      Since:
      24.2
    • booleanConverter

      Class<?> booleanConverter
      A node or operation class. The short-circuit operation uses this class to convert each operand value to a boolean value used by the boolean operation.

      If no converter is provided, the operands must already be booleans. The interpreter will cast each operand to boolean in order to compare it against true or false (throwing ClassCastException or NullPointerException as appropriate). However, since the last operand is not compared against true or false, it is not checked; it is the language's responsibility to ensure the operands are boolean (or to properly handle a non-boolean result in the consuming operation).

      The class can be (but does not need to be) declared as an Operation or OperationProxy. If it is not declared as either, it will undergo the same validation as an Operation (see the Operation Javadoc for the specific requirements). In addition, such a node/operation must:

      • Only have specializations returning boolean.
      • Only have specializations that take a single dynamic operand.
      Since:
      24.2
      Default:
      void.class
    • javadoc

      String javadoc
      Optional documentation for the short circuit operation. This documentation is included in the javadoc for the generated interpreter.
      Since:
      24.2
      Default:
      ""