Search in sources :

Example 1 with VariadicMemory

use of php.runtime.memory.helper.VariadicMemory 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;
}
Also used : ArrayMemory(php.runtime.memory.ArrayMemory) ReferenceMemory(php.runtime.memory.ReferenceMemory) ForeachIterator(php.runtime.lang.ForeachIterator) ParameterEntity(php.runtime.reflection.ParameterEntity) Memory(php.runtime.Memory) ArrayMemory(php.runtime.memory.ArrayMemory) ReferenceMemory(php.runtime.memory.ReferenceMemory) ObjectMemory(php.runtime.memory.ObjectMemory) VariadicMemory(php.runtime.memory.helper.VariadicMemory) VariadicMemory(php.runtime.memory.helper.VariadicMemory)

Example 2 with VariadicMemory

use of php.runtime.memory.helper.VariadicMemory in project jphp by jphp-compiler.

the class InvokeArgumentHelper method unpackArgs.

public static Memory[] unpackArgs(Environment env, TraceInfo trace, Memory[] passed, ParameterEntity[] parameters) {
    List<Memory> varPassed = null;
    if (passed == null) {
        return null;
    }
    int cnt = 0, paramCnt = 0;
    ParameterEntity parameterEntity = null;
    boolean variadicMemoryExists = false;
    for (Memory arg : passed) {
        if (arg instanceof VariadicMemory) {
            variadicMemoryExists = true;
            if (varPassed == null) {
                varPassed = new ArrayList<Memory>();
                for (int i = 0; i < cnt; i++) {
                    varPassed.add(passed[i]);
                }
            }
            boolean isGenerator = arg.instanceOf(Generator.class);
            ForeachIterator foreachIterator = arg.getNewIterator(env, !isGenerator, false);
            if (foreachIterator == null || (!isGenerator && !arg.isTraversable())) {
                env.warning(trace, INVALID_TYPE_MESSAGE);
            } else {
                boolean isRef;
                while (foreachIterator.next()) {
                    if (parameters != null) {
                        if (parameterEntity == null || !parameterEntity.isVariadic()) {
                            parameterEntity = paramCnt < parameters.length ? parameters[paramCnt] : null;
                        }
                    }
                    isRef = parameterEntity != null && parameterEntity.isReference();
                    Memory value = foreachIterator.getValue();
                    varPassed.add(isRef ? value : value.toImmutable());
                    paramCnt++;
                    if (parameterEntity != null && !parameterEntity.isVariadic()) {
                        parameterEntity = null;
                    }
                }
            }
        } else {
            if (variadicMemoryExists) {
                env.error(trace, "Cannot use positional argument after argument unpacking");
            }
            if (varPassed != null) {
                varPassed.add(arg);
            }
            paramCnt++;
        }
        cnt++;
    }
    if (varPassed != null) {
        passed = varPassed.toArray(new Memory[varPassed.size()]);
    }
    return passed;
}
Also used : ForeachIterator(php.runtime.lang.ForeachIterator) ParameterEntity(php.runtime.reflection.ParameterEntity) Memory(php.runtime.Memory) ArrayMemory(php.runtime.memory.ArrayMemory) ReferenceMemory(php.runtime.memory.ReferenceMemory) ObjectMemory(php.runtime.memory.ObjectMemory) VariadicMemory(php.runtime.memory.helper.VariadicMemory) VariadicMemory(php.runtime.memory.helper.VariadicMemory)

Aggregations

Memory (php.runtime.Memory)2 ForeachIterator (php.runtime.lang.ForeachIterator)2 ArrayMemory (php.runtime.memory.ArrayMemory)2 ObjectMemory (php.runtime.memory.ObjectMemory)2 ReferenceMemory (php.runtime.memory.ReferenceMemory)2 VariadicMemory (php.runtime.memory.helper.VariadicMemory)2 ParameterEntity (php.runtime.reflection.ParameterEntity)2