Search in sources :

Example 86 with Memory

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

the class ExpressionStmtCompiler method writePushParameters.

public void writePushParameters(Collection<ExprStmtToken> parameters, boolean useConstants, Memory... additional) {
    if (parameters.isEmpty()) {
        code.add(new InsnNode(ACONST_NULL));
        stackPush(Memory.Type.REFERENCE);
        return;
    }
    if (useConstants && additional == null || additional.length == 0) {
        List<Memory> constantParameters = new ArrayList<Memory>();
        for (ExprStmtToken param : parameters) {
            Memory paramMemory = writeExpression(param, true, true, false);
            if (paramMemory == null || paramMemory.isArray()) {
                // skip arrays.
                break;
            }
            constantParameters.add(paramMemory);
        }
        if (constantParameters.size() == parameters.size()) {
            writePushConstantMemoryArray(constantParameters);
            return;
        }
    }
    writePushSmallInt(parameters.size() + (additional == null ? 0 : additional.length));
    code.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Memory.class)));
    stackPop();
    stackPush(Memory.Type.REFERENCE);
    int i = 0;
    for (ExprStmtToken param : parameters) {
        writePushDup();
        writePushSmallInt(i);
        writeExpression(param, true, false);
        writePopBoxing();
        code.add(new InsnNode(AASTORE));
        stackPop();
        stackPop();
        stackPop();
        i++;
    }
    if (additional != null) {
        for (Memory m : additional) {
            writePushDup();
            writePushSmallInt(i);
            writePushMemory(m);
            writePopBoxing();
            code.add(new InsnNode(AASTORE));
            stackPop();
            stackPop();
            stackPop();
            i++;
        }
    }
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory)

Example 87 with Memory

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

the class ExpressionStmtCompiler method tryWritePushMacro.

Memory tryWritePushMacro(MacroToken macro, boolean writeOpcode) {
    if (macro instanceof LineMacroToken) {
        return LongMemory.valueOf(macro.getMeta().getStartLine() + 1);
    } else if (macro instanceof FileMacroToken) {
        return new StringMemory(compiler.getSourceFile());
    } else if (macro instanceof DirMacroToken) {
        String sourceFile = compiler.getSourceFile();
        String parent = new File(sourceFile).getParent();
        // Fix issue #198.
        if (sourceFile.startsWith(parent + "//") && parent.endsWith(":")) {
            parent += "//";
        }
        return new StringMemory(parent);
    } else if (macro instanceof FunctionMacroToken) {
        if (method.clazz.getFunctionName().isEmpty())
            return method.clazz.isSystem() ? Memory.CONST_EMPTY_STRING : method.getRealName() == null ? Memory.CONST_EMPTY_STRING : new StringMemory(method.getRealName());
        else {
            return method.clazz.getFunctionName() == null ? Memory.CONST_EMPTY_STRING : new StringMemory(method.clazz.getFunctionName());
        }
    } else if (macro instanceof MethodMacroToken) {
        if (method.clazz.isSystem())
            return method.clazz.getFunctionName() != null ? new StringMemory(method.clazz.getFunctionName()) : Memory.NULL;
        else
            return new StringMemory(method.clazz.entity.getName() + (method.getRealName() == null ? "" : "::" + method.getRealName()));
    } else if (macro instanceof ClassMacroToken) {
        if (method.clazz.entity.isTrait()) {
            if (writeOpcode) {
                writePushEnv();
                writeSysDynamicCall(Environment.class, "__getMacroClass", Memory.class);
            }
            return null;
        } else {
            if (method.clazz.getClassContext() != null) {
                return new StringMemory(method.clazz.getClassContext().getFulledName());
            } else {
                return new StringMemory(method.clazz.isSystem() ? "" : method.clazz.entity.getName());
            }
        }
    } else if (macro instanceof NamespaceMacroToken) {
        return new StringMemory(compiler.getNamespace() == null || compiler.getNamespace().getName() == null ? "" : compiler.getNamespace().getName().getName());
    } else if (macro instanceof TraitMacroToken) {
        if (method.clazz.entity.isTrait())
            return new StringMemory(method.clazz.entity.getName());
        else
            return Memory.CONST_EMPTY_STRING;
    } else
        throw new IllegalArgumentException("Unsupported macro value: " + macro.getWord());
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) Environment(php.runtime.env.Environment) File(java.io.File)

Example 88 with Memory

use of php.runtime.Memory 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 89 with Memory

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

the class ExpressionStmtCompiler method writeLogicOperator.

Memory writeLogicOperator(LogicOperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
    if (stackEmpty(true))
        unexpectedToken(operator);
    if (!writeOpcode) {
        StackItem top = stackPeek();
        Memory one = tryWritePush(top, false, false, true);
        if (one == null)
            return null;
        Memory two = writeExpression(operator.getRightValue(), true, true, false);
        if (two == null)
            return null;
        stackPop();
        Memory r = operator.calc(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), one, two);
        stackPush(r);
        return r;
    }
    writeLineNumber(operator);
    StackItem o = stackPop();
    writePush(o);
    writePopBoolean();
    LabelNode end = new LabelNode();
    LabelNode next = new LabelNode();
    if (operator instanceof BooleanOrExprToken || operator instanceof BooleanOr2ExprToken) {
        code.add(new JumpInsnNode(IFEQ, next));
        stackPop();
        if (returnValue) {
            writePushBooleanAsMemory(true);
            stackPop();
        }
    } else if (operator instanceof BooleanAndExprToken || operator instanceof BooleanAnd2ExprToken) {
        code.add(new JumpInsnNode(IFNE, next));
        stackPop();
        if (returnValue) {
            writePushBooleanAsMemory(false);
            stackPop();
        }
    }
    code.add(new JumpInsnNode(GOTO, end));
    code.add(next);
    writeExpression(operator.getRightValue(), returnValue, false);
    if (returnValue) {
        if (operator.getLast() instanceof ValueIfElseToken)
            writePopBoxing();
        else
            writePopBooleanAsObject();
    }
    code.add(end);
    return null;
}
Also used : StackItem(org.develnext.jphp.core.compiler.common.misc.StackItem) UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory)

Example 90 with Memory

use of php.runtime.Memory 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)

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