use of php.runtime.lang.ForeachIterator in project jphp by jphp-compiler.
the class SPLFunctions method iterator_apply.
public static long iterator_apply(Environment env, TraceInfo trace, Memory object, Memory callback, Memory args) throws Throwable {
if (expectingImplement(env, trace, 1, object, Traversable.class)) {
Invoker invoker = expectingCallback(env, trace, 2, callback);
if (invoker == null)
return 0;
if (args != null && !expecting(env, trace, 3, args, Memory.Type.ARRAY)) {
return 0;
}
ForeachIterator iterator = object.getNewIterator(env, false, false);
Memory[] values = args == null ? null : args.toValue(ArrayMemory.class).values(true);
int i = 0;
while (iterator.next()) {
if (!invoker.call(values).toBoolean())
break;
i++;
}
return i;
} else
return 0;
}
use of php.runtime.lang.ForeachIterator 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.lang.ForeachIterator in project jphp by jphp-compiler.
the class WrapFlow method append.
@Signature(@Arg(value = "collection", type = HintType.TRAVERSABLE))
public Memory append(Environment env, Memory... args) {
final ForeachIterator appendIterator = args[0].toImmutable().getNewIterator(env);
final ForeachIterator iterator = getSelfIterator(env);
return new ObjectMemory(new WrapFlow(env, new ForeachIterator(false, false, false) {
protected boolean applyAppended = false;
@Override
public void reset() {
iterator.reset();
appendIterator.reset();
applyAppended = false;
}
@Override
protected boolean init() {
return true;
}
@Override
protected boolean nextValue() {
ForeachIterator it = appendIterator;
boolean r = false;
if (!applyAppended) {
it = iterator;
r = it.next();
if (!r) {
applyAppended = true;
it = appendIterator;
}
} else
applyAppended = true;
if (applyAppended)
r = it.next();
return r;
}
@Override
protected boolean prevValue() {
return false;
}
@Override
public Object getKey() {
return applyAppended ? appendIterator.getKey() : iterator.getKey();
}
@Override
public Memory getMemoryKey() {
return applyAppended ? appendIterator.getMemoryKey() : iterator.getMemoryKey();
}
@Override
public Memory getValue() {
return applyAppended ? appendIterator.getValue() : iterator.getValue();
}
}));
}
use of php.runtime.lang.ForeachIterator 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();
}
use of php.runtime.lang.ForeachIterator in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushMemory.
public void writePushMemory(Memory memory) {
Memory.Type type = Memory.Type.REFERENCE;
if (memory instanceof UndefinedMemory) {
code.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Memory.class), "UNDEFINED", Type.getDescriptor(Memory.class)));
} else if (memory instanceof NullMemory) {
code.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Memory.class), "NULL", Type.getDescriptor(Memory.class)));
} else if (memory instanceof FalseMemory) {
writePushConstBoolean(false);
return;
} else if (memory instanceof TrueMemory) {
writePushConstBoolean(true);
return;
} else if (memory instanceof KeyValueMemory) {
writePushMemory(((KeyValueMemory) memory).key);
writePopBoxing();
writePushMemory(((KeyValueMemory) memory).value);
writePopBoxing();
writeSysStaticCall(KeyValueMemory.class, "valueOf", Memory.class, Memory.class, Memory.class);
setStackPeekAsImmutable();
return;
} else if (memory instanceof ReferenceMemory) {
code.add(new TypeInsnNode(NEW, Type.getInternalName(ReferenceMemory.class)));
code.add(new InsnNode(DUP));
code.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(ReferenceMemory.class), Constants.INIT_METHOD, "()V", false));
} else if (memory instanceof ArrayMemory) {
writePushNewObject(ArrayMemory.class);
ArrayMemory array = (ArrayMemory) memory;
ForeachIterator foreachIterator = ((ArrayMemory) memory).foreachIterator(false, false);
while (foreachIterator.next()) {
writePushDup();
if (array.isList()) {
writePushMemory(foreachIterator.getValue());
writePopBoxing();
writeSysDynamicCall(ArrayMemory.class, "add", ReferenceMemory.class, Memory.class);
} else {
Memory key = foreachIterator.getMemoryKey();
writePushMemory(key);
if (!key.isString())
writePopBoxing();
writePushMemory(foreachIterator.getValue());
writePopBoxing();
writeSysDynamicCall(ArrayMemory.class, "put", ReferenceMemory.class, Object.class, Memory.class);
}
writePopAll(1);
}
stackPop();
stackPush(Memory.Type.ARRAY);
setStackPeekAsImmutable();
return;
} else {
switch(memory.type) {
case INT:
{
code.add(new LdcInsnNode(memory.toLong()));
type = Memory.Type.INT;
}
break;
case DOUBLE:
{
code.add(new LdcInsnNode(memory.toDouble()));
type = Memory.Type.DOUBLE;
}
break;
case STRING:
{
code.add(new LdcInsnNode(memory.toString()));
type = Memory.Type.STRING;
}
break;
}
}
stackPush(type);
setStackPeekAsImmutable();
}
Aggregations