[前][次][番号順一覧][スレッド一覧]

ruby-changes:15173

From: knu <ko1@a...>
Date: Fri, 26 Mar 2010 04:12:04 +0900 (JST)
Subject: [ruby-changes:15173] Ruby:r27053 (ruby_1_8): * prelude.rb, Makefile.in, common.mk: Introduce prelude.rb.

knu	2010-03-26 04:11:51 +0900 (Fri, 26 Mar 2010)

  New Revision: 27053

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27053

  Log:
    * prelude.rb, Makefile.in, common.mk: Introduce prelude.rb.
    
    * eval.c (rb_eval_prelude): New function exported only for use in
      preludes.
    
    * configure.in: Define RUBY_EXEC_PREFIX and RUBY_LIB_PREFIX.
    
    * ruby.c (proc_options, ruby_init_loadpath, ruby_prelude): Load
      prelude.
    
    * compile_prelude.rb: Port the prelude compiler from trunk.
    
    * miniprelude.c: Currently miniruby does not include prelude.rb.

  Added files:
    branches/ruby_1_8/compile_prelude.rb
    branches/ruby_1_8/miniprelude.c
    branches/ruby_1_8/prelude.rb
  Modified files:
    branches/ruby_1_8/Makefile.in
    branches/ruby_1_8/common.mk
    branches/ruby_1_8/configure.in
    branches/ruby_1_8/eval.c
    branches/ruby_1_8/ruby.c

Index: ruby_1_8/Makefile.in
===================================================================
--- ruby_1_8/Makefile.in	(revision 27052)
+++ ruby_1_8/Makefile.in	(revision 27053)
@@ -51,7 +51,7 @@
 DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(EXTLDFLAGS) @ARCH_FLAG@
 SOLIBS = @SOLIBS@
 MAINLIBS = @MAINLIBS@
-MINIOBJS = @MINIOBJS@
+ARCHMINIOBJS = @MINIOBJS@
 
 RUBY_INSTALL_NAME=@RUBY_INSTALL_NAME@
 RUBY_SO_NAME=@RUBY_SO_NAME@
@@ -107,7 +107,7 @@
 
 miniruby$(EXEEXT):
 		@$(RM) $@
-		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
+		$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT) $(LIBS) $(OUTFLAG)$@
 
 $(PROGRAM):
 		@$(RM) $@
Index: ruby_1_8/prelude.rb
===================================================================
--- ruby_1_8/prelude.rb	(revision 0)
+++ ruby_1_8/prelude.rb	(revision 27053)
@@ -0,0 +1 @@
+# currently empty
Index: ruby_1_8/configure.in
===================================================================
--- ruby_1_8/configure.in	(revision 27052)
+++ ruby_1_8/configure.in	(revision 27053)
@@ -1829,6 +1829,8 @@
 RUBY_LIB_PATH="${RUBY_LIB_PREFIX}/${ruby_version}"
 RUBY_SITE_LIB_PATH2="${RUBY_SITE_LIB_PATH}/${ruby_version}"
 
+AC_DEFINE_UNQUOTED(RUBY_EXEC_PREFIX, "${RUBY_EXEC_PREFIX}")
+AC_DEFINE_UNQUOTED(RUBY_LIB_PREFIX, ${RUBY_LIB_PREFIX})
 AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}")
 AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_SITE_LIB_PATH}")
 AC_DEFINE_UNQUOTED(RUBY_SITE_LIB2, "${RUBY_SITE_LIB_PATH2}")
Index: ruby_1_8/miniprelude.c
===================================================================
--- ruby_1_8/miniprelude.c	(revision 0)
+++ ruby_1_8/miniprelude.c	(revision 27053)
@@ -0,0 +1,11 @@
+#include "ruby.h"
+
+void Init_prelude _((void));
+
+void Init_prelude()
+{
+    /*
+     * Do nada, meaning miniruby does not support features implemented
+     * in prelude.rb.
+     */
+}
Index: ruby_1_8/ruby.c
===================================================================
--- ruby_1_8/ruby.c	(revision 27052)
+++ ruby_1_8/ruby.c	(revision 27053)
@@ -254,6 +254,7 @@
 {
 #if defined LOAD_RELATIVE
     char libpath[FILENAME_MAX+1];
+    size_t baselen;
     char *p;
     int rest;
 #if defined _WIN32 || defined __CYGWIN__
@@ -298,12 +299,16 @@
 	strcpy(libpath, ".");
 	p = libpath + 1;
     }
+#define PREFIX_PATH() rb_str_new(libpath, baselen)
 
-    rest = FILENAME_MAX - (p - libpath);
+    baselen = p - libpath;
+    rest = FILENAME_MAX - baselen;
 
 #define RUBY_RELATIVE(path) (strncpy(p, (path), rest), libpath)
 #else
+    static const char exec_prefix[] = RUBY_EXEC_PREFIX;
 #define RUBY_RELATIVE(path) (path)
+#define PREFIX_PATH() rubylib_mangled_path(exec_prefix, sizeof(exec_prefix)-1)
 #endif
 #define incpush(path) rb_ary_push(rb_load_path, rubylib_mangled_path2(path))
 
@@ -338,6 +343,8 @@
     if (rb_safe_level() == 0) {
 	incpush(".");
     }
+
+    rb_const_set(rb_cObject, rb_intern("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
 }
 
 struct req_list {
@@ -481,7 +488,17 @@
     return s;
 }
 
+static void ruby_prelude _((void));
+void Init_prelude _((void));
+
 static void
+ruby_prelude()
+{
+    Init_prelude();
+    rb_const_remove(rb_cObject, rb_intern("TMP_RUBY_PREFIX"));
+}
+
+static void
 proc_options(argc, argv)
     int argc;
     char **argv;
@@ -841,6 +858,7 @@
     process_sflag();
 
     ruby_init_loadpath();
+    ruby_prelude();
     ruby_sourcefile = rb_source_filename(argv0);
     if (e_script) {
 	require_libraries();
Index: ruby_1_8/compile_prelude.rb
===================================================================
--- ruby_1_8/compile_prelude.rb	(revision 0)
+++ ruby_1_8/compile_prelude.rb	(revision 27053)
@@ -0,0 +1,187 @@
+# This file is interpreted by miniruby.
+# Do not use features that miniruby does not provide,
+# including what's in prelude.rb.
+
+require 'erb'
+
+class Prelude
+  SRCDIR = File.dirname(__FILE__)
+  $:.unshift(SRCDIR)
+
+  C_ESC = {
+    "\\" => "\\\\",
+    '"' => '\"',
+    "\n" => '\n',
+  }
+
+  0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
+  0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
+  C_ESC_PAT = Regexp.union(*C_ESC.keys)
+
+  def c_esc(str)
+    '"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"'
+  end
+  def prelude_base(filename)
+    filename[/\A#{Regexp.quote(SRCDIR)}\/(.*?)(\.rb)?\z/om, 1]
+  end
+  def prelude_name(filename)
+    "<internal:" + prelude_base(filename) + ">"
+  end
+
+  def initialize(preludes)
+    @mkconf = nil
+    @have_sublib = false
+    @need_ruby_prefix = false
+    @preludes = {}
+    @mains = preludes.map {|filename| translate(filename)[0]}
+  end
+
+  def translate(filename, sub = false)
+    idx = @preludes[filename]
+    return idx if idx
+    lines = []
+    @preludes[filename] = result = [@preludes.size, filename, lines, sub]
+    File.readlines(filename).each do |line|
+      line.gsub!(/RbConfig::CONFIG\["(\w+)"\]/) {
+        key = $1
+        unless @mkconf
+          require './rbconfig'
+          @mkconf = RbConfig::MAKEFILE_CONFIG.merge('prefix'=>'#{TMP_RUBY_PREFIX}')
+        end
+        if RbConfig::MAKEFILE_CONFIG.has_key? key
+          val = RbConfig.expand("$(#{key})", @mkconf)
+          @need_ruby_prefix ||= /\A\#\{TMP_RUBY_PREFIX\}/ =~ val
+          c_esc(val)
+        else
+          "nil"
+        end
+      }
+      line.sub!(/require\s*\(?\s*(["'])(.*?)\1\)?/) do
+        orig, path = $&, $2
+        path = File.join(SRCDIR, path)
+        if File.exist?(path)
+          @have_sublib = true
+          "TMP_RUBY_PREFIX.require(#{translate(path, true)[0]})"
+        else
+          orig
+        end
+      end
+      lines << c_esc(line)
+    end
+    result
+  end
+
+  def emit(outfile)
+    init_name = outfile[/\w+(?=_prelude.c\b)/] || 'prelude'
+    erb = ERB.new(<<'EOS', nil, '%')
+/* -*-c-*-
+ THIS FILE WAS AUTOGENERATED BY compile_prelude.rb. DO NOT EDIT.
+
+ soruces: <%= @preludes.map {|n,*| prelude_base(n)}.join(', ') %>
+*/
+#include "ruby.h"
+
+VALUE rb_eval_prelude _((VALUE, const char *));
+
+% preludes = @preludes.values.sort
+% preludes.each {|i, prelude, lines, sub|
+
+static const char prelude_name<%=i%>[] = <%=c_esc(prelude_name(*prelude))%>;
+static const char prelude_code<%=i%>[] =
+%   lines.each {|line|
+<%=line%>
+%   }
+;
+% }
+
+#define PRELUDE_COUNT <%=@have_sublib ? preludes.size : 0%>
+
+% if @have_sublib or @need_ruby_prefix
+struct prelude_env {
+    volatile VALUE prefix_path;
+#if PRELUDE_COUNT > 0
+    char loaded[PRELUDE_COUNT];
+#endif
+};
+
+static VALUE
+prelude_prefix_path(VALUE self)
+{
+    struct prelude_env *ptr = DATA_PTR(self);
+    return ptr->prefix_path;
+}
+% end
+
+% if @have_sublib
+static VALUE
+prelude_require(VALUE self, VALUE nth)
+{
+    struct prelude_env *ptr = DATA_PTR(self);
+    VALUE code;
+    const char *name;
+    int n = FIX2INT(nth);
+
+    if (n > PRELUDE_COUNT) return Qfalse;
+    if (ptr->loaded[n]) return Qfalse;
+    ptr->loaded[n] = 1;
+    switch (n) {
+%   @preludes.each_value do |i, prelude, lines, sub|
+%     if sub
+      case <%=i%>:
+	code = rb_str_new(prelude_code<%=i%>, sizeof(prelude_code<%=i%>) - 1);
+        name = prelude_name<%=i%>;
+	break;
+%     end
+%   end
+      default:
+	return Qfalse;
+    }
+    rb_eval_prelude(code, name);
+    return Qtrue;
+}
+
+% end
+void Init_<%=init_name%> _((void));
+
+void
+Init_<%=init_name%>()
+{
+% if @have_sublib or @need_ruby_prefix
+    struct prelude_env memo;
+    ID name = rb_intern("TMP_RUBY_PREFIX");
+    VALUE prelude = Data_Wrap_Struct(rb_cData, 0, 0, &memo);
+
+    memo.prefix_path = rb_const_remove(rb_cObject, name);
+    rb_const_set(rb_cObject, name, prelude);
+    rb_define_singleton_method(prelude, "to_s", prelude_prefix_path, 0);
+% end
+% if @have_sublib
+    memset(memo.loaded, 0, sizeof(memo.loaded));
+    rb_define_singleton_method(prelude, "require", prelude_require, 1);
+% end
+% preludes.each do |i, prelude, lines, sub|
+%   next if sub
+    rb_eval_prelude(rb_str_new(prelude_code<%=i%>, sizeof(prelude_code<%=i%>) - 1), prelude_name<%=i%>);
+% end
+% if @have_sublib or @need_ruby_prefix
+    rb_gc_force_recycle(prelude);
+% end
+
+#if 0
+% preludes.length.times {|i|
+    puts(prelude_code<%=i%>);
+% }
+#endif
+}
+EOS
+    tmp = erb.result(binding)
+    open(outfile, 'w'){|f|
+      f << tmp
+    }
+  end
+end
+
+preludes = ARGV.dup
+outfile = preludes.pop
+Prelude.new(preludes).emit(outfile)
+

Property changes on: ruby_1_8/compile_prelude.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:executable
   + *

Index: ruby_1_8/common.mk
===================================================================
--- ruby_1_8/common.mk	(revision 27052)
+++ ruby_1_8/common.mk	(revision 27053)
@@ -20,8 +20,9 @@
 MAINOBJ	      = main.$(OBJEXT)
 EXTOBJS	      = 
 DLDOBJS	      = $(DMYEXT)
+MINIOBJS      = $(ARCHMINIOBJS) miniprelude.$(OBJEXT)
 
-OBJS	      = array.$(OBJEXT) \
+COMMONOBJS    = array.$(OBJEXT) \
 		bignum.$(OBJEXT) \
 		class.$(OBJEXT) \
 		compar.$(OBJEXT) \
@@ -60,6 +61,11 @@
 		version.$(OBJEXT) \
 		$(MISSING)
 
+OBJS          = $(COMMONOBJS) prelude.$(OBJEXT)
+
+PRELUDE_SCRIPTS = $(srcdir)/prelude.rb
+PRELUDES      = prelude.c miniprelude.c
+
 SCRIPT_ARGS   =	--dest-dir="$(DESTDIR)" \
 		--extout="$(EXTOUT)" \
 		--mflags="$(MFLAGS)" \
@@ -81,6 +87,8 @@
 
 VCS           = svn
 
+COMPILE_PRELUDE = $(MINIRUBY) -I$(srcdir) $(srcdir)/compile_prelude.rb
+
 all: main $(RDOCTARGET)
 
 main: exts
@@ -93,7 +101,7 @@
 
 prog: $(PROGRAM) $(WPROGRAM)
 
-miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) $(MINIOBJS) $(OBJS) $(DMYEXT)
+miniruby$(EXEEXT): config.status $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT)
 
 $(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
 
@@ -307,7 +315,7 @@
 distclean: distclean-ext distclean-local
 distclean-local:: clean-local
 	@$(RM) $(MKFILES) config.h rbconfig.rb
-	@$(RM) config.cache config.log config.status
+	@$(RM) config.cache config.log config.status $(PRELUDES)
 	@$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)
 distclean-ext::
 
@@ -455,6 +463,12 @@
 version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \
   {$(VPATH)}version.h {$(VPATH)}revision.h
 
+prelude.c: $(srcdir)/compile_prelude.rb $(RBCONFIG) $(PRELUDE_SCRIPTS) $(PREP)
+	$(COMPILE_PRELUDE) $(PRELUDE_SCRIPTS) $@
+
+miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c $(RUBY_H_INCLUDES)
+prelude.$(OBJEXT): {$(VPATH)}prelude.c $(RUBY_H_INCLUDES)
+
 dist: $(PROGRAM)
 	$(RUNRUBY) $(srcdir)/distruby.rb
 
Index: ruby_1_8/eval.c
===================================================================
--- ruby_1_8/eval.c	(revision 27052)
+++ ruby_1_8/eval.c	(revision 27053)
@@ -6722,6 +6722,14 @@
     return result;
 }
 
+VALUE
+rb_eval_prelude(src, name)
+    VALUE src;
+    const char *name;
+{
+    return eval(ruby_top_self, src, Qnil, name, 1);
+}
+
 /*
  *  call-seq:
  *     eval(string [, binding [, filename [,lineno]]])  => obj

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]