001    package railo.transformer.bytecode;
002    
003    import java.util.List;
004    import java.util.Stack;
005    
006    import org.objectweb.asm.ClassWriter;
007    import org.objectweb.asm.commons.GeneratorAdapter;
008    import org.objectweb.asm.commons.Method;
009    
010    import railo.commons.lang.StringUtil;
011    import railo.transformer.bytecode.extern.StringExternalizerWriter;
012    import railo.transformer.bytecode.literal.LitString;
013    import railo.transformer.bytecode.visitor.TryCatchFinallyData;
014    
015    public class BytecodeContext {
016            
017    
018            private ClassWriter classWriter;
019            private GeneratorAdapter adapter;
020            private String className;
021            private List<LitString> keys;
022            private int count=0;
023            private Method method;
024            private boolean doSubFunctions=true;
025            private BytecodeContext staticConstr;
026            private BytecodeContext constr;
027            
028            private static long _id=0;
029            private synchronized static String id() {
030                    if(_id<0)_id=0;
031                    return StringUtil.addZeros(++_id,4);
032            }
033            
034            private String id=id();
035    
036            public BytecodeContext(BytecodeContext statConstr,BytecodeContext constr,StringExternalizerWriter externalizer,List keys,ClassWriter classWriter,String className, GeneratorAdapter adapter,Method method,boolean writeLog) {
037                    this.classWriter = classWriter;
038                    this.className = className;
039                    this.writeLog = writeLog;
040                    this.adapter = adapter;
041                    this.keys = keys;
042                    this.method=method;
043                    this.staticConstr=statConstr;
044                    this.constr=constr;
045                    this.externalizer=externalizer;
046            }
047            
048            public BytecodeContext(BytecodeContext statConstr,BytecodeContext constr,List keys,BytecodeContext bc, GeneratorAdapter adapter,Method method) {
049                    this.classWriter = bc.getClassWriter();
050                    this.className = bc.getClassName();
051                    this.writeLog = bc.writeLog();
052                    this.externalizer=bc.externalizer;
053                    
054                    this.adapter = adapter;
055                    this.keys = keys;
056                    this.method=method;
057                    this.staticConstr=statConstr;
058                    this.constr=constr;
059            }
060            
061            /**
062             * @return the id
063             */
064            public String getId() {
065                    return id;
066            }
067            
068            /**
069             * @return the count
070             */
071            public int getCount() {
072                    return count;
073            }
074    
075            /**
076             * @param count the count to set
077             */
078            public int incCount() {
079                    return ++this.count;
080            }
081            public void resetCount() {
082                    this.count=0;
083            }
084            /**
085             * @return the adapter
086             */
087            public GeneratorAdapter getAdapter() {
088                    return adapter;
089            }
090            /**
091             * @param adapter the adapter to set
092             */
093            public void setAdapter(BytecodeContext bc) {
094                    this.adapter = bc.getAdapter();
095            }
096            /**
097             * @return the classWriter
098             */
099            public ClassWriter getClassWriter() {
100                    return classWriter;
101            }
102            /**
103             * @param classWriter the classWriter to set
104             */
105            public void setClassWriter(ClassWriter classWriter) {
106                    this.classWriter = classWriter;
107            }
108            /**
109             * @return the className
110             */
111            public String getClassName() {
112                    return className;
113            }
114            /**
115             * @param className the className to set
116             */
117            public void setClassName(String className) {
118                    this.className = className;
119            }
120    
121            public synchronized int registerKey(LitString lit)  {
122                    int index = keys.indexOf(lit);
123                    if(index!=-1)return index;// calls the toString method of litString
124                    
125                    keys.add(lit);
126                    
127                    return keys.size()-1;
128            }
129    
130            public List getKeys() {
131                    return keys;
132            }
133    
134    
135            Stack tcf=new Stack();
136            private int currentTag;
137            private int line;
138            private BytecodeContext root;
139            private boolean writeLog;
140            private StringExternalizerWriter externalizer;
141            //private static BytecodeContext staticConstr;
142            public void pushTryCatchFinallyData(TryCatchFinallyData data) {
143                    tcf.push(data);
144            }
145            public void popTryCatchFinallyData() {
146                    tcf.pop();
147            }
148            
149            public Stack getTryCatchFinallyDataStack() {
150                    return tcf;
151            }
152    
153            /**
154             * @return the method
155             */
156            public Method getMethod() {
157                    return method;
158            }
159    
160            /**
161             * @return the doSubFunctions
162             */
163            public boolean doSubFunctions() {
164                    return doSubFunctions;
165            }
166    
167            /**
168             * @param doSubFunctions the doSubFunctions to set
169             * @return 
170             */
171            public boolean changeDoSubFunctions(boolean doSubFunctions) {
172                    boolean old=this.doSubFunctions;
173                    this.doSubFunctions = doSubFunctions;
174                    return old;
175            }
176    
177            /**
178             * @return the currentTag
179             */
180            public int getCurrentTag() {
181                    return currentTag;
182            }
183    
184            /**
185             * @param currentTag the currentTag to set
186             */
187            public void setCurrentTag(int currentTag) {
188                    this.currentTag = currentTag;
189            }
190    
191            public BytecodeContext getStaticConstructor() {
192                    return staticConstr;
193            }
194            public BytecodeContext getConstructor() {
195                    return constr;
196            }
197    
198            public void visitLineNumber(int line) {
199                    this.line=line;
200                    getAdapter().visitLineNumber(line,getAdapter().mark());
201            }
202    
203            public int getLine() {
204                    return line;
205            }
206    
207            public BytecodeContext getRoot() {
208                    return root;
209            }
210            public void setRoot(BytecodeContext root) {
211                    this.root= root;
212            }
213    
214            public boolean writeLog() {
215                    return this.writeLog;
216            }
217    
218            public StringExternalizerWriter getStringExternalizerWriter() {
219                    return externalizer;
220            }
221    
222    }