comparison 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
comparison
equal deleted inserted replaced
13568:f29a358cf3da 13569:1894412de0ed
1 /* 1 /*
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This 2 * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
3 * code is released under a tri EPL/GPL/LGPL license. You can use it, 3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
4 * redistribute it and/or modify it under the terms of the: 4 * redistribute it and/or modify it under the terms of the:
5 * 5 *
6 * Eclipse Public License version 1.0 6 * Eclipse Public License version 1.0
7 * GNU General Public License version 2 7 * GNU General Public License version 2
14 import java.util.regex.*; 14 import java.util.regex.*;
15 15
16 import com.oracle.truffle.api.*; 16 import com.oracle.truffle.api.*;
17 import com.oracle.truffle.api.frame.*; 17 import com.oracle.truffle.api.frame.*;
18 import com.oracle.truffle.api.impl.*; 18 import com.oracle.truffle.api.impl.*;
19 import com.oracle.truffle.api.nodes.instrument.*;
20 import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain;
19 import com.oracle.truffle.ruby.nodes.*; 21 import com.oracle.truffle.ruby.nodes.*;
20 import com.oracle.truffle.ruby.nodes.call.*; 22 import com.oracle.truffle.ruby.nodes.call.*;
21 import com.oracle.truffle.ruby.nodes.cast.*; 23 import com.oracle.truffle.ruby.nodes.cast.*;
22 import com.oracle.truffle.ruby.nodes.constants.*; 24 import com.oracle.truffle.ruby.nodes.constants.*;
23 import com.oracle.truffle.ruby.nodes.control.*; 25 import com.oracle.truffle.ruby.nodes.control.*;
85 nodeDefinedNames.put(org.jrubyparser.ast.OrNode.class, "expression"); 87 nodeDefinedNames.put(org.jrubyparser.ast.OrNode.class, "expression");
86 nodeDefinedNames.put(org.jrubyparser.ast.LocalVarNode.class, "local-variable"); 88 nodeDefinedNames.put(org.jrubyparser.ast.LocalVarNode.class, "local-variable");
87 nodeDefinedNames.put(org.jrubyparser.ast.DVarNode.class, "local-variable"); 89 nodeDefinedNames.put(org.jrubyparser.ast.DVarNode.class, "local-variable");
88 } 90 }
89 91
92 private static final Set<String> debugIgnoredCalls = new HashSet<>();
93
94 static {
95 debugIgnoredCalls.add("downto");
96 debugIgnoredCalls.add("each");
97 debugIgnoredCalls.add("times");
98 debugIgnoredCalls.add("upto");
99 }
100
90 /** 101 /**
91 * Global variables which in common usage have frame local semantics. 102 * Global variables which in common usage have frame local semantics.
92 */ 103 */
93 public static final Set<String> FRAME_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$_")); 104 public static final Set<String> FRAME_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$_"));
94 105
287 block = temp; 298 block = temp;
288 } 299 }
289 300
290 final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, block, args, extraArgument); 301 final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, block, args, extraArgument);
291 302
292 return new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments()); 303 RubyNode translated = new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments());
304
305 if (context.getConfiguration().getDebug()) {
306 final CallNode callNode = (CallNode) translated;
307 if (!debugIgnoredCalls.contains(callNode.getName())) {
308
309 final RubyProxyNode proxy = new RubyProxyNode(context, translated);
310 proxy.markAs(NodePhylum.CALL);
311 proxy.getProbeChain().appendProbe(new RubyCallProbe(context, node.getName()));
312 translated = proxy;
313 }
314 }
315
316 return translated;
293 } 317 }
294 318
295 protected class ArgumentsAndBlockTranslation { 319 protected class ArgumentsAndBlockTranslation {
296 320
297 private final RubyNode block; 321 private final RubyNode block;
1145 if (translated instanceof RubyProxyNode) { 1169 if (translated instanceof RubyProxyNode) {
1146 proxy = (RubyProxyNode) translated; 1170 proxy = (RubyProxyNode) translated;
1147 } else { 1171 } else {
1148 proxy = new RubyProxyNode(context, translated); 1172 proxy = new RubyProxyNode(context, translated);
1149 } 1173 }
1174 proxy.markAs(NodePhylum.ASSIGNMENT);
1150 context.getDebugManager().registerLocalDebugProxy(methodIdentifier, node.getName(), proxy.getProbeChain()); 1175 context.getDebugManager().registerLocalDebugProxy(methodIdentifier, node.getName(), proxy.getProbeChain());
1151 1176
1152 translated = proxy; 1177 translated = proxy;
1153 } 1178 }
1154 1179
1453 RubyNode translated = (RubyNode) node.getNextNode().accept(this); 1478 RubyNode translated = (RubyNode) node.getNextNode().accept(this);
1454 1479
1455 if (context.getConfiguration().getDebug()) { 1480 if (context.getConfiguration().getDebug()) {
1456 1481
1457 RubyProxyNode proxy; 1482 RubyProxyNode proxy;
1458 SourceSection sourceSection;
1459 if (translated instanceof RubyProxyNode) { 1483 if (translated instanceof RubyProxyNode) {
1460 proxy = (RubyProxyNode) translated; 1484 proxy = (RubyProxyNode) translated;
1461 sourceSection = proxy.getChild().getSourceSection(); 1485 if (proxy.getChild() instanceof CallNode) {
1486 // Special case; replace proxy with one registered by line, merge in information
1487 final CallNode callNode = (CallNode) proxy.getChild();
1488 final ProbeChain probeChain = proxy.getProbeChain();
1489
1490 proxy = new RubyProxyNode(context, callNode, probeChain);
1491 }
1462 } else { 1492 } else {
1463 proxy = new RubyProxyNode(context, translated); 1493 proxy = new RubyProxyNode(context, translated);
1464 sourceSection = translated.getSourceSection(); 1494 }
1465 } 1495 proxy.markAs(NodePhylum.STATEMENT);
1466 context.getDebugManager().registerProbeChain(sourceSection, proxy.getProbeChain());
1467 translated = proxy; 1496 translated = proxy;
1468 } 1497 }
1469 1498
1470 if (context.getConfiguration().getTrace()) { 1499 if (context.getConfiguration().getTrace()) {
1471 RubyProxyNode proxy; 1500 RubyProxyNode proxy;