PageRenderTime 33ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/patches/ruby/2.2.2/railsexpress/04-backported-bugfixes-222.patch

http://github.com/skaes/rvm-patchsets
Patch | 2465 lines | 2356 code | 109 blank | 0 comment | 0 complexity | 637bfe8b0faca130e45ee084bb9f43d6 MD5 | raw file
  1. diff --git a/ChangeLog b/ChangeLog
  2. index 909c092..ae878d3 100644
  3. --- a/ChangeLog
  4. +++ b/ChangeLog
  5. @@ -1,3 +1,254 @@
  6. +Fri Jun 12 01:39:49 2015 Eric Wong <e@80x24.org>
  7. +
  8. + * ext/socket/ancdata.c: use RB_GC_GUARD instead of volatile
  9. + [ruby-core:69419] [Feature #11198]
  10. +
  11. +Fri Jun 12 01:16:13 2015 Eric Wong <e@80x24.org>
  12. +
  13. + * ext/openssl/ossl_asn1.c (ossl_asn1_traverse, ossl_asn1_decode,
  14. + ossl_asn1_decode_all): use RB_GC_GUARD instead of volatile
  15. + [ruby-core:69371] [Bug #11185]
  16. +
  17. +Fri Jun 12 01:14:00 2015 NARUSE, Yui <naruse@ruby-lang.org>
  18. +
  19. + * win32/win32.c (setup_overlapped): seek to the file end only when
  20. + writing (mode:a), not reading (mode:a+, read).
  21. +
  22. +Fri Jun 12 01:11:52 2015 Aaron Patterson <tenderlove@ruby-lang.org>
  23. +
  24. + * load.c (loaded_feature_path): stop returning false negatives for
  25. + filenames which are trailing substrings of file extensions. For
  26. + example, 'b', which a trailing substring of ".rb" should not return
  27. + false. [Bug #11155][ruby-core:69206]
  28. +
  29. + * test/ruby/test_autoload.rb: test for fix
  30. +
  31. +Sun May 24 03:56:27 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  32. +
  33. + * marshal.c (r_symreal): register symbol names as strings first so
  34. + that r_symlink always returns valid names.
  35. + [ruby-core:68587] [Bug #10991]
  36. +
  37. + * marshal.c (r_ivar, r_object0): now need to intern symbol names.
  38. +
  39. + * marshal.c (r_object0): compare with symbol names.
  40. +
  41. +Sun May 24 03:53:07 2015 Eric Wong <e@80x24.org>
  42. +
  43. + * ext/socket/ancdata.c (bsock_recvmsg_internal): GC guard
  44. + [Bug #11123]
  45. +
  46. +Sun May 24 03:44:42 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  47. +
  48. + * range.c (linear_object_p, range_include): test if covered for
  49. + linear objects. [ruby-core:69052] [Bug #11113]
  50. +
  51. +Sun May 24 03:41:45 2015 Shugo Maeda <shugo@ruby-lang.org>
  52. +
  53. + * lib/net/imap.rb (body_ext_mpart): should work even if body-fld-dsp
  54. + is omitted. [ruby-core:69093] [Bug #11128]
  55. +
  56. +Sun May 24 03:37:14 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
  57. +
  58. + * string.c: added documentation for character sequence \' with String#sub
  59. + [Bug #11132][ruby-core:69121][fix GH-900][ci skip] Patch by @shishir127
  60. +
  61. +Sun May 24 03:32:53 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
  62. +
  63. + * rational.c: Added documentation for rational literal.
  64. + [Bug #11075][fix GH-885][ci skip] Patch by @shishir127
  65. +
  66. +Sun May 24 03:06:20 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  67. +
  68. + * ext/socket/ipsocket.c (init_inetsock_internal): preserve errno
  69. + before other library calls and use rb_syserr_fail.
  70. + [ruby-core:68531] [Bug #10975]
  71. +
  72. +Sun May 24 03:01:17 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  73. +
  74. + * ext/-test-/printf/printf.c (uint_to_str): renamed to get rid of
  75. + conflict on cygwin. [ruby-core:68877] [Bug #11065]
  76. +
  77. +Sun May 24 02:44:53 2015 Koichi Sasada <ko1@atdot.net>
  78. +
  79. + * vm.c (vm_exec): check other events when RETURN is thrown.
  80. + [Bug #10724]
  81. +
  82. + * test/ruby/test_settracefunc.rb: add a test.
  83. +
  84. +Sun May 24 02:21:47 2015 Masahiro Tomita <tommy@tmtm.org>
  85. +
  86. + * ext/socket/raddrinfo.c (addrinfo_mload): fix memory leak of
  87. + addrinfo. [ruby-dev:48923] [Bug #11051]
  88. +
  89. +Sun May 24 02:17:05 2015 Kenta Murata <mrkn@cookpad.com>
  90. +
  91. + * bigdecimal: conform to ruby's license. [ruby-core:68466] [Bug #10952]
  92. +
  93. +Sun May 24 02:06:34 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  94. +
  95. + * ext/-test-/file/fs.c (get_fsname): try magic number only if
  96. + f_type is included. [ruby-dev:48913] [Bug #11000]
  97. +
  98. +Sun May 24 02:06:34 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  99. +
  100. + * ext/-test-/file/fs.c (get_fsname): return filesystem name by
  101. + statfs/statvfs. [ruby-core:68624] [Bug #10998]
  102. +
  103. +Sun May 24 02:02:00 2015 Koichi Sasada <ko1@atdot.net>
  104. +
  105. + * test/ruby/test_symbol.rb: fix syntax error.
  106. +
  107. +Sun May 24 02:02:00 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  108. +
  109. + * hash.c (rb_any_hash): Symbols are compared by the identities
  110. + always. [ruby-core:68767] [Bug #11035]
  111. +
  112. +Sun May 24 02:01:07 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  113. +
  114. + * hash.c (rb_any_hash): use same hash values with Float#hash so
  115. + that -0.0 and +0.0 will be identical.
  116. + [ruby-core:68541] [Bug #10979]
  117. +
  118. +Thu May 21 01:34:48 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  119. +
  120. + * gc.c (id2ref): prohibit from accessing internal objects.
  121. + [ruby-core:68348] [Bug #10918]
  122. +
  123. +Thu May 21 01:32:02 2015 Rei Odaira <Rei.Odaira@gmail.com>
  124. +
  125. + * ext/pty/pty.c: AIX supports autopush.
  126. + Patch by Perry Smith [ruby-core:58539] [Bug #9144]
  127. +
  128. +Thu May 21 01:07:41 2015 Misumi Rize <r@ayase-e.li>
  129. +
  130. + * vm_insnhelper.c (vm_throw_start): search the target to break
  131. + from a block with nested rescue, from the nested blocks.
  132. + [ruby-core:67765] [Bug #10775] [Fix GH-820]
  133. +
  134. +Thu May 21 00:55:45 2015 Koichi Sasada <ko1@atdot.net>
  135. +
  136. + * vm_args.c: protect value stack from calling other methods
  137. + during complex parameter setting process (splat, kw, and so on).
  138. + [Bug #11027]
  139. +
  140. + * vm_core.h: remove rb_thead_t::mark_stack_len.
  141. + With this modification, we don't need to use th->mark_stack_len.
  142. +
  143. + * test/ruby/test_keyword.rb: add a test.
  144. +
  145. + * cont.c (cont_capture): catch up this fix.
  146. +
  147. + * vm.c (rb_thread_mark): ditto.
  148. +
  149. +Thu May 21 00:07:54 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  150. +
  151. + * vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow
  152. + symbols to just instance_eval/exec, except for definition of
  153. + singletons. [ruby-core:68961] [Bug #11086]
  154. +
  155. +Wed May 20 04:33:50 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  156. +
  157. + * string.c (STR_SET_EMBED): clear NOFREE flag at embedding as
  158. + embedded strings no longer refer static strings.
  159. + [ruby-core:68436] [Bug #10942]
  160. +
  161. +Wed May 20 03:46:11 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  162. +
  163. + * dir.c (need_normalization): use getattrlist() if fgetattrlist()
  164. + is unavailable, on OSX 10.5. [ruby-core:68829] [Bug #11054]
  165. +
  166. +Wed May 20 03:25:34 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  167. +
  168. + * proc.c (proc_binding): replicate env from method object, and
  169. + allocate the local variable area for the iseq local table.
  170. + [ruby-core:68673] [Bug #11012]
  171. +
  172. +Wed May 20 03:25:34 2015 Koichi Sasada <ko1@atdot.net>
  173. +
  174. + * proc.c: use RUBY_VM_IFUNC_P() to recognize IFUNC or not.
  175. +
  176. + * vm.c: ditto.
  177. +
  178. + * vm_dump.c: ditto.
  179. +
  180. + * vm_insnhelper.c: ditto.
  181. +
  182. + * vm_core.h: use RB_TYPE_P() instead of BUILTIN_TYPE().
  183. +
  184. +Wed May 20 03:10:49 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  185. +
  186. + * benchmark/bm_hash_aref_flo.rb: make more realistic data.
  187. + [ruby-core:68632] [[Bug #10999]
  188. +
  189. +Wed May 20 02:49:49 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  190. +
  191. + * proc.c (respond_to_missing_p): check if the receiver responds to
  192. + the given method by respond_to_missing?.
  193. +
  194. + * proc.c (mnew_missing): create Method object for method_missing.
  195. + [ruby-core:68564] [Bug #10985]
  196. +
  197. +Wed May 20 02:16:05 2015 NAKAMURA Usaku <usa@ruby-lang.org>
  198. +
  199. + * dir.c (replace_real_basename): need to check the return value of
  200. + GLOB_REALLOC().
  201. +
  202. +Wed May 20 02:16:05 2015 NAKAMURA Usaku <usa@ruby-lang.org>
  203. +
  204. + * dir.c (replace_real_basename): shouldn't create Ruby object before
  205. + the object system is loaded.
  206. + [ruby-core:68430] [Bug #10941]
  207. +
  208. +Wed May 20 01:58:12 2015 Tanaka Akira <akr@fsij.org>
  209. +
  210. + * lib/resolv.rb (Resolv::DNS::Label::Str#==): Check class equality.
  211. + (Resolv::DNS::Name#initialize): Normalize labels as
  212. + Resolv::DNS::Label::Str objects.
  213. +
  214. +Wed May 20 01:47:23 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  215. +
  216. + * iseq.c (rb_iseq_compile_with_option): check source type, must be
  217. + an IO or a String. [ruby-core:69219] [Bug #11159]
  218. +
  219. +Fri May 15 05:01:25 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  220. +
  221. + * symbol.c (Init_sym): make dsym_fstrs a hash compared by identity
  222. + as the keys are unique fstrings, to get rid of running hash and
  223. + compare methods and causing new object allocation during garbage
  224. + collection phase. [ruby-dev:48891] [Bug #10933]
  225. +
  226. +Thu May 14 00:50:40 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  227. +
  228. + * parse.y (lambda): push and reset cmdarg_stack in lambda body.
  229. + [ruby-core:69017] [Bug #11107]
  230. +
  231. +Thu May 14 00:39:29 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  232. +
  233. + * dln.c (dln_load): check if a different libruby is loaded by the
  234. + extension library, and then bail out to get rid of very frequent
  235. + reported stale bug reports.
  236. +
  237. +Thu May 14 00:29:44 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  238. +
  239. + * lib/fileutils.rb (FileUtils#mv): show the exact target path in
  240. + the error message instead of the destination parent directory
  241. + name. patched by Joao Britto <jabcalves AT gmail.com> at
  242. + [ruby-core:68706]. [Bug #11021]
  243. +
  244. +Thu May 14 00:19:04 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  245. +
  246. + * thread_pthread.c (reserve_stack): keep sp safe zone to get rid
  247. + of crash by -fstack-check. [ruby-core:68740] [Bug #11030]
  248. +
  249. +Tue Apr 14 23:33:39 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
  250. +
  251. + * configure.in: check also procstat_getvmmap, which is not
  252. + available on FreeBSD 9. [ruby-core:68468] [Bug #10954]
  253. +
  254. + * vm_dump.c (procstat_vm): use kinfo_getvmmap instead if
  255. + procstat_getvmmap is not available.
  256. +
  257. Mon Apr 13 22:11:21 2015 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
  258. * ext/openssl/lib/openssl/ssl.rb: stricter hostname verification
  259. diff --git a/benchmark/bm_hash_aref_flo.rb b/benchmark/bm_hash_aref_flo.rb
  260. index a097bb5..2217274 100644
  261. --- a/benchmark/bm_hash_aref_flo.rb
  262. +++ b/benchmark/bm_hash_aref_flo.rb
  263. @@ -1,4 +1,4 @@
  264. h = {}
  265. -strs = (1..10000).to_a.map!(&:to_f)
  266. +strs = [*1..10000].map! {|i| i.fdiv(10)}
  267. strs.each { |s| h[s] = s }
  268. 50.times { strs.each { |s| h[s] } }
  269. diff --git a/bootstraptest/test_block.rb b/bootstraptest/test_block.rb
  270. index 6a2ccfc..cdc5960 100644
  271. --- a/bootstraptest/test_block.rb
  272. +++ b/bootstraptest/test_block.rb
  273. @@ -597,3 +597,17 @@ assert_equal 'true', %q{
  274. C1.new.foo{}
  275. }
  276. +assert_equal 'ok', %q{
  277. + 1.times do
  278. + begin
  279. + raise
  280. + rescue
  281. + begin
  282. + raise
  283. + rescue
  284. + break
  285. + end
  286. + end
  287. + end
  288. + 'ok'
  289. +}
  290. diff --git a/class.c b/class.c
  291. index 65d0d30..f142f44 100644
  292. --- a/class.c
  293. +++ b/class.c
  294. @@ -1531,7 +1531,8 @@ singleton_class_of(VALUE obj)
  295. {
  296. VALUE klass;
  297. - if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) {
  298. + if (FIXNUM_P(obj) || FLONUM_P(obj) || STATIC_SYM_P(obj)) {
  299. + no_singleton:
  300. rb_raise(rb_eTypeError, "can't define singleton");
  301. }
  302. if (SPECIAL_CONST_P(obj)) {
  303. @@ -1541,9 +1542,9 @@ singleton_class_of(VALUE obj)
  304. return klass;
  305. }
  306. else {
  307. - enum ruby_value_type type = BUILTIN_TYPE(obj);
  308. - if (type == T_FLOAT || type == T_BIGNUM) {
  309. - rb_raise(rb_eTypeError, "can't define singleton");
  310. + switch (BUILTIN_TYPE(obj)) {
  311. + case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
  312. + goto no_singleton;
  313. }
  314. }
  315. diff --git a/configure.in b/configure.in
  316. index 8297c5a..7330df4 100644
  317. --- a/configure.in
  318. +++ b/configure.in
  319. @@ -2036,6 +2036,7 @@ AC_CHECK_FUNCS(fchmod)
  320. AC_CHECK_FUNCS(fchown)
  321. AC_CHECK_FUNCS(fcntl)
  322. AC_CHECK_FUNCS(fdatasync)
  323. +AC_CHECK_FUNCS(fgetattrlist)
  324. AC_CHECK_FUNCS(fmod)
  325. AC_CHECK_FUNCS(fsync)
  326. AC_CHECK_FUNCS(ftruncate)
  327. @@ -3085,6 +3086,9 @@ fi
  328. AS_CASE(["$target_os"],
  329. [freebsd*], [
  330. AC_CHECK_LIB([procstat], [procstat_open_sysctl])
  331. + if test "x$ac_cv_lib_procstat_procstat_open_sysctl" = xyes; then
  332. + AC_CHECK_FUNCS(procstat_getvmmap)
  333. + fi
  334. ])
  335. AS_CASE(["$target_cpu-$target_os"],
  336. [*-darwin*], [
  337. diff --git a/cont.c b/cont.c
  338. index 78ae089..22e0c5a 100644
  339. --- a/cont.c
  340. +++ b/cont.c
  341. @@ -490,7 +490,7 @@ cont_capture(volatile int *stat)
  342. contval = cont->self;
  343. #ifdef CAPTURE_JUST_VALID_VM_STACK
  344. - cont->vm_stack_slen = th->cfp->sp + th->mark_stack_len - th->stack;
  345. + cont->vm_stack_slen = th->cfp->sp - th->stack;
  346. cont->vm_stack_clen = th->stack + th->stack_size - (VALUE*)th->cfp;
  347. cont->vm_stack = ALLOC_N(VALUE, cont->vm_stack_slen + cont->vm_stack_clen);
  348. MEMCPY(cont->vm_stack, th->stack, VALUE, cont->vm_stack_slen);
  349. diff --git a/dir.c b/dir.c
  350. index 0903ec8..84413c6 100644
  351. --- a/dir.c
  352. +++ b/dir.c
  353. @@ -103,13 +103,23 @@ char *strchr(char*,char);
  354. #include <sys/mount.h>
  355. #include <sys/vnode.h>
  356. +# if defined HAVE_FGETATTRLIST || !defined HAVE_GETATTRLIST
  357. +# define need_normalization(dirp, path) need_normalization(dirp)
  358. +# else
  359. +# define need_normalization(dirp, path) need_normalization(path)
  360. +# endif
  361. static inline int
  362. -need_normalization(DIR *dirp)
  363. +need_normalization(DIR *dirp, const char *path)
  364. {
  365. -# ifdef HAVE_GETATTRLIST
  366. +# if defined HAVE_FGETATTRLIST || defined HAVE_GETATTRLIST
  367. u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)];
  368. struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,};
  369. - if (!fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), 0)) {
  370. +# if defined HAVE_FGETATTRLIST
  371. + int ret = fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), 0);
  372. +# else
  373. + int ret = getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0);
  374. +# endif
  375. + if (!ret) {
  376. const fsobj_tag_t *tag = (void *)(attrbuf+1);
  377. switch (*tag) {
  378. case VT_HFS:
  379. @@ -694,7 +704,7 @@ dir_each(VALUE dir)
  380. RETURN_ENUMERATOR(dir, 0, 0);
  381. GetDIR(dir, dirp);
  382. rewinddir(dirp->dir);
  383. - IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp->dir));
  384. + IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp->dir, RSTRING_PTR(dirp->path)));
  385. while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
  386. const char *name = dp->d_name;
  387. size_t namlen = NAMLEN(dp);
  388. @@ -1481,12 +1491,34 @@ replace_real_basename(char *path, long base, rb_encoding *enc, int norm_p)
  389. free(wplain);
  390. if (h == INVALID_HANDLE_VALUE) return path;
  391. FindClose(h);
  392. - tmp = rb_w32_conv_from_wchar(fd.cFileName, enc);
  393. - wlen = RSTRING_LEN(tmp);
  394. - path = GLOB_REALLOC(path, base + wlen + 1);
  395. - memcpy(path + base, RSTRING_PTR(tmp), wlen);
  396. - path[base + wlen] = 0;
  397. - rb_str_resize(tmp, 0);
  398. + if (tmp) {
  399. + char *buf;
  400. + tmp = rb_w32_conv_from_wchar(fd.cFileName, enc);
  401. + wlen = RSTRING_LEN(tmp);
  402. + buf = GLOB_REALLOC(path, base + wlen + 1);
  403. + if (buf) {
  404. + path = buf;
  405. + memcpy(path + base, RSTRING_PTR(tmp), wlen);
  406. + path[base + wlen] = 0;
  407. + }
  408. + rb_str_resize(tmp, 0);
  409. + }
  410. + else {
  411. + char *utf8filename;
  412. + wlen = WideCharToMultiByte(CP_UTF8, 0, fd.cFileName, -1, NULL, 0, NULL, NULL);
  413. + utf8filename = GLOB_REALLOC(0, wlen);
  414. + if (utf8filename) {
  415. + char *buf;
  416. + WideCharToMultiByte(CP_UTF8, 0, fd.cFileName, -1, utf8filename, wlen, NULL, NULL);
  417. + buf = GLOB_REALLOC(path, base + wlen + 1);
  418. + if (buf) {
  419. + path = buf;
  420. + memcpy(path + base, utf8filename, wlen);
  421. + path[base + wlen] = 0;
  422. + }
  423. + GLOB_FREE(utf8filename);
  424. + }
  425. + }
  426. return path;
  427. }
  428. #elif USE_NAME_ON_FS == 1
  429. @@ -1639,7 +1671,7 @@ glob_helper(
  430. # endif
  431. return 0;
  432. }
  433. - IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp));
  434. + IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp, *path ? path : "."));
  435. # if NORMALIZE_UTF8PATH
  436. if (!(norm_p || magical || recursive)) {
  437. diff --git a/dln.c b/dln.c
  438. index 355cec1..e5269ca 100644
  439. --- a/dln.c
  440. +++ b/dln.c
  441. @@ -106,13 +106,12 @@ dln_loaderror(const char *format, ...)
  442. # define USE_DLN_DLOPEN
  443. #endif
  444. -#ifndef FUNCNAME_PATTERN
  445. -# if defined(__hp9000s300) || ((defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(__ELF__)) || defined(__BORLANDC__) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD)
  446. -# define FUNCNAME_PREFIX "_Init_"
  447. -# else
  448. -# define FUNCNAME_PREFIX "Init_"
  449. -# endif
  450. +#if defined(__hp9000s300) || ((defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(__ELF__)) || defined(__BORLANDC__) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD)
  451. +# define EXTERNAL_PREFIX "_"
  452. +#else
  453. +# define EXTERNAL_PREFIX ""
  454. #endif
  455. +#define FUNCNAME_PREFIX EXTERNAL_PREFIX"Init_"
  456. #if defined __CYGWIN__ || defined DOSISH
  457. #define isdirsep(x) ((x) == '/' || (x) == '\\')
  458. @@ -1330,6 +1329,23 @@ dln_load(const char *file)
  459. error = dln_strerror();
  460. goto failed;
  461. }
  462. +# if defined RUBY_EXPORT
  463. + {
  464. + static const char incompatible[] = "incompatible library version";
  465. + void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc");
  466. + if (ex && ex != ruby_xmalloc) {
  467. +
  468. +# if defined __APPLE__
  469. + /* dlclose() segfaults */
  470. + rb_fatal("%s - %s", incompatible, file);
  471. +# else
  472. + dlclose(handle);
  473. + error = incompatible;
  474. + goto failed;
  475. +# endif
  476. + }
  477. + }
  478. +# endif
  479. init_fct = (void(*)())(VALUE)dlsym(handle, buf);
  480. if (init_fct == NULL) {
  481. diff --git a/ext/-test-/file/extconf.rb b/ext/-test-/file/extconf.rb
  482. index 4e134dd..be4a2fb 100644
  483. --- a/ext/-test-/file/extconf.rb
  484. +++ b/ext/-test-/file/extconf.rb
  485. @@ -1,4 +1,18 @@
  486. $INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
  487. +
  488. +headers = %w[sys/param.h sys/mount.h sys/vfs.h].select {|h| have_header(h)}
  489. +if have_type("struct statfs", headers)
  490. + have_struct_member("struct statfs", "f_fstypename", headers)
  491. + have_struct_member("struct statfs", "f_type", headers)
  492. +end
  493. +
  494. +headers = %w[sys/statvfs.h]
  495. +if have_type("struct statvfs", headers)
  496. + have_struct_member("struct statvfs", "f_fstypename", headers)
  497. + have_struct_member("struct statvfs", "f_basetype", headers)
  498. + have_struct_member("struct statvfs", "f_type", headers)
  499. +end
  500. +
  501. $srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
  502. inits = $srcs.map {|s| File.basename(s, ".*")}
  503. inits.delete("init")
  504. diff --git a/ext/-test-/file/fs.c b/ext/-test-/file/fs.c
  505. index 4a41bf3..1ab067e 100644
  506. --- a/ext/-test-/file/fs.c
  507. +++ b/ext/-test-/file/fs.c
  508. @@ -1,55 +1,69 @@
  509. #include "ruby/ruby.h"
  510. #include "ruby/io.h"
  511. -#ifdef __linux__
  512. -# define HAVE_GETMNTENT
  513. +#ifdef HAVE_SYS_MOUNT_H
  514. +#include <sys/mount.h>
  515. +#endif
  516. +#ifdef HAVE_SYS_VFS_H
  517. +#include <sys/vfs.h>
  518. #endif
  519. -#ifdef HAVE_GETMNTENT
  520. -# include <stdio.h>
  521. -# include <mntent.h>
  522. +#if defined HAVE_STRUCT_STATFS_F_FSTYPENAME
  523. +typedef struct statfs statfs_t;
  524. +# define STATFS(f, s) statfs((f), (s))
  525. +# define HAVE_STRUCT_STATFS_T_F_FSTYPENAME 1
  526. +# if defined HAVE_STRUCT_STATFS_F_TYPE
  527. +# define HAVE_STRUCT_STATFS_T_F_TYPE 1
  528. +# endif
  529. +#elif defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME) /* NetBSD */
  530. +typedef struct statvfs statfs_t;
  531. +# define STATFS(f, s) statvfs((f), (s))
  532. +# define HAVE_STRUCT_STATFS_T_F_FSTYPENAME 1
  533. +# if defined HAVE_STRUCT_STATVFS_F_TYPE
  534. +# define HAVE_STRUCT_STATFS_T_F_TYPE 1
  535. +# endif
  536. +#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE) /* AIX, HP-UX, Solaris */
  537. +typedef struct statvfs statfs_t;
  538. +# define STATFS(f, s) statvfs((f), (s))
  539. +# define HAVE_STRUCT_STATFS_T_F_FSTYPENAME 1
  540. +# define f_fstypename f_basetype
  541. +# if defined HAVE_STRUCT_STATVFS_F_TYPE
  542. +# define HAVE_STRUCT_STATFS_T_F_TYPE 1
  543. +# endif
  544. #endif
  545. VALUE
  546. get_fsname(VALUE self, VALUE str)
  547. {
  548. -#ifdef HAVE_GETMNTENT
  549. - const char *path;
  550. - struct mntent mntbuf;
  551. - static const int buflen = 4096;
  552. - char *buf = alloca(buflen);
  553. - int len = 0;
  554. - FILE *fp;
  555. -#define FSNAME_LEN 100
  556. - char name[FSNAME_LEN] = "";
  557. +#ifdef STATFS
  558. + statfs_t st;
  559. +# define CSTR(s) rb_str_new_cstr(s)
  560. FilePathValue(str);
  561. - path = RSTRING_PTR(str);
  562. - fp = setmntent("/etc/mtab", "r");
  563. - if (!fp) rb_sys_fail("setmntent(/etb/mtab)");;
  564. -
  565. - while (getmntent_r(fp, &mntbuf, buf, buflen)) {
  566. - int i;
  567. - char *mnt_dir = mntbuf.mnt_dir;
  568. - for (i=0; mnt_dir[i]; i++) {
  569. - if (mnt_dir[i] != path[i]) {
  570. - goto next_entry;
  571. - }
  572. - }
  573. - if (i >= len) {
  574. - len = i;
  575. - strlcpy(name, mntbuf.mnt_type, FSNAME_LEN);
  576. - }
  577. -next_entry:
  578. - ;
  579. + str = rb_str_encode_ospath(str);
  580. + if (STATFS(StringValueCStr(str), &st) == -1) {
  581. + rb_sys_fail_str(str);
  582. }
  583. - endmntent(fp);
  584. -
  585. - if (!len) rb_sys_fail("no matching entry");;
  586. - return rb_str_new_cstr(name);
  587. -#else
  588. - return Qnil;
  589. +# ifdef HAVE_STRUCT_STATFS_T_F_FSTYPENAME
  590. + if (st.f_fstypename[0])
  591. + return CSTR(st.f_fstypename);
  592. +# endif
  593. +# ifdef HAVE_STRUCT_STATFS_T_F_TYPE
  594. + switch (st.f_type) {
  595. + case 0x9123683E: /* BTRFS_SUPER_MAGIC */
  596. + return CSTR("btrfs");
  597. + case 0x7461636f: /* OCFS2_SUPER_MAGIC */
  598. + return CSTR("ocfs");
  599. + case 0xEF53: /* EXT2_SUPER_MAGIC EXT3_SUPER_MAGIC EXT4_SUPER_MAGIC */
  600. + return CSTR("ext4");
  601. + case 0x58465342: /* XFS_SUPER_MAGIC */
  602. + return CSTR("xfs");
  603. + case 0x01021994: /* TMPFS_MAGIC */
  604. + return CSTR("tmpfs");
  605. + }
  606. +# endif
  607. #endif
  608. + return Qnil;
  609. }
  610. void
  611. diff --git a/ext/-test-/printf/printf.c b/ext/-test-/printf/printf.c
  612. index ef7570f..666f559 100644
  613. --- a/ext/-test-/printf/printf.c
  614. +++ b/ext/-test-/printf/printf.c
  615. @@ -20,7 +20,7 @@ printf_test_q(VALUE self, VALUE obj)
  616. }
  617. static char *
  618. -utoa(char *p, char *e, unsigned int x)
  619. +uint_to_str(char *p, char *e, unsigned int x)
  620. {
  621. char *e0 = e;
  622. if (e <= p) return p;
  623. @@ -71,12 +71,12 @@ printf_test_call(int argc, VALUE *argv, VALUE self)
  624. *p++ = '0';
  625. }
  626. if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("width"))))) {
  627. - p = utoa(p, format + sizeof(format), NUM2UINT(v));
  628. + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v));
  629. }
  630. if (!NIL_P(v = rb_hash_aref(opt, ID2SYM(rb_intern("prec"))))) {
  631. *p++ = '.';
  632. if (FIXNUM_P(v))
  633. - p = utoa(p, format + sizeof(format), NUM2UINT(v));
  634. + p = uint_to_str(p, format + sizeof(format), NUM2UINT(v));
  635. }
  636. }
  637. *p++ = cnv;
  638. diff --git a/ext/-test-/string/nofree.c b/ext/-test-/string/nofree.c
  639. new file mode 100644
  640. index 0000000..d3d8071
  641. --- /dev/null
  642. +++ b/ext/-test-/string/nofree.c
  643. @@ -0,0 +1,13 @@
  644. +#include "ruby.h"
  645. +
  646. +VALUE
  647. +bug_str_nofree(VALUE self)
  648. +{
  649. + return rb_str_new_cstr("abcdef");
  650. +}
  651. +
  652. +void
  653. +Init_nofree(VALUE klass)
  654. +{
  655. + rb_define_singleton_method(klass, "nofree", bug_str_nofree, 0);
  656. +}
  657. diff --git a/ext/bigdecimal/README b/ext/bigdecimal/README
  658. deleted file mode 100644
  659. index 7a43628..0000000
  660. --- a/ext/bigdecimal/README
  661. +++ /dev/null
  662. @@ -1,60 +0,0 @@
  663. -
  664. - Ruby BIGDECIMAL(Variable Precision) extension library.
  665. - Copyright (C) 1999 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
  666. -
  667. -BigDecimal is copyrighted free software by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.
  668. -You can redistribute it and/or modify it under either the terms of the GPL
  669. -(see COPYING file), or the conditions below:
  670. -
  671. - 1. You may make and give away verbatim copies of the source form of the
  672. - software without restriction, provided that you duplicate all of the
  673. - original copyright notices and associated disclaimers.
  674. -
  675. - 2. You may modify your copy of the software in any way, provided that
  676. - you do at least ONE of the following:
  677. -
  678. - a) place your modifications in the Public Domain or otherwise
  679. - make them Freely Available, such as by posting said
  680. - modifications to Usenet or an equivalent medium, or by allowing
  681. - the author to include your modifications in the software.
  682. -
  683. - b) use the modified software only within your corporation or
  684. - organization.
  685. -
  686. - c) rename any non-standard executables so the names do not conflict
  687. - with standard executables, which must also be provided.
  688. -
  689. - d) make other distribution arrangements with the author.
  690. -
  691. - 3. You may distribute the software in object code or executable
  692. - form, provided that you do at least ONE of the following:
  693. -
  694. - a) distribute the executables and library files of the software,
  695. - together with instructions (in the manual page or equivalent)
  696. - on where to get the original distribution.
  697. -
  698. - b) accompany the distribution with the machine-readable source of
  699. - the software.
  700. -
  701. - c) give non-standard executables non-standard names, with
  702. - instructions on where to get the original software distribution.
  703. -
  704. - d) make other distribution arrangements with the author.
  705. -
  706. - 4. You may modify and include the part of the software into any other
  707. - software (possibly commercial).
  708. -
  709. - 5. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  710. - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  711. - WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  712. - PURPOSE.
  713. -
  714. -* The Author
  715. -
  716. -Feel free to send comments and bug reports to the ruby-core team.
  717. -
  718. - http://bugs.ruby-lang.org
  719. -
  720. --------------------------------------------------------
  721. -created at: Thu Dec 22 1999
  722. -updated at: Wed Sep 28 2011
  723. diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
  724. index 9606646..aabdbc6 100644
  725. --- a/ext/bigdecimal/bigdecimal.c
  726. +++ b/ext/bigdecimal/bigdecimal.c
  727. @@ -4,13 +4,6 @@
  728. *
  729. * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
  730. *
  731. - * You may distribute under the terms of either the GNU General Public
  732. - * License or the Artistic License, as specified in the README file
  733. - * of this BigDecimal distribution.
  734. - *
  735. - * NOTE: Change log in this source removed to reduce source code size.
  736. - * See rev. 1.25 if needed.
  737. - *
  738. */
  739. /* #define BIGDECIMAL_DEBUG 1 */
  740. diff --git a/ext/bigdecimal/bigdecimal.gemspec b/ext/bigdecimal/bigdecimal.gemspec
  741. index 197bdea..7e291a3 100644
  742. --- a/ext/bigdecimal/bigdecimal.gemspec
  743. +++ b/ext/bigdecimal/bigdecimal.gemspec
  744. @@ -6,6 +6,7 @@ Gem::Specification.new do |s|
  745. s.name = "bigdecimal"
  746. s.version = _VERSION
  747. s.date = date
  748. + s.license = 'ruby'
  749. s.summary = "Arbitrary-precision decimal floating-point number library."
  750. s.homepage = "http://www.ruby-lang.org"
  751. s.email = "mrkn@mrkn.jp"
  752. @@ -16,7 +17,6 @@ Gem::Specification.new do |s|
  753. bigdecimal.gemspec
  754. bigdecimal.c
  755. bigdecimal.h
  756. - README
  757. depend extconf.rb
  758. lib/bigdecimal/jacobian.rb
  759. lib/bigdecimal/ludcmp.rb
  760. diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
  761. index 9d3e0fc..e8adea6 100644
  762. --- a/ext/bigdecimal/bigdecimal.h
  763. +++ b/ext/bigdecimal/bigdecimal.h
  764. @@ -4,13 +4,6 @@
  765. *
  766. * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
  767. *
  768. - * You may distribute under the terms of either the GNU General Public
  769. - * License or the Artistic License, as specified in the README file
  770. - * of this BigDecimal distribution.
  771. - *
  772. - * NOTES:
  773. - * 2003-03-28 V1.0 checked in.
  774. - *
  775. */
  776. #ifndef RUBY_BIG_DECIMAL_H
  777. diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
  778. index 3a24d17..6d564a3 100644
  779. --- a/ext/openssl/ossl_asn1.c
  780. +++ b/ext/openssl/ossl_asn1.c
  781. @@ -1029,7 +1029,7 @@ static VALUE
  782. ossl_asn1_traverse(VALUE self, VALUE obj)
  783. {
  784. unsigned char *p;
  785. - volatile VALUE tmp;
  786. + VALUE tmp;
  787. long len, read = 0, offset = 0;
  788. obj = ossl_to_der_if_possible(obj);
  789. @@ -1037,6 +1037,7 @@ ossl_asn1_traverse(VALUE self, VALUE obj)
  790. p = (unsigned char *)RSTRING_PTR(tmp);
  791. len = RSTRING_LEN(tmp);
  792. ossl_asn1_decode0(&p, len, &offset, 0, 1, &read);
  793. + RB_GC_GUARD(tmp);
  794. int_ossl_decode_sanity_check(len, read, offset);
  795. return Qnil;
  796. }
  797. @@ -1058,7 +1059,7 @@ ossl_asn1_decode(VALUE self, VALUE obj)
  798. {
  799. VALUE ret;
  800. unsigned char *p;
  801. - volatile VALUE tmp;
  802. + VALUE tmp;
  803. long len, read = 0, offset = 0;
  804. obj = ossl_to_der_if_possible(obj);
  805. @@ -1066,6 +1067,7 @@ ossl_asn1_decode(VALUE self, VALUE obj)
  806. p = (unsigned char *)RSTRING_PTR(tmp);
  807. len = RSTRING_LEN(tmp);
  808. ret = ossl_asn1_decode0(&p, len, &offset, 0, 0, &read);
  809. + RB_GC_GUARD(tmp);
  810. int_ossl_decode_sanity_check(len, read, offset);
  811. return ret;
  812. }
  813. @@ -1089,7 +1091,7 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
  814. VALUE ary, val;
  815. unsigned char *p;
  816. long len, tmp_len = 0, read = 0, offset = 0;
  817. - volatile VALUE tmp;
  818. + VALUE tmp;
  819. obj = ossl_to_der_if_possible(obj);
  820. tmp = rb_str_new4(StringValue(obj));
  821. @@ -1104,6 +1106,7 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
  822. read += tmp_read;
  823. tmp_len -= tmp_read;
  824. }
  825. + RB_GC_GUARD(tmp);
  826. int_ossl_decode_sanity_check(len, read, offset);
  827. return ary;
  828. }
  829. diff --git a/ext/pty/pty.c b/ext/pty/pty.c
  830. index 29cc689..631adb2 100644
  831. --- a/ext/pty/pty.c
  832. +++ b/ext/pty/pty.c
  833. @@ -261,7 +261,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
  834. if ((slavefd = rb_cloexec_open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
  835. rb_update_max_fd(slavefd);
  836. -#if defined(I_PUSH) && !defined(__linux__)
  837. +#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
  838. if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
  839. if (ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
  840. if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) goto error;
  841. @@ -345,7 +345,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
  842. if (no_mesg(slavedevice, nomesg) == -1) goto error;
  843. if((slavefd = rb_cloexec_open(slavedevice, O_RDWR, 0)) == -1) goto error;
  844. rb_update_max_fd(slavefd);
  845. -#if defined(I_PUSH) && !defined(__linux__)
  846. +#if defined(I_PUSH) && !defined(__linux__) && !defined(_AIX)
  847. if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
  848. if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
  849. ioctl(slavefd, I_PUSH, "ttcompat");
  850. diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
  851. index f0dbb2b..b69417e 100644
  852. --- a/ext/socket/ancdata.c
  853. +++ b/ext/socket/ancdata.c
  854. @@ -1135,7 +1135,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
  855. struct msghdr mh;
  856. struct iovec iov;
  857. #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
  858. - volatile VALUE controls_str = 0;
  859. + VALUE controls_str = 0;
  860. VALUE *controls_ptr = NULL;
  861. int family;
  862. #endif
  863. @@ -1291,6 +1291,9 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
  864. rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block");
  865. rb_sys_fail("sendmsg(2)");
  866. }
  867. +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
  868. + RB_GC_GUARD(controls_str);
  869. +#endif
  870. return SSIZET2NUM(ss);
  871. }
  872. @@ -1711,6 +1714,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
  873. discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
  874. rb_ary_push(ret, ctl);
  875. }
  876. + RB_GC_GUARD(ctl_str);
  877. }
  878. #endif
  879. diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c
  880. index ef5ce76..16a8373 100644
  881. --- a/ext/socket/ipsocket.c
  882. +++ b/ext/socket/ipsocket.c
  883. @@ -41,6 +41,7 @@ inetsock_cleanup(struct inetsock_arg *arg)
  884. static VALUE
  885. init_inetsock_internal(struct inetsock_arg *arg)
  886. {
  887. + int error = 0;
  888. int type = arg->type;
  889. struct addrinfo *res, *lres;
  890. int fd, status = 0, local = 0;
  891. @@ -80,6 +81,7 @@ init_inetsock_internal(struct inetsock_arg *arg)
  892. syscall = "socket(2)";
  893. fd = status;
  894. if (fd < 0) {
  895. + error = errno;
  896. continue;
  897. }
  898. arg->fd = fd;
  899. @@ -107,6 +109,7 @@ init_inetsock_internal(struct inetsock_arg *arg)
  900. }
  901. if (status < 0) {
  902. + error = errno;
  903. close(fd);
  904. arg->fd = fd = -1;
  905. continue;
  906. @@ -124,7 +127,7 @@ init_inetsock_internal(struct inetsock_arg *arg)
  907. port = arg->remote.serv;
  908. }
  909. - rsock_sys_fail_host_port(syscall, host, port);
  910. + rsock_syserr_fail_host_port(error, syscall, host, port);
  911. }
  912. arg->fd = -1;
  913. @@ -132,8 +135,9 @@ init_inetsock_internal(struct inetsock_arg *arg)
  914. if (type == INET_SERVER) {
  915. status = listen(fd, SOMAXCONN);
  916. if (status < 0) {
  917. + error = errno;
  918. close(fd);
  919. - rb_sys_fail("listen(2)");
  920. + rb_syserr_fail(error, "listen(2)");
  921. }
  922. }
  923. diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
  924. index e13684a..d838898 100644
  925. --- a/ext/socket/raddrinfo.c
  926. +++ b/ext/socket/raddrinfo.c
  927. @@ -1643,6 +1643,7 @@ addrinfo_mload(VALUE self, VALUE ary)
  928. len = res->ai->ai_addrlen;
  929. memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen);
  930. + rb_freeaddrinfo(res);
  931. break;
  932. }
  933. }
  934. diff --git a/gc.c b/gc.c
  935. index 5940564..549d7ca 100644
  936. --- a/gc.c
  937. +++ b/gc.c
  938. @@ -2771,6 +2771,9 @@ id2ref(VALUE obj, VALUE objid)
  939. if (!is_live_object(objspace, ptr)) {
  940. rb_raise(rb_eRangeError, "%p is recycled object", p0);
  941. }
  942. + if (RBASIC(ptr)->klass == 0) {
  943. + rb_raise(rb_eRangeError, "%p is internal object", p0);
  944. + }
  945. return (VALUE)ptr;
  946. }
  947. diff --git a/hash.c b/hash.c
  948. index 8d37dc6..fb4c5a5 100644
  949. --- a/hash.c
  950. +++ b/hash.c
  951. @@ -142,13 +142,19 @@ rb_any_hash(VALUE a)
  952. }
  953. else if (FLONUM_P(a)) {
  954. /* prevent pathological behavior: [Bug #10761] */
  955. - a = (st_index_t)rb_float_value(a);
  956. + return rb_dbl_hash(rb_float_value(a));
  957. }
  958. hnum = rb_objid_hash((st_index_t)a);
  959. }
  960. else if (BUILTIN_TYPE(a) == T_STRING) {
  961. hnum = rb_str_hash(a);
  962. }
  963. + else if (BUILTIN_TYPE(a) == T_SYMBOL) {
  964. + hnum = rb_objid_hash((st_index_t)a);
  965. + }
  966. + else if (BUILTIN_TYPE(a) == T_FLOAT) {
  967. + return rb_dbl_hash(rb_float_value(a));
  968. + }
  969. else {
  970. hval = rb_hash(a);
  971. hnum = FIX2LONG(hval);
  972. diff --git a/internal.h b/internal.h
  973. index 4da45a4..1833dca 100644
  974. --- a/internal.h
  975. +++ b/internal.h
  976. @@ -773,6 +773,7 @@ double ruby_float_mod(double x, double y);
  977. int rb_num_negative_p(VALUE);
  978. VALUE rb_int_succ(VALUE num);
  979. VALUE rb_int_pred(VALUE num);
  980. +VALUE rb_dbl_hash(double d);
  981. #if USE_FLONUM
  982. #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
  983. diff --git a/iseq.c b/iseq.c
  984. index de65dcb..9cf5df6 100644
  985. --- a/iseq.c
  986. +++ b/iseq.c
  987. @@ -596,6 +596,7 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE li
  988. if (RB_TYPE_P((src), T_FILE))
  989. node = rb_parser_compile_file_path(parser, file, src, ln);
  990. else {
  991. + StringValue(src);
  992. node = rb_parser_compile_string_path(parser, file, src, ln);
  993. if (!node) {
  994. diff --git a/lib/fileutils.rb b/lib/fileutils.rb
  995. index 23fd193..932776c 100644
  996. --- a/lib/fileutils.rb
  997. +++ b/lib/fileutils.rb
  998. @@ -518,7 +518,7 @@ module FileUtils
  999. begin
  1000. if destent.exist?
  1001. if destent.directory?
  1002. - raise Errno::EEXIST, dest
  1003. + raise Errno::EEXIST, d
  1004. else
  1005. destent.remove_file if rename_cannot_overwrite_file?
  1006. end
  1007. diff --git a/lib/net/imap.rb b/lib/net/imap.rb
  1008. index a772c46..0517ca1 100644
  1009. --- a/lib/net/imap.rb
  1010. +++ b/lib/net/imap.rb
  1011. @@ -2625,7 +2625,13 @@ module Net
  1012. return param
  1013. end
  1014. disposition = body_fld_dsp
  1015. - match(T_SPACE)
  1016. +
  1017. + token = lookahead
  1018. + if token.symbol == T_SPACE
  1019. + shift_token
  1020. + else
  1021. + return param, disposition
  1022. + end
  1023. language = body_fld_lang
  1024. token = lookahead
  1025. diff --git a/lib/resolv.rb b/lib/resolv.rb
  1026. index 7855c6e..dee6afd 100644
  1027. --- a/lib/resolv.rb
  1028. +++ b/lib/resolv.rb
  1029. @@ -1183,7 +1183,7 @@ class Resolv
  1030. end
  1031. def ==(other)
  1032. - return @downcase == other.downcase
  1033. + return self.class == other.class && @downcase == other.downcase
  1034. end
  1035. def eql?(other)
  1036. @@ -1219,6 +1219,14 @@ class Resolv
  1037. end
  1038. def initialize(labels, absolute=true) # :nodoc:
  1039. + labels = labels.map {|label|
  1040. + case label
  1041. + when String then Label::Str.new(label)
  1042. + when Label::Str then label
  1043. + else
  1044. + raise ArgumentError, "unexpected label: #{label.inspect}"
  1045. + end
  1046. + }
  1047. @labels = labels
  1048. @absolute = absolute
  1049. end
  1050. diff --git a/load.c b/load.c
  1051. index 65017c9..af3548c 100644
  1052. --- a/load.c
  1053. +++ b/load.c
  1054. @@ -318,7 +318,7 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len,
  1055. const char *e;
  1056. if (vlen < len+1) return 0;
  1057. - if (!strncmp(name+(vlen-len), feature, len)) {
  1058. + if (strchr(feature, '.') && !strncmp(name+(vlen-len), feature, len)) {
  1059. plen = vlen - len;
  1060. }
  1061. else {
  1062. diff --git a/marshal.c b/marshal.c
  1063. index bd57b1f..ab1ab56 100644
  1064. --- a/marshal.c
  1065. +++ b/marshal.c
  1066. @@ -1298,11 +1298,18 @@ r_bytes0(long len, struct load_arg *arg)
  1067. static int
  1068. sym2encidx(VALUE sym, VALUE val)
  1069. {
  1070. - if (sym == ID2SYM(rb_id_encoding())) {
  1071. + static const char name_encoding[8] = "encoding";
  1072. + const char *p;
  1073. + long l;
  1074. + if (rb_enc_get_index(sym) != ENCINDEX_US_ASCII) return -1;
  1075. + RSTRING_GETMEM(sym, p, l);
  1076. + if (l <= 0) return -1;
  1077. + if (l == sizeof(name_encoding) &&
  1078. + memcmp(p, name_encoding, sizeof(name_encoding)) == 0) {
  1079. int idx = rb_enc_find_index(StringValueCStr(val));
  1080. return idx;
  1081. }
  1082. - else if (sym == ID2SYM(rb_intern("E"))) {
  1083. + else if (l == 1 && *p == 'E') {
  1084. if (val == Qfalse) return rb_usascii_encindex();
  1085. else if (val == Qtrue) return rb_utf8_encindex();
  1086. /* bogus ignore */
  1087. @@ -1330,7 +1337,8 @@ r_symreal(struct load_arg *arg, int ivar)
  1088. int idx = -1;
  1089. st_index_t n = arg->symbols->num_entries;
  1090. - st_insert(arg->symbols, (st_data_t)n, (st_data_t)0);
  1091. + if (rb_enc_str_asciionly_p(s)) rb_enc_associate_index(s, ENCINDEX_US_ASCII);
  1092. + st_insert(arg->symbols, (st_data_t)n, (st_data_t)s);
  1093. if (ivar) {
  1094. long num = r_long(arg);
  1095. while (num-- > 0) {
  1096. @@ -1339,10 +1347,8 @@ r_symreal(struct load_arg *arg, int ivar)
  1097. }
  1098. }
  1099. if (idx > 0) rb_enc_associate_index(s, idx);
  1100. - sym = rb_str_intern(s);
  1101. - st_insert(arg->symbols, (st_data_t)n, (st_data_t)sym);
  1102. - return sym;
  1103. + return s;
  1104. }
  1105. static VALUE
  1106. @@ -1370,7 +1376,7 @@ r_symbol(struct load_arg *arg)
  1107. static VALUE
  1108. r_unique(struct load_arg *arg)
  1109. {
  1110. - return rb_sym2str(r_symbol(arg));
  1111. + return r_symbol(arg);
  1112. }
  1113. static VALUE
  1114. @@ -1468,7 +1474,7 @@ r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
  1115. if (has_encoding) *has_encoding = TRUE;
  1116. }
  1117. else {
  1118. - rb_ivar_set(obj, SYM2ID(sym), val);
  1119. + rb_ivar_set(obj, rb_intern_str(sym), val);
  1120. }
  1121. } while (--len > 0);
  1122. }
  1123. @@ -1793,13 +1799,13 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
  1124. v = r_entry0(v, idx, arg);
  1125. values = rb_ary_new2(len);
  1126. for (i=0; i<len; i++) {
  1127. + VALUE n = rb_sym2str(RARRAY_AREF(mem, i));
  1128. slot = r_symbol(arg);
  1129. - if (RARRAY_AREF(mem, i) != slot) {
  1130. + if (!rb_str_equal(n, slot)) {
  1131. rb_raise(rb_eTypeError, "struct %"PRIsVALUE" not compatible (:%"PRIsVALUE" for :%"PRIsVALUE")",
  1132. rb_class_name(klass),
  1133. - rb_sym2str(slot),
  1134. - rb_sym2str(RARRAY_AREF(mem, i)));
  1135. + slot, n);
  1136. }
  1137. rb_ary_push(values, r_object(arg));
  1138. arg->readable -= 2;
  1139. @@ -1937,11 +1943,12 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
  1140. else {
  1141. v = r_symreal(arg, 0);
  1142. }
  1143. + v = rb_str_intern(v);
  1144. v = r_leave(v, arg);
  1145. break;
  1146. case TYPE_SYMLINK:
  1147. - v = r_symlink(arg);
  1148. + v = rb_str_intern(r_symlink(arg));
  1149. break;
  1150. default:
  1151. diff --git a/numeric.c b/numeric.c
  1152. index 0222c76..e7435bb 100644
  1153. --- a/numeric.c
  1154. +++ b/numeric.c
  1155. @@ -1137,10 +1137,14 @@ flo_eq(VALUE x, VALUE y)
  1156. static VALUE
  1157. flo_hash(VALUE num)
  1158. {
  1159. - double d;
  1160. + return rb_dbl_hash(RFLOAT_VALUE(num));
  1161. +}
  1162. +
  1163. +VALUE
  1164. +rb_dbl_hash(double d)
  1165. +{
  1166. st_index_t hash;
  1167. - d = RFLOAT_VALUE(num);
  1168. /* normalize -0.0 to 0.0 */
  1169. if (d == 0.0) d = 0.0;
  1170. hash = rb_memhash(&d, sizeof(d));
  1171. diff --git a/parse.y b/parse.y
  1172. index 0f9a567..1e29197 100644
  1173. --- a/parse.y
  1174. +++ b/parse.y
  1175. @@ -3534,14 +3534,19 @@ lambda : {
  1176. {
  1177. $<num>$ = ruby_sourceline;
  1178. }
  1179. + {
  1180. + $<val>$ = cmdarg_stack;
  1181. + cmdarg_stack = 0;
  1182. + }
  1183. lambda_body
  1184. {
  1185. lpar_beg = $<num>2;
  1186. + cmdarg_stack = $<val>5;
  1187. /*%%%*/
  1188. - $$ = NEW_LAMBDA($3, $5);
  1189. + $$ = NEW_LAMBDA($3, $6);
  1190. nd_set_line($$, $<num>4);
  1191. /*%
  1192. - $$ = dispatch2(lambda, $3, $5);
  1193. + $$ = dispatch2(lambda, $3, $6);
  1194. %*/
  1195. dyna_pop($<vars>1);
  1196. }
  1197. diff --git a/proc.c b/proc.c
  1198. index 48d7dcb..5995c97 100644
  1199. --- a/proc.c
  1200. +++ b/proc.c
  1201. @@ -719,7 +719,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
  1202. GetProcPtr(procval, proc);
  1203. iseq = proc->block.iseq;
  1204. - if (BUILTIN_TYPE(iseq) == T_NODE || iseq->param.flags.has_block) {
  1205. + if (RUBY_VM_IFUNC_P(iseq) || iseq->param.flags.has_block) {
  1206. if (rb_block_given_p()) {
  1207. rb_proc_t *passed_proc;
  1208. RB_GC_GUARD(passed_procval) = rb_block_proc();
  1209. @@ -843,7 +843,7 @@ rb_block_min_max_arity(rb_block_t *block, int *max)
  1210. {
  1211. rb_iseq_t *iseq = block->iseq;
  1212. if (iseq) {
  1213. - if (BUILTIN_TYPE(iseq) != T_NODE) {
  1214. + if (!RUBY_VM_IFUNC_P(iseq)) {
  1215. return rb_iseq_min_max_arity(iseq, max);
  1216. }
  1217. else {
  1218. @@ -1131,29 +1131,68 @@ rb_obj_is_method(VALUE m)
  1219. }
  1220. }
  1221. +static int
  1222. +respond_to_missing_p(VALUE klass, VALUE obj, VALUE sym, int scope)
  1223. +{
  1224. + /* TODO: merge with obj_respond_to() */
  1225. + ID rmiss = idRespond_to_missing;
  1226. +
  1227. + if (obj == Qundef) return 0;
  1228. + if (rb_method_basic_definition_p(klass, rmiss)) return 0;
  1229. + return RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue));
  1230. +}
  1231. +
  1232. +
  1233. +static VALUE
  1234. +mnew_missing(VALUE rclass, VALUE klass, VALUE obj, ID id, ID rid, VALUE mclass)
  1235. +{
  1236. + struct METHOD *data;
  1237. + VALUE method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
  1238. + rb_method_entry_t *me;
  1239. + rb_method_definition_t *def;
  1240. +
  1241. + data->recv = obj;
  1242. + data->rclass = rclass;
  1243. + data->defined_class = klass;
  1244. + data->id = rid;
  1245. +
  1246. + me = ALLOC(rb_method_entry_t);
  1247. + data->me = me;
  1248. + me->flag = 0;
  1249. + me->mark = 0;
  1250. + me->called_id = id;
  1251. + me->klass = klass;
  1252. + me->def = 0;
  1253. +
  1254. + def = ALLOC(rb_method_definition_t);
  1255. + me->def = def;
  1256. + def->type = VM_METHOD_TYPE_MISSING;
  1257. + def->original_id = id;
  1258. + def->alias_count = 0;
  1259. +
  1260. + data->ume = ALLOC(struct unlinked_method_entry_list_entry);
  1261. + data->me->def->alias_count++;
  1262. +
  1263. + OBJ_INFECT(method, klass);
  1264. +
  1265. + return method;
  1266. +}
  1267. +
  1268. static VALUE
  1269. mnew_internal(rb_method_entry_t *me, VALUE defined_class, VALUE klass,
  1270. VALUE obj, ID id, VALUE mclass, int scope, int error)
  1271. {
  1272. - VALUE method;
  1273. + struct METHOD *data;
  1274. VALUE rclass = klass;
  1275. + VALUE method;
  1276. ID rid = id;
  1277. - struct METHOD *data;
  1278. rb_method_definition_t *def = 0;
  1279. rb_method_flag_t flag = NOEX_UNDEF;
  1280. again:
  1281. if (UNDEFINED_METHOD_ENTRY_P(me)) {
  1282. - ID rmiss = idRespond_to_missing;
  1283. - VALUE sym = ID2SYM(id);
  1284. -
  1285. - if (obj != Qundef && !rb_method_basic_definition_p(klass, rmiss)) {
  1286. - if (RTEST(rb_funcall(obj, rmiss, 2, sym, scope ? Qfalse : Qtrue))) {
  1287. - me = 0;
  1288. - defined_class = klass;
  1289. -
  1290. - goto gen_method;
  1291. - }
  1292. + if (respond_to_missing_p(klass, obj, ID2SYM(id), scope)) {
  1293. + return mnew_missing(rclass, klass, obj, id, rid, mclass);
  1294. }
  1295. if (!error) return Qnil;
  1296. rb_print_undef(klass, id, 0);
  1297. @@ -1180,7 +1219,6 @@ mnew_internal(rb_method_entry_t *me, VALUE defined_class, VALUE klass,
  1298. rclass = RCLASS_SUPER(rclass);
  1299. }
  1300. - gen_method:
  1301. method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
  1302. data->recv = obj;
  1303. @@ -1188,25 +1226,7 @@ mnew_internal(rb_method_entry_t *me, VALUE defined_class, VALUE klass,
  1304. data->defined_class = defined_class;
  1305. data->id = rid;
  1306. data->me = ALLOC(rb_method_entry_t);
  1307. - if (me) {
  1308. - *data->me = *me;
  1309. - }
  1310. - else {
  1311. - me = data->me;
  1312. - me->flag = 0;
  1313. - me->mark = 0;
  1314. - me->called_id = id;
  1315. - me->klass = klass;
  1316. - me->def = 0;
  1317. -
  1318. - def = ALLOC(rb_method_definition_t);
  1319. - me->def = def;
  1320. -
  1321. - def->type = VM_METHOD_TYPE_MISSING;
  1322. - def->original_id = id;
  1323. - def->alias_count = 0;
  1324. -
  1325. - }
  1326. + *data->me = *me;
  1327. data->ume = ALLOC(struct unlinked_method_entry_list_entry);
  1328. data->me->def->alias_count++;
  1329. @@ -1438,6 +1458,23 @@ rb_method_name_error(VALUE klass, VALUE str)
  1330. QUOTE(str), s0, rb_class_name(c));
  1331. }
  1332. +static VALUE
  1333. +obj_method(VALUE obj, VALUE vid, int scope)
  1334. +{
  1335. + ID id = rb_check_id(&vid);
  1336. + const VALUE klass = CLASS_OF(obj);
  1337. + const VALUE mclass = rb_cMethod;
  1338. +
  1339. + if (!id) {
  1340. + if (respond_to_missing_p(klass, obj, vid, scope)) {
  1341. + id = rb_intern_str(vid);
  1342. + return mnew_missing(klass, klass, obj, id, id, mclass);
  1343. + }
  1344. + rb_method_name_error(klass, vid);
  1345. + }
  1346. + return mnew(klass, obj, id, mclass, scope);
  1347. +}
  1348. +
  1349. /*
  1350. * call-seq:
  1351. * obj.method(sym) -> method
  1352. @@ -1469,11 +1506,7 @@ rb_method_name_error(VALUE klass, VALUE str)
  1353. VALUE
  1354. rb_obj_method(VALUE obj, VALUE vid)
  1355. {
  1356. - ID id = rb_check_id(&vid);
  1357. - if (!id) {
  1358. - rb_method_name_error(CLASS_OF(obj), vid);
  1359. - }
  1360. - return mnew(CLASS_OF(obj), obj, id, rb_cMethod, FALSE);
  1361. + return obj_method(obj, vid, FALSE);
  1362. }
  1363. /*
  1364. @@ -1486,11 +1519,7 @@ rb_obj_method(VALUE obj, VALUE vid)
  1365. VALUE
  1366. rb_obj_public_method(VALUE obj, VALUE vid)
  1367. {
  1368. - ID id = rb_check_id(&vid);
  1369. - if (!id) {
  1370. - rb_method_name_error(CLASS_OF(obj), vid);
  1371. - }
  1372. - return mnew(CLASS_OF(obj), obj, id, rb_cMethod, TRUE);
  1373. + return obj_method(obj, vid, TRUE);
  1374. }
  1375. /*
  1376. @@ -1524,6 +1553,11 @@ rb_obj_singleton_method(VALUE obj, VALUE vid)
  1377. VALUE klass;
  1378. ID id = rb_check_id(&vid);
  1379. if (!id) {
  1380. + if (!NIL_P(klass = rb_singleton_class_get(obj)) &&
  1381. + respond_to_missing_p(klass, obj, vid, FALSE)) {
  1382. + id = rb_intern_str(vid);
  1383. + return mnew_missing(klass, klass, obj, id, id, rb_cMethod);
  1384. + }
  1385. rb_name_error_str(vid, "undefined singleton method `%"PRIsVALUE"' for `%"PRIsVALUE"'",
  1386. QUOTE(vid), obj);
  1387. }
  1388. @@ -1683,7 +1717,7 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
  1389. rb_proc_t *proc;
  1390. body = proc_dup(body);
  1391. GetProcPtr(body, proc);
  1392. - if (BUILTIN_TYPE(proc->block.iseq) != T_NODE) {
  1393. + if (!RUBY_VM_IFUNC_P(proc->block.iseq)) {
  1394. proc->block.iseq->defined_method_id = id;
  1395. RB_OBJ_WRITE(proc->block.iseq->self, &proc->block.iseq->klass, mod);
  1396. proc->is_lambda = TRUE;
  1397. @@ -2443,22 +2477,40 @@ static VALUE
  1398. proc_binding(VALUE self)
  1399. {
  1400. rb_proc_t *proc;
  1401. - VALUE bindval;
  1402. + VALUE bindval, envval;
  1403. rb_binding_t *bind;
  1404. rb_iseq_t *iseq;
  1405. GetProcPtr(self, proc);
  1406. + envval = proc->envval;
  1407. iseq = proc->block.iseq;
  1408. - if (RB_TYPE_P((VALUE)iseq, T_NODE)) {
  1409. + if (RUBY_VM_IFUNC_P(iseq)) {
  1410. + rb_env_t *env;
  1411. if (!IS_METHOD_PROC_NODE((NODE *)iseq)) {
  1412. rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
  1413. }
  1414. iseq = rb_method_get_iseq(RNODE(iseq)->u2.value);
  1415. + GetEnvPtr(envval, env);
  1416. + if (iseq && env->local_size < iseq->local_size) {
  1417. + int prev_local_size = env->local_size;
  1418. + int local_size = iseq->local_size;
  1419. + VALUE newenvval = TypedData_Wrap_Struct(RBASIC_CLASS(envval), RTYPEDDATA_TYPE(envval), 0);
  1420. + rb_env_t *newenv = xmalloc(sizeof(rb_env_t) + ((local_size + 1) * sizeof(VALUE)));
  1421. + RTYPEDDATA_DATA(newenvval) = newenv;
  1422. + newenv->env_size = local_size + 2;
  1423. + newenv->local_size = local_size;
  1424. + newenv->prev_envval = env->prev_envval;
  1425. + newenv->block = env->block;
  1426. + MEMCPY(newenv->env, env->env, VALUE, prev_local_size + 1);
  1427. + rb_mem_clear(newenv->env + prev_local_size + 1, local_size - prev_local_size);
  1428. + newenv->env[local_size + 1] = newenvval;
  1429. + envval = newenvval;
  1430. + }
  1431. }
  1432. bindval = rb_binding_alloc(rb_cBinding);
  1433. GetBindingPtr(bindval, bind);
  1434. - bind->env = proc->envval;
  1435. + bind->env = envval;
  1436. bind->blockprocval = proc->blockprocval;
  1437. if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
  1438. bind->path = iseq->location.path;
  1439. diff --git a/range.c b/range.c
  1440. index f4ab7e1..857cb48 100644
  1441. --- a/range.c
  1442. +++ b/range.c
  1443. @@ -329,6 +329,21 @@ discrete_object_p(VALUE obj)
  1444. return rb_respond_to(obj, id_succ);
  1445. }
  1446. +static int
  1447. +linear_object_p(VALUE obj)
  1448. +{
  1449. + if (FIXNUM_P(obj) || FLONUM_P(obj)) return TRUE;
  1450. + if (SPECIAL_CONST_P(obj)) return FALSE;
  1451. + switch (BUILTIN_TYPE(obj)) {
  1452. + case T_FLOAT:
  1453. + case T_BIGNUM:
  1454. + return TRUE;
  1455. + }
  1456. + if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE;
  1457. + if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE;
  1458. + return FALSE;
  1459. +}
  1460. +
  1461. static VALUE
  1462. range_step_size(VALUE range, VALUE args, VALUE eobj)
  1463. {
  1464. @@ -1155,8 +1170,7 @@ range_include(VALUE range, VALUE val)
  1465. VALUE beg = RANGE_BEG(range);
  1466. VALUE end = RANGE_END(range);
  1467. int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
  1468. - rb_obj_is_kind_of(beg, rb_cNumeric) ||
  1469. - rb_obj_is_kind_of(end, rb_cNumeric);
  1470. + linear_object_p(beg) || linear_object_p(end);
  1471. if (nv ||
  1472. !NIL_P(rb_check_to_integer(beg, "to_int")) ||
  1473. diff --git a/rational.c b/rational.c
  1474. index addb195..134db64 100644
  1475. --- a/rational.c
  1476. +++ b/rational.c
  1477. @@ -2465,13 +2465,14 @@ nurat_s_convert(int argc, VALUE *argv, VALUE klass)
  1478. * a/b (b>0). Where a is numerator and b is denominator. Integer a
  1479. * equals rational a/1 mathematically.
  1480. *
  1481. - * In ruby, you can create rational object with Rational, to_r or
  1482. - * rationalize method. The return values will be irreducible.
  1483. + * In ruby, you can create rational object with Rational, to_r,
  1484. + * rationalize method or suffixing r to a literal. The return values will be irreducible.
  1485. *
  1486. * Rational(1) #=> (1/1)
  1487. * Rational(2, 3) #=> (2/3)
  1488. * Rational(4, -6) #=> (-2/3)
  1489. * 3.to_r #=> (3/1)
  1490. + * 2/3r #=> (2/3)
  1491. *
  1492. * You can also create rational object from floating-point numbers or
  1493. * strings.
  1494. diff --git a/string.c b/string.c
  1495. index 2652b29..e6a5fb8 100644
  1496. --- a/string.c
  1497. +++ b/string.c
  1498. @@ -60,7 +60,7 @@ VALUE rb_cSymbol;
  1499. FL_SET((str), STR_NOEMBED);\
  1500. STR_SET_EMBED_LEN((str), 0);\
  1501. } while (0)
  1502. -#define STR_SET_EMBED(str) FL_UNSET((str), STR_NOEMBED)
  1503. +#define STR_SET_EMBED(str) FL_UNSET((str), (STR_NOEMBED|STR_NOFREE))
  1504. #define STR_SET_EMBED_LEN(str, n) do { \
  1505. long tmp_n = (n);\
  1506. RBASIC(str)->flags &= ~RSTRING_EMBED_LEN_MASK;\
  1507. @@ -4226,6 +4226,9 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
  1508. * double-quoted string, both back-references must be preceded by an
  1509. * additional backslash. However, within +replacement+ the special match
  1510. * variables, such as <code>&$</code>, will not refer to the current match.
  1511. + * If +replacement+ is a String that looks like a pattern's capture group but
  1512. + * is actaully not a pattern capture group e.g. <code>"\\'"</code>, then it
  1513. + * will have to be preceded by two backslashes like so <code>"\\\\'"</code>.
  1514. *
  1515. * If the second argument is a Hash, and the matched text is one of its keys,
  1516. * the corresponding value is the replacement string.
  1517. diff --git a/symbol.c b/symbol.c
  1518. index 1127020..696f017 100644
  1519. --- a/symbol.c
  1520. +++ b/symbol.c
  1521. @@ -122,7 +122,7 @@ static const struct st_hash_type symhash = {
  1522. void
  1523. Init_sym(void)
  1524. {
  1525. - VALUE dsym_fstrs = rb_hash_new();
  1526. + VALUE dsym_fstrs = rb_ident_hash_new();
  1527. global_symbols.dsymbol_fstr_hash = dsym_fstrs;
  1528. rb_gc_register_mark_object(dsym_fstrs);
  1529. rb_obj_hide(dsym_fstrs);
  1530. diff --git a/test/-ext-/string/test_nofree.rb b/test/-ext-/string/test_nofree.rb
  1531. new file mode 100644
  1532. index 0000000..234c84d
  1533. --- /dev/null
  1534. +++ b/test/-ext-/string/test_nofree.rb
  1535. @@ -0,0 +1,10 @@
  1536. +require 'test/unit'
  1537. +
  1538. +class Test_StringNoFree < Test::Unit::TestCase
  1539. + def test_no_memory_leak
  1540. + bug10942 = '[ruby-core:68436] [Bug #10942] no leak on nofree string'
  1541. + assert_no_memory_leak(%w(-r-test-/string/string), '',
  1542. + '1000000.times {Bug::String.nofree << "a" * 100}',
  1543. + bug10942, rss: true, limit: 2.0)
  1544. + end
  1545. +end
  1546. diff --git a/test/-ext-/symbol/test_inadvertent_creation.rb b/test/-ext-/symbol/test_inadvertent_creation.rb
  1547. index 4e7a85f..f772086 100644
  1548. --- a/test/-ext-/symbol/test_inadvertent_creation.rb
  1549. +++ b/test/-ext-/symbol/test_inadvertent_creation.rb
  1550. @@ -82,6 +82,28 @@ module Test_Symbol
  1551. assert_not_interned_false(c, :class_variable_defined?, noninterned_name("@@"), feature5072)
  1552. end
  1553. + def test_missing_method
  1554. + bug10985 = '[ruby-core:68564] [Bug #10985]'
  1555. + m = nil
  1556. + c = Class.new do
  1557. + def self.respond_to_missing?(*)
  1558. + true
  1559. + end
  1560. + end
  1561. +
  1562. + s = noninterned_name
  1563. + assert_nothing_raised(NameError, bug10985) {m = c.method(s)}
  1564. + assert_raise_with_message(NoMethodError, /#{s}/) {m.call}
  1565. +
  1566. + s = noninterned_name
  1567. + assert_nothing_raised(NameError, bug10985) {m = c.public_method(s.to_sym)}
  1568. + assert_raise_with_message(NoMethodError, /#{s}/) {m.call}
  1569. +
  1570. + s = noninterned_name
  1571. + assert_nothing_raised(NameError, bug10985) {m = c.singleton_method(s.to_sym)}
  1572. + assert_raise_with_message(NoMethodError, /#{s}/) {m.call}
  1573. + end
  1574. +
  1575. Feature5079 = '[ruby-core:38404]'
  1576. def test_undefined_instance_variable
  1577. diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
  1578. index fe9a1b3..295fbfd9 100644
  1579. --- a/test/fileutils/test_fileutils.rb
  1580. +++ b/test/fileutils/test_fileutils.rb
  1581. @@ -416,7 +416,8 @@ class TestFileUtils < Test::Unit::TestCase
  1582. mkdir 'tmp/tmpdir'
  1583. mkdir_p 'tmp/dest2/tmpdir'
  1584. - assert_raise(Errno::EEXIST) {
  1585. + assert_raise_with_message(Errno::EEXIST, %r' - tmp/dest2/tmpdir\z',
  1586. + '[ruby-core:68706] [Bug #11021]') {
  1587. mv 'tmp/tmpdir', 'tmp/dest2'
  1588. }
  1589. mkdir 'tmp/dest2/tmpdir/junk'
  1590. diff --git a/test/net/imap/test_imap_response_parser.rb b/test/net/imap/test_imap_response_parser.rb
  1591. index ded7dd1..1612d78 100644
  1592. --- a/test/net/imap/test_imap_response_parser.rb
  1593. +++ b/test/net/imap/test_imap_response_parser.rb
  1594. @@ -276,4 +276,17 @@ EOF
  1595. assert_equal("SEARCH", response.name)
  1596. assert_equal([87216, 87221], response.data)
  1597. end
  1598. +
  1599. + # [Bug #11128]
  1600. + def test_body_ext_mpart_without_lang
  1601. + parser = Net::IMAP::ResponseParser.new
  1602. + response = parser.parse("* 4 FETCH (BODY (((\"text\" \"plain\" (\"charset\" \"utf-8\") NIL NIL \"7bit\" 257 9 NIL NIL NIL NIL)(\"text\" \"html\" (\"charset\" \"utf-8\") NIL NIL \"quoted-printable\" 655 9 NIL NIL NIL NIL) \"alternative\" (\"boundary\" \"001a1137a5047848dd05157ddaa1\") NIL)(\"application\" \"pdf\" (\"name\" \"test.xml\" \"x-apple-part-url\" \"9D00D9A2-98AB-4EFB-85BA-FB255F8BF3D7\") NIL NIL \"base64\" 4383638 NIL (\"attachment\" (\"filename\" \"test.xml\")) NIL NIL) \"mixed\" (\"boundary\" \"001a1137a5047848e405157ddaa3\") NIL))\r\n")
  1603. + assert_equal("FETCH", response.name)
  1604. + body = response.data.attr["BODY"]
  1605. + assert_equal(nil, body.parts[0].disposition)
  1606. + assert_equal(nil, body.parts[0].language)
  1607. + assert_equal("ATTACHMENT", body.parts[1].disposition.dsp_type)
  1608. + assert_equal("test.xml", body.parts[1].disposition.param["FILENAME"])
  1609. + assert_equal(nil, body.parts[1].language)
  1610. + end
  1611. end
  1612. diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb
  1613. index 8e54dd7..d7e5c36 100644
  1614. --- a/test/resolv/test_dns.rb
  1615. +++ b/test/resolv/test_dns.rb
  1616. @@ -190,4 +190,11 @@ class TestResolvDNS < Test::Unit::TestCase
  1617. upper = Resolv::DNS::Name.create("Ruby-Lang.org")
  1618. assert_equal(lower, upper, bug10550)
  1619. end
  1620. +
  1621. + def test_ipv6_name
  1622. + addr = Resolv::IPv6.new("\0"*16)
  1623. + labels = addr.to_name.to_a
  1624. + expected = (['0'] * 32 + ['ip6', 'arpa']).map {|label| Resolv::DNS::Label::Str.new(label) }
  1625. + assert_equal(expected, labels)
  1626. + end
  1627. end
  1628. diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb
  1629. index a95c274..da8855b 100644
  1630. --- a/test/ruby/test_autoload.rb
  1631. +++ b/test/ruby/test_autoload.rb
  1632. @@ -55,6 +55,32 @@ p Foo::Bar
  1633. }
  1634. end
  1635. + def test_autoload_with_unqualified_file_name # [ruby-core:69206]
  1636. + lp = $LOAD_PATH.dup
  1637. + lf = $LOADED_FEATURES.dup
  1638. +
  1639. + Dir.mktmpdir('autoload') { |tmpdir|
  1640. + $LOAD_PATH << tmpdir
  1641. +
  1642. + Dir.chdir(tmpdir) do
  1643. + eval <<-END
  1644. + class ::Object
  1645. + module A
  1646. + autoload :C, 'b'
  1647. + end
  1648. + end
  1649. + END
  1650. +
  1651. + File.open('b.rb', 'w') {|file| file.puts 'module A; class C; end; end'}
  1652. + assert_kind_of Class, ::A::C
  1653. + end
  1654. + }
  1655. + ensure
  1656. + $LOAD_PATH.replace lp
  1657. + $LOADED_FEATURES.replace lf
  1658. + Object.send(:remove_const, :A) if Object.const_defined?(:A)
  1659. + end
  1660. +
  1661. def test_require_explicit
  1662. Tempfile.create(['autoload', '.rb']) {|file|
  1663. file.puts 'class Object; AutoloadTest = 1; end'
  1664. diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
  1665. index ac2d843..eab4d12 100644
  1666. --- a/test/ruby/test_float.rb
  1667. +++ b/test/ruby/test_float.rb
  1668. @@ -672,4 +672,12 @@ class TestFloat < Test::Unit::TestCase
  1669. assert_equal(0.0, z)
  1670. assert_equal(-Float::INFINITY, 1.0/z)
  1671. end
  1672. +
  1673. + def test_hash_0
  1674. + bug10979 = '[ruby-core:68541] [Bug #10979]'
  1675. + assert_equal(+0.0.hash, -0.0.hash)
  1676. + assert_operator(+0.0, :eql?, -0.0)
  1677. + h = {0.0 => bug10979}
  1678. + assert_equal(bug10979, h[-0.0])
  1679. + end
  1680. end
  1681. diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
  1682. index 4af440a..686646d 100644
  1683. --- a/test/ruby/test_iseq.rb
  1684. +++ b/test/ruby/test_iseq.rb
  1685. @@ -134,4 +134,11 @@ class TestISeq < Test::Unit::TestCase
  1686. assert(!op.to_s.match(/^opt_/), "#{op}")
  1687. }
  1688. end
  1689. +
  1690. + def test_invalid_source
  1691. + bug11159 = '[ruby-core:69219] [Bug #11159]'
  1692. + assert_raise(TypeError, bug11159) {ISeq.compile(nil)}
  1693. + assert_raise(TypeError, bug11159) {ISeq.compile(:foo)}
  1694. + assert_raise(TypeError, bug11159) {ISeq.compile(1)}
  1695. + end
  1696. end
  1697. diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
  1698. index 70cdba1..9c76e15 100644
  1699. --- a/test/ruby/test_keyword.rb
  1700. +++ b/test/ruby/test_keyword.rb
  1701. @@ -566,4 +566,14 @@ class TestKeywordArguments < Test::Unit::TestCase
  1702. result = m(["a" => 10]) { |a = nil, **b| [a, b] }
  1703. assert_equal([{"a" => 10}, {}], result)
  1704. end
  1705. +
  1706. + def method_for_test_to_hash_call_during_setup_complex_parameters k1:, k2:, **rest_kw
  1707. + [k1, k2, rest_kw]
  1708. + end
  1709. +
  1710. + def test_to_hash_call_during_setup_complex_parameters
  1711. + sym = "sym_#{Time.now}".to_sym
  1712. + h = method_for_test_to_hash_call_during_setup_complex_parameters k1: "foo", k2: "bar", sym => "baz"
  1713. + assert_equal ["foo", "bar", {sym => "baz"}], h, '[Bug #11027]'
  1714. + end
  1715. end
  1716. diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
  1717. index 9b82d52..3d5d6c9 100644
  1718. --- a/test/ruby/test_marshal.rb
  1719. +++ b/test/ruby/test_marshal.rb
  1720. @@ -252,6 +252,17 @@ class TestMarshal < Test::Unit::TestCase
  1721. assert_include(Marshal.dump([:a, :a]), ';')
  1722. end
  1723. + def test_symlink_in_ivar
  1724. + bug10991 = '[ruby-core:68587] [Bug #10991]'
  1725. + sym = Marshal.load("\x04\x08" +
  1726. + "I" ":\x0bKernel" +
  1727. + ("\x06" +
  1728. + ("I" ":\x07@a" +
  1729. + ("\x06" ":\x07@b" "e;\x0""o:\x0bObject""\x0")) +
  1730. + "0"))
  1731. + assert_equal(:Kernel, sym, bug10991)
  1732. + end
  1733. +
  1734. ClassUTF8 = eval("class R\u{e9}sum\u{e9}; self; end")
  1735. iso_8859_1 = Encoding::ISO_8859_1
  1736. diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
  1737. index c8b5ff1..35ddc87 100644
  1738. --- a/test/ruby/test_method.rb
  1739. +++ b/test/ruby/test_method.rb
  1740. @@ -877,4 +877,18 @@ class TestMethod < Test::Unit::TestCase
  1741. obj.bar
  1742. end
  1743. end
  1744. +
  1745. + def test_to_proc_binding
  1746. + bug11012 = '[ruby-core:68673] [Bug #11012]'
  1747. + class << (obj = Object.new)
  1748. + src = 1000.times.map {|i|"v#{i} = nil"}.join("\n")
  1749. + eval("def foo()\n""#{src}\n""end")
  1750. + end
  1751. +
  1752. + b = obj.method(:foo).to_proc.binding
  1753. + b.local_variables.each_with_index {|n, i|
  1754. + b.local_variable_set(n, i)
  1755. + }
  1756. + assert_equal([998, 999], %w[v998 v999].map {|n| b.local_variable_get(n)}, bug11012)
  1757. + end
  1758. end
  1759. diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
  1760. index f81047d..852515f 100644
  1761. --- a/test/ruby/test_range.rb
  1762. +++ b/test/ruby/test_range.rb
  1763. @@ -283,6 +283,14 @@ class TestRange < Test::Unit::TestCase
  1764. assert_not_operator(0..10, :===, 11)
  1765. end
  1766. + def test_eqq_time
  1767. + bug11113 = '[ruby-core:69052] [Bug #11113]'
  1768. + t = Time.now
  1769. + assert_nothing_raised(TypeError, bug11113) {
  1770. + assert_operator(t..(t+10), :===, t+5)
  1771. + }
  1772. + end
  1773. +
  1774. def test_include
  1775. assert_include("a".."z", "c")
  1776. assert_not_include("a".."z", "5")
  1777. diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
  1778. index 8d3da54..7cb1248 100644
  1779. --- a/test/ruby/test_rubyoptions.rb
  1780. +++ b/test/ruby/test_rubyoptions.rb
  1781. @@ -720,6 +720,14 @@ class TestRubyOptions < Test::Unit::TestCase
  1782. bug10555, encoding: "locale")
  1783. end
  1784. end
  1785. +
  1786. + def test_command_line_glob_with_dir
  1787. + bug10941 = '[ruby-core:68430] [Bug #10941]'
  1788. + with_tmpchdir do |dir|
  1789. + Dir.mkdir('test')
  1790. + assert_in_out_err(["-e", "", "test/*"], "", [], [], bug10941)
  1791. + end
  1792. + end
  1793. end
  1794. if /mswin|mingw/ =~ RUBY_PLATFORM
  1795. diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
  1796. index 58e927c..1dcd2cc 100644
  1797. --- a/test/ruby/test_settracefunc.rb
  1798. +++ b/test/ruby/test_settracefunc.rb
  1799. @@ -1332,4 +1332,24 @@ class TestSetTraceFunc < Test::Unit::TestCase
  1800. }
  1801. assert_equal [__LINE__ - 3, __LINE__ - 2], lines, 'Bug #10449'
  1802. end
  1803. +
  1804. + class Bug10724
  1805. + def initialize
  1806. + loop{return}
  1807. + end
  1808. + end
  1809. +
  1810. + def test_throwing_return_with_finish_frame
  1811. + target_th = Thread.current
  1812. + evs = []
  1813. +
  1814. + TracePoint.new(:call, :return){|tp|
  1815. + return if Thread.current != target_th
  1816. + evs << tp.event
  1817. + }.enable{
  1818. + a = Bug10724.new
  1819. + }
  1820. +
  1821. + assert_equal([:call, :return], evs)
  1822. + end
  1823. end
  1824. diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb
  1825. index 596f2b0..ee29cd5 100644
  1826. --- a/test/ruby/test_symbol.rb
  1827. +++ b/test/ruby/test_symbol.rb
  1828. @@ -199,6 +199,35 @@ class TestSymbol < Test::Unit::TestCase
  1829. assert_raise(TypeError) { a = :foo; def a.foo; end }
  1830. end
  1831. + SymbolsForEval = [
  1832. + :foo,
  1833. + "dynsym_#{Random.rand(10000)}_#{Time.now}".to_sym
  1834. + ]
  1835. +
  1836. + def test_instance_eval
  1837. + bug11086 = '[ruby-core:68961] [Bug #11086]'
  1838. + SymbolsForEval.each do |sym|
  1839. + assert_nothing_raised(TypeError, sym, bug11086) {
  1840. + sym.instance_eval {}
  1841. + }
  1842. + assert_raise(TypeError, sym, bug11086) {
  1843. + sym.instance_eval {def foo; end}
  1844. + }
  1845. + end
  1846. + end
  1847. +
  1848. + def test_instance_exec
  1849. + bug11086 = '[ruby-core:68961] [Bug #11086]'
  1850. + SymbolsForEval.each do |sym|
  1851. + assert_nothing_raised(TypeError, sym, bug11086) {
  1852. + sym.instance_exec {}
  1853. + }
  1854. + assert_raise(TypeError, sym, bug11086) {
  1855. + sym.instance_exec {def foo; end}
  1856. + }
  1857. + end
  1858. + end
  1859. +
  1860. def test_frozen_symbol
  1861. assert_equal(true, :foo.frozen?)
  1862. assert_equal(true, :each.frozen?)
  1863. @@ -238,4 +267,23 @@ class TestSymbol < Test::Unit::TestCase
  1864. 200_000.times { |i| i.to_s.to_sym }
  1865. end;
  1866. end
  1867. +
  1868. + def test_hash_redefinition
  1869. + assert_separately([], <<-'end;')
  1870. + bug11035 = '[ruby-core:68767] [Bug #11035]'
  1871. + class Symbol
  1872. + def hash
  1873. + raise
  1874. + end
  1875. + end
  1876. +
  1877. + h = {}
  1878. + assert_nothing_raised(RuntimeError, bug11035) {
  1879. + h[:foo] = 1
  1880. + }
  1881. + assert_nothing_raised(RuntimeError, bug11035) {
  1882. + h['bar'.to_sym] = 2
  1883. + }
  1884. + end;
  1885. + end
  1886. end
  1887. diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
  1888. index 0274a11..dbb1816 100644
  1889. --- a/test/ruby/test_syntax.rb
  1890. +++ b/test/ruby/test_syntax.rb
  1891. @@ -400,6 +400,11 @@ WARN
  1892. assert_valid_syntax("bar def foo; self.each do end end", bug9308)
  1893. end
  1894. + def test_do_block_in_lambda
  1895. + bug11107 = '[ruby-core:69017] [Bug #11107]'
  1896. + assert_valid_syntax('p ->() do a() do end end', bug11107)
  1897. + end
  1898. +
  1899. def test_reserved_method_no_args
  1900. bug6403 = '[ruby-dev:45626]'
  1901. assert_valid_syntax("def self; :foo; end", __FILE__, bug6403)
  1902. diff --git a/test/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb
  1903. index 61b889e..96e1991 100644
  1904. --- a/test/socket/test_addrinfo.rb
  1905. +++ b/test/socket/test_addrinfo.rb
  1906. @@ -468,6 +468,17 @@ class TestSocketAddrinfo < Test::Unit::TestCase
  1907. assert_equal(ai1.canonname, ai2.canonname)
  1908. end
  1909. + def test_marshal_memory_leak
  1910. + bug11051 = '[ruby-dev:48923] [Bug #11051]'
  1911. + assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true, limit: 2.0)
  1912. + d = Marshal.dump(Addrinfo.tcp("127.0.0.1", 80))
  1913. + 1000.times {Marshal.load(d)}
  1914. + PREP
  1915. + GC.start
  1916. + 20_000.times {Marshal.load(d)}
  1917. + CODE
  1918. + end
  1919. +
  1920. if Socket.const_defined?("AF_INET6") && Socket::AF_INET6.is_a?(Integer)
  1921. def test_addrinfo_new_inet6
  1922. diff --git a/thread_pthread.c b/thread_pthread.c
  1923. index 711e60b..5fcad19 100644
  1924. --- a/thread_pthread.c
  1925. +++ b/thread_pthread.c
  1926. @@ -662,11 +662,16 @@ reserve_stack(volatile char *limit, size_t size)
  1927. # endif
  1928. struct rlimit rl;
  1929. volatile char buf[0x100];
  1930. + enum {stack_check_margin = 0x1000}; /* for -fstack-check */
  1931. +
  1932. STACK_GROW_DIR_DETECTION;
  1933. if (!getrlimit(RLIMIT_STACK, &rl) && rl.rlim_cur == RLIM_INFINITY)
  1934. return;
  1935. + if (size < stack_check_margin) return;
  1936. + size -= stack_check_margin;
  1937. +
  1938. size -= sizeof(buf); /* margin */
  1939. if (IS_STACK_DIR_UPPER()) {
  1940. const volatile char *end = buf + sizeof(buf);
  1941. @@ -674,13 +679,14 @@ reserve_stack(volatile char *limit, size_t size)
  1942. if (limit > end) {
  1943. size = limit - end;
  1944. limit = alloca(size);
  1945. - limit[size-1] = 0;
  1946. + limit[stack_check_margin+size-1] = 0;
  1947. }
  1948. }
  1949. else {
  1950. limit -= size;
  1951. if (buf > limit) {
  1952. limit = alloca(buf - limit);
  1953. + limit -= stack_check_margin;
  1954. limit[0] = 0;
  1955. }
  1956. }
  1957. diff --git a/version.h b/version.h
  1958. index 6766b31..e5f8480 100644
  1959. --- a/version.h
  1960. +++ b/version.h
  1961. @@ -1,10 +1,10 @@
  1962. #define RUBY_VERSION "2.2.2"
  1963. -#define RUBY_RELEASE_DATE "2015-04-13"
  1964. -#define RUBY_PATCHLEVEL 95
  1965. +#define RUBY_RELEASE_DATE "2015-06-12"
  1966. +#define RUBY_PATCHLEVEL 133
  1967. #define RUBY_RELEASE_YEAR 2015
  1968. -#define RUBY_RELEASE_MONTH 4
  1969. -#define RUBY_RELEASE_DAY 13
  1970. +#define RUBY_RELEASE_MONTH 6
  1971. +#define RUBY_RELEASE_DAY 12
  1972. #include "ruby/version.h"
  1973. diff --git a/vm.c b/vm.c
  1974. index e6ef3a8..17f3c53 100644
  1975. --- a/vm.c
  1976. +++ b/vm.c
  1977. @@ -380,7 +380,7 @@ env_mark(void * const ptr)
  1978. RUBY_MARK_UNLESS_NULL(env->block.proc);
  1979. if (env->block.iseq) {
  1980. - if (BUILTIN_TYPE(env->block.iseq) == T_NODE) {
  1981. + if (RUBY_VM_IFUNC_P(env->block.iseq)) {
  1982. RUBY_MARK_UNLESS_NULL((VALUE)env->block.iseq);
  1983. }
  1984. else {
  1985. @@ -768,7 +768,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
  1986. if (SPECIAL_CONST_P(block->iseq)) {
  1987. return Qnil;
  1988. }
  1989. - else if (BUILTIN_TYPE(block->iseq) != T_NODE) {
  1990. + else if (!RUBY_VM_IFUNC_P(block->iseq)) {
  1991. VALUE ret;
  1992. const rb_iseq_t *iseq = block->iseq;
  1993. const rb_control_frame_t *cfp;
  1994. @@ -1287,6 +1287,30 @@ vm_frametype_name(const rb_control_frame_t *cfp)
  1995. }
  1996. #endif
  1997. +static void
  1998. +hook_before_rewind(rb_thread_t *th, rb_control_frame_t *cfp)
  1999. +{
  2000. + switch (VM_FRAME_TYPE(th->cfp)) {
  2001. + case VM_FRAME_MAGIC_METHOD:
  2002. + RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
  2003. + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil);
  2004. + break;
  2005. + case VM_FRAME_MAGIC_BLOCK:
  2006. + case VM_FRAME_MAGIC_LAMBDA:
  2007. + if (VM_FRAME_TYPE_BMETHOD_P(th->cfp)) {
  2008. + EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
  2009. + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, th->cfp->me->called_id, th->cfp->me->klass, Qnil);
  2010. + }
  2011. + else {
  2012. + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
  2013. + }
  2014. + break;
  2015. + case VM_FRAME_MAGIC_CLASS:
  2016. + EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->cfp->self, 0, 0, Qnil);
  2017. + break;
  2018. + }
  2019. +}
  2020. +
  2021. /* evaluator body */
  2022. /* finish
  2023. @@ -1385,7 +1409,6 @@ vm_frametype_name(const rb_control_frame_t *cfp)
  2024. };
  2025. */
  2026. -
  2027. static VALUE
  2028. vm_exec(rb_thread_t *th)
  2029. {
  2030. @@ -1455,15 +1478,9 @@ vm_exec(rb_thread_t *th)
  2031. }
  2032. }
  2033. if (!catch_iseqval) {
  2034. - result = GET_THROWOBJ_VAL(err);
  2035. th->errinfo = Qnil;
  2036. -
  2037. - switch (VM_FRAME_TYPE(cfp)) {
  2038. - case VM_FRAME_MAGIC_LAMBDA:
  2039. - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
  2040. - break;
  2041. - }
  2042. -
  2043. + result = GET_THROWOBJ_VAL(err);
  2044. + hook_before_rewind(th, th->cfp);
  2045. vm_pop_frame(th);
  2046. goto finish_vme;
  2047. }
  2048. @@ -1606,26 +1623,7 @@ vm_exec(rb_thread_t *th)
  2049. }
  2050. else {
  2051. /* skip frame */
  2052. -
  2053. - switch (VM_FRAME_TYPE(th->cfp)) {
  2054. - case VM_FRAME_MAGIC_METHOD:
  2055. - RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
  2056. - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil);
  2057. - break;
  2058. - case VM_FRAME_MAGIC_BLOCK:
  2059. - case VM_FRAME_MAGIC_LAMBDA:
  2060. - if (VM_FRAME_TYPE_BMETHOD_P(th->cfp)) {
  2061. - EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
  2062. - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, th->cfp->me->called_id, th->cfp->me->klass, Qnil);
  2063. - }
  2064. - else {
  2065. - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
  2066. - }
  2067. - break;
  2068. - case VM_FRAME_MAGIC_CLASS:
  2069. - EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->cfp->self, 0, 0, Qnil);
  2070. - break;
  2071. - }
  2072. + hook_before_rewind(th, th->cfp);
  2073. if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
  2074. vm_pop_frame(th);
  2075. @@ -2015,7 +2013,6 @@ rb_thread_mark(void *ptr)
  2076. rb_control_frame_t *limit_cfp = (void *)(th->stack + th->stack_size);
  2077. rb_gc_mark_values((long)(sp - p), p);
  2078. - rb_gc_mark_locations(sp, sp + th->mark_stack_len);
  2079. while (cfp != limit_cfp) {
  2080. rb_iseq_t *iseq = cfp->iseq;
  2081. diff --git a/vm_args.c b/vm_args.c
  2082. index 446ad48..abdd161 100644
  2083. --- a/vm_args.c
  2084. +++ b/vm_args.c
  2085. @@ -83,19 +83,17 @@ args_reduce(struct args_info *args, int over_argc)
  2086. }
  2087. static inline int
  2088. -args_check_block_arg0(struct args_info *args, rb_thread_t *th, const int msl)
  2089. +args_check_block_arg0(struct args_info *args, rb_thread_t *th)
  2090. {
  2091. VALUE ary = Qnil;
  2092. if (args->rest && RARRAY_LEN(args->rest) == 1) {
  2093. VALUE arg0 = RARRAY_AREF(args->rest, 0);
  2094. ary = rb_check_array_type(arg0);
  2095. - th->mark_stack_len = msl;
  2096. }
  2097. else if (args->argc == 1) {
  2098. VALUE arg0 = args->argv[0];
  2099. ary = rb_check_array_type(arg0);
  2100. - th->mark_stack_len = msl;
  2101. args->argv[0] = arg0; /* see: https://bugs.ruby-lang.org/issues/8484 */
  2102. }
  2103. @@ -173,10 +171,9 @@ args_rest_array(struct args_info *args)
  2104. }
  2105. static int
  2106. -keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th, const int msl)
  2107. +keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th)
  2108. {
  2109. *rest_hash_ptr = rb_check_hash_type(*kw_hash_ptr);
  2110. - th->mark_stack_len = msl;
  2111. if (!NIL_P(*rest_hash_ptr)) {
  2112. VALUE hash = rb_extract_keywords(rest_hash_ptr);
  2113. @@ -191,7 +188,7 @@ keyword_hash_p(VALUE *kw_hash_ptr, VALUE *rest_hash_ptr, rb_thread_t *th, const
  2114. }
  2115. static VALUE
  2116. -args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *th, const int msl)
  2117. +args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *th)
  2118. {
  2119. VALUE rest_hash;
  2120. @@ -200,7 +197,7 @@ args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *t
  2121. assert(args->argc > 0);
  2122. *kw_hash_ptr = args->argv[args->argc-1];
  2123. - if (keyword_hash_p(kw_hash_ptr, &rest_hash, th, msl)) {
  2124. + if (keyword_hash_p(kw_hash_ptr, &rest_hash, th)) {
  2125. if (rest_hash) {
  2126. args->argv[args->argc-1] = rest_hash;
  2127. }
  2128. @@ -216,7 +213,7 @@ args_pop_keyword_hash(struct args_info *args, VALUE *kw_hash_ptr, rb_thread_t *t
  2129. if (len > 0) {
  2130. *kw_hash_ptr = RARRAY_AREF(args->rest, len - 1);
  2131. - if (keyword_hash_p(kw_hash_ptr, &rest_hash, th, msl)) {
  2132. + if (keyword_hash_p(kw_hash_ptr, &rest_hash, th)) {
  2133. if (rest_hash) {
  2134. RARRAY_ASET(args->rest, len - 1, rest_hash);
  2135. }
  2136. @@ -511,9 +508,27 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
  2137. int given_argc;
  2138. struct args_info args_body, *args;
  2139. VALUE keyword_hash = Qnil;
  2140. - const int msl = ci->argc + iseq->param.size;
  2141. + VALUE * const orig_sp = th->cfp->sp;
  2142. + int i;
  2143. - th->mark_stack_len = msl;
  2144. + /*
  2145. + * Extend SP for GC.
  2146. + *
  2147. + * [pushed values] [uninitialized values]
  2148. + * <- ci->argc -->
  2149. + * <- iseq->param.size------------------>
  2150. + * ^ locals ^ sp
  2151. + *
  2152. + * =>
  2153. + * [pushed values] [initialized values ]
  2154. + * <- ci->argc -->
  2155. + * <- iseq->param.size------------------>
  2156. + * ^ locals ^ sp
  2157. + */
  2158. + for (i=ci->argc; i<iseq->param.size; i++) {
  2159. + locals[i] = Qnil;
  2160. + }
  2161. + th->cfp->sp = &locals[i];
  2162. /* setup args */
  2163. args = &args_body;
  2164. @@ -556,7 +571,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
  2165. (min_argc > 0 || iseq->param.opt_num > 1 ||
  2166. iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
  2167. !iseq->param.flags.ambiguous_param0 &&
  2168. - args_check_block_arg0(args, th, msl)) {
  2169. + args_check_block_arg0(args, th)) {
  2170. given_argc = RARRAY_LENINT(args->rest);
  2171. }
  2172. break;
  2173. @@ -564,7 +579,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
  2174. if (given_argc == 1 &&
  2175. given_argc != iseq->param.lead_num &&
  2176. !iseq->param.flags.has_rest &&
  2177. - args_check_block_arg0(args, th, msl)) {
  2178. + args_check_block_arg0(args, th)) {
  2179. given_argc = RARRAY_LENINT(args->rest);
  2180. }
  2181. }
  2182. @@ -590,7 +605,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
  2183. if (given_argc > min_argc &&
  2184. (iseq->param.flags.has_kw || iseq->param.flags.has_kwrest) &&
  2185. args->kw_argv == NULL) {
  2186. - if (args_pop_keyword_hash(args, &keyword_hash, th, msl)) {
  2187. + if (args_pop_keyword_hash(args, &keyword_hash, th)) {
  2188. given_argc--;
  2189. }
  2190. }
  2191. @@ -662,8 +677,7 @@ setup_parameters_complex(rb_thread_t * const th, const rb_iseq_t * const iseq, r
  2192. }
  2193. #endif
  2194. - th->mark_stack_len = 0;
  2195. -
  2196. + th->cfp->sp = orig_sp;
  2197. return opt_pc;
  2198. }
  2199. diff --git a/vm_core.h b/vm_core.h
  2200. index 3eb1b85..9079130 100644
  2201. --- a/vm_core.h
  2202. +++ b/vm_core.h
  2203. @@ -642,7 +642,6 @@ typedef struct rb_thread_struct {
  2204. enum rb_thread_status status;
  2205. int to_kill;
  2206. int priority;
  2207. - int mark_stack_len;
  2208. native_thread_data_t native_thread_data;
  2209. void *blocking_region_buffer;
  2210. @@ -913,7 +912,7 @@ rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp);
  2211. #define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
  2212. (!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th)))
  2213. -#define RUBY_VM_IFUNC_P(ptr) (BUILTIN_TYPE(ptr) == T_NODE)
  2214. +#define RUBY_VM_IFUNC_P(ptr) RB_TYPE_P((VALUE)(ptr), T_NODE)
  2215. #define RUBY_VM_NORMAL_ISEQ_P(ptr) \
  2216. ((ptr) && !RUBY_VM_IFUNC_P(ptr))
  2217. diff --git a/vm_dump.c b/vm_dump.c
  2218. index da2e6a9..a8d4875 100644
  2219. --- a/vm_dump.c
  2220. +++ b/vm_dump.c
  2221. @@ -36,7 +36,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
  2222. const char *magic, *iseq_name = "-", *selfstr = "-", *biseq_name = "-";
  2223. VALUE tmp;
  2224. - if (cfp->block_iseq != 0 && BUILTIN_TYPE(cfp->block_iseq) != T_NODE) {
  2225. + if (cfp->block_iseq != 0 && !RUBY_VM_IFUNC_P(cfp->block_iseq)) {
  2226. biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */
  2227. }
  2228. @@ -735,7 +735,11 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp)
  2229. ptrwidth, "START", ptrwidth, "END", "PRT", "RES",
  2230. "PRES", "REF", "SHD", "FL", "TP", "PATH");
  2231. +#ifdef HAVE_PROCSTAT_GETVMMAP
  2232. freep = procstat_getvmmap(procstat, kipp, &cnt);
  2233. +#else
  2234. + freep = kinfo_getvmmap(kipp->ki_pid, &cnt);
  2235. +#endif
  2236. if (freep == NULL)
  2237. return;
  2238. for (i = 0; i < cnt; i++) {
  2239. diff --git a/vm_eval.c b/vm_eval.c
  2240. index 2bdf63b..bcd455b 100644
  2241. --- a/vm_eval.c
  2242. +++ b/vm_eval.c
  2243. @@ -1629,6 +1629,20 @@ specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self)
  2244. }
  2245. }
  2246. +static VALUE
  2247. +singleton_class_for_eval(VALUE self)
  2248. +{
  2249. + if (SPECIAL_CONST_P(self)) {
  2250. + return rb_special_singleton_class(self);
  2251. + }
  2252. + switch (BUILTIN_TYPE(self)) {
  2253. + case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
  2254. + return Qnil;
  2255. + default:
  2256. + return rb_singleton_class(self);
  2257. + }
  2258. +}
  2259. +
  2260. /*
  2261. * call-seq:
  2262. * obj.instance_eval(string [, filename [, lineno]] ) -> obj
  2263. @@ -1665,14 +1679,7 @@ specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self)
  2264. VALUE
  2265. rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
  2266. {
  2267. - VALUE klass;
  2268. -
  2269. - if (SPECIAL_CONST_P(self)) {
  2270. - klass = rb_special_singleton_class(self);
  2271. - }
  2272. - else {
  2273. - klass = rb_singleton_class(self);
  2274. - }
  2275. + VALUE klass = singleton_class_for_eval(self);
  2276. return specific_eval(argc, argv, klass, self);
  2277. }
  2278. @@ -1697,14 +1704,7 @@ rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
  2279. VALUE
  2280. rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
  2281. {
  2282. - VALUE klass;
  2283. -
  2284. - if (SPECIAL_CONST_P(self)) {
  2285. - klass = rb_special_singleton_class(self);
  2286. - }
  2287. - else {
  2288. - klass = rb_singleton_class(self);
  2289. - }
  2290. + VALUE klass = singleton_class_for_eval(self);
  2291. return yield_under(klass, self, rb_ary_new4(argc, argv));
  2292. }
  2293. diff --git a/vm_insnhelper.c b/vm_insnhelper.c
  2294. index 21c60af..8b2f8e7 100644
  2295. --- a/vm_insnhelper.c
  2296. +++ b/vm_insnhelper.c
  2297. @@ -630,13 +630,11 @@ vm_throw_start(rb_thread_t * const th, rb_control_frame_t * const reg_cfp, int s
  2298. rb_iseq_t *base_iseq = GET_ISEQ();
  2299. escape_cfp = reg_cfp;
  2300. - search_parent:
  2301. - if (base_iseq->type != ISEQ_TYPE_BLOCK) {
  2302. + while (base_iseq->type != ISEQ_TYPE_BLOCK) {
  2303. if (escape_cfp->iseq->type == ISEQ_TYPE_CLASS) {
  2304. escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp);
  2305. ep = escape_cfp->ep;
  2306. base_iseq = escape_cfp->iseq;
  2307. - goto search_parent;
  2308. }
  2309. else {
  2310. ep = VM_EP_PREV_EP(ep);
  2311. @@ -2073,7 +2071,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci
  2312. }
  2313. iseq = block->iseq;
  2314. - if (BUILTIN_TYPE(iseq) != T_NODE) {
  2315. + if (!RUBY_VM_IFUNC_P(iseq)) {
  2316. int opt_pc;
  2317. const int arg_size = iseq->param.size;
  2318. int is_lambda = block_proc_is_lambda(block->proc);
  2319. diff --git a/win32/win32.c b/win32/win32.c
  2320. index b7d7e32..fc2c99e 100644
  2321. --- a/win32/win32.c
  2322. +++ b/win32/win32.c
  2323. @@ -6318,12 +6318,16 @@ rb_w32_close(int fd)
  2324. }
  2325. static int
  2326. -setup_overlapped(OVERLAPPED *ol, int fd)
  2327. +setup_overlapped(OVERLAPPED *ol, int fd, int iswrite)
  2328. {
  2329. memset(ol, 0, sizeof(*ol));
  2330. if (!(_osfile(fd) & (FDEV | FPIPE))) {
  2331. LONG high = 0;
  2332. - DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT;
  2333. + /* On mode:a, it can write only FILE_END.
  2334. + * On mode:a+, though it can write only FILE_END,
  2335. + * it can read from everywhere.
  2336. + */
  2337. + DWORD method = ((_osfile(fd) & FAPPEND) && iswrite) ? FILE_END : FILE_CURRENT;
  2338. DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method);
  2339. #ifndef INVALID_SET_FILE_POINTER
  2340. #define INVALID_SET_FILE_POINTER ((DWORD)-1)
  2341. @@ -6420,7 +6424,7 @@ rb_w32_read(int fd, void *buf, size_t size)
  2342. /* if have cancel_io, use Overlapped I/O */
  2343. if (cancel_io) {
  2344. - if (setup_overlapped(&ol, fd)) {
  2345. + if (setup_overlapped(&ol, fd, FALSE)) {
  2346. MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
  2347. return -1;
  2348. }
  2349. @@ -6550,7 +6554,7 @@ rb_w32_write(int fd, const void *buf, size_t size)
  2350. /* if have cancel_io, use Overlapped I/O */
  2351. if (cancel_io) {
  2352. - if (setup_overlapped(&ol, fd)) {
  2353. + if (setup_overlapped(&ol, fd, TRUE)) {
  2354. MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
  2355. return -1;
  2356. }