Search in sources :

Example 1 with DynamicAccessExprToken

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

the class ListCompiler method write.

public void write(ListExprToken list, boolean returnValue, boolean writeValue) {
    if (writeValue) {
        expr.writeExpression(list.getValue(), true, false);
        expr.writePopBoxing();
    }
    if (list.isHasRef() && (list.getValue() != null && list.getValue().isSingle() && ValueExprToken.isConstable(list.getValue().getSingle(), true))) {
        compiler.getEnvironment().error(list.getValue().toTraceInfo(compiler.getContext()), Messages.ERR_CANNOT_ASSIGN_REF_TO_NON_REF_VALUE.fetch());
    }
    int i, length = list.getVariables().size();
    for (i = 0; i < length; i++) {
        // desc order as in PHP
        ListExprToken.Variable v = list.getVariables().get(i);
        expr.writePushDup();
        if (v.indexes != null) {
            for (Object index : v.indexes) {
                expr.writePushTraceInfo(v.var);
                if (v.isRef) {
                    expr.writePushConstBoolean(true);
                }
                if (index instanceof Integer) {
                    expr.writePushConstLong((Integer) index);
                } else {
                    expr.writeExpression((ExprStmtToken) index, true, false);
                    switch(expr.stackPeek().type) {
                        case INT:
                        case STRING:
                            break;
                        default:
                            expr.writePopBoxing();
                            break;
                    }
                }
                // expr.writePushTraceInfo(list);
                if (v.isRef) {
                    expr.writeSysStaticCall(MemoryUtils.class, REF_VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, Boolean.TYPE, expr.stackPeek().type.toClass());
                } else {
                    expr.writeSysStaticCall(MemoryUtils.class, VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, expr.stackPeek().type.toClass());
                }
            // expr.writeSysDynamicCall(Memory.class, "valueOfIndex", Memory.class, expr.stackPeek().type.toClass());
            }
            expr.writePushTraceInfo(v.var);
        } else {
            expr.writePushTraceInfo(v.var);
        }
        if (v.isWithKey()) {
            expr.writeExpression(v.exprIndex, true, false);
            switch(expr.stackPeek().type) {
                case INT:
                case STRING:
                    break;
                default:
                    expr.writePopBoxing();
                    break;
            }
        } else {
            expr.writePushConstLong(v.index);
        }
        expr.writeSysStaticCall(MemoryUtils.class, v.isRef ? REF_VALUE_FOR_LIST_METHOD : VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, expr.stackPeek().type.toClass());
        if (v.isVariable()) {
            LocalVariable variable = method.getLocalVariable(v.getVariableName());
            if (v.isRef) {
                variable.setReference(false);
                expr.writePushMemory(new ReferenceMemory());
                expr.writeVarAssign(variable, (VariableExprToken) v.var.getSingle(), false, true);
                variable.setReference(true);
            }
            expr.writeVarAssign(variable, (VariableExprToken) v.var.getSingle(), false, !v.isRef);
        } else if (v.isArray() || v.isStaticProperty() || v.isArrayPush()) {
            expr.writeExpression(v.var, true, false);
            if (expr.stackPeek().immutable || expr.stackPeek().isConstant())
                expr.unexpectedToken(v.var.getSingle());
            expr.writeSysStaticCall(Memory.class, "assignRight", Memory.class, Memory.class, Memory.class);
            expr.writePopAll(1);
        } else if (v.isDynamicProperty()) {
            DynamicAccessExprToken dynamic = (DynamicAccessExprToken) v.var.getLast();
            ExprStmtToken var = new ExprStmtToken(this.env, this.compiler.getContext(), v.var.getTokens());
            var.getTokens().remove(var.getTokens().size() - 1);
            var.updateAsmExpr(this.env, this.compiler.getContext());
            expr.writeDynamicAccessInfo(dynamic, false);
            expr.writeExpression(var, true, false);
            expr.writePopBoxing(false);
            expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
            expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
            expr.writeSysStaticCall(ObjectInvokeHelper.class, "assignPropertyRight", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, Memory.class, PropertyCallCache.class, int.class);
            expr.writePopAll(1);
        }
    }
    if (!returnValue)
        expr.writePopAll(1);
}
Also used : ReferenceMemory(php.runtime.memory.ReferenceMemory) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) Memory(php.runtime.Memory) ReferenceMemory(php.runtime.memory.ReferenceMemory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) DynamicAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken) ListExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken)

Example 2 with DynamicAccessExprToken

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

the class TokenizerTest method testBraces.

@Test
public void testBraces() throws IOException {
    Tokenizer tokenizer = new Tokenizer(new Context(" :: ->foobar('a', 1, 3.0);"));
    assertTrue(tokenizer.nextToken() instanceof StaticAccessExprToken);
    assertTrue(tokenizer.nextToken() instanceof DynamicAccessExprToken);
    assertTrue(tokenizer.nextToken() instanceof NameToken);
    assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
    assertTrue(tokenizer.nextToken() instanceof StringExprToken);
    assertTrue(tokenizer.nextToken() instanceof CommaToken);
    assertTrue(tokenizer.nextToken() instanceof IntegerExprToken);
    assertTrue(tokenizer.nextToken() instanceof CommaToken);
    assertTrue(tokenizer.nextToken() instanceof DoubleExprToken);
    assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
    assertTrue(tokenizer.nextToken() instanceof SemicolonToken);
}
Also used : Context(php.runtime.env.Context) CommaToken(org.develnext.jphp.core.tokenizer.token.expr.CommaToken) SemicolonToken(org.develnext.jphp.core.tokenizer.token.SemicolonToken) DoubleExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.DoubleExprToken) StaticAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken) BraceExprToken(org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken) IntegerExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.IntegerExprToken) DynamicAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken) Tokenizer(org.develnext.jphp.core.tokenizer.Tokenizer) StringExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken) NameToken(org.develnext.jphp.core.tokenizer.token.expr.value.NameToken) Test(org.junit.Test)

Example 3 with DynamicAccessExprToken

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

the class CallCompiler method writePushDynamicMethod.

/**
 * $var->method()
 */
public Memory writePushDynamicMethod(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
    expr.getMethod().getEntity().setImmutable(false);
    if (!writeOpcode)
        return null;
    DynamicAccessExprToken access = (DynamicAccessExprToken) function.getName();
    if (access instanceof DynamicAccessAssignExprToken) {
        expr.unexpectedToken(access);
    }
    expr.writeLineNumber(function);
    expr.writeDynamicAccessPrepare(access, true);
    expr.writePushParameters(function.getParameters());
    expr.writeSysStaticCall(ObjectInvokeHelper.class, "invokeMethod", Memory.class, Memory.class, String.class, String.class, Environment.class, TraceInfo.class, Memory[].class);
    if (!returnValue) {
        expr.writePopAll(1);
    }
    if (statistic != null) {
        statistic.returnType = StackItem.Type.REFERENCE;
    }
    return null;
}
Also used : Memory(php.runtime.Memory) DynamicAccessAssignExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessAssignExprToken) DynamicAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken)

Example 4 with DynamicAccessExprToken

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

the class ForeachCompiler method write.

@Override
public void write(ForeachStmtToken token) {
    expr.writeDefineVariables(token.getLocal());
    LabelNode start = new LabelNode();
    LabelNode end = new LabelNode();
    LabelNode l = new LabelNode();
    add(l);
    expr.writePushEnv();
    expr.writePushTraceInfo(token);
    expr.writeExpression(token.getIterator(), true, false, true);
    expr.writePopBoxing();
    expr.writePushConstBoolean(token.isValueReference());
    expr.writePushConstBoolean(token.isKeyReference());
    expr.writeSysDynamicCall(Environment.class, "__getIterator", ForeachIterator.class, TraceInfo.class, Memory.class, Boolean.TYPE, Boolean.TYPE);
    String name = "~foreach~" + method.nextStatementIndex(ForeachIterator.class);
    LocalVariable foreachVariable = method.getLocalVariable(name);
    if (foreachVariable == null)
        foreachVariable = method.addLocalVariable(name, l, ForeachIterator.class);
    /*LocalVariable foreachVariable = method.addLocalVariable(
                "~foreach~" + method.nextStatementIndex(ForeachIterator.class), l, ForeachIterator.class
        );*/
    foreachVariable.setEndLabel(end);
    expr.writeVarStore(foreachVariable, false, false);
    method.pushJump(end, start);
    add(start);
    expr.writeVarLoad(foreachVariable);
    expr.writeSysDynamicCall(ForeachIterator.class, "next", Boolean.TYPE);
    add(new JumpInsnNode(IFEQ, end));
    expr.stackPop();
    // $key
    if (token.getKey() != null) {
        LocalVariable key = method.getLocalVariable(token.getKey().getName());
        expr.checkAssignableVar(token.getKey());
        expr.writeVarLoad(foreachVariable);
        expr.writeSysDynamicCall(ForeachIterator.class, "getMemoryKey", Memory.class);
        if (token.isKeyReference()) {
            throw new FatalException("Key element cannot be a reference", token.getKey().toTraceInfo(compiler.getContext()));
        // writeVarStore(key, false, false);
        } else
            expr.writeVarAssign(key, null, false, false);
    }
    // $var
    // LocalVariable variable = method.getLocalVariable(token.getValue().getName());
    Token last = token.getValue().getLast();
    VariableExprToken var = null;
    if (last instanceof DynamicAccessExprToken) {
        DynamicAccessExprToken setter = (DynamicAccessExprToken) last;
        ExprStmtToken value = new ExprStmtToken(this.env, this.compiler.getContext(), token.getValue().getTokens());
        value.getTokens().remove(value.getTokens().size() - 1);
        value.updateAsmExpr(this.env, this.compiler.getContext());
        expr.writeExpression(value, true, false);
        expr.writeVarLoad(foreachVariable);
        expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
        if (!token.isValueReference())
            expr.writePopImmutable();
        expr.writeDynamicAccessInfo(setter, false);
        expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
        expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
        expr.writeSysStaticCall(ObjectInvokeHelper.class, "assignProperty", Memory.class, Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
    } else {
        if (token.getValue().getSingle() instanceof VariableExprToken)
            expr.checkAssignableVar(var = (VariableExprToken) token.getValue().getSingle());
        ExprStmtToken value = token.getValue();
        expr.writeVarLoad(foreachVariable);
        expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
        if (value.isSingle() && value.getSingle() instanceof ListExprToken) {
            ListExprToken listExprToken = (ListExprToken) value.getSingle();
            if (!token.isValueReference() && !listExprToken.isHasRef()) {
                expr.writePopImmutable();
            }
            ListCompiler listCompiler = (ListCompiler) expr.getCompiler(ListExprToken.class);
            listCompiler.write(listExprToken, false, false);
        } else {
            if (!token.isValueReference())
                expr.writePopImmutable();
            expr.writeExpression(value, true, false);
            if (expr.stackPeek().immutable)
                expr.unexpectedToken(value.getLast());
            expr.writeSysStaticCall(Memory.class, token.isValueReference() ? "assignRefRight" : "assignRight", Memory.class, Memory.class, Memory.class);
        }
    }
    expr.writePopAll(1);
    /*
        if (token.isValueReference())
            writeVarStore(variable, false, false);
        else
            writeVarAssign(variable, false, true); */
    // body
    expr.write(BodyStmtToken.class, token.getBody());
    add(new JumpInsnNode(GOTO, start));
    add(end);
    /*if (compiler.getLangMode() == LangMode.JPHP){
            if (token.isValueReference() && var != null){
                expr.writeVarLoad(var.getName());
                expr.writeSysDynamicCall(Memory.class, "unset", void.class);
            }
        }*/
    method.popJump();
    expr.writeUndefineVariables(token.getLocal());
    method.prevStatementIndex(ForeachIterator.class);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ForeachIterator(php.runtime.lang.ForeachIterator) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) FatalException(php.runtime.exceptions.FatalException) ListCompiler(org.develnext.jphp.core.compiler.jvm.statement.expr.value.ListCompiler) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) DynamicAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken) Token(org.develnext.jphp.core.tokenizer.token.Token) BodyStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken) ForeachStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ForeachStmtToken) VariableExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken) ExprStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken) ListExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken) DynamicAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken) VariableExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken) ListExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken)

Aggregations

DynamicAccessExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken)4 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)2 ListExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken)2 ExprStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken)2 Memory (php.runtime.Memory)2 ListCompiler (org.develnext.jphp.core.compiler.jvm.statement.expr.value.ListCompiler)1 Tokenizer (org.develnext.jphp.core.tokenizer.Tokenizer)1 SemicolonToken (org.develnext.jphp.core.tokenizer.token.SemicolonToken)1 Token (org.develnext.jphp.core.tokenizer.token.Token)1 BraceExprToken (org.develnext.jphp.core.tokenizer.token.expr.BraceExprToken)1 CommaToken (org.develnext.jphp.core.tokenizer.token.expr.CommaToken)1 DynamicAccessAssignExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessAssignExprToken)1 DoubleExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.DoubleExprToken)1 IntegerExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.IntegerExprToken)1 NameToken (org.develnext.jphp.core.tokenizer.token.expr.value.NameToken)1 StaticAccessExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken)1 StringExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.StringExprToken)1 VariableExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken)1 BodyStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken)1 ForeachStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.ForeachStmtToken)1