enter

@Advice.OnMethodEnter(skipOn = OnNonDefaultValue::class, suppress = Throwable::class)
open fun enter(slot: Int, key: String, @Advice.Origin sig: MethodType, @Advice.This(optional = true) self: Any, @Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) args: Array<Any>): Any

Read once into a local, hand that to the bridge, store it back — none of which is decoration. Advice.AllArguments has no backing variable: every READ builds a fresh array out of the parameter slots, and the write distributes whatever array is on the stack into them. So a re-read would hand back the original values (args = args is a perfect round trip), and only the array the bridge actually mutated may be stored.

The distribution casts each element and aborts on the first bad one — inside the suppression handler, so nothing escapes, but the slots ahead of it are already written. Validating in Patch.InterceptHandler first is what keeps the rewrite all-or-nothing.

Return

null to run the body, or an Object[1] carrying the substitute return value