[#1378] differences between Module and Class ? — Mathieu Bouchard <matju@...>

25 messages 2003/08/11
[#1387] Re: differences between Module and Class ? — matz@... (Yukihiro Matsumoto) 2003/08/12

Hi,

[#1442] Re: differences between Module and Class ? — Mathieu Bouchard <matju@...> 2003/08/21

[#1406] _id2ref bug? — Ryan Pavlik <rpav@...>

While debugging some caching code, I've come across a segfault related

22 messages 2003/08/14
[#1407] Re: _id2ref bug? — matz@... (Yukihiro Matsumoto) 2003/08/14

Hi,

[#1413] Re: _id2ref bug? (REPRODUCED, short) — Ryan Pavlik <rpav@...> 2003/08/14

On Fri, 15 Aug 2003 01:57:18 +0900

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

In This Thread