diff graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java @ 13569:1894412de0ed

Ruby: major upgrade in debugging support, mainly for navigation: step, next (passing over calls), return (from enclosing function), etc. Also a few bug fixes.
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 08 Jan 2014 14:03:36 -0800
parents 0fbee3eb71f0
children d7af2296cebb
line wrap: on
line diff
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java	Wed Jan 08 14:00:21 2014 -0800
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java	Wed Jan 08 14:03:36 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
+ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
  * code is released under a tri EPL/GPL/LGPL license. You can use it,
  * redistribute it and/or modify it under the terms of the:
  *
@@ -16,6 +16,8 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.nodes.instrument.*;
+import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain;
 import com.oracle.truffle.ruby.nodes.*;
 import com.oracle.truffle.ruby.nodes.call.*;
 import com.oracle.truffle.ruby.nodes.cast.*;
@@ -87,6 +89,15 @@
         nodeDefinedNames.put(org.jrubyparser.ast.DVarNode.class, "local-variable");
     }
 
+    private static final Set<String> debugIgnoredCalls = new HashSet<>();
+
+    static {
+        debugIgnoredCalls.add("downto");
+        debugIgnoredCalls.add("each");
+        debugIgnoredCalls.add("times");
+        debugIgnoredCalls.add("upto");
+    }
+
     /**
      * Global variables which in common usage have frame local semantics.
      */
@@ -289,7 +300,20 @@
 
         final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, block, args, extraArgument);
 
-        return new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments());
+        RubyNode translated = new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments());
+
+        if (context.getConfiguration().getDebug()) {
+            final CallNode callNode = (CallNode) translated;
+            if (!debugIgnoredCalls.contains(callNode.getName())) {
+
+                final RubyProxyNode proxy = new RubyProxyNode(context, translated);
+                proxy.markAs(NodePhylum.CALL);
+                proxy.getProbeChain().appendProbe(new RubyCallProbe(context, node.getName()));
+                translated = proxy;
+            }
+        }
+
+        return translated;
     }
 
     protected class ArgumentsAndBlockTranslation {
@@ -1147,6 +1171,7 @@
             } else {
                 proxy = new RubyProxyNode(context, translated);
             }
+            proxy.markAs(NodePhylum.ASSIGNMENT);
             context.getDebugManager().registerLocalDebugProxy(methodIdentifier, node.getName(), proxy.getProbeChain());
 
             translated = proxy;
@@ -1455,15 +1480,19 @@
         if (context.getConfiguration().getDebug()) {
 
             RubyProxyNode proxy;
-            SourceSection sourceSection;
             if (translated instanceof RubyProxyNode) {
                 proxy = (RubyProxyNode) translated;
-                sourceSection = proxy.getChild().getSourceSection();
+                if (proxy.getChild() instanceof CallNode) {
+                    // Special case; replace proxy with one registered by line, merge in information
+                    final CallNode callNode = (CallNode) proxy.getChild();
+                    final ProbeChain probeChain = proxy.getProbeChain();
+
+                    proxy = new RubyProxyNode(context, callNode, probeChain);
+                }
             } else {
                 proxy = new RubyProxyNode(context, translated);
-                sourceSection = translated.getSourceSection();
             }
-            context.getDebugManager().registerProbeChain(sourceSection, proxy.getProbeChain());
+            proxy.markAs(NodePhylum.STATEMENT);
             translated = proxy;
         }