Package org.codehaus.groovy.vmplugin.v8

# Class IndyCompoundAssign

java.lang.Object
org.codehaus.groovy.vmplugin.v8.IndyCompoundAssign

public final class IndyCompoundAssign extends Object
GEP-15: resolver for dynamic compound-assignment operators (`+=`, `-=`, ...).

This class holds only the GEP-15-specific policy; the call-site lifecycle is owned by `IndyInterface`. A compound-assignment `op=` is emitted as an `invokedynamic` to `IndyInterface.bootstrap(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType, java.lang.String, int)` with call type `IndyInterface.CallType.COMPOUND_ASSIGN`, so it rides the same boot handle, per-receiver-class inline cache, monomorphic-promotion and deopt-storm protection as a normal method call. `IndyInterface.fallback(org.codehaus.groovy.vmplugin.v8.CacheableCallSite, java.lang.Class<?>, java.lang.String, int, java.lang.Boolean, java.lang.Boolean, java.lang.Boolean, java.lang.Object, java.lang.Object[])` routes resolution here via `resolve(org.codehaus.groovy.vmplugin.v8.CacheableCallSite, java.lang.Class<?>, java.lang.String, java.lang.Object[])`.

What remains GEP-15-specific:

- the two operator names (`assignName`/`baseName`) packed into the bootstrap `name` and unpacked here;
- a `respondsTo` probe to pick `*Assign` vs base — run only on a cache miss;
- the in-place return-receiver composition for the assign branch;
- a `(receiver class, arg class)` guard (arg class is part of the key so overloads stay correct), under the shared MOP switch point;
- a generic fall back to `ScriptBytecodeAdapter.compoundAssign(java.lang.Object, java.lang.Object, java.lang.String, java.lang.String)` for null/unresolved receivers.

The actual invocation is built by `Selector.selectInvokeHandle(org.codehaus.groovy.vmplugin.v8.CacheableCallSite, java.lang.Class<?>, java.lang.String, java.lang.Object[])`, so selection/coercion/vargs/category/exception handling match a normal call.

WARNING: internal, indy-only. Not for use outside this package.

Since:
  6.0.0

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final char`
  `NAME_SEPARATOR`
  Separator packing `assignName` and `baseName` into one bootstrap constant (NUL cannot appear in a JVM method name, even a Groovy quoted one).

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static boolean`
  `guard(Class<?> rc, Class<?> ac, Object receiver, Object arg)`
  Guard: receiver and argument runtime classes both match the cached shape.
  `static String`
  `packNames(String assignName, String baseName)`
  Packs the two operator names into a single bootstrap `name` constant.
  `static org.codehaus.groovy.vmplugin.v8.MethodHandleWrapper`
  `resolve(CacheableCallSite callSite, Class<?> sender, String packedNames, Object[] arguments)`
  Resolves the invocation for one receiver/arg shape and returns a `MethodHandleWrapper` for `IndyInterface`'s inline cache.

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

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### NAME_SEPARATOR

    public static final char NAME_SEPARATOR
    Separator packing `assignName` and `baseName` into one bootstrap constant (NUL cannot appear in a JVM method name, even a Groovy quoted one).
    See Also:
      - Constant Field Values

- ## Method Details

  - ### packNames

    public static String packNames(String assignName, String baseName)
    Packs the two operator names into a single bootstrap `name` constant. Called from code generation.

  - ### resolve

    public static org.codehaus.groovy.vmplugin.v8.MethodHandleWrapper resolve(CacheableCallSite callSite, Class<?> sender, String packedNames, Object[] arguments)
    Resolves the invocation for one receiver/arg shape and returns a `MethodHandleWrapper` for `IndyInterface`'s inline cache. The wrapper's target handle is `(Object receiver, Object arg) -> Object`, guarded on the receiver/arg classes and the shared MOP switch point with the call site's fallback (re-resolve) path as the else-branch.
    Parameters:
      `callSite` - the compound-assignment call site (type `(Object,Object)->Object`)
      `sender` - the sending class
      `packedNames` - `assignName` and `baseName` joined by `NAME_SEPARATOR`
      `arguments` - the runtime arguments: `[receiver, arg]`

  - ### guard

    public static boolean guard(Class<?> rc, Class<?> ac, Object receiver, Object arg)
    Guard: receiver and argument runtime classes both match the cached shape.