use of php.runtime.Memory in project jphp by jphp-compiler.
the class JavaMethod method invoke.
@Signature({ @Arg(value = "object", typeClass = "php\\lang\\JavaObject", optional = @Optional("NULL")) })
public Memory invoke(Environment env, Memory... args) {
int len = args.length - 1;
if (len < paramTypes.length || len > paramTypes.length)
exception(env, new IllegalArgumentException("Invalid argument count"));
Object[] passed = new Object[len];
int i = 0;
for (MemoryUtils.Converter converter : converters) {
Memory arg = args[i + 1];
if (arg.instanceOf("php\\lang\\JavaObject")) {
passed[i] = ((JavaObject) arg.toValue(ObjectMemory.class).value).getObject();
} else {
if (converter != null) {
passed[i] = converter.run(args[i + 1]);
} else {
passed[i] = null;
}
}
i++;
}
Object obj = args[0].isNull() ? null : ((JavaObject) args[0].toValue(ObjectMemory.class).value).getObject();
try {
Object result = method.invoke(obj, passed);
if (result == null)
return Memory.NULL;
if (resultConverter != null)
return MemoryUtils.valueOf(result);
else {
if (method.getReturnType() == void.class)
return Memory.NULL;
return new ObjectMemory(JavaObject.of(env, result));
}
} catch (IllegalAccessException e) {
exception(env, e);
} catch (InvocationTargetException e) {
exception(env, e.getTargetException());
}
return Memory.NULL;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class InvokeArgumentHelper method makeArguments.
public static Memory[] makeArguments(Environment env, Memory[] args, ParameterEntity[] parameters, String originClassName, String originMethodName, TraceInfo trace) {
if (parameters == null)
return args;
args = unpackArgs(env, trace, args, parameters);
Memory[] passed = args;
if ((args == null && parameters.length > 0) || (args != null && args.length < parameters.length)) {
passed = new Memory[parameters.length];
if (args != null && args.length > 0) {
System.arraycopy(args, 0, passed, 0, args.length);
}
}
int i = 0;
if (passed != null) {
boolean variadicMemoryExists = false;
for (ParameterEntity param : parameters) {
Memory arg = passed[i];
if (param.isVariadic()) {
ArrayMemory variadicArgs = new ArrayMemory();
int _i = i;
while (arg != null) {
if (arg instanceof VariadicMemory) {
variadicMemoryExists = true;
ForeachIterator iterator = arg.getNewIterator(env, param.isReference(), false);
if (iterator == null) {
env.warning(trace, INVALID_TYPE_MESSAGE);
} else {
makeVariadic(iterator, variadicArgs, param, env, trace, _i, originClassName, originMethodName);
}
} else {
if (variadicMemoryExists) {
env.error(trace, "Cannot use positional argument after argument unpacking");
}
if (!param.checkTypeHinting(env, arg)) {
invalidType(env, trace, param, _i + 1, arg, originClassName, originMethodName);
}
variadicArgs.add(makeValue(param, arg, env, trace));
}
i++;
if (i < passed.length) {
arg = passed[i];
} else {
break;
}
}
passed[_i] = variadicArgs;
break;
}
if (arg == null) {
Memory def = param.getDefaultValue();
if (def != null) {
if (!param.isReference()) {
passed[i] = param.isMutable() ? def.toImmutable(env, trace) : def;
} else {
passed[i] = new ReferenceMemory(param.isMutable() ? def.toImmutable(env, trace) : def);
}
} else {
if (param.getTypeClass() != null) {
invalidType(env, trace, param, i + 1, null, originClassName, originMethodName);
}
env.error(trace, ErrorType.E_ERROR, Messages.ERR_MISSING_ARGUMENT, (i + 1) + " ($" + param.getName() + ")", originMethodName == null ? originClassName : originClassName + "::" + originMethodName);
passed[i] = param.isReference() ? new ReferenceMemory() : Memory.NULL;
}
} else {
if (param.isReference()) {
if (!arg.isReference() && !arg.isObject()) {
env.error(trace, ErrorType.E_ERROR, "Only variables can be passed by reference");
passed[i] = new ReferenceMemory(arg);
}
} else {
passed[i] = param.isMutable() ? arg.toImmutable() : arg.toValue();
}
}
if (!param.checkTypeHinting(env, passed[i])) {
invalidType(env, trace, param, i + 1, passed[i], originClassName, originMethodName);
}
i++;
}
if (!variadicMemoryExists) {
for (int j = parameters.length; j < passed.length; j++) {
passed[j] = passed[j].toImmutable();
}
}
}
return passed;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class InvokeArgumentHelper method makeVariadic.
public static void makeVariadic(ForeachIterator iterator, ArrayMemory variadicArray, ParameterEntity param, Environment env, TraceInfo trace, int index, String originClassName, String originMethodName) {
while (iterator.next()) {
Memory arg = iterator.getValue();
if (!param.checkTypeHinting(env, arg)) {
invalidType(env, trace, param, index + 1, arg, originClassName, originMethodName);
}
variadicArray.add(makeValue(param, iterator.getValue(), env, trace));
}
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class InvokeHelper method call.
public static Memory call(Environment env, TraceInfo trace, FunctionEntity function, Memory[] args) throws Throwable {
Memory[] passed = makeArguments(env, args, function.getParameters(), function.getName(), null, trace);
Memory result = function.getImmutableResult();
if (result != null)
return result;
if (trace != null && function.isUsesStackTrace())
env.pushCall(trace, null, args, function.getName(), null, null);
try {
result = function.invoke(env, trace, passed);
} finally {
if (trace != null && function.isUsesStackTrace())
env.popCall();
}
return result;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class MultipleIterator method current.
@Override
@Signature
public Memory current(Environment env, Memory... args) {
if (iterators.size() == 0) {
return Memory.FALSE;
}
ArrayMemory result = new ArrayMemory();
ForeachIterator iterator = iterators.getNewIterator(env);
while (iterator.next()) {
Iterator el = iterator.getValue().toObject(Iterator.class);
if (env.invokeMethodNoThrow(el, "valid").toBoolean()) {
Memory current = env.invokeMethodNoThrow(el, "current");
if ((flags & MIT_KEYS_ASSOC) == MIT_KEYS_ASSOC) {
result.put(iterator.getKey(), current);
} else {
result.add(current);
}
} else {
if ((flags & MIT_NEED_ALL) == MIT_NEED_ALL) {
env.exception(InvalidArgumentException.class, "One of iterators is not valid");
}
}
}
return result.toConstant();
}
Aggregations