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

ruby-changes:15091

From: nobu <ko1@a...>
Date: Thu, 18 Mar 2010 04:45:52 +0900 (JST)
Subject: [ruby-changes:15091] Ruby:r26968 (mvm): * merged from trunk r26939:26967.

nobu	2010-03-18 04:45:21 +0900 (Thu, 18 Mar 2010)

  New Revision: 26968

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

  Log:
    * merged from trunk r26939:26967.

  Added directories:
    branches/mvm/ext/tmpdir/
  Modified files:
    branches/mvm/.merged-trunk-revision
    branches/mvm/ChangeLog
    branches/mvm/NEWS
    branches/mvm/compile.c
    branches/mvm/configure.in
    branches/mvm/enc/trans/chinese.trans
    branches/mvm/enc/trans/emoji.trans
    branches/mvm/enc/trans/single_byte.trans
    branches/mvm/ext/bigdecimal/bigdecimal.c
    branches/mvm/file.c
    branches/mvm/hash.c
    branches/mvm/include/ruby/encoding.h
    branches/mvm/include/ruby/ruby.h
    branches/mvm/iseq.c
    branches/mvm/lib/tmpdir.rb
    branches/mvm/lib/uri/common.rb
    branches/mvm/load.c
    branches/mvm/parse.y
    branches/mvm/prelude.rb
    branches/mvm/ruby.c
    branches/mvm/test/ruby/test_m17n_comb.rb
    branches/mvm/test/ruby/test_string.rb
    branches/mvm/test/uri/test_common.rb
    branches/mvm/tool/transcode-tblgen.rb
    branches/mvm/util.c
    branches/mvm/version.h
    branches/mvm/vm.c
    branches/mvm/vm_core.h
    branches/mvm/vm_eval.c
    branches/mvm/win32/win32.c

Index: mvm/prelude.rb
===================================================================
--- mvm/prelude.rb	(revision 26967)
+++ mvm/prelude.rb	(revision 26968)
@@ -22,17 +22,3 @@
     }
   end
 end
-
-module Kernel
-  module_function
-  def require_relative(relative_feature)
-    c = caller.first
-    e = c.rindex(/:\d+:in /)
-    file = $`
-    if /\A\((.*)\)/ =~ file # eval, etc.
-      raise LoadError, "require_relative is called in #{$1}"
-    end
-    absolute_feature = File.join(File.dirname(File.realpath(file)), relative_feature)
-    require absolute_feature
-  end
-end
Index: mvm/include/ruby/ruby.h
===================================================================
--- mvm/include/ruby/ruby.h	(revision 26967)
+++ mvm/include/ruby/ruby.h	(revision 26968)
@@ -1104,7 +1104,7 @@
 NORETURN(void rb_exit(int));
 NORETURN(void rb_notimplement(void));
 
-/* reports if `-w' specified */
+/* reports if `-W' specified */
 PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2);
 PRINTF_ARGS(void rb_compile_warning(const char *, int, const char*, ...), 3, 4);
 PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2);
Index: mvm/include/ruby/encoding.h
===================================================================
--- mvm/include/ruby/encoding.h	(revision 26967)
+++ mvm/include/ruby/encoding.h	(revision 26968)
@@ -95,6 +95,7 @@
 VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *);
 VALUE rb_str_export_to_enc(VALUE, rb_encoding *);
 VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to);
+VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts);
 
 /* index -> rb_encoding */
 rb_encoding* rb_enc_from_index(int idx);
@@ -197,7 +198,7 @@
 #define ENC_DUMMY_FLAG (1<<24)
 #define ENC_INDEX_MASK (~(~0U<<24))
 
-#define ENC_TO_ENCINDEX(enc)   ((enc)->ruby_encoding_index & ENC_INDEX_MASK)
+#define ENC_TO_ENCINDEX(enc) (int)((enc)->ruby_encoding_index & ENC_INDEX_MASK)
 
 #define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG)
 #define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG)
Index: mvm/configure.in
===================================================================
--- mvm/configure.in	(revision 26967)
+++ mvm/configure.in	(revision 26968)
@@ -1349,9 +1349,9 @@
 	rb_cv_rshift_sign=yes,
 	rb_cv_rshift_sign=no)])
 if test "$rb_cv_rshift_sign" = yes; then
-  AC_DEFINE(RSHIFT(x,y), ((x)>>((int)y)))
+  AC_DEFINE(RSHIFT(x,y), ((x)>>(int)(y)))
 else
-  AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>(y)) : (x)>>(y)))
+  AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>(int)(y)) : (x)>>(int)(y)))
 fi
 
 test "$rb_cv_fcnt" = "not found" && rb_cv_fcnt="not found (OK if using GNU libc)"
Index: mvm/ChangeLog
===================================================================
--- mvm/ChangeLog	(revision 26967)
+++ mvm/ChangeLog	(revision 26968)
@@ -1,3 +1,132 @@
+Thu Mar 18 04:40:56 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (rb_intern3): get rid of type-punning cast.
+
+Thu Mar 18 02:29:42 2010  Yusuke Endoh  <mame@t...>
+
+	* compile.c (iseq_build_body): add mark to jump table hash of case.
+
+Thu Mar 18 00:58:27 2010  NARUSE, Yui  <naruse@r...>
+
+	* util.c (ruby_strtod): Add support for Hexadecimal
+	  floating-point expression [ruby-dev:40650] #2969
+
+Thu Mar 18 00:00:58 2010  NARUSE, Yui  <naruse@r...>
+
+	* lib/uri/common.rb (URI#{en,de}code_www_form_component):
+	  renamed from URI#{en,de}code_www_component. [ruby-dev:40672]
+
+	* lib/uri/common.rb (URI#encode_www_form_component): %-encoded
+	  element should have always two hex.
+
+	* lib/uri/common.rb (URI#encode_www_form_component):
+	  better treatment for ASCII incompatible encodings and
+	  encodings whose lead byte may use 7bit.
+
+	* lib/uri/common.rb (URI#decode_www_form_component): add %20.
+
+	* lib/uri/common.rb (URI#decode_www_form_component): add
+	  result's encoding as 2nd argument.
+
+	* lib/uri/common.rb (URI#decode_www_form): added.
+
+Wed Mar 17 16:25:53 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* hash.c (rb_hash_aset): allow recursive key.  [ruby-core:24648]
+
+Wed Mar 17 06:39:59 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* ruby.h (rb_warning, rb_sys_warning): fixed typo in rdoc.
+	  [ruby-core:28696]
+
+Wed Mar 17 02:29:46 2010  Yusuke Endoh  <mame@t...>
+
+	* compile.c, iseq.c, ruby.c, vm.c, vm_core.h, vm_eval.c: add absolute
+	  path field into rb_iseq_t.  The field contains a string representing
+	  a path to corresponding source file. or nil when the iseq is created
+	  from -e, stdin, eval, etc.  This field is used for require_relative.
+	  [ruby-dev:40004]
+
+	* load.c (rb_f_require_relative): add C implementation of
+	  require_relative.
+
+	* prelude.rb (require_relative): get rid of Ruby implementation of
+	  require_relative.
+
+Wed Mar 17 01:24:01 2010  Yusuke Endoh  <mame@t...>
+
+	* parse.y (rb_intern3): prohibit Symbol with an invalid encoding.
+	  [ruby-core:24621]
+
+	* test/ruby/test_m17n_comb.rb: modify a test for above.
+
+Tue Mar 16 22:51:11 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb: specialize for singleton mappings.
+
+Tue Mar 16 20:13:00 2010  Kenta Murata  <mrkn@m...>
+
+	* enc/trans/emoji.trans: added codepoints leading 0xf4 into
+	  nomap_table.
+
+Tue Mar 16 17:33:30 2010  NARUSE, Yui  <naruse@r...>
+
+	* ext/bigdecimal/bigdecimal.c (VpCtoV): keep e's sign.
+	  When e doesn't over flow e * BASE_FIG but overflow e * 10,
+	  e will overflow.
+
+Tue Mar 16 17:18:44 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* include/ruby/encoding.h (rb_str_conv_enc_opts): missing prototype.
+
+Tue Mar 16 15:20:13 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/tmpdir: split from lib/tmpdir.rb.
+
+	* win32/win32.c (rb_w32_system_tmpdir): extracted from init_env.
+
+	* win32/win32.c (rb_w32_getcwd): removed duplicated code.
+
+Tue Mar 16 14:06:13 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* include/ruby/encoding.h (ENC_TO_ENCINDEX): suppress warnings.
+
+Tue Mar 16 14:03:24 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* configure.in (RSHIFT): parenthesize the argument of cast instead
+	  of the result.
+
+Tue Mar 16 11:23:42 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* file.c (file_expand_path): ignore dname if it has different
+	  drive letter or UNC.
+
+Tue Mar 16 07:16:56 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb: redundant loop removed.
+
+Tue Mar 16 07:01:43 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb: refactored to use tree as memo key.
+
+Tue Mar 16 04:05:13 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb: more info in generating macro names.
+
+Mon Mar 15 21:58:03 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb: ActionMap#each_firstbyte inlined.
+
+Mon Mar 15 21:22:49 2010  Tanaka Akira  <akr@f...>
+
+	* tool/transcode-tblgen.rb (transcode_tblgen): add valid_encoding
+	  optional argument.
+
+	* enc/trans/single_byte.trans use valid_encoding argument for
+	  transcode_tblgen.
+
+	* enc/trans/chinese.trans: ditto.
+
 Mon Mar 15 18:33:36 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* random.c (default_rand): removed initial buffer.
@@ -111,7 +240,7 @@
 
 	* tool/transcode-tblgen.rb: reject ambiguous mapping.
 
-	* enc/trans/single_byte.trans: remove ambiguous maping such as
+	* enc/trans/single_byte.trans: remove ambiguous mapping such as
 	  \xD6 -> U+05F2 and \xD6\xC7 -> U+FB1F in Windows-1255
 
 Sat Mar 13 23:48:27 2010  Yukihiro Matsumoto  <matz@r...>
@@ -124,7 +253,7 @@
 
 Sat Mar 13 17:48:43 2010  Nobuyoshi Nakada  <nobu@r...>
 
-	* tool/file2lastrev.rb: refactord.  fixed changed revision of git.
+	* tool/file2lastrev.rb: refactored.  fixed changed revision of git.
 
 Sat Mar 13 15:44:20 2010  Yukihiro Matsumoto  <matz@r...>
 
@@ -465,7 +594,7 @@
 
 Wed Mar  3 06:19:25 2010  Nobuyoshi Nakada  <nobu@r...>
 
-	* win32/win32.c (signbig): defined.
+	* win32/win32.c (signbit): defined.
 
 	* win32/Makefile.sub, symbian/setup (config.h): pack.c requires
 	  SIZEOF_INT*_T now.
Index: mvm/enc/trans/chinese.trans
===================================================================
--- mvm/enc/trans/chinese.trans	(revision 26967)
+++ mvm/enc/trans/chinese.trans	(revision 26968)
@@ -1,16 +1,18 @@
 #include "transcode_data.h"
 
 <%
-  set_valid_byte_pattern 'GB2312', 'EUC-KR'
-  set_valid_byte_pattern 'GB12345', 'EUC-KR'
+  gb2312_valid_byte_pattern = ValidEncoding['EUC-KR']
+  gb12345_valid_byte_pattern = ValidEncoding['EUC-KR']
 
   transcode_tblgen "GB2312", "UTF-8",
   [["{00-7f}", :nomap]] +
-  citrus_decode_mapsrc("euc", 0x8080, "GB2312/UCS")
+  citrus_decode_mapsrc("euc", 0x8080, "GB2312/UCS"),
+  gb2312_valid_byte_pattern
 
   transcode_tblgen "GB12345", "UTF-8",
   [["{00-7f}", :nomap]] +
-  citrus_decode_mapsrc("euc", 0x8080, "GB12345/UCS")
+  citrus_decode_mapsrc("euc", 0x8080, "GB12345/UCS"),
+  gb12345_valid_byte_pattern
 
   transcode_tblgen "UTF-8", "GB2312",
   [["{00-7f}", :nomap]] +
Index: mvm/enc/trans/emoji.trans
===================================================================
--- mvm/enc/trans/emoji.trans	(revision 26967)
+++ mvm/enc/trans/emoji.trans	(revision 26968)
@@ -12,6 +12,7 @@
     ["{ee-ef}{80-bf}{80-bf}", :nomap0],
     ["f0{90-bf}{80-bf}{80-bf}", :nomap0],
     ["{f1-f3}{80-bf}{80-bf}{80-bf}", :nomap0],
+    ["f4{80-8f}{80-bf}{80-bf}", :nomap0],
   ]
 
   companies = %w(DoCoMo KDDI SoftBank Unicode)
Index: mvm/enc/trans/single_byte.trans
===================================================================
--- mvm/enc/trans/single_byte.trans	(revision 26967)
+++ mvm/enc/trans/single_byte.trans	(revision 26968)
@@ -22,9 +22,8 @@
     require(name.downcase + "-tbl")
     control1_if_needed = (name =~ /^ISO-8859/) ? CONTROL1_TO_UCS_TBL : []
     tbl_to_ucs = control1_if_needed + eval(name.gsub(/-/, '_') + "_TO_UCS_TBL")
-    set_valid_byte_pattern(name, '1byte')
     code = ''
-    code << transcode_tblgen(name, "UTF-8", [["{00-7f}", :nomap], *tbl_to_ucs.reject {|a, b| a.length != 2 }])
+    code << transcode_tblgen(name, "UTF-8", [["{00-7f}", :nomap], *tbl_to_ucs.reject {|a, b| a.length != 2 }], '{00-ff}')
     code << "\n"
     code << transcode_tblgen("UTF-8", name, [["{00-7f}", :nomap], *tbl_to_ucs.map {|a,b| [b,a] }])
     code
Index: mvm/vm_core.h
===================================================================
--- mvm/vm_core.h	(revision 26967)
+++ mvm/vm_core.h	(revision 26968)
@@ -158,6 +158,7 @@
     VALUE type;          /* instruction sequence type */
     VALUE name;	         /* String: iseq name */
     VALUE filename;      /* file information where this sequence from */
+    VALUE filepath;      /* real file path or nil */
     VALUE *iseq;         /* iseq (insn number and openrads) */
     VALUE *iseq_encoded; /* encoded iseq */
     unsigned long iseq_size;
@@ -537,11 +538,11 @@
 } rb_thread_t;
 
 /* iseq.c */
-VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
-VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent);
-VALUE rb_iseq_new_main(NODE *node, VALUE filename);
-VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
-VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*);
+VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent);
+VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath);
+VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*);
 VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
 VALUE rb_iseq_disasm(VALUE self);
 int rb_iseq_disasm_insn(VALUE str, VALUE *iseqval, size_t pos, rb_iseq_t *iseq, VALUE child);
Index: mvm/iseq.c
===================================================================
--- mvm/iseq.c	(revision 26967)
+++ mvm/iseq.c	(revision 26968)
@@ -96,6 +96,7 @@
 	RUBY_MARK_UNLESS_NULL(iseq->mark_ary);
 	RUBY_MARK_UNLESS_NULL(iseq->name);
 	RUBY_MARK_UNLESS_NULL(iseq->filename);
+	RUBY_MARK_UNLESS_NULL(iseq->filepath);
 	RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack);
 	RUBY_MARK_UNLESS_NULL(iseq->klass);
 	RUBY_MARK_UNLESS_NULL(iseq->coverage);
@@ -205,9 +206,11 @@
     }
 }
 
+VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict);
+
 static VALUE
 prepare_iseq_build(rb_iseq_t *iseq,
-		   VALUE name, VALUE filename, VALUE line_no,
+		   VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
 		   VALUE parent, VALUE type, VALUE block_opt,
 		   const rb_compile_option_t *option)
 {
@@ -216,6 +219,7 @@
 
     iseq->name = name;
     iseq->filename = filename;
+    iseq->filepath = filepath == Qnil ? Qnil : rb_realpath_internal(Qnil, filepath, 1);
     iseq->line_no = line_no;
     iseq->defined_method_id = 0;
     iseq->mark_ary = rb_ary_tmp_new(3);
@@ -359,31 +363,31 @@
 }
 
 VALUE
-rb_iseq_new(NODE *node, VALUE name, VALUE filename,
+rb_iseq_new(NODE *node, VALUE name, VALUE filename, VALUE filepath,
 	      VALUE parent, VALUE type)
 {
-    return rb_iseq_new_with_opt(node, name, filename, INT2FIX(0), parent, type,
+    return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, type,
 				&COMPILE_OPTION_DEFAULT);
 }
 
 VALUE
-rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent)
+rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent)
 {
-    return rb_iseq_new_with_opt(node, name, filename, INT2FIX(0), parent, ISEQ_TYPE_TOP,
+    return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, ISEQ_TYPE_TOP,
 				&COMPILE_OPTION_DEFAULT);
 }
 
 VALUE
-rb_iseq_new_main(NODE *node, VALUE filename)
+rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath)
 {
     rb_thread_t *th = GET_THREAD();
     VALUE parent = th->base_block->iseq->self;
-    return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), filename, INT2FIX(0),
+    return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), filename, filepath, INT2FIX(0),
 				parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
 }
 
 static VALUE
-rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE line_no,
+rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
 				VALUE parent, VALUE type, VALUE bopt,
 				const rb_compile_option_t *option)
 {
@@ -393,28 +397,28 @@
     GetISeqPtr(self, iseq);
     iseq->self = self;
 
-    prepare_iseq_build(iseq, name, filename, line_no, parent, type, bopt, option);
+    prepare_iseq_build(iseq, name, filename, filepath, line_no, parent, type, bopt, option);
     rb_iseq_compile_node(self, node);
     cleanup_iseq_build(iseq);
     return self;
 }
 
 VALUE
-rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE line_no,
+rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
 		     VALUE parent, VALUE type,
 		     const rb_compile_option_t *option)
 {
     /* TODO: argument check */
-    return rb_iseq_new_with_bopt_and_opt(node, name, filename, line_no, parent, type,
+    return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type,
 					   Qfalse, option);
 }
 
 VALUE
-rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE line_no,
+rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE line_no,
 		       VALUE parent, VALUE type, VALUE bopt)
 {
     /* TODO: argument check */
-    return rb_iseq_new_with_bopt_and_opt(node, name, filename, line_no, parent, type,
+    return rb_iseq_new_with_bopt_and_opt(node, name, filename, filepath, line_no, parent, type,
 					   bopt, &COMPILE_OPTION_DEFAULT);
 }
 
@@ -428,7 +432,7 @@
     VALUE iseqval = iseq_alloc(self);
 
     VALUE magic, version1, version2, format_type, misc;
-    VALUE name, filename, line_no;
+    VALUE name, filename, filepath, line_no;
     VALUE type, body, locals, args, exception;
 
     VALUE iseq_type;
@@ -452,6 +456,7 @@
 
     name        = CHECK_STRING(rb_ary_entry(data, i++));
     filename    = CHECK_STRING(rb_ary_entry(data, i++));
+    filepath    = CHECK_STRING(rb_ary_entry(data, i++));
     line_no     = CHECK_INTEGER(rb_ary_entry(data, i++));
 
     type        = CHECK_SYMBOL(rb_ary_entry(data, i++));
@@ -494,7 +499,7 @@
     }
 
     make_compile_option(&option, opt);
-    prepare_iseq_build(iseq, name, filename, line_no,
+    prepare_iseq_build(iseq, name, filename, filepath, line_no,
 		       parent, iseq_type, 0, &option);
 
     rb_iseq_build_from_ary(iseq, locals, args, exception, body);
@@ -531,7 +536,7 @@
 }
 
 VALUE
-rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt)
+rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE filepath, VALUE line, VALUE opt)
 {
     rb_compile_option_t option;
     const char *fn = StringValueCStr(file);
@@ -542,11 +547,11 @@
 
     if (th->base_block && th->base_block->iseq) {
 	return rb_iseq_new_with_opt(node, th->base_block->iseq->name,
-				    file, line, th->base_block->iseq->self,
+				    file, filepath, line, th->base_block->iseq->self,
 				    ISEQ_TYPE_EVAL, &option);
     }
     else {
-	return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, line, Qfalse,
+	return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, filepath, line, Qfalse,
 				    ISEQ_TYPE_TOP, &option);
     }
 }
@@ -554,21 +559,21 @@
 VALUE
 rb_iseq_compile(VALUE src, VALUE file, VALUE line)
 {
-    return rb_iseq_compile_with_option(src, file, line, Qnil);
+    return rb_iseq_compile_with_option(src, file, Qnil, line, Qnil);
 }
 
 static VALUE
 iseq_s_compile(int argc, VALUE *argv, VALUE self)
 {
-    VALUE src, file = Qnil, line = INT2FIX(1), opt = Qnil;
+    VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;
 
     rb_secure(1);
 
-    rb_scan_args(argc, argv, "13", &src, &file, &line, &opt);
+    rb_scan_args(argc, argv, "13", &src, &file, &path, &line, &opt);
     if (NIL_P(file)) file = rb_str_new2("<compiled>");
     if (NIL_P(line)) line = INT2FIX(1);
 
-    return rb_iseq_compile_with_option(src, file, line, opt);
+    return rb_iseq_compile_with_option(src, file, path, line, opt);
 }
 
 static VALUE
@@ -591,7 +596,7 @@
     parser = rb_parser_new();
     node = rb_parser_compile_file(parser, fname, f, NUM2INT(line));
     make_compile_option(&option, opt);
-    return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file, line, Qfalse,
+    return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file, file, line, Qfalse,
 				ISEQ_TYPE_TOP, &option);
 }
 
@@ -1309,7 +1314,7 @@
 
     /*
      * [:magic, :major_version, :minor_version, :format_type, :misc,
-     *  :name, :filename, :line_no, :type, :locals, :args,
+     *  :name, :filename, :filepath, :line_no, :type, :locals, :args,
      *  :catch_table, :bytecode]
      */
     rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat"));
@@ -1319,6 +1324,7 @@
     rb_ary_push(val, misc);
     rb_ary_push(val, iseq->name);
     rb_ary_push(val, iseq->filename);
+    rb_ary_push(val, iseq->filepath);
     rb_ary_push(val, iseq->line_no);
     rb_ary_push(val, type);
     rb_ary_push(val, locals);
Index: mvm/load.c
===================================================================
--- mvm/load.c	(revision 26967)
+++ mvm/load.c	(revision 26968)
@@ -297,7 +297,7 @@
 	th->mild_compile_error++;
 	node = (NODE *)rb_load_file(RSTRING_PTR(fname));
 	loaded = TRUE;
-	iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, Qfalse);
+	iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, fname, Qfalse);
 	th->mild_compile_error--;
 	rb_iseq_eval(iseq);
     }
@@ -448,6 +448,19 @@
     return rb_require_safe(fname, rb_safe_level());
 }
 
+VALUE
+rb_f_require_relative(VALUE obj, VALUE fname)
+{
+    VALUE rb_current_realfilepath(void);
+    VALUE rb_file_s_dirname(VALUE klass, VALUE fname);
+    VALUE base = rb_current_realfilepath();
+    if (NIL_P(base)) {
+	rb_raise(rb_eLoadError, "cannot infer basepath");
+    }
+    base = rb_file_s_dirname(rb_cFile, base);
+    return rb_require_safe(rb_file_expand_path(fname, base), rb_safe_level());
+}
+
 static int
 search_required(VALUE fname, volatile VALUE *path, int safe_level)
 {
@@ -746,6 +759,7 @@
 
     rb_define_global_function("load", rb_f_load, -1);
     rb_define_global_function("require", rb_f_require, 1);
+    rb_define_global_function("require_relative", rb_f_require_relative, 1);
     rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
     rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
     rb_define_global_function("autoload", rb_f_autoload, 2);
Index: mvm/lib/uri/common.rb
===================================================================
--- mvm/lib/uri/common.rb	(revision 26967)
+++ mvm/lib/uri/common.rb	(revision 26968)
@@ -729,49 +729,60 @@
   #
   # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
   #
-  # See URI.decode_www_component(str), URI.encode_www_form(enum)
-  def self.encode_www_component(str)
+  # See URI.decode_www_form_component, URI.encode_www_form
+  def self.encode_www_form_component(str)
     if TBLENCWWWCOMP_.empty?
       256.times do |i|
         case i
         when 0x20
           TBLENCWWWCOMP_[' '] = '+'
-        when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A
+        # when 0x2A, 0x2D, 0x2E, 0x30..0x39, 0x41..0x5A, 0x5F, 0x61..0x7A
         else
-          TBLENCWWWCOMP_[i.chr] = '%%%X' % i
+          TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
         end
       end
       TBLENCWWWCOMP_.freeze
     end
-    str = str.to_s.dup
-    enc = str.encoding
-    str.force_encoding(Encoding::ASCII_8BIT)
-    str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
-    str.force_encoding(enc)
+    str = str.to_s
+    case str.encoding
+    when Encoding::ASCII_8BIT, Encoding::US_ASCII, Encoding::UTF_8
+      str = str.dup.force_encoding(Encoding::ASCII_8BIT)
+      str.gsub!(/[^*\-.0-9A-Z_a-z]/, TBLENCWWWCOMP_)
+    when Encoding::UTF_16BE, Encoding::UTF_16LE, Encoding::UTF_32BE, Encoding::UTF_32LE
+      reg = Regexp.new('[^*\-.0-9A-Z_a-z]+'.encode(str.encoding))
+      str = str.gsub(reg){
+        $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_).
+        force_encoding(str.encoding)
+      }
+    else
+      if str.encoding.ascii_compatible?
+        str = str.gsub(/[^*\-.0-9A-Z_a-z]+/){
+          $&.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_)}
+      else
+        str = str.force_encoding(Encoding::ASCII_8BIT).gsub(/./, TBLENCWWWCOMP_)
+      end
+    end
+    str.force_encoding(Encoding::US_ASCII)
   end
 
   # Decode given +str+ of URL-encoded form data.
   #
   # This decods + to SP.
   #
-  # See URI.encode_www_component(str)
-  def self.decode_www_component(str)
+  # See URI.encode_www_form_component, URI.decode_www_form
+  def self.decode_www_form_component(str, enc=Encoding::UTF_8)
     if TBLDECWWWCOMP_.empty?
       256.times do |i|
-        case i
-        when 0x20
-          TBLDECWWWCOMP_['+'] = ' '
-        else
-          h, l = i>>4, i&15
-          TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
-          TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
-          TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
-          TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
-        end
+        h, l = i>>4, i&15
+        TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
+        TBLDECWWWCOMP_['+'] = ' ' if i == 0x20
       end
       TBLDECWWWCOMP_.freeze
     end
-    str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_)
+    str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(Encoding::UTF_8)
   end
 
   # Generate URL-encoded form data from given +enum+.
@@ -779,7 +790,7 @@
   # This generates application/x-www-form-urlencoded data defined in HTML5
   # from given an Enumerable object.
   #
-  # This internally uses URI.encode_www_component(str).
+  # This internally uses URI.encode_www_form_component(str).
   #
   # This doesn't convert encodings of give items, so convert them before call
   # this method if you want to send data as other than original encoding or
@@ -789,7 +800,7 @@
   #
   # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
   #
-  # See URI.encode_www_component(str)
+  # See URI.encode_www_form_component, URI.decode_www_form
   def self.encode_www_form(enum)
     str = nil
     enum.each do |k,v|
@@ -798,12 +809,43 @@
       else
         str = ''.force_encoding(Encoding::US_ASCII)
       end
-      str << encode_www_component(k)
+      str << encode_www_form_component(k)
       str << '='
-      str << encode_www_component(v)
+      str << encode_www_form_component(v)
     end
     str
   end
+
+  # Decode URL-encoded form data from given +str+.
+  #
+  # This decodes application/x-www-form-urlencoded data
+  # and returns array of key-value array.
+  # This internally uses URI.decode_www_form_component.
+  #
+  # _charset_ hack is not supported now because the mapping from given charset
+  # to Ruby's encoding is not clear yet.
+  # see also http://www.w3.org/TR/html5/syntax.html#character-encodings-0
+  #
+  # This refers http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
+  #
+  # ary = URI.decode_www_form("a=1&a=2&b=3")
+  # p ary                  #=> [['a', '1'], ['a', '2'], ['b', '3']]
+  # p ary.assoc('a').last  #=> '1'
+  # p ary.assoc('b').last  #=> '3'
+  # p ary.rassoc('a').last #=> '2'
+  # p Hash[ary]            # => {"a"=>"2", "b"=>"3"}
+  #
+  # See URI.decode_www_form_component, URI.encode_www_form
+  def self.decode_www_form(str, enc=Encoding::UTF_8)
+    ary = []
+    unless /\A\??(?<query>[^=;&]*=[^;&]*(?:[;&][^=;&]*=[^;&]*)*)\z/ =~ str
+      raise ArgumentError, "invalid data of application/x-www-form-urlencoded (#{str})"
+    end
+    query.scan(/([^=;&]+)=([^;&]*)/) do
+      ary << [decode_www_form_component($1, enc), decode_www_form_component($2, enc)]
+    end
+    ary
+  end
 end
 
 module Kernel
Index: mvm/lib/tmpdir.rb
===================================================================
--- mvm/lib/tmpdir.rb	(revision 26967)
+++ mvm/lib/tmpdir.rb	(revision 26968)
@@ -5,37 +5,15 @@
 #
 
 require 'fileutils'
+begin
+  require 'tmpdir.so'
+rescue LoadError
+end
 
 class Dir
 
-  @@systmpdir = '/tmp'
+  @@systmpdir ||= '/tmp'
 
-  if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and
-      begin
-        require 'Win32API'
-        true
-      rescue LoadError
-      end
-    CSIDL_LOCAL_APPDATA = 0x001c
-    max_pathlen = 260
-    windir = "\0"*(max_pathlen+1)
-    begin
-      getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')
-      raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0
-      windir.rstrip!
-    rescue RuntimeError
-      begin
-        getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')
-      rescue RuntimeError
-        getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')
-      end
-      windir[getdir.call(windir, windir.size)..-1] = ""
-    end
-    windir.force_encoding(Dir.pwd.encoding)
-    temp = File.expand_path('temp', windir.untaint)
-    @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)
-  end
-
   ##
   # Returns the operating system's temporary file path.
 
Index: mvm/compile.c
===================================================================
--- mvm/compile.c	(revision 26967)
+++ mvm/compile.c	(revision 26968)
@@ -169,6 +169,9 @@
 #define iseq_filename(iseq) \
   (((rb_iseq_t*)DATA_PTR(iseq))->filename)
 
+#define iseq_filepath(iseq) \
+  (((rb_iseq_t*)DATA_PTR(iseq))->filepath)
+
 #define NEW_ISEQVAL(node, name, type, line_no)       \
   new_child_iseq(iseq, node, name, 0, type, line_no)
 
@@ -917,7 +920,7 @@
     VALUE ret;
 
     debugs("[new_child_iseq]> ---------------------------------------\n");
-    ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self), INT2FIX(line_no),
+    ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self), iseq_filepath(iseq->self), INT2FIX(line_no),
 			       parent, type, iseq->compile_data->option);
     debugs("[new_child_iseq]< ---------------------------------------\n");
     iseq_add_mark_object(iseq, ret);
@@ -5287,6 +5290,7 @@
 				rb_ary_store(op, i+1, (VALUE)label | 1);
 			    }
 			    argv[j] = op;
+			    iseq_add_mark_object_compile_time(iseq, op);
 			}
 			break;
 		      default:
Index: mvm/vm_eval.c
===================================================================
--- mvm/vm_eval.c	(revision 26967)
+++ mvm/vm_eval.c	(revision 26968)
@@ -1711,6 +1711,16 @@
     }
 }
 
+VALUE
+rb_current_realfilepath(void)
+{
+    rb_thread_t *th = GET_THREAD();
+    rb_control_frame_t *cfp = th->cfp;
+    cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
+    if (cfp != 0) return cfp->iseq->filepath;
+    return Qnil;
+}
+
 void
 Init_vm_eval(void)
 {
Index: mvm/win32/win32.c
===================================================================
--- mvm/win32/win32.c	(revision 26967)
+++ mvm/win32/win32.c	(revision 26968)
@@ -430,6 +430,22 @@
 
 #define numberof(array) (sizeof(array) / sizeof(*array))
 
+UINT
+rb_w32_system_tmpdir(WCHAR *path, UINT len)
+{
+    static const WCHAR temp[] = L"temp";
+    WCHAR *p;
+
+    if (!get_special_folder(CSIDL_LOCAL_APPDATA, path)) {
+	if (get_system_directory(path, len)) return 0;
+    }
+    p = translate_wchar(path, L'\\', L'/');
+    if (*(p - 1) != L'/') *p++ = L'/';
+    if (p - path + numberof(temp) >= len) return 0;
+    memcpy(p, temp, sizeof(temp));
+    return p - path + numberof(temp) - 1;
+}
+
 static void
 init_env(void)
 {
@@ -484,15 +500,8 @@
     if (!GetEnvironmentVariableW(TMPDIR, env, numberof(env)) &&
 	!GetEnvironmentVariableW(L"TMP", env, numberof(env)) &&
 	!GetEnvironmentVariableW(L"TEMP", env, numberof(env)) &&
-	(get_special_folder(CSIDL_LOCAL_APPDATA, env) ||
-	 get_system_directory(env, numberof(env)))) {
-	static const WCHAR temp[] = L"temp";
-	WCHAR *p = translate_wchar(env, L'\\', L'/');
-	if (*(p - 1) != L'/') *p++ = L'/';
-	if (p - env + numberof(temp) < numberof(env)) {
-	    memcpy(p, temp, sizeof(temp));
-	    set_env_val(TMPDIR);
-	}
+	rb_w32_system_tmpdir(env, numberof(env))) {
+	set_env_val(TMPDIR);
     }
 
 #undef env
@@ -3579,7 +3588,6 @@
 rb_w32_getcwd(char *buffer, int size)
 {
     char *p = buffer;
-    char *bp;
     int len;
 
     len = GetCurrentDirectory(0, NULL);
@@ -3610,11 +3618,7 @@
         return NULL;
     }
 
-    for (bp = p; *bp != '\0'; bp = CharNext(bp)) {
-	if (*bp == '\\') {
-	    *bp = '/';
-	}
-    }
+    translate_char(p, '\\', '/');
 
     return p;
 }
Index: mvm/parse.y
===================================================================
--- mvm/parse.y	(revision 26967)
+++ mvm/parse.y	(revision 26968)
@@ -9616,6 +9616,10 @@
     str = (VALUE)&fake_str;
     rb_enc_associate(str, enc);
 
+    if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
+    	rb_raise(rb_eEncodingError, "invalid encoding symbol");
+    }
+
     if (st_lookup(global_symbols.sym_id, str, &data))
 	return (ID)data;
 
Index: mvm/util.c
===================================================================
--- mvm/util.c	(revision 26967)
+++ mvm/util.c	(revision 26968)
@@ -2106,6 +2106,44 @@
         }
 break2:
     if (*s == '0') {
+	if (s[1] == 'x' || s[1] == 'X') {
+	    static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
+	    s0 = ++s;
+	    adj = 0;
+
+	    while (*++s && (s1 = strchr(hexdigit, *s))) {
+		adj *= 16;
+		adj += (s1 - hexdigit) & 15;
+	    }
+
+	    if (*s == '.') {
+		aadj = 1.;
+		while (*++s && (s1 = strchr(hexdigit, *s))) {
+		    aadj /= 16;
+		    adj += aadj * ((s1 - hexdigit) & 15);
+		}
+	    }
+
+	    if (*s != 'P' && *s != 'p') {
+		s = s0;
+		goto ret;
+	    }
+
+	    dsign = 0x2C - *++s; /* +: 2B, -: 2D */
+	    if (abs(dsign) != 1) {
+		s = s0;
+		goto ret;
+	    }
+
+	    for (nd = 0, s++; (c = *s) >= '0' && c <= '9'; s++) {
+		nd *= 10;
+		nd += c;
+		nd -= '0';
+	    }
+
+	    dval(rv) = ldexp(adj, nd * dsign);
+	    goto ret;
+	}
         nz0 = 1;
         while (*++s == '0') ;
         if (!*s)
Index: mvm/ext/bigdecimal/bigdecimal.c
===================================================================
--- mvm/ext/bigdecimal/bigdecimal.c	(revision 26967)
+++ mvm/ext/bigdecimal/bigdecimal.c	(revision 26968)
@@ -4045,6 +4045,7 @@
             e = e * 10 + exp_chr[i] - '0';
             if(es>e*((S_INT)BASE_FIG)) {
 		exponent_overflow = 1;
+		e = es;
 		break;
             }
             ++i;
Index: mvm/ext/tmpdir/tmpdir.c
===================================================================
--- mvm/ext/tmpdir/tmpdir.c	(revision 0)
+++ mvm/ext/tmpdir/tmpdir.c	(revision 26968)
@@ -0,0 +1,32 @@
+#include <ruby/ruby.h>
+#include <ruby/encoding.h>
+
+#define numberof(array) (sizeof(array) / sizeof(*array))
+
+#ifdef HAVE_RB_W32_SYSTEM_TMPDIR
+UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
+VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
+#endif
+
+static VALUE
+system_tmpdir(void)
+{
+#ifdef HAVE_RB_W32_SYSTEM_TMPDIR
+    WCHAR path[_MAX_PATH];
+    UINT len = rb_w32_system_tmpdir(path, numberof(path));
+    if (!len) return Qnil;
+    return rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
+#else
+    return rb_filesystem_str_new_cstr("/tmp");
+#endif
+}
+
+/*
+ * sets Dir.@@systmpdir.
+ */
+void
+Init_tmpdir(void)
+{
+    rb_cvar_set(rb_cDir, rb_intern_const("@@systmpdir"),
+		rb_obj_freeze(system_tmpdir()));
+}

Property changes on: mvm/ext/tmpdir/tmpdir.c
___________________________________________________________________
Name: svn:keywords
   + Author Id Revision
Name: svn:eol-style
   + LF

Index: mvm/ext/tmpdir/extconf.rb
===================================================================
--- mvm/ext/tmpdir/extconf.rb	(revision 0)
+++ mvm/ext/tmpdir/extconf.rb	(revision 26968)
@@ -0,0 +1,6 @@
+case
+when have_func("rb_w32_system_tmpdir")
+  ok = true # win32
+else
+end
+create_makefile("tmpdir") if ok

Property changes on: mvm/ext/tmpdir/extconf.rb
___________________________________________________________________
Name: svn:keywords
   + Author Id Revision
Name: svn:eol-style
   + LF

Index: mvm/hash.c
===================================================================
--- mvm/hash.c	(revision 26967)
+++ mvm/hash.c	(revision 26968)
@@ -1094,9 +1094,6 @@
 {
     rb_hash_modify(hash);
     hash_update(hash, key);
-    if (hash == key) {
-	rb_raise(rb_eArgError, "recursive key for hash");
-    }
     if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) {
 	st_insert(RHASH(hash)->ntbl, key, val);
     }
Index: mvm/NEWS
===================================================================
--- mvm/NEWS	(revision 26967)
+++ mvm/NEWS	(revision 26968)
@@ -313,6 +313,7 @@
 * \d, \s, and \w are now ASCII only; use POSIX bracket classes and \p{} for
   Unicode semantics
 * $: no longer includes the current directory, use require_relative
+* Symbol with an invalid encoding is forbidden to exist.
 
 === Compilation options
 
Index: mvm/.merged-trunk-revision
===================================================================
--- mvm/.merged-trunk-revision	(revision 26967)
+++ mvm/.merged-trunk-revision	(revision 26968)
@@ -1 +1 @@
-26939
+26967
Index: mvm/vm.c
===================================================================
--- mvm/vm.c	(revision 26967)
+++ mvm/vm.c	(revision 26968)
@@ -1435,7 +1435,7 @@
 {
     rb_thread_t *th = GET_THREAD();
     const rb_control_frame_t *reg_cfp = th->cfp;
-    volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP);
+    volatile VALUE iseqval = rb_iseq_new(0, filename, filename, filename, 0, ISEQ_TYPE_TOP);
     VALUE val;
 
     vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP,
@@ -2304,7 +2304,7 @@
 	rb_thread_t *th = GET_THREAD();
 	rb_vm_t *vm = th->vm;
 	VALUE filename = rb_str_new2("<main>");
-	volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP);
+	volatile VALUE iseqval = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
         volatile VALUE th_self;
 	rb_iseq_t *iseq;
 
Index: mvm/version.h
===================================================================
--- mvm/version.h	(revision 26967)
+++ mvm/version.h	(revision 26968)
@@ -1,5 +1,5 @@
 #define RUBY_VERSION "1.9.2"
-#define RUBY_RELEASE_DATE "2010-03-15"
+#define RUBY_RELEASE_DATE "2010-03-18"
 #define RUBY_PATCHLEVEL -1
 #define RUBY_BRANCH_NAME "mvm"
 
@@ -8,7 +8,7 @@
 #define RUBY_VERSION_TEENY 1
 #define RUBY_RELEASE_YEAR 2010
 #define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 15
+#define RUBY_RELEASE_DAY 18
 
 #include "ruby/version.h"
 
Index: mvm/ruby.c
===================================================================
--- mvm/ruby.c	(revision 26967)
+++ mvm/ruby.c	(revision 26968)
@@ -1456,7 +1456,9 @@
     }
 
     PREPARE_PARSE_MAIN({
-	iseq = rb_iseq_new_main(tree, opt->script_name);
+	VALUE path = Qnil;
+	if (!opt->e_script && strcmp(opt->script, "-")) path = opt->script_name;
+	iseq = rb_iseq_new_main(tree, opt->script_name, path);
     });
 
     if (opt->dump & DUMP_BIT(insns)) {
Index: mvm/tool/transcode-tblgen.rb
===================================================================
--- mvm/tool/transcode-tblgen.rb	(revision 26967)
+++ mvm/tool/transcode-tblgen.rb	(revision 26968)
@@ -81,18 +81,31 @@
   alias == eql?
 end
 
+class Branch
+  def initialize(byte_min, byte_max, child_tree)
+    @byte_min = byte_min
+    @byte_max = byte_max
+    @child_tree = child_tree
+    @hash = byte_min.hash ^ byte_max.hash ^ child_tree.hash
+  end
+  attr_reader :byte_min, :byte_max, :child_tree, :hash
+
+  def eql?(other)
+    self.class == other.class &&
+    @hash == other.hash &&
+    @byte_min == other.byte_min &&
+    @byte_max == other.byte_max &&
+    @child_tree == other.child_tree
+  end
+  alias == eql?
+end
+
 class ActionMap
-  def self.parse_to_rects(hash)
-    h = {}
-    hash.each {|pat, action|
-      pat = pat.to_s
-      h[pat] = action
-    }
-    hash = h
-
+  def self.parse_to_rects(mapping)
     rects = []
     n = 0
-    hash.each {|pat, action|
+    mapping.each {|pat, action|
+      pat = pat.to_s
       if /\A\s*\(empset\)\s*\z/ =~ pat
         next
       elsif /\A\s*\(empstr\)\s*\z/ =~ pat
@@ -165,18 +178,18 @@
   end
 
   def self.build_tree(rects)
-    expand("", rects) {|actions|
+    expand("", rects) {|prefix, actions|
       unambiguous_action(actions)
     }
   end
 
-  def self.parse(hash)
-    rects = parse_to_rects(hash)
+  def self.parse(mapping)
+    rects = parse_to_rects(mapping)
     tree = build_tree(rects)
-    self.new("", tree)
+    self.new(tree)
   end
 
-  def self.merge(*rects_list)
+  def self.merge_rects(*rects_list)
     if rects_list.length < 2
       raise ArgumentError, "not enough arguments"
     end
@@ -186,99 +199,122 @@
       all_rects.concat rects.map {|min, max, action| [min, max, [i, action]] }
     }
 
-    tree = expand("", all_rects) {|actions|
+    tree = expand("", all_rects) {|prefix, actions|
       args = Array.new(rects_list.length) { [] }
       actions.each {|i, action|
         args[i] << action
       }
-      yield(args)
+      yield(prefix, *args)
     }
 
-    self.new("", tree)
+    self.new(tree)
   end
 
+  def self.merge(*mappings, &block)
+    merge_rects(*mappings.map {|m| parse_to_rects(m) }, &block)
+  end
+
   def self.expand(prefix, rects, &block)
-    return [] if rects.empty?
-    has_empty = false
-    has_nonempty = false
-    rects.each {|min, max, action|
-      if min.empty?
-        has_empty = true
+    #numsing = numreg = 0
+    #rects.each {|min, max, action| if min == max then numsing += 1 else numreg += 1 end }
+    #puts "#{numsing} singleton mappings and #{numreg} region mappings."
+    singleton_rects = []
+    region_rects = []
+    rects.each {|rect|
+      min, max, action = rect
+      if min == max
+        singleton_rects << rect
       else
-        has_nonempty = true
+        region_rects << rect
       end
     }
-    if has_empty && has_nonempty
-      raise ArgumentError, "ambiguous pattern: #{prefix}"
-    end
-    if has_empty
-      actions = rects.map {|min, max, action| action }.uniq
-      act = block.call(actions)
+    expand_rec(prefix, singleton_rects, region_rects, &block)
+  end
+
+  def self.expand_rec(prefix, singleton_rects, region_rects, &block)
+    some_mapping = singleton_rects[0] || region_rects[0]
+    return [] if !some_mapping
+    if some_mapping[0].empty?
+      h = {}
+      (singleton_rects + region_rects).each {|min, max, action|
+        raise ArgumentError, "ambiguous pattern: #{prefix}" if !min.empty?
+        h[action] = true
+      }
+      actions = h.keys
+      act = block.call(prefix, actions)
       tree = Action.new(act)
     else
       tree = []
-      each_firstbyte_range(prefix, rects) {|byte_min, byte_max, rects2|
-        prefix2 = prefix
+      each_firstbyte_range(prefix, singleton_rects, region_rects) {|byte_min, byte_max, s_rects2, r_rects2|
         if byte_min == byte_max
-          prefix2 += "%02X" % byte_min
+          prefix2 = prefix + "%02X" % byte_min
         else
-          prefix2 += "{%02X-%02X}" % [byte_min, byte_max]
+          prefix2 = prefix + "{%02X-%02X}" % [byte_min, byte_max]
         end
-        child_tree = expand(prefix2, rects2, &block)
-        tree << [byte_min, byte_max, child_tree]
+        child_tree = expand_rec(prefix2, s_rects2, r_rects2, &block)
+        tree << Branch.new(byte_min, byte_max, child_tree)
       }
     end
     return tree
   end
 
-  def self.each_firstbyte_range(prefix, rects)
-    a = []
+  def self.each_firstbyte_range(prefix, singleton_rects, region_rects)
     index_from = {}
-    rects.each {|min, max, action|
-      raise ArgumentError, "emptyable pattern" if min.empty?
+
+    singleton_ary = []
+    singleton_rects.each {|seq, _, action|
+      raise ArgumentError, "ambiguous pattern: #{prefix}" if seq.empty?
+      seq_firstbyte = seq[0,2].to_i(16)
+      seq_rest = seq[2..-1]
+      singleton_ary << [seq_firstbyte, [seq_rest, seq_rest, action]]
+      index_from[seq_firstbyte] = true
+      index_from[seq_firstbyte+1] = true
+    }
+
+    region_ary = []
+    region_rects.each {|min, max, action|
+      raise ArgumentError, "ambiguous pattern: #{prefix}" if min.empty?
       min_firstbyte = min[0,2].to_i(16)
       min_rest = min[2..-1]
       max_firstbyte = max[0,2].to_i(16)
       max_rest = max[2..-1]
-      a << [min_firstbyte, max_firstbyte, [min_rest, max_rest, action]]
+      region_ary << [min_firstbyte, max_firstbyte, [min_rest, max_rest, action]]
       index_from[min_firstbyte] = true
       index_from[max_firstbyte+1] = true
     }
-    byte_from = {}
+
+    byte_from = Array.new(index_from.size)
     index_from.keys.sort.each_with_index {|byte, i|
       index_from[byte] = i
       byte_from[i] = byte
     }
-    rects_hash = {}
-    a.each {|min_firstbyte, max_firstbyte, rest_elt|
+
+    singleton_rects_hash = {}
+    singleton_ary.each {|seq_firstbyte, rest_elt|
+      i = index_from[seq_firstbyte]
+      (singleton_rects_hash[i] ||= []) << rest_elt
+    }
+
+    region_rects_hash = {}
+    region_ary.each {|min_firstbyte, max_firstbyte, rest_elt|
       index_from[min_firstbyte].upto(index_from[max_firstbyte+1]-1) {|i|
-        rects_hash[i] ||= []
-        rects_hash[i] << rest_elt
+        (region_rects_hash[i] ||= []) << rest_elt
       }
     }
+
     0.upto(index_from.size-1) {|i|
-      rects2 = rects_hash[i]
-      yield byte_from[i], byte_from[i+1]-1, rects2 if rects2
+      s_rects = singleton_rects_hash[i]
+      r_rects = region_rects_hash[i]
+      if s_rects || r_rects
+        yield byte_from[i], byte_from[i+1]-1, (s_rects || []), (r_rects || [])
+      end
     }
   end
 
-  def initialize(prefix, tree)
-    @prefix = prefix # just for debug
+  def initialize(tree)
     @tree = tree
   end
 
-  def hash
-    return @hash if defined? @hash
-    @hash = @tree.hash
-  end
-
-  def eql?(other)
-    self.class == other.class &&
-    @tree == other.instance_eval { @tree }
-  end
-
-  alias == eql?
-
   def inspect
     "\#<#{self.class}:" + 
     @tree.inspect +
@@ -290,8 +326,8 @@
     when Action
       0
     else
-      tree.map {|byte_min, byte_max, child_tree|
-        max_input_length_rec(child_tree)
+      tree.map {|branch|
+        max_input_length_rec(branch.child_tree)
       }.max + 1
     end
   end
@@ -308,16 +344,6 @@
     end
   end
 
-  def each_firstbyte
-    @tree.each {|byte_min, byte_max, child_tree|
-      byte_min.upto(byte_max) {|byte|
-        prefix = @prefix + ("%02X" % byte)
-        am = ActionMap.new(prefix, child_tree)
-        yield byte, am
-      }
-    }
-  end
-
   OffsetsMemo = {}
   InfosMemo = {}
 
@@ -422,7 +448,9 @@
     code
   end
 
-  def generate_lookup_node(bytes_code, words_code, name, table)
+  def generate_lookup_node(name, table)
+    bytes_code = @bytes_code
+    words_code = @words_code
     offsets = []
     infos = []
     infomap = {}
@@ -480,24 +508,29 @@
   PostMemo = {}
   NextName = "a"
 
-  def generate_node(bytes_code, words_code, name_hint=nil)
-    if n = PreMemo[self]
+  def generate_node(name_hint=nil)
+    if n = PreMemo[@tree]
       return n
     end
 
     table = Array.new(0x100, :invalid)
-    each_firstbyte {|byte, rest|
+    @tree.each {|branch|
+      byte_min, byte_max, child_tree = branch.byte_min, branch.byte_max, branch.child_tree
+      rest = ActionMap.new(child_tree)
       if a = rest.empty_action
-        table[byte] = a
+        table.fill(a, byte_min..byte_max)
       else
         name_hint2 = nil
-        name_hint2 = "#{name_hint}_#{'%02X' % byte}" if name_hint
-        table[byte] = "/*BYTE_LOOKUP*/" + rest.gennode(bytes_code, words_code, name_hint2)
+        if name_hint
+          name_hint2 = "#{name_hint}_#{byte_min == byte_max ? '%02X' % byte_min : '%02Xto%02X' % [byte_min, byte_max]}"
+        end
+        v = "/*BYTE_LOOKUP*/" + rest.gennode(@bytes_code, @words_code, name_hint2)
+        table.fill(v, byte_min..byte_max)
       end
     }
 
     if n = PostMemo[table]
-      return PreMemo[self] = n
+      return PreMemo[@tree] = n
     end
 
     if !name_hint
@@ -505,16 +538,16 @@
       NextName.succ!
     end
 
-    PreMemo[self] = PostMemo[table] = name_hint
+    PreMemo[@tree] = PostMemo[table] = name_hint
 
-    generate_lookup_node(bytes_code, words_code, name_hint, table)
+    generate_lookup_node(name_hint, table)
     name_hint
   end
 
   def gennode(bytes_code, words_code, name_hint=nil)
     @bytes_code = bytes_code
     @words_code = words_code
-    name = generate_node(bytes_code, words_code, name_hint)
+    name = generate_node(name_hint)
     @bytes_code = nil
     @words_code = nil
     return name
@@ -649,18 +682,20 @@
   r
 end
 
-def transcode_compile_tree(name, from, map)
+def transcode_compile_tree(name, from, map, valid_encoding=nil)
   map = encode_utf8(map)
   h = {}
   map.each {|k, v|
     h[k] = v unless h[k] # use first mapping
   }
-  if valid_encoding = ValidEncoding[from]
-    rects = ActionMap.parse_to_rects(h)
-    undef_rects = ActionMap.parse_to_rects(valid_encoding => :undef)
-    am = ActionMap.merge(rects, undef_rects) {|a1, a2|
-      a1 = a1.empty? ? nil : ActionMap.unambiguous_action(a1)
-      a2 = a2.empty? ? nil : ActionMap.unambiguous_action(a2)
+  valid_encoding = ValidEncoding[from] if valid_encoding == nil
+  if valid_encoding
+    am = ActionMap.merge(h, {valid_encoding => :undef}) {|prefix, as1, as2|
+      a1 = as1.empty? ? nil : ActionMap.unambiguous_action(as1)
+      a2 = as2.empty? ? nil : ActionMap.unambiguous_action(as2)
+      if !a2
+        raise "invalid mapping: #{prefix}"
+      end
       a1 || a2
     }
   else
@@ -675,7 +710,7 @@
 TRANSCODERS = []
 TRANSCODE_GENERATED_TRANSCODER_CODE = ''
 
-def transcode_tbl_only(from, to, map)
+def transcode_tbl_only(from, to, map, valid_encoding=nil)
   if VERBOSE_MODE
     if from.empty? || to.empty?
       STDERR.puts "converter for #{from.empty? ? to : from}"
@@ -692,12 +727,12 @@
   else
     tree_name = "from_#{id_from}_to_#{id_to}"
   end
-  real_tree_name, max_input = transcode_compile_tree(tree_name, from, map)
+  real_tree_name, max_input = transcode_compile_tree(tree_name, from, map, valid_encoding)
   return map, tree_name, real_tree_name, max_input
 end
 
-def transcode_tblgen(from, to, map)
-  map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map)
+def transcode_tblgen(from, to, map, valid_encoding=nil)
+  map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map, valid_encoding)
   transcoder_name = "rb_#{tree_name}"
   TRANSCODERS << transcoder_name
   input_unit_length = UnitLength[from]
Index: mvm/test/ruby/test_string.rb
===================================================================
--- mvm/test/ruby/test_string.rb	(revision 26967)
+++ mvm/test/ruby/test_string.rb	(revision 26968)
@@ -1385,6 +1385,15 @@
     assert_equal(5.9742e24, S("5.9742e24").to_f)
     assert_equal(98.6,      S("98.6 degrees").to_f)
     assert_equal(0.0,       S("degrees 100.0").to_f)
+    assert_equal([ 0.0].pack('G'), [S(" 0.0").to_f].pack('G'))
+    assert_equal([-0.0].pack('G'), [S("-0.0").to_f].pack('G'))
+    assert_equal([ 0.0].pack('G'), [S(" 0x0p+0").to_f].pack('G'))
+    assert_equal([-0.0].pack('G'), [S("-0x0p+0").to_f].pack('G'))
+    assert_equal(1.0,       S("0X1.P+0").to_f)
+    assert_equal(1024.0,    S("0x1p+10").to_f)
+    assert_equal(0.0009765625, S("0x1p-10").to_f)
+    assert_equal(2.6881171418161356e+43, S("0x1.3494a9b171bf5p+144").to_f)
+    assert_equal(-3.720075976020836e-44, S("-0x1.a8c1f14e2af5dp-145").to_f)
   end
 
   def test_to_i
Index: mvm/test/ruby/test_m17n_comb.rb
===================================================================
--- mvm/test/ruby/test_m17n_comb.rb	(revision 26967)
+++ mvm/test/ruby/test_m17n_comb.rb	(revision 26968)
@@ -1040,10 +1040,12 @@
     STRINGS.each {|s|
       if /\0/ =~ a(s)
         assert_raise(ArgumentError) { s.intern }
-      else
+      elsif s.valid_encoding?
         sym = s.intern
         assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s")
         assert_equal(sym, s.to_sym)
+      else
+        assert_raise(EncodingError) { s.intern }
       end
     }
   end
Index: mvm/test/uri/test_common.rb
===================================================================
--- mvm/test/uri/test_common.rb	(revision 26967)
+++ mvm/test/uri/test_common.rb	(revision 26968)
@@ -50,16 +50,22 @@
     assert_raise(NoMethodError) { Object.new.URI("http://www.ruby-lang.org/") }
   end
 
-  def test_encode_www_component
-    assert_equal("+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
+  def test_encode_www_form_component
+    assert_equal("%00+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
                  "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E",
-                 URI.encode_www_component(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~"))
+                 URI.encode_www_form_component("\x00 !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~"))
+    assert_equal("%95%41", URI.encode_www_form_component(
+                   "\x95\x41".force_encoding(Encoding::Shift_JIS)))
+    assert_equal("%30%42", URI.encode_www_form_component(
+                   "\x30\x42".force_encoding(Encoding::UTF_16BE)))
+    assert_equal("%30%42", URI.encode_www_form_component(
+                   "\x30\x42".force_encoding(Encoding::ISO_2022_JP)))
   end
 
-  def test_decode_www_component
-    assert_equal(" !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~",
-                 URI.decode_www_component(
-                   "+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
+  def test_decode_www_form_component
+    assert_equal("  !\"\#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~",
+                 URI.decode_www_form_component(
+                   "%20+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
                    "AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E"))
   end
 
@@ -74,6 +80,12 @@
     assert_equal(expected, URI.encode_www_form([["a", "1"], ["\u3042", "\u6F22"]]))
     assert_equal(expected, URI.encode_www_form([[:a, 1], [:"\u3042", "\u6F22"]]))
   end
+
+  def test_decode_www_form
+    assert_equal([%w[a 1], %w[a 2]], URI.decode_www_form("a=1&a=2"))
+    assert_equal([%w[a 1], ["\u3042", "\u6F22"]],
+                 URI.decode_www_form("a=1&%E3%81%82=%E6%BC%A2"))
+  end
 end
 
 
Index: mvm/file.c
===================================================================
--- mvm/file.c	(revision 26967)
+++ mvm/file.c	(revision 26968)
@@ -2566,6 +2566,12 @@
 # define CharNext(p) ((p) + 1)
 #endif
 
+#if defined(DOSISH_UNC)
+#define has_unc(buf) (isdirsep((buf)[0]) && isdirsep((buf)[1]))
+#else
+#define has_unc(buf) 0
+#endif
+
 #ifdef DOSISH_DRIVE_LETTER
 static inline int
 has_drive_letter(const char *buf)
@@ -2604,6 +2610,19 @@
     }
     return drvcwd;
 }
+
+static inline int
+not_same_drive(VALUE path, int drive)
+{
+    const char *p = RSTRING_PTR(path);
+    if (RSTRING_LEN(path) < 2) return 0;
+    if (has_drive_letter(p)) {
+	return TOLOWER(p[0]) != TOLOWER(drive);
+    }
+    else {
+	return has_unc(p);
+    }
+}
 #endif
 
 static inline char *
@@ -2829,7 +2848,7 @@
 	else {
 	    /* specified drive, but not full path */
 	    int same = 0;
-	    if (!NIL_P(dname)) {
+	    if (!NIL_P(dname) || !not_same_drive(dname, s[0])) {
 		file_expand_path(dname, Qnil, abs_mode, result);
 		BUFINIT();
 		if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) {
@@ -3217,8 +3236,8 @@
     }
 }
 
-static VALUE
-realpath_internal(VALUE basedir, VALUE path, int strict)
+VALUE
+rb_realpath_internal(VALUE basedir, VALUE path, int strict)
 {
     long prefixlen;
     VALUE resolved;
@@ -3306,7 +3325,7 @@
 {
     VALUE path, basedir;
     rb_scan_args(argc, argv, "11", &path, &basedir);
-    return realpath_internal(basedir, path, 1);
+    return rb_realpath_internal(basedir, path, 1);
 }
 
 /*
@@ -3326,7 +3345,7 @@
 {
     VALUE path, basedir;
     rb_scan_args(argc, argv, "11", &path, &basedir);
-    return realpath_internal(basedir, path, 0);
+    return rb_realpath_internal(basedir, path, 0);
 }
 
 static size_t
@@ -3458,7 +3477,7 @@
  *     File.dirname("/home/gumby/work/ruby.rb")   #=> "/home/gumby/work"
  */
 
-static VALUE
+VALUE
 rb_file_s_dirname(VALUE klass, VALUE fname)
 {
     const char *name, *root, *p;

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

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