Search in sources :

Example 1 with CompileFunction

use of php.runtime.ext.support.compile.CompileFunction in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writePushCall.

Memory writePushCall(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
    Token name = function.getName();
    if (name instanceof NameToken) {
        String realName = ((NameToken) name).getName();
        CompileFunction compileFunction = compiler.getScope().findCompileFunction(realName);
        // try find system function, like max, sin, cos, etc.
        if (compileFunction == null && name instanceof FulledNameToken && compiler.getEnvironment().fetchFunction(realName) == null && compiler.findFunction(realName) == null) {
            String tryName = ((FulledNameToken) name).getLastName().getName();
            compileFunction = compiler.getScope().findCompileFunction(tryName);
        }
        if (compileFunction != null) {
            return writePushCompileFunction(function, compileFunction, returnValue, writeOpcode, statistic);
        } else {
            if (!writeOpcode)
                return null;
            method.entity.setImmutable(false);
            int index = method.clazz.getAndIncCallFuncCount();
            writePushEnv();
            writePushTraceInfo(function);
            writePushString(realName.toLowerCase());
            writePushString(realName);
            writePushParameters(function.getParameters());
            writeGetStatic("$CALL_FUNC_CACHE", FunctionCallCache.class);
            writePushConstInt(index);
            writeSysStaticCall(InvokeHelper.class, "call", Memory.class, Environment.class, TraceInfo.class, String.class, String.class, Memory[].class, FunctionCallCache.class, Integer.TYPE);
            if (!returnValue)
                writePopAll(1);
        }
    } else if (name instanceof StaticAccessExprToken) {
        method.entity.setImmutable(false);
        if (((StaticAccessExprToken) name).isAsParent())
            return writePushParentDynamicMethod(function, returnValue, writeOpcode, statistic);
        else
            return writePushStaticMethod(function, returnValue, writeOpcode, statistic);
    } else if (name instanceof DynamicAccessExprToken) {
        method.entity.setImmutable(false);
        return writePushDynamicMethod(function, returnValue, writeOpcode, statistic);
    } else {
        if (!writeOpcode)
            return null;
        method.entity.setImmutable(false);
        writeLineNumber(function);
        writePush((ValueExprToken) function.getName(), true, false);
        writePopBoxing();
        writePushParameters(function.getParameters());
        writePushEnv();
        writePushTraceInfo(function);
        writeSysStaticCall(InvokeHelper.class, "callAny", Memory.class, Memory.class, Memory[].class, Environment.class, TraceInfo.class);
        if (!returnValue)
            writePopAll(1);
    }
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) CompileFunction(php.runtime.ext.support.compile.CompileFunction) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ClassExprToken(org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken) OpenEchoTagToken(org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken)

Example 2 with CompileFunction

use of php.runtime.ext.support.compile.CompileFunction in project jphp by jphp-compiler.

the class CompileScope method findCompileFunction.

public CompileFunction findCompileFunction(String name) {
    name = name.toLowerCase();
    CompileFunction function = compileFunctionMap.get(name);
    if (function != null) {
        return function;
    }
    synchronized (this) {
        CompileFunctionSpec functionSpec = compileFunctionSpecMap.get(name);
        if (functionSpec == null) {
            return null;
        }
        compileFunctionMap.put(name, function = functionSpec.toFunction());
    }
    return function;
}
Also used : CompileFunctionSpec(php.runtime.ext.support.compile.CompileFunctionSpec) CompileFunction(php.runtime.ext.support.compile.CompileFunction)

Example 3 with CompileFunction

use of php.runtime.ext.support.compile.CompileFunction in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writePushCompileFunction.

Memory writePushCompileFunction(CallExprToken function, CompileFunction compileFunction, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
    CompileFunction.Method method = compileFunction.find(function.getParameters().size());
    if (method == null) {
        if (!writeOpcode)
            return Memory.NULL;
        writeWarning(function, Messages.ERR_EXPECT_LEAST_PARAMS.fetch(compileFunction.name, compileFunction.getMinArgs(), function.getParameters().size()));
        if (returnValue)
            writePushNull();
        return null;
    } else if (!method.isVarArg() && method.argsCount < function.getParameters().size()) {
        if (!writeOpcode)
            return Memory.NULL;
        writeWarning(function, Messages.ERR_EXPECT_EXACTLY_PARAMS.fetch(compileFunction.name, method.argsCount, function.getParameters().size()));
        if (returnValue)
            writePushNull();
        return null;
    }
    if (statistic != null)
        statistic.returnType = StackItem.Type.valueOf(method.resultType);
    Class[] types = method.parameterTypes;
    ListIterator<ExprStmtToken> iterator = function.getParameters().listIterator();
    Object[] arguments = new Object[types.length];
    int j = 0;
    boolean immutable = method.isImmutable;
    boolean init = false;
    for (int i = 0; i < method.parameterTypes.length; i++) {
        Class<?> argType = method.parameterTypes[i];
        boolean isRef = method.references[i];
        boolean isMutable = method.isPresentAnnotationOfParam(i, Runtime.MutableValue.class);
        if (method.isPresentAnnotationOfParam(i, Runtime.GetLocals.class)) {
            if (!writeOpcode)
                return null;
            immutable = false;
            writePushLocal();
        } else if (argType == Environment.class) {
            if (immutable) {
                arguments[i] = compiler.getEnvironment();
            } else {
                if (!writeOpcode)
                    return null;
                writePushEnv();
            }
        } else if (argType == TraceInfo.class) {
            if (immutable) {
                arguments[i] = function.toTraceInfo(compiler.getContext());
            } else {
                if (!writeOpcode)
                    return null;
                writePushTraceInfo(function);
            }
        } else {
            if (argType == Memory[].class) {
                Memory[] args = new Memory[function.getParameters().size() - j];
                boolean arrCreated = false;
                for (int t = 0; t < function.getParameters().size() - j; t++) {
                    ExprStmtToken next = iterator.next();
                    if (immutable)
                        args[t] = writeExpression(next, true, true, false);
                    if (args[t] == null) {
                        if (!writeOpcode)
                            return null;
                        if (!arrCreated) {
                            if (immutable) {
                                for (int n = 0; n < i; /*j*/
                                n++) {
                                    if (arguments[n] instanceof TraceInfo) {
                                        writePushTraceInfo(function);
                                    } else if (arguments[n] instanceof Environment) {
                                        writePushEnv();
                                    } else {
                                        writePushMemory((Memory) arguments[n]);
                                        writePop(types[n], true, true);
                                        arguments[t] = null;
                                    }
                                }
                            }
                            // create new array
                            writePushSmallInt(args.length);
                            code.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Memory.class)));
                            stackPop();
                            stackPush(Memory.Type.REFERENCE);
                            arrCreated = true;
                        }
                        writePushDup();
                        writePushSmallInt(t);
                        writeExpression(next, true, false, writeOpcode);
                        //if (!isRef)  BUGFIX - array is memory[] and so we need to convert value to memory
                        writePopBoxing(!isRef);
                        code.add(new InsnNode(AASTORE));
                        stackPop();
                        stackPop();
                        stackPop();
                        immutable = false;
                    }
                }
                if (!immutable && !arrCreated) {
                    code.add(new InsnNode(ACONST_NULL));
                    stackPush(Memory.Type.REFERENCE);
                }
                arguments[i] = MemoryUtils.valueOf(args);
            } else {
                ExprStmtToken next = iterator.next();
                if (!immutable && !init) {
                    init = true;
                    for (int k = 0; k < i; /*j*/
                    k++) {
                        if (arguments[k] != null) {
                            if (arguments[k] instanceof TraceInfo) {
                                writePushTraceInfo(function);
                            } else if (arguments[k] instanceof Environment) {
                                writePushEnv();
                            } else {
                                writePushMemory((Memory) arguments[k]);
                                writePop(types[k], true, isRef);
                                arguments[k] = null;
                            }
                        }
                    }
                }
                if (immutable)
                    arguments[i] = writeExpression(next, true, true, false);
                if (arguments[i] == null) {
                    if (!writeOpcode)
                        return null;
                    if (!init) {
                        for (int n = 0; n < i; /*j*/
                        n++) {
                            if (arguments[n] instanceof TraceInfo) {
                                writePushTraceInfo(function);
                            } else if (arguments[n] instanceof Environment) {
                                writePushEnv();
                            } else {
                                writePushMemory((Memory) arguments[n]);
                                writePop(types[n], true, false);
                            }
                            arguments[n] = null;
                        }
                        init = true;
                    }
                    if (isRef)
                        writeExpression(next, true, false, writeOpcode);
                    else {
                        Memory tmp = writeExpression(next, true, true, true);
                        if (tmp != null)
                            writePushMemory(tmp);
                    }
                    writePop(argType, true, isMutable && !isRef);
                    if (!isMutable && !isRef && stackPeek().type.isReference()) {
                        writeSysDynamicCall(Memory.class, "toValue", Memory.class);
                    }
                    immutable = false;
                }
                j++;
            }
        }
    }
    if (immutable) {
        if (!returnValue)
            return null;
        Object[] typedArguments = new Object[arguments.length];
        for (int i = 0; i < arguments.length; i++) {
            if (method.parameterTypes[i] != Memory.class && arguments[i] instanceof Memory)
                typedArguments[i] = method.converters[i].run((Memory) arguments[i]);
            else
                //MemoryUtils.toValue((Memory)arguments[i], types[i]);
                typedArguments[i] = arguments[i];
        }
        try {
            Object value = method.method.invoke(null, typedArguments);
            return MemoryUtils.valueOf(value);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e.getCause());
        }
    }
    if (!writeOpcode)
        return null;
    this.method.entity.setImmutable(false);
    writeLineNumber(function);
    writePushStaticCall(method.method);
    if (returnValue) {
        if (method.resultType == void.class)
            writePushNull();
        setStackPeekAsImmutable();
    }
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) CompileFunction(php.runtime.ext.support.compile.CompileFunction) TraceInfo(php.runtime.env.TraceInfo) InvocationTargetException(java.lang.reflect.InvocationTargetException) Runtime(php.runtime.annotation.Runtime) Environment(php.runtime.env.Environment) CompileClass(php.runtime.ext.support.compile.CompileClass) IObject(php.runtime.lang.IObject)

Aggregations

CompileFunction (php.runtime.ext.support.compile.CompileFunction)3 Memory (php.runtime.Memory)2 UndefinedMemory (php.runtime.memory.helper.UndefinedMemory)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 OpenEchoTagToken (org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken)1 Token (org.develnext.jphp.core.tokenizer.token.Token)1 ClassExprToken (org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken)1 OperatorExprToken (org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken)1 ValueExprToken (org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)1 Runtime (php.runtime.annotation.Runtime)1 Environment (php.runtime.env.Environment)1 TraceInfo (php.runtime.env.TraceInfo)1 CompileClass (php.runtime.ext.support.compile.CompileClass)1 CompileFunctionSpec (php.runtime.ext.support.compile.CompileFunctionSpec)1 IObject (php.runtime.lang.IObject)1