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/