Search in sources :

Example 11 with LocalVariable

use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.

the class MethodStmtCompiler method writeHeader.

void writeHeader() {
    int access = 0;
    if (statement != null) {
        if (compiler.getScope().isDebugMode()) {
            statement.setDynamicLocal(true);
        }
        switch(statement.getModifier()) {
            case PRIVATE:
                access += Opcodes.ACC_PRIVATE;
                break;
            case PROTECTED:
                access += Opcodes.ACC_PROTECTED;
                break;
            case PUBLIC:
                access += Opcodes.ACC_PUBLIC;
                break;
        }
        if (statement.isStatic())
            access += Opcodes.ACC_STATIC;
        //if (statement.isAbstract()) access += Opcodes.ACC_ABSTRACT;
        if (statement.isFinal())
            access += Opcodes.ACC_FINAL;
        node.access = access;
        node.name = clazz.isSystem() || entity == null ? statement.getName().getName() : entity.getInternalName();
        node.desc = Type.getMethodDescriptor(Type.getType(Memory.class), Type.getType(Environment.class), Type.getType(Memory[].class));
        if (external) {
            node.desc = Type.getMethodDescriptor(Type.getType(Memory.class), Type.getType(Environment.class), Type.getType(Memory[].class), Type.getType(ArrayMemory.class));
        }
    }
    if (statement != null) {
        LabelNode label = labelStart = writeLabel(node, statement.getMeta().getStartLine());
        if (!statement.isStatic())
            addLocalVariable("~this", label, Object.class);
        ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(this, null);
        // Environment env
        addLocalVariable("~env", label, Environment.class);
        // Memory[] arguments
        LocalVariable args = addLocalVariable("~args", label, Memory[].class);
        if (statement.isDynamicLocal()) {
            if (external)
                addLocalVariable("~passedLocal", label, ArrayMemory.class);
            LocalVariable local = addLocalVariable("~local", label, ArrayMemory.class);
            if (external) {
                expressionCompiler.writeVarLoad("~passedLocal");
                expressionCompiler.writeSysStaticCall(ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
                expressionCompiler.setStackPeekAsImmutable();
                expressionCompiler.writeVarStore(local, false, true);
            } else {
                expressionCompiler.writePushConstNull();
                expressionCompiler.writeSysStaticCall(ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
                expressionCompiler.setStackPeekAsImmutable();
                expressionCompiler.writeVarStore(local, false, true);
            }
        }
        if (statement.getUses() != null && !statement.getUses().isEmpty()) {
            int i = 0;
            expressionCompiler.writeVarLoad("~this");
            expressionCompiler.writeGetDynamic("uses", Memory[].class);
            for (ArgumentStmtToken argument : statement.getUses()) {
                LocalVariable local;
                if (statement.isDynamicLocal()) {
                    expressionCompiler.writeDefineVariable(argument.getName());
                    local = getLocalVariable(argument.getName().getName());
                } else {
                    local = addLocalVariable(argument.getName().getName(), label, Memory.class);
                }
                if (argument.isReference()) {
                    local.setReference(true);
                    statement.variable(argument.getName()).setUnstable(true);
                }
                expressionCompiler.writePushDup();
                expressionCompiler.writePushGetFromArray(i, Memory.class);
                if (statement.isDynamicLocal()) {
                    expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
                } else {
                    expressionCompiler.writeVarStore(local, false, false);
                }
                local.pushLevel();
                i++;
            }
            expressionCompiler.writePopAll(1);
        }
        int i = 0;
        for (ArgumentStmtToken argument : statement.getArguments()) {
            if (argument.isReference()) {
                statement.variable(argument.getName()).setReference(true).setUnstable(true);
            }
            LabelNode next = new LabelNode();
            expressionCompiler.writeDefineVariable(argument.getName());
            LocalVariable local = getLocalVariable(argument.getName().getName());
            if (local != null) {
                expressionCompiler.writeVarLoad(args);
                expressionCompiler.writePushGetFromArray(i, Memory.class);
                expressionCompiler.writeVarAssign(local, argument.getName(), true, false);
                // if length <= i then undefined
                node.instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, next));
                expressionCompiler.stackPop();
                if (argument.getValue() == null)
                    expressionCompiler.writePushNull();
                else
                    expressionCompiler.writeExpression(argument.getValue(), true, false);
                expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
                node.instructions.add(next);
                local.pushLevel();
            }
            i++;
        }
    } else {
        LabelNode label = labelStart = writeLabel(node, clazz.statement.getMeta().getStartLine());
    }
}
Also used : ArrayMemory(php.runtime.memory.ArrayMemory) ArrayMemory(php.runtime.memory.ArrayMemory) ClassConstantMemory(php.runtime.memory.helper.ClassConstantMemory) Memory(php.runtime.Memory) ConstantMemory(php.runtime.memory.helper.ConstantMemory) ObjectMemory(php.runtime.memory.ObjectMemory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) IObject(php.runtime.lang.IObject)

Example 12 with LocalVariable

use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.

the class MethodStmtCompiler method writeFooter.

@SuppressWarnings("unchecked")
void writeFooter() {
    LabelNode endL = new LabelNode();
    node.instructions.add(endL);
    for (LocalVariable variable : localVariables.values()) {
        String description = Type.getDescriptor(variable.getClazz() == null ? Object.class : variable.getClazz());
        if (variable.name.equals("~this")) {
            //if (variable.getClazz() != Memory.class && !clazz.statement.isTrait()) {
            description = "L" + clazz.entity.getCompiledInternalName() + ";";
        //}
        }
        node.localVariables.add(new LocalVariableNode(variable.name, description, null, variable.label == null ? labelStart : variable.label, variable.getEndLabel() == null ? endL : variable.getEndLabel(), variable.index));
    }
//node.maxStack = this.stackMaxSize;  !!! we don't need this, see: ClassWriter.COMPUTE_FRAMES
//node.maxLocals = this.localVariables.size();
}
Also used : LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) IObject(php.runtime.lang.IObject)

Example 13 with LocalVariable

use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.

the class ClassStmtCompiler method writeInitEnvironment.

@SuppressWarnings("unchecked")
protected void writeInitEnvironment() {
    if (!dynamicConstants.isEmpty() || !dynamicProperties.isEmpty()) {
        initDynamicExists = true;
        MethodNode node = new MethodNodeImpl();
        node.access = ACC_STATIC + ACC_PUBLIC;
        node.name = "__$initEnvironment";
        node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class));
        if (entity.isTrait()) {
            node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class), Type.getType(String.class));
        }
        MethodStmtCompiler methodCompiler = new MethodStmtCompiler(this, node);
        ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(methodCompiler, null);
        methodCompiler.writeHeader();
        LabelNode l0 = expressionCompiler.makeLabel();
        methodCompiler.addLocalVariable("~env", l0, Environment.class);
        if (entity.isTrait())
            methodCompiler.addLocalVariable("~class_name", l0, String.class);
        LocalVariable l_class = methodCompiler.addLocalVariable("~class", l0, ClassEntity.class);
        expressionCompiler.writePushEnv();
        if (entity.isTrait()) {
            expressionCompiler.writeVarLoad("~class_name");
            expressionCompiler.writePushDupLowerCase();
        } else {
            expressionCompiler.writePushConstString(entity.getName());
            expressionCompiler.writePushConstString(entity.getLowerName());
        }
        expressionCompiler.writePushConstBoolean(true);
        expressionCompiler.writeSysDynamicCall(Environment.class, "fetchClass", ClassEntity.class, String.class, String.class, Boolean.TYPE);
        expressionCompiler.writeVarStore(l_class, false, false);
        // corrects defination of constants
        final List<ConstStmtToken.Item> first = new ArrayList<ConstStmtToken.Item>();
        final Set<String> usedNames = new HashSet<String>();
        final List<ConstStmtToken.Item> other = new ArrayList<ConstStmtToken.Item>();
        for (ConstStmtToken.Item el : dynamicConstants) {
            Token tk = el.value.getSingle();
            if (tk instanceof StaticAccessExprToken) {
                StaticAccessExprToken access = (StaticAccessExprToken) tk;
                boolean self = false;
                if (access.getClazz() instanceof SelfExprToken)
                    self = true;
                else if (access.getClazz() instanceof FulledNameToken && ((FulledNameToken) access.getClazz()).getName().equalsIgnoreCase(entity.getName())) {
                    self = true;
                }
                if (self) {
                    String name = ((NameToken) access.getField()).getName();
                    if (usedNames.contains(el.getFulledName()))
                        first.add(0, el);
                    else
                        first.add(el);
                    usedNames.add(name);
                    continue;
                }
            }
            if (usedNames.contains(el.getFulledName()))
                first.add(0, el);
            else
                other.add(el);
        }
        other.addAll(0, first);
        for (ConstStmtToken.Item el : other) {
            expressionCompiler.writeVarLoad(l_class);
            expressionCompiler.writePushEnv();
            expressionCompiler.writePushConstString(el.getFulledName());
            expressionCompiler.writeExpression(el.value, true, false, true);
            expressionCompiler.writePopBoxing(true);
            expressionCompiler.writeSysDynamicCall(ClassEntity.class, "addDynamicConstant", void.class, Environment.class, String.class, Memory.class);
        }
        for (ClassVarStmtToken el : dynamicProperties) {
            expressionCompiler.writeVarLoad(l_class);
            expressionCompiler.writePushEnv();
            expressionCompiler.writePushConstString(el.getVariable().getName());
            expressionCompiler.writeExpression(el.getValue(), true, false, true);
            expressionCompiler.writePopBoxing(true);
            expressionCompiler.writeSysDynamicCall(ClassEntity.class, el.isStatic() ? "addDynamicStaticProperty" : "addDynamicProperty", void.class, Environment.class, String.class, Memory.class);
        }
        node.instructions.add(new InsnNode(RETURN));
        methodCompiler.writeFooter();
        this.node.methods.add(node);
    }
}
Also used : StaticAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) ValueExprToken(org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken) StaticAccessExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.StaticAccessExprToken) ClassStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ClassStmtToken) ClassVarStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ClassVarStmtToken) MethodStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.MethodStmtToken) Token(org.develnext.jphp.core.tokenizer.token.Token) SelfExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.SelfExprToken) ConstStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ConstStmtToken) NameToken(org.develnext.jphp.core.tokenizer.token.expr.value.NameToken) FulledNameToken(org.develnext.jphp.core.tokenizer.token.expr.value.FulledNameToken) MethodNodeImpl(org.develnext.jphp.core.compiler.jvm.node.MethodNodeImpl) ClassVarStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ClassVarStmtToken) NameToken(org.develnext.jphp.core.tokenizer.token.expr.value.NameToken) FulledNameToken(org.develnext.jphp.core.tokenizer.token.expr.value.FulledNameToken) ConstStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.ConstStmtToken) SelfExprToken(org.develnext.jphp.core.tokenizer.token.expr.value.SelfExprToken) FulledNameToken(org.develnext.jphp.core.tokenizer.token.expr.value.FulledNameToken)

Example 14 with LocalVariable

use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writeDefineVariable.

protected void writeDefineVariable(VariableExprToken value) {
    if (methodStatement.isUnusedVariable(value))
        return;
    LocalVariable variable = method.getLocalVariable(value.getName());
    if (variable == null) {
        LabelNode label = writeLabel(node, value.getMeta().getStartLine());
        variable = method.addLocalVariable(value.getName(), label, Memory.class);
        if (methodStatement.isReference(value) || compiler.getScope().superGlobals.contains(value.getName())) {
            variable.setReference(true);
        } else {
            variable.setReference(false);
        }
        if (variable.name.equals("this") && method.getLocalVariable("~this") != null) {
            // $this
            writeDefineThis(variable);
        } else if (compiler.getScope().superGlobals.contains(value.getName())) {
            // super-globals
            writeDefineGlobalVar(value.getName());
        } else if (methodStatement.isDynamicLocal()) {
            // ref-local variables
            writePushLocal();
            writePushConstString(value.getName());
            writeSysDynamicCall(Memory.class, "refOfIndex", Memory.class, String.class);
            makeVarStore(variable);
            stackPop();
            variable.pushLevel();
            variable.setValue(null);
            variable.setReference(true);
        } else {
            // simple local variables
            if (variable.isReference()) {
                writePushNewObject(ReferenceMemory.class);
            } else {
                writePushNull();
            }
            makeVarStore(variable);
            stackPop();
            variable.pushLevel();
        }
    } else
        variable.pushLevel();
}
Also used : UndefinedMemory(php.runtime.memory.helper.UndefinedMemory) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)

Example 15 with LocalVariable

use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.

the class ExpressionStmtCompiler method writePushThis.

public void writePushThis() {
    if (method.clazz.isClosure() || method.getGeneratorEntity() != null) {
        writeVarLoad("~this");
        writeGetDynamic("self", Memory.class);
    } else {
        if (method.getLocalVariable("this") == null) {
            if (!methodStatement.isStatic()) {
                LabelNode label = writeLabel(node);
                LocalVariable local = method.addLocalVariable("this", label, Memory.class);
                writeDefineThis(local);
            } else {
                writePushNull();
                return;
            }
        }
        writeVarLoad("this");
    }
}
Also used : LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)

Aggregations

LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)23 Memory (php.runtime.Memory)11 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)6 ValueExprToken (org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken)5 LabelNode (org.objectweb.asm.tree.LabelNode)5 UndefinedMemory (php.runtime.memory.helper.UndefinedMemory)5 VariableExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken)4 ExprStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken)4 Environment (php.runtime.env.Environment)4 Token (org.develnext.jphp.core.tokenizer.token.Token)3 InsnNode (org.objectweb.asm.tree.InsnNode)3 StackItem (org.develnext.jphp.core.compiler.common.misc.StackItem)2 DynamicAccessExprToken (org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken)2 GetVarExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.GetVarExprToken)2 ListExprToken (org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken)2 BodyStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken)2 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)2 CompileClass (php.runtime.ext.support.compile.CompileClass)2 IObject (php.runtime.lang.IObject)2 MethodNodeImpl (org.develnext.jphp.core.compiler.jvm.node.MethodNodeImpl)1