Source Code Cross Referenced for CompilerScope.java in  » Scripting » oscript-2.10.4 » oscript » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » oscript 2.10.4 » oscript.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*=============================================================================
002:         *     Copyright Texas Instruments 2000-2003.  All Rights Reserved.
003:         *   
004:         * This program is free software; you can redistribute it and/or
005:         * modify it under the terms of the GNU Lesser General Public
006:         * License as published by the Free Software Foundation; either
007:         * version 2 of the License, or (at your option) any later version.
008:         * 
009:         * This program is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012:         * Lesser General Public License for more details.
013:         * 
014:         * You should have received a copy of the GNU Lesser General Public
015:         * License along with this library; if not, write to the Free Software
016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         * 
018:         * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019:         */
020:
021:        package oscript.compiler;
022:
023:        import java.util.*;
024:
025:        import oscript.data.*;
026:        import oscript.syntaxtree.*;
027:        import oscript.util.*;
028:
029:        // The Bytecode Engineerign Library
030:        import org.apache.bcel.generic.*;
031:        import org.apache.bcel.Constants;
032:        import org.apache.bcel.classfile.JavaClass;
033:
034:        /**
035:         * This class helps the compiler track declarations of variables within a
036:         * scope, in order to optimize resolving references to variables by caching
037:         * and, when possible, statically resolving the reference in order to avoid
038:         * performing the normal hashtable lookup(s).  It is also responsible for
039:         * generating the {@link Scope#createMember} and {@link Scope#lookupInScope}
040:         * code, so that the rest of the compiler does not need to worry about what
041:         * optimization strategy (if any) is used to resolve references.
042:         * <p>
043:         * Note that this class is fairly tightly coupled to {@link CompilerVisitor}.
044:         * It would be an inner class if it were not for file size issues.
045:         * 
046:         * @author Rob Clark (rob@ti.com)
047:         * @version 0
048:         */
049:        public class CompilerScope {
050:            private static final org.apache.bcel.generic.Type BASIC_SCOPE_TYPE = new ObjectType(
051:                    "oscript.data.BasicScope");
052:
053:            private SymbolTable smit = new OpenHashSymbolTable();
054:            private SymbolTable privSmit;
055:            private SymbolTable pubpSmit;
056:
057:            private int slot;
058:            private LocalVariableGen lg;
059:            private CompilerScope prev;
060:            private boolean hasFxnInScope;
061:            private Hashtable memberTable = new Hashtable();
062:            private int conditionalNestingCnt = 0;
063:            private int smitIdx = -1;
064:            private int privSmitIdx, pubpSmitIdx;
065:
066:            /**
067:             * The compiler for the compiled unit within which this scope is 
068:             * declared.
069:             */
070:            CompilerVisitor cv;
071:
072:            /**
073:             * Used to mark that the scope is open, meaning there may be variables
074:             * declared in this scope that the compiler doesn't know about.  This
075:             * can be the result of an "eval", "import", or "mixin".
076:             */
077:            private boolean openScope = false;
078:
079:            /**
080:             * Constructor for scope to represent a scope passed in to the
081:             * node-evaluator, rather than constructed by the node-evaluator
082:             * 
083:             * @param cv       the compiler that declares this scope
084:             * @param slot     the local variable slot of the externally constructed
085:             *    scope object
086:             * @param argIds   array of argument ids and attributes
087:             */
088:            CompilerScope(CompilerVisitor cv, int slot, int[] argIds) {
089:                this .cv = cv;
090:                this .slot = slot;
091:
092:                // for top-level scopes, also construct private and public/protect
093:                // index tables:
094:                privSmit = new OpenHashSymbolTable();
095:                pubpSmit = new OpenHashSymbolTable();
096:
097:                if (argIds != null)
098:                    for (int i = 0; i < argIds.length; i += 2)
099:                        smit.create(argIds[i]);
100:
101:                // create smit instance variable:
102:                smitIdx = cv.ctx.getInstanceConstantIdx(smit);
103:                privSmitIdx = cv.ctx.getInstanceConstantIdx(privSmit);
104:                pubpSmitIdx = cv.ctx.getInstanceConstantIdx(pubpSmit);
105:            }
106:
107:            /**
108:             * Constructor to represent a scope constructed by this node-evaluator.
109:             * 
110:             * @param cv       the compiler that declares this scope
111:             * @param prev     the enclosing scope
112:             * @param hasFxnInScope   a flag from the parser indicating if there is
113:             *    (or might be) a function declaration within this scope.  If there
114:             *    is no function in this scope, scope storage can be allocated from
115:             *    the stack
116:             */
117:            CompilerScope(CompilerVisitor cv, CompilerScope prev,
118:                    boolean hasFxnInScope) {
119:                this .cv = cv;
120:                this .prev = prev;
121:                this .hasFxnInScope = hasFxnInScope;
122:
123:                // create local variable for scope object:
124:                lg = cv.mg.addLocalVariable(cv.ctx
125:                        .makeUniqueIdentifierName("scope"), BASIC_SCOPE_TYPE,
126:                        null, null);
127:                slot = lg.getIndex();
128:
129:                // create smit instance variable:
130:                smitIdx = cv.ctx.getInstanceConstantIdx(smit);
131:
132:                // if no fxn in scope, we can re-use the scope, which entails
133:                // extra logic to see if a scope has already been created, 
134:                // and to reset() when leaving the scope... also, we can allocate
135:                // the scope from the stack:
136:                if (!hasFxnInScope) {
137:                    BranchInstruction IFNONNULL = null;
138:                    // note insert into head of list, hence insert'd instructions are
139:                    // in reverse order:
140:                    cv.il.insert(new ASTORE(slot));
141:                    cv.il.insert(InstructionConstants.ACONST_NULL);
142:                    cv.il.append(new ALOAD(slot));
143:                    IFNONNULL = new IFNONNULL(null);
144:                    cv.il.append(IFNONNULL);
145:
146:                    // "sf.allocateScope(currentScope,smit)"
147:                    cv.il.append(InstructionConstants.ALOAD_1); // sf
148:                    cv.il.append(new ALOAD(prev.getSlot())); // currentScope
149:                    cv.il.append(new GETSTATIC(smitIdx)); // smit
150:                    cv.il
151:                            .append(new INVOKEVIRTUAL(
152:                                    cv.ctx
153:                                            .methodref(
154:                                                    "oscript.util.StackFrame",
155:                                                    "allocateBasicScope",
156:                                                    "(Loscript/data/Scope;Loscript/util/SymbolTable;)Loscript/data/BasicScope;")));
157:
158:                    // "scopeXX = " ...
159:                    cv.il.append(new ASTORE(slot));
160:
161:                    if (!hasFxnInScope)
162:                        cv.il.setNextAsTarget(IFNONNULL);
163:                } else {
164:                    // "new BasicScope(currentScope,smit)"
165:                    cv.il.append(new NEW(cv.ctx.cp
166:                            .addClass("oscript.data.BasicScope")));
167:                    cv.il.append(InstructionConstants.DUP);
168:                    cv.il.append(new ALOAD(prev.getSlot())); // currentScope
169:                    cv.il.append(new GETSTATIC(smitIdx)); // smit
170:                    cv.il
171:                            .append(new INVOKESPECIAL(
172:                                    cv.ctx
173:                                            .methodref(
174:                                                    "oscript.data.BasicScope",
175:                                                    "<init>",
176:                                                    "(Loscript/data/Scope;Loscript/util/SymbolTable;)V")));
177:
178:                    // "scopeXX = " ...
179:                    cv.il.append(new ASTORE(slot));
180:                }
181:            }
182:
183:            /**
184:             * Get the instance-constant indexs of the SMIT... this is needed for the
185:             * topmost CompilerScope in a function, so that the compiler can generate
186:             * an accessor method.
187:             */
188:            int[] getSharedMemberIndexTableIdxs() {
189:                return new int[] { smitIdx, pubpSmitIdx, privSmitIdx };
190:            }
191:
192:            /**
193:             * Mark this scope as open.  An open scope may possibly have members
194:             * declared in it that the compiler does not know about, such as 
195:             * because of an <code>eval</code> or <code>import</code> statement.
196:             */
197:            void markOpen() {
198:                openScope = true;
199:
200:                // XXX should clear any cached lookups, since the lookup may
201:                //     change after this point
202:            }
203:
204:            /**
205:             * Called when processing has reached the end of this scope, to pop
206:             * this scope of the stack
207:             */
208:            CompilerScope pop() {
209:                if (prev != null) {
210:                    if (!hasFxnInScope) {
211:                        cv.il.append(new ALOAD(slot));
212:                        cv.il.append(new INVOKEVIRTUAL(cv.ctx.methodref(
213:                                "oscript.data.BasicScope", "reset", "()V")));
214:                    }
215:                }
216:                lg.setEnd(cv.il.getLastInstructionHandle());
217:                return prev;
218:            }
219:
220:            /**
221:             * Get the slot for the local variable that refers to this scope object
222:             */
223:            int getSlot() {
224:                return slot;
225:            }
226:
227:            /**
228:             * Generate the {@link Scope#createMember} call.  The code is generated
229:             * at the current position in the compiler that this scope is declared
230:             * in.  Stack:
231:             * <pre>
232:             *   ... -&gt; ... , Value
233:             * </pre>
234:             * 
235:             * @param id   the &lt;IDENTIFIER&gt; token
236:             * @param attr         the permissions attribute
237:             */
238:            void createMember(NodeToken id, int attr) {
239:                cv.il.append(new ALOAD(getSlot()));
240:                cv.handle(id);
241:                cv.ctx.pushSymbol(cv.il, id.tokenImage);
242:                cv.ctx.pushInt(cv.il, attr);
243:                cv.il.append(new INVOKEVIRTUAL(cv.ctx.methodref(
244:                        "oscript.data.Scope", "createMember",
245:                        "(II)Loscript/data/Value;")));
246:
247:                createMemberImpl(id.otokenImage).dumpInitializer();
248:
249:                int iid = Symbol.getSymbol(id.otokenImage).getId();
250:                smit.create(iid);
251:                if (privSmit != null) {
252:                    if (attr == Reference.ATTR_PRIVATE)
253:                        privSmit.create(iid);
254:                    else
255:                        pubpSmit.create(iid);
256:                }
257:            }
258:
259:            private Member createMemberImpl(Value name) {
260:                Member member = new Member(this , name);
261:                memberTable.put(name, member);
262:                return member;
263:            }
264:
265:            /**
266:             * Dump the code to perform a {@link Scope#lookupInScope}.
267:             * 
268:             * @param cv   the compiler instance within which to perform the lookup
269:             * @param id   the &lt;IDENTIFIER&gt; token
270:             */
271:            void lookupInScope(CompilerVisitor cv, NodeToken id) {
272:                cv.handle(id);
273:
274:                Value name = id.otokenImage;
275:                Member member = (Member) (memberTable.get(name));
276:
277:                if (member == null) {
278:                    if ((prev == null) || openScope)
279:                        createMemberImpl(name).dumpLookup(cv);
280:                    else
281:                        prev.lookupInScope(cv, id);
282:                } else {
283:                    member.dumpLookup(cv);
284:                }
285:            }
286:
287:            /**
288:             * Called by the compiler to indicate that compilation has entered a 
289:             * potentially condional path within this scope.  (It does not matter 
290:             * if this scope is entirely enclosed by a conditional path, what does 
291:             * matter is a conditional path enclosed by this scope.)
292:             * 
293:             * @see #leaveConditional
294:             */
295:            void enterConditional() {
296:                conditionalNestingCnt++;
297:            }
298:
299:            /**
300:             * Called by the compiler to indicate that compilation has left a
301:             * potentially conditional path within this scope.
302:             * 
303:             * @see #enterConditional
304:             */
305:            void leaveConditional() {
306:                conditionalNestingCnt--;
307:            }
308:
309:            /**
310:             */
311:            boolean inConditional() {
312:                return cv.scope.inConditionalImpl(this );
313:            }
314:
315:            private boolean inConditionalImpl(CompilerScope terminator) {
316:                if (conditionalNestingCnt > 0)
317:                    return true;
318:                else if (this  != terminator)
319:                    return prev.inConditionalImpl(terminator);
320:                else
321:                    return false;
322:            }
323:        }
324:
325:        /**
326:         * An instance of this class is created for each variable that is declared
327:         * or looked up, to track the status of that variable
328:         */
329:        class Member {
330:            private int slot = -1;
331:            private CompilerScope scope;
332:            private Value name;
333:            private boolean mayNeedToLoad;
334:            private boolean definitelyNeedToLoad = true;
335:            private CompilerVisitor cv;
336:
337:            private InstructionHandle initializerHandle = null;
338:
339:            /**
340:             * Class Constructor for a member of a scope.
341:             * 
342:             * @param scope   the scope this member is declared in
343:             * @param name    the member name
344:             */
345:            Member(CompilerScope scope, Value name) {
346:                this .scope = scope;
347:                this .name = name;
348:                cv = scope.cv;
349:
350:                mayNeedToLoad = scope.inConditional();
351:
352:                cv.defer(new Runnable() {
353:                    public void run() {
354:                        if (initializerHandle != null) {
355:                            try {
356:                                cv.il.delete(initializerHandle);
357:                            } catch (Throwable t) {
358:                                Thread.dumpStack();
359:                            }
360:                            initializerHandle = null;
361:                        }
362:                    }
363:                });
364:            }
365:
366:            //  protected void finalize()
367:            //  {
368:            //    System.err.println(name + ": slot=" + slot);
369:            //  }
370:
371:            /**
372:             * Called when we decide that this member should be cached.
373:             */
374:            private void createLocalVar() {
375:                if (slot != -1)
376:                    return; // already created
377:
378:                LocalVariableGen lg = cv.mg.addLocalVariable(cv.ctx
379:                        .makeUniqueIdentifierName(name.castToString()),
380:                        cv.ctx.VALUE_TYPE, null, // XXX setStart!
381:                        null);
382:
383:                slot = lg.getIndex();
384:
385:                //if(XXX)
386:                {
387:                    cv.il.insert(new ASTORE(slot)); // insert at head in reverse order
388:                    cv.il.insert(InstructionConstants.ACONST_NULL);
389:                }
390:
391:                if (initializerHandle == null)
392:                    Thread.dumpStack();
393:
394:                // replace initializerHandle:
395:                InstructionHandle tmp = cv.il.append(initializerHandle,
396:                        InstructionConstants.DUP);
397:                cv.il.append(tmp, new ASTORE(slot));
398:            }
399:
400:            /**
401:             * can only be called by defining scope, after createMember
402:             */
403:            void dumpInitializer() {
404:                if (initializerHandle != null)
405:                    Thread.dumpStack();
406:                initializerHandle = cv.il.append(InstructionConstants.NOP);
407:                definitelyNeedToLoad = false;
408:            }
409:
410:            /**
411:             * can only be called by defining scope, after lookupInScope
412:             */
413:            void dumpLookup(CompilerVisitor cv) {
414:                // XXX perhaps this could be cleaned up:
415:                if (definitelyNeedToLoad) {
416:                    mayNeedToLoad = scope.inConditional();
417:
418:                    cv.il.append(new ALOAD(scope.getSlot()));
419:
420:                    cv.ctx.pushSymbol(cv.il, name.castToString());
421:
422:                    cv.il.append(new INVOKEVIRTUAL(cv.ctx.methodref(
423:                            "oscript.data.Scope", "lookupInScope",
424:                            "(I)Loscript/data/Value;")));
425:
426:                    dumpInitializer();
427:                } else if (mayNeedToLoad) {
428:                    createLocalVar();
429:
430:                    mayNeedToLoad = scope.inConditional();
431:
432:                    cv.il.append(new ALOAD(slot));
433:
434:                    cv.il.append(InstructionConstants.DUP);
435:
436:                    BranchInstruction IFNONNULL = new IFNONNULL(null);
437:                    cv.il.append(IFNONNULL);
438:                    cv.il.append(InstructionConstants.POP);
439:                    cv.il.append(new ALOAD(scope.getSlot()));
440:
441:                    cv.ctx.pushSymbol(cv.il, name.castToString());
442:
443:                    cv.il.append(new INVOKEVIRTUAL(cv.ctx.methodref(
444:                            "oscript.data.Scope", "lookupInScope",
445:                            "(I)Loscript/data/Value;")));
446:                    cv.il.append(InstructionConstants.DUP);
447:                    cv.il.append(new ASTORE(slot));
448:
449:                    cv.il.setNextAsTarget(IFNONNULL);
450:                } else {
451:                    createLocalVar();
452:                    cv.il.append(new ALOAD(slot));
453:                }
454:            }
455:        }
456:
457:        /*
458:         *   Local Variables:
459:         *   tab-width: 2
460:         *   indent-tabs-mode: nil
461:         *   mode: java
462:         *   c-indentation-style: java
463:         *   c-basic-offset: 2
464:         *   eval: (c-set-offset 'substatement-open '0)
465:         *   eval: (c-set-offset 'case-label '+)
466:         *   eval: (c-set-offset 'inclass '+)
467:         *   eval: (c-set-offset 'inline-open '0)
468:         *   End:
469:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.