Search in sources :

Example 6 with ValueExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeExpression.

@SuppressWarnings("unchecked")
public Memory writeExpression(ExprStmtToken expression, boolean returnValue, boolean returnMemory, boolean writeOpcode) {
    int initStackSize = method.getStackCount();
    exprStackInit.push(initStackSize);
    if (!expression.isStmtList()) {
        if (expression.getAsmExpr() == null) {
            throw new CriticalException("Invalid expression token without asm expr, on line " + expression.getMeta().getStartLine() + ", expr = " + expression.getWord());
        }
        // new ASMExpression(compiler.getEnvironment(), compiler.getContext(), expression).getResult();
        expression = expression.getAsmExpr();
    }
    List<Token> tokens = expression.getTokens();
    int operatorCount = 0;
    for (Token token : tokens) {
        if (token instanceof OperatorExprToken)
            operatorCount++;
    }
    boolean invalid = false;
    for (Token token : tokens) {
        if (token == null)
            continue;
        writeTickTrigger(token);
        if (writeOpcode) {
            if (token instanceof StmtToken) {
                if (!(token instanceof ReturnStmtToken))
                    method.entity.setImmutable(false);
            }
            BaseStatementCompiler cmp = getCompiler(token.getClass());
            if (cmp != null && !(cmp instanceof BaseExprCompiler)) {
                cmp.write(token);
                continue;
            }
        }
        if (token instanceof ValueExprToken) {
            // mixed, calls, numbers, strings, vars, etc.
            if (token instanceof CallExprToken && ((CallExprToken) token).getName() instanceof OperatorExprToken) {
                if (writeOpcode) {
                    writePush((ValueExprToken) token, true, true);
                    method.entity.setImmutable(false);
                } else
                    break;
            } else
                stackPush((ValueExprToken) token);
        } else if (token instanceof OperatorExprToken) {
            // + - * / % && || or ! and == > < etc.
            operatorCount--;
            if (operatorCount >= 0) {
                Memory result;
                if (operatorCount == 0) {
                    result = writeOperator((OperatorExprToken) token, returnValue, writeOpcode);
                } else
                    result = writeOperator((OperatorExprToken) token, true, writeOpcode);
                if (!writeOpcode && result == null) {
                    invalid = true;
                    break;
                }
                if (result == null)
                    method.entity.setImmutable(false);
            }
        } else
            break;
    }
    Memory result = null;
    if (!invalid && returnMemory && returnValue && !stackEmpty(false) && stackPeek().isConstant()) {
        result = stackPop().memory;
        invalid = true;
    }
    if (!invalid) {
        if (returnValue && !stackEmpty(false) && stackPeek().isKnown()) {
            if (returnMemory)
                result = tryWritePush(stackPop(), writeOpcode, returnValue, true);
            else
                writePush(stackPop());
        } else if (method.getStackCount() > 0) {
            if (stackPeekToken() instanceof CallableExprToken) {
                if (returnMemory)
                    result = tryWritePush(stackPopToken(), returnValue, writeOpcode, true);
                else
                    writePush(stackPopToken(), returnValue, true);
            } else if (stackPeek().isConstant()) {
                stackPop();
            }
        }
    }
    if (!returnValue && writeOpcode) {
        writePopAll(method.getStackCount() - initStackSize);
    } else if (!writeOpcode) {
        int count = method.getStackCount() - initStackSize;
        for (int i = 0; i < count; i++) {
            stackPop();
        }
    }
    exprStackInit.pop();
    return result;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) 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) CriticalException(php.runtime.exceptions.CriticalException) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 7 with ValueExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken 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 8 with ValueExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writePushStaticMethod.

Memory writePushStaticMethod(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
    StaticAccessExprToken access = (StaticAccessExprToken) function.getName();
    if (!writeOpcode)
        return null;
    writeLineNumber(function);
    if (writePushFastStaticMethod(function, returnValue))
        return null;
    writePushEnv();
    writePushTraceInfo(function.getName());
    String methodName = null;
    ValueExprToken clazz = access.getClazz();
    if ((clazz instanceof NameToken || (clazz instanceof SelfExprToken && !method.clazz.entity.isTrait())) && access.getField() instanceof NameToken) {
        String className;
        if (clazz instanceof SelfExprToken)
            className = getMacros(clazz).toString();
        else
            className = ((NameToken) clazz).getName();
        writePushString(className.toLowerCase());
        methodName = ((NameToken) access.getField()).getName();
        writePushString(methodName.toLowerCase());
        writePushString(className);
        writePushString(methodName);
        writePushParameters(function.getParameters());
        if (method.clazz.statement.isTrait()) {
            writePushConstNull();
            writePushConstInt(0);
        } else {
            int cacheIndex = method.clazz.getAndIncCallMethCount();
            writeGetStatic("$CALL_METH_CACHE", MethodCallCache.class);
            writePushConstInt(cacheIndex);
        }
        writeSysStaticCall(InvokeHelper.class, "callStatic", Memory.class, Environment.class, TraceInfo.class, // lower sign name
        String.class, // lower sign name
        String.class, // origin names
        String.class, // origin names
        String.class, Memory[].class, MethodCallCache.class, Integer.TYPE);
    } else {
        if (clazz instanceof NameToken) {
            writePushString(((NameToken) clazz).getName());
            writePushDupLowerCase();
        } else if (clazz instanceof SelfExprToken) {
            writePushSelf(true);
        } else if (clazz instanceof StaticExprToken) {
            writePushStatic();
            writePushDupLowerCase();
        } else {
            writePush(clazz, true, false);
            writePopString();
            writePushDupLowerCase();
        }
        if (access.getField() != null) {
            ValueExprToken field = access.getField();
            if (field instanceof NameToken) {
                writePushString(((NameToken) field).getName());
                writePushString(((NameToken) field).getName().toLowerCase());
            } else if (field instanceof ClassExprToken) {
                unexpectedToken(field);
            } else {
                writePush(access.getField(), true, false);
                writePopString();
                writePushDupLowerCase();
            }
        } else {
            writeExpression(access.getFieldExpr(), true, false);
            writePopString();
            writePushDupLowerCase();
        }
        writePushParameters(function.getParameters());
        if (clazz instanceof StaticExprToken || method.clazz.statement.isTrait() || clazz instanceof VariableExprToken) {
            writePushConstNull();
            writePushConstInt(0);
        } else {
            int cacheIndex = method.clazz.getAndIncCallMethCount();
            writeGetStatic("$CALL_METH_CACHE", MethodCallCache.class);
            writePushConstInt(cacheIndex);
        }
        writeSysStaticCall(InvokeHelper.class, "callStaticDynamic", Memory.class, Environment.class, TraceInfo.class, String.class, String.class, String.class, String.class, Memory[].class, MethodCallCache.class, Integer.TYPE);
    }
    if (statistic != null)
        statistic.returnType = StackItem.Type.REFERENCE;
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) ClassExprToken(org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 9 with ValueExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.

the class ASMExpression method processToken.

protected void processToken(Token token, Stack<Token> stack, List<Token> result) {
    if (token instanceof CallExprToken) {
        CallExprToken call = (CallExprToken) token;
        if (call.getName() instanceof OperatorExprToken) {
            processOperator(stack, result, (OperatorExprToken) call.getName());
        }
        result.add(token);
    } else if (token instanceof ValueExprToken) {
        result.add(token);
    } else if (token instanceof BraceExprToken) {
        BraceExprToken brace = (BraceExprToken) token;
        if (brace.isSimpleOpened()) {
            stack.push(brace);
        } else if (brace.isSimpleClosed()) {
            if (stack.empty())
                unexpectedToken(brace);
            boolean done = false;
            do {
                Token el = stack.pop();
                if (el instanceof BraceExprToken && ((BraceExprToken) el).isSimpleOpened()) {
                    done = true;
                    break;
                }
                result.add(el);
            } while (!stack.isEmpty());
            if (!done)
                unexpectedToken(brace);
        } else
            unexpectedToken(brace);
    } else if (token instanceof OperatorExprToken) {
        OperatorExprToken operator = (OperatorExprToken) token;
        /*boolean done = !stack.empty();
            if (done){
                if (operator.isRightSide())
                    done = getPriority(stack.peek()) > prior;
                else
                    done = getPriority(stack.peek()) > prior;
            }

            if (done){
                if (prior == 1){
                    processOperator(stack, result, prior);
                    result.add(token);
                    return;
                }

                stack.push(token);
                return;
            }*/
        processOperator(stack, result, operator);
        stack.push(token);
    }
}
Also used : CallExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) ExprToken(org.develnext.jphp.core.tokenizer.token.expr.ExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) OperatorExprToken(org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken) CallExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 10 with ValueExprToken

use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.

the class StaticAccessValueCompiler method write.

@Override
public void write(StaticAccessExprToken token, boolean returnValue) {
    boolean isConstant = token.getField() instanceof NameToken;
    if (token.getField() instanceof ClassExprToken) {
        if (token.getClazz() instanceof ParentExprToken) {
            expr.writePushParent(token.getClazz());
        } else if (token.getClazz() instanceof StaticExprToken) {
            expr.writePushStatic();
        } else if (token.getClazz() instanceof SelfExprToken) {
            expr.writePushSelf(false);
        } else
            expr.unexpectedToken(token);
    } else {
        ValueExprToken clazz = token.getClazz();
        if (clazz instanceof ParentExprToken) {
            expr.writePushParent(clazz);
        } else if (clazz instanceof NameToken) {
            expr.writePushConstString(((NameToken) clazz).getName());
            expr.writePushConstString(((NameToken) clazz).getName().toLowerCase());
        } else {
            if (clazz instanceof StaticExprToken) {
                expr.writePushStatic();
            } else {
                if (clazz != null) {
                    expr.writePush(clazz, true, false);
                } else {
                // it static access operator. skip.
                }
            }
            expr.writePopString();
            expr.writePushDupLowerCase();
        }
        if (isConstant) {
            expr.writePushConstString(((NameToken) token.getField()).getName());
            expr.writePushEnv();
            expr.writePushTraceInfo(token);
            int cacheIndex = method.clazz.getAndIncCallConstCount();
            expr.writeGetStatic("$CALL_CONST_CACHE", ConstantCallCache.class);
            expr.writePushConstInt(cacheIndex);
            expr.writeSysStaticCall(ObjectInvokeHelper.class, "getConstant", Memory.class, String.class, String.class, String.class, Environment.class, TraceInfo.class, ConstantCallCache.class, Integer.TYPE);
            expr.setStackPeekAsImmutable();
        } else {
            if (token.getFieldExpr() != null) {
                expr.writeExpression(token.getFieldExpr(), true, false);
                expr.writePopString();
            } else {
                if (!(token.getField() instanceof VariableExprToken))
                    expr.unexpectedToken(token.getField());
                expr.writePushConstString(((VariableExprToken) token.getField()).getName());
            }
            expr.writePushEnv();
            expr.writePushTraceInfo(token);
            String name = "get";
            if (token instanceof StaticAccessUnsetExprToken)
                name = "unset";
            else if (token instanceof StaticAccessIssetExprToken)
                name = "isset";
            if (token.getFieldExpr() == null && token.getField() instanceof NameToken) {
                expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
                expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
            } else {
                expr.writePushConstNull();
                expr.writePushConstInt(0);
            }
            expr.writeSysStaticCall(ObjectInvokeHelper.class, name + "StaticProperty", Memory.class, String.class, String.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
        }
    }
    if (!returnValue)
        expr.writePopAll(1);
}
Also used : ClassExprToken(org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Aggregations

ValueExprToken (org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)12 Memory (php.runtime.Memory)8 UndefinedMemory (php.runtime.memory.helper.UndefinedMemory)6 StackItem (org.develnext.jphp.core.compiler.common.misc.StackItem)5 Token (org.develnext.jphp.core.tokenizer.token.Token)5 ClassExprToken (org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken)5 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)4 OperatorExprToken (org.develnext.jphp.core.tokenizer.token.expr.OperatorExprToken)4 OpenEchoTagToken (org.develnext.jphp.core.tokenizer.token.OpenEchoTagToken)3 ExprStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken)3 Environment (php.runtime.env.Environment)3 GetVarExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.GetVarExprToken)2 VariableExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken)2 TraceInfo (php.runtime.env.TraceInfo)2 CriticalException (php.runtime.exceptions.CriticalException)2 CompileClass (php.runtime.ext.support.compile.CompileClass)2 BraceExprToken (org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken)1 ExprToken (org.develnext.jphp.core.tokenizer.token.expr.ExprToken)1 CallExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.CallExprToken)1 StringBuilderExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.StringBuilderExprToken)1