Package: org.codehaus.groovy.runtime

## [Java] Interface GeneratedDispatcher

-     @FunctionalInterface
      public interface GeneratedDispatcher

  A per-class table of compiler-generated dispatch targets, reached by a compact integer id instead of a MethodHandle.

  The compiler emits per class: an array-shaped table (`$packedDispatch$(int, Object[])`, covering every target) plus array-free per-arity tables (`$packedDispatch1$`, `$packedDispatch2$`) for the hot shapes taking one or two values beyond the receiver — avoiding the packed argument array, which cannot be scalar-replaced when the dispatch call does not inline. Each table is a switch over the id whose case casts the arguments to the target's declared parameter types and invokes it directly, so the whole chain is ordinary, JIT-friendly bytecode. A single `invokedynamic` accessor per class links all three through bootstrap into one constant Bundle, created lazily on first use.

  Adapters such as PackedClosure hold `(dispatchers, id)` and make a plain interface call per invocation. Unlike a `MethodHandle` held in an instance field — which the JIT cannot treat as a constant, so every call runs the (comparatively slow) method-handle invoker — this executes as a cheap indirect call, and inlines fully when the call site is monomorphic. The id space is not limited to packed closure bodies: any statically-known target the compiler wants to reach through a shared adapter (for example a statically-resolved method reference) can claim an id in the same tables.

  Since:
    6.0.0

- - ### Nested Class Summary

    Nested classes
    Modifiers | Name | Description
    --- | --- | ---
    `interface` | `GeneratedDispatcher.Arity1` | Array-free companion for targets taking exactly one value beyond the receiver.
    `interface` | `GeneratedDispatcher.Arity2` | Array-free companion for targets taking exactly two values beyond the receiver.
    `class` | `GeneratedDispatcher.Bundle` | The hosting class's three dispatch shapes, linked once by bootstrap and shared by all of that class's adapters.

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public static CallSite` | `bootstrap(Lookup caller, String name, MethodType type)` Legacy invokedynamic bootstrap for the dispatcher accessor, kept for class files emitted by earlier 6.0 pre-releases: adapts the class's three private static dispatch tables to their functional interfaces (one hidden class each, via `LambdaMetafactory` with the caller's full-privilege lookup) and returns them as one constant Bundle.
    `` | `public static CallSite` | `bootstrap(Lookup caller, String name, MethodType type, MethodHandle factory)` Invokedynamic bootstrap for the dispatcher accessor: the hosting class supplies (as a constant bootstrap argument) a compiler-emitted factory that builds the bundle from its own bytecode-level `LambdaMetafactory` sites, so linking is one call and this method neither looks anything up nor defines any class — fit for any ahead-of-time runtime that restricts run-time reflection or class definition.
    `` | `public Object` | `dispatch(int id, Object[] args)` Invokes the dispatch target registered under `id` in the hosting class.
    `` | `public static Class<?>[]` | `paramTypes(Lookup caller, String name, Class<?> type, String descriptor)` Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a method descriptor (which, unlike `Class` constants, can carry primitive types) with the hosting class's loader into a `Class[]` resolved once per literal site and shared by every adapter created there — closure creation then loads one constant instead of allocating and filling an array.

- - ### Method Detail

    - #### public static CallSite bootstrap(Lookup caller, String name, MethodType type)

      Legacy invokedynamic bootstrap for the dispatcher accessor, kept for class files emitted by earlier 6.0 pre-releases: adapts the class's three private static dispatch tables to their functional interfaces (one hidden class each, via `LambdaMetafactory` with the caller's full-privilege lookup) and returns them as one constant Bundle. Current class files link through the one-`MethodHandle` overload instead. Emitted bytecode reaches this through `org.codehaus.groovy.vmplugin.v8.IndyInterface#packedDispatchers` — the central bytecode-facing bootstrap surface — which delegates here.

      throws:
        Throwable if the tables cannot be found or linked (a compiler bug)
      Parameters:
        `caller` - the hosting class's lookup (supplied by the JVM)
        `name` - the invoked name (unused)
        `type` - the accessor's type: `() -> Object` as emitted (typed loosely so the `Bundle` type stays off the emitted-bytecode surface); the constant is typed off the requested return type, so `() -> Bundle` also links
      Returns:
        a constant call site producing the bundle

    - #### public static CallSite bootstrap(Lookup caller, String name, MethodType type, MethodHandle factory)

      Invokedynamic bootstrap for the dispatcher accessor: the hosting class supplies (as a constant bootstrap argument) a compiler-emitted factory that builds the bundle from its own bytecode-level `LambdaMetafactory` sites, so linking is one call and this method neither looks anything up nor defines any class — fit for any ahead-of-time runtime that restricts run-time reflection or class definition. Under GraalVM native image, the verified case, those sites are pre-processed at image build time and the factory's method references reach the class's own private tables without reflection metadata (GROOVY-12227). Emitted bytecode reaches this through `org.codehaus.groovy.vmplugin.v8.IndyInterface#packedDispatchers`.

      throws:
        Throwable if the factory fails (a compiler bug)
      Parameters:
        `caller` - the hosting class's lookup (supplied by the JVM, unused)
        `name` - the invoked name (unused)
        `type` - the accessor's type (see the three-argument overload)
        `factory` - the hosting class's `$packedDispatchersFactory$`, `() -> Bundle`
      Returns:
        a constant call site producing the bundle

    - #### public Object dispatch(int id, Object[] args)

      Invokes the dispatch target registered under `id` in the hosting class.

      Parameters:
        `id` - the compile-time-assigned index of the target in the hosting class's table
        `args` - the packed argument array: `args[0]` is the receiver (the adapter's owner — ignored by static targets), followed by any captured values, then the call arguments, all in the target's declared parameter order
      Returns:
        the target's return value (`null` for a void target)

    - #### public static Class<?>[] paramTypes(Lookup caller, String name, Class<?> type, String descriptor)

      Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a method descriptor (which, unlike `Class` constants, can carry primitive types) with the hosting class's loader into a `Class[]` resolved once per literal site and shared by every adapter created there — closure creation then loads one constant instead of allocating and filling an array. Sharing matches generated closure classes, whose parameter-type arrays are likewise cached per class. Emitted bytecode reaches this through `org.codehaus.groovy.vmplugin.v8.IndyInterface#packedParamTypes`, which delegates here.

      Parameters:
        `caller` - the hosting class's lookup (supplied by the JVM)
        `name` - the constant's name (unused)
        `type` - the constant's type: `Class[]`
        `descriptor` - a method descriptor whose parameter types are the closure's declared parameter types (the return type is ignored)
      Returns:
        the declared parameter types