Search in sources :

Example 81 with Memory

use of php.runtime.Memory in project jphp by jphp-compiler.

the class ClassStmtCompiler method writeConstant.

protected void writeConstant(ConstStmtToken constant) {
    MethodStmtCompiler methodStmtCompiler = new MethodStmtCompiler(this, (MethodStmtToken) null);
    ExpressionStmtCompiler expressionStmtCompiler = new ExpressionStmtCompiler(methodStmtCompiler, null);
    DocumentComment documentComment = null;
    if (constant.getDocComment() != null)
        documentComment = new DocumentComment(constant.getDocComment().getComment());
    for (ConstStmtToken.Item el : constant.items) {
        Memory value = expressionStmtCompiler.writeExpression(el.value, true, true, false);
        ConstantEntity constantEntity = new ConstantEntity(el.getFulledName(), value, true);
        constantEntity.setTrace(el.name.toTraceInfo(compiler.getContext()));
        constantEntity.setDocComment(documentComment);
        if (value != null && !value.isArray()) {
            ConstantEntity c = entity.findConstant(el.getFulledName());
            if (c != null && c.getClazz().getId() == entity.getId()) {
                compiler.getEnvironment().error(constant.toTraceInfo(compiler.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_REDEFINE_CLASS_CONSTANT, entity.getName() + "::" + el.getFulledName());
                return;
            }
            entity.addConstant(constantEntity);
        } else {
            if (ValueExprToken.isConstable(el.value.getSingle(), false)) {
                dynamicConstants.add(el);
                entity.addConstant(constantEntity);
            } else
                compiler.getEnvironment().error(constant.toTraceInfo(compiler.getContext()), Messages.ERR_EXPECTED_CONST_VALUE.fetch(entity.getName() + "::" + el.getFulledName()));
        }
    }
}
Also used : Memory(php.runtime.Memory) ConstStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ConstStmtToken)

Example 82 with Memory

use of php.runtime.Memory in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeOperator.

Memory writeOperator(OperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
    if (writeOpcode) {
        BaseExprCompiler compiler = (BaseExprCompiler) getCompiler(operator.getClass());
        if (compiler != null) {
            if (writeOpcode) {
                writeLineNumber(operator);
            }
            compiler.write(operator, returnValue);
            return null;
        }
    }
    if (operator instanceof LogicOperatorExprToken) {
        return writeLogicOperator((LogicOperatorExprToken) operator, returnValue, writeOpcode);
    }
    if (!operator.isBinary()) {
        return writeUnaryOperator(operator, returnValue, writeOpcode);
    }
    if (stackEmpty(true))
        unexpectedToken(operator);
    StackItem o1 = stackPop();
    if (o1.isInvalidForOperations())
        unexpectedToken(operator);
    if (stackEmpty(true))
        unexpectedToken(operator);
    StackItem o2 = stackPeek();
    ValueExprToken L = stackPopToken();
    if (o2.isInvalidForOperations())
        unexpectedToken(operator);
    if (!(operator instanceof AssignExprToken || operator instanceof AssignOperatorExprToken))
        if (o1.getMemory() != null && o2.getMemory() != null) {
            Memory result;
            stackPush(result = CompilerUtils.calcBinary(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), o2.getMemory(), o1.getMemory(), operator, false));
            return result;
        }
    LocalVariable variable = null;
    if (L instanceof VariableExprToken) {
        variable = method.getLocalVariable(((VariableExprToken) L).getName());
    }
    if (operator instanceof AssignExprToken) {
        if (L instanceof VariableExprToken) {
            if (!writeOpcode)
                return null;
            writeVariableAssign((VariableExprToken) L, o1, (AssignExprToken) operator, returnValue);
            return null;
        }
    }
    Memory value1 = operator instanceof AssignableOperatorToken ? null : // LEFT
    tryWritePush(o2, false, false, true);
    // RIGHT
    Memory value2 = tryWritePush(o1, false, false, true);
    if (value1 != null && value2 != null) {
        stackPush(value1);
        stackPush(value2);
        return writeOperator(operator, returnValue, writeOpcode);
    }
    if (!returnValue && CompilerUtils.isOperatorAlwaysReturn(operator)) {
        unexpectedToken(operator);
    }
    if (!writeOpcode) {
        stackPush(o2);
        stackPush(o1);
        return null;
    }
    if (writeOpcode) {
        writeLineNumber(operator);
    }
    StackItem.Type Lt = tryGetType(o2);
    StackItem.Type Rt = tryGetType(o1);
    String name = operator.getCode();
    Class operatorResult = operator.getResultClass();
    boolean isInvert = false;
    boolean sideOperator = operator.isSide();
    if (variable != null && !variable.isReference()) {
        if (operator instanceof AssignOperatorExprToken) {
            name = ((AssignOperatorExprToken) operator).getOperatorCode();
            if (operator instanceof AssignConcatExprToken)
                operatorResult = String.class;
            if (operator instanceof AssignPlusExprToken || operator instanceof AssignMulExprToken)
                sideOperator = false;
        }
    }
    if (operator instanceof AssignableOperatorToken && tryIsImmutable(o2))
        unexpectedToken(operator);
    if (Lt.isConstant() && Rt.isConstant()) {
        if (operator instanceof AssignableOperatorToken)
            unexpectedToken(operator);
        writeScalarOperator(o2, Lt, o1, Rt, operator, operatorResult, name);
    } else {
        isInvert = !o1.isKnown();
        if (!o1.isKnown() && !o2.isKnown() && o1.getLevel() > o2.getLevel())
            isInvert = false;
        if (Lt.isConstant() && !isInvert) {
            writePush(o2);
            if (methodExists(OperatorUtils.class, name, Lt.toClass(), Rt.toClass())) {
                writePush(o1);
                writeSysStaticCall(OperatorUtils.class, name, operatorResult, Lt.toClass(), Rt.toClass());
            } else {
                writePopBoxing();
                writePush(o1);
                writeSysDynamicCall(Memory.class, name, operatorResult, Rt.toClass());
            }
        } else {
            if (isInvert) {
                stackPush(o1);
                if (o2.isKnown())
                    writePopBoxing(false);
                writePush(o2);
                if (!o2.isKnown() && !o2.type.isReference()) {
                    writeSysStaticCall(OperatorUtils.class, name, operatorResult, Lt.toClass(), Rt.toClass());
                    name = null;
                } else if (sideOperator) {
                    name += "Right";
                }
            /*if (cloneValue){
                        writeSysDynamicCall(Memory.class, name, operatorResult, isInvert ? Lt.toClass() : Rt.toClass());
                        writePush(o2);
                        name = null;
                    }*/
            } else {
                writePush(o2);
                writePopBoxing(false);
                /*if (cloneValue)
                        writePushDup();*/
                writePush(o1);
                if (Rt.isReference()) {
                    writePopBoxing(false);
                }
                if (!o1.immutable && !operator.isMutableArguments())
                    writePopImmutable();
            }
            if (name != null) {
                writeSysDynamicCall(Memory.class, name, operatorResult, isInvert ? Lt.toClass() : Rt.toClass());
            }
            if (operator.getCheckerCode() != null) {
                writePopBoxing();
                writePushEnv();
                writePushTraceInfo(operator);
                writeSysDynamicCall(Memory.class, operator.getCheckerCode(), Memory.class, Environment.class, TraceInfo.class);
            }
        }
        setStackPeekAsImmutable();
        if (operator instanceof AssignOperatorExprToken) {
            if (variable == null || variable.isReference()) {
                /*if (isInvert)
                        writeSysStaticCall(Memory.class, "assignRight", Memory.class, Rt.toClass(), Memory.class);
                    else
                        writeSysDynamicCall(Memory.class, "assign", Memory.class, stackPeek().type.toClass());
                    */
                if (!returnValue)
                    writePopAll(1);
            } else {
                if (returnValue)
                    writePushDup(StackItem.Type.valueOf(operatorResult));
                writePopBoxing(operatorResult);
                makeVarStore(variable);
                variable.setValue(!stackPeek().isConstant() ? null : stackPeek().getMemory());
                stackPop();
            }
        }
    }
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) StackItem(org.develnext.jphp.core.compiler.common.misc.StackItem) CompileClass(php.runtime.ext.support.compile.CompileClass) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)

Example 83 with Memory

use of php.runtime.Memory in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeUnaryOperator.

Memory writeUnaryOperator(OperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
    if (stackEmpty(true))
        unexpectedToken(operator);
    StackItem o = stackPop();
    ValueExprToken L = o.getToken();
    Memory mem = tryWritePush(o, false, false, true);
    StackItem.Type type = tryGetType(o);
    if (mem != null) {
        Memory result = CompilerUtils.calcUnary(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), mem, operator);
        if (operator instanceof ValueIfElseToken) {
            ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
            ExprStmtToken ret = valueIfElseToken.getValue();
            if (mem.toBoolean()) {
                if (ret == null)
                    result = mem;
                else
                    result = writeExpression(ret, true, true, false);
            } else {
                result = writeExpression(valueIfElseToken.getAlternative(), true, true, false);
            }
        } else if (operator instanceof ArrayGetExprToken && !(operator instanceof ArrayGetRefExprToken)) {
        // TODO: check!!!
        /*Memory array = mem;
                ArrayGetExprToken arrayGet = (ArrayGetExprToken)operator;
                for(ExprStmtToken expr : arrayGet.getParameters()){
                    Memory key = writeExpression(expr, true, true, false);
                    if (key == null)
                        break;
                    result = array = array.valueOfIndex(key).toImmutable();
                }*/
        }
        if (result != null) {
            stackPush(result);
            setStackPeekAsImmutable();
            return result;
        }
    }
    if (!writeOpcode)
        return null;
    writeLineNumber(operator);
    String name = operator.getCode();
    Class operatorResult = operator.getResultClass();
    LocalVariable variable = null;
    if (L instanceof VariableExprToken) {
        variable = method.getLocalVariable(((VariableExprToken) L).getName());
        if (operator instanceof ArrayPushExprToken || operator instanceof ArrayGetRefExprToken)
            variable.setValue(null);
    }
    if (operator instanceof IncExprToken || operator instanceof DecExprToken) {
        if (variable == null || variable.isReference()) {
            if (operator.getAssociation() == Association.LEFT && returnValue) {
                writePush(o);
                if (stackPeek().type.isConstant())
                    unexpectedToken(operator);
                writePushDup();
                writePopImmutable();
                code.add(new InsnNode(SWAP));
                writePushDup();
            } else {
                writePush(o);
                if (stackPeek().type.isConstant())
                    unexpectedToken(operator);
                writePushDup();
            }
            writeSysDynamicCall(Memory.class, name, operatorResult);
            writeSysDynamicCall(Memory.class, "assign", Memory.class, operatorResult);
            if (!returnValue || operator.getAssociation() == Association.LEFT) {
                writePopAll(1);
            }
        } else {
            writePush(o);
            if (stackPeek().type.isConstant())
                unexpectedToken(operator);
            if (operator.getAssociation() == Association.LEFT && returnValue) {
                writeVarLoad(variable);
            }
            writeSysDynamicCall(Memory.class, name, operatorResult);
            // TODO for constant values
            variable.setValue(null);
            if (operator.getAssociation() == Association.RIGHT)
                writeVarStore(variable, returnValue);
            else {
                writeVarStore(variable, false);
            }
        }
    } else if (operator instanceof AmpersandRefToken) {
        writePush(o, false, false);
        setStackPeekAsImmutable();
        Token token = o.getToken();
        if (token instanceof VariableExprToken) {
            LocalVariable local = method.getLocalVariable(((VariableExprToken) token).getName());
            local.setValue(null);
        }
    } else if (operator instanceof SilentToken) {
        writePushEnv();
        writeSysDynamicCall(Environment.class, "__pushSilent", void.class);
        writePush(o);
        writePushEnv();
        writeSysDynamicCall(Environment.class, "__popSilent", void.class);
    } else if (operator instanceof ValueIfElseToken) {
        writePush(o);
        ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
        LabelNode end = new LabelNode();
        LabelNode elseL = new LabelNode();
        if (valueIfElseToken.getValue() == null) {
            StackItem.Type dup = stackPeek().type;
            writePushDup();
            writePopBoolean();
            code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
            stackPop();
            writePopBoxing();
            stackPop();
            code.add(new JumpInsnNode(Opcodes.GOTO, end));
            code.add(elseL);
            // remove duplicate of condition value , IMPORTANT!!!
            makePop(dup);
            writeExpression(valueIfElseToken.getAlternative(), true, false);
            writePopBoxing();
            code.add(end);
        } else {
            writePopBoolean();
            code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
            stackPop();
            writeExpression(valueIfElseToken.getValue(), true, false);
            writePopBoxing();
            stackPop();
            // goto end
            code.add(new JumpInsnNode(Opcodes.GOTO, end));
            // else
            code.add(elseL);
            writeExpression(valueIfElseToken.getAlternative(), true, false);
            writePopBoxing();
            code.add(end);
        }
        setStackPeekAsImmutable(false);
    } else if (operator instanceof ArrayGetExprToken) {
        stackPush(o);
        writeArrayGet((ArrayGetExprToken) operator, returnValue);
    } else if (operator instanceof CallOperatorToken) {
        stackPush(o);
        CallOperatorToken call = (CallOperatorToken) operator;
        writePushParameters(call.getParameters());
        writePushEnv();
        writePushTraceInfo(operator);
        writeSysStaticCall(InvokeHelper.class, "callAny", Memory.class, Memory.class, Memory[].class, Environment.class, TraceInfo.class);
        if (!returnValue)
            writePopAll(1);
    } else {
        writePush(o);
        writePopBoxing();
        if (operator.isEnvironmentNeeded() && operator.isTraceNeeded()) {
            writePushEnv();
            writePushTraceInfo(operator);
            writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class, TraceInfo.class);
        } else if (operator.isEnvironmentNeeded()) {
            writePushEnv();
            writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class);
        } else if (operator.isTraceNeeded()) {
            writePushTraceInfo(operator);
            writeSysDynamicCall(Memory.class, name, operatorResult, TraceInfo.class);
        } else
            writeSysDynamicCall(Memory.class, name, operatorResult);
        if (!returnValue) {
            writePopAll(1);
        }
    }
    return null;
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) 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) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) ObjectInvokeHelper(php.runtime.invoke.ObjectInvokeHelper) InvokeHelper(php.runtime.invoke.InvokeHelper) TraceInfo(php.runtime.env.TraceInfo) StackItem(org.develnext.jphp.core.compiler.common.misc.StackItem) Type(org.objectweb.asm.Type) Environment(php.runtime.env.Environment) CompileClass(php.runtime.ext.support.compile.CompileClass)

Example 84 with Memory

use of php.runtime.Memory in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writePushFastStaticMethod.

boolean writePushFastStaticMethod(CallExprToken function, boolean returnValue) {
    StaticAccessExprToken access = (StaticAccessExprToken) function.getName();
    CompileClass compileClass = compiler.getEnvironment().scope.findCompileClass(access.getClazz().getWord());
    if (compileClass == null)
        return false;
    ClassEntity classEntity = compiler.getEnvironment().fetchClass(compileClass.getNativeClass());
    MethodEntity methodEntity = classEntity.findMethod(access.getField().getWord().toLowerCase());
    if (methodEntity != null && methodEntity.getNativeMethod() != null && methodEntity.getNativeMethod().isAnnotationPresent(Runtime.FastMethod.class)) {
        int cnt = methodEntity.getRequiredParamCount();
        if (cnt > function.getParameters().size()) {
            writeWarning(function, Messages.ERR_EXPECT_EXACTLY_PARAMS.fetch(methodEntity.getClazzName() + "::" + methodEntity.getName(), cnt, function.getParameters().size()));
            if (returnValue)
                writePushNull();
            return true;
        }
        List<Memory> additional = new ArrayList<Memory>();
        for (ParameterEntity param : methodEntity.getParameters()) {
            if (param.getDefaultValue() != null)
                additional.add(param.getDefaultValue());
            else if (!additional.isEmpty())
                throw new IllegalStateException("Arguments with default values must be located at the end");
        }
        writePushEnv();
        writePushParameters(function.getParameters(), additional.toArray(new Memory[0]));
        writeSysStaticCall(compileClass.getNativeClass(), methodEntity.getName(), Memory.class, Environment.class, Memory[].class);
        if (!returnValue)
            writePopAll(1);
        return true;
    }
    return false;
}
Also used : CompileClass(php.runtime.ext.support.compile.CompileClass) UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory)

Example 85 with Memory

use of php.runtime.Memory in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method stackPush.

public void stackPush(ValueExprToken token) {
    Memory o = CompilerUtils.toMemory(token);
    if (o != null) {
        stackPush(o);
    } else if (token instanceof StaticAccessExprToken) {
        StaticAccessExprToken access = (StaticAccessExprToken) token;
        if (access.getField() instanceof NameToken) {
            String constant = ((NameToken) access.getField()).getName();
            String clazz = null;
            ClassEntity entity = null;
            if (access.getClazz() instanceof ParentExprToken) {
                entity = method.clazz.entity.getParent();
                if (entity != null)
                    clazz = entity.getName();
            } else if (access.getClazz() instanceof FulledNameToken) {
                clazz = ((FulledNameToken) access.getClazz()).getName();
                entity = compiler.getModule().findClass(clazz);
            }
            if (entity == null && method.clazz.entity != null && method.clazz.entity.getName().equalsIgnoreCase(clazz))
                entity = method.clazz.entity;
            if (entity != null) {
                ConstantEntity c = entity.findConstant(constant);
                if (c != null && c.getValue() != null) {
                    stackPush(c.getValue());
                    stackPeek().setLevel(-1);
                    return;
                }
            }
        }
        stackPush(token, StackItem.Type.REFERENCE);
    } else {
        if (token instanceof VariableExprToken && !methodStatement.isUnstableVariable((VariableExprToken) token)) {
            LocalVariable local = method.getLocalVariable(((VariableExprToken) token).getName());
            if (local != null && local.getValue() != null) {
                stackPush(token, local.getValue());
                stackPeek().setLevel(-1);
                return;
            }
        }
        stackPush(token, StackItem.Type.REFERENCE);
    }
    stackPeek().setLevel(-1);
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)

Aggregations

Memory (php.runtime.Memory)346 Test (org.junit.Test)124 ArrayMemory (php.runtime.memory.ArrayMemory)122 ObjectMemory (php.runtime.memory.ObjectMemory)75 LongMemory (php.runtime.memory.LongMemory)58 StringMemory (php.runtime.memory.StringMemory)58 ForeachIterator (php.runtime.lang.ForeachIterator)47 ReferenceMemory (php.runtime.memory.ReferenceMemory)40 KeyValueMemory (php.runtime.memory.KeyValueMemory)25 Invoker (php.runtime.invoke.Invoker)21 ArrayKeyMemory (php.runtime.memory.helper.ArrayKeyMemory)21 ArrayValueMemory (php.runtime.memory.helper.ArrayValueMemory)21 ShortcutMemory (php.runtime.memory.helper.ShortcutMemory)21 Environment (php.runtime.env.Environment)20 IObject (php.runtime.lang.IObject)19 UndefinedMemory (php.runtime.memory.helper.UndefinedMemory)16 ClassEntity (php.runtime.reflection.ClassEntity)16 TraceInfo (php.runtime.env.TraceInfo)12 File (java.io.File)7 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)7