Re: NODE_DSTR and NODE_EVSTR?
From:
nobu.nokada@...
Date:
2003-08-22 12:42:52 UTC
List:
ruby-core #1457
Hi,
At Fri, 22 Aug 2003 21:00:47 +0900,
Robert Feldt wrote:
> >> How are "dynamic" strings represented internally?
> >
> > NodeDump or ii would help you.
> >
> Have you been able to compile them with 1.8? I haven't.
Hmmm, the latest in PragProg site still seems 0.1.7 for 1.6.
This is my own patch to NodeDump 0.1.7.
diff -ru2pN nodeDump-0.1.7/MANIFEST nodeDump-0.1.7+/MANIFEST
--- nodeDump-0.1.7/MANIFEST 1970-01-01 09:00:00.000000000 +0900
+++ nodeDump-0.1.7+/MANIFEST 2003-07-29 12:10:48.000000000 +0900
@@ -0,0 +7 @@
+MANIFEST
+README
+depend
+extconf.rb
+makenodenames.rb
+nd_version.h
+nodeDump.c
diff -ru2pN nodeDump-0.1.7/depend nodeDump-0.1.7+/depend
--- nodeDump-0.1.7/depend 1970-01-01 09:00:00.000000000 +0900
+++ nodeDump-0.1.7+/depend 2003-07-28 01:03:05.000000000 +0900
@@ -0,0 +1,4 @@
+node_names.h: $(hdrdir)/node.h
+ $(RUBY) $(srcdir)/makenodenames.rb $< $@
+
+nodeDump.o: node_names.h
diff -ru2pN nodeDump-0.1.7/extconf.rb nodeDump-0.1.7+/extconf.rb
--- nodeDump-0.1.7/extconf.rb 2002-06-18 00:44:02.000000000 +0900
+++ nodeDump-0.1.7+/extconf.rb 2003-07-28 01:00:39.000000000 +0900
@@ -3,114 +3,6 @@
# for the typedef.
#
-
-
require 'mkmf'
-require "rbconfig"
-
-# Return the full path to node.h
-
-def nameOfNode_h
- cfg = Config::CONFIG
- srcdir = cfg["srcdir"]
- libdir = cfg["libdir"]+"/ruby/"+cfg["MAJOR"]+"."+cfg["MINOR"]
- archdir = libdir+"/"+cfg["arch"]
-
- if File.exist? archdir + "/ruby.h"
- hdrdir = archdir
- else File.exist? srcdir + "/ruby.h"
- hdrdir = srcdir
- end
-
- hdrdir + "/node.h"
-end
-
-# Given a list of node names, check that our nodeDump.c file
-# handles them all
-
-# these are internal Ruby nodes that don't appear in a parse tree
-
-DUMMY_NODES = %w( NODE_MEMO NODE_LAST NODE_ALLOCA NODE_CNAME
- NODE_CFUNC NODE_IFUNC NODE_RESBODY)
-
-
-def checkWeHandle(nameList)
- nodes = File.new(File.join(File.dirname($0), "nodeDump.c")).grep(/case\s+(NODE_\w+):/) { $1 }
- inRubyNotDump = nameList - nodes - DUMMY_NODES
- inDumpNotRuby = nodes - nameList
-
- if !inRubyNotDump.empty?
- $stderr.print "\n\nNodes we don't handle:\n", inRubyNotDump.join(", "), "\n"
- end
-
- if !inDumpNotRuby.empty?
- $stderr.print "\n\nNodes we handle not in Ruby:\n", inDumpNotRuby.join(", "), "\n"
- end
-
- # fail if there's anything in Ruby that we don't now about
- return inRubyNotDump.empty?
-end
-
-
-# Create a node_names.h file containing enum -> name mappings
-
-def createNodeNames
-
- nameList = []
-
- node = nameOfNode_h()
-
- File.open("node_names.h", "w") do |op|
-
- copying = false
-
- op.puts "const char *node_names[] = {"
-
- IO.foreach(node) do |line|
-
- if copying
- if line =~ /\};/
- copying = false
- else
- if line =~ /^#/
- op.puts line
- else
- if line =~ /\s*(\w+)(,)?/
- op.puts "\t\"#$1\"#$2"
- op.puts "\#define\t #{$1} #{$1}"
- nameList << $1
- end
- end
- end
- end
-
- copying = true if line =~ /enum node_type/
- end
-
- op.puts "};"
- end
-
- checkWeHandle(nameList)
-end
-
-if createNodeNames()
-
- have_func("rb_proc_new", "ruby.h")
-
- $CPPFLAGS << " -I."
- create_makefile("NodeDump")
-
-else
-
- $stderr.puts <<_EOM_
-
-=================================================================
-
-NodeDump can not be built on this system. This is probably due to
-an incompatibility with Ruby versions. This version of NodeDump
-only runs with Ruby 1.6 or later.
-
-=================================================================
-
-_EOM_
-end
+have_func("rb_proc_new", "ruby.h")
+create_makefile("NodeDump")
diff -ru2pN nodeDump-0.1.7/makenodenames.rb nodeDump-0.1.7+/makenodenames.rb
--- nodeDump-0.1.7/makenodenames.rb 1970-01-01 09:00:00.000000000 +0900
+++ nodeDump-0.1.7+/makenodenames.rb 2003-07-28 00:59:44.000000000 +0900
@@ -0,0 +1,71 @@
+#! /usr/bin/ruby
+
+class NodeList
+ DUMMY = %w( NODE_MEMO NODE_LAST NODE_ALLOCA NODE_CNAME
+ NODE_CFUNC NODE_IFUNC NODE_RESBODY)
+
+ def initialize(node, src = File.join(File.dirname(__FILE__), "nodeDump.c"))
+ @in_dump = File.new(src).grep(/case\s+(NODE_\w+):/) {$1}
+ copying = false
+ @in_ruby = []
+ @source = []
+ IO.foreach(node) do |line|
+ if copying
+ case line
+ when /\};/
+ break
+ when /^#/
+ @source << line
+ when /\s*(\w+)(,)?/
+ @source << "\t\"#$1\"#$2"
+ @source << "\#define\t #{$1} #{$1}"
+ @in_ruby << $1
+ end
+ elsif line =~ /enum node_type/
+ copying = true
+ end
+ end
+ end
+
+ def handle?
+ inRubyNotDump = @in_ruby - @in_dump - DUMMY
+ inDumpNotRuby = @in_dump - @in_ruby
+ unless inRubyNotDump.empty?
+ $deferr.puts "\n\nNodes we don't handle:", inRubyNotDump.join(", ")
+ end
+ unless inDumpNotRuby.empty?
+ $deferr.puts "\n\nNodes we handle not in Ruby:", inDumpNotRuby.join(", ")
+ end
+ inRubyNotDump.empty?
+ end
+
+ # Create a node_names.h file containing enum -> name mappings
+ def create(out)
+ out.puts "#ifndef NODE_NAMES_H"
+ out.puts "#define NODE_NAMES_H"
+ out.puts "const char *node_names[] = {"
+ out.puts @source
+ out.puts "};"
+ out.puts "#endif /* NODE_NAMES_H */"
+ end
+end
+
+# (1..2) === ARGV.size or abort "usage: #$0 node.h [node_names.h]"
+
+nodes = NodeList.new(ARGV.shift)
+nodes.handle? or abort <<_EOM_
+
+=================================================================
+
+NodeDump can not be built on this system. This is probably due to
+an incompatibility with Ruby versions. This version of NodeDump
+only runs with Ruby 1.6 or later.
+
+=================================================================
+
+_EOM_
+if ARGV.empty?
+ nodes.create($defout)
+else
+ File.open(ARGV.shift, "w") {|op| nodes.create(op)}
+end
diff -ru2pN nodeDump-0.1.7/nodeDump.c nodeDump-0.1.7+/nodeDump.c
--- nodeDump-0.1.7/nodeDump.c 2002-07-11 22:37:39.000000000 +0900
+++ nodeDump-0.1.7+/nodeDump.c 2003-03-26 16:35:17.000000000 +0900
@@ -32,4 +32,6 @@ struct global_entry {
};
+static void doDump(NODE *n, int level);
+
static void lp(int level, const char *fmt, ...) {
va_list ap;
@@ -57,4 +59,23 @@ static char * tail(char* s, char *e)
}
+static void
+dump_cpath(const char *s, NODE *cpath, int level)
+{
+ ID id;
+ if (SPECIAL_CONST_P(cpath)) {
+ id = (ID)cpath;
+ cpath = 0;
+ }
+ else {
+ id = cpath->nd_mid;
+ if (cpath->nd_head) {
+ p(" %s %d (%s) in\n", s, id, rb_id2name(id));
+ doDump(cpath->nd_head, level+2);
+ return;
+ }
+ }
+ p(" class %d (%s)\n", id, rb_id2name(id));
+}
+
static void dumpLiteral(long lit, int level) {
@@ -90,5 +111,6 @@ static void dumpValue(VALUE v, int level
}
-static void doDump(NODE *n, int level) {
+static void doDump(NODE *n, int level)
+{
NODE *n1;
@@ -103,5 +125,4 @@ static void doDump(NODE *n, int level) {
lp(level, "%s: ", node_names[type]);
- again:
switch (type) {
@@ -117,10 +138,9 @@ static void doDump(NODE *n, int level) {
case NODE_OR:
nl();
- doDump(n->nd_1st, level + 1);
- if (n->nd_2nd && nd_type(n->nd_2nd)) {
- n = n->nd_2nd;
- goto again;
- }
- doDump(n->nd_2nd, level + 1);
+ ++level;
+ do {
+ doDump(n->nd_1st, level);
+ } while (n->nd_2nd && (type == nd_type(n = n->nd_2nd)));
+ doDump(n, level);
break;
@@ -196,4 +216,7 @@ static void doDump(NODE *n, int level) {
case NODE_CALL:
case NODE_FCALL:
+#ifdef NODE_ATTRASGN
+ case NODE_ATTRASGN:
+#endif
if (type == NODE_FCALL) {
p(" to function: %d (%s)\n", n->nd_mid, rb_id2name(n->nd_mid));
@@ -202,5 +225,10 @@ static void doDump(NODE *n, int level) {
p(" to method: %d (%s)\n", n->nd_mid, rb_id2name(n->nd_mid));
lp(level, "Receiver:\n");
- doDump(n->nd_recv, level+1);
+ if (n->nd_recv == (NODE *)1) {
+ lp(level, "%s: ", node_names[NODE_SELF]);
+ }
+ else {
+ doDump(n->nd_recv, level+1);
+ }
}
@@ -254,6 +282,10 @@ static void doDump(NODE *n, int level) {
case NODE_CLASS:
+#ifdef nd_cpath
+ dump_cpath("class", n->nd_cpath, level);
+#else
id = n->nd_cname;
p(" class %d (%s)\n", id, rb_id2name(id));
+#endif
if (n->nd_super) {
lp(level+1, "Superclass:\n");
@@ -352,4 +384,7 @@ static void doDump(NODE *n, int level) {
case NODE_DREGX:
case NODE_DREGX_ONCE:
+#ifdef NODE_DSYM
+ case NODE_DSYM:
+#endif
dumpLiteral(n->nd_lit, level+1);
n1 = n->nd_next;
@@ -460,10 +495,15 @@ static void doDump(NODE *n, int level) {
break;
- case NODE_LIT:
case NODE_EVSTR:
+ if (!n->nd_lit) {
+ nl();
+ doDump(n->nd_body, level+1);
+ break;
+ }
+ case NODE_LIT:
case NODE_XSTR:
dumpLiteral(n->nd_lit, level+1);
break;
-
+
case NODE_LVAR:
p(" LV %d (%s)\n", n->nd_cnt, rb_id2name(n->nd_vid));
@@ -499,6 +539,10 @@ static void doDump(NODE *n, int level) {
case NODE_MODULE:
+#ifdef nd_cpath
+ dump_cpath("module", n->nd_cpath, level);
+#else
id = n->nd_cname;
p(" module %d (%s)\n", id, rb_id2name(id));
+#endif
doDump(n->nd_body, level+1);
break;
@@ -609,11 +653,22 @@ static void doDump(NODE *n, int level) {
break;
+#ifdef NODE_RESTARGS
case NODE_RESTARGS:
+#endif
#ifdef NODE_RESTARY
case NODE_RESTARY:
#endif
+#ifdef NODE_RESTARY2
+ case NODE_RESTARY2:
+#endif
#ifdef NODE_REXPAND
case NODE_REXPAND:
#endif
+#ifdef NODE_SPLAT
+ case NODE_SPLAT:
+#endif
+#ifdef NODE_SVALUE
+ case NODE_SVALUE:
+#endif
nl();
doDump(n->nd_head, level+1);
@@ -672,8 +727,14 @@ static void doDump(NODE *n, int level) {
case NODE_WHILE:
nl();
- lp(level+1, "Condition:\n");
- doDump(n->nd_cond, level+2);
+ if (n->nd_state) {
+ lp(level+1, "Condition:\n");
+ doDump(n->nd_cond, level+2);
+ }
lp(level+1, "Body:\n");
doDump(n->nd_body, level+2);
+ if (!n->nd_state) {
+ lp(level+1, "Condition:\n");
+ doDump(n->nd_cond, level+2);
+ }
break;
--
Nobu Nakada