package php.runtime.ext.core.classes; import php.runtime.Memory; import php.runtime.annotation.Runtime; import php.runtime.common.HintType; import php.runtime.env.Environment; import php.runtime.invoke.DynamicMethodInvoker; import php.runtime.invoke.FunctionInvoker; import php.runtime.invoke.Invoker; import php.runtime.invoke.StaticMethodInvoker; import php.runtime.lang.BaseObject; import php.runtime.lang.Closure; import php.runtime.memory.ArrayMemory; import php.runtime.memory.LongMemory; import php.runtime.memory.ObjectMemory; import php.runtime.memory.StringBuilderMemory; import php.runtime.reflection.ClassEntity; import php.runtime.reflection.ParameterEntity; import static php.runtime.annotation.Reflection.*; @Name("php\\lang\\Invoker") public class WrapInvoker extends BaseObject { protected Invoker invoker; public WrapInvoker(Environment env, Invoker invoker) { super(env); this.invoker = invoker; } public WrapInvoker(Environment env, ClassEntity clazz) { super(env, clazz); } public Invoker getInvoker() { return invoker; } @Signature({ @Arg(value = "callback", type = HintType.CALLABLE) }) public Memory __construct(Environment env, Memory... args) { this.invoker = Invoker.valueOf(env, null, args[0]); return Memory.NULL; } @Signature private Memory __clone(Environment env, Memory... args) { return Memory.NULL; } @Signature public Memory canAccess(Environment env, Memory... args) { return invoker.canAccess(env) == 0 ? Memory.TRUE : Memory.FALSE; } @Signature public Memory getArgumentCount(Environment env, Memory... args) { return LongMemory.valueOf(invoker.getArgumentCount()); } @Signature public Memory getDescription(Environment env, Memory... args) { StringBuilderMemory sb = new StringBuilderMemory(); sb.append(invoker.getName()); sb.append("("); int i = 0; if (invoker.getParameters() == null) { sb.append("<internal>"); } else for(ParameterEntity param : invoker.getParameters()) { if (i != 0) sb.append(", "); sb.append(param.getSignatureString()); i++; } sb.append(")"); return sb; } @Signature public Memory isClosure(Environment env, Memory... args) { return invoker instanceof DynamicMethodInvoker && ((DynamicMethodInvoker) invoker).getObject() instanceof Closure ? Memory.TRUE : Memory.FALSE; } @Signature public Memory isNamedFunction(Environment env, Memory... args) { return invoker instanceof FunctionInvoker ? Memory.TRUE : Memory.FALSE; } @Signature public Memory isStaticCall(Environment env, Memory... args) { return invoker instanceof StaticMethodInvoker ? Memory.TRUE : Memory.FALSE; } @Signature public Memory isDynamicCall(Environment env, Memory... args) { return invoker instanceof DynamicMethodInvoker && !(((DynamicMethodInvoker) invoker).getObject() instanceof Closure) ? Memory.TRUE : Memory.FALSE; } @Signature public Memory call(Environment env, Memory... args) { invoker.setTrace(env.trace()); env.popCall(); try { return invoker.callNoThrow(args); } finally { env.pushCall(this, "call"); } } @Signature(@Arg(value = "args", type = HintType.ARRAY)) public Memory callArray(Environment env, Memory... args) { return call(env, args[0].toValue(ArrayMemory.class).values()); } @Signature public Memory __invoke(Environment env, Memory... args) { return call(env, args); } @Runtime.FastMethod @Signature({ @Arg("callback") }) public static Memory of(Environment env, Memory... args) { Invoker invoker = Invoker.valueOf(env, null, args[0]); if (invoker == null) return Memory.NULL; return new ObjectMemory(new WrapInvoker(env, invoker)); } }