Source Code Cross Referenced for Block.java in  » Scripting » jruby » org » jruby » runtime » 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 » jruby » org.jruby.runtime 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /***** BEGIN LICENSE BLOCK *****
002:         * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003:         *
004:         * The contents of this file are subject to the Common Public
005:         * License Version 1.0 (the "License"); you may not use this file
006:         * except in compliance with the License. You may obtain a copy of
007:         * the License at http://www.eclipse.org/legal/cpl-v10.html
008:         *
009:         * Software distributed under the License is distributed on an "AS
010:         * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011:         * implied. See the License for the specific language governing
012:         * rights and limitations under the License.
013:         *
014:         * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
015:         * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
016:         * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
017:         * Copyright (C) 2004-2007 Thomas E Enebo <enebo@acm.org>
018:         * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
019:         * 
020:         * Alternatively, the contents of this file may be used under the terms of
021:         * either of the GNU General Public License Version 2 or later (the "GPL"),
022:         * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
023:         * in which case the provisions of the GPL or the LGPL are applicable instead
024:         * of those above. If you wish to allow use of your version of this file only
025:         * under the terms of either the GPL or the LGPL, and not to allow others to
026:         * use your version of this file under the terms of the CPL, indicate your
027:         * decision by deleting the provisions above and replace them with the notice
028:         * and other provisions required by the GPL or the LGPL. If you do not delete
029:         * the provisions above, a recipient may use your version of this file under
030:         * the terms of any one of the CPL, the GPL or the LGPL.
031:         ***** END LICENSE BLOCK *****/package org.jruby.runtime;
032:
033:        import org.jruby.Ruby;
034:        import org.jruby.RubyArray;
035:        import org.jruby.RubyModule;
036:        import org.jruby.RubyProc;
037:        import org.jruby.ast.IterNode;
038:        import org.jruby.ast.MultipleAsgnNode;
039:        import org.jruby.ast.Node;
040:        import org.jruby.ast.NodeTypes;
041:        import org.jruby.ast.util.ArgsUtil;
042:        import org.jruby.evaluator.AssignmentVisitor;
043:        import org.jruby.evaluator.EvaluationState;
044:        import org.jruby.exceptions.JumpException;
045:        import org.jruby.parser.BlockStaticScope;
046:        import org.jruby.runtime.builtin.IRubyObject;
047:        import org.jruby.util.collections.SinglyLinkedList;
048:
049:        /**
050:         *  Internal live representation of a block ({...} or do ... end).
051:         */
052:        public class Block {
053:            /**
054:             * All Block variables should either refer to a real block or this NULL_BLOCK.
055:             */
056:            public static final Block NULL_BLOCK = new Block() {
057:                public boolean isGiven() {
058:                    return false;
059:                }
060:
061:                public IRubyObject yield(ThreadContext context,
062:                        IRubyObject value, IRubyObject self, RubyModule klass,
063:                        boolean aValue) {
064:                    throw context.getRuntime().newLocalJumpError("noreason",
065:                            (IRubyObject) value, "yield called out of block");
066:                }
067:
068:                public Block cloneBlock() {
069:                    return this ;
070:                }
071:            };
072:
073:            /**
074:             * 'self' at point when the block is defined
075:             */
076:            protected IRubyObject self;
077:
078:            /**
079:             * AST Node representing the parameter (VARiable) list to the block.
080:             */
081:            private IterNode iterNode;
082:
083:            /**
084:             * frame of method which defined this block
085:             */
086:            protected Frame frame;
087:            protected SinglyLinkedList cref;
088:            protected Visibility visibility;
089:            protected RubyModule klass;
090:
091:            /**
092:             * A reference to all variable values (and names) that are in-scope for this block.
093:             */
094:            protected DynamicScope dynamicScope;
095:
096:            /**
097:             * The Proc that this block is associated with.  When we reference blocks via variable
098:             * reference they are converted to Proc objects.  We store a reference of the associated
099:             * Proc object for easy conversion.  
100:             */
101:            private RubyProc proc = null;
102:
103:            public boolean isLambda = false;
104:
105:            protected Arity arity;
106:
107:            public static Block createBlock(ThreadContext context,
108:                    IterNode iterNode, DynamicScope dynamicScope,
109:                    IRubyObject self) {
110:                return new Block(iterNode, self, context.getCurrentFrame(),
111:                        context.peekCRef(), context.getCurrentFrame()
112:                                .getVisibility(), context.getRubyClass(),
113:                        dynamicScope);
114:            }
115:
116:            protected Block() {
117:                this (null, null, null, null, null, null, null);
118:            }
119:
120:            public Block(IterNode iterNode, IRubyObject self, Frame frame,
121:                    SinglyLinkedList cref, Visibility visibility,
122:                    RubyModule klass, DynamicScope dynamicScope) {
123:
124:                //assert method != null;
125:
126:                this .iterNode = iterNode;
127:                this .self = self;
128:                this .frame = frame;
129:                this .visibility = visibility;
130:                this .klass = klass;
131:                this .cref = cref;
132:                this .dynamicScope = dynamicScope;
133:                this .arity = iterNode == null ? null : Arity
134:                        .procArityOf(iterNode.getVarNode());
135:            }
136:
137:            public static Block createBinding(Frame frame,
138:                    DynamicScope dynamicScope) {
139:                ThreadContext context = frame.getSelf().getRuntime()
140:                        .getCurrentContext();
141:
142:                // We create one extra dynamicScope on a binding so that when we 'eval "b=1", binding' the
143:                // 'b' will get put into this new dynamic scope.  The original scope does not see the new
144:                // 'b' and successive evals with this binding will.  I take it having the ability to have 
145:                // succesive binding evals be able to share same scope makes sense from a programmers 
146:                // perspective.   One crappy outcome of this design is it requires Dynamic and Static 
147:                // scopes to be mutable for this one case.
148:
149:                // Note: In Ruby 1.9 all of this logic can go away since they will require explicit
150:                // bindings for evals.
151:
152:                // We only define one special dynamic scope per 'logical' binding.  So all bindings for
153:                // the same scope should share the same dynamic scope.  This allows multiple evals with
154:                // different different bindings in the same scope to see the same stuff.
155:                DynamicScope extraScope = dynamicScope.getBindingScope();
156:
157:                // No binding scope so we should create one
158:                if (extraScope == null) {
159:                    // If the next scope out has the same binding scope as this scope it means
160:                    // we are evaling within an eval and in that case we should be sharing the same
161:                    // binding scope.
162:                    DynamicScope parent = dynamicScope.getNextCapturedScope();
163:                    if (parent != null
164:                            && parent.getBindingScope() == dynamicScope) {
165:                        extraScope = dynamicScope;
166:                    } else {
167:                        extraScope = new DynamicScope(new BlockStaticScope(
168:                                dynamicScope.getStaticScope()), dynamicScope);
169:                        dynamicScope.setBindingScope(extraScope);
170:                    }
171:                }
172:
173:                // FIXME: Ruby also saves wrapper, which we do not
174:                return new Block(null, frame.getSelf(), frame, context
175:                        .peekCRef(), frame.getVisibility(), context
176:                        .getBindingRubyClass(), extraScope);
177:            }
178:
179:            public IRubyObject call(ThreadContext context, IRubyObject[] args) {
180:                return yield(context,
181:                        context.getRuntime().newArrayNoCopy(args), null, null,
182:                        true);
183:            }
184:
185:            protected void pre(ThreadContext context, RubyModule klass) {
186:                context.preYieldSpecificBlock(this , klass);
187:            }
188:
189:            protected void post(ThreadContext context) {
190:                context.postYield();
191:            }
192:
193:            public IRubyObject yield(ThreadContext context, IRubyObject value) {
194:                return yield(context, value, null, null, false);
195:            }
196:
197:            /**
198:             * Yield to this block, usually passed to the current call.
199:             * 
200:             * @param context represents the current thread-specific data
201:             * @param value The value to yield, either a single value or an array of values
202:             * @param self The current self
203:             * @param klass
204:             * @param aValue Should value be arrayified or not?
205:             * @return
206:             */
207:            public IRubyObject yield(ThreadContext context, IRubyObject value,
208:                    IRubyObject self, RubyModule klass, boolean aValue) {
209:                if (klass == null) {
210:                    self = this .self;
211:                    frame.setSelf(self);
212:                }
213:
214:                pre(context, klass);
215:
216:                try {
217:                    if (iterNode.getVarNode() != null) {
218:                        if (aValue) {
219:                            setupBlockArgs(context, iterNode.getVarNode(),
220:                                    value, self);
221:                        } else {
222:                            setupBlockArg(context, iterNode.getVarNode(),
223:                                    value, self);
224:                        }
225:                    }
226:
227:                    // This while loop is for restarting the block call in case a 'redo' fires.
228:                    while (true) {
229:                        try {
230:                            return EvaluationState.eval(context.getRuntime(),
231:                                    context, iterNode.getBodyNode(), self,
232:                                    NULL_BLOCK);
233:                        } catch (JumpException je) {
234:                            if (je.getJumpType() == JumpException.JumpType.RedoJump) {
235:                                context.pollThreadEvents();
236:                                // do nothing, allow loop to redo
237:                            } else {
238:                                if (je.getJumpType() == JumpException.JumpType.BreakJump
239:                                        && je.getTarget() == null) {
240:                                    je.setTarget(this );
241:                                }
242:                                throw je;
243:                            }
244:                        }
245:                    }
246:
247:                } catch (JumpException je) {
248:                    // A 'next' is like a local return from the block, ending this call or yield.
249:                    if (je.getJumpType() == JumpException.JumpType.NextJump)
250:                        return (IRubyObject) je.getValue();
251:
252:                    throw je;
253:                } finally {
254:                    post(context);
255:                }
256:            }
257:
258:            private void setupBlockArgs(ThreadContext context, Node varNode,
259:                    IRubyObject value, IRubyObject self) {
260:                Ruby runtime = self.getRuntime();
261:
262:                switch (varNode.nodeId) {
263:                case NodeTypes.ZEROARGNODE:
264:                    break;
265:                case NodeTypes.MULTIPLEASGNNODE:
266:                    value = AssignmentVisitor.multiAssign(runtime, context,
267:                            self, (MultipleAsgnNode) varNode,
268:                            (RubyArray) value, false);
269:                    break;
270:                default:
271:                    int length = arrayLength(value);
272:                    switch (length) {
273:                    case 0:
274:                        value = runtime.getNil();
275:                        break;
276:                    case 1:
277:                        value = ((RubyArray) value).eltInternal(0);
278:                        break;
279:                    default:
280:                        runtime.getWarnings().warn(
281:                                "multiple values for a block parameter ("
282:                                        + length + " for 1)");
283:                    }
284:                    AssignmentVisitor.assign(runtime, context, self, varNode,
285:                            value, Block.NULL_BLOCK, false);
286:                }
287:            }
288:
289:            private void setupBlockArg(ThreadContext context, Node varNode,
290:                    IRubyObject value, IRubyObject self) {
291:                Ruby runtime = self.getRuntime();
292:
293:                switch (varNode.nodeId) {
294:                case NodeTypes.ZEROARGNODE:
295:                    return;
296:                case NodeTypes.MULTIPLEASGNNODE:
297:                    value = AssignmentVisitor.multiAssign(runtime, context,
298:                            self, (MultipleAsgnNode) varNode, ArgsUtil
299:                                    .convertToRubyArray(runtime, value,
300:                                            ((MultipleAsgnNode) varNode)
301:                                                    .getHeadNode() != null),
302:                            false);
303:                    break;
304:                default:
305:                    if (value == null) {
306:                        runtime
307:                                .getWarnings()
308:                                .warn(
309:                                        "multiple values for a block parameter (0 for 1)");
310:                    }
311:                    AssignmentVisitor.assign(runtime, context, self, varNode,
312:                            value, Block.NULL_BLOCK, false);
313:                }
314:            }
315:
316:            private int arrayLength(IRubyObject node) {
317:                return node instanceof  RubyArray ? ((RubyArray) node)
318:                        .getLength() : 0;
319:            }
320:
321:            public Block cloneBlock() {
322:                // We clone dynamic scope because this will be a new instance of a block.  Any previously
323:                // captured instances of this block may still be around and we do not want to start
324:                // overwriting those values when we create a new one.
325:                // ENEBO: Once we make self, lastClass, and lastMethod immutable we can remove duplicate
326:                Block newBlock = new Block(iterNode, self, frame.duplicate(),
327:                        cref, visibility, klass, dynamicScope.cloneScope());
328:
329:                newBlock.isLambda = isLambda;
330:
331:                return newBlock;
332:            }
333:
334:            /**
335:             * What is the arity of this block?
336:             * 
337:             * @return the arity
338:             */
339:            public Arity arity() {
340:                return arity;
341:            }
342:
343:            public Visibility getVisibility() {
344:                return visibility;
345:            }
346:
347:            public void setVisibility(Visibility visibility) {
348:                this .visibility = visibility;
349:            }
350:
351:            public void setSelf(IRubyObject self) {
352:                this .self = self;
353:            }
354:
355:            public SinglyLinkedList getCRef() {
356:                return cref;
357:            }
358:
359:            /**
360:             * Retrieve the proc object associated with this block
361:             * 
362:             * @return the proc or null if this has no proc associated with it
363:             */
364:            public RubyProc getProcObject() {
365:                return proc;
366:            }
367:
368:            /**
369:             * Set the proc object associated with this block
370:             * 
371:             * @param procObject
372:             */
373:            public void setProcObject(RubyProc procObject) {
374:                this .proc = procObject;
375:            }
376:
377:            /**
378:             * Gets the dynamicVariables that are local to this block.   Parent dynamic scopes are also
379:             * accessible via the current dynamic scope.
380:             * 
381:             * @return Returns all relevent variable scoping information
382:             */
383:            public DynamicScope getDynamicScope() {
384:                return dynamicScope;
385:            }
386:
387:            /**
388:             * Gets the frame.
389:             * 
390:             * @return Returns a RubyFrame
391:             */
392:            public Frame getFrame() {
393:                return frame;
394:            }
395:
396:            /**
397:             * Gets the klass.
398:             * @return Returns a RubyModule
399:             */
400:            public RubyModule getKlass() {
401:                return klass;
402:            }
403:
404:            /**
405:             * Is the current block a real yield'able block instead a null one
406:             * 
407:             * @return true if this is a valid block or false otherwise
408:             */
409:            public boolean isGiven() {
410:                return true;
411:            }
412:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.