001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.expression.var;
020
021import lucee.transformer.bytecode.BytecodeContext;
022import lucee.transformer.bytecode.BytecodeException;
023import lucee.transformer.bytecode.expression.ExpressionBase;
024import lucee.transformer.bytecode.util.TypeScope;
025import lucee.transformer.bytecode.util.Types;
026
027import org.objectweb.asm.Type;
028import org.objectweb.asm.commons.GeneratorAdapter;
029import org.objectweb.asm.commons.Method;
030
031public final class VariableRef extends ExpressionBase {
032
033        
034        private Variable variable;
035        // Object touch (Object,String)
036    /*private final static Method TOUCH =  new Method("touch",
037                        Types.OBJECT,
038                        new Type[]{Types.OBJECT,Types.STRING});*/
039    // lucee.runtime.type.ref.Reference getReference (Object,String)
040    /*private final static Method GET_REFERENCE =  new Method("getReference",
041                        Types.REFERENCE,
042                        new Type[]{Types.OBJECT,Types.STRING});*/
043
044        // Object touch (Object,Key)
045    private final static Method TOUCH_KEY =  new Method("touch",
046                        Types.OBJECT,
047                        new Type[]{Types.OBJECT,Types.COLLECTION_KEY});
048    // lucee.runtime.type.ref.Reference getReference (Object,Key)
049    private final static Method GET_REFERENCE_KEY =  new Method("getReference",
050                        Types.REFERENCE,
051                        new Type[]{Types.OBJECT,Types.COLLECTION_KEY});
052
053        public VariableRef(Variable variable) {
054                super(variable.getStart(),variable.getEnd());
055                this.variable=variable;
056        }
057
058        /**
059         *
060         * @see lucee.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
061         */
062        public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
063                GeneratorAdapter adapter = bc.getAdapter();
064                int count=variable.countFM+variable.countDM;
065                
066                for(int i=0;i<=count;i++) {
067                adapter.loadArg(0);
068                }
069                TypeScope.invokeScope(adapter, variable.scope);
070                
071                boolean isLast;
072                for(int i=0;i<count;i++) {
073                        isLast=(i+1)==count;
074                        Variable.registerKey(bc,((DataMember)variable.members.get(i)).getName());
075                        adapter.invokeVirtual(Types.PAGE_CONTEXT,isLast?GET_REFERENCE_KEY:TOUCH_KEY);
076                }
077                return Types.REFERENCE;
078        }
079
080        /* *
081         *
082         * @see lucee.transformer.bytecode.expression.Expression#getType()
083         * /
084        public int getType() {
085                return Types._OBJECT;
086        }*/
087
088}