/// <summary> /// Invokes this callback (must be bound). /// </summary> /// <param name="args">Arguments to be passed to target function or method (can be <see cref="PhpReference"/>s).</param> /// <returns>The value returned by the called function or method (can be a <see cref="PhpReference"/>).</returns> internal object InvokeInternal(params object[] args) { Debug.Assert(IsBound, "Callback must be bound."); Debug.Assert(routineDesc != null); // Since it's possible to call non static method statically we can't use this condition in the assert && (routineDesc.IsStatic || instance != null)); // push args to PHP stack and invoke the desc PhpStack stack = (context != null ? context.Stack : ScriptContext.CurrentContext.Stack); if (state == State.BoundToCaller) { // push the real target name and args as a PhpArray stack.AddFrame(targetName, new PhpArray(args)); } else { stack.AddFrame(args); } stack.Callback = true; stack.LateStaticBindType = this.lateStaticBindType; return(routineDesc.Invoke(instance, stack, callingContext)); }