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


0001:        /*******************************************************************************
0002:         * BEGIN LICENSE BLOCK *** Version: CPL 1.0/GPL 2.0/LGPL 2.1
0003:         * 
0004:         * The contents of this file are subject to the Common Public License Version
0005:         * 1.0 (the "License"); you may not use this file except in compliance with the
0006:         * License. You may obtain a copy of the License at
0007:         * http://www.eclipse.org/legal/cpl-v10.html
0008:         * 
0009:         * Software distributed under the License is distributed on an "AS IS" basis,
0010:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
0011:         * the specific language governing rights and limitations under the License.
0012:         * 
0013:         * Copyright (C) 2006 Charles Oliver Nutter <headius@headius.com>
0014:         * Copytight (C) 2006-2007 Thomas E Enebo <enebo@acm.org>
0015:         * Copyright (C) 2007 Miguel Covarrubias <mlcovarrubias@gmail.com>
0016:         * Copyright (C) 2007 Ola Bini <ola@ologix.com>
0017:         * 
0018:         * Alternatively, the contents of this file may be used under the terms of
0019:         * either of the GNU General Public License Version 2 or later (the "GPL"), or
0020:         * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in
0021:         * which case the provisions of the GPL or the LGPL are applicable instead of
0022:         * those above. If you wish to allow use of your version of this file only under
0023:         * the terms of either the GPL or the LGPL, and not to allow others to use your
0024:         * version of this file under the terms of the CPL, indicate your decision by
0025:         * deleting the provisions above and replace them with the notice and other
0026:         * provisions required by the GPL or the LGPL. If you do not delete the
0027:         * provisions above, a recipient may use your version of this file under the
0028:         * terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ****
0029:         ******************************************************************************/package org.jruby.evaluator;
0030:
0031:        import org.jruby.Ruby;
0032:        import org.jruby.MetaClass;
0033:        import org.jruby.RubyArray;
0034:        import org.jruby.RubyBignum;
0035:        import org.jruby.RubyClass;
0036:        import org.jruby.RubyException;
0037:        import org.jruby.RubyFloat;
0038:        import org.jruby.RubyHash;
0039:        import org.jruby.RubyKernel;
0040:        import org.jruby.RubyLocalJumpError;
0041:        import org.jruby.RubyModule;
0042:        import org.jruby.RubyObject;
0043:        import org.jruby.RubyProc;
0044:        import org.jruby.RubyRange;
0045:        import org.jruby.RubyRegexp;
0046:        import org.jruby.RubyString;
0047:        import org.jruby.ast.AliasNode;
0048:        import org.jruby.ast.ArgsCatNode;
0049:        import org.jruby.ast.ArgsNode;
0050:        import org.jruby.ast.ArgsPushNode;
0051:        import org.jruby.ast.ArrayNode;
0052:        import org.jruby.ast.AttrAssignNode;
0053:        import org.jruby.ast.BackRefNode;
0054:        import org.jruby.ast.BeginNode;
0055:        import org.jruby.ast.BignumNode;
0056:        import org.jruby.ast.BinaryOperatorNode;
0057:        import org.jruby.ast.BlockNode;
0058:        import org.jruby.ast.BlockPassNode;
0059:        import org.jruby.ast.BreakNode;
0060:        import org.jruby.ast.CallNode;
0061:        import org.jruby.ast.CaseNode;
0062:        import org.jruby.ast.ClassNode;
0063:        import org.jruby.ast.ClassVarAsgnNode;
0064:        import org.jruby.ast.ClassVarDeclNode;
0065:        import org.jruby.ast.ClassVarNode;
0066:        import org.jruby.ast.Colon2Node;
0067:        import org.jruby.ast.Colon3Node;
0068:        import org.jruby.ast.ConstDeclNode;
0069:        import org.jruby.ast.ConstNode;
0070:        import org.jruby.ast.DAsgnNode;
0071:        import org.jruby.ast.DRegexpNode;
0072:        import org.jruby.ast.DStrNode;
0073:        import org.jruby.ast.DSymbolNode;
0074:        import org.jruby.ast.DVarNode;
0075:        import org.jruby.ast.DXStrNode;
0076:        import org.jruby.ast.DefinedNode;
0077:        import org.jruby.ast.DefnNode;
0078:        import org.jruby.ast.DefsNode;
0079:        import org.jruby.ast.DotNode;
0080:        import org.jruby.ast.EnsureNode;
0081:        import org.jruby.ast.EvStrNode;
0082:        import org.jruby.ast.FCallNode;
0083:        import org.jruby.ast.FixnumNode;
0084:        import org.jruby.ast.FlipNode;
0085:        import org.jruby.ast.FloatNode;
0086:        import org.jruby.ast.ForNode;
0087:        import org.jruby.ast.GlobalAsgnNode;
0088:        import org.jruby.ast.GlobalVarNode;
0089:        import org.jruby.ast.HashNode;
0090:        import org.jruby.ast.IfNode;
0091:        import org.jruby.ast.InstAsgnNode;
0092:        import org.jruby.ast.InstVarNode;
0093:        import org.jruby.ast.IterNode;
0094:        import org.jruby.ast.ListNode;
0095:        import org.jruby.ast.LocalAsgnNode;
0096:        import org.jruby.ast.LocalVarNode;
0097:        import org.jruby.ast.Match2Node;
0098:        import org.jruby.ast.Match3Node;
0099:        import org.jruby.ast.MatchNode;
0100:        import org.jruby.ast.ModuleNode;
0101:        import org.jruby.ast.MultipleAsgnNode;
0102:        import org.jruby.ast.NewlineNode;
0103:        import org.jruby.ast.NextNode;
0104:        import org.jruby.ast.Node;
0105:        import org.jruby.ast.NodeTypes;
0106:        import org.jruby.ast.NotNode;
0107:        import org.jruby.ast.NthRefNode;
0108:        import org.jruby.ast.OpAsgnNode;
0109:        import org.jruby.ast.OpAsgnOrNode;
0110:        import org.jruby.ast.OpElementAsgnNode;
0111:        import org.jruby.ast.OptNNode;
0112:        import org.jruby.ast.OrNode;
0113:        import org.jruby.ast.PostExeNode;
0114:        import org.jruby.ast.RegexpNode;
0115:        import org.jruby.ast.RescueBodyNode;
0116:        import org.jruby.ast.RescueNode;
0117:        import org.jruby.ast.ReturnNode;
0118:        import org.jruby.ast.RootNode;
0119:        import org.jruby.ast.SClassNode;
0120:        import org.jruby.ast.SValueNode;
0121:        import org.jruby.ast.SplatNode;
0122:        import org.jruby.ast.StrNode;
0123:        import org.jruby.ast.SuperNode;
0124:        import org.jruby.ast.SymbolNode;
0125:        import org.jruby.ast.ToAryNode;
0126:        import org.jruby.ast.UndefNode;
0127:        import org.jruby.ast.UntilNode;
0128:        import org.jruby.ast.VAliasNode;
0129:        import org.jruby.ast.VCallNode;
0130:        import org.jruby.ast.WhenNode;
0131:        import org.jruby.ast.WhileNode;
0132:        import org.jruby.ast.XStrNode;
0133:        import org.jruby.ast.YieldNode;
0134:        import org.jruby.ast.ZSuperNode;
0135:        import org.jruby.ast.types.INameNode;
0136:        import org.jruby.ast.util.ArgsUtil;
0137:        import org.jruby.exceptions.JumpException;
0138:        import org.jruby.exceptions.RaiseException;
0139:        import org.jruby.exceptions.JumpException.JumpType;
0140:        import org.jruby.internal.runtime.methods.DefaultMethod;
0141:        import org.jruby.internal.runtime.methods.DynamicMethod;
0142:        import org.jruby.internal.runtime.methods.WrapperMethod;
0143:        import org.jruby.lexer.yacc.ISourcePosition;
0144:        import org.jruby.parser.ReOptions;
0145:        import org.jruby.parser.StaticScope;
0146:        import org.jruby.runtime.Block;
0147:        import org.jruby.runtime.CallType;
0148:        import org.jruby.runtime.DynamicScope;
0149:        import org.jruby.runtime.EventHook;
0150:        import org.jruby.runtime.SharedScopeBlock;
0151:        import org.jruby.runtime.MethodIndex;
0152:        import org.jruby.runtime.ThreadContext;
0153:        import org.jruby.runtime.Visibility;
0154:        import org.jruby.runtime.builtin.IRubyObject;
0155:        import org.jruby.util.ByteList;
0156:        import org.jruby.util.KCode;
0157:        import org.jruby.util.collections.SinglyLinkedList;
0158:
0159:        public class EvaluationState {
0160:            public static IRubyObject eval(Ruby runtime, ThreadContext context,
0161:                    Node node, IRubyObject self, Block block) {
0162:                try {
0163:                    return evalInternal(runtime, context, node, self, block);
0164:                } catch (StackOverflowError sfe) {
0165:                    throw runtime.newSystemStackError("stack level too deep");
0166:                }
0167:            }
0168:
0169:            private static IRubyObject evalInternal(Ruby runtime,
0170:                    ThreadContext context, Node node, IRubyObject self,
0171:                    Block aBlock) {
0172:                do {
0173:                    if (node == null)
0174:                        return nilNode(runtime, context);
0175:
0176:                    switch (node.nodeId) {
0177:                    case NodeTypes.ALIASNODE:
0178:                        return aliasNode(runtime, context, node);
0179:                    case NodeTypes.ANDNODE: {
0180:                        BinaryOperatorNode iVisited = (BinaryOperatorNode) node;
0181:
0182:                        IRubyObject result = evalInternal(runtime, context,
0183:                                iVisited.getFirstNode(), self, aBlock);
0184:                        if (!result.isTrue())
0185:                            return result;
0186:                        node = iVisited.getSecondNode();
0187:                        continue;
0188:                    }
0189:                    case NodeTypes.ARGSCATNODE:
0190:                        return argsCatNode(runtime, context, node, self, aBlock);
0191:                    case NodeTypes.ARGSPUSHNODE:
0192:                        return argsPushNode(runtime, context, node, self,
0193:                                aBlock);
0194:                    case NodeTypes.ARRAYNODE:
0195:                        return arrayNode(runtime, context, node, self, aBlock);
0196:                    case NodeTypes.ATTRASSIGNNODE:
0197:                        return attrAssignNode(runtime, context, node, self,
0198:                                aBlock);
0199:                    case NodeTypes.BACKREFNODE:
0200:                        return backRefNode(context, node);
0201:                    case NodeTypes.BEGINNODE:
0202:                        node = ((BeginNode) node).getBodyNode();
0203:                        continue;
0204:                    case NodeTypes.BIGNUMNODE:
0205:                        return bignumNode(runtime, node);
0206:                    case NodeTypes.BLOCKNODE:
0207:                        return blockNode(runtime, context, node, self, aBlock);
0208:                    case NodeTypes.BLOCKPASSNODE:
0209:                        assert false : "Call nodes and friends deal with this";
0210:                    case NodeTypes.BREAKNODE:
0211:                        return breakNode(runtime, context, node, self, aBlock);
0212:                    case NodeTypes.CALLNODE:
0213:                        return callNode(runtime, context, node, self, aBlock);
0214:                    case NodeTypes.CASENODE:
0215:                        return caseNode(runtime, context, node, self, aBlock);
0216:                    case NodeTypes.CLASSNODE:
0217:                        return classNode(runtime, context, node, self, aBlock);
0218:                    case NodeTypes.CLASSVARASGNNODE:
0219:                        return classVarAsgnNode(runtime, context, node, self,
0220:                                aBlock);
0221:                    case NodeTypes.CLASSVARDECLNODE:
0222:                        return classVarDeclNode(runtime, context, node, self,
0223:                                aBlock);
0224:                    case NodeTypes.CLASSVARNODE:
0225:                        return classVarNode(runtime, context, node, self);
0226:                    case NodeTypes.COLON2NODE:
0227:                        return colon2Node(runtime, context, node, self, aBlock);
0228:                    case NodeTypes.COLON3NODE:
0229:                        return colon3Node(runtime, node);
0230:                    case NodeTypes.CONSTDECLNODE:
0231:                        return constDeclNode(runtime, context, node, self,
0232:                                aBlock);
0233:                    case NodeTypes.CONSTNODE:
0234:                        return constNode(context, node);
0235:                    case NodeTypes.DASGNNODE:
0236:                        return dAsgnNode(runtime, context, node, self, aBlock);
0237:                    case NodeTypes.DEFINEDNODE:
0238:                        return definedNode(runtime, context, node, self, aBlock);
0239:                    case NodeTypes.DEFNNODE:
0240:                        return defnNode(runtime, context, node);
0241:                    case NodeTypes.DEFSNODE:
0242:                        return defsNode(runtime, context, node, self, aBlock);
0243:                    case NodeTypes.DOTNODE:
0244:                        return dotNode(runtime, context, node, self, aBlock);
0245:                    case NodeTypes.DREGEXPNODE:
0246:                        return dregexpNode(runtime, context, node, self, aBlock);
0247:                    case NodeTypes.DSTRNODE:
0248:                        return dStrNode(runtime, context, node, self, aBlock);
0249:                    case NodeTypes.DSYMBOLNODE:
0250:                        return dSymbolNode(runtime, context, node, self, aBlock);
0251:                    case NodeTypes.DVARNODE:
0252:                        return dVarNode(runtime, context, node);
0253:                    case NodeTypes.DXSTRNODE:
0254:                        return dXStrNode(runtime, context, node, self, aBlock);
0255:                    case NodeTypes.ENSURENODE:
0256:                        return ensureNode(runtime, context, node, self, aBlock);
0257:                    case NodeTypes.EVSTRNODE:
0258:                        return evStrNode(runtime, context, node, self, aBlock);
0259:                    case NodeTypes.FALSENODE:
0260:                        return falseNode(runtime, context);
0261:                    case NodeTypes.FCALLNODE:
0262:                        return fCallNode(runtime, context, node, self, aBlock);
0263:                    case NodeTypes.FIXNUMNODE:
0264:                        return fixnumNode(runtime, node);
0265:                    case NodeTypes.FLIPNODE:
0266:                        return flipNode(runtime, context, node, self, aBlock);
0267:                    case NodeTypes.FLOATNODE:
0268:                        return floatNode(runtime, node);
0269:                    case NodeTypes.FORNODE:
0270:                        return forNode(runtime, context, node, self, aBlock);
0271:                    case NodeTypes.GLOBALASGNNODE:
0272:                        return globalAsgnNode(runtime, context, node, self,
0273:                                aBlock);
0274:                    case NodeTypes.GLOBALVARNODE:
0275:                        return globalVarNode(runtime, context, node);
0276:                    case NodeTypes.HASHNODE:
0277:                        return hashNode(runtime, context, node, self, aBlock);
0278:                    case NodeTypes.IFNODE: {
0279:                        IfNode iVisited = (IfNode) node;
0280:                        IRubyObject result = evalInternal(runtime, context,
0281:                                iVisited.getCondition(), self, aBlock);
0282:
0283:                        if (result.isTrue()) {
0284:                            node = iVisited.getThenBody();
0285:                        } else {
0286:                            node = iVisited.getElseBody();
0287:                        }
0288:                        continue;
0289:                    }
0290:                    case NodeTypes.INSTASGNNODE:
0291:                        return instAsgnNode(runtime, context, node, self,
0292:                                aBlock);
0293:                    case NodeTypes.INSTVARNODE:
0294:                        return instVarNode(runtime, node, self);
0295:                    case NodeTypes.ITERNODE:
0296:                        assert false : "Call nodes deal with these directly";
0297:                    case NodeTypes.LOCALASGNNODE:
0298:                        return localAsgnNode(runtime, context, node, self,
0299:                                aBlock);
0300:                    case NodeTypes.LOCALVARNODE:
0301:                        return localVarNode(runtime, context, node);
0302:                    case NodeTypes.MATCH2NODE:
0303:                        return match2Node(runtime, context, node, self, aBlock);
0304:                    case NodeTypes.MATCH3NODE:
0305:                        return match3Node(runtime, context, node, self, aBlock);
0306:                    case NodeTypes.MATCHNODE:
0307:                        return matchNode(runtime, context, node, self, aBlock);
0308:                    case NodeTypes.MODULENODE:
0309:                        return moduleNode(runtime, context, node, self, aBlock);
0310:                    case NodeTypes.MULTIPLEASGNNODE:
0311:                        return multipleAsgnNode(runtime, context, node, self,
0312:                                aBlock);
0313:                    case NodeTypes.NEWLINENODE: {
0314:                        NewlineNode iVisited = (NewlineNode) node;
0315:
0316:                        // something in here is used to build up ruby stack trace...
0317:                        context.setPosition(iVisited.getPosition());
0318:
0319:                        if (isTrace(runtime)) {
0320:                            callTraceFunction(runtime, context,
0321:                                    EventHook.RUBY_EVENT_LINE);
0322:                        }
0323:
0324:                        // TODO: do above but not below for additional newline nodes
0325:                        node = iVisited.getNextNode();
0326:                        continue;
0327:                    }
0328:                    case NodeTypes.NEXTNODE:
0329:                        return nextNode(runtime, context, node, self, aBlock);
0330:                    case NodeTypes.NILNODE:
0331:                        return nilNode(runtime, context);
0332:                    case NodeTypes.NOTNODE:
0333:                        return notNode(runtime, context, node, self, aBlock);
0334:                    case NodeTypes.NTHREFNODE:
0335:                        return nthRefNode(context, node);
0336:                    case NodeTypes.OPASGNANDNODE: {
0337:                        BinaryOperatorNode iVisited = (BinaryOperatorNode) node;
0338:
0339:                        // add in reverse order
0340:                        IRubyObject result = evalInternal(runtime, context,
0341:                                iVisited.getFirstNode(), self, aBlock);
0342:                        if (!result.isTrue())
0343:                            return pollAndReturn(context, result);
0344:                        node = iVisited.getSecondNode();
0345:                        continue;
0346:                    }
0347:                    case NodeTypes.OPASGNNODE:
0348:                        return opAsgnNode(runtime, context, node, self, aBlock);
0349:                    case NodeTypes.OPASGNORNODE:
0350:                        return opAsgnOrNode(runtime, context, node, self,
0351:                                aBlock);
0352:                    case NodeTypes.OPELEMENTASGNNODE:
0353:                        return opElementAsgnNode(runtime, context, node, self,
0354:                                aBlock);
0355:                    case NodeTypes.OPTNNODE:
0356:                        return optNNode(runtime, context, node, self, aBlock);
0357:                    case NodeTypes.ORNODE:
0358:                        return orNode(runtime, context, node, self, aBlock);
0359:                    case NodeTypes.POSTEXENODE:
0360:                        return postExeNode(runtime, context, node, self, aBlock);
0361:                    case NodeTypes.REDONODE:
0362:                        return redoNode(context, node);
0363:                    case NodeTypes.REGEXPNODE:
0364:                        return regexpNode(runtime, node);
0365:                    case NodeTypes.RESCUEBODYNODE:
0366:                        node = ((RescueBodyNode) node).getBodyNode();
0367:                        continue;
0368:                    case NodeTypes.RESCUENODE:
0369:                        return rescueNode(runtime, context, node, self, aBlock);
0370:                    case NodeTypes.RETRYNODE:
0371:                        return retryNode(context);
0372:                    case NodeTypes.RETURNNODE:
0373:                        return returnNode(runtime, context, node, self, aBlock);
0374:                    case NodeTypes.ROOTNODE:
0375:                        return rootNode(runtime, context, node, self, aBlock);
0376:                    case NodeTypes.SCLASSNODE:
0377:                        return sClassNode(runtime, context, node, self, aBlock);
0378:                    case NodeTypes.SELFNODE:
0379:                        return pollAndReturn(context, self);
0380:                    case NodeTypes.SPLATNODE:
0381:                        return splatNode(runtime, context, node, self, aBlock);
0382:                    case NodeTypes.STRNODE:
0383:                        return strNode(runtime, node);
0384:                    case NodeTypes.SUPERNODE:
0385:                        return super Node(runtime, context, node, self, aBlock);
0386:                    case NodeTypes.SVALUENODE:
0387:                        return sValueNode(runtime, context, node, self, aBlock);
0388:                    case NodeTypes.SYMBOLNODE:
0389:                        return symbolNode(runtime, node);
0390:                    case NodeTypes.TOARYNODE:
0391:                        return toAryNode(runtime, context, node, self, aBlock);
0392:                    case NodeTypes.TRUENODE:
0393:                        return trueNode(runtime, context);
0394:                    case NodeTypes.UNDEFNODE:
0395:                        return undefNode(runtime, context, node);
0396:                    case NodeTypes.UNTILNODE:
0397:                        return untilNode(runtime, context, node, self, aBlock);
0398:                    case NodeTypes.VALIASNODE:
0399:                        return valiasNode(runtime, node);
0400:                    case NodeTypes.VCALLNODE:
0401:                        return vcallNode(runtime, context, node, self);
0402:                    case NodeTypes.WHENNODE:
0403:                        assert false;
0404:                        return null;
0405:                    case NodeTypes.WHILENODE:
0406:                        return whileNode(runtime, context, node, self, aBlock);
0407:                    case NodeTypes.XSTRNODE:
0408:                        return xStrNode(runtime, context, node, self);
0409:                    case NodeTypes.YIELDNODE:
0410:                        return yieldNode(runtime, context, node, self, aBlock);
0411:                    case NodeTypes.ZARRAYNODE:
0412:                        return zArrayNode(runtime);
0413:                    case NodeTypes.ZSUPERNODE:
0414:                        return zsuper Node(runtime, context, node, self, aBlock);
0415:                    default:
0416:                        throw new RuntimeException(
0417:                                "Invalid node encountered in interpreter: \""
0418:                                        + node.getClass().getName()
0419:                                        + "\", please report this at www.jruby.org");
0420:                    }
0421:                } while (true);
0422:            }
0423:
0424:            private static IRubyObject aliasNode(Ruby runtime,
0425:                    ThreadContext context, Node node) {
0426:                AliasNode iVisited = (AliasNode) node;
0427:
0428:                if (context.getRubyClass() == null) {
0429:                    throw runtime.newTypeError("no class to make alias");
0430:                }
0431:
0432:                context.getRubyClass().defineAlias(iVisited.getNewName(),
0433:                        iVisited.getOldName());
0434:                context.getRubyClass().callMethod(context, "method_added",
0435:                        runtime.newSymbol(iVisited.getNewName()));
0436:
0437:                return runtime.getNil();
0438:            }
0439:
0440:            private static IRubyObject argsCatNode(Ruby runtime,
0441:                    ThreadContext context, Node node, IRubyObject self,
0442:                    Block aBlock) {
0443:                ArgsCatNode iVisited = (ArgsCatNode) node;
0444:
0445:                IRubyObject args = evalInternal(runtime, context, iVisited
0446:                        .getFirstNode(), self, aBlock);
0447:                IRubyObject secondArgs = splatValue(runtime, evalInternal(
0448:                        runtime, context, iVisited.getSecondNode(), self,
0449:                        aBlock));
0450:                RubyArray list = args instanceof  RubyArray ? (RubyArray) args
0451:                        : runtime.newArray(args);
0452:
0453:                return list.concat(secondArgs);
0454:            }
0455:
0456:            private static IRubyObject argsPushNode(Ruby runtime,
0457:                    ThreadContext context, Node node, IRubyObject self,
0458:                    Block aBlock) {
0459:                ArgsPushNode iVisited = (ArgsPushNode) node;
0460:
0461:                RubyArray args = (RubyArray) evalInternal(runtime, context,
0462:                        iVisited.getFirstNode(), self, aBlock).dup();
0463:                return args.append(evalInternal(runtime, context, iVisited
0464:                        .getSecondNode(), self, aBlock));
0465:            }
0466:
0467:            private static IRubyObject arrayNode(Ruby runtime,
0468:                    ThreadContext context, Node node, IRubyObject self,
0469:                    Block aBlock) {
0470:                ArrayNode iVisited = (ArrayNode) node;
0471:                IRubyObject[] array = new IRubyObject[iVisited.size()];
0472:
0473:                for (int i = 0; i < iVisited.size(); i++) {
0474:                    Node next = iVisited.get(i);
0475:
0476:                    array[i] = evalInternal(runtime, context, next, self,
0477:                            aBlock);
0478:                }
0479:
0480:                if (iVisited.isLightweight()) {
0481:                    return runtime.newArrayNoCopyLight(array);
0482:                }
0483:
0484:                return runtime.newArrayNoCopy(array);
0485:            }
0486:
0487:            public static RubyArray arrayValue(Ruby runtime, IRubyObject value) {
0488:                IRubyObject newValue = value.convertToType(runtime.getArray(),
0489:                        MethodIndex.TO_ARY, "to_ary", false);
0490:                if (newValue.isNil()) {
0491:                    // Object#to_a is obsolete.  We match Ruby's hack until to_a goes away.  Then we can 
0492:                    // remove this hack too.
0493:                    if (value.getMetaClass().searchMethod("to_a")
0494:                            .getImplementationClass() != runtime.getKernel()) {
0495:                        newValue = value.convertToType(runtime.getArray(),
0496:                                MethodIndex.TO_A, "to_a", false);
0497:                        if (newValue.getType() != runtime.getClass("Array")) {
0498:                            throw runtime
0499:                                    .newTypeError("`to_a' did not return Array");
0500:                        }
0501:                    } else {
0502:                        newValue = runtime.newArray(value);
0503:                    }
0504:                }
0505:
0506:                return (RubyArray) newValue;
0507:            }
0508:
0509:            private static IRubyObject aryToAry(Ruby runtime, IRubyObject value) {
0510:                if (value instanceof  RubyArray)
0511:                    return value;
0512:
0513:                if (value.respondsTo("to_ary")) {
0514:                    return value.convertToType(runtime.getArray(),
0515:                            MethodIndex.TO_A, "to_ary", false);
0516:                }
0517:
0518:                return runtime.newArray(value);
0519:            }
0520:
0521:            private static IRubyObject attrAssignNode(Ruby runtime,
0522:                    ThreadContext context, Node node, IRubyObject self,
0523:                    Block aBlock) {
0524:                AttrAssignNode iVisited = (AttrAssignNode) node;
0525:
0526:                IRubyObject receiver = evalInternal(runtime, context, iVisited
0527:                        .getReceiverNode(), self, aBlock);
0528:                IRubyObject[] args = setupArgs(runtime, context, iVisited
0529:                        .getArgsNode(), self);
0530:
0531:                assert receiver.getMetaClass() != null : receiver.getClass()
0532:                        .getName();
0533:
0534:                // If reciever is self then we do the call the same way as vcall
0535:                CallType callType = (receiver == self ? CallType.VARIABLE
0536:                        : CallType.NORMAL);
0537:
0538:                RubyModule module = receiver.getMetaClass();
0539:
0540:                String name = iVisited.getName();
0541:
0542:                DynamicMethod method = module.searchMethod(name);
0543:
0544:                if (method.isUndefined()
0545:                        || (!method.isCallableFrom(self, callType))) {
0546:                    return RubyObject.callMethodMissing(context, receiver,
0547:                            method, name, args, self, callType,
0548:                            Block.NULL_BLOCK);
0549:                }
0550:
0551:                method.call(context, receiver, module, name, args, false,
0552:                        Block.NULL_BLOCK);
0553:
0554:                return args[args.length - 1];
0555:            }
0556:
0557:            private static IRubyObject backRefNode(ThreadContext context,
0558:                    Node node) {
0559:                BackRefNode iVisited = (BackRefNode) node;
0560:                IRubyObject backref = context.getBackref();
0561:                switch (iVisited.getType()) {
0562:                case '~':
0563:                    return backref;
0564:                case '&':
0565:                    return RubyRegexp.last_match(backref);
0566:                case '`':
0567:                    return RubyRegexp.match_pre(backref);
0568:                case '\'':
0569:                    return RubyRegexp.match_post(backref);
0570:                case '+':
0571:                    return RubyRegexp.match_last(backref);
0572:                default:
0573:                    assert false : "backref with invalid type";
0574:                    return null;
0575:                }
0576:            }
0577:
0578:            private static IRubyObject bignumNode(Ruby runtime, Node node) {
0579:                return RubyBignum.newBignum(runtime, ((BignumNode) node)
0580:                        .getValue());
0581:            }
0582:
0583:            private static IRubyObject blockNode(Ruby runtime,
0584:                    ThreadContext context, Node node, IRubyObject self,
0585:                    Block aBlock) {
0586:                BlockNode iVisited = (BlockNode) node;
0587:
0588:                IRubyObject result = runtime.getNil();
0589:                for (int i = 0; i < iVisited.size(); i++) {
0590:                    result = evalInternal(runtime, context, (Node) iVisited
0591:                            .get(i), self, aBlock);
0592:                }
0593:
0594:                return result;
0595:            }
0596:
0597:            private static IRubyObject breakNode(Ruby runtime,
0598:                    ThreadContext context, Node node, IRubyObject self,
0599:                    Block aBlock) {
0600:                BreakNode iVisited = (BreakNode) node;
0601:
0602:                IRubyObject result = evalInternal(runtime, context, iVisited
0603:                        .getValueNode(), self, aBlock);
0604:
0605:                throw context.prepareJumpException(
0606:                        JumpException.JumpType.BreakJump, null, result);
0607:            }
0608:
0609:            private static IRubyObject callNode(Ruby runtime,
0610:                    ThreadContext context, Node node, IRubyObject self,
0611:                    Block aBlock) {
0612:                CallNode iVisited = (CallNode) node;
0613:
0614:                IRubyObject receiver = evalInternal(runtime, context, iVisited
0615:                        .getReceiverNode(), self, aBlock);
0616:                IRubyObject[] args = setupArgs(runtime, context, iVisited
0617:                        .getArgsNode(), self);
0618:
0619:                assert receiver.getMetaClass() != null : receiver.getClass()
0620:                        .getName();
0621:
0622:                Block block = getBlock(runtime, context, self, aBlock, iVisited
0623:                        .getIterNode());
0624:                RubyModule module = receiver.getMetaClass();
0625:                String name = iVisited.getName();
0626:                int index = iVisited.index;
0627:
0628:                // No block provided lets look at fast path for STI dispatch.
0629:                if (!block.isGiven()) {
0630:                    if (index != 0) {
0631:                        return receiver.callMethod(context, module, index,
0632:                                name, args, CallType.NORMAL, Block.NULL_BLOCK);
0633:                    } else {
0634:                        DynamicMethod method = module.searchMethod(name);
0635:
0636:                        if (method.isUndefined()
0637:                                || (!method.isCallableFrom(self,
0638:                                        CallType.NORMAL))) {
0639:                            return RubyObject.callMethodMissing(context,
0640:                                    receiver, method, name, args, self,
0641:                                    CallType.NORMAL, Block.NULL_BLOCK);
0642:                        }
0643:
0644:                        return method.call(context, receiver, module, name,
0645:                                args, false, Block.NULL_BLOCK);
0646:                    }
0647:                }
0648:
0649:                while (true) {
0650:                    try {
0651:                        DynamicMethod method = module.searchMethod(name);
0652:
0653:                        if (method.isUndefined()
0654:                                || (index != MethodIndex.METHOD_MISSING && !method
0655:                                        .isCallableFrom(self, CallType.NORMAL))) {
0656:                            return RubyObject.callMethodMissing(context,
0657:                                    receiver, method, name, index, args, self,
0658:                                    CallType.NORMAL, block);
0659:                        }
0660:
0661:                        return method.call(context, receiver, module, name,
0662:                                args, false, block);
0663:                    } catch (JumpException je) {
0664:                        switch (je.getJumpType().getTypeId()) {
0665:                        case JumpType.RETRY:
0666:                            // allow loop to retry
0667:                        case JumpType.BREAK:
0668:                            return (IRubyObject) je.getValue();
0669:                        default:
0670:                            throw je;
0671:                        }
0672:                    }
0673:                }
0674:            }
0675:
0676:            private static IRubyObject caseNode(Ruby runtime,
0677:                    ThreadContext context, Node node, IRubyObject self,
0678:                    Block aBlock) {
0679:                CaseNode iVisited = (CaseNode) node;
0680:                IRubyObject expression = null;
0681:                if (iVisited.getCaseNode() != null) {
0682:                    expression = evalInternal(runtime, context, iVisited
0683:                            .getCaseNode(), self, aBlock);
0684:                }
0685:
0686:                context.pollThreadEvents();
0687:
0688:                IRubyObject result = runtime.getNil();
0689:
0690:                Node firstWhenNode = iVisited.getFirstWhenNode();
0691:                while (firstWhenNode != null) {
0692:                    if (!(firstWhenNode instanceof  WhenNode)) {
0693:                        node = firstWhenNode;
0694:                        return evalInternal(runtime, context, node, self,
0695:                                aBlock);
0696:                    }
0697:
0698:                    WhenNode whenNode = (WhenNode) firstWhenNode;
0699:
0700:                    if (whenNode.getExpressionNodes() instanceof  ArrayNode) {
0701:                        ArrayNode arrayNode = (ArrayNode) whenNode
0702:                                .getExpressionNodes();
0703:                        for (int i = 0; i < arrayNode.size(); i++) {
0704:                            Node tag = arrayNode.get(i);
0705:
0706:                            context.setPosition(tag.getPosition());
0707:                            if (isTrace(runtime)) {
0708:                                callTraceFunction(runtime, context,
0709:                                        EventHook.RUBY_EVENT_LINE);
0710:                            }
0711:
0712:                            // Ruby grammar has nested whens in a case body because of
0713:                            // productions case_body and when_args.
0714:                            if (tag instanceof  WhenNode) {
0715:                                RubyArray expressions = (RubyArray) evalInternal(
0716:                                        runtime, context, ((WhenNode) tag)
0717:                                                .getExpressionNodes(), self,
0718:                                        aBlock);
0719:
0720:                                for (int j = 0, k = expressions.getLength(); j < k; j++) {
0721:                                    IRubyObject condition = expressions
0722:                                            .eltInternal(j);
0723:
0724:                                    if ((expression != null && condition
0725:                                            .callMethod(context,
0726:                                                    MethodIndex.OP_EQQ, "===",
0727:                                                    expression).isTrue())
0728:                                            || (expression == null && condition
0729:                                                    .isTrue())) {
0730:                                        node = ((WhenNode) firstWhenNode)
0731:                                                .getBodyNode();
0732:                                        return evalInternal(runtime, context,
0733:                                                node, self, aBlock);
0734:                                    }
0735:                                }
0736:                                continue;
0737:                            }
0738:
0739:                            result = evalInternal(runtime, context, tag, self,
0740:                                    aBlock);
0741:
0742:                            if ((expression != null && result.callMethod(
0743:                                    context, MethodIndex.OP_EQQ, "===",
0744:                                    expression).isTrue())
0745:                                    || (expression == null && result.isTrue())) {
0746:                                node = whenNode.getBodyNode();
0747:                                return evalInternal(runtime, context, node,
0748:                                        self, aBlock);
0749:                            }
0750:                        }
0751:                    } else {
0752:                        result = evalInternal(runtime, context, whenNode
0753:                                .getExpressionNodes(), self, aBlock);
0754:
0755:                        if ((expression != null && result.callMethod(context,
0756:                                MethodIndex.OP_EQQ, "===", expression).isTrue())
0757:                                || (expression == null && result.isTrue())) {
0758:                            node = ((WhenNode) firstWhenNode).getBodyNode();
0759:                            return evalInternal(runtime, context, node, self,
0760:                                    aBlock);
0761:                        }
0762:                    }
0763:
0764:                    context.pollThreadEvents();
0765:
0766:                    firstWhenNode = whenNode.getNextCase();
0767:                }
0768:
0769:                return runtime.getNil();
0770:            }
0771:
0772:            private static IRubyObject classNode(Ruby runtime,
0773:                    ThreadContext context, Node node, IRubyObject self,
0774:                    Block aBlock) {
0775:                ClassNode iVisited = (ClassNode) node;
0776:                Node super Node = iVisited.getSuperNode();
0777:                RubyClass super Class = null;
0778:                if (super Node != null) {
0779:                    IRubyObject _super  = evalInternal(runtime, context,
0780:                            super Node, self, aBlock);
0781:                    if (!(_super  instanceof  RubyClass)) {
0782:                        throw runtime
0783:                                .newTypeError("superclass must be a Class ("
0784:                                        + RubyObject.trueFalseNil(_super )
0785:                                        + ") given");
0786:                    }
0787:                    super Class = super Node == null ? null : (RubyClass) _super ;
0788:                }
0789:                Node classNameNode = iVisited.getCPath();
0790:                String name = ((INameNode) classNameNode).getName();
0791:                RubyModule enclosingClass = getEnclosingModule(runtime,
0792:                        context, classNameNode, self, aBlock);
0793:                RubyClass rubyClass = enclosingClass.defineOrGetClassUnder(
0794:                        name, super Class);
0795:
0796:                return evalClassDefinitionBody(runtime, context, iVisited
0797:                        .getScope(), iVisited.getBodyNode(), rubyClass, self,
0798:                        aBlock);
0799:            }
0800:
0801:            private static IRubyObject classVarAsgnNode(Ruby runtime,
0802:                    ThreadContext context, Node node, IRubyObject self,
0803:                    Block aBlock) {
0804:                ClassVarAsgnNode iVisited = (ClassVarAsgnNode) node;
0805:                IRubyObject result = evalInternal(runtime, context, iVisited
0806:                        .getValueNode(), self, aBlock);
0807:                RubyModule rubyClass = getClassVariableBase(context, runtime);
0808:
0809:                if (rubyClass == null) {
0810:                    rubyClass = self.getMetaClass();
0811:                }
0812:                rubyClass.setClassVar(iVisited.getName(), result);
0813:
0814:                return result;
0815:            }
0816:
0817:            private static IRubyObject classVarDeclNode(Ruby runtime,
0818:                    ThreadContext context, Node node, IRubyObject self,
0819:                    Block aBlock) {
0820:                ClassVarDeclNode iVisited = (ClassVarDeclNode) node;
0821:
0822:                RubyModule rubyClass = getClassVariableBase(context, runtime);
0823:                if (rubyClass == null) {
0824:                    throw runtime
0825:                            .newTypeError("no class/module to define class variable");
0826:                }
0827:                IRubyObject result = evalInternal(runtime, context, iVisited
0828:                        .getValueNode(), self, aBlock);
0829:                rubyClass.setClassVar(iVisited.getName(), result);
0830:
0831:                return result;
0832:            }
0833:
0834:            private static IRubyObject classVarNode(Ruby runtime,
0835:                    ThreadContext context, Node node, IRubyObject self) {
0836:                ClassVarNode iVisited = (ClassVarNode) node;
0837:                RubyModule rubyClass = getClassVariableBase(context, runtime);
0838:
0839:                if (rubyClass == null) {
0840:                    rubyClass = self.getMetaClass();
0841:                }
0842:
0843:                return rubyClass.getClassVar(iVisited.getName());
0844:            }
0845:
0846:            private static IRubyObject colon2Node(Ruby runtime,
0847:                    ThreadContext context, Node node, IRubyObject self,
0848:                    Block aBlock) {
0849:                Colon2Node iVisited = (Colon2Node) node;
0850:                Node leftNode = iVisited.getLeftNode();
0851:                // TODO: Made this more colon3 friendly because of cpath production
0852:                // rule in grammar (it is convenient to think of them as the same thing
0853:                // at a grammar level even though evaluation is).
0854:                if (leftNode == null) {
0855:                    return runtime.getObject().getConstantFrom(
0856:                            iVisited.getName());
0857:                } else {
0858:                    IRubyObject result = evalInternal(runtime, context,
0859:                            iVisited.getLeftNode(), self, aBlock);
0860:                    if (result instanceof  RubyModule) {
0861:                        return ((RubyModule) result).getConstantFrom(iVisited
0862:                                .getName());
0863:                    } else {
0864:                        return result.callMethod(context, iVisited.getName(),
0865:                                aBlock);
0866:                    }
0867:                }
0868:            }
0869:
0870:            private static IRubyObject colon3Node(Ruby runtime, Node node) {
0871:                return runtime.getObject().getConstantFrom(
0872:                        ((Colon3Node) node).getName());
0873:            }
0874:
0875:            private static IRubyObject constDeclNode(Ruby runtime,
0876:                    ThreadContext context, Node node, IRubyObject self,
0877:                    Block aBlock) {
0878:                ConstDeclNode iVisited = (ConstDeclNode) node;
0879:                Node constNode = iVisited.getConstNode();
0880:
0881:                IRubyObject result = evalInternal(runtime, context, iVisited
0882:                        .getValueNode(), self, aBlock);
0883:
0884:                if (constNode == null) {
0885:                    return context.setConstantInCurrent(iVisited.getName(),
0886:                            result);
0887:                } else if (constNode.nodeId == NodeTypes.COLON2NODE) {
0888:                    RubyModule module = (RubyModule) evalInternal(runtime,
0889:                            context, ((Colon2Node) iVisited.getConstNode())
0890:                                    .getLeftNode(), self, aBlock);
0891:                    return context.setConstantInModule(iVisited.getName(),
0892:                            module, result);
0893:                } else { // colon3
0894:                    return context.setConstantInObject(iVisited.getName(),
0895:                            result);
0896:                }
0897:            }
0898:
0899:            private static IRubyObject constNode(ThreadContext context,
0900:                    Node node) {
0901:                return context.getConstant(((ConstNode) node).getName());
0902:            }
0903:
0904:            private static IRubyObject dAsgnNode(Ruby runtime,
0905:                    ThreadContext context, Node node, IRubyObject self,
0906:                    Block aBlock) {
0907:                DAsgnNode iVisited = (DAsgnNode) node;
0908:
0909:                IRubyObject result = evalInternal(runtime, context, iVisited
0910:                        .getValueNode(), self, aBlock);
0911:
0912:                // System.out.println("DSetting: " + iVisited.getName() + " at index " + iVisited.getIndex() + " and at depth " + iVisited.getDepth() + " and set " + result);
0913:                context.getCurrentScope().setValue(iVisited.getIndex(), result,
0914:                        iVisited.getDepth());
0915:
0916:                return result;
0917:            }
0918:
0919:            private static IRubyObject definedNode(Ruby runtime,
0920:                    ThreadContext context, Node node, IRubyObject self,
0921:                    Block aBlock) {
0922:                DefinedNode iVisited = (DefinedNode) node;
0923:                String definition = getDefinition(runtime, context, iVisited
0924:                        .getExpressionNode(), self, aBlock);
0925:                if (definition != null) {
0926:                    return runtime.newString(definition);
0927:                } else {
0928:                    return runtime.getNil();
0929:                }
0930:            }
0931:
0932:            private static IRubyObject defnNode(Ruby runtime,
0933:                    ThreadContext context, Node node) {
0934:                DefnNode iVisited = (DefnNode) node;
0935:
0936:                RubyModule containingClass = context.getRubyClass();
0937:
0938:                if (containingClass == null) {
0939:                    throw runtime.newTypeError("No class to add method.");
0940:                }
0941:
0942:                String name = iVisited.getName();
0943:
0944:                if (containingClass == runtime.getObject()
0945:                        && name == "initialize") {
0946:                    runtime
0947:                            .getWarnings()
0948:                            .warn(
0949:                                    "redefining Object#initialize may cause infinite loop");
0950:                }
0951:
0952:                Visibility visibility = context.getCurrentVisibility();
0953:                if (name == "initialize" || visibility.isModuleFunction()
0954:                        || context.isTopLevel()) {
0955:                    visibility = Visibility.PRIVATE;
0956:                }
0957:
0958:                DefaultMethod newMethod = new DefaultMethod(containingClass,
0959:                        iVisited.getScope(), iVisited.getBodyNode(),
0960:                        (ArgsNode) iVisited.getArgsNode(), visibility, context
0961:                                .peekCRef());
0962:
0963:                containingClass.addMethod(name, newMethod);
0964:
0965:                if (context.getCurrentVisibility().isModuleFunction()) {
0966:                    containingClass.getSingletonClass().addMethod(
0967:                            name,
0968:                            new WrapperMethod(containingClass
0969:                                    .getSingletonClass(), newMethod,
0970:                                    Visibility.PUBLIC));
0971:                    containingClass.callMethod(context,
0972:                            "singleton_method_added", runtime.newSymbol(name));
0973:                }
0974:
0975:                // 'class << state.self' and 'class << obj' uses defn as opposed to defs
0976:                if (containingClass.isSingleton()) {
0977:                    ((MetaClass) containingClass).getAttachedObject()
0978:                            .callMethod(context, "singleton_method_added",
0979:                                    runtime.newSymbol(iVisited.getName()));
0980:                } else {
0981:                    containingClass.callMethod(context, "method_added", runtime
0982:                            .newSymbol(name));
0983:                }
0984:
0985:                return runtime.getNil();
0986:            }
0987:
0988:            private static IRubyObject defsNode(Ruby runtime,
0989:                    ThreadContext context, Node node, IRubyObject self,
0990:                    Block aBlock) {
0991:                DefsNode iVisited = (DefsNode) node;
0992:                IRubyObject receiver = evalInternal(runtime, context, iVisited
0993:                        .getReceiverNode(), self, aBlock);
0994:
0995:                RubyClass rubyClass;
0996:
0997:                if (receiver.isNil()) {
0998:                    rubyClass = runtime.getNilClass();
0999:                } else if (receiver == runtime.getTrue()) {
1000:                    rubyClass = runtime.getClass("TrueClass");
1001:                } else if (receiver == runtime.getFalse()) {
1002:                    rubyClass = runtime.getClass("FalseClass");
1003:                } else {
1004:                    if (runtime.getSafeLevel() >= 4 && !receiver.isTaint()) {
1005:                        throw runtime
1006:                                .newSecurityError("Insecure; can't define singleton method.");
1007:                    }
1008:                    if (receiver.isFrozen()) {
1009:                        throw runtime.newFrozenError("object");
1010:                    }
1011:                    if (receiver.getMetaClass() == runtime.getFixnum()
1012:                            || receiver.getMetaClass() == runtime
1013:                                    .getClass("Symbol")) {
1014:                        throw runtime
1015:                                .newTypeError("can't define singleton method \""
1016:                                        + iVisited.getName()
1017:                                        + "\" for "
1018:                                        + receiver.getType());
1019:                    }
1020:
1021:                    rubyClass = receiver.getSingletonClass();
1022:                }
1023:
1024:                if (runtime.getSafeLevel() >= 4) {
1025:                    Object method = rubyClass.getMethods().get(
1026:                            iVisited.getName());
1027:                    if (method != null) {
1028:                        throw runtime
1029:                                .newSecurityError("Redefining method prohibited.");
1030:                    }
1031:                }
1032:
1033:                DefaultMethod newMethod = new DefaultMethod(rubyClass, iVisited
1034:                        .getScope(), iVisited.getBodyNode(),
1035:                        (ArgsNode) iVisited.getArgsNode(), Visibility.PUBLIC,
1036:                        context.peekCRef());
1037:
1038:                rubyClass.addMethod(iVisited.getName(), newMethod);
1039:                receiver.callMethod(context, "singleton_method_added", runtime
1040:                        .newSymbol(iVisited.getName()));
1041:
1042:                return runtime.getNil();
1043:            }
1044:
1045:            private static IRubyObject dotNode(Ruby runtime,
1046:                    ThreadContext context, Node node, IRubyObject self,
1047:                    Block aBlock) {
1048:                DotNode iVisited = (DotNode) node;
1049:                return RubyRange.newRange(runtime, evalInternal(runtime,
1050:                        context, iVisited.getBeginNode(), self, aBlock),
1051:                        evalInternal(runtime, context, iVisited.getEndNode(),
1052:                                self, aBlock), iVisited.isExclusive());
1053:            }
1054:
1055:            private static IRubyObject dregexpNode(Ruby runtime,
1056:                    ThreadContext context, Node node, IRubyObject self,
1057:                    Block aBlock) {
1058:                DRegexpNode iVisited = (DRegexpNode) node;
1059:
1060:                RubyString string = runtime.newString(new ByteList());
1061:                for (int i = 0; i < iVisited.size(); i++) {
1062:                    Node iterNode = iVisited.get(i);
1063:                    if (iterNode instanceof  StrNode) {
1064:                        string.getByteList().append(
1065:                                ((StrNode) iterNode).getValue());
1066:                    } else {
1067:                        string.append(evalInternal(runtime, context, iterNode,
1068:                                self, aBlock));
1069:                    }
1070:                }
1071:
1072:                String lang = null;
1073:                int opts = iVisited.getOptions();
1074:                if ((opts & 16) != 0) { // param n
1075:                    lang = "n";
1076:                } else if ((opts & 48) != 0) { // param s
1077:                    lang = "s";
1078:                } else if ((opts & 64) != 0) { // param s
1079:                    lang = "u";
1080:                }
1081:
1082:                try {
1083:                    return RubyRegexp.newRegexp(runtime, string.toString(),
1084:                            iVisited.getOptions(), lang);
1085:                } catch (jregex.PatternSyntaxException e) {
1086:                    //                    System.err.println(iVisited.getValue().toString());
1087:                    //                    e.printStackTrace();
1088:                    throw runtime.newRegexpError(e.getMessage());
1089:                }
1090:            }
1091:
1092:            private static IRubyObject dStrNode(Ruby runtime,
1093:                    ThreadContext context, Node node, IRubyObject self,
1094:                    Block aBlock) {
1095:                DStrNode iVisited = (DStrNode) node;
1096:
1097:                RubyString string = runtime.newString(new ByteList());
1098:                for (int i = 0; i < iVisited.size(); i++) {
1099:                    Node iterNode = iVisited.get(i);
1100:                    if (iterNode instanceof  StrNode) {
1101:                        string.getByteList().append(
1102:                                ((StrNode) iterNode).getValue());
1103:                    } else {
1104:                        string.append(evalInternal(runtime, context, iterNode,
1105:                                self, aBlock));
1106:                    }
1107:                }
1108:
1109:                return string;
1110:            }
1111:
1112:            private static IRubyObject dSymbolNode(Ruby runtime,
1113:                    ThreadContext context, Node node, IRubyObject self,
1114:                    Block aBlock) {
1115:                DSymbolNode iVisited = (DSymbolNode) node;
1116:
1117:                RubyString string = runtime.newString(new ByteList());
1118:                for (int i = 0; i < iVisited.size(); i++) {
1119:                    Node iterNode = iVisited.get(i);
1120:                    if (iterNode instanceof  StrNode) {
1121:                        string.getByteList().append(
1122:                                ((StrNode) iterNode).getValue());
1123:                    } else {
1124:                        string.append(evalInternal(runtime, context, iterNode,
1125:                                self, aBlock));
1126:                    }
1127:                }
1128:
1129:                return runtime.newSymbol(string.toString());
1130:            }
1131:
1132:            private static IRubyObject dVarNode(Ruby runtime,
1133:                    ThreadContext context, Node node) {
1134:                DVarNode iVisited = (DVarNode) node;
1135:
1136:                // System.out.println("DGetting: " + iVisited.getName() + " at index " + iVisited.getIndex() + " and at depth " + iVisited.getDepth());
1137:                IRubyObject obj = context.getCurrentScope().getValue(
1138:                        iVisited.getIndex(), iVisited.getDepth());
1139:
1140:                // FIXME: null check is removable once we figure out how to assign to unset named block args
1141:                return obj == null ? runtime.getNil() : obj;
1142:            }
1143:
1144:            private static IRubyObject dXStrNode(Ruby runtime,
1145:                    ThreadContext context, Node node, IRubyObject self,
1146:                    Block aBlock) {
1147:                DXStrNode iVisited = (DXStrNode) node;
1148:
1149:                RubyString string = runtime.newString(new ByteList());
1150:                for (int i = 0; i < iVisited.size(); i++) {
1151:                    Node iterNode = iVisited.get(i);
1152:                    if (iterNode instanceof  StrNode) {
1153:                        string.getByteList().append(
1154:                                ((StrNode) iterNode).getValue());
1155:                    } else {
1156:                        string.append(evalInternal(runtime, context, iterNode,
1157:                                self, aBlock));
1158:                    }
1159:                }
1160:
1161:                return self.callMethod(context, "`", string);
1162:            }
1163:
1164:            private static IRubyObject ensureNode(Ruby runtime,
1165:                    ThreadContext context, Node node, IRubyObject self,
1166:                    Block aBlock) {
1167:                EnsureNode iVisited = (EnsureNode) node;
1168:
1169:                // save entering the try if there's nothing to ensure
1170:                if (iVisited.getEnsureNode() != null) {
1171:                    IRubyObject result = runtime.getNil();
1172:
1173:                    try {
1174:                        result = evalInternal(runtime, context, iVisited
1175:                                .getBodyNode(), self, aBlock);
1176:                    } finally {
1177:                        evalInternal(runtime, context,
1178:                                iVisited.getEnsureNode(), self, aBlock);
1179:                    }
1180:
1181:                    return result;
1182:                }
1183:
1184:                node = iVisited.getBodyNode();
1185:                return evalInternal(runtime, context, node, self, aBlock);
1186:            }
1187:
1188:            private static IRubyObject evStrNode(Ruby runtime,
1189:                    ThreadContext context, Node node, IRubyObject self,
1190:                    Block aBlock) {
1191:                return evalInternal(runtime, context,
1192:                        ((EvStrNode) node).getBody(), self, aBlock).asString();
1193:            }
1194:
1195:            private static IRubyObject falseNode(Ruby runtime,
1196:                    ThreadContext context) {
1197:                return pollAndReturn(context, runtime.getFalse());
1198:            }
1199:
1200:            private static IRubyObject fCallNode(Ruby runtime,
1201:                    ThreadContext context, Node node, IRubyObject self,
1202:                    Block aBlock) {
1203:                FCallNode iVisited = (FCallNode) node;
1204:
1205:                IRubyObject[] args = setupArgs(runtime, context, iVisited
1206:                        .getArgsNode(), self);
1207:                Block block = getBlock(runtime, context, self, aBlock, iVisited
1208:                        .getIterNode());
1209:
1210:                String name = iVisited.getName();
1211:                int index = iVisited.index;
1212:
1213:                // No block provided lets look at fast path for STI dispatch.
1214:                if (!block.isGiven()) {
1215:                    RubyModule module = self.getMetaClass();
1216:                    if (module.index != 0 && index != 0) {
1217:                        return self.callMethod(context, module, iVisited.index,
1218:                                name, args, CallType.FUNCTIONAL,
1219:                                Block.NULL_BLOCK);
1220:                    } else {
1221:                        DynamicMethod method = module.searchMethod(name);
1222:                        if (method.isUndefined()
1223:                                || (!method.isCallableFrom(self,
1224:                                        CallType.FUNCTIONAL))) {
1225:                            return RubyObject.callMethodMissing(context, self,
1226:                                    method, name, args, self,
1227:                                    CallType.FUNCTIONAL, Block.NULL_BLOCK);
1228:                        }
1229:
1230:                        return method.call(context, self, module, name, args,
1231:                                false, Block.NULL_BLOCK);
1232:                    }
1233:                }
1234:
1235:                while (true) {
1236:                    try {
1237:                        RubyModule module = self.getMetaClass();
1238:                        IRubyObject result = self.callMethod(context, module,
1239:                                name, args, CallType.FUNCTIONAL, block);
1240:                        if (result == null) {
1241:                            result = runtime.getNil();
1242:                        }
1243:
1244:                        return result;
1245:                    } catch (JumpException je) {
1246:                        switch (je.getJumpType().getTypeId()) {
1247:                        case JumpType.RETRY:
1248:                            // allow loop to retry
1249:                            break;
1250:                        case JumpType.BREAK:
1251:                            // JRUBY-530, Kernel#loop case:
1252:                            if (je.isBreakInKernelLoop()) {
1253:                                // consume and rethrow or just keep rethrowing?
1254:                                if (block == je.getTarget())
1255:                                    je.setBreakInKernelLoop(false);
1256:
1257:                                throw je;
1258:                            }
1259:
1260:                            return (IRubyObject) je.getValue();
1261:                        default:
1262:                            throw je;
1263:                        }
1264:                    }
1265:                }
1266:            }
1267:
1268:            private static IRubyObject fixnumNode(Ruby runtime, Node node) {
1269:                return ((FixnumNode) node).getFixnum(runtime);
1270:            }
1271:
1272:            private static IRubyObject flipNode(Ruby runtime,
1273:                    ThreadContext context, Node node, IRubyObject self,
1274:                    Block aBlock) {
1275:                FlipNode iVisited = (FlipNode) node;
1276:                IRubyObject result = runtime.getNil();
1277:
1278:                if (iVisited.isExclusive()) {
1279:                    if (!context.getCurrentScope().getValue(
1280:                            iVisited.getIndex(), iVisited.getDepth()).isTrue()) {
1281:                        result = evalInternal(runtime, context,
1282:                                iVisited.getBeginNode(), self, aBlock).isTrue() ? runtime
1283:                                .getFalse()
1284:                                : runtime.getTrue();
1285:                        context.getCurrentScope().setValue(iVisited.getIndex(),
1286:                                result, iVisited.getDepth());
1287:                        return result;
1288:                    } else {
1289:                        if (evalInternal(runtime, context,
1290:                                iVisited.getEndNode(), self, aBlock).isTrue()) {
1291:                            context.getCurrentScope().setValue(
1292:                                    iVisited.getIndex(), runtime.getFalse(),
1293:                                    iVisited.getDepth());
1294:                        }
1295:                        return runtime.getTrue();
1296:                    }
1297:                } else {
1298:                    if (!context.getCurrentScope().getValue(
1299:                            iVisited.getIndex(), iVisited.getDepth()).isTrue()) {
1300:                        if (evalInternal(runtime, context,
1301:                                iVisited.getBeginNode(), self, aBlock).isTrue()) {
1302:                            context
1303:                                    .getCurrentScope()
1304:                                    .setValue(
1305:                                            iVisited.getIndex(),
1306:                                            evalInternal(runtime, context,
1307:                                                    iVisited.getEndNode(),
1308:                                                    self, aBlock).isTrue() ? runtime
1309:                                                    .getFalse()
1310:                                                    : runtime.getTrue(),
1311:                                            iVisited.getDepth());
1312:                            return runtime.getTrue();
1313:                        } else {
1314:                            return runtime.getFalse();
1315:                        }
1316:                    } else {
1317:                        if (evalInternal(runtime, context,
1318:                                iVisited.getEndNode(), self, aBlock).isTrue()) {
1319:                            context.getCurrentScope().setValue(
1320:                                    iVisited.getIndex(), runtime.getFalse(),
1321:                                    iVisited.getDepth());
1322:                        }
1323:                        return runtime.getTrue();
1324:                    }
1325:                }
1326:            }
1327:
1328:            private static IRubyObject floatNode(Ruby runtime, Node node) {
1329:                return RubyFloat.newFloat(runtime, ((FloatNode) node)
1330:                        .getValue());
1331:            }
1332:
1333:            private static IRubyObject forNode(Ruby runtime,
1334:                    ThreadContext context, Node node, IRubyObject self,
1335:                    Block aBlock) {
1336:                ForNode iVisited = (ForNode) node;
1337:
1338:                Block block = SharedScopeBlock.createSharedScopeBlock(context,
1339:                        iVisited, context.getCurrentScope(), self);
1340:
1341:                try {
1342:                    while (true) {
1343:                        try {
1344:                            ISourcePosition position = context.getPosition();
1345:
1346:                            IRubyObject recv = null;
1347:                            try {
1348:                                recv = evalInternal(runtime, context, iVisited
1349:                                        .getIterNode(), self, aBlock);
1350:                            } finally {
1351:                                context.setPosition(position);
1352:                            }
1353:
1354:                            return recv.callMethod(context, "each",
1355:                                    IRubyObject.NULL_ARRAY, CallType.NORMAL,
1356:                                    block);
1357:                        } catch (JumpException je) {
1358:                            switch (je.getJumpType().getTypeId()) {
1359:                            case JumpType.RETRY:
1360:                                // do nothing, allow loop to retry
1361:                                break;
1362:                            default:
1363:                                throw je;
1364:                            }
1365:                        }
1366:                    }
1367:                } catch (JumpException je) {
1368:                    switch (je.getJumpType().getTypeId()) {
1369:                    case JumpType.BREAK:
1370:                        return (IRubyObject) je.getValue();
1371:                    default:
1372:                        throw je;
1373:                    }
1374:                }
1375:            }
1376:
1377:            private static IRubyObject globalAsgnNode(Ruby runtime,
1378:                    ThreadContext context, Node node, IRubyObject self,
1379:                    Block aBlock) {
1380:                GlobalAsgnNode iVisited = (GlobalAsgnNode) node;
1381:
1382:                IRubyObject result = evalInternal(runtime, context, iVisited
1383:                        .getValueNode(), self, aBlock);
1384:
1385:                if (iVisited.getName().length() == 2) {
1386:                    switch (iVisited.getName().charAt(1)) {
1387:                    case '_':
1388:                        context.getCurrentScope().setLastLine(result);
1389:                        return result;
1390:                    case '~':
1391:                        context.setBackref(result);
1392:                        return result;
1393:                    }
1394:                }
1395:
1396:                runtime.getGlobalVariables().set(iVisited.getName(), result);
1397:
1398:                // FIXME: this should be encapsulated along with the set above
1399:                if (iVisited.getName() == "$KCODE") {
1400:                    runtime.setKCode(KCode.create(runtime, result.toString()));
1401:                }
1402:
1403:                return result;
1404:            }
1405:
1406:            private static IRubyObject globalVarNode(Ruby runtime,
1407:                    ThreadContext context, Node node) {
1408:                GlobalVarNode iVisited = (GlobalVarNode) node;
1409:
1410:                if (iVisited.getName().length() == 2) {
1411:                    IRubyObject value = null;
1412:                    switch (iVisited.getName().charAt(1)) {
1413:                    case '_':
1414:                        value = context.getCurrentScope().getLastLine();
1415:                        if (value == null) {
1416:                            return runtime.getNil();
1417:                        }
1418:                        return value;
1419:                    case '~':
1420:                        value = context.getCurrentScope().getBackRef();
1421:                        if (value == null) {
1422:                            return runtime.getNil();
1423:                        }
1424:                        return value;
1425:                    }
1426:                }
1427:
1428:                return runtime.getGlobalVariables().get(iVisited.getName());
1429:            }
1430:
1431:            private static IRubyObject hashNode(Ruby runtime,
1432:                    ThreadContext context, Node node, IRubyObject self,
1433:                    Block aBlock) {
1434:                HashNode iVisited = (HashNode) node;
1435:
1436:                RubyHash hash = null;
1437:                if (iVisited.getListNode() != null) {
1438:                    hash = RubyHash.newHash(runtime);
1439:
1440:                    for (int i = 0; i < iVisited.getListNode().size();) {
1441:                        // insert all nodes in sequence, hash them in the final instruction
1442:                        // KEY
1443:                        IRubyObject key = evalInternal(runtime, context,
1444:                                iVisited.getListNode().get(i++), self, aBlock);
1445:                        IRubyObject value = evalInternal(runtime, context,
1446:                                iVisited.getListNode().get(i++), self, aBlock);
1447:
1448:                        hash.fastASet(key, value);
1449:                    }
1450:                }
1451:
1452:                if (hash == null) {
1453:                    return RubyHash.newHash(runtime);
1454:                }
1455:
1456:                return hash;
1457:            }
1458:
1459:            private static IRubyObject instAsgnNode(Ruby runtime,
1460:                    ThreadContext context, Node node, IRubyObject self,
1461:                    Block aBlock) {
1462:                InstAsgnNode iVisited = (InstAsgnNode) node;
1463:
1464:                IRubyObject result = evalInternal(runtime, context, iVisited
1465:                        .getValueNode(), self, aBlock);
1466:                self.setInstanceVariable(iVisited.getName(), result);
1467:
1468:                return result;
1469:            }
1470:
1471:            private static IRubyObject instVarNode(Ruby runtime, Node node,
1472:                    IRubyObject self) {
1473:                InstVarNode iVisited = (InstVarNode) node;
1474:                IRubyObject variable = self.getInstanceVariable(iVisited
1475:                        .getName());
1476:
1477:                return variable == null ? runtime.getNil() : variable;
1478:            }
1479:
1480:            private static IRubyObject localAsgnNode(Ruby runtime,
1481:                    ThreadContext context, Node node, IRubyObject self,
1482:                    Block aBlock) {
1483:                LocalAsgnNode iVisited = (LocalAsgnNode) node;
1484:                IRubyObject result = evalInternal(runtime, context, iVisited
1485:                        .getValueNode(), self, aBlock);
1486:
1487:                //System.out.println("LSetting: " + iVisited.getName() + " at index " + iVisited.getIndex() + " and at depth " + iVisited.getDepth() + " and set " + result);
1488:                context.getCurrentScope().setValue(iVisited.getIndex(), result,
1489:                        iVisited.getDepth());
1490:
1491:                return result;
1492:            }
1493:
1494:            private static IRubyObject localVarNode(Ruby runtime,
1495:                    ThreadContext context, Node node) {
1496:                LocalVarNode iVisited = (LocalVarNode) node;
1497:
1498:                //        System.out.println("DGetting: " + iVisited.getName() + " at index " + iVisited.getIndex() + " and at depth " + iVisited.getDepth());
1499:                IRubyObject result = context.getCurrentScope().getValue(
1500:                        iVisited.getIndex(), iVisited.getDepth());
1501:
1502:                return result == null ? runtime.getNil() : result;
1503:            }
1504:
1505:            private static IRubyObject match2Node(Ruby runtime,
1506:                    ThreadContext context, Node node, IRubyObject self,
1507:                    Block aBlock) {
1508:                Match2Node iVisited = (Match2Node) node;
1509:                IRubyObject recv = evalInternal(runtime, context, iVisited
1510:                        .getReceiverNode(), self, aBlock);
1511:                IRubyObject value = evalInternal(runtime, context, iVisited
1512:                        .getValueNode(), self, aBlock);
1513:
1514:                return ((RubyRegexp) recv).match(value);
1515:            }
1516:
1517:            private static IRubyObject match3Node(Ruby runtime,
1518:                    ThreadContext context, Node node, IRubyObject self,
1519:                    Block aBlock) {
1520:                Match3Node iVisited = (Match3Node) node;
1521:                IRubyObject recv = evalInternal(runtime, context, iVisited
1522:                        .getReceiverNode(), self, aBlock);
1523:                IRubyObject value = evalInternal(runtime, context, iVisited
1524:                        .getValueNode(), self, aBlock);
1525:
1526:                if (value instanceof  RubyString) {
1527:                    return ((RubyRegexp) recv).match(value);
1528:                } else {
1529:                    return value.callMethod(context, "=~", recv);
1530:                }
1531:            }
1532:
1533:            private static IRubyObject matchNode(Ruby runtime,
1534:                    ThreadContext context, Node node, IRubyObject self,
1535:                    Block aBlock) {
1536:                return ((RubyRegexp) evalInternal(runtime, context,
1537:                        ((MatchNode) node).getRegexpNode(), self, aBlock))
1538:                        .match2();
1539:            }
1540:
1541:            private static IRubyObject moduleNode(Ruby runtime,
1542:                    ThreadContext context, Node node, IRubyObject self,
1543:                    Block aBlock) {
1544:                ModuleNode iVisited = (ModuleNode) node;
1545:                Node classNameNode = iVisited.getCPath();
1546:                String name = ((INameNode) classNameNode).getName();
1547:                RubyModule enclosingModule = getEnclosingModule(runtime,
1548:                        context, classNameNode, self, aBlock);
1549:
1550:                if (enclosingModule == null) {
1551:                    throw runtime.newTypeError("no outer class/module");
1552:                }
1553:
1554:                RubyModule module;
1555:                if (enclosingModule == runtime.getObject()) {
1556:                    module = runtime.getOrCreateModule(name);
1557:                } else {
1558:                    module = enclosingModule.defineModuleUnder(name);
1559:                }
1560:                return evalClassDefinitionBody(runtime, context, iVisited
1561:                        .getScope(), iVisited.getBodyNode(), module, self,
1562:                        aBlock);
1563:            }
1564:
1565:            private static IRubyObject multipleAsgnNode(Ruby runtime,
1566:                    ThreadContext context, Node node, IRubyObject self,
1567:                    Block aBlock) {
1568:                MultipleAsgnNode iVisited = (MultipleAsgnNode) node;
1569:
1570:                switch (iVisited.getValueNode().nodeId) {
1571:                case NodeTypes.ARRAYNODE: {
1572:                    ArrayNode iVisited2 = (ArrayNode) iVisited.getValueNode();
1573:                    IRubyObject[] array = new IRubyObject[iVisited2.size()];
1574:
1575:                    for (int i = 0; i < iVisited2.size(); i++) {
1576:                        Node next = iVisited2.get(i);
1577:
1578:                        array[i] = evalInternal(runtime, context, next, self,
1579:                                aBlock);
1580:                    }
1581:                    return AssignmentVisitor.multiAssign(runtime, context,
1582:                            self, iVisited, RubyArray.newArrayNoCopyLight(
1583:                                    runtime, array), false);
1584:                }
1585:                case NodeTypes.SPLATNODE: {
1586:                    SplatNode splatNode = (SplatNode) iVisited.getValueNode();
1587:                    RubyArray rubyArray = splatValue(runtime, evalInternal(
1588:                            runtime, context, ((SplatNode) splatNode)
1589:                                    .getValue(), self, aBlock));
1590:                    return AssignmentVisitor.multiAssign(runtime, context,
1591:                            self, iVisited, rubyArray, false);
1592:                }
1593:                default:
1594:                    IRubyObject value = evalInternal(runtime, context, iVisited
1595:                            .getValueNode(), self, aBlock);
1596:
1597:                    if (!(value instanceof  RubyArray)) {
1598:                        value = RubyArray.newArray(runtime, value);
1599:                    }
1600:
1601:                    return AssignmentVisitor.multiAssign(runtime, context,
1602:                            self, iVisited, (RubyArray) value, false);
1603:                }
1604:            }
1605:
1606:            private static IRubyObject nextNode(Ruby runtime,
1607:                    ThreadContext context, Node node, IRubyObject self,
1608:                    Block aBlock) {
1609:                NextNode iVisited = (NextNode) node;
1610:
1611:                context.pollThreadEvents();
1612:
1613:                IRubyObject result = evalInternal(runtime, context, iVisited
1614:                        .getValueNode(), self, aBlock);
1615:
1616:                // now used as an interpreter event
1617:                throw context.prepareJumpException(
1618:                        JumpException.JumpType.NextJump, iVisited, result);
1619:            }
1620:
1621:            private static IRubyObject nilNode(Ruby runtime,
1622:                    ThreadContext context) {
1623:                return pollAndReturn(context, runtime.getNil());
1624:            }
1625:
1626:            private static IRubyObject notNode(Ruby runtime,
1627:                    ThreadContext context, Node node, IRubyObject self,
1628:                    Block aBlock) {
1629:                NotNode iVisited = (NotNode) node;
1630:
1631:                IRubyObject result = evalInternal(runtime, context, iVisited
1632:                        .getConditionNode(), self, aBlock);
1633:                return result.isTrue() ? runtime.getFalse() : runtime.getTrue();
1634:            }
1635:
1636:            private static IRubyObject nthRefNode(ThreadContext context,
1637:                    Node node) {
1638:                return RubyRegexp.nth_match(((NthRefNode) node)
1639:                        .getMatchNumber(), context.getBackref());
1640:            }
1641:
1642:            private static IRubyObject pollAndReturn(ThreadContext context,
1643:                    IRubyObject result) {
1644:                context.pollThreadEvents();
1645:                return result;
1646:            }
1647:
1648:            private static IRubyObject opAsgnNode(Ruby runtime,
1649:                    ThreadContext context, Node node, IRubyObject self,
1650:                    Block aBlock) {
1651:                OpAsgnNode iVisited = (OpAsgnNode) node;
1652:                IRubyObject receiver = evalInternal(runtime, context, iVisited
1653:                        .getReceiverNode(), self, aBlock);
1654:                IRubyObject value = receiver.callMethod(context, iVisited
1655:                        .getVariableName());
1656:
1657:                if (iVisited.getOperatorName() == "||") {
1658:                    if (value.isTrue()) {
1659:                        return pollAndReturn(context, value);
1660:                    }
1661:                    value = evalInternal(runtime, context, iVisited
1662:                            .getValueNode(), self, aBlock);
1663:                } else if (iVisited.getOperatorName() == "&&") {
1664:                    if (!value.isTrue()) {
1665:                        return pollAndReturn(context, value);
1666:                    }
1667:                    value = evalInternal(runtime, context, iVisited
1668:                            .getValueNode(), self, aBlock);
1669:                } else {
1670:                    value = value.callMethod(context, iVisited.index, iVisited
1671:                            .getOperatorName(), evalInternal(runtime, context,
1672:                            iVisited.getValueNode(), self, aBlock));
1673:                }
1674:
1675:                receiver.callMethod(context, iVisited.getVariableNameAsgn(),
1676:                        value);
1677:
1678:                return pollAndReturn(context, value);
1679:            }
1680:
1681:            private static IRubyObject opAsgnOrNode(Ruby runtime,
1682:                    ThreadContext context, Node node, IRubyObject self,
1683:                    Block aBlock) {
1684:                OpAsgnOrNode iVisited = (OpAsgnOrNode) node;
1685:                String def = getDefinition(runtime, context, iVisited
1686:                        .getFirstNode(), self, aBlock);
1687:
1688:                IRubyObject result = runtime.getNil();
1689:                if (def != null) {
1690:                    result = evalInternal(runtime, context, iVisited
1691:                            .getFirstNode(), self, aBlock);
1692:                }
1693:                if (!result.isTrue()) {
1694:                    result = evalInternal(runtime, context, iVisited
1695:                            .getSecondNode(), self, aBlock);
1696:                }
1697:
1698:                return pollAndReturn(context, result);
1699:            }
1700:
1701:            private static IRubyObject opElementAsgnNode(Ruby runtime,
1702:                    ThreadContext context, Node node, IRubyObject self,
1703:                    Block aBlock) {
1704:                OpElementAsgnNode iVisited = (OpElementAsgnNode) node;
1705:                IRubyObject receiver = evalInternal(runtime, context, iVisited
1706:                        .getReceiverNode(), self, aBlock);
1707:
1708:                IRubyObject[] args = setupArgs(runtime, context, iVisited
1709:                        .getArgsNode(), self);
1710:
1711:                IRubyObject firstValue = receiver.callMethod(context,
1712:                        MethodIndex.AREF, "[]", args);
1713:
1714:                if (iVisited.getOperatorName() == "||") {
1715:                    if (firstValue.isTrue()) {
1716:                        return firstValue;
1717:                    }
1718:                    firstValue = evalInternal(runtime, context, iVisited
1719:                            .getValueNode(), self, aBlock);
1720:                } else if (iVisited.getOperatorName() == "&&") {
1721:                    if (!firstValue.isTrue()) {
1722:                        return firstValue;
1723:                    }
1724:                    firstValue = evalInternal(runtime, context, iVisited
1725:                            .getValueNode(), self, aBlock);
1726:                } else {
1727:                    firstValue = firstValue.callMethod(context, iVisited.index,
1728:                            iVisited.getOperatorName(), evalInternal(runtime,
1729:                                    context, iVisited.getValueNode(), self,
1730:                                    aBlock));
1731:                }
1732:
1733:                IRubyObject[] expandedArgs = new IRubyObject[args.length + 1];
1734:                System.arraycopy(args, 0, expandedArgs, 0, args.length);
1735:                expandedArgs[expandedArgs.length - 1] = firstValue;
1736:                return receiver.callMethod(context, MethodIndex.ASET, "[]=",
1737:                        expandedArgs);
1738:            }
1739:
1740:            private static IRubyObject optNNode(Ruby runtime,
1741:                    ThreadContext context, Node node, IRubyObject self,
1742:                    Block aBlock) {
1743:                OptNNode iVisited = (OptNNode) node;
1744:
1745:                IRubyObject result = runtime.getNil();
1746:                outerLoop: while (RubyKernel.gets(runtime.getTopSelf(),
1747:                        IRubyObject.NULL_ARRAY).isTrue()) {
1748:                    loop: while (true) { // Used for the 'redo' command
1749:                        try {
1750:                            result = evalInternal(runtime, context, iVisited
1751:                                    .getBodyNode(), self, aBlock);
1752:                            break;
1753:                        } catch (JumpException je) {
1754:                            switch (je.getJumpType().getTypeId()) {
1755:                            case JumpType.REDO:
1756:                                // do nothing, this iteration restarts
1757:                                break;
1758:                            case JumpType.NEXT:
1759:                                // recheck condition
1760:                                break loop;
1761:                            case JumpType.BREAK:
1762:                                // end loop
1763:                                result = (IRubyObject) je.getValue();
1764:                                break outerLoop;
1765:                            default:
1766:                                throw je;
1767:                            }
1768:                        }
1769:                    }
1770:                }
1771:
1772:                return pollAndReturn(context, result);
1773:            }
1774:
1775:            private static IRubyObject orNode(Ruby runtime,
1776:                    ThreadContext context, Node node, IRubyObject self,
1777:                    Block aBlock) {
1778:                OrNode iVisited = (OrNode) node;
1779:
1780:                IRubyObject result = evalInternal(runtime, context, iVisited
1781:                        .getFirstNode(), self, aBlock);
1782:
1783:                if (!result.isTrue()) {
1784:                    result = evalInternal(runtime, context, iVisited
1785:                            .getSecondNode(), self, aBlock);
1786:                }
1787:
1788:                return result;
1789:            }
1790:
1791:            private static IRubyObject postExeNode(Ruby runtime,
1792:                    ThreadContext context, Node node, IRubyObject self,
1793:                    Block aBlock) {
1794:                PostExeNode iVisited = (PostExeNode) node;
1795:
1796:                // FIXME: I use a for block to implement END node because we need a proc which captures
1797:                // its enclosing scope.   ForBlock now represents these node and should be renamed.
1798:                Block block = SharedScopeBlock.createSharedScopeBlock(context,
1799:                        iVisited, context.getCurrentScope(), self);
1800:
1801:                runtime.pushExitBlock(runtime.newProc(true, block));
1802:
1803:                return runtime.getNil();
1804:            }
1805:
1806:            private static IRubyObject redoNode(ThreadContext context, Node node) {
1807:                context.pollThreadEvents();
1808:
1809:                // now used as an interpreter event
1810:                throw context.prepareJumpException(
1811:                        JumpException.JumpType.RedoJump, null, node);
1812:            }
1813:
1814:            private static IRubyObject regexpNode(Ruby runtime, Node node) {
1815:                RegexpNode iVisited = (RegexpNode) node;
1816:                String lang = null;
1817:                int opts = iVisited.getOptions();
1818:                if ((opts & 16) != 0) { // param n
1819:                    lang = "n";
1820:                } else if ((opts & 48) != 0) { // param s
1821:                    lang = "s";
1822:                } else if ((opts & 64) != 0) { // param s
1823:                    lang = "u";
1824:                }
1825:
1826:                IRubyObject noCaseGlobal = runtime.getGlobalVariables().get(
1827:                        "$=");
1828:
1829:                int extraOptions = noCaseGlobal.isTrue() ? ReOptions.RE_OPTION_IGNORECASE
1830:                        : 0;
1831:
1832:                try {
1833:                    return RubyRegexp.newRegexp(runtime, iVisited.getValue(),
1834:                            iVisited.getPattern(extraOptions), iVisited
1835:                                    .getFlags(extraOptions), lang);
1836:                } catch (jregex.PatternSyntaxException e) {
1837:                    throw runtime.newRegexpError(e.getMessage());
1838:                }
1839:            }
1840:
1841:            private static IRubyObject rescueNode(Ruby runtime,
1842:                    ThreadContext context, Node node, IRubyObject self,
1843:                    Block aBlock) {
1844:                RescueNode iVisited = (RescueNode) node;
1845:                RescuedBlock: while (true) {
1846:                    IRubyObject globalExceptionState = runtime
1847:                            .getGlobalVariables().get("$!");
1848:                    boolean anotherExceptionRaised = false;
1849:                    try {
1850:                        // Execute rescue block
1851:                        IRubyObject result = evalInternal(runtime, context,
1852:                                iVisited.getBodyNode(), self, aBlock);
1853:
1854:                        // If no exception is thrown execute else block
1855:                        if (iVisited.getElseNode() != null) {
1856:                            if (iVisited.getRescueNode() == null) {
1857:                                runtime.getWarnings().warn(
1858:                                        iVisited.getElseNode().getPosition(),
1859:                                        "else without rescue is useless");
1860:                            }
1861:                            result = evalInternal(runtime, context, iVisited
1862:                                    .getElseNode(), self, aBlock);
1863:                        }
1864:
1865:                        return result;
1866:                    } catch (RaiseException raiseJump) {
1867:                        RubyException raisedException = raiseJump
1868:                                .getException();
1869:                        // TODO: Rubicon TestKernel dies without this line.  A cursory glance implies we
1870:                        // falsely set $! to nil and this sets it back to something valid.  This should 
1871:                        // get fixed at the same time we address bug #1296484.
1872:                        runtime.getGlobalVariables().set("$!", raisedException);
1873:
1874:                        RescueBodyNode rescueNode = iVisited.getRescueNode();
1875:
1876:                        while (rescueNode != null) {
1877:                            Node exceptionNodes = rescueNode
1878:                                    .getExceptionNodes();
1879:                            ListNode exceptionNodesList;
1880:
1881:                            if (exceptionNodes instanceof  SplatNode) {
1882:                                exceptionNodesList = (ListNode) evalInternal(
1883:                                        runtime, context, exceptionNodes, self,
1884:                                        aBlock);
1885:                            } else {
1886:                                exceptionNodesList = (ListNode) exceptionNodes;
1887:                            }
1888:
1889:                            if (isRescueHandled(runtime, context,
1890:                                    raisedException, exceptionNodesList, self)) {
1891:                                try {
1892:                                    return evalInternal(runtime, context,
1893:                                            rescueNode, self, aBlock);
1894:                                } catch (JumpException je) {
1895:                                    if (je.getJumpType() == JumpException.JumpType.RetryJump) {
1896:                                        // should be handled in the finally block below
1897:                                        //state.runtime.getGlobalVariables().set("$!", state.runtime.getNil());
1898:                                        //state.threadContext.setRaisedException(null);
1899:                                        continue RescuedBlock;
1900:
1901:                                    } else {
1902:                                        anotherExceptionRaised = true;
1903:                                        throw je;
1904:                                    }
1905:                                }
1906:                            }
1907:
1908:                            rescueNode = rescueNode.getOptRescueNode();
1909:                        }
1910:
1911:                        // no takers; bubble up
1912:                        throw raiseJump;
1913:                    } finally {
1914:                        // clear exception when handled or retried
1915:                        if (!anotherExceptionRaised)
1916:                            runtime.getGlobalVariables().set("$!",
1917:                                    globalExceptionState);
1918:                    }
1919:                }
1920:            }
1921:
1922:            private static IRubyObject retryNode(ThreadContext context) {
1923:                context.pollThreadEvents();
1924:
1925:                throw context.prepareJumpException(
1926:                        JumpException.JumpType.RetryJump, null, null);
1927:            }
1928:
1929:            private static IRubyObject returnNode(Ruby runtime,
1930:                    ThreadContext context, Node node, IRubyObject self,
1931:                    Block aBlock) {
1932:                ReturnNode iVisited = (ReturnNode) node;
1933:
1934:                IRubyObject result = evalInternal(runtime, context, iVisited
1935:                        .getValueNode(), self, aBlock);
1936:
1937:                throw context.prepareJumpException(
1938:                        JumpException.JumpType.ReturnJump, context
1939:                                .getFrameJumpTarget(), result);
1940:            }
1941:
1942:            private static IRubyObject rootNode(Ruby runtime,
1943:                    ThreadContext context, Node node, IRubyObject self,
1944:                    Block aBlock) {
1945:                RootNode iVisited = (RootNode) node;
1946:                DynamicScope scope = iVisited.getScope();
1947:
1948:                // Serialization killed our dynamic scope.  We can just create an empty one
1949:                // since serialization cannot serialize an eval (which is the only thing
1950:                // which is capable of having a non-empty dynamic scope).
1951:                if (scope == null) {
1952:                    scope = new DynamicScope(iVisited.getStaticScope());
1953:                }
1954:
1955:                // Each root node has a top-level scope that we need to push
1956:                context.preRootNode(scope);
1957:
1958:                // FIXME: Wire up BEGIN and END nodes
1959:
1960:                try {
1961:                    return evalInternal(runtime, context, iVisited
1962:                            .getBodyNode(), self, aBlock);
1963:                } finally {
1964:                    context.postRootNode();
1965:                }
1966:            }
1967:
1968:            private static IRubyObject sClassNode(Ruby runtime,
1969:                    ThreadContext context, Node node, IRubyObject self,
1970:                    Block aBlock) {
1971:                SClassNode iVisited = (SClassNode) node;
1972:                IRubyObject receiver = evalInternal(runtime, context, iVisited
1973:                        .getReceiverNode(), self, aBlock);
1974:
1975:                RubyClass singletonClass;
1976:
1977:                if (receiver.isNil()) {
1978:                    singletonClass = runtime.getNilClass();
1979:                } else if (receiver == runtime.getTrue()) {
1980:                    singletonClass = runtime.getClass("TrueClass");
1981:                } else if (receiver == runtime.getFalse()) {
1982:                    singletonClass = runtime.getClass("FalseClass");
1983:                } else if (receiver.getMetaClass() == runtime.getFixnum()
1984:                        || receiver.getMetaClass() == runtime
1985:                                .getClass("Symbol")) {
1986:                    throw runtime.newTypeError("no virtual class for "
1987:                            + receiver.getMetaClass().getBaseName());
1988:                } else {
1989:                    if (runtime.getSafeLevel() >= 4 && !receiver.isTaint()) {
1990:                        throw runtime
1991:                                .newSecurityError("Insecure: can't extend object.");
1992:                    }
1993:
1994:                    singletonClass = receiver.getSingletonClass();
1995:                }
1996:
1997:                return evalClassDefinitionBody(runtime, context, iVisited
1998:                        .getScope(), iVisited.getBodyNode(), singletonClass,
1999:                        self, aBlock);
2000:            }
2001:
2002:            private static IRubyObject splatNode(Ruby runtime,
2003:                    ThreadContext context, Node node, IRubyObject self,
2004:                    Block aBlock) {
2005:                return splatValue(runtime, evalInternal(runtime, context,
2006:                        ((SplatNode) node).getValue(), self, aBlock));
2007:            }
2008:
2009:            private static IRubyObject strNode(Ruby runtime, Node node) {
2010:                return runtime.newStringShared((ByteList) ((StrNode) node)
2011:                        .getValue());
2012:            }
2013:
2014:            private static IRubyObject super Node(Ruby runtime,
2015:                    ThreadContext context, Node node, IRubyObject self,
2016:                    Block aBlock) {
2017:                SuperNode iVisited = (SuperNode) node;
2018:
2019:                RubyModule klazz = context.getFrameKlazz();
2020:
2021:                if (klazz == null) {
2022:                    String name = context.getFrameName();
2023:                    throw runtime.newNameError("Superclass method '" + name
2024:                            + "' disabled.", name);
2025:                }
2026:                IRubyObject[] args = setupArgs(runtime, context, iVisited
2027:                        .getArgsNode(), self);
2028:                Block block = getBlock(runtime, context, self, aBlock, iVisited
2029:                        .getIterNode());
2030:
2031:                // If no explicit block passed to super, then use the one passed in.
2032:                if (!block.isGiven())
2033:                    block = aBlock;
2034:
2035:                return self.callSuper(context, args, block);
2036:            }
2037:
2038:            private static IRubyObject sValueNode(Ruby runtime,
2039:                    ThreadContext context, Node node, IRubyObject self,
2040:                    Block aBlock) {
2041:                return aValueSplat(runtime, evalInternal(runtime, context,
2042:                        ((SValueNode) node).getValue(), self, aBlock));
2043:            }
2044:
2045:            private static IRubyObject symbolNode(Ruby runtime, Node node) {
2046:                return runtime.newSymbol(((SymbolNode) node).getName());
2047:            }
2048:
2049:            private static IRubyObject toAryNode(Ruby runtime,
2050:                    ThreadContext context, Node node, IRubyObject self,
2051:                    Block aBlock) {
2052:                return aryToAry(runtime, evalInternal(runtime, context,
2053:                        ((ToAryNode) node).getValue(), self, aBlock));
2054:            }
2055:
2056:            private static IRubyObject trueNode(Ruby runtime,
2057:                    ThreadContext context) {
2058:                return pollAndReturn(context, runtime.getTrue());
2059:            }
2060:
2061:            private static IRubyObject undefNode(Ruby runtime,
2062:                    ThreadContext context, Node node) {
2063:                UndefNode iVisited = (UndefNode) node;
2064:
2065:                if (context.getRubyClass() == null) {
2066:                    throw runtime.newTypeError("No class to undef method '"
2067:                            + iVisited.getName() + "'.");
2068:                }
2069:                context.getRubyClass().undef(iVisited.getName());
2070:
2071:                return runtime.getNil();
2072:            }
2073:
2074:            private static IRubyObject untilNode(Ruby runtime,
2075:                    ThreadContext context, Node node, IRubyObject self,
2076:                    Block aBlock) {
2077:                UntilNode iVisited = (UntilNode) node;
2078:
2079:                IRubyObject result = runtime.getNil();
2080:                boolean firstTest = iVisited.evaluateAtStart();
2081:
2082:                outerLoop: while (!firstTest
2083:                        || !(result = evalInternal(runtime, context, iVisited
2084:                                .getConditionNode(), self, aBlock)).isTrue()) {
2085:                    firstTest = true;
2086:                    loop: while (true) { // Used for the 'redo' command
2087:                        try {
2088:                            result = evalInternal(runtime, context, iVisited
2089:                                    .getBodyNode(), self, aBlock);
2090:                            break loop;
2091:                        } catch (JumpException je) {
2092:                            switch (je.getJumpType().getTypeId()) {
2093:                            case JumpType.REDO:
2094:                                continue;
2095:                            case JumpType.NEXT:
2096:                                break loop;
2097:                            case JumpType.BREAK:
2098:                                // JRUBY-530 until case
2099:                                if (je.getTarget() == aBlock) {
2100:                                    je.setTarget(null);
2101:
2102:                                    throw je;
2103:                                }
2104:
2105:                                result = (IRubyObject) je.getValue();
2106:
2107:                                break outerLoop;
2108:                            default:
2109:                                throw je;
2110:                            }
2111:                        }
2112:                    }
2113:                }
2114:
2115:                return pollAndReturn(context, result);
2116:            }
2117:
2118:            private static IRubyObject valiasNode(Ruby runtime, Node node) {
2119:                VAliasNode iVisited = (VAliasNode) node;
2120:                runtime.getGlobalVariables().alias(iVisited.getNewName(),
2121:                        iVisited.getOldName());
2122:
2123:                return runtime.getNil();
2124:            }
2125:
2126:            private static IRubyObject vcallNode(Ruby runtime,
2127:                    ThreadContext context, Node node, IRubyObject self) {
2128:                VCallNode iVisited = (VCallNode) node;
2129:                RubyModule module = self.getMetaClass();
2130:                String name = iVisited.getName();
2131:                int index = iVisited.index;
2132:
2133:                if (module.index != 0 && index != 0) {
2134:                    return self.callMethod(context, module, index, name,
2135:                            IRubyObject.NULL_ARRAY, CallType.VARIABLE,
2136:                            Block.NULL_BLOCK);
2137:                } else {
2138:                    DynamicMethod method = module.searchMethod(name);
2139:
2140:                    if (method.isUndefined()
2141:                            || (index != MethodIndex.METHOD_MISSING && !method
2142:                                    .isCallableFrom(self, CallType.VARIABLE))) {
2143:                        return RubyObject.callMethodMissing(context, self,
2144:                                method, name, index, IRubyObject.NULL_ARRAY,
2145:                                self, CallType.VARIABLE, Block.NULL_BLOCK);
2146:                    }
2147:
2148:                    return method.call(context, self, module, name,
2149:                            IRubyObject.NULL_ARRAY, false, Block.NULL_BLOCK);
2150:                }
2151:            }
2152:
2153:            private static IRubyObject whileNode(Ruby runtime,
2154:                    ThreadContext context, Node node, IRubyObject self,
2155:                    Block aBlock) {
2156:                WhileNode iVisited = (WhileNode) node;
2157:
2158:                IRubyObject result = runtime.getNil();
2159:                boolean firstTest = iVisited.evaluateAtStart();
2160:
2161:                outerLoop: while (!firstTest
2162:                        || (result = evalInternal(runtime, context, iVisited
2163:                                .getConditionNode(), self, aBlock)).isTrue()) {
2164:                    firstTest = true;
2165:                    loop: while (true) { // Used for the 'redo' command
2166:                        try {
2167:                            evalInternal(runtime, context, iVisited
2168:                                    .getBodyNode(), self, aBlock);
2169:                            break loop;
2170:                        } catch (RaiseException re) {
2171:                            if (re.getException().isKindOf(
2172:                                    runtime.getClass("LocalJumpError"))) {
2173:                                RubyLocalJumpError jumpError = (RubyLocalJumpError) re
2174:                                        .getException();
2175:
2176:                                IRubyObject reason = jumpError.reason();
2177:
2178:                                // admittedly inefficient
2179:                                if (reason.asSymbol().equals("break")) {
2180:                                    return jumpError.exitValue();
2181:                                } else if (reason.asSymbol().equals("next")) {
2182:                                    break loop;
2183:                                } else if (reason.asSymbol().equals("redo")) {
2184:                                    continue;
2185:                                }
2186:                            }
2187:
2188:                            throw re;
2189:                        } catch (JumpException je) {
2190:                            switch (je.getJumpType().getTypeId()) {
2191:                            case JumpType.REDO:
2192:                                continue;
2193:                            case JumpType.NEXT:
2194:                                break loop;
2195:                            case JumpType.BREAK:
2196:                                // JRUBY-530, while case
2197:                                if (je.getTarget() == aBlock) {
2198:                                    je.setTarget(null);
2199:
2200:                                    throw je;
2201:                                }
2202:
2203:                                break outerLoop;
2204:                            default:
2205:                                throw je;
2206:                            }
2207:                        }
2208:                    }
2209:                }
2210:
2211:                return pollAndReturn(context, result);
2212:            }
2213:
2214:            private static IRubyObject xStrNode(Ruby runtime,
2215:                    ThreadContext context, Node node, IRubyObject self) {
2216:                return self.callMethod(context, "`", runtime
2217:                        .newStringShared((ByteList) ((XStrNode) node)
2218:                                .getValue()));
2219:            }
2220:
2221:            private static IRubyObject yieldNode(Ruby runtime,
2222:                    ThreadContext context, Node node, IRubyObject self,
2223:                    Block aBlock) {
2224:                YieldNode iVisited = (YieldNode) node;
2225:
2226:                IRubyObject result = null;
2227:                if (iVisited.getArgsNode() != null) {
2228:                    result = evalInternal(runtime, context, iVisited
2229:                            .getArgsNode(), self, aBlock);
2230:                }
2231:
2232:                Block block = context.getCurrentFrame().getBlock();
2233:
2234:                return block.yield(context, result, null, null, iVisited
2235:                        .getCheckState());
2236:            }
2237:
2238:            private static IRubyObject zArrayNode(Ruby runtime) {
2239:                return runtime.newArray();
2240:            }
2241:
2242:            private static IRubyObject zsuper Node(Ruby runtime,
2243:                    ThreadContext context, Node node, IRubyObject self,
2244:                    Block aBlock) {
2245:                if (context.getFrameKlazz() == null) {
2246:                    String name = context.getFrameName();
2247:                    throw runtime.newNameError("superclass method '" + name
2248:                            + "' disabled", name);
2249:                }
2250:
2251:                Block block = getBlock(runtime, context, self, aBlock,
2252:                        ((ZSuperNode) node).getIterNode());
2253:
2254:                // Has the method that is calling super received a block argument
2255:                if (!block.isGiven())
2256:                    block = context.getCurrentFrame().getBlock();
2257:
2258:                context.getCurrentScope().getArgValues(context.getFrameArgs(),
2259:                        context.getCurrentFrame().getRequiredArgCount());
2260:                return self.callSuper(context, context.getFrameArgs(), block);
2261:            }
2262:
2263:            public static IRubyObject aValueSplat(Ruby runtime,
2264:                    IRubyObject value) {
2265:                if (!(value instanceof  RubyArray)
2266:                        || ((RubyArray) value).length().getLongValue() == 0) {
2267:                    return runtime.getNil();
2268:                }
2269:
2270:                RubyArray array = (RubyArray) value;
2271:
2272:                return array.getLength() == 1 ? array
2273:                        .first(IRubyObject.NULL_ARRAY) : array;
2274:            }
2275:
2276:            private static void callTraceFunction(Ruby runtime,
2277:                    ThreadContext context, int event) {
2278:                String name = context.getFrameName();
2279:                RubyModule type = context.getFrameKlazz();
2280:                runtime.callEventHooks(context, event, context.getPosition()
2281:                        .getFile(), context.getPosition().getStartLine(), name,
2282:                        type);
2283:            }
2284:
2285:            /** Evaluates the body in a class or module definition statement.
2286:             *
2287:             */
2288:            private static IRubyObject evalClassDefinitionBody(Ruby runtime,
2289:                    ThreadContext context, StaticScope scope, Node bodyNode,
2290:                    RubyModule type, IRubyObject self, Block block) {
2291:                context.preClassEval(scope, type);
2292:
2293:                try {
2294:                    if (isTrace(runtime)) {
2295:                        callTraceFunction(runtime, context,
2296:                                EventHook.RUBY_EVENT_CLASS);
2297:                    }
2298:
2299:                    return evalInternal(runtime, context, bodyNode, type, block);
2300:                } finally {
2301:                    if (isTrace(runtime)) {
2302:                        callTraceFunction(runtime, context,
2303:                                EventHook.RUBY_EVENT_END);
2304:                    }
2305:
2306:                    context.postClassEval();
2307:                }
2308:            }
2309:
2310:            private static String getArgumentDefinition(Ruby runtime,
2311:                    ThreadContext context, Node node, String type,
2312:                    IRubyObject self, Block block) {
2313:                if (node == null)
2314:                    return type;
2315:
2316:                if (node instanceof  ArrayNode) {
2317:                    for (int i = 0; i < ((ArrayNode) node).size(); i++) {
2318:                        Node iterNode = ((ArrayNode) node).get(i);
2319:                        if (getDefinitionInner(runtime, context, iterNode,
2320:                                self, block) == null)
2321:                            return null;
2322:                    }
2323:                } else if (getDefinitionInner(runtime, context, node, self,
2324:                        block) == null) {
2325:                    return null;
2326:                }
2327:
2328:                return type;
2329:            }
2330:
2331:            public static Block getBlock(Ruby runtime, ThreadContext context,
2332:                    IRubyObject self, Block currentBlock, Node blockNode) {
2333:                if (blockNode == null)
2334:                    return Block.NULL_BLOCK;
2335:
2336:                if (blockNode instanceof  IterNode) {
2337:                    IterNode iterNode = (IterNode) blockNode;
2338:                    // Create block for this iter node
2339:                    // FIXME: We shouldn't use the current scope if it's not actually from the same hierarchy of static scopes
2340:                    return Block.createBlock(context, iterNode,
2341:                            new DynamicScope(iterNode.getScope(), context
2342:                                    .getCurrentScope()), self);
2343:                } else if (blockNode instanceof  BlockPassNode) {
2344:                    BlockPassNode blockPassNode = (BlockPassNode) blockNode;
2345:                    IRubyObject proc = evalInternal(runtime, context,
2346:                            blockPassNode.getBodyNode(), self, currentBlock);
2347:
2348:                    // No block from a nil proc
2349:                    if (proc.isNil())
2350:                        return Block.NULL_BLOCK;
2351:
2352:                    // If not already a proc then we should try and make it one.
2353:                    if (!(proc instanceof  RubyProc)) {
2354:                        proc = proc.convertToType(runtime.getClass("Proc"), 0,
2355:                                "to_proc", false);
2356:
2357:                        if (!(proc instanceof  RubyProc)) {
2358:                            throw runtime.newTypeError("wrong argument type "
2359:                                    + proc.getMetaClass().getName()
2360:                                    + " (expected Proc)");
2361:                        }
2362:                    }
2363:
2364:                    // TODO: Add safety check for taintedness
2365:
2366:                    if (currentBlock.isGiven()) {
2367:                        RubyProc procObject = currentBlock.getProcObject();
2368:                        // The current block is already associated with proc.  No need to create a new one
2369:                        if (procObject != null && procObject == proc)
2370:                            return currentBlock;
2371:                    }
2372:
2373:                    return ((RubyProc) proc).getBlock();
2374:                }
2375:
2376:                assert false : "Trying to get block from something which cannot deliver";
2377:                return null;
2378:            }
2379:
2380:            /* Something like cvar_cbase() from eval.c, factored out for the benefit
2381:             * of all the classvar-related node evaluations */
2382:            public static RubyModule getClassVariableBase(
2383:                    ThreadContext context, Ruby runtime) {
2384:                SinglyLinkedList cref = context.peekCRef();
2385:                RubyModule rubyClass = (RubyModule) cref.getValue();
2386:                if (rubyClass.isSingleton()) {
2387:                    cref = cref.getNext();
2388:                    rubyClass = (RubyModule) cref.getValue();
2389:                    if (cref.getNext() == null) {
2390:                        runtime
2391:                                .getWarnings()
2392:                                .warn(
2393:                                        "class variable access from toplevel singleton method");
2394:                    }
2395:                }
2396:                return rubyClass;
2397:            }
2398:
2399:            private static String getDefinition(Ruby runtime,
2400:                    ThreadContext context, Node node, IRubyObject self,
2401:                    Block aBlock) {
2402:                try {
2403:                    context.setWithinDefined(true);
2404:                    return getDefinitionInner(runtime, context, node, self,
2405:                            aBlock);
2406:                } finally {
2407:                    context.setWithinDefined(false);
2408:                }
2409:            }
2410:
2411:            private static String getDefinitionInner(Ruby runtime,
2412:                    ThreadContext context, Node node, IRubyObject self,
2413:                    Block aBlock) {
2414:                if (node == null)
2415:                    return "expression";
2416:
2417:                switch (node.nodeId) {
2418:                case NodeTypes.ATTRASSIGNNODE: {
2419:                    AttrAssignNode iVisited = (AttrAssignNode) node;
2420:
2421:                    if (getDefinitionInner(runtime, context, iVisited
2422:                            .getReceiverNode(), self, aBlock) != null) {
2423:                        try {
2424:                            IRubyObject receiver = eval(runtime, context,
2425:                                    iVisited.getReceiverNode(), self, aBlock);
2426:                            RubyClass metaClass = receiver.getMetaClass();
2427:                            DynamicMethod method = metaClass
2428:                                    .searchMethod(iVisited.getName());
2429:                            Visibility visibility = method.getVisibility();
2430:
2431:                            if (!visibility.isPrivate()
2432:                                    && (!visibility.isProtected() || self
2433:                                            .isKindOf(metaClass.getRealClass()))) {
2434:                                if (metaClass.isMethodBound(iVisited.getName(),
2435:                                        false)) {
2436:                                    return getArgumentDefinition(runtime,
2437:                                            context, iVisited.getArgsNode(),
2438:                                            "assignment", self, aBlock);
2439:                                }
2440:                            }
2441:                        } catch (JumpException excptn) {
2442:                        }
2443:                    }
2444:
2445:                    return null;
2446:                }
2447:                case NodeTypes.BACKREFNODE:
2448:                    return "$" + ((BackRefNode) node).getType();
2449:                case NodeTypes.CALLNODE: {
2450:                    CallNode iVisited = (CallNode) node;
2451:
2452:                    if (getDefinitionInner(runtime, context, iVisited
2453:                            .getReceiverNode(), self, aBlock) != null) {
2454:                        try {
2455:                            IRubyObject receiver = eval(runtime, context,
2456:                                    iVisited.getReceiverNode(), self, aBlock);
2457:                            RubyClass metaClass = receiver.getMetaClass();
2458:                            DynamicMethod method = metaClass
2459:                                    .searchMethod(iVisited.getName());
2460:                            Visibility visibility = method.getVisibility();
2461:
2462:                            if (!visibility.isPrivate()
2463:                                    && (!visibility.isProtected() || self
2464:                                            .isKindOf(metaClass.getRealClass()))) {
2465:                                if (metaClass.isMethodBound(iVisited.getName(),
2466:                                        false)) {
2467:                                    return getArgumentDefinition(runtime,
2468:                                            context, iVisited.getArgsNode(),
2469:                                            "method", self, aBlock);
2470:                                }
2471:                            }
2472:                        } catch (JumpException excptn) {
2473:                        }
2474:                    }
2475:
2476:                    return null;
2477:                }
2478:                case NodeTypes.CLASSVARASGNNODE:
2479:                case NodeTypes.CLASSVARDECLNODE:
2480:                case NodeTypes.CONSTDECLNODE:
2481:                case NodeTypes.DASGNNODE:
2482:                case NodeTypes.GLOBALASGNNODE:
2483:                case NodeTypes.LOCALASGNNODE:
2484:                case NodeTypes.MULTIPLEASGNNODE:
2485:                case NodeTypes.OPASGNNODE:
2486:                case NodeTypes.OPELEMENTASGNNODE:
2487:                    return "assignment";
2488:
2489:                case NodeTypes.CLASSVARNODE: {
2490:                    ClassVarNode iVisited = (ClassVarNode) node;
2491:
2492:                    if (context.getRubyClass() == null
2493:                            && self.getMetaClass().isClassVarDefined(
2494:                                    iVisited.getName())) {
2495:                        return "class_variable";
2496:                    } else if (!context.getRubyClass().isSingleton()
2497:                            && context.getRubyClass().isClassVarDefined(
2498:                                    iVisited.getName())) {
2499:                        return "class_variable";
2500:                    }
2501:
2502:                    IRubyObject attached = context.getRubyClass()
2503:                            .getInstanceVariable("__attached__");
2504:                    if (attached instanceof  RubyModule) {
2505:                        RubyModule module = (RubyModule) attached;
2506:                        if (module.isClassVarDefined(iVisited.getName()))
2507:                            return "class_variable";
2508:                    }
2509:
2510:                    return null;
2511:                }
2512:                case NodeTypes.COLON3NODE:
2513:                case NodeTypes.COLON2NODE: {
2514:                    Colon3Node iVisited = (Colon3Node) node;
2515:
2516:                    try {
2517:                        IRubyObject left = runtime.getObject();
2518:                        if (iVisited instanceof  Colon2Node) {
2519:                            left = EvaluationState.eval(runtime, context,
2520:                                    ((Colon2Node) iVisited).getLeftNode(),
2521:                                    self, aBlock);
2522:                        }
2523:
2524:                        if (left instanceof  RubyModule
2525:                                && ((RubyModule) left).getConstantAt(iVisited
2526:                                        .getName()) != null) {
2527:                            return "constant";
2528:                        } else if (left.getMetaClass().isMethodBound(
2529:                                iVisited.getName(), true)) {
2530:                            return "method";
2531:                        }
2532:                    } catch (JumpException excptn) {
2533:                    }
2534:
2535:                    return null;
2536:                }
2537:                case NodeTypes.CONSTNODE:
2538:                    if (context
2539:                            .getConstantDefined(((ConstNode) node).getName())) {
2540:                        return "constant";
2541:                    }
2542:                    return null;
2543:                case NodeTypes.DVARNODE:
2544:                    return "local-variable(in-block)";
2545:                case NodeTypes.FALSENODE:
2546:                    return "false";
2547:                case NodeTypes.FCALLNODE: {
2548:                    FCallNode iVisited = (FCallNode) node;
2549:                    if (self.getMetaClass().isMethodBound(iVisited.getName(),
2550:                            false)) {
2551:                        return getArgumentDefinition(runtime, context, iVisited
2552:                                .getArgsNode(), "method", self, aBlock);
2553:                    }
2554:
2555:                    return null;
2556:                }
2557:                case NodeTypes.GLOBALVARNODE:
2558:                    if (runtime.getGlobalVariables().isDefined(
2559:                            ((GlobalVarNode) node).getName())) {
2560:                        return "global-variable";
2561:                    }
2562:                    return null;
2563:                case NodeTypes.INSTVARNODE:
2564:                    if (self
2565:                            .getInstanceVariable(((InstVarNode) node).getName()) != null) {
2566:                        return "instance-variable";
2567:                    }
2568:                    return null;
2569:                case NodeTypes.LOCALVARNODE:
2570:                    return "local-variable";
2571:                case NodeTypes.MATCH2NODE:
2572:                case NodeTypes.MATCH3NODE:
2573:                    return "method";
2574:                case NodeTypes.NILNODE:
2575:                    return "nil";
2576:                case NodeTypes.NTHREFNODE:
2577:                    return "$" + ((NthRefNode) node).getMatchNumber();
2578:                case NodeTypes.SELFNODE:
2579:                    return "state.getSelf()";
2580:                case NodeTypes.SUPERNODE: {
2581:                    SuperNode iVisited = (SuperNode) node;
2582:                    String name = context.getFrameName();
2583:                    RubyModule klazz = context.getFrameKlazz();
2584:                    if (name != null && klazz != null
2585:                            && klazz.getSuperClass().isMethodBound(name, false)) {
2586:                        return getArgumentDefinition(runtime, context, iVisited
2587:                                .getArgsNode(), "super", self, aBlock);
2588:                    }
2589:
2590:                    return null;
2591:                }
2592:                case NodeTypes.TRUENODE:
2593:                    return "true";
2594:                case NodeTypes.VCALLNODE: {
2595:                    VCallNode iVisited = (VCallNode) node;
2596:                    if (self.getMetaClass().isMethodBound(iVisited.getName(),
2597:                            false)) {
2598:                        return "method";
2599:                    }
2600:
2601:                    return null;
2602:                }
2603:                case NodeTypes.YIELDNODE:
2604:                    return aBlock.isGiven() ? "yield" : null;
2605:                case NodeTypes.ZSUPERNODE: {
2606:                    String name = context.getFrameName();
2607:                    RubyModule klazz = context.getFrameKlazz();
2608:                    if (name != null && klazz != null
2609:                            && klazz.getSuperClass().isMethodBound(name, false)) {
2610:                        return "super";
2611:                    }
2612:                    return null;
2613:                }
2614:                default:
2615:                    try {
2616:                        EvaluationState.eval(runtime, context, node, self,
2617:                                aBlock);
2618:                        return "expression";
2619:                    } catch (JumpException jumpExcptn) {
2620:                    }
2621:                }
2622:
2623:                return null;
2624:            }
2625:
2626:            private static RubyModule getEnclosingModule(Ruby runtime,
2627:                    ThreadContext context, Node node, IRubyObject self,
2628:                    Block block) {
2629:                RubyModule enclosingModule = null;
2630:
2631:                if (node instanceof  Colon2Node) {
2632:                    IRubyObject result = evalInternal(runtime, context,
2633:                            ((Colon2Node) node).getLeftNode(), self, block);
2634:
2635:                    if (result != null && !result.isNil()) {
2636:                        enclosingModule = (RubyModule) result;
2637:                    }
2638:                } else if (node instanceof  Colon3Node) {
2639:                    enclosingModule = runtime.getObject();
2640:                }
2641:
2642:                if (enclosingModule == null) {
2643:                    enclosingModule = (RubyModule) context.peekCRef()
2644:                            .getValue();
2645:                }
2646:
2647:                return enclosingModule;
2648:            }
2649:
2650:            private static boolean isRescueHandled(Ruby runtime,
2651:                    ThreadContext context, RubyException currentException,
2652:                    ListNode exceptionNodes, IRubyObject self) {
2653:                if (exceptionNodes == null) {
2654:                    return currentException.isKindOf(runtime
2655:                            .getClass("StandardError"));
2656:                }
2657:
2658:                IRubyObject[] args = setupArgs(runtime, context,
2659:                        exceptionNodes, self);
2660:
2661:                for (int i = 0; i < args.length; i++) {
2662:                    if (!args[i].isKindOf(runtime.getClass("Module"))) {
2663:                        throw runtime
2664:                                .newTypeError("class or module required for rescue clause");
2665:                    }
2666:                    if (args[i].callMethod(context, "===", currentException)
2667:                            .isTrue())
2668:                        return true;
2669:                }
2670:                return false;
2671:            }
2672:
2673:            /**
2674:             * Helper method.
2675:             *
2676:             * test if a trace function is avaiable.
2677:             *
2678:             */
2679:            private static boolean isTrace(Ruby runtime) {
2680:                return runtime.hasEventHooks();
2681:            }
2682:
2683:            private static IRubyObject[] setupArgs(Ruby runtime,
2684:                    ThreadContext context, Node node, IRubyObject self) {
2685:                if (node == null)
2686:                    return IRubyObject.NULL_ARRAY;
2687:
2688:                if (node instanceof  ArrayNode) {
2689:                    ArrayNode argsArrayNode = (ArrayNode) node;
2690:                    ISourcePosition position = context.getPosition();
2691:                    int size = argsArrayNode.size();
2692:                    IRubyObject[] argsArray = new IRubyObject[size];
2693:
2694:                    for (int i = 0; i < size; i++) {
2695:                        argsArray[i] = evalInternal(runtime, context,
2696:                                argsArrayNode.get(i), self, Block.NULL_BLOCK);
2697:                    }
2698:
2699:                    context.setPosition(position);
2700:
2701:                    return argsArray;
2702:                }
2703:
2704:                return ArgsUtil.convertToJavaArray(evalInternal(runtime,
2705:                        context, node, self, Block.NULL_BLOCK));
2706:            }
2707:
2708:            public static RubyArray splatValue(Ruby runtime, IRubyObject value) {
2709:                if (value.isNil()) {
2710:                    return runtime.newArray(value);
2711:                }
2712:
2713:                return arrayValue(runtime, value);
2714:            }
2715:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.