summaryrefslogtreecommitdiff
path: root/include/ruby/internal/intern
ModeNameSize
-rw-r--r--array.h25961logplain
-rw-r--r--bignum.h30764logplain
-rw-r--r--class.h16077logplain
-rw-r--r--compar.h2573logplain
-rw-r--r--complex.h8406logplain
-rw-r--r--cont.h11701logplain
-rw-r--r--dir.h1942logplain
-rw-r--r--enum.h2891logplain
-rw-r--r--enumerator.h12422logplain
-rw-r--r--error.h9994logplain
-rw-r--r--eval.h8696logplain
-rw-r--r--file.h9598logplain
-rw-r--r--hash.h11896logplain
-rw-r--r--io.h26896logplain
-rw-r--r--load.h10670logplain
-rw-r--r--marshal.h5578logplain
-rw-r--r--numeric.h7672logplain
-rw-r--r--object.h19538logplain
-rw-r--r--parse.h6326logplain
-rw-r--r--proc.h13860logplain
-rw-r--r--process.h11569logplain
-rw-r--r--random.h4400logplain
-rw-r--r--range.h4071logplain
-rw-r--r--rational.h6491logplain
-rw-r--r--re.h8728logplain
-rw-r--r--ruby.h2848logplain
-rw-r--r--select.h3946logplain
d---------select109logplain
-rw-r--r--signal.h6544logplain
-rw-r--r--sprintf.h6468logplain
-rw-r--r--string.h68979logplain
-rw-r--r--struct.h9418logplain
-rw-r--r--thread.h18460logplain
-rw-r--r--time.h6486logplain
-rw-r--r--variable.h21308logplain
-rw-r--r--vm.h16805logplain
r>-rwxr-xr-xbasictest/test.rb3
-rw-r--r--benchmark/README.md6
-rw-r--r--benchmark/array_sample.yml4
-rw-r--r--benchmark/array_sort_int.yml15
-rw-r--r--benchmark/attr_accessor.yml29
-rw-r--r--benchmark/buffer_each.yml27
-rw-r--r--benchmark/buffer_get.yml25
-rw-r--r--benchmark/cgi_escape_html.yml37
-rw-r--r--benchmark/constant_invalidation.rb22
-rw-r--r--benchmark/enum_minmax.yml25
-rw-r--r--benchmark/enum_sort.yml15
-rw-r--r--benchmark/enum_tally.yml4
-rw-r--r--benchmark/erb_escape_html.yml31
-rw-r--r--benchmark/float_methods.yml14
-rw-r--r--benchmark/float_neg_posi.yml8
-rw-r--r--benchmark/float_to_s.yml7
-rw-r--r--benchmark/hash_aref_array.rb5
-rw-r--r--benchmark/hash_first.yml11
-rw-r--r--benchmark/io_write.rb22
-rw-r--r--benchmark/iseq_load_from_binary.yml25
-rw-r--r--benchmark/ivar_extend.yml23
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit.rb2
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit_exec.rb237
-rw-r--r--benchmark/lib/benchmark_driver/runner/ractor.rb122
-rw-r--r--benchmark/marshal_dump_load_integer.yml22
-rw-r--r--benchmark/masgn.yml53
-rw-r--r--benchmark/method_bind_call.yml16
-rw-r--r--benchmark/mjit_exec_jt2jt.yml6
-rw-r--r--benchmark/mjit_exec_vm2jt.yml6
-rw-r--r--benchmark/mjit_exec_vm2vm.yml6
-rw-r--r--benchmark/mjit_integer.yml2
-rw-r--r--benchmark/module_eqq.yml27
-rw-r--r--benchmark/nilclass.yml6
-rw-r--r--benchmark/numeric_methods.yml29
-rw-r--r--benchmark/ractor_const.yml4
-rw-r--r--benchmark/ractor_float_to_s.yml8
-rw-r--r--benchmark/range_min.yml2
-rw-r--r--benchmark/so_nbody.rb58
-rw-r--r--benchmark/string_concat.yml45
-rw-r--r--benchmark/time_at.yml7
-rw-r--r--benchmark/time_new.yml4
-rw-r--r--benchmark/time_now.yml3
-rw-r--r--benchmark/time_parse.yml10
-rw-r--r--benchmark/vm_case_classes.yml9
-rw-r--r--benchmark/vm_const.yml6
-rw-r--r--benchmark/vm_cvar.yml20
-rw-r--r--benchmark/vm_dstr_ary.rb6
-rw-r--r--benchmark/vm_dstr_bool.rb7
-rw-r--r--benchmark/vm_dstr_class_module.rb10
-rw-r--r--benchmark/vm_dstr_digit.rb7
-rw-r--r--benchmark/vm_dstr_int.rb5
-rw-r--r--benchmark/vm_dstr_nil.rb6
-rw-r--r--benchmark/vm_dstr_obj.rb6
-rw-r--r--benchmark/vm_dstr_obj_def.rb8
-rw-r--r--benchmark/vm_dstr_str.rb6
-rw-r--r--benchmark/vm_dstr_sym.rb6
-rw-r--r--benchmark/vm_freezeobj.yml6
-rw-r--r--benchmark/vm_ivar_embedded_obj_init.yml14
-rw-r--r--benchmark/vm_ivar_extended_obj_init.yml16
-rw-r--r--benchmark/vm_ivar_generic_get.yml17
-rw-r--r--benchmark/vm_ivar_generic_set.yml14
-rw-r--r--benchmark/vm_ivar_get.yml37
-rw-r--r--benchmark/vm_ivar_get_unintialized.yml12
-rw-r--r--benchmark/vm_ivar_init.yml14
-rw-r--r--benchmark/vm_ivar_lazy_set.yml12
-rw-r--r--benchmark/vm_ivar_of_class.yml12
-rw-r--r--benchmark/vm_ivar_of_class_set.yml11
-rw-r--r--benchmark/vm_ivar_set_on_instance.yml35
-rw-r--r--benchmark/vm_ivar_set_subclass.yml9
-rw-r--r--benchmark/vm_lvar_cond_set.yml8
-rw-r--r--benchmark/vm_thread_condvar1.rb8
-rw-r--r--benchmark/vm_thread_condvar2.rb10
-rw-r--r--bignum.c1260
-rwxr-xr-xbin/bundle27
-rwxr-xr-xbin/bundler27
-rwxr-xr-xbin/erb27
-rwxr-xr-xbin/gem19
-rwxr-xr-xbin/irb27
-rwxr-xr-xbin/racc27
-rwxr-xr-xbin/rdoc27
-rwxr-xr-xbin/ri27
-rwxr-xr-xbootstraptest/runner.rb823
-rw-r--r--bootstraptest/test_attr.rb16
-rw-r--r--bootstraptest/test_autoload.rb30
-rw-r--r--bootstraptest/test_constant_cache.rb187
-rw-r--r--bootstraptest/test_eval.rb31
-rw-r--r--bootstraptest/test_fiber.rb4
-rw-r--r--bootstraptest/test_insns.rb3
-rw-r--r--bootstraptest/test_io.rb5
-rw-r--r--bootstraptest/test_jump.rb4
-rw-r--r--bootstraptest/test_literal.rb7
-rw-r--r--bootstraptest/test_method.rb2
-rw-r--r--bootstraptest/test_ractor.rb338
-rw-r--r--bootstraptest/test_syntax.rb2
-rw-r--r--bootstraptest/test_thread.rb8
-rw-r--r--bootstraptest/test_yjit.rb3530
-rw-r--r--bootstraptest/test_yjit_30k_ifelse.rb241023
-rw-r--r--bootstraptest/test_yjit_30k_methods.rb121018
-rw-r--r--bootstraptest/test_yjit_rust_port.rb422
-rw-r--r--builtin.c2
-rw-r--r--builtin.h82
-rw-r--r--ccan/build_assert/build_assert.h12
-rw-r--r--ccan/check_type/check_type.h28
-rw-r--r--ccan/container_of/container_of.h52
-rw-r--r--ccan/list/list.h589
-rw-r--r--ccan/str/str.h9
-rw-r--r--class.c1502
-rw-r--r--common.mk3689
-rw-r--r--compar.c51
-rw-r--r--compile.c10704
-rw-r--r--complex.c877
-rw-r--r--configure.ac1569
-rw-r--r--cont.c1299
-rw-r--r--coroutine/Stack.h16
-rw-r--r--coroutine/amd64/Context.S2
-rw-r--r--coroutine/amd64/Context.h31
-rw-r--r--coroutine/arm32/Context.h6
-rw-r--r--coroutine/arm64/Context.S11
-rw-r--r--coroutine/arm64/Context.h31
-rw-r--r--coroutine/asyncify/Context.c10
-rw-r--r--coroutine/asyncify/Context.h93
-rw-r--r--coroutine/copy/Context.c162
-rw-r--r--coroutine/copy/Context.h90
-rw-r--r--coroutine/emscripten/Context.c8
-rw-r--r--coroutine/emscripten/Context.h77
-rw-r--r--coroutine/ppc/Context.S90
-rw-r--r--coroutine/ppc/Context.h58
-rw-r--r--coroutine/ppc64/Context.S89
-rw-r--r--coroutine/ppc64/Context.h57
-rw-r--r--coroutine/ppc64le/Context.h6
-rw-r--r--coroutine/pthread/Context.c272
-rw-r--r--coroutine/pthread/Context.h63
-rw-r--r--coroutine/riscv64/Context.S87
-rw-r--r--coroutine/riscv64/Context.h46
-rw-r--r--coroutine/ucontext/Context.c1
-rw-r--r--coroutine/ucontext/Context.h9
-rw-r--r--coroutine/universal/Context.S16
-rw-r--r--coroutine/universal/Context.h21
-rw-r--r--coroutine/win32/Context.h6
-rw-r--r--coroutine/win64/Context.h6
-rw-r--r--coroutine/x86/Context.S2
-rw-r--r--coroutine/x86/Context.h6
-rw-r--r--coverage/README2
-rw-r--r--cygwin/GNUmakefile.in47
-rw-r--r--darray.h179
-rw-r--r--debug.c378
-rw-r--r--debug_counter.c36
-rw-r--r--debug_counter.h61
-rw-r--r--defs/gmake.mk238
-rw-r--r--defs/id.def35
-rw-r--r--defs/keywords2
-rw-r--r--defs/lex.c.src2
-rw-r--r--dir.c1905
-rw-r--r--dir.rb188
-rw-r--r--dln.c1423
-rw-r--r--dln.h5
-rw-r--r--dln_find.c250
-rw-r--r--dmyenc.c2
-rw-r--r--doc/.document7
-rw-r--r--doc/ChangeLog-0.60_to_1.110
-rw-r--r--doc/ChangeLog-1.9.330
-rw-r--r--doc/ChangeLog-2.0.08
-rw-r--r--doc/ChangeLog-2.3.015
-rw-r--r--doc/ChangeLog-2.4.04
-rw-r--r--doc/ChangeLog-YARV48
-rw-r--r--doc/NEWS-2.0.0529
-rw-r--r--doc/NEWS-2.1.0376
-rw-r--r--doc/NEWS-2.2.0359
-rw-r--r--doc/NEWS-2.5.0565
-rw-r--r--doc/NEWS-2.7.0826
-rw-r--r--doc/NEWS-3.0.0.md820
-rw-r--r--doc/NEWS/NEWS-1.8.7 (renamed from doc/NEWS-1.8.7)0
-rw-r--r--doc/NEWS/NEWS-1.9.1 (renamed from doc/NEWS-1.9.1)0
-rw-r--r--doc/NEWS/NEWS-1.9.2 (renamed from doc/NEWS-1.9.2)0
-rw-r--r--doc/NEWS/NEWS-1.9.3 (renamed from doc/NEWS-1.9.3)0
-rw-r--r--doc/NEWS/NEWS-2.0.0529
-rw-r--r--doc/NEWS/NEWS-2.1.0376
-rw-r--r--doc/NEWS/NEWS-2.2.0359
-rw-r--r--doc/NEWS/NEWS-2.3.0 (renamed from doc/NEWS-2.3.0)0
-rw-r--r--doc/NEWS/NEWS-2.4.0 (renamed from doc/NEWS-2.4.0)0
-rw-r--r--doc/NEWS/NEWS-2.5.0565
-rw-r--r--doc/NEWS/NEWS-2.6.0 (renamed from doc/NEWS-2.6.0)0
-rw-r--r--doc/NEWS/NEWS-2.7.0845
-rw-r--r--doc/NEWS/NEWS-3.0.0.md829
-rw-r--r--doc/NEWS/NEWS-3.1.0.md660
-rw-r--r--doc/bsearch.rdoc120
-rw-r--r--doc/case_mapping.rdoc116
-rw-r--r--doc/character_selectors.rdoc97
-rw-r--r--doc/command_injection.rdoc29
-rw-r--r--doc/contributing.md12
-rw-r--r--doc/contributing.rdoc428
-rw-r--r--doc/contributing/building_ruby.md172
-rw-r--r--doc/contributing/documentation_guide.md435
-rw-r--r--doc/contributing/making_changes_to_ruby.md28
-rw-r--r--doc/contributing/making_changes_to_stdlibs.md49
-rw-r--r--doc/contributing/reporting_issues.md91
-rw-r--r--doc/contributing/testing_ruby.md138
-rw-r--r--doc/date/calendars.rdoc62
-rw-r--r--doc/encodings.rdoc479
-rw-r--r--doc/examples/files.rdoc26
-rw-r--r--doc/extension.ja.rdoc68
-rw-r--r--doc/extension.rdoc149
-rw-r--r--doc/fiber.md45
-rw-r--r--doc/format_specifications.rdoc348
-rw-r--r--doc/implicit_conversion.rdoc23
-rw-r--r--doc/irb/irb.rd.ja17
-rw-r--r--doc/maintainers.rdoc81
-rw-r--r--doc/make_cheatsheet.md124
-rw-r--r--doc/marshal.rdoc2
-rw-r--r--doc/matchdata/begin.rdoc30
-rw-r--r--doc/matchdata/end.rdoc30
-rw-r--r--doc/matchdata/offset.rdoc31
-rw-r--r--doc/math/math.rdoc117
-rw-r--r--doc/memory_view.md6
-rw-r--r--doc/method_documentation.rdoc183
-rw-r--r--doc/mjit/mjit.md39
-rw-r--r--doc/net-http/examples.rdoc31
-rw-r--r--doc/net-http/included_getters.rdoc3
-rw-r--r--doc/optparse/.document1
-rw-r--r--doc/optparse/argument_converters.rdoc380
-rw-r--r--doc/optparse/creates_option.rdoc7
-rw-r--r--doc/optparse/option_params.rdoc509
-rw-r--r--doc/optparse/ruby/argument_keywords.rb6
-rw-r--r--doc/optparse/ruby/argument_strings.rb6
-rw-r--r--doc/optparse/ruby/argv.rb2
-rw-r--r--doc/optparse/ruby/array.rb6
-rw-r--r--doc/optparse/ruby/basic.rb17
-rw-r--r--doc/optparse/ruby/block.rb9
-rw-r--r--doc/optparse/ruby/collected_options.rb8
-rw-r--r--doc/optparse/ruby/custom_converter.rb9
-rw-r--r--doc/optparse/ruby/date.rb6
-rw-r--r--doc/optparse/ruby/datetime.rb6
-rw-r--r--doc/optparse/ruby/decimal_integer.rb7
-rw-r--r--doc/optparse/ruby/decimal_numeric.rb7
-rw-r--r--doc/optparse/ruby/default_values.rb8
-rw-r--r--doc/optparse/ruby/descriptions.rb15
-rw-r--r--doc/optparse/ruby/explicit_array_values.rb9
-rw-r--r--doc/optparse/ruby/explicit_hash_values.rb9
-rw-r--r--doc/optparse/ruby/false_class.rb6
-rw-r--r--doc/optparse/ruby/float.rb6
-rw-r--r--doc/optparse/ruby/help.rb18
-rw-r--r--doc/optparse/ruby/help_banner.rb7
-rw-r--r--doc/optparse/ruby/help_format.rb25
-rw-r--r--doc/optparse/ruby/help_program_name.rb7
-rw-r--r--doc/optparse/ruby/integer.rb6
-rw-r--r--doc/optparse/ruby/long_names.rb9
-rw-r--r--doc/optparse/ruby/long_optional.rb6
-rw-r--r--doc/optparse/ruby/long_required.rb6
-rw-r--r--doc/optparse/ruby/long_simple.rb9
-rw-r--r--doc/optparse/ruby/long_with_negation.rb6
-rw-r--r--doc/optparse/ruby/match_converter.rb9
-rw-r--r--doc/optparse/ruby/matched_values.rb6
-rw-r--r--doc/optparse/ruby/method.rb11
-rw-r--r--doc/optparse/ruby/missing_options.rb12
-rw-r--r--doc/optparse/ruby/mixed_names.rb12
-rw-r--r--doc/optparse/ruby/name_abbrev.rb9
-rw-r--r--doc/optparse/ruby/no_abbreviation.rb10
-rw-r--r--doc/optparse/ruby/numeric.rb6
-rw-r--r--doc/optparse/ruby/object.rb6
-rw-r--r--doc/optparse/ruby/octal_integer.rb7
-rw-r--r--doc/optparse/ruby/optional_argument.rb9
-rw-r--r--doc/optparse/ruby/parse.rb13
-rw-r--r--doc/optparse/ruby/parse_bang.rb13
-rw-r--r--doc/optparse/ruby/proc.rb13
-rw-r--r--doc/optparse/ruby/regexp.rb6
-rw-r--r--doc/optparse/ruby/required_argument.rb9
-rw-r--r--doc/optparse/ruby/shellwords.rb6
-rw-r--r--doc/optparse/ruby/short_names.rb9
-rw-r--r--doc/optparse/ruby/short_optional.rb6
-rw-r--r--doc/optparse/ruby/short_range.rb6
-rw-r--r--doc/optparse/ruby/short_required.rb6
-rw-r--r--doc/optparse/ruby/short_simple.rb9
-rw-r--r--doc/optparse/ruby/string.rb6
-rw-r--r--doc/optparse/ruby/terminator.rb6
-rw-r--r--doc/optparse/ruby/time.rb6
-rw-r--r--doc/optparse/ruby/true_class.rb6
-rw-r--r--doc/optparse/ruby/uri.rb6
-rw-r--r--doc/optparse/tutorial.rdoc835
-rw-r--r--doc/packed_data.rdoc590
-rw-r--r--doc/ractor.md107
-rw-r--r--doc/rdoc/markup_reference.rb1257
-rw-r--r--doc/regexp.rdoc97
-rw-r--r--doc/standard_library.rdoc20
-rw-r--r--doc/strftime_formatting.rdoc527
-rw-r--r--doc/string/b.rdoc14
-rw-r--r--doc/string/bytes.rdoc6
-rw-r--r--doc/string/bytesize.rdoc11
-rw-r--r--doc/string/center.rdoc16
-rw-r--r--doc/string/chars.rdoc5
-rw-r--r--doc/string/chomp.rdoc29
-rw-r--r--doc/string/chop.rdoc16
-rw-r--r--doc/string/codepoints.rdoc6
-rw-r--r--doc/string/delete_prefix.rdoc8
-rw-r--r--doc/string/delete_suffix.rdoc8
-rw-r--r--doc/string/each_byte.rdoc17
-rw-r--r--doc/string/each_char.rdoc17
-rw-r--r--doc/string/each_codepoint.rdoc18
-rw-r--r--doc/string/each_grapheme_cluster.rdoc12
-rw-r--r--doc/string/each_line.rdoc60
-rw-r--r--doc/string/end_with_p.rdoc11
-rw-r--r--doc/string/force_encoding.rdoc20
-rw-r--r--doc/string/grapheme_clusters.rdoc6
-rw-r--r--doc/string/index.rdoc38
-rw-r--r--doc/string/length.rdoc13
-rw-r--r--doc/string/ljust.rdoc16
-rw-r--r--doc/string/new.rdoc51
-rw-r--r--doc/string/ord.rdoc6
-rw-r--r--doc/string/partition.rdoc24
-rw-r--r--doc/string/rjust.rdoc16
-rw-r--r--doc/string/rpartition.rdoc24
-rw-r--r--doc/string/scrub.rdoc25
-rw-r--r--doc/string/split.rdoc86
-rw-r--r--doc/string/start_with_p.rdoc18
-rw-r--r--doc/string/sum.rdoc11
-rw-r--r--doc/symbol/casecmp.rdoc27
-rw-r--r--doc/symbol/casecmp_p.rdoc26
-rw-r--r--doc/syntax/assignment.rdoc6
-rw-r--r--doc/syntax/calling_methods.rdoc18
-rw-r--r--doc/syntax/comments.rdoc8
-rw-r--r--doc/syntax/control_expressions.rdoc26
-rw-r--r--doc/syntax/literals.rdoc283
-rw-r--r--doc/syntax/methods.rdoc111
-rw-r--r--doc/syntax/modules_and_classes.rdoc4
-rw-r--r--doc/syntax/pattern_matching.rdoc43
-rw-r--r--doc/syntax/precedence.rdoc2
-rw-r--r--doc/timezones.rdoc108
-rw-r--r--doc/transcode.rdoc52
-rw-r--r--doc/yjit/yjit.md417
-rw-r--r--doc/yjit/yjit_hacking.md75
-rw-r--r--enc/Makefile.in4
-rw-r--r--enc/ascii.c6
-rw-r--r--enc/cesu_8.c23
-rw-r--r--enc/depend5984
-rw-r--r--enc/encdb.c2
-rw-r--r--enc/encinit.c.erb1
-rw-r--r--enc/jis/props.h.blt4
-rw-r--r--enc/jis/props.kwd2
-rw-r--r--enc/jis/props.src2
-rwxr-xr-xenc/make_encmake.rb2
-rw-r--r--enc/trans/newline.trans20
-rw-r--r--enc/trans/transdb.c2
-rw-r--r--enc/unicode/12.1.0/casefold.h7428
-rw-r--r--enc/unicode/12.1.0/name2ctype.h41810
-rw-r--r--enc/unicode/15.0.0/casefold.h7629
-rw-r--r--enc/unicode/15.0.0/name2ctype.h45690
-rw-r--r--enc/unicode/case-folding.rb418
-rw-r--r--enc/utf_16_32.h2
-rw-r--r--encindex.h6
-rw-r--r--encoding.c812
-rw-r--r--enum.c2880
-rw-r--r--enumerator.c1088
-rw-r--r--error.c1230
-rw-r--r--eval.c1263
-rw-r--r--eval_error.c565
-rw-r--r--eval_intern.h92
-rw-r--r--eval_jump.c40
-rw-r--r--ext/-test-/RUBY_ALIGNOF/depend3
-rw-r--r--ext/-test-/abi/abi.c11
-rw-r--r--ext/-test-/abi/extconf.rb4
-rw-r--r--ext/-test-/arith_seq/beg_len_step/beg_len_step.c19
-rw-r--r--ext/-test-/arith_seq/beg_len_step/depend161
-rw-r--r--ext/-test-/arith_seq/beg_len_step/extconf.rb2
-rw-r--r--ext/-test-/arith_seq/extract/depend27
-rw-r--r--ext/-test-/array/concat/depend162
-rw-r--r--ext/-test-/array/concat/extconf.rb2
-rw-r--r--ext/-test-/array/concat/to_ary_concat.c38
-rw-r--r--ext/-test-/array/resize/depend27
-rw-r--r--ext/-test-/array/resize/resize.c6
-rw-r--r--ext/-test-/auto_ext.rb1
-rw-r--r--ext/-test-/bignum/big2str.c12
-rw-r--r--ext/-test-/bignum/depend201
-rw-r--r--ext/-test-/bignum/div.c8
-rw-r--r--ext/-test-/bignum/intpack.c40
-rw-r--r--ext/-test-/bignum/mul.c28
-rw-r--r--ext/-test-/bignum/str2big.c16
-rw-r--r--ext/-test-/bug-14834/depend29
-rw-r--r--ext/-test-/bug-3571/depend27
-rw-r--r--ext/-test-/bug-5832/depend27
-rw-r--r--ext/-test-/bug_reporter/depend27
-rw-r--r--ext/-test-/class/depend54
-rw-r--r--ext/-test-/cxxanyargs/depend12
-rw-r--r--ext/-test-/cxxanyargs/extconf.rb4
-rw-r--r--ext/-test-/debug/depend85
-rw-r--r--ext/-test-/debug/inspector.c14
-rw-r--r--ext/-test-/debug/profile_frames.c27
-rw-r--r--ext/-test-/dln/empty/depend159
-rw-r--r--ext/-test-/dln/empty/empty.c2
-rw-r--r--ext/-test-/econv/append.c15
-rw-r--r--ext/-test-/econv/extconf.rb3
-rw-r--r--ext/-test-/econv/init.c11
-rw-r--r--ext/-test-/enumerator_kw/depend27
-rw-r--r--ext/-test-/enumerator_kw/enumerator_kw.c3
-rw-r--r--ext/-test-/eval/eval.c13
-rw-r--r--ext/-test-/eval/extconf.rb2
-rw-r--r--ext/-test-/exception/depend119
-rw-r--r--ext/-test-/fatal/depend27
-rw-r--r--ext/-test-/fatal/rb_fatal.c3
-rw-r--r--ext/-test-/file/depend103
-rw-r--r--ext/-test-/file/fs.c16
-rw-r--r--ext/-test-/float/depend54
-rw-r--r--ext/-test-/funcall/depend27
-rw-r--r--ext/-test-/funcall/funcall.c12
-rw-r--r--ext/-test-/gvl/call_without_gvl/call_without_gvl.c12
-rw-r--r--ext/-test-/gvl/call_without_gvl/depend27
-rw-r--r--ext/-test-/hash/depend54
-rw-r--r--ext/-test-/integer/core_ext.c16
-rw-r--r--ext/-test-/integer/depend84
-rw-r--r--ext/-test-/iseq_load/depend27
-rw-r--r--ext/-test-/iter/depend81
-rw-r--r--ext/-test-/load/dot.dot/depend159
-rw-r--r--ext/-test-/load/dot.dot/dot.dot.c2
-rw-r--r--ext/-test-/load/protect/depend27
-rw-r--r--ext/-test-/marshal/compat/depend27
-rw-r--r--ext/-test-/marshal/internal_ivar/depend27
-rw-r--r--ext/-test-/marshal/internal_ivar/internal_ivar.c5
-rw-r--r--ext/-test-/marshal/usr/depend27
-rw-r--r--ext/-test-/memory_status/depend3
-rw-r--r--ext/-test-/memory_status/memory_status.c31
-rw-r--r--ext/-test-/memory_view/depend3
-rw-r--r--ext/-test-/memory_view/extconf.rb2
-rw-r--r--ext/-test-/memory_view/memory_view.c7
-rw-r--r--ext/-test-/method/depend54
-rw-r--r--ext/-test-/notimplement/depend27
-rw-r--r--ext/-test-/num2int/depend27
-rw-r--r--ext/-test-/num2int/num2int.c26
-rw-r--r--ext/-test-/path_to_class/depend27
-rw-r--r--ext/-test-/popen_deadlock/depend28
-rw-r--r--ext/-test-/postponed_job/depend29
-rw-r--r--ext/-test-/postponed_job/postponed_job.c31
-rw-r--r--ext/-test-/printf/depend38
-rw-r--r--ext/-test-/printf/printf.c64
-rw-r--r--ext/-test-/proc/depend81
-rw-r--r--ext/-test-/proc/super.c2
-rw-r--r--ext/-test-/random/bad_version.c135
-rw-r--r--ext/-test-/random/depend170
-rw-r--r--ext/-test-/random/loop.c1
-rw-r--r--ext/-test-/rational/depend31
-rw-r--r--ext/-test-/rational/rat.c15
-rw-r--r--ext/-test-/rb_call_super_kw/depend27
-rw-r--r--ext/-test-/rb_call_super_kw/rb_call_super_kw.c3
-rw-r--r--ext/-test-/recursion/depend27
-rw-r--r--ext/-test-/regexp/depend54
-rw-r--r--ext/-test-/scan_args/depend27
-rw-r--r--ext/-test-/st/foreach/depend27
-rw-r--r--ext/-test-/st/foreach/foreach.c100
-rw-r--r--ext/-test-/st/numhash/depend27
-rw-r--r--ext/-test-/st/numhash/numhash.c16
-rw-r--r--ext/-test-/st/update/depend27
-rw-r--r--ext/-test-/st/update/update.c12
-rw-r--r--ext/-test-/string/capacity.c9
-rw-r--r--ext/-test-/string/coderange.c8
-rw-r--r--ext/-test-/string/cstr.c26
-rw-r--r--ext/-test-/string/depend135
-rw-r--r--ext/-test-/string/enc_str_buf_cat.c14
-rw-r--r--ext/-test-/string/fstring.c15
-rw-r--r--ext/-test-/string/qsort.c14
-rw-r--r--ext/-test-/string/set_len.c10
-rw-r--r--ext/-test-/struct/depend108
-rw-r--r--ext/-test-/struct/member.c2
-rw-r--r--ext/-test-/symbol/depend54
-rw-r--r--ext/-test-/symbol/type.c6
-rw-r--r--ext/-test-/thread/instrumentation/depend164
-rw-r--r--ext/-test-/thread/instrumentation/extconf.rb2
-rw-r--r--ext/-test-/thread/instrumentation/instrumentation.c141
-rw-r--r--ext/-test-/thread_fd/depend161
-rw-r--r--ext/-test-/thread_fd/extconf.rb2
-rw-r--r--ext/-test-/thread_fd/thread_fd.c30
-rw-r--r--ext/-test-/thread_fd_close/depend162
-rw-r--r--ext/-test-/thread_fd_close/extconf.rb2
-rw-r--r--ext/-test-/thread_fd_close/thread_fd_close.c14
-rw-r--r--ext/-test-/time/depend82
-rw-r--r--ext/-test-/time/leap_second.c1
-rw-r--r--ext/-test-/tracepoint/depend58
-rw-r--r--ext/-test-/tracepoint/gc_hook.c26
-rw-r--r--ext/-test-/tracepoint/tracepoint.c54
-rw-r--r--ext/-test-/typeddata/depend27
-rw-r--r--ext/-test-/typeddata/typeddata.c2
-rw-r--r--ext/-test-/vm/at_exit.c12
-rw-r--r--ext/-test-/vm/depend27
-rw-r--r--ext/-test-/wait/depend174
-rw-r--r--ext/-test-/wait/extconf.rb2
-rw-r--r--ext/-test-/wait/wait.c39
-rw-r--r--ext/-test-/wait_for_single_fd/depend166
-rw-r--r--ext/-test-/wait_for_single_fd/extconf.rb8
-rw-r--r--ext/-test-/wait_for_single_fd/wait_for_single_fd.c94
-rw-r--r--ext/-test-/win32/console/attribute.c26
-rw-r--r--ext/-test-/win32/fd_setsize/fd_setsize.c10
-rw-r--r--ext/bigdecimal/bigdecimal.c3095
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec16
-rw-r--r--ext/bigdecimal/bigdecimal.h293
-rw-r--r--ext/bigdecimal/bits.h24
-rw-r--r--ext/bigdecimal/depend190
-rw-r--r--ext/bigdecimal/extconf.rb23
-rw-r--r--ext/bigdecimal/lib/bigdecimal/jacobian.rb6
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb8
-rw-r--r--ext/bigdecimal/missing.c27
-rw-r--r--ext/bigdecimal/missing.h196
-rw-r--r--ext/bigdecimal/missing/dtoa.c3462
-rw-r--r--ext/cgi/escape/depend38
-rw-r--r--ext/cgi/escape/escape.c365
-rw-r--r--ext/continuation/depend27
-rw-r--r--ext/coverage/coverage.c307
-rw-r--r--ext/coverage/depend7
-rw-r--r--ext/date/date.gemspec31
-rw-r--r--ext/date/date_core.c2218
-rw-r--r--ext/date/date_parse.c131
-rw-r--r--ext/date/date_strftime.c2
-rw-r--r--ext/date/date_strptime.c105
-rw-r--r--ext/date/depend141
-rw-r--r--ext/date/extconf.rb7
-rw-r--r--ext/date/lib/date.rb7
-rw-r--r--ext/date/prereq.mk7
-rw-r--r--ext/date/zonetab.h18
-rw-r--r--ext/date/zonetab.list2
-rw-r--r--ext/dbm/dbm.c1156
-rw-r--r--ext/dbm/dbm.gemspec21
-rw-r--r--ext/dbm/depend163
-rw-r--r--ext/dbm/extconf.rb292
-rw-r--r--ext/digest/bubblebabble/bubblebabble.c2
-rw-r--r--ext/digest/bubblebabble/depend27
-rw-r--r--ext/digest/bubblebabble/extconf.rb2
-rw-r--r--ext/digest/depend27
-rw-r--r--ext/digest/digest.c12
-rw-r--r--ext/digest/digest.gemspec53
-rw-r--r--ext/digest/digest.h2
-rw-r--r--ext/digest/digest_conf.rb2
-rw-r--r--ext/digest/extconf.rb2
-rw-r--r--ext/digest/lib/digest.rb18
-rw-r--r--ext/digest/lib/digest/loader.rb3
-rw-r--r--ext/digest/lib/digest/version.rb5
-rw-r--r--ext/digest/md5/depend7
-rw-r--r--ext/digest/md5/extconf.rb2
-rw-r--r--ext/digest/md5/md5.c2
-rw-r--r--ext/digest/rmd160/depend6
-rw-r--r--ext/digest/rmd160/extconf.rb4
-rw-r--r--ext/digest/sha1/depend7
-rw-r--r--ext/digest/sha1/extconf.rb2
-rw-r--r--ext/digest/sha2/depend7
-rw-r--r--ext/digest/sha2/extconf.rb2
-rw-r--r--ext/digest/sha2/lib/sha2.rb2
-rw-r--r--ext/digest/sha2/lib/sha2/loader.rb3
-rw-r--r--ext/digest/sha2/sha2.c16
-rw-r--r--ext/digest/sha2/sha2init.c2
-rw-r--r--ext/erb/escape/escape.c95
-rw-r--r--ext/erb/escape/extconf.rb7
-rw-r--r--ext/etc/depend12
-rw-r--r--ext/etc/etc.c150
-rw-r--r--ext/etc/etc.gemspec13
-rw-r--r--ext/etc/extconf.rb6
-rwxr-xr-xext/extmk.rb137
-rw-r--r--ext/fcntl/depend27
-rw-r--r--ext/fcntl/fcntl.c17
-rw-r--r--ext/fcntl/fcntl.gemspec2
-rw-r--r--ext/fiber/depend3
-rw-r--r--ext/fiber/extconf.rb4
-rw-r--r--ext/fiber/fiber.c8
-rw-r--r--ext/fiddle/closure.c159
-rw-r--r--ext/fiddle/conversions.c20
-rw-r--r--ext/fiddle/conversions.h1
-rw-r--r--ext/fiddle/depend45
-rw-r--r--ext/fiddle/extconf.rb82
-rw-r--r--ext/fiddle/extlibs13
-rw-r--r--ext/fiddle/fiddle.c218
-rw-r--r--ext/fiddle/fiddle.gemspec9
-rw-r--r--ext/fiddle/fiddle.h32
-rw-r--r--ext/fiddle/function.c12
-rw-r--r--ext/fiddle/handle.c119
-rw-r--r--ext/fiddle/lib/fiddle.rb47
-rw-r--r--ext/fiddle/lib/fiddle/closure.rb25
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb24
-rw-r--r--ext/fiddle/lib/fiddle/function.rb6
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb35
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb71
-rw-r--r--ext/fiddle/lib/fiddle/types.rb35
-rw-r--r--ext/fiddle/lib/fiddle/version.rb2
-rw-r--r--ext/fiddle/memory_view.c89
-rw-r--r--ext/fiddle/pointer.c27
-rw-r--r--ext/gdbm/README1
-rw-r--r--ext/gdbm/depend163
-rw-r--r--ext/gdbm/extconf.rb19
-rw-r--r--ext/gdbm/gdbm.c1306
-rw-r--r--ext/gdbm/gdbm.gemspec21
-rw-r--r--ext/io/console/console.c70
-rw-r--r--ext/io/console/depend41
-rw-r--r--ext/io/console/extconf.rb6
-rw-r--r--ext/io/console/io-console.gemspec20
-rw-r--r--ext/io/console/win32_vk.inc327
-rw-r--r--ext/io/console/win32_vk.list2
-rw-r--r--ext/io/nonblock/depend38
-rw-r--r--ext/io/nonblock/io-nonblock.gemspec16
-rw-r--r--ext/io/nonblock/nonblock.c67
-rw-r--r--ext/io/wait/depend39
-rw-r--r--ext/io/wait/extconf.rb31
-rw-r--r--ext/io/wait/io-wait.gemspec27
-rw-r--r--ext/io/wait/wait.c290
-rw-r--r--ext/json/VERSION2
-rw-r--r--ext/json/generator/depend38
-rw-r--r--ext/json/generator/generator.c16
-rw-r--r--ext/json/json.gemspec10
-rw-r--r--ext/json/lib/json.rb2
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/depend38
-rw-r--r--ext/json/parser/extconf.rb3
-rw-r--r--ext/json/parser/parser.c4794
-rw-r--r--ext/json/parser/parser.h6
-rw-r--r--ext/json/parser/parser.rl117
-rw-r--r--ext/json/parser/prereq.mk5
-rw-r--r--ext/monitor/depend27
-rw-r--r--ext/monitor/monitor.c18
-rw-r--r--ext/nkf/depend38
-rw-r--r--ext/nkf/nkf-utf8/config.h2
-rw-r--r--ext/nkf/nkf-utf8/nkf.c24
-rw-r--r--ext/nkf/nkf-utf8/nkf.h4
-rw-r--r--ext/nkf/nkf.c92
-rw-r--r--ext/nkf/nkf.gemspec2
-rw-r--r--ext/objspace/depend57
-rw-r--r--ext/objspace/lib/objspace.rb97
-rw-r--r--ext/objspace/lib/objspace/trace.rb45
-rw-r--r--ext/objspace/object_tracing.c170
-rw-r--r--ext/objspace/objspace.c421
-rw-r--r--ext/objspace/objspace_dump.c322
-rw-r--r--ext/openssl/History.md260
-rw-r--r--ext/openssl/depend417
-rw-r--r--ext/openssl/extconf.rb157
-rw-r--r--ext/openssl/lib/openssl.rb1
-rw-r--r--ext/openssl/lib/openssl/buffering.rb9
-rw-r--r--ext/openssl/lib/openssl/config.rb501
-rw-r--r--ext/openssl/lib/openssl/hmac.rb65
-rw-r--r--ext/openssl/lib/openssl/pkey.rb429
-rw-r--r--ext/openssl/lib/openssl/ssl.rb19
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/lib/openssl/x509.rb22
-rw-r--r--ext/openssl/openssl.gemspec9
-rw-r--r--ext/openssl/openssl_missing.c66
-rw-r--r--ext/openssl/openssl_missing.h71
-rw-r--r--ext/openssl/ossl.c105
-rw-r--r--ext/openssl/ossl.h32
-rw-r--r--ext/openssl/ossl_asn1.c39
-rw-r--r--ext/openssl/ossl_bn.c354
-rw-r--r--ext/openssl/ossl_cipher.c51
-rw-r--r--ext/openssl/ossl_config.c453
-rw-r--r--ext/openssl/ossl_config.h11
-rw-r--r--ext/openssl/ossl_digest.c26
-rw-r--r--ext/openssl/ossl_engine.c31
-rw-r--r--ext/openssl/ossl_hmac.c191
-rw-r--r--ext/openssl/ossl_kdf.c14
-rw-r--r--ext/openssl/ossl_ocsp.c58
-rw-r--r--ext/openssl/ossl_pkcs12.c24
-rw-r--r--ext/openssl/ossl_pkcs7.c101
-rw-r--r--ext/openssl/ossl_pkey.c1333
-rw-r--r--ext/openssl/ossl_pkey.h109
-rw-r--r--ext/openssl/ossl_pkey_dh.c470
-rw-r--r--ext/openssl/ossl_pkey_dsa.c505
-rw-r--r--ext/openssl/ossl_pkey_ec.c500
-rw-r--r--ext/openssl/ossl_pkey_rsa.c599
-rw-r--r--ext/openssl/ossl_ssl.c888
-rw-r--r--ext/openssl/ossl_ssl_session.c57
-rw-r--r--ext/openssl/ossl_ts.c93
-rw-r--r--ext/openssl/ossl_x509.c6
-rw-r--r--ext/openssl/ossl_x509cert.c178
-rw-r--r--ext/openssl/ossl_x509crl.c23
-rw-r--r--ext/openssl/ossl_x509ext.c3
-rw-r--r--ext/openssl/ossl_x509name.c11
-rw-r--r--ext/openssl/ossl_x509req.c23
-rw-r--r--ext/openssl/ossl_x509revoked.c6
-rw-r--r--ext/openssl/ossl_x509store.c283
-rw-r--r--ext/openssl/ruby_missing.h24
-rw-r--r--ext/pathname/depend38
-rw-r--r--ext/pathname/lib/pathname.rb17
-rw-r--r--ext/pathname/pathname.c26
-rw-r--r--ext/pathname/pathname.gemspec6
-rw-r--r--ext/psych/.gitignore1
-rw-r--r--ext/psych/depend204
-rw-r--r--ext/psych/extconf.rb70
-rw-r--r--ext/psych/lib/psych.rb246
-rw-r--r--ext/psych/lib/psych/class_loader.rb8
-rw-r--r--ext/psych/lib/psych/core_ext.rb2
-rw-r--r--ext/psych/lib/psych/exception.rb18
-rw-r--r--ext/psych/lib/psych/handler.rb2
-rw-r--r--ext/psych/lib/psych/handlers/document_stream.rb2
-rw-r--r--ext/psych/lib/psych/handlers/recorder.rb2
-rw-r--r--ext/psych/lib/psych/json/stream.rb4
-rw-r--r--ext/psych/lib/psych/json/tree_builder.rb2
-rw-r--r--ext/psych/lib/psych/nodes.rb14
-rw-r--r--ext/psych/lib/psych/nodes/node.rb8
-rw-r--r--ext/psych/lib/psych/nodes/scalar.rb2
-rw-r--r--ext/psych/lib/psych/parser.rb13
-rw-r--r--ext/psych/lib/psych/scalar_scanner.rb38
-rw-r--r--ext/psych/lib/psych/syntax_error.rb2
-rw-r--r--ext/psych/lib/psych/tree_builder.rb2
-rw-r--r--ext/psych/lib/psych/versions.rb6
-rw-r--r--ext/psych/lib/psych/visitors.rb12
-rw-r--r--ext/psych/lib/psych/visitors/json_tree.rb2
-rw-r--r--ext/psych/lib/psych/visitors/to_ruby.rb34
-rw-r--r--ext/psych/lib/psych/visitors/visitor.rb2
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb74
-rw-r--r--ext/psych/psych.gemspec5
-rw-r--r--ext/psych/psych_parser.c52
-rw-r--r--ext/psych/yaml/api.c1393
-rw-r--r--ext/psych/yaml/config.h80
-rw-r--r--ext/psych/yaml/dumper.c394
-rw-r--r--ext/psych/yaml/emitter.c2358
-rw-r--r--ext/psych/yaml/loader.c544
-rw-r--r--ext/psych/yaml/parser.c1375
-rw-r--r--ext/psych/yaml/reader.c469
-rw-r--r--ext/psych/yaml/scanner.c3598
-rw-r--r--ext/psych/yaml/writer.c141
-rw-r--r--ext/psych/yaml/yaml.h1985
-rw-r--r--ext/psych/yaml/yaml_private.h688
-rw-r--r--ext/pty/depend41
-rw-r--r--ext/pty/extconf.rb6
-rw-r--r--ext/pty/lib/expect.rb16
-rw-r--r--ext/pty/pty.c178
-rw-r--r--ext/racc/cparse/cparse.c6
-rw-r--r--ext/racc/cparse/depend27
-rw-r--r--ext/racc/cparse/extconf.rb1
-rw-r--r--ext/rbconfig/sizeof/depend54
-rw-r--r--ext/readline/depend12
-rw-r--r--ext/readline/readline-ext.gemspec6
-rw-r--r--ext/readline/readline.c9
-rw-r--r--ext/ripper/depend21
-rw-r--r--ext/ripper/eventids2.c19
-rw-r--r--ext/ripper/extconf.rb3
-rw-r--r--ext/ripper/lib/ripper/lexer.rb96
-rw-r--r--ext/ripper/tools/preproc.rb2
-rw-r--r--ext/socket/addrinfo.h36
-rw-r--r--ext/socket/ancdata.c274
-rw-r--r--ext/socket/basicsocket.c151
-rw-r--r--ext/socket/constants.c6
-rw-r--r--ext/socket/depend630
-rw-r--r--ext/socket/extconf.rb30
-rw-r--r--ext/socket/getaddrinfo.c898
-rw-r--r--ext/socket/getnameinfo.c226
-rw-r--r--ext/socket/ifaddr.c9
-rw-r--r--ext/socket/init.c270
-rw-r--r--ext/socket/ipsocket.c196
-rw-r--r--ext/socket/lib/socket.rb9
-rw-r--r--ext/socket/mkconstants.rb40
-rw-r--r--ext/socket/option.c98
-rw-r--r--ext/socket/raddrinfo.c403
-rw-r--r--ext/socket/rubysocket.h51
-rw-r--r--ext/socket/socket.c524
-rw-r--r--ext/socket/sockssocket.c4
-rw-r--r--ext/socket/tcpserver.c24
-rw-r--r--ext/socket/tcpsocket.c18
-rw-r--r--ext/socket/udpsocket.c55
-rw-r--r--ext/socket/unixserver.c31
-rw-r--r--ext/socket/unixsocket.c148
-rw-r--r--ext/stringio/depend38
-rw-r--r--ext/stringio/stringio.c402
-rw-r--r--ext/stringio/stringio.gemspec20
-rw-r--r--ext/strscan/depend38
-rw-r--r--ext/strscan/extconf.rb11
-rw-r--r--ext/strscan/strscan.c195
-rw-r--r--ext/strscan/strscan.gemspec27
-rw-r--r--ext/syslog/depend27
-rw-r--r--ext/syslog/syslog.c22
-rw-r--r--ext/syslog/syslog.gemspec2
-rw-r--r--ext/win32/lib/win32/registry.rb17
-rw-r--r--ext/win32/lib/win32/sspi.rb2
-rw-r--r--ext/win32/resolv/resolv.c18
-rw-r--r--ext/win32ole/sample/xml.rb12
-rw-r--r--ext/win32ole/win32ole.c186
-rw-r--r--ext/win32ole/win32ole.gemspec3
-rw-r--r--ext/win32ole/win32ole_event.c21
-rw-r--r--ext/win32ole/win32ole_method.c5
-rw-r--r--ext/win32ole/win32ole_param.c3
-rw-r--r--ext/win32ole/win32ole_record.c3
-rw-r--r--ext/win32ole/win32ole_type.c5
-rw-r--r--ext/win32ole/win32ole_typelib.c19
-rw-r--r--ext/win32ole/win32ole_variable.c4
-rw-r--r--ext/win32ole/win32ole_variant.c9
-rw-r--r--ext/win32ole/win32ole_variant_m.c2
-rw-r--r--ext/zlib/depend38
-rw-r--r--ext/zlib/extconf.rb9
-rw-r--r--ext/zlib/extlibs8
-rw-r--r--ext/zlib/win32/zlib-1.2.11-mswin.patch95
-rw-r--r--ext/zlib/zlib.c192
-rw-r--r--ext/zlib/zlib.gemspec8
-rw-r--r--file.c3441
-rw-r--r--gc.c8596
-rw-r--r--gc.h39
-rw-r--r--gc.rb267
-rw-r--r--gem_prelude.rb17
-rw-r--r--gems/bundled_gems23
-rw-r--r--gems/lib/core_assertions.rb1
-rw-r--r--gems/lib/envutil.rb1
-rw-r--r--gems/lib/rake/extensiontask.rb12
-rw-r--r--goruby.c38
-rw-r--r--hash.c2202
-rw-r--r--hrtime.h59
-rw-r--r--id_table.c167
-rw-r--r--id_table.h9
-rw-r--r--include/ruby.h2
-rw-r--r--include/ruby/assert.h6
-rw-r--r--include/ruby/atomic.h990
-rw-r--r--include/ruby/backward.h53
-rw-r--r--include/ruby/backward/2/assume.h27
-rw-r--r--include/ruby/backward/2/attributes.h7
-rw-r--r--include/ruby/backward/2/bool.h5
-rw-r--r--include/ruby/backward/2/gcc_version_since.h5
-rw-r--r--include/ruby/backward/2/inttypes.h3
-rw-r--r--include/ruby/backward/2/limits.h5
-rw-r--r--include/ruby/backward/2/long_long.h12
-rw-r--r--include/ruby/backward/2/r_cast.h5
-rw-r--r--include/ruby/backward/2/rmodule.h3
-rw-r--r--include/ruby/backward/2/stdalign.h6
-rw-r--r--include/ruby/backward/2/stdarg.h26
-rw-r--r--include/ruby/backward/cxxanyargs.hpp83
-rw-r--r--include/ruby/debug.h580
-rw-r--r--include/ruby/defines.h11
-rw-r--r--include/ruby/encoding.h412
-rw-r--r--include/ruby/fiber/scheduler.h374
-rw-r--r--include/ruby/internal/abi.h58
-rw-r--r--include/ruby/internal/anyargs.h45
-rw-r--r--include/ruby/internal/arithmetic.h5
-rw-r--r--include/ruby/internal/arithmetic/char.h31
-rw-r--r--include/ruby/internal/arithmetic/double.h49
-rw-r--r--include/ruby/internal/arithmetic/fixnum.h32
-rw-r--r--include/ruby/internal/arithmetic/gid_t.h9
-rw-r--r--include/ruby/internal/arithmetic/int.h129
-rw-r--r--include/ruby/internal/arithmetic/intptr_t.h38
-rw-r--r--include/ruby/internal/arithmetic/long.h160
-rw-r--r--include/ruby/internal/arithmetic/long_long.h108
-rw-r--r--include/ruby/internal/arithmetic/mode_t.h9
-rw-r--r--include/ruby/internal/arithmetic/off_t.h15
-rw-r--r--include/ruby/internal/arithmetic/pid_t.h9
-rw-r--r--include/ruby/internal/arithmetic/short.h85
-rw-r--r--include/ruby/internal/arithmetic/size_t.h24
-rw-r--r--include/ruby/internal/arithmetic/st_data_t.h24
-rw-r--r--include/ruby/internal/arithmetic/uid_t.h9
-rw-r--r--include/ruby/internal/assume.h7
-rw-r--r--include/ruby/internal/attr/alloc_size.h2
-rw-r--r--include/ruby/internal/attr/artificial.h2
-rw-r--r--include/ruby/internal/attr/cold.h4
-rw-r--r--include/ruby/internal/attr/const.h6
-rw-r--r--include/ruby/internal/attr/constexpr.h7
-rw-r--r--include/ruby/internal/attr/deprecated.h18
-rw-r--r--include/ruby/internal/attr/diagnose_if.h2
-rw-r--r--include/ruby/internal/attr/enum_extensibility.h2
-rw-r--r--include/ruby/internal/attr/error.h2
-rw-r--r--include/ruby/internal/attr/flag_enum.h2
-rw-r--r--include/ruby/internal/attr/forceinline.h2
-rw-r--r--include/ruby/internal/attr/format.h2
-rw-r--r--include/ruby/internal/attr/maybe_unused.h2
-rw-r--r--include/ruby/internal/attr/noalias.h15
-rw-r--r--include/ruby/internal/attr/nodiscard.h4
-rw-r--r--include/ruby/internal/attr/noexcept.h2
-rw-r--r--include/ruby/internal/attr/noinline.h2
-rw-r--r--include/ruby/internal/attr/nonnull.h4
-rw-r--r--include/ruby/internal/attr/nonstring.h32
-rw-r--r--include/ruby/internal/attr/noreturn.h2
-rw-r--r--include/ruby/internal/attr/pure.h4
-rw-r--r--include/ruby/internal/attr/restrict.h5
-rw-r--r--include/ruby/internal/attr/returns_nonnull.h2
-rw-r--r--include/ruby/internal/attr/warning.h2
-rw-r--r--include/ruby/internal/attr/weakref.h2
-rw-r--r--include/ruby/internal/cast.h5
-rw-r--r--include/ruby/internal/compiler_is.h2
-rw-r--r--include/ruby/internal/compiler_is/apple.h5
-rw-r--r--include/ruby/internal/compiler_is/clang.h5
-rw-r--r--include/ruby/internal/compiler_is/gcc.h5
-rw-r--r--include/ruby/internal/compiler_is/intel.h5
-rw-r--r--include/ruby/internal/compiler_is/msvc.h5
-rw-r--r--include/ruby/internal/compiler_is/sunpro.h5
-rw-r--r--include/ruby/internal/compiler_since.h6
-rw-r--r--include/ruby/internal/config.h15
-rw-r--r--include/ruby/internal/constant_p.h3
-rw-r--r--include/ruby/internal/core.h4
-rw-r--r--include/ruby/internal/core/rarray.h345
-rw-r--r--include/ruby/internal/core/rbasic.h89
-rw-r--r--include/ruby/internal/core/rbignum.h39
-rw-r--r--include/ruby/internal/core/rclass.h62
-rw-r--r--include/ruby/internal/core/rdata.h234
-rw-r--r--include/ruby/internal/core/rfile.h17
-rw-r--r--include/ruby/internal/core/rhash.h112
-rw-r--r--include/ruby/internal/core/rmatch.h85
-rw-r--r--include/ruby/internal/core/robject.h124
-rw-r--r--include/ruby/internal/core/rregexp.h88
-rw-r--r--include/ruby/internal/core/rstring.h409
-rw-r--r--include/ruby/internal/core/rstruct.h58
-rw-r--r--include/ruby/internal/core/rtypeddata.h428
-rw-r--r--include/ruby/internal/ctype.h382
-rw-r--r--include/ruby/internal/dllexport.h28
-rw-r--r--include/ruby/internal/dosish.h28
-rw-r--r--include/ruby/internal/encoding/coderange.h202
-rw-r--r--include/ruby/internal/encoding/ctype.h258
-rw-r--r--include/ruby/internal/encoding/encoding.h1060
-rw-r--r--include/ruby/internal/encoding/pathname.h184
-rw-r--r--include/ruby/internal/encoding/re.h46
-rw-r--r--include/ruby/internal/encoding/sprintf.h78
-rw-r--r--include/ruby/internal/encoding/string.h346
-rw-r--r--include/ruby/internal/encoding/symbol.h100
-rw-r--r--include/ruby/internal/encoding/transcode.h562
-rw-r--r--include/ruby/internal/error.h568
-rw-r--r--include/ruby/internal/eval.h382
-rw-r--r--include/ruby/internal/event.h157
-rw-r--r--include/ruby/internal/fl_type.h745
-rw-r--r--include/ruby/internal/gc.h15
-rw-r--r--include/ruby/internal/glob.h88
-rw-r--r--include/ruby/internal/globals.h226
-rw-r--r--include/ruby/internal/has/attribute.h9
-rw-r--r--include/ruby/internal/has/builtin.h30
-rw-r--r--include/ruby/internal/has/c_attribute.h2
-rw-r--r--include/ruby/internal/has/cpp_attribute.h9
-rw-r--r--include/ruby/internal/has/declspec_attribute.h5
-rw-r--r--include/ruby/internal/has/extension.h2
-rw-r--r--include/ruby/internal/has/feature.h2
-rw-r--r--include/ruby/internal/has/warning.h2
-rw-r--r--include/ruby/internal/intern/array.h659
-rw-r--r--include/ruby/internal/intern/bignum.h815
-rw-r--r--include/ruby/internal/intern/class.h385
-rw-r--r--include/ruby/internal/intern/compar.h34
-rw-r--r--include/ruby/internal/intern/complex.h203
-rw-r--r--include/ruby/internal/intern/cont.h255
-rw-r--r--include/ruby/internal/intern/dir.h11
-rw-r--r--include/ruby/internal/intern/enum.h44
-rw-r--r--include/ruby/internal/intern/enumerator.h201
-rw-r--r--include/ruby/internal/intern/error.h249
-rw-r--r--include/ruby/internal/intern/eval.h183
-rw-r--r--include/ruby/internal/intern/file.h191
-rw-r--r--include/ruby/internal/intern/gc.h375
-rw-r--r--include/ruby/internal/intern/hash.h305
-rw-r--r--include/ruby/internal/intern/io.h635
-rw-r--r--include/ruby/internal/intern/load.h194
-rw-r--r--include/ruby/internal/intern/marshal.h83
-rw-r--r--include/ruby/internal/intern/numeric.h188
-rw-r--r--include/ruby/internal/intern/object.h499
-rw-r--r--include/ruby/internal/intern/parse.h156
-rw-r--r--include/ruby/internal/intern/proc.h336
-rw-r--r--include/ruby/internal/intern/process.h239
-rw-r--r--include/ruby/internal/intern/random.h75
-rw-r--r--include/ruby/internal/intern/range.h60
-rw-r--r--include/ruby/internal/intern/rational.h138
-rw-r--r--include/ruby/internal/intern/re.h227
-rw-r--r--include/ruby/internal/intern/ruby.h46
-rw-r--r--include/ruby/internal/intern/select.h38
-rw-r--r--include/ruby/internal/intern/select/largesize.h141
-rw-r--r--include/ruby/internal/intern/select/posix.h70
-rw-r--r--include/ruby/internal/intern/select/win32.h153
-rw-r--r--include/ruby/internal/intern/signal.h121
-rw-r--r--include/ruby/internal/intern/sprintf.h132
-rw-r--r--include/ruby/internal/intern/string.h1655
-rw-r--r--include/ruby/internal/intern/struct.h184
-rw-r--r--include/ruby/internal/intern/thread.h452
-rw-r--r--include/ruby/internal/intern/time.h122
-rw-r--r--include/ruby/internal/intern/variable.h629
-rw-r--r--include/ruby/internal/intern/vm.h404
-rw-r--r--include/ruby/internal/interpreter.h235
-rw-r--r--include/ruby/internal/iterator.h480
-rw-r--r--include/ruby/internal/memory.h440
-rw-r--r--include/ruby/internal/method.h180
-rw-r--r--include/ruby/internal/module.h154
-rw-r--r--include/ruby/internal/newobj.h170
-rw-r--r--include/ruby/internal/rgengc.h286
-rw-r--r--include/ruby/internal/scan_args.h157
-rw-r--r--include/ruby/internal/special_consts.h228
-rw-r--r--include/ruby/internal/static_assert.h2
-rw-r--r--include/ruby/internal/stdalign.h10
-rw-r--r--include/ruby/internal/stdbool.h4
-rw-r--r--include/ruby/internal/symbol.h256
-rw-r--r--include/ruby/internal/token_paste.h75
-rw-r--r--include/ruby/internal/value.h71
-rw-r--r--include/ruby/internal/value_type.h199
-rw-r--r--include/ruby/internal/variable.h301
-rw-r--r--include/ruby/internal/warning_push.h43
-rw-r--r--include/ruby/internal/xmalloc.h110
-rw-r--r--include/ruby/io.h924
-rw-r--r--include/ruby/io/buffer.h92
-rw-r--r--include/ruby/memory_view.h202
-rw-r--r--include/ruby/missing.h160
-rw-r--r--include/ruby/onigmo.h15
-rw-r--r--include/ruby/ractor.h217
-rw-r--r--include/ruby/random.h281
-rw-r--r--include/ruby/re.h129
-rw-r--r--include/ruby/regex.h1
-rw-r--r--include/ruby/ruby.h223
-rw-r--r--include/ruby/st.h2
-rw-r--r--include/ruby/subst.h1
-rw-r--r--include/ruby/thread.h201
-rw-r--r--include/ruby/thread_native.h149
-rw-r--r--include/ruby/util.h195
-rw-r--r--include/ruby/version.h109
-rw-r--r--include/ruby/vm.h19
-rw-r--r--include/ruby/win32.h70
-rw-r--r--inits.c16
-rw-r--r--insns.def218
-rw-r--r--integer.rb150
-rw-r--r--internal.h18
-rw-r--r--internal/array.h64
-rw-r--r--internal/basic_operators.h64
-rw-r--r--internal/bignum.h6
-rw-r--r--internal/bits.h7
-rw-r--r--internal/class.h85
-rw-r--r--internal/cmdlineopt.h61
-rw-r--r--internal/compar.h33
-rw-r--r--internal/compile.h5
-rw-r--r--internal/compilers.h3
-rw-r--r--internal/complex.h2
-rw-r--r--internal/cont.h13
-rw-r--r--internal/dir.h1
-rw-r--r--internal/enc.h1
-rw-r--r--internal/encoding.h8
-rw-r--r--internal/enum.h1
-rw-r--r--internal/enumerator.h1
-rw-r--r--internal/error.h71
-rw-r--r--internal/eval.h2
-rw-r--r--internal/file.h1
-rw-r--r--internal/fixnum.h3
-rw-r--r--internal/gc.h53
-rw-r--r--internal/hash.h5
-rw-r--r--internal/imemo.h9
-rw-r--r--internal/inits.h1
-rw-r--r--internal/io.h5
-rw-r--r--internal/load.h1
-rw-r--r--internal/loadpath.h1
-rw-r--r--internal/math.h1
-rw-r--r--internal/missing.h1
-rw-r--r--internal/numeric.h26
-rw-r--r--internal/object.h30
-rw-r--r--internal/parse.h4
-rw-r--r--internal/proc.h1
-rw-r--r--internal/process.h5
-rw-r--r--internal/ractor.h6
-rw-r--r--internal/random.h1
-rw-r--r--internal/range.h1
-rw-r--r--internal/rational.h3
-rw-r--r--internal/re.h3
-rw-r--r--internal/sanitizers.h1
-rw-r--r--internal/scheduler.h44
-rw-r--r--internal/serial.h1
-rw-r--r--internal/signal.h1
-rw-r--r--internal/static_assert.h1
-rw-r--r--internal/string.h13
-rw-r--r--internal/struct.h1
-rw-r--r--internal/symbol.h3
-rw-r--r--internal/thread.h4
-rw-r--r--internal/time.h6
-rw-r--r--internal/transcode.h1
-rw-r--r--internal/util.h4
-rw-r--r--internal/variable.h16
-rw-r--r--internal/vm.h18
-rw-r--r--internal/warnings.h3
-rw-r--r--io.c9885
-rw-r--r--io_buffer.c3515
-rw-r--r--iseq.c2367
-rw-r--r--iseq.h123
-rw-r--r--kernel.rb10
-rw-r--r--lex.c.blt2
-rw-r--r--lib/.document26
-rw-r--r--lib/English.gemspec4
-rw-r--r--lib/abbrev.gemspec4
-rw-r--r--lib/base64.gemspec8
-rw-r--r--lib/base64.rb6
-rw-r--r--lib/benchmark.rb29
-rw-r--r--lib/benchmark/benchmark.gemspec2
-rw-r--r--lib/benchmark/version.rb3
-rw-r--r--lib/bundler.rb175
-rw-r--r--lib/bundler/.document1
-rw-r--r--lib/bundler/build_metadata.rb2
-rw-r--r--lib/bundler/bundler.gemspec23
-rw-r--r--lib/bundler/cli.rb169
-rw-r--r--lib/bundler/cli/add.rb2
-rw-r--r--lib/bundler/cli/binstubs.rb8
-rw-r--r--lib/bundler/cli/cache.rb3
-rw-r--r--lib/bundler/cli/check.rb8
-rw-r--r--lib/bundler/cli/common.rb21
-rw-r--r--lib/bundler/cli/config.rb11
-rw-r--r--lib/bundler/cli/console.rb4
-rw-r--r--lib/bundler/cli/doctor.rb27
-rw-r--r--lib/bundler/cli/exec.rb7
-rw-r--r--lib/bundler/cli/gem.rb234
-rw-r--r--lib/bundler/cli/info.rb35
-rw-r--r--lib/bundler/cli/init.rb8
-rw-r--r--lib/bundler/cli/install.rb84
-rw-r--r--lib/bundler/cli/issue.rb7
-rw-r--r--lib/bundler/cli/list.rb8
-rw-r--r--lib/bundler/cli/lock.rb15
-rw-r--r--lib/bundler/cli/open.rb13
-rw-r--r--lib/bundler/cli/outdated.rb42
-rw-r--r--lib/bundler/cli/platform.rb14
-rw-r--r--lib/bundler/cli/remove.rb3
-rw-r--r--lib/bundler/cli/show.rb2
-rw-r--r--lib/bundler/cli/update.rb25
-rw-r--r--lib/bundler/cli/viz.rb2
-rw-r--r--lib/bundler/compact_index_client.rb10
-rw-r--r--lib/bundler/compact_index_client/cache.rb11
-rw-r--r--lib/bundler/compact_index_client/updater.rb107
-rw-r--r--lib/bundler/constants.rb2
-rw-r--r--lib/bundler/current_ruby.rb25
-rw-r--r--lib/bundler/definition.rb816
-rw-r--r--lib/bundler/dep_proxy.rb48
-rw-r--r--lib/bundler/dependency.rb95
-rw-r--r--lib/bundler/digest.rb71
-rw-r--r--lib/bundler/dsl.rb152
-rw-r--r--lib/bundler/endpoint_specification.rb28
-rw-r--r--lib/bundler/env.rb6
-rw-r--r--lib/bundler/environment_preserver.rb10
-rw-r--r--lib/bundler/errors.rb44
-rw-r--r--lib/bundler/feature_flag.rb7
-rw-r--r--lib/bundler/fetcher.rb66
-rw-r--r--lib/bundler/fetcher/base.rb14
-rw-r--r--lib/bundler/fetcher/compact_index.rb49
-rw-r--r--lib/bundler/fetcher/dependency.rb8
-rw-r--r--lib/bundler/fetcher/downloader.rb22
-rw-r--r--lib/bundler/fetcher/index.rb30
-rw-r--r--lib/bundler/force_platform.rb18
-rw-r--r--lib/bundler/friendly_errors.rb65
-rw-r--r--lib/bundler/gem_helper.rb56
-rw-r--r--lib/bundler/gem_helpers.rb11
-rw-r--r--lib/bundler/gem_version_promoter.rb151
-rw-r--r--lib/bundler/gemdeps.rb29
-rw-r--r--lib/bundler/graph.rb6
-rw-r--r--lib/bundler/index.rb72
-rw-r--r--lib/bundler/injector.rb26
-rw-r--r--lib/bundler/inline.rb33
-rw-r--r--lib/bundler/installer.rb103
-rw-r--r--lib/bundler/installer/gem_installer.rb37
-rw-r--r--lib/bundler/installer/parallel_installer.rb59
-rw-r--r--lib/bundler/installer/standalone.rb71
-rw-r--r--lib/bundler/lazy_specification.rb131
-rw-r--r--lib/bundler/lockfile_generator.rb6
-rw-r--r--lib/bundler/lockfile_parser.rb92
-rw-r--r--lib/bundler/man/bundle-add.182
-rw-r--r--lib/bundler/man/bundle-add.1.ronn20
-rw-r--r--lib/bundler/man/bundle-binstubs.142
-rw-r--r--lib/bundler/man/bundle-cache.161
-rw-r--r--lib/bundler/man/bundle-cache.1.ronn11
-rw-r--r--lib/bundler/man/bundle-check.131
-rw-r--r--lib/bundler/man/bundle-clean.124
-rw-r--r--lib/bundler/man/bundle-clean.1.ronn2
-rw-r--r--lib/bundler/man/bundle-config.1512
-rw-r--r--lib/bundler/man/bundle-config.1.ronn101
-rw-r--r--lib/bundler/man/bundle-console.153
-rw-r--r--lib/bundler/man/bundle-console.1.ronn44
-rw-r--r--lib/bundler/man/bundle-doctor.144
-rw-r--r--lib/bundler/man/bundle-exec.1165
-rw-r--r--lib/bundler/man/bundle-exec.1.ronn12
-rw-r--r--lib/bundler/man/bundle-gem.1105
-rw-r--r--lib/bundler/man/bundle-gem.1.ronn26
-rw-r--r--lib/bundler/man/bundle-help.113
-rw-r--r--lib/bundler/man/bundle-help.1.ronn12
-rw-r--r--lib/bundler/man/bundle-info.120
-rw-r--r--lib/bundler/man/bundle-info.1.ronn6
-rw-r--r--lib/bundler/man/bundle-init.129
-rw-r--r--lib/bundler/man/bundle-init.1.ronn2
-rw-r--r--lib/bundler/man/bundle-inject.136
-rw-r--r--lib/bundler/man/bundle-inject.1.ronn4
-rw-r--r--lib/bundler/man/bundle-install.1313
-rw-r--r--lib/bundler/man/bundle-install.1.ronn39
-rw-r--r--lib/bundler/man/bundle-list.150
-rw-r--r--lib/bundler/man/bundle-lock.184
-rw-r--r--lib/bundler/man/bundle-open.152
-rw-r--r--lib/bundler/man/bundle-open.1.ronn10
-rw-r--r--lib/bundler/man/bundle-outdated.1152
-rw-r--r--lib/bundler/man/bundle-outdated.1.ronn32
-rw-r--r--lib/bundler/man/bundle-platform.171
-rw-r--r--lib/bundler/man/bundle-platform.1.ronn21
-rw-r--r--lib/bundler/man/bundle-plugin.181
-rw-r--r--lib/bundler/man/bundle-plugin.1.ronn59
-rw-r--r--lib/bundler/man/bundle-pristine.134
-rw-r--r--lib/bundler/man/bundle-remove.131
-rw-r--r--lib/bundler/man/bundle-show.123
-rw-r--r--lib/bundler/man/bundle-update.1394
-rw-r--r--lib/bundler/man/bundle-update.1.ronn9
-rw-r--r--lib/bundler/man/bundle-version.135
-rw-r--r--lib/bundler/man/bundle-version.1.ronn24
-rw-r--r--lib/bundler/man/bundle-viz.142
-rw-r--r--lib/bundler/man/bundle-viz.1.ronn2
-rw-r--r--lib/bundler/man/bundle.1141
-rw-r--r--lib/bundler/man/bundle.1.ronn19
-rw-r--r--lib/bundler/man/gemfile.5736
-rw-r--r--lib/bundler/man/gemfile.5.ronn196
-rw-r--r--lib/bundler/man/index.txt29
-rw-r--r--lib/bundler/match_metadata.rb13
-rw-r--r--lib/bundler/match_platform.rb1
-rw-r--r--lib/bundler/match_remote_metadata.rb29
-rw-r--r--lib/bundler/mirror.rb12
-rw-r--r--lib/bundler/plugin.rb40
-rw-r--r--lib/bundler/plugin/api/source.rb32
-rw-r--r--lib/bundler/plugin/index.rb15
-rw-r--r--lib/bundler/plugin/installer.rb27
-rw-r--r--lib/bundler/plugin/installer/git.rb4
-rw-r--r--lib/bundler/plugin/installer/rubygems.rb8
-rw-r--r--lib/bundler/plugin/source_list.rb4
-rw-r--r--lib/bundler/process_lock.rb2
-rw-r--r--lib/bundler/psyched_yaml.rb22
-rw-r--r--lib/bundler/remote_specification.rb12
-rw-r--r--lib/bundler/resolver.rb711
-rw-r--r--lib/bundler/resolver/base.rb107
-rw-r--r--lib/bundler/resolver/candidate.rb94
-rw-r--r--lib/bundler/resolver/incompatibility.rb15
-rw-r--r--lib/bundler/resolver/package.rb72
-rw-r--r--lib/bundler/resolver/root.rb25
-rw-r--r--lib/bundler/resolver/spec_group.rb130
-rw-r--r--lib/bundler/retry.rb2
-rw-r--r--lib/bundler/ruby_dsl.rb8
-rw-r--r--lib/bundler/ruby_version.rb29
-rw-r--r--lib/bundler/rubygems_ext.rb225
-rw-r--r--lib/bundler/rubygems_gem_installer.rb97
-rw-r--r--lib/bundler/rubygems_integration.rb165
-rw-r--r--lib/bundler/runtime.rb38
-rw-r--r--lib/bundler/safe_marshal.rb31
-rw-r--r--lib/bundler/self_manager.rb168
-rw-r--r--lib/bundler/settings.rb134
-rw-r--r--lib/bundler/setup.rb7
-rw-r--r--lib/bundler/shared_helpers.rb53
-rw-r--r--lib/bundler/source.rb30
-rw-r--r--lib/bundler/source/git.rb131
-rw-r--r--lib/bundler/source/git/git_proxy.rb363
-rw-r--r--lib/bundler/source/metadata.rb11
-rw-r--r--lib/bundler/source/path.rb16
-rw-r--r--lib/bundler/source/path/installer.rb27
-rw-r--r--lib/bundler/source/rubygems.rb380
-rw-r--r--lib/bundler/source/rubygems_aggregate.rb68
-rw-r--r--lib/bundler/source_list.rb170
-rw-r--r--lib/bundler/source_map.rb71
-rw-r--r--lib/bundler/spec_set.rb125
-rw-r--r--lib/bundler/stub_specification.rb16
-rw-r--r--lib/bundler/templates/Executable8
-rw-r--r--lib/bundler/templates/Executable.bundler27
-rw-r--r--lib/bundler/templates/Executable.standalone8
-rw-r--r--lib/bundler/templates/Gemfile2
-rw-r--r--lib/bundler/templates/gems.rb8
-rw-r--r--lib/bundler/templates/newgem/CHANGELOG.md.tt5
-rw-r--r--lib/bundler/templates/newgem/Cargo.toml.tt7
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt10
-rw-r--r--lib/bundler/templates/newgem/README.md.tt26
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt30
-rw-r--r--lib/bundler/templates/newgem/bin/console.tt4
-rw-r--r--lib/bundler/templates/newgem/circleci/config.yml.tt12
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt15
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt10
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt5
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/newgem.c.tt2
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt12
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt33
-rw-r--r--lib/bundler/templates/newgem/gitignore.tt3
-rw-r--r--lib/bundler/templates/newgem/gitlab-ci.yml.tt17
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt45
-rw-r--r--lib/bundler/templates/newgem/rubocop.yml.tt3
-rw-r--r--lib/bundler/templates/newgem/sig/newgem.rbs.tt8
-rw-r--r--lib/bundler/templates/newgem/standard.yml.tt3
-rw-r--r--lib/bundler/templates/newgem/test/minitest/newgem_test.rb.tt13
-rw-r--r--lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt13
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt6
-rw-r--r--lib/bundler/ui/rg_proxy.rb2
-rw-r--r--lib/bundler/ui/shell.rb49
-rw-r--r--lib/bundler/ui/silent.rb26
-rw-r--r--lib/bundler/uri_normalizer.rb23
-rw-r--r--lib/bundler/vendor/.document1
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool.rb115
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb66
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb40
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb2
-rw-r--r--lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb56
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb1760
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo.rb11
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb57
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb81
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb256
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb36
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb66
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb62
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb63
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb61
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb126
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb46
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb36
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb158
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/errors.rb143
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb6
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb101
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb67
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb835
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb46
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/state.rb58
-rw-r--r--lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb2
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub.rb31
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb20
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb189
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb182
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb150
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb43
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb121
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb45
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb19
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb60
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb105
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb3
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb129
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb411
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb248
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb178
-rw-r--r--lib/bundler/vendor/thor/lib/thor.rb11
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb10
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb16
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb3
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb6
-rw-r--r--lib/bundler/vendor/thor/lib/thor/error.rb15
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/arguments.rb6
-rw-r--r--lib/bundler/vendor/thor/lib/thor/parser/options.rb37
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/basic.rb35
-rw-r--r--lib/bundler/vendor/thor/lib/thor/shell/color.rb6
-rw-r--r--lib/bundler/vendor/thor/lib/thor/util.rb2
-rw-r--r--lib/bundler/vendor/thor/lib/thor/version.rb2
-rw-r--r--lib/bundler/vendor/tmpdir/lib/tmpdir.rb154
-rw-r--r--lib/bundler/vendor/tsort/lib/tsort.rb452
-rw-r--r--lib/bundler/vendor/uri/lib/uri.rb6
-rw-r--r--lib/bundler/vendor/uri/lib/uri/common.rb167
-rw-r--r--lib/bundler/vendor/uri/lib/uri/file.rb8
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ftp.rb4
-rw-r--r--lib/bundler/vendor/uri/lib/uri/generic.rb45
-rw-r--r--lib/bundler/vendor/uri/lib/uri/http.rb43
-rw-r--r--lib/bundler/vendor/uri/lib/uri/https.rb4
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ldap.rb4
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ldaps.rb3
-rw-r--r--lib/bundler/vendor/uri/lib/uri/mailto.rb5
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb39
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb30
-rw-r--r--lib/bundler/vendor/uri/lib/uri/version.rb2
-rw-r--r--lib/bundler/vendor/uri/lib/uri/ws.rb83
-rw-r--r--lib/bundler/vendor/uri/lib/uri/wss.rb23
-rw-r--r--lib/bundler/vendored_molinillo.rb4
-rw-r--r--lib/bundler/vendored_persistent.rb34
-rw-r--r--lib/bundler/vendored_pub_grub.rb4
-rw-r--r--lib/bundler/vendored_tmpdir.rb4
-rw-r--r--lib/bundler/vendored_tsort.rb4
-rw-r--r--lib/bundler/version.rb6
-rw-r--r--lib/bundler/version_ranges.rb122
-rw-r--r--lib/bundler/worker.rb35
-rw-r--r--lib/cgi.rb4
-rw-r--r--lib/cgi/cgi.gemspec21
-rw-r--r--lib/cgi/cookie.rb50
-rw-r--r--lib/cgi/core.rb45
-rw-r--r--lib/cgi/session.rb58
-rw-r--r--lib/cgi/session/pstore.rb16
-rw-r--r--lib/cgi/util.rb75
-rw-r--r--lib/csv.rb548
-rw-r--r--lib/csv/csv.gemspec2
-rw-r--r--lib/csv/fields_converter.rb13
-rw-r--r--lib/csv/input_record_separator.rb18
-rw-r--r--lib/csv/parser.rb345
-rw-r--r--lib/csv/row.rb231
-rw-r--r--lib/csv/table.rb626
-rw-r--r--lib/csv/version.rb2
-rw-r--r--lib/csv/writer.rb13
-rw-r--r--lib/debug.gemspec22
-rw-r--r--lib/debug.rb1106
-rw-r--r--lib/delegate.rb4
-rw-r--r--lib/delegate/delegate.gemspec2
-rw-r--r--lib/did_you_mean.rb59
-rw-r--r--lib/did_you_mean/core_ext/name_error.rb54
-rw-r--r--lib/did_you_mean/formatter.rb44
-rw-r--r--lib/did_you_mean/formatters/plain_formatter.rb35
-rw-r--r--lib/did_you_mean/formatters/verbose_formatter.rb49
-rw-r--r--lib/did_you_mean/spell_checker.rb18
-rw-r--r--lib/did_you_mean/spell_checkers/method_name_checker.rb10
-rw-r--r--lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb5
-rw-r--r--lib/did_you_mean/spell_checkers/pattern_key_name_checker.rb20
-rw-r--r--lib/did_you_mean/spell_checkers/require_path_checker.rb6
-rw-r--r--lib/did_you_mean/verbose.rb6
-rw-r--r--lib/did_you_mean/version.rb2
-rw-r--r--lib/drb/drb.gemspec6
-rw-r--r--lib/drb/drb.rb11
-rw-r--r--lib/drb/extserv.rb4
-rw-r--r--lib/drb/extservm.rb6
-rw-r--r--lib/drb/version.rb2
-rw-r--r--lib/erb.gemspec42
-rw-r--r--lib/erb.rb595
-rw-r--r--lib/erb/compiler.rb471
-rw-r--r--lib/erb/def_method.rb46
-rw-r--r--lib/erb/util.rb62
-rw-r--r--lib/erb/version.rb5
-rw-r--r--lib/error_highlight.rb2
-rw-r--r--lib/error_highlight/base.rb514
-rw-r--r--lib/error_highlight/core_ext.rb47
-rw-r--r--lib/error_highlight/error_highlight.gemspec27
-rw-r--r--lib/error_highlight/formatter.rb23
-rw-r--r--lib/error_highlight/version.rb3
-rw-r--r--lib/fileutils.gemspec2
-rw-r--r--lib/fileutils.rb1731
-rw-r--r--lib/find.gemspec2
-rw-r--r--lib/find.rb4
-rw-r--r--lib/forwardable.rb6
-rw-r--r--lib/forwardable/forwardable.gemspec2
-rw-r--r--lib/forwardable/impl.rb3
-rw-r--r--lib/getoptlong.rb575
-rw-r--r--lib/getoptlong/getoptlong.gemspec2
-rw-r--r--lib/ipaddr.gemspec18
-rw-r--r--lib/ipaddr.rb143
-rw-r--r--lib/irb.rb245
-rw-r--r--lib/irb/cmd/backtrace.rb21
-rw-r--r--lib/irb/cmd/break.rb21
-rw-r--r--lib/irb/cmd/catch.rb21
-rw-r--r--lib/irb/cmd/chws.rb12
-rw-r--r--lib/irb/cmd/continue.rb17
-rw-r--r--lib/irb/cmd/debug.rb136
-rw-r--r--lib/irb/cmd/delete.rb17
-rw-r--r--lib/irb/cmd/edit.rb61
-rw-r--r--lib/irb/cmd/finish.rb17
-rw-r--r--lib/irb/cmd/fork.rb7
-rw-r--r--lib/irb/cmd/help.rb23
-rw-r--r--lib/irb/cmd/info.rb29
-rw-r--r--lib/irb/cmd/irb_info.rb37
-rw-r--r--lib/irb/cmd/load.rb39
-rw-r--r--lib/irb/cmd/ls.rb116
-rw-r--r--lib/irb/cmd/measure.rb26
-rw-r--r--lib/irb/cmd/next.rb17
-rw-r--r--lib/irb/cmd/nop.rb42
-rw-r--r--lib/irb/cmd/pushws.rb15
-rw-r--r--lib/irb/cmd/show_cmds.rb39
-rw-r--r--lib/irb/cmd/show_source.rb112
-rw-r--r--lib/irb/cmd/step.rb17
-rw-r--r--lib/irb/cmd/subirb.rb44
-rw-r--r--lib/irb/cmd/whereami.rb25
-rw-r--r--lib/irb/color.rb99
-rw-r--r--lib/irb/color_printer.rb40
-rw-r--r--lib/irb/completion.rb252
-rw-r--r--lib/irb/context.rb120
-rw-r--r--lib/irb/ext/loader.rb65
-rw-r--r--lib/irb/ext/multi-irb.rb1
-rw-r--r--lib/irb/ext/save-history.rb24
-rw-r--r--lib/irb/extend-command.rb186
-rw-r--r--lib/irb/init.rb85
-rw-r--r--lib/irb/input-method.rb149
-rw-r--r--lib/irb/inspector.rb22
-rw-r--r--lib/irb/irb.gemspec56
-rw-r--r--lib/irb/lc/error.rb11
-rw-r--r--lib/irb/lc/help-message95
-rw-r--r--lib/irb/lc/ja/encoding_aliases.rb6
-rw-r--r--lib/irb/lc/ja/error.rb11
-rw-r--r--lib/irb/lc/ja/help-message14
-rw-r--r--lib/irb/ruby-lex.rb521
-rw-r--r--lib/irb/version.rb4
-rw-r--r--lib/irb/workspace.rb21
-rw-r--r--lib/logger.rb773
-rw-r--r--lib/logger/errors.rb2
-rw-r--r--lib/logger/formatter.rb8
-rw-r--r--lib/logger/log_device.rb8
-rw-r--r--lib/logger/logger.gemspec3
-rw-r--r--lib/logger/version.rb2
-rw-r--r--lib/matrix.rb2464
-rw-r--r--lib/matrix/eigenvalue_decomposition.rb882
-rw-r--r--lib/matrix/lup_decomposition.rb219
-rw-r--r--lib/matrix/matrix.gemspec29
-rw-r--r--lib/matrix/version.rb5
-rw-r--r--lib/mkmf.rb233
-rw-r--r--lib/mutex_m.rb15
-rw-r--r--lib/net/ftp.rb1534
-rw-r--r--lib/net/http.rb2126
-rw-r--r--lib/net/http/backward.rb40
-rw-r--r--lib/net/http/exceptions.rb55
-rw-r--r--lib/net/http/generic_request.rb117
-rw-r--r--lib/net/http/header.rb791
-rw-r--r--lib/net/http/net-http.gemspec15
-rw-r--r--lib/net/http/proxy_delta.rb2
-rw-r--r--lib/net/http/request.rb79
-rw-r--r--lib/net/http/requests.rb352
-rw-r--r--lib/net/http/response.rb367
-rw-r--r--lib/net/http/responses.rb1313
-rw-r--r--lib/net/http/status.rb13
-rw-r--r--lib/net/https.rb2
-rw-r--r--lib/net/imap.rb3730
-rw-r--r--lib/net/net-ftp.gemspec36
-rw-r--r--lib/net/net-imap.gemspec37
-rw-r--r--lib/net/net-pop.gemspec34
-rw-r--r--lib/net/net-protocol.gemspec9
-rw-r--r--lib/net/net-smtp.gemspec35
-rw-r--r--lib/net/pop.rb1022
-rw-r--r--lib/net/protocol.rb86
-rw-r--r--lib/net/smtp.rb1112
-rw-r--r--lib/open-uri.gemspec7
-rw-r--r--lib/open-uri.rb44
-rw-r--r--lib/open3.gemspec33
-rw-r--r--lib/open3.rb6
-rw-r--r--lib/open3/open3.gemspec33
-rw-r--r--lib/open3/version.rb3
-rw-r--r--lib/optparse.rb283
-rw-r--r--lib/optparse/ac.rb2
-rw-r--r--lib/optparse/date.rb2
-rw-r--r--lib/optparse/kwargs.rb7
-rw-r--r--lib/optparse/optparse.gemspec7
-rw-r--r--lib/optparse/shellwords.rb2
-rw-r--r--lib/optparse/time.rb2
-rw-r--r--lib/optparse/uri.rb2
-rw-r--r--lib/ostruct.rb90
-rw-r--r--lib/ostruct/ostruct.gemspec2
-rw-r--r--lib/pp.gemspec2
-rw-r--r--lib/pp.rb106
-rw-r--r--lib/prettyprint.gemspec2
-rw-r--r--lib/prime.gemspec28
-rw-r--r--lib/prime.rb561
-rw-r--r--lib/pstore.rb578
-rw-r--r--lib/racc/grammar.rb6
-rw-r--r--lib/racc/grammarfileparser.rb4
-rw-r--r--lib/racc/info.rb2
-rw-r--r--lib/racc/parser-text.rb4
-rw-r--r--lib/racc/parser.rb4
-rw-r--r--lib/racc/parserfilegenerator.rb44
-rw-r--r--lib/racc/pre-setup13
-rw-r--r--lib/racc/racc.gemspec75
-rw-r--r--lib/racc/rdoc/grammar.en.rdoc219
-rw-r--r--lib/racc/statetransitiontable.rb12
-rw-r--r--lib/random/formatter.rb245
-rw-r--r--lib/rdoc.rb92
-rw-r--r--lib/rdoc/any_method.rb9
-rw-r--r--lib/rdoc/code_objects.rb3
-rw-r--r--lib/rdoc/context.rb4
-rw-r--r--lib/rdoc/context/section.rb2
-rw-r--r--lib/rdoc/cross_reference.rb64
-rw-r--r--lib/rdoc/generator.rb10
-rw-r--r--lib/rdoc/generator/darkfish.rb4
-rw-r--r--lib/rdoc/generator/markup.rb2
-rw-r--r--lib/rdoc/generator/template/darkfish/_head.rhtml24
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml30
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml24
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml29
-rw-r--r--lib/rdoc/generator/template/darkfish/class.rhtml42
-rw-r--r--lib/rdoc/generator/template/darkfish/css/rdoc.css45
-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttfbin71200 -> 138268 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttfbin71692 -> 138680 bytes-rw-r--r--lib/rdoc/generator/template/darkfish/index.rhtml2
-rw-r--r--lib/rdoc/generator/template/darkfish/js/darkfish.js2
-rw-r--r--lib/rdoc/generator/template/darkfish/js/search.js2
-rw-r--r--lib/rdoc/generator/template/darkfish/table_of_contents.rhtml4
-rw-r--r--lib/rdoc/i18n.rb2
-rw-r--r--lib/rdoc/known_classes.rb9
-rw-r--r--lib/rdoc/markdown.rb784
-rw-r--r--lib/rdoc/markdown/literals.rb122
-rw-r--r--lib/rdoc/markup.rb701
-rw-r--r--lib/rdoc/markup/attr_span.rb10
-rw-r--r--lib/rdoc/markup/attribute_manager.rb125
-rw-r--r--lib/rdoc/markup/parser.rb18
-rw-r--r--lib/rdoc/markup/pre_process.rb2
-rw-r--r--lib/rdoc/markup/table.rb47
-rw-r--r--lib/rdoc/markup/to_html.rb55
-rw-r--r--lib/rdoc/markup/to_joined_paragraph.rb1
-rw-r--r--lib/rdoc/markup/to_label.rb2
-rw-r--r--lib/rdoc/markup/to_rdoc.rb51
-rw-r--r--lib/rdoc/markup/to_table_of_contents.rb1
-rw-r--r--lib/rdoc/method_attr.rb2
-rw-r--r--lib/rdoc/normal_class.rb2
-rw-r--r--lib/rdoc/normal_module.rb2
-rw-r--r--lib/rdoc/options.rb116
-rw-r--r--lib/rdoc/parser.rb21
-rw-r--r--lib/rdoc/parser/c.rb220
-rw-r--r--lib/rdoc/parser/changelog.rb159
-rw-r--r--lib/rdoc/parser/ruby.rb53
-rw-r--r--lib/rdoc/rd.rb7
-rw-r--r--lib/rdoc/rd/block_parser.rb22
-rw-r--r--lib/rdoc/rd/inline_parser.rb2
-rw-r--r--lib/rdoc/rdoc.gemspec25
-rw-r--r--lib/rdoc/rdoc.rb47
-rw-r--r--lib/rdoc/ri.rb9
-rw-r--r--lib/rdoc/ri/driver.rb104
-rw-r--r--lib/rdoc/rubygems_hook.rb6
-rw-r--r--lib/rdoc/servlet.rb2
-rw-r--r--lib/rdoc/single_class.rb5
-rw-r--r--lib/rdoc/stats.rb7
-rw-r--r--lib/rdoc/store.rb45
-rw-r--r--lib/rdoc/task.rb6
-rw-r--r--lib/rdoc/text.rb16
-rw-r--r--lib/rdoc/version.rb4
-rw-r--r--lib/readline.gemspec26
-rw-r--r--lib/readline.rb1
-rw-r--r--lib/reline.rb215
-rw-r--r--lib/reline/ansi.rb217
-rw-r--r--lib/reline/config.rb96
-rw-r--r--lib/reline/general_io.rb24
-rw-r--r--lib/reline/key_actor/base.rb12
-rw-r--r--lib/reline/key_actor/emacs.rb2
-rw-r--r--lib/reline/key_stroke.rb78
-rw-r--r--lib/reline/line_editor.rb953
-rw-r--r--lib/reline/reline.gemspec16
-rw-r--r--lib/reline/terminfo.rb174
-rw-r--r--lib/reline/unicode.rb46
-rw-r--r--lib/reline/version.rb2
-rw-r--r--lib/reline/windows.rb418
-rw-r--r--lib/resolv-replace.gemspec4
-rw-r--r--lib/resolv.gemspec4
-rw-r--r--lib/resolv.rb16
-rw-r--r--lib/rinda/rinda.gemspec2
-rw-r--r--lib/ruby2_keywords.gemspec23
-rw-r--r--lib/ruby_vm/mjit/c_pointer.rb329
-rw-r--r--lib/ruby_vm/mjit/c_type.rb91
-rw-r--r--lib/ruby_vm/mjit/compiler.rb952
-rw-r--r--lib/ruby_vm/mjit/hooks.rb32
-rw-r--r--lib/rubygems.rb304
-rw-r--r--lib/rubygems/available_set.rb7
-rw-r--r--lib/rubygems/basic_specification.rb25
-rw-r--r--lib/rubygems/bundler_version_finder.rb62
-rw-r--r--lib/rubygems/command.rb90
-rw-r--r--lib/rubygems/command_manager.rb52
-rw-r--r--lib/rubygems/commands/build_command.rb20
-rw-r--r--lib/rubygems/commands/cert_command.rb144
-rw-r--r--lib/rubygems/commands/check_command.rb41
-rw-r--r--lib/rubygems/commands/cleanup_command.rb47
-rw-r--r--lib/rubygems/commands/contents_command.rb27
-rw-r--r--lib/rubygems/commands/dependency_command.rb81
-rw-r--r--lib/rubygems/commands/environment_command.rb18
-rw-r--r--lib/rubygems/commands/exec_command.rb249
-rw-r--r--lib/rubygems/commands/fetch_command.rb46
-rw-r--r--lib/rubygems/commands/generate_index_command.rb35
-rw-r--r--lib/rubygems/commands/help_command.rb13
-rw-r--r--lib/rubygems/commands/info_command.rb6
-rw-r--r--lib/rubygems/commands/install_command.rb59
-rw-r--r--lib/rubygems/commands/list_command.rb9
-rw-r--r--lib/rubygems/commands/lock_command.rb9
-rw-r--r--lib/rubygems/commands/mirror_command.rb7
-rw-r--r--lib/rubygems/commands/open_command.rb21
-rw-r--r--lib/rubygems/commands/outdated_command.rb11
-rw-r--r--lib/rubygems/commands/owner_command.rb36
-rw-r--r--lib/rubygems/commands/pristine_command.rb114
-rw-r--r--lib/rubygems/commands/push_command.rb33
-rw-r--r--lib/rubygems/commands/query_command.rb19
-rw-r--r--lib/rubygems/commands/rdoc_command.rb52
-rw-r--r--lib/rubygems/commands/search_command.rb9
-rw-r--r--lib/rubygems/commands/server_command.rb92
-rw-r--r--lib/rubygems/commands/setup_command.rb424
-rw-r--r--lib/rubygems/commands/signin_command.rb19
-rw-r--r--lib/rubygems/commands/signout_command.rb15
-rw-r--r--lib/rubygems/commands/sources_command.rb45
-rw-r--r--lib/rubygems/commands/specification_command.rb37
-rw-r--r--lib/rubygems/commands/stale_command.rb5
-rw-r--r--lib/rubygems/commands/uninstall_command.rb84
-rw-r--r--lib/rubygems/commands/unpack_command.rb27
-rw-r--r--lib/rubygems/commands/update_command.rb142
-rw-r--r--lib/rubygems/commands/which_command.rb15
-rw-r--r--lib/rubygems/commands/yank_command.rb25
-rw-r--r--lib/rubygems/compatibility.rb6
-rw-r--r--lib/rubygems/config_file.rb95
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb7
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb224
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb70
-rw-r--r--lib/rubygems/core_ext/tcpsocket_init.rb54
-rw-r--r--lib/rubygems/defaults.rb71
-rw-r--r--lib/rubygems/dependency.rb38
-rw-r--r--lib/rubygems/dependency_installer.rb75
-rw-r--r--lib/rubygems/dependency_list.rb15
-rw-r--r--lib/rubygems/deprecate.rb68
-rw-r--r--lib/rubygems/doctor.rb43
-rw-r--r--lib/rubygems/errors.rb11
-rw-r--r--lib/rubygems/exceptions.rb52
-rw-r--r--lib/rubygems/ext.rb14
-rw-r--r--lib/rubygems/ext/build_error.rb3
-rw-r--r--lib/rubygems/ext/builder.rb79
-rw-r--r--lib/rubygems/ext/cargo_builder.rb360
-rw-r--r--lib/rubygems/ext/cargo_builder/link_flag_converter.rb27
-rw-r--r--lib/rubygems/ext/cmake_builder.rb7
-rw-r--r--lib/rubygems/ext/configure_builder.rb6
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb104
-rw-r--r--lib/rubygems/ext/rake_builder.rb13
-rw-r--r--lib/rubygems/gem_runner.rb29
-rw-r--r--lib/rubygems/gemcutter_utilities.rb149
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener.rb105
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb163
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_poller.rb78
-rw-r--r--lib/rubygems/indexer.rb59
-rw-r--r--lib/rubygems/install_default_message.rb5
-rw-r--r--lib/rubygems/install_message.rb5
-rw-r--r--lib/rubygems/install_update_options.rb132
-rw-r--r--lib/rubygems/installer.rb250
-rw-r--r--lib/rubygems/installer_test_case.rb247
-rw-r--r--lib/rubygems/installer_uninstaller_utils.rb9
-rw-r--r--lib/rubygems/local_remote_options.rb47
-rw-r--r--lib/rubygems/mock_gem_ui.rb5
-rw-r--r--lib/rubygems/name_tuple.rb14
-rw-r--r--lib/rubygems/optparse.rb3
-rw-r--r--lib/rubygems/optparse/.document1
-rw-r--r--lib/rubygems/optparse/lib/optionparser.rb2
-rw-r--r--lib/rubygems/optparse/lib/optparse.rb2308
-rw-r--r--lib/rubygems/optparse/lib/optparse/ac.rb54
-rw-r--r--lib/rubygems/optparse/lib/optparse/date.rb18
-rw-r--r--lib/rubygems/optparse/lib/optparse/kwargs.rb22
-rw-r--r--lib/rubygems/optparse/lib/optparse/shellwords.rb7
-rw-r--r--lib/rubygems/optparse/lib/optparse/time.rb11
-rw-r--r--lib/rubygems/optparse/lib/optparse/uri.rb7
-rw-r--r--lib/rubygems/optparse/lib/optparse/version.rb71
-rw-r--r--lib/rubygems/package.rb200
-rw-r--r--lib/rubygems/package/digest_io.rb1
-rw-r--r--lib/rubygems/package/file_source.rb5
-rw-r--r--lib/rubygems/package/io_source.rb5
-rw-r--r--lib/rubygems/package/old.rb19
-rw-r--r--lib/rubygems/package/source.rb1
-rw-r--r--lib/rubygems/package/tar_header.rb125
-rw-r--r--lib/rubygems/package/tar_reader.rb31
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb100
-rw-r--r--lib/rubygems/package/tar_test_case.rb139
-rw-r--r--lib/rubygems/package/tar_writer.rb15
-rw-r--r--lib/rubygems/package_task.rb9
-rw-r--r--lib/rubygems/path_support.rb8
-rw-r--r--lib/rubygems/platform.rb161
-rw-r--r--lib/rubygems/psych_additions.rb10
-rw-r--r--lib/rubygems/psych_tree.rb3
-rw-r--r--lib/rubygems/query_utils.rb100
-rw-r--r--lib/rubygems/rdoc.rb5
-rw-r--r--lib/rubygems/remote_fetcher.rb88
-rw-r--r--lib/rubygems/request.rb47
-rw-r--r--lib/rubygems/request/connection_pools.rb10
-rw-r--r--lib/rubygems/request/http_pool.rb5
-rw-r--r--lib/rubygems/request/https_pool.rb1
-rw-r--r--lib/rubygems/request_set.rb45
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb246
-rw-r--r--lib/rubygems/request_set/lockfile.rb19
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb55
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb8
-rw-r--r--lib/rubygems/requirement.rb56
-rw-r--r--lib/rubygems/resolver.rb81
-rw-r--r--lib/rubygems/resolver/activation_request.rb7
-rw-r--r--lib/rubygems/resolver/api_set.rb9
-rw-r--r--lib/rubygems/resolver/api_specification.rb13
-rw-r--r--lib/rubygems/resolver/best_set.rb13
-rw-r--r--lib/rubygems/resolver/composed_set.rb1
-rw-r--r--lib/rubygems/resolver/conflict.rb21
-rw-r--r--lib/rubygems/resolver/current_set.rb1
-rw-r--r--lib/rubygems/resolver/dependency_request.rb5
-rw-r--r--lib/rubygems/resolver/git_set.rb5
-rw-r--r--lib/rubygems/resolver/git_specification.rb13
-rw-r--r--lib/rubygems/resolver/index_set.rb7
-rw-r--r--lib/rubygems/resolver/index_specification.rb22
-rw-r--r--lib/rubygems/resolver/installed_specification.rb9
-rw-r--r--lib/rubygems/resolver/installer_set.rb58
-rw-r--r--lib/rubygems/resolver/local_specification.rb5
-rw-r--r--lib/rubygems/resolver/lock_set.rb9
-rw-r--r--lib/rubygems/resolver/lock_specification.rb9
-rw-r--r--lib/rubygems/resolver/molinillo.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb16
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb60
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb2
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb13
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb18
-rw-r--r--lib/rubygems/resolver/requirement_list.rb1
-rw-r--r--lib/rubygems/resolver/set.rb2
-rw-r--r--lib/rubygems/resolver/source_set.rb2
-rw-r--r--lib/rubygems/resolver/spec_specification.rb1
-rw-r--r--lib/rubygems/resolver/specification.rb3
-rw-r--r--lib/rubygems/resolver/stats.rb3
-rw-r--r--lib/rubygems/resolver/vendor_set.rb3
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb7
-rw-r--r--lib/rubygems/s3_uri_signer.rb22
-rw-r--r--lib/rubygems/safe_yaml.rb24
-rw-r--r--lib/rubygems/security.rb113
-rw-r--r--lib/rubygems/security/policies.rb95
-rw-r--r--lib/rubygems/security/policy.rb43
-rw-r--r--lib/rubygems/security/signer.rb20
-rw-r--r--lib/rubygems/security/trust_dir.rb8
-rw-r--r--lib/rubygems/security_option.rb15
-rw-r--r--lib/rubygems/server.rb882
-rw-r--r--lib/rubygems/shellwords.rb3
-rw-r--r--lib/rubygems/source.rb61
-rw-r--r--lib/rubygems/source/git.rb51
-rw-r--r--lib/rubygems/source/installed.rb3
-rw-r--r--lib/rubygems/source/local.rb5
-rw-r--r--lib/rubygems/source/lock.rb1
-rw-r--r--lib/rubygems/source/specific_file.rb3
-rw-r--r--lib/rubygems/source/vendor.rb1
-rw-r--r--lib/rubygems/source_list.rb14
-rw-r--r--lib/rubygems/spec_fetcher.rb75
-rw-r--r--lib/rubygems/specification.rb560
-rw-r--r--lib/rubygems/specification_policy.rb92
-rw-r--r--lib/rubygems/stub_specification.rb55
-rw-r--r--lib/rubygems/syck_hack.rb77
-rw-r--r--lib/rubygems/test_case.rb1510
-rw-r--r--lib/rubygems/test_utilities.rb373
-rw-r--r--lib/rubygems/text.rb43
-rw-r--r--lib/rubygems/tsort.rb3
-rw-r--r--lib/rubygems/tsort/.document1
-rw-r--r--lib/rubygems/tsort/lib/tsort.rb452
-rw-r--r--lib/rubygems/uninstaller.rb97
-rw-r--r--lib/rubygems/unknown_command_spell_checker.rb21
-rw-r--r--lib/rubygems/update_suggestion.rb69
-rw-r--r--lib/rubygems/uri.rb126
-rw-r--r--lib/rubygems/uri_formatter.rb2
-rw-r--r--lib/rubygems/uri_parser.rb34
-rw-r--r--lib/rubygems/uri_parsing.rb23
-rw-r--r--lib/rubygems/user_interaction.rb78
-rw-r--r--lib/rubygems/util.rb29
-rw-r--r--lib/rubygems/util/licenses.rb116
-rw-r--r--lib/rubygems/util/list.rb1
-rw-r--r--lib/rubygems/validator.rb13
-rw-r--r--lib/rubygems/version.rb45
-rw-r--r--lib/rubygems/version_option.rb11
-rw-r--r--lib/securerandom.gemspec4
-rw-r--r--lib/securerandom.rb244
-rw-r--r--lib/set.rb194
-rw-r--r--lib/set/set.gemspec6
-rw-r--r--lib/set/sorted_set.rb2
-rw-r--r--lib/syntax_suggest.rb3
-rw-r--r--lib/syntax_suggest/api.rb201
-rw-r--r--lib/syntax_suggest/around_block_scan.rb232
-rw-r--r--lib/syntax_suggest/block_expand.rb165
-rw-r--r--lib/syntax_suggest/capture/before_after_keyword_ends.rb85
-rw-r--r--lib/syntax_suggest/capture/falling_indent_lines.rb71
-rw-r--r--lib/syntax_suggest/capture_code_context.rb245
-rw-r--r--lib/syntax_suggest/clean_document.rb306
-rw-r--r--lib/syntax_suggest/cli.rb130
-rw-r--r--lib/syntax_suggest/code_block.rb100
-rw-r--r--lib/syntax_suggest/code_frontier.rb178
-rw-r--r--lib/syntax_suggest/code_line.rb237
-rw-r--r--lib/syntax_suggest/code_search.rb139
-rw-r--r--lib/syntax_suggest/core_ext.rb114
-rw-r--r--lib/syntax_suggest/display_code_with_line_numbers.rb70
-rw-r--r--lib/syntax_suggest/display_invalid_blocks.rb83
-rw-r--r--lib/syntax_suggest/explain_syntax.rb103
-rw-r--r--lib/syntax_suggest/left_right_lex_count.rb168
-rw-r--r--lib/syntax_suggest/lex_all.rb55
-rw-r--r--lib/syntax_suggest/lex_value.rb70
-rw-r--r--lib/syntax_suggest/parse_blocks_from_indent_line.rb60
-rw-r--r--lib/syntax_suggest/pathname_from_message.rb59
-rw-r--r--lib/syntax_suggest/priority_engulf_queue.rb63
-rw-r--r--lib/syntax_suggest/priority_queue.rb105
-rw-r--r--lib/syntax_suggest/ripper_errors.rb36
-rw-r--r--lib/syntax_suggest/scan_history.rb134
-rw-r--r--lib/syntax_suggest/syntax_suggest.gemspec32
-rw-r--r--lib/syntax_suggest/unvisited_lines.rb36
-rw-r--r--lib/syntax_suggest/version.rb5
-rw-r--r--lib/tempfile.gemspec4
-rw-r--r--lib/tempfile.rb151
-rw-r--r--lib/time.gemspec2
-rw-r--r--lib/time.rb37
-rw-r--r--lib/timeout.rb171
-rw-r--r--lib/timeout/timeout.gemspec8
-rw-r--r--lib/tmpdir.gemspec4
-rw-r--r--lib/tmpdir.rb30
-rw-r--r--lib/tracer.rb292
-rw-r--r--lib/tracer/tracer.gemspec25
-rw-r--r--lib/tsort.gemspec2
-rw-r--r--lib/tsort.rb20
-rw-r--r--lib/un.gemspec5
-rw-r--r--lib/un.rb47
-rw-r--r--lib/unicode_normalize/normalize.rb2
-rw-r--r--lib/unicode_normalize/tables.rb228
-rw-r--r--lib/uri.rb5
-rw-r--r--lib/uri/common.rb82
-rw-r--r--lib/uri/file.rb8
-rw-r--r--lib/uri/ftp.rb3
-rw-r--r--lib/uri/generic.rb49
-rw-r--r--lib/uri/http.rb42
-rw-r--r--lib/uri/https.rb3
-rw-r--r--lib/uri/ldap.rb2
-rw-r--r--lib/uri/ldaps.rb3
-rw-r--r--lib/uri/mailto.rb4
-rw-r--r--lib/uri/rfc2396_parser.rb24
-rw-r--r--lib/uri/rfc3986_parser.rb17
-rw-r--r--lib/uri/uri.gemspec2
-rw-r--r--lib/uri/version.rb2
-rw-r--r--lib/uri/ws.rb3
-rw-r--r--lib/uri/wss.rb3
-rw-r--r--lib/weakref.rb5
-rw-r--r--lib/yaml.rb14
-rw-r--r--lib/yaml/store.rb2
-rw-r--r--lib/yaml/yaml.gemspec2
-rwxr-xr-xlibexec/bundle36
-rwxr-xr-xlibexec/bundler2
-rwxr-xr-xlibexec/erb12
-rwxr-xr-xlibexec/rdoc1
-rwxr-xr-xlibexec/syntax_suggest7
-rw-r--r--load.c1091
-rw-r--r--localeinit.c12
-rw-r--r--main.c28
-rw-r--r--man/bundle-add.166
-rw-r--r--man/bundle-binstubs.142
-rw-r--r--man/bundle-cache.155
-rw-r--r--man/bundle-check.131
-rw-r--r--man/bundle-clean.124
-rw-r--r--man/bundle-config.1488
-rw-r--r--man/bundle-doctor.144
-rw-r--r--man/bundle-exec.1165
-rw-r--r--man/bundle-gem.1102
-rw-r--r--man/bundle-info.120
-rw-r--r--man/bundle-init.125
-rw-r--r--man/bundle-inject.133
-rw-r--r--man/bundle-install.1338
-rw-r--r--man/bundle-list.150
-rw-r--r--man/bundle-lock.184
-rw-r--r--man/bundle-open.132
-rw-r--r--man/bundle-outdated.1155
-rw-r--r--man/bundle-platform.161
-rw-r--r--man/bundle-pristine.134
-rw-r--r--man/bundle-remove.131
-rw-r--r--man/bundle-show.123
-rw-r--r--man/bundle-update.1394
-rw-r--r--man/bundle-viz.139
-rw-r--r--man/bundle.1136
-rw-r--r--man/gemfile.5686
-rw-r--r--man/irb.149
-rw-r--r--man/ruby.144
-rw-r--r--marshal.c1921
-rw-r--r--marshal.rb40
-rw-r--r--math.c696
-rw-r--r--memory_view.c37
-rw-r--r--method.h32
-rw-r--r--mini_builtin.c15
-rwxr-xr-xmisc/expand_tabs.rb59
-rwxr-xr-xmisc/lldb_cruby.py292
-rw-r--r--misc/lldb_disasm.py29
-rw-r--r--misc/lldb_rb/commands/command_template.py30
-rw-r--r--misc/lldb_rb/commands/heap_page_command.py26
-rw-r--r--misc/lldb_rb/commands/rclass_ext_command.py14
-rw-r--r--misc/lldb_rb/constants.py4
-rw-r--r--misc/lldb_rb/rb_base_command.py69
-rw-r--r--misc/lldb_yjit.py47
-rw-r--r--misc/rb_optparse.bash5
-rw-r--r--[-rwxr-xr-x]misc/rb_optparse.zsh13
-rw-r--r--missing/dtoa.c111
-rw-r--r--missing/dup2.c60
-rw-r--r--missing/erf.c15
-rw-r--r--missing/finite.c9
-rw-r--r--missing/flock.c9
-rw-r--r--missing/isinf.c69
-rw-r--r--missing/isnan.c32
-rw-r--r--missing/langinfo.c2
-rw-r--r--missing/signbit.c19
-rw-r--r--missing/tgamma.c15
-rw-r--r--mjit.c1797
-rw-r--r--mjit.h149
-rw-r--r--mjit.rb37
-rw-r--r--mjit_c.c43
-rw-r--r--mjit_c.h97
-rw-r--r--mjit_c.rb807
-rw-r--r--mjit_compile.c594
-rw-r--r--mjit_worker.c1446
-rw-r--r--nilclass.rb25
-rw-r--r--node.c1524
-rw-r--r--node.h96
-rw-r--r--numeric.c4906
-rw-r--r--numeric.rb405
-rw-r--r--object.c2308
-rw-r--r--pack.c2355
-rw-r--r--pack.rb280
-rw-r--r--parse.y1964
-rw-r--r--prelude.rb9
-rw-r--r--probes_helper.h14
-rw-r--r--proc.c1290
-rw-r--r--process.c2309
-rw-r--r--ractor.c409
-rw-r--r--ractor.rb24
-rw-r--r--ractor_core.h129
-rw-r--r--random.c687
-rw-r--r--range.c1949
-rw-r--r--rational.c871
-rw-r--r--re.c2949
-rw-r--r--regcomp.c44
-rw-r--r--regenc.c15
-rw-r--r--regenc.h15
-rw-r--r--regerror.c4
-rw-r--r--regexec.c841
-rw-r--r--regint.h63
-rw-r--r--regparse.c19
-rw-r--r--ruby-runner.c56
-rw-r--r--ruby.c2356
-rw-r--r--ruby_assert.h1
-rw-r--r--rubystub.c29
-rw-r--r--sample/coverage.rb2
-rw-r--r--sample/drb/README.ja.rdoc2
-rw-r--r--sample/drb/README.rdoc4
-rw-r--r--sample/drb/dchats.rb2
-rw-r--r--sample/exyacc.rb2
-rw-r--r--sample/from.rb2
-rw-r--r--sample/getoptlong/abbrev.rb9
-rw-r--r--sample/getoptlong/aliases.rb8
-rw-r--r--sample/getoptlong/argv.rb12
-rw-r--r--sample/getoptlong/each.rb12
-rw-r--r--sample/getoptlong/fibonacci.rb62
-rw-r--r--sample/getoptlong/permute.rb12
-rw-r--r--sample/getoptlong/require_order.rb13
-rw-r--r--sample/getoptlong/return_in_order.rb13
-rw-r--r--sample/getoptlong/simple.rb7
-rw-r--r--sample/getoptlong/types.rb10
-rwxr-xr-xsample/mine.rb8
-rw-r--r--sample/mpart.rb44
-rw-r--r--sample/openssl/c_rehash.rb3
-rw-r--r--sample/openssl/cert2text.rb7
-rw-r--r--sample/openssl/certstore.rb7
-rw-r--r--sample/openssl/echo_cli.rb2
-rw-r--r--sample/openssl/echo_svr.rb8
-rw-r--r--sample/openssl/gen_csr.rb14
-rw-r--r--sample/openssl/smime_read.rb11
-rw-r--r--sample/openssl/smime_write.rb15
-rwxr-xr-xsample/rss/blend.rb79
-rwxr-xr-xsample/rss/convert.rb69
-rwxr-xr-xsample/rss/list_description.rb91
-rwxr-xr-xsample/rss/re_read.rb64
-rwxr-xr-xsample/rss/rss_recent.rb85
-rw-r--r--sample/testunit/adder.rb13
-rw-r--r--sample/testunit/subtracter.rb12
-rw-r--r--sample/testunit/tc_adder.rb18
-rw-r--r--sample/testunit/tc_subtracter.rb18
-rw-r--r--sample/testunit/ts_examples.rb7
-rw-r--r--sample/trick2015/kinaba/entry.rb4
-rw-r--r--sample/trick2018/01-kinaba/remarks.markdown2
-rw-r--r--sample/trick2018/02-mame/entry.rb4
-rw-r--r--sample/trick2022/01-tompng/Gemfile2
-rw-r--r--sample/trick2022/01-tompng/Gemfile.lock13
-rw-r--r--sample/trick2022/01-tompng/authors.markdown3
-rw-r--r--sample/trick2022/01-tompng/entry.rb40
-rw-r--r--sample/trick2022/01-tompng/remarks.markdown51
-rw-r--r--sample/trick2022/02-tompng/authors.markdown3
-rw-r--r--sample/trick2022/02-tompng/entry.rb32
-rw-r--r--sample/trick2022/02-tompng/remarks.markdown32
-rw-r--r--sample/trick2022/03-mame/authors.markdown3
-rw-r--r--sample/trick2022/03-mame/entry.rb27
-rw-r--r--sample/trick2022/03-mame/remarks.markdown96
-rw-r--r--sample/trick2022/03-mame/test.txt13
-rw-r--r--sample/trick2022/README.md14
-rw-r--r--sample/uumerge.rb2
-rw-r--r--scheduler.c591
-rw-r--r--shape.c825
-rw-r--r--shape.h232
-rw-r--r--signal.c517
-rw-r--r--siphash.c105
-rw-r--r--sparc.c4
-rw-r--r--spec/README.md34
-rw-r--r--spec/bundler/bundler/bundler_spec.rb248
-rw-r--r--spec/bundler/bundler/cli_spec.rb110
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb26
-rw-r--r--spec/bundler/bundler/definition_spec.rb95
-rw-r--r--spec/bundler/bundler/dep_proxy_spec.rb22
-rw-r--r--spec/bundler/bundler/dependency_spec.rb157
-rw-r--r--spec/bundler/bundler/digest_spec.rb24
-rw-r--r--spec/bundler/bundler/dsl_spec.rb83
-rw-r--r--spec/bundler/bundler/endpoint_specification_spec.rb48
-rw-r--r--spec/bundler/bundler/env_spec.rb41
-rw-r--r--spec/bundler/bundler/fetcher/dependency_spec.rb18
-rw-r--r--spec/bundler/bundler/fetcher/downloader_spec.rb46
-rw-r--r--spec/bundler/bundler/fetcher/index_spec.rb25
-rw-r--r--spec/bundler/bundler/fetcher_spec.rb34
-rw-r--r--spec/bundler/bundler/friendly_errors_spec.rb14
-rw-r--r--spec/bundler/bundler/gem_helper_spec.rb81
-rw-r--r--spec/bundler/bundler/gem_version_promoter_spec.rb246
-rw-r--r--spec/bundler/bundler/installer/gem_installer_spec.rb18
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb39
-rw-r--r--spec/bundler/bundler/installer/spec_installation_spec.rb4
-rw-r--r--spec/bundler/bundler/plugin/dsl_spec.rb2
-rw-r--r--spec/bundler/bundler/plugin/index_spec.rb22
-rw-r--r--spec/bundler/bundler/plugin/installer_spec.rb2
-rw-r--r--spec/bundler/bundler/plugin_spec.rb52
-rw-r--r--spec/bundler/bundler/psyched_yaml_spec.rb9
-rw-r--r--spec/bundler/bundler/remote_specification_spec.rb2
-rw-r--r--spec/bundler/bundler/resolver/candidate_spec.rb21
-rw-r--r--spec/bundler/bundler/ruby_dsl_spec.rb27
-rw-r--r--spec/bundler/bundler/ruby_version_spec.rb46
-rw-r--r--spec/bundler/bundler/rubygems_integration_spec.rb34
-rw-r--r--spec/bundler/bundler/settings_spec.rb25
-rw-r--r--spec/bundler/bundler/shared_helpers_spec.rb35
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb61
-rw-r--r--spec/bundler/bundler/source/git_spec.rb49
-rw-r--r--spec/bundler/bundler/source/rubygems_spec.rb14
-rw-r--r--spec/bundler/bundler/source_list_spec.rb78
-rw-r--r--spec/bundler/bundler/source_spec.rb38
-rw-r--r--spec/bundler/bundler/stub_specification_spec.rb27
-rw-r--r--spec/bundler/bundler/ui/shell_spec.rb19
-rw-r--r--spec/bundler/bundler/vendored_persistent_spec.rb77
-rw-r--r--spec/bundler/bundler/version_ranges_spec.rb40
-rw-r--r--spec/bundler/bundler/worker_spec.rb47
-rw-r--r--spec/bundler/cache/gems_spec.rb42
-rw-r--r--spec/bundler/cache/git_spec.rb88
-rw-r--r--spec/bundler/cache/path_spec.rb12
-rw-r--r--spec/bundler/commands/add_spec.rb58
-rw-r--r--spec/bundler/commands/binstubs_spec.rb102
-rw-r--r--spec/bundler/commands/cache_spec.rb110
-rw-r--r--spec/bundler/commands/check_spec.rb228
-rw-r--r--spec/bundler/commands/clean_spec.rb29
-rw-r--r--spec/bundler/commands/config_spec.rb128
-rw-r--r--spec/bundler/commands/doctor_spec.rb40
-rw-r--r--spec/bundler/commands/exec_spec.rb293
-rw-r--r--spec/bundler/commands/fund_spec.rb16
-rw-r--r--spec/bundler/commands/help_spec.rb20
-rw-r--r--spec/bundler/commands/info_spec.rb84
-rw-r--r--spec/bundler/commands/init_spec.rb38
-rw-r--r--spec/bundler/commands/inject_spec.rb4
-rw-r--r--spec/bundler/commands/install_spec.rb568
-rw-r--r--spec/bundler/commands/lock_spec.rb810
-rw-r--r--spec/bundler/commands/newgem_spec.rb825
-rw-r--r--spec/bundler/commands/open_spec.rb61
-rw-r--r--spec/bundler/commands/outdated_spec.rb674
-rw-r--r--spec/bundler/commands/platform_spec.rb1307
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb66
-rw-r--r--spec/bundler/commands/pristine_spec.rb14
-rw-r--r--spec/bundler/commands/remove_spec.rb97
-rw-r--r--spec/bundler/commands/show_spec.rb6
-rw-r--r--spec/bundler/commands/update_spec.rb1116
-rw-r--r--spec/bundler/commands/viz_spec.rb6
-rw-r--r--spec/bundler/install/allow_offline_install_spec.rb7
-rw-r--r--spec/bundler/install/binstubs_spec.rb4
-rw-r--r--spec/bundler/install/bundler_spec.rb137
-rw-r--r--spec/bundler/install/deploy_spec.rb223
-rw-r--r--spec/bundler/install/failure_spec.rb97
-rw-r--r--spec/bundler/install/gemfile/eval_gemfile_spec.rb41
-rw-r--r--spec/bundler/install/gemfile/force_ruby_platform_spec.rb118
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb296
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb245
-rw-r--r--spec/bundler/install/gemfile/groups_spec.rb55
-rw-r--r--spec/bundler/install/gemfile/install_if_spec.rb2
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb293
-rw-r--r--spec/bundler/install/gemfile/platform_spec.rb266
-rw-r--r--spec/bundler/install/gemfile/ruby_spec.rb40
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb1483
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb839
-rw-r--r--spec/bundler/install/gemfile_spec.rb10
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb136
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb122
-rw-r--r--spec/bundler/install/gems/flex_spec.rb158
-rw-r--r--spec/bundler/install/gems/fund_spec.rb43
-rw-r--r--spec/bundler/install/gems/native_extensions_spec.rb10
-rw-r--r--spec/bundler/install/gems/post_install_spec.rb2
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb384
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb231
-rw-r--r--spec/bundler/install/gems/sudo_spec.rb190
-rw-r--r--spec/bundler/install/gemspecs_spec.rb16
-rw-r--r--spec/bundler/install/git_spec.rb109
-rw-r--r--spec/bundler/install/global_cache_spec.rb29
-rw-r--r--spec/bundler/install/path_spec.rb24
-rw-r--r--spec/bundler/install/prereleases_spec.rb6
-rw-r--r--spec/bundler/install/process_lock_spec.rb22
-rw-r--r--spec/bundler/install/redownload_spec.rb1
-rw-r--r--spec/bundler/install/yanked_spec.rb168
-rw-r--r--spec/bundler/lock/git_spec.rb128
-rw-r--r--spec/bundler/lock/lockfile_spec.rb554
-rw-r--r--spec/bundler/other/ext_spec.rb4
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb345
-rw-r--r--spec/bundler/other/platform_spec.rb1272
-rw-r--r--spec/bundler/plugins/command_spec.rb6
-rw-r--r--spec/bundler/plugins/install_spec.rb66
-rw-r--r--spec/bundler/plugins/source/example_spec.rb22
-rw-r--r--spec/bundler/quality_es_spec.rb4
-rw-r--r--spec/bundler/quality_spec.rb68
-rw-r--r--spec/bundler/realworld/dependency_api_spec.rb10
-rw-r--r--spec/bundler/realworld/double_check_spec.rb6
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb369
-rw-r--r--spec/bundler/realworld/ffi_spec.rb57
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock5
-rw-r--r--spec/bundler/realworld/gemfile_source_header_spec.rb10
-rw-r--r--spec/bundler/realworld/git_spec.rb11
-rw-r--r--spec/bundler/realworld/mirror_probe_spec.rb45
-rw-r--r--spec/bundler/realworld/parallel_spec.rb4
-rw-r--r--spec/bundler/realworld/slow_perf_spec.rb33
-rw-r--r--spec/bundler/resolver/basic_spec.rb74
-rw-r--r--spec/bundler/resolver/platform_spec.rb263
-rw-r--r--spec/bundler/runtime/executable_spec.rb1
-rw-r--r--spec/bundler/runtime/gem_tasks_spec.rb6
-rw-r--r--spec/bundler/runtime/inline_spec.rb258
-rw-r--r--spec/bundler/runtime/load_spec.rb2
-rw-r--r--spec/bundler/runtime/platform_spec.rb300
-rw-r--r--spec/bundler/runtime/require_spec.rb19
-rw-r--r--spec/bundler/runtime/self_management_spec.rb126
-rw-r--r--spec/bundler/runtime/setup_spec.rb437
-rw-r--r--spec/bundler/runtime/with_unbundled_env_spec.rb2
-rw-r--r--spec/bundler/spec_helper.rb54
-rw-r--r--spec/bundler/support/artifice/compact_index.rb118
-rw-r--r--spec/bundler/support/artifice/compact_index_api_missing.rb13
-rw-r--r--spec/bundler/support/artifice/compact_index_basic_authentication.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_checksum_mismatch.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_concurrent_download.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_creds_diff_host.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_extra.rb35
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_api.rb50
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_api_missing.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_extra_missing.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_forbidden.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_host_redirect.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_no_gem.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_partial_update_no_etag_not_incremental.rb40
-rw-r--r--spec/bundler/support/artifice/compact_index_precompiled_before.rb25
-rw-r--r--spec/bundler/support/artifice/compact_index_range_not_satisfiable.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_rate_limited.rb8
-rw-r--r--spec/bundler/support/artifice/compact_index_redirects.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb8
-rw-r--r--spec/bundler/support/artifice/compact_index_wrong_dependencies.rb6
-rw-r--r--spec/bundler/support/artifice/compact_index_wrong_gem_checksum.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint.rb95
-rw-r--r--spec/bundler/support/artifice/endpoint_500.rb7
-rw-r--r--spec/bundler/support/artifice/endpoint_api_forbidden.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_api_missing.rb18
-rw-r--r--spec/bundler/support/artifice/endpoint_basic_authentication.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_creds_diff_host.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_extra.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_extra_api.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_extra_missing.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_fallback.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_host_redirect.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_marshal_fail.rb11
-rw-r--r--spec/bundler/support/artifice/endpoint_marshal_fail_basic_authentication.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_mirror_source.rb4
-rw-r--r--spec/bundler/support/artifice/endpoint_redirect.rb6
-rw-r--r--spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb8
-rw-r--r--spec/bundler/support/artifice/endpoint_timeout.rb6
-rw-r--r--spec/bundler/support/artifice/fail.rb11
-rw-r--r--spec/bundler/support/artifice/helpers/artifice.rb30
-rw-r--r--spec/bundler/support/artifice/helpers/compact_index.rb118
-rw-r--r--spec/bundler/support/artifice/helpers/compact_index_extra.rb33
-rw-r--r--spec/bundler/support/artifice/helpers/compact_index_extra_api.rb48
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint.rb112
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint_extra.rb29
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint_fallback.rb15
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint_marshal_fail.rb9
-rw-r--r--spec/bundler/support/artifice/helpers/rack_request.rb100
-rw-r--r--spec/bundler/support/artifice/used_cassettes.txt20908
-rw-r--r--spec/bundler/support/artifice/vcr.rb48
-rw-r--r--spec/bundler/support/artifice/windows.rb11
-rw-r--r--spec/bundler/support/builders.rb120
-rw-r--r--spec/bundler/support/bundle.rb10
-rw-r--r--spec/bundler/support/filters.rb10
-rw-r--r--spec/bundler/support/hax.rb65
-rw-r--r--spec/bundler/support/helpers.rb113
-rw-r--r--spec/bundler/support/indexes.rb40
-rw-r--r--spec/bundler/support/matchers.rb108
-rw-r--r--spec/bundler/support/path.rb79
-rw-r--r--spec/bundler/support/platforms.rb40
-rw-r--r--spec/bundler/support/rubygems_ext.rb111
-rw-r--r--spec/bundler/support/rubygems_version_manager.rb15
-rw-r--r--spec/bundler/support/sometimes.rb57
-rw-r--r--spec/bundler/support/streams.rb19
-rw-r--r--spec/bundler/support/sudo.rb18
-rw-r--r--spec/bundler/update/gems/fund_spec.rb16
-rw-r--r--spec/bundler/update/git_spec.rb68
-rw-r--r--spec/bundler/update/path_spec.rb1
-rw-r--r--spec/default.mspec22
-rw-r--r--spec/mspec/.rspec1
-rw-r--r--spec/mspec/Gemfile2
-rw-r--r--spec/mspec/Gemfile.lock25
-rw-r--r--spec/mspec/README.md2
-rwxr-xr-xspec/mspec/bin/mspec2
-rwxr-xr-xspec/mspec/lib/mspec/commands/mkspec.rb16
-rwxr-xr-xspec/mspec/lib/mspec/commands/mspec.rb6
-rw-r--r--spec/mspec/lib/mspec/expectations/expectations.rb4
-rw-r--r--spec/mspec/lib/mspec/expectations/should.rb10
-rw-r--r--spec/mspec/lib/mspec/guards/platform.rb4
-rw-r--r--spec/mspec/lib/mspec/guards/superuser.rb10
-rw-r--r--spec/mspec/lib/mspec/guards/version.rb28
-rw-r--r--spec/mspec/lib/mspec/helpers/datetime.rb1
-rw-r--r--spec/mspec/lib/mspec/helpers/numeric.rb4
-rw-r--r--spec/mspec/lib/mspec/helpers/ruby_exe.rb36
-rw-r--r--spec/mspec/lib/mspec/helpers/warning.rb2
-rw-r--r--spec/mspec/lib/mspec/matchers/base.rb30
-rw-r--r--spec/mspec/lib/mspec/matchers/match_yaml.rb6
-rw-r--r--spec/mspec/lib/mspec/matchers/output.rb8
-rw-r--r--spec/mspec/lib/mspec/matchers/raise_error.rb8
-rw-r--r--spec/mspec/lib/mspec/runner/actions/leakchecker.rb3
-rw-r--r--spec/mspec/lib/mspec/runner/actions/timeout.rb37
-rw-r--r--spec/mspec/lib/mspec/runner/context.rb1
-rw-r--r--spec/mspec/lib/mspec/runner/exception.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/base.rb26
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/junit.rb6
-rw-r--r--spec/mspec/lib/mspec/runner/mspec.rb8
-rw-r--r--spec/mspec/lib/mspec/runner/shared.rb8
-rw-r--r--spec/mspec/lib/mspec/utils/name_map.rb7
-rw-r--r--spec/mspec/lib/mspec/utils/options.rb15
-rw-r--r--spec/mspec/lib/mspec/utils/script.rb20
-rw-r--r--spec/mspec/lib/mspec/utils/warnings.rb2
-rw-r--r--spec/mspec/spec/commands/mkspec_spec.rb196
-rw-r--r--spec/mspec/spec/commands/mspec_ci_spec.rb72
-rw-r--r--spec/mspec/spec/commands/mspec_run_spec.rb74
-rw-r--r--spec/mspec/spec/commands/mspec_spec.rb106
-rw-r--r--spec/mspec/spec/commands/mspec_tag_spec.rb170
-rw-r--r--spec/mspec/spec/expectations/expectations_spec.rb18
-rw-r--r--spec/mspec/spec/expectations/should.rb73
-rw-r--r--spec/mspec/spec/expectations/should_spec.rb18
-rw-r--r--spec/mspec/spec/fixtures/should.rb75
-rw-r--r--spec/mspec/spec/guards/block_device_spec.rb26
-rw-r--r--spec/mspec/spec/guards/bug_spec.rb84
-rw-r--r--spec/mspec/spec/guards/conflict_spec.rb30
-rw-r--r--spec/mspec/spec/guards/endian_spec.rb34
-rw-r--r--spec/mspec/spec/guards/feature_spec.rb82
-rw-r--r--spec/mspec/spec/guards/guard_spec.rb218
-rw-r--r--spec/mspec/spec/guards/platform_spec.rb188
-rw-r--r--spec/mspec/spec/guards/quarantine_spec.rb20
-rw-r--r--spec/mspec/spec/guards/superuser_spec.rb22
-rw-r--r--spec/mspec/spec/guards/support_spec.rb28
-rw-r--r--spec/mspec/spec/guards/user_spec.rb10
-rw-r--r--spec/mspec/spec/guards/version_spec.rb92
-rw-r--r--spec/mspec/spec/helpers/argf_spec.rb16
-rw-r--r--spec/mspec/spec/helpers/argv_spec.rb10
-rw-r--r--spec/mspec/spec/helpers/datetime_spec.rb18
-rw-r--r--spec/mspec/spec/helpers/fixture_spec.rb8
-rw-r--r--spec/mspec/spec/helpers/flunk_spec.rb10
-rw-r--r--spec/mspec/spec/helpers/fs_spec.rb60
-rw-r--r--spec/mspec/spec/helpers/io_spec.rb48
-rw-r--r--spec/mspec/spec/helpers/mock_to_path_spec.rb14
-rw-r--r--spec/mspec/spec/helpers/numeric_spec.rb20
-rw-r--r--spec/mspec/spec/helpers/ruby_exe_spec.rb165
-rw-r--r--spec/mspec/spec/helpers/scratch_spec.rb10
-rw-r--r--spec/mspec/spec/helpers/suppress_warning_spec.rb4
-rw-r--r--spec/mspec/spec/helpers/tmp_spec.rb10
-rw-r--r--spec/mspec/spec/integration/interpreter_spec.rb8
-rw-r--r--spec/mspec/spec/integration/object_methods_spec.rb6
-rw-r--r--spec/mspec/spec/integration/run_spec.rb34
-rw-r--r--spec/mspec/spec/integration/tag_spec.rb10
-rw-r--r--spec/mspec/spec/matchers/base_spec.rb140
-rw-r--r--spec/mspec/spec/matchers/be_an_instance_of_spec.rb22
-rw-r--r--spec/mspec/spec/matchers/be_ancestor_of_spec.rb10
-rw-r--r--spec/mspec/spec/matchers/be_close_spec.rb24
-rw-r--r--spec/mspec/spec/matchers/be_computed_by_spec.rb14
-rw-r--r--spec/mspec/spec/matchers/be_empty_spec.rb10
-rw-r--r--spec/mspec/spec/matchers/be_false_spec.rb16
-rw-r--r--spec/mspec/spec/matchers/be_kind_of_spec.rb22
-rw-r--r--spec/mspec/spec/matchers/be_nan_spec.rb12
-rw-r--r--spec/mspec/spec/matchers/be_nil_spec.rb14
-rw-r--r--spec/mspec/spec/matchers/be_true_or_false_spec.rb8
-rw-r--r--spec/mspec/spec/matchers/be_true_spec.rb16
-rw-r--r--spec/mspec/spec/matchers/block_caller_spec.rb6
-rw-r--r--spec/mspec/spec/matchers/complain_spec.rb43
-rw-r--r--spec/mspec/spec/matchers/eql_spec.rb22
-rw-r--r--spec/mspec/spec/matchers/equal_element_spec.rb78
-rw-r--r--spec/mspec/spec/matchers/equal_spec.rb20
-rw-r--r--spec/mspec/spec/matchers/have_class_variable_spec.rb18
-rw-r--r--spec/mspec/spec/matchers/have_constant_spec.rb14
-rw-r--r--spec/mspec/spec/matchers/have_instance_method_spec.rb20
-rw-r--r--spec/mspec/spec/matchers/have_instance_variable_spec.rb18
-rw-r--r--spec/mspec/spec/matchers/have_method_spec.rb24
-rw-r--r--spec/mspec/spec/matchers/have_private_instance_method_spec.rb20
-rw-r--r--spec/mspec/spec/matchers/have_private_method_spec.rb16
-rw-r--r--spec/mspec/spec/matchers/have_protected_instance_method_spec.rb20
-rw-r--r--spec/mspec/spec/matchers/have_public_instance_method_spec.rb20
-rw-r--r--spec/mspec/spec/matchers/have_singleton_method_spec.rb16
-rw-r--r--spec/mspec/spec/matchers/include_any_of_spec.rb26
-rw-r--r--spec/mspec/spec/matchers/include_spec.rb22
-rw-r--r--spec/mspec/spec/matchers/infinity_spec.rb18
-rw-r--r--spec/mspec/spec/matchers/match_yaml_spec.rb22
-rw-r--r--spec/mspec/spec/matchers/output_spec.rb48
-rw-r--r--spec/mspec/spec/matchers/output_to_fd_spec.rb30
-rw-r--r--spec/mspec/spec/matchers/raise_error_spec.rb90
-rw-r--r--spec/mspec/spec/matchers/respond_to_spec.rb26
-rw-r--r--spec/mspec/spec/matchers/signed_zero_spec.rb18
-rw-r--r--spec/mspec/spec/mocks/mock_spec.rb238
-rw-r--r--spec/mspec/spec/mocks/proxy_spec.rb196
-rw-r--r--spec/mspec/spec/runner/actions/filter_spec.rb44
-rw-r--r--spec/mspec/spec/runner/actions/tag_spec.rb144
-rw-r--r--spec/mspec/spec/runner/actions/taglist_spec.rb70
-rw-r--r--spec/mspec/spec/runner/actions/tagpurge_spec.rb66
-rw-r--r--spec/mspec/spec/runner/actions/tally_spec.rb167
-rw-r--r--spec/mspec/spec/runner/actions/timer_spec.rb22
-rw-r--r--spec/mspec/spec/runner/context_spec.rb342
-rw-r--r--spec/mspec/spec/runner/example_spec.rb50
-rw-r--r--spec/mspec/spec/runner/exception_spec.rb50
-rw-r--r--spec/mspec/spec/runner/filters/match_spec.rb16
-rw-r--r--spec/mspec/spec/runner/filters/profile_spec.rb70
-rw-r--r--spec/mspec/spec/runner/filters/regexp_spec.rb18
-rw-r--r--spec/mspec/spec/runner/filters/tag_spec.rb48
-rw-r--r--spec/mspec/spec/runner/formatters/describe_spec.rb24
-rw-r--r--spec/mspec/spec/runner/formatters/dotted_spec.rb119
-rw-r--r--spec/mspec/spec/runner/formatters/file_spec.rb34
-rw-r--r--spec/mspec/spec/runner/formatters/html_spec.rb88
-rw-r--r--spec/mspec/spec/runner/formatters/junit_spec.rb100
-rw-r--r--spec/mspec/spec/runner/formatters/method_spec.rb69
-rw-r--r--spec/mspec/spec/runner/formatters/multi_spec.rb20
-rw-r--r--spec/mspec/spec/runner/formatters/specdoc_spec.rb30
-rw-r--r--spec/mspec/spec/runner/formatters/spinner_spec.rb32
-rw-r--r--spec/mspec/spec/runner/formatters/summary_spec.rb4
-rw-r--r--spec/mspec/spec/runner/formatters/unit_spec.rb33
-rw-r--r--spec/mspec/spec/runner/formatters/yaml_spec.rb79
-rw-r--r--spec/mspec/spec/runner/mspec_spec.rb287
-rw-r--r--spec/mspec/spec/runner/shared_spec.rb20
-rw-r--r--spec/mspec/spec/runner/tag_spec.rb96
-rw-r--r--spec/mspec/spec/spec_helper.rb21
-rw-r--r--spec/mspec/spec/utils/deprecate_spec.rb10
-rw-r--r--spec/mspec/spec/utils/name_map_spec.rb78
-rw-r--r--spec/mspec/spec/utils/options_spec.rb476
-rw-r--r--spec/mspec/spec/utils/script_spec.rb255
-rw-r--r--spec/mspec/spec/utils/version_spec.rb30
-rw-r--r--spec/mspec/tool/remove_old_guards.rb12
-rw-r--r--spec/mspec/tool/sync/sync-rubyspec.rb11
-rwxr-xr-xspec/mspec/tool/tag_from_output.rb33
-rw-r--r--spec/ruby/.mspec.constants3
-rw-r--r--spec/ruby/.rubocop.yml56
-rw-r--r--spec/ruby/.rubocop_todo.yml11
-rw-r--r--spec/ruby/CONTRIBUTING.md21
-rw-r--r--spec/ruby/README.md23
-rw-r--r--spec/ruby/command_line/backtrace_limit_spec.rb48
-rw-r--r--spec/ruby/command_line/dash_encoding_spec.rb8
-rw-r--r--spec/ruby/command_line/dash_r_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_e_spec.rb3
-rw-r--r--spec/ruby/command_line/dash_upper_s_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_upper_u_spec.rb6
-rw-r--r--spec/ruby/command_line/dash_upper_w_spec.rb42
-rw-r--r--spec/ruby/command_line/dash_v_spec.rb3
-rw-r--r--spec/ruby/command_line/dash_w_spec.rb4
-rw-r--r--spec/ruby/command_line/dash_x_spec.rb2
-rw-r--r--spec/ruby/command_line/error_message_spec.rb4
-rw-r--r--spec/ruby/command_line/feature_spec.rb18
-rw-r--r--spec/ruby/command_line/fixtures/backtrace.rb35
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_two_literals.rb2
-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb70
-rw-r--r--spec/ruby/command_line/syntax_error_spec.rb4
-rw-r--r--spec/ruby/core/array/clear_spec.rb20
-rw-r--r--spec/ruby/core/array/compact_spec.rb30
-rw-r--r--spec/ruby/core/array/concat_spec.rb58
-rw-r--r--spec/ruby/core/array/deconstruct_spec.rb10
-rw-r--r--spec/ruby/core/array/delete_at_spec.rb22
-rw-r--r--spec/ruby/core/array/delete_if_spec.rb16
-rw-r--r--spec/ruby/core/array/delete_spec.rb22
-rw-r--r--spec/ruby/core/array/difference_spec.rb28
-rw-r--r--spec/ruby/core/array/drop_spec.rb13
-rw-r--r--spec/ruby/core/array/drop_while_spec.rb13
-rw-r--r--spec/ruby/core/array/each_spec.rb35
-rw-r--r--spec/ruby/core/array/element_set_spec.rb144
-rw-r--r--spec/ruby/core/array/fill_spec.rb26
-rw-r--r--spec/ruby/core/array/filter_spec.rb18
-rw-r--r--spec/ruby/core/array/fixtures/classes.rb62
-rw-r--r--spec/ruby/core/array/flatten_spec.rb10
-rw-r--r--spec/ruby/core/array/intersect_spec.rb17
-rw-r--r--spec/ruby/core/array/intersection_spec.rb16
-rw-r--r--spec/ruby/core/array/keep_if_spec.rb1
-rw-r--r--spec/ruby/core/array/multiply_spec.rb40
-rw-r--r--spec/ruby/core/array/pack/a_spec.rb11
-rw-r--r--spec/ruby/core/array/pack/b_spec.rb7
-rw-r--r--spec/ruby/core/array/pack/c_spec.rb14
-rw-r--r--spec/ruby/core/array/pack/h_spec.rb5
-rw-r--r--spec/ruby/core/array/pack/m_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/p_spec.rb24
-rw-r--r--spec/ruby/core/array/pack/shared/basic.rb52
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb74
-rw-r--r--spec/ruby/core/array/pack/shared/integer.rb96
-rw-r--r--spec/ruby/core/array/pack/shared/numeric_basic.rb10
-rw-r--r--spec/ruby/core/array/pack/shared/taint.rb33
-rw-r--r--spec/ruby/core/array/pack/shared/unicode.rb14
-rw-r--r--spec/ruby/core/array/pack/u_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/w_spec.rb14
-rw-r--r--spec/ruby/core/array/pack/x_spec.rb1
-rw-r--r--spec/ruby/core/array/pack/z_spec.rb10
-rw-r--r--spec/ruby/core/array/plus_spec.rb16
-rw-r--r--spec/ruby/core/array/pop_spec.rb52
-rw-r--r--spec/ruby/core/array/sample_spec.rb26
-rw-r--r--spec/ruby/core/array/shared/clone.rb24
-rw-r--r--spec/ruby/core/array/shared/collect.rb31
-rw-r--r--spec/ruby/core/array/shared/inspect.rb26
-rw-r--r--spec/ruby/core/array/shared/join.rb85
-rw-r--r--spec/ruby/core/array/shared/slice.rb397
-rw-r--r--spec/ruby/core/array/shared/unshift.rb18
-rw-r--r--spec/ruby/core/array/shift_spec.rb16
-rw-r--r--spec/ruby/core/array/slice_spec.rb106
-rw-r--r--spec/ruby/core/array/sum_spec.rb29
-rw-r--r--spec/ruby/core/array/take_spec.rb13
-rw-r--r--spec/ruby/core/array/take_while_spec.rb13
-rw-r--r--spec/ruby/core/array/to_h_spec.rb72
-rw-r--r--spec/ruby/core/array/union_spec.rb26
-rw-r--r--spec/ruby/core/array/uniq_spec.rb76
-rw-r--r--spec/ruby/core/array/values_at_spec.rb17
-rw-r--r--spec/ruby/core/array/zip_spec.rb6
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb68
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb59
-rw-r--r--spec/ruby/core/binding/eval_spec.rb16
-rw-r--r--spec/ruby/core/binding/source_location_spec.rb10
-rw-r--r--spec/ruby/core/builtin_constants/builtin_constants_spec.rb18
-rw-r--r--spec/ruby/core/class/attached_object_spec.rb31
-rw-r--r--spec/ruby/core/class/subclasses_spec.rb60
-rw-r--r--spec/ruby/core/comparable/clamp_spec.rb78
-rw-r--r--spec/ruby/core/complex/comparision_spec.rb27
-rw-r--r--spec/ruby/core/complex/comparison_spec.rb25
-rw-r--r--spec/ruby/core/complex/polar_spec.rb16
-rw-r--r--spec/ruby/core/conditionvariable/broadcast_spec.rb (renamed from spec/ruby/library/conditionvariable/broadcast_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/marshal_dump_spec.rb (renamed from spec/ruby/library/conditionvariable/marshal_dump_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/signal_spec.rb (renamed from spec/ruby/library/conditionvariable/signal_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/wait_spec.rb (renamed from spec/ruby/library/conditionvariable/wait_spec.rb)0
-rw-r--r--spec/ruby/core/data/constants_spec.rb14
-rw-r--r--spec/ruby/core/dir/children_spec.rb102
-rw-r--r--spec/ruby/core/dir/each_child_spec.rb77
-rw-r--r--spec/ruby/core/dir/entries_spec.rb6
-rw-r--r--spec/ruby/core/dir/fixtures/common.rb32
-rw-r--r--spec/ruby/core/dir/foreach_spec.rb12
-rw-r--r--spec/ruby/core/dir/glob_spec.rb91
-rw-r--r--spec/ruby/core/dir/home_spec.rb45
-rw-r--r--spec/ruby/core/dir/mkdir_spec.rb18
-rw-r--r--spec/ruby/core/dir/read_spec.rb33
-rw-r--r--spec/ruby/core/dir/shared/chroot.rb9
-rw-r--r--spec/ruby/core/dir/shared/glob.rb110
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb2
-rw-r--r--spec/ruby/core/encoding/converter/putback_spec.rb13
-rw-r--r--spec/ruby/core/encoding/default_external_spec.rb8
-rw-r--r--spec/ruby/core/encoding/list_spec.rb6
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb97
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb9
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb9
-rw-r--r--spec/ruby/core/enumerable/chain_spec.rb30
-rw-r--r--spec/ruby/core/enumerable/chunk_spec.rb5
-rw-r--r--spec/ruby/core/enumerable/compact_spec.rb11
-rw-r--r--spec/ruby/core/enumerable/each_cons_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/each_slice_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/filter_map_spec.rb34
-rw-r--r--spec/ruby/core/enumerable/filter_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb18
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb18
-rw-r--r--spec/ruby/core/enumerable/group_by_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb9
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb9
-rw-r--r--spec/ruby/core/enumerable/shared/collect.rb14
-rw-r--r--spec/ruby/core/enumerable/shared/entries.rb10
-rw-r--r--spec/ruby/core/enumerable/shared/inject.rb10
-rw-r--r--spec/ruby/core/enumerable/sum_spec.rb26
-rw-r--r--spec/ruby/core/enumerable/tally_spec.rb73
-rw-r--r--spec/ruby/core/enumerable/to_h_spec.rb80
-rw-r--r--spec/ruby/core/enumerable/uniq_spec.rb76
-rw-r--r--spec/ruby/core/enumerable/zip_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb17
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb17
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb26
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb26
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb14
-rw-r--r--spec/ruby/core/enumerator/chain/each_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/chain/initialize_spec.rb44
-rw-r--r--spec/ruby/core/enumerator/chain/inspect_spec.rb20
-rw-r--r--spec/ruby/core/enumerator/chain/rewind_spec.rb96
-rw-r--r--spec/ruby/core/enumerator/chain/size_spec.rb30
-rw-r--r--spec/ruby/core/enumerator/lazy/chunk_while_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/compact_spec.rb11
-rw-r--r--spec/ruby/core/enumerator/lazy/eager_spec.rb38
-rw-r--r--spec/ruby/core/enumerator/lazy/filter_map_spec.rb14
-rw-r--r--spec/ruby/core/enumerator/lazy/filter_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/lazy/lazy_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_after_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_before_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_when_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/with_index_spec.rb36
-rw-r--r--spec/ruby/core/enumerator/new_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/plus_spec.rb46
-rw-r--r--spec/ruby/core/enumerator/produce_spec.rb48
-rw-r--r--spec/ruby/core/enumerator/yielder/append_spec.rb24
-rw-r--r--spec/ruby/core/enumerator/yielder/to_proc_spec.rb20
-rw-r--r--spec/ruby/core/env/except_spec.rb36
-rw-r--r--spec/ruby/core/env/filter_spec.rb16
-rw-r--r--spec/ruby/core/env/merge_spec.rb6
-rw-r--r--spec/ruby/core/env/shared/update.rb38
-rw-r--r--spec/ruby/core/env/shift_spec.rb37
-rw-r--r--spec/ruby/core/env/slice_spec.rb40
-rw-r--r--spec/ruby/core/env/to_h_spec.rb100
-rw-r--r--spec/ruby/core/exception/errno_spec.rb9
-rw-r--r--spec/ruby/core/exception/frozen_error_spec.rb28
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb126
-rw-r--r--spec/ruby/core/exception/interrupt_spec.rb27
-rw-r--r--spec/ruby/core/exception/key_error_spec.rb22
-rw-r--r--spec/ruby/core/exception/name_error_spec.rb12
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb16
-rw-r--r--spec/ruby/core/exception/result_spec.rb8
-rw-r--r--spec/ruby/core/exception/signal_exception_spec.rb12
-rw-r--r--spec/ruby/core/exception/system_exit_spec.rb46
-rw-r--r--spec/ruby/core/exception/top_level_spec.rb46
-rw-r--r--spec/ruby/core/false/case_compare_spec.rb14
-rw-r--r--spec/ruby/core/false/to_s_spec.rb12
-rw-r--r--spec/ruby/core/fiber/blocking_spec.rb79
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb130
-rw-r--r--spec/ruby/core/fiber/shared/blocking.rb41
-rw-r--r--spec/ruby/core/fiber/storage_spec.rb117
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb74
-rw-r--r--spec/ruby/core/file/atime_spec.rb22
-rw-r--r--spec/ruby/core/file/basename_spec.rb15
-rw-r--r--spec/ruby/core/file/ctime_spec.rb4
-rw-r--r--spec/ruby/core/file/dirname_spec.rb16
-rw-r--r--spec/ruby/core/file/extname_spec.rb4
-rw-r--r--spec/ruby/core/file/mtime_spec.rb20
-rw-r--r--spec/ruby/core/file/open_spec.rb48
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb16
-rw-r--r--spec/ruby/core/file/shared/path.rb14
-rw-r--r--spec/ruby/core/file/shared/read.rb4
-rw-r--r--spec/ruby/core/file/utime_spec.rb45
-rw-r--r--spec/ruby/core/float/coerce_spec.rb4
-rw-r--r--spec/ruby/core/float/comparison_spec.rb71
-rw-r--r--spec/ruby/core/float/divide_spec.rb4
-rw-r--r--spec/ruby/core/float/divmod_spec.rb4
-rw-r--r--spec/ruby/core/float/gt_spec.rb21
-rw-r--r--spec/ruby/core/float/gte_spec.rb21
-rw-r--r--spec/ruby/core/float/lt_spec.rb21
-rw-r--r--spec/ruby/core/float/lte_spec.rb21
-rw-r--r--spec/ruby/core/float/minus_spec.rb2
-rw-r--r--spec/ruby/core/float/multiply_spec.rb2
-rw-r--r--spec/ruby/core/float/plus_spec.rb2
-rw-r--r--spec/ruby/core/float/round_spec.rb64
-rw-r--r--spec/ruby/core/float/shared/equal.rb21
-rw-r--r--spec/ruby/core/float/shared/to_i.rb4
-rw-r--r--spec/ruby/core/gc/auto_compact_spec.rb26
-rw-r--r--spec/ruby/core/gc/disable_spec.rb2
-rw-r--r--spec/ruby/core/gc/enable_spec.rb2
-rw-r--r--spec/ruby/core/gc/measure_total_time_spec.rb19
-rw-r--r--spec/ruby/core/gc/stat_spec.rb62
-rw-r--r--spec/ruby/core/gc/total_time_spec.rb15
-rw-r--r--spec/ruby/core/hash/constructor_spec.rb27
-rw-r--r--spec/ruby/core/hash/deconstruct_keys_spec.rb32
-rw-r--r--spec/ruby/core/hash/filter_spec.rb12
-rw-r--r--spec/ruby/core/hash/hash_spec.rb9
-rw-r--r--spec/ruby/core/hash/merge_spec.rb24
-rw-r--r--spec/ruby/core/hash/rehash_spec.rb18
-rw-r--r--spec/ruby/core/hash/reject_spec.rb7
-rw-r--r--spec/ruby/core/hash/ruby2_keywords_hash_spec.rb96
-rw-r--r--spec/ruby/core/hash/shared/eql.rb84
-rw-r--r--spec/ruby/core/hash/shared/to_s.rb17
-rw-r--r--spec/ruby/core/hash/shared/update.rb16
-rw-r--r--spec/ruby/core/hash/shift_spec.rb42
-rw-r--r--spec/ruby/core/hash/to_a_spec.rb10
-rw-r--r--spec/ruby/core/hash/to_h_spec.rb58
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb55
-rw-r--r--spec/ruby/core/integer/allbits_spec.rb2
-rw-r--r--spec/ruby/core/integer/anybits_spec.rb2
-rw-r--r--spec/ruby/core/integer/bit_and_spec.rb14
-rw-r--r--spec/ruby/core/integer/bit_or_spec.rb33
-rw-r--r--spec/ruby/core/integer/bit_xor_spec.rb35
-rw-r--r--spec/ruby/core/integer/chr_spec.rb65
-rw-r--r--spec/ruby/core/integer/complement_spec.rb6
-rw-r--r--spec/ruby/core/integer/constants_spec.rb36
-rw-r--r--spec/ruby/core/integer/digits_spec.rb9
-rw-r--r--spec/ruby/core/integer/div_spec.rb10
-rw-r--r--spec/ruby/core/integer/divide_spec.rb12
-rw-r--r--spec/ruby/core/integer/divmod_spec.rb12
-rw-r--r--spec/ruby/core/integer/element_reference_spec.rb122
-rw-r--r--spec/ruby/core/integer/fdiv_spec.rb51
-rw-r--r--spec/ruby/core/integer/left_shift_spec.rb57
-rw-r--r--spec/ruby/core/integer/minus_spec.rb6
-rw-r--r--spec/ruby/core/integer/multiply_spec.rb6
-rw-r--r--spec/ruby/core/integer/nobits_spec.rb2
-rw-r--r--spec/ruby/core/integer/plus_spec.rb23
-rw-r--r--spec/ruby/core/integer/remainder_spec.rb2
-rw-r--r--spec/ruby/core/integer/right_shift_spec.rb61
-rw-r--r--spec/ruby/core/integer/shared/abs.rb4
-rw-r--r--spec/ruby/core/integer/shared/exponent.rb11
-rw-r--r--spec/ruby/core/integer/shared/modulo.rb10
-rw-r--r--spec/ruby/core/integer/to_f_spec.rb6
-rw-r--r--spec/ruby/core/integer/to_s_spec.rb6
-rw-r--r--spec/ruby/core/integer/try_convert_spec.rb40
-rw-r--r--spec/ruby/core/integer/uminus_spec.rb8
-rw-r--r--spec/ruby/core/integer/zero_spec.rb21
-rw-r--r--spec/ruby/core/io/advise_spec.rb14
-rw-r--r--spec/ruby/core/io/binmode_spec.rb4
-rw-r--r--spec/ruby/core/io/close_on_exec_spec.rb4
-rw-r--r--spec/ruby/core/io/close_spec.rb49
-rw-r--r--spec/ruby/core/io/dup_spec.rb19
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb9
-rw-r--r--spec/ruby/core/io/fixtures/classes.rb29
-rw-r--r--spec/ruby/core/io/gets_spec.rb52
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb9
-rw-r--r--spec/ruby/core/io/lineno_spec.rb45
-rw-r--r--spec/ruby/core/io/new_spec.rb2
-rw-r--r--spec/ruby/core/io/nonblock_spec.rb70
-rw-r--r--spec/ruby/core/io/open_spec.rb4
-rw-r--r--spec/ruby/core/io/path_spec.rb14
-rw-r--r--spec/ruby/core/io/pipe_spec.rb11
-rw-r--r--spec/ruby/core/io/print_spec.rb25
-rw-r--r--spec/ruby/core/io/read_nonblock_spec.rb49
-rw-r--r--spec/ruby/core/io/read_spec.rb25
-rw-r--r--spec/ruby/core/io/readchar_spec.rb66
-rw-r--r--spec/ruby/core/io/readline_spec.rb35
-rw-r--r--spec/ruby/core/io/readlines_spec.rb26
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb17
-rw-r--r--spec/ruby/core/io/rewind_spec.rb15
-rw-r--r--spec/ruby/core/io/set_encoding_by_bom_spec.rb265
-rw-r--r--spec/ruby/core/io/set_encoding_spec.rb49
-rw-r--r--spec/ruby/core/io/shared/each.rb84
-rw-r--r--spec/ruby/core/io/shared/new.rb2
-rw-r--r--spec/ruby/core/io/shared/pos.rb8
-rw-r--r--spec/ruby/core/io/shared/readlines.rb142
-rw-r--r--spec/ruby/core/io/shared/write.rb10
-rw-r--r--spec/ruby/core/io/sysread_spec.rb36
-rw-r--r--spec/ruby/core/io/sysseek_spec.rb7
-rw-r--r--spec/ruby/core/io/syswrite_spec.rb10
-rw-r--r--spec/ruby/core/io/ungetbyte_spec.rb29
-rw-r--r--spec/ruby/core/io/ungetc_spec.rb2
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb10
-rw-r--r--spec/ruby/core/io/write_spec.rb34
-rw-r--r--spec/ruby/core/kernel/Complex_spec.rb151
-rw-r--r--spec/ruby/core/kernel/Float_spec.rb32
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb163
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb11
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb15
-rw-r--r--spec/ruby/core/kernel/caller_locations_spec.rb16
-rw-r--r--spec/ruby/core/kernel/caller_spec.rb16
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb131
-rw-r--r--spec/ruby/core/kernel/define_singleton_method_spec.rb15
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb75
-rw-r--r--spec/ruby/core/kernel/fixtures/Complex.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb32
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_core_method.rb2
-rw-r--r--spec/ruby/core/kernel/format_spec.rb1
-rw-r--r--spec/ruby/core/kernel/initialize_clone_spec.rb28
-rw-r--r--spec/ruby/core/kernel/initialize_dup_spec.rb20
-rw-r--r--spec/ruby/core/kernel/inspect_spec.rb18
-rw-r--r--spec/ruby/core/kernel/instance_variable_get_spec.rb6
-rw-r--r--spec/ruby/core/kernel/instance_variable_set_spec.rb12
-rw-r--r--spec/ruby/core/kernel/instance_variables_spec.rb11
-rw-r--r--spec/ruby/core/kernel/lambda_spec.rb24
-rw-r--r--spec/ruby/core/kernel/match_spec.rb28
-rw-r--r--spec/ruby/core/kernel/method_spec.rb24
-rw-r--r--spec/ruby/core/kernel/nil_spec.rb10
-rw-r--r--spec/ruby/core/kernel/open_spec.rb27
-rw-r--r--spec/ruby/core/kernel/p_spec.rb6
-rw-r--r--spec/ruby/core/kernel/print_spec.rb12
-rw-r--r--spec/ruby/core/kernel/proc_spec.rb10
-rw-r--r--spec/ruby/core/kernel/public_send_spec.rb8
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb19
-rw-r--r--spec/ruby/core/kernel/rand_spec.rb46
-rw-r--r--spec/ruby/core/kernel/remove_instance_variable_spec.rb13
-rw-r--r--spec/ruby/core/kernel/require_relative_spec.rb2
-rw-r--r--spec/ruby/core/kernel/shared/dup_clone.rb24
-rw-r--r--spec/ruby/core/kernel/shared/load.rb45
-rw-r--r--spec/ruby/core/kernel/shared/method.rb8
-rw-r--r--spec/ruby/core/kernel/shared/require.rb38
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb124
-rw-r--r--spec/ruby/core/kernel/shared/sprintf_encoding.rb33
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb2
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb6
-rw-r--r--spec/ruby/core/kernel/srand_spec.rb16
-rw-r--r--spec/ruby/core/kernel/system_spec.rb12
-rw-r--r--spec/ruby/core/kernel/taint_spec.rb45
-rw-r--r--spec/ruby/core/kernel/tainted_spec.rb12
-rw-r--r--spec/ruby/core/kernel/then_spec.rb6
-rw-r--r--spec/ruby/core/kernel/to_s_spec.rb10
-rw-r--r--spec/ruby/core/kernel/trap_spec.rb5
-rw-r--r--spec/ruby/core/kernel/trust_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untaint_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untrust_spec.rb25
-rw-r--r--spec/ruby/core/kernel/untrusted_spec.rb28
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb72
-rw-r--r--spec/ruby/core/main/fixtures/using.rb1
-rw-r--r--spec/ruby/core/main/fixtures/using_in_main.rb5
-rw-r--r--spec/ruby/core/main/fixtures/using_in_method.rb5
-rw-r--r--spec/ruby/core/main/private_spec.rb12
-rw-r--r--spec/ruby/core/main/public_spec.rb13
-rw-r--r--spec/ruby/core/main/ruby2_keywords_spec.rb9
-rw-r--r--spec/ruby/core/main/using_spec.rb20
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb94
-rw-r--r--spec/ruby/core/marshal/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb2
-rw-r--r--spec/ruby/core/marshal/shared/load.rb365
-rw-r--r--spec/ruby/core/matchdata/allocate_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb29
-rw-r--r--spec/ruby/core/matchdata/fixtures/classes.rb3
-rw-r--r--spec/ruby/core/matchdata/match_length_spec.rb34
-rw-r--r--spec/ruby/core/matchdata/match_spec.rb34
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb26
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb26
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb73
-rw-r--r--spec/ruby/core/math/ldexp_spec.rb6
-rw-r--r--spec/ruby/core/math/log2_spec.rb2
-rw-r--r--spec/ruby/core/math/sqrt_spec.rb4
-rw-r--r--spec/ruby/core/method/compose_spec.rb134
-rw-r--r--spec/ruby/core/method/fixtures/classes.rb30
-rw-r--r--spec/ruby/core/method/owner_spec.rb6
-rw-r--r--spec/ruby/core/method/parameters_spec.rb15
-rw-r--r--spec/ruby/core/method/private_spec.rb21
-rw-r--r--spec/ruby/core/method/protected_spec.rb21
-rw-r--r--spec/ruby/core/method/public_spec.rb21
-rw-r--r--spec/ruby/core/method/shared/to_s.rb32
-rw-r--r--spec/ruby/core/method/super_method_spec.rb21
-rw-r--r--spec/ruby/core/method/unbind_spec.rb12
-rw-r--r--spec/ruby/core/module/allocate_spec.rb14
-rw-r--r--spec/ruby/core/module/append_features_spec.rb14
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb15
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb12
-rw-r--r--spec/ruby/core/module/autoload_spec.rb146
-rw-r--r--spec/ruby/core/module/class_variables_spec.rb8
-rw-r--r--spec/ruby/core/module/const_added_spec.rb125
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb12
-rw-r--r--spec/ruby/core/module/const_get_spec.rb22
-rw-r--r--spec/ruby/core/module/const_set_spec.rb3
-rw-r--r--spec/ruby/core/module/const_source_location_spec.rb333
-rw-r--r--spec/ruby/core/module/constants_spec.rb6
-rw-r--r--spec/ruby/core/module/define_method_spec.rb140
-rw-r--r--spec/ruby/core/module/deprecate_constant_spec.rb23
-rw-r--r--spec/ruby/core/module/extend_object_spec.rb14
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb13
-rw-r--r--spec/ruby/core/module/include_spec.rb323
-rw-r--r--spec/ruby/core/module/included_modules_spec.rb2
-rw-r--r--spec/ruby/core/module/instance_method_spec.rb42
-rw-r--r--spec/ruby/core/module/method_defined_spec.rb90
-rw-r--r--spec/ruby/core/module/module_function_spec.rb40
-rw-r--r--spec/ruby/core/module/name_spec.rb26
-rw-r--r--spec/ruby/core/module/prepend_features_spec.rb14
-rw-r--r--spec/ruby/core/module/prepend_spec.rb385
-rw-r--r--spec/ruby/core/module/private_class_method_spec.rb12
-rw-r--r--spec/ruby/core/module/private_method_defined_spec.rb88
-rw-r--r--spec/ruby/core/module/private_spec.rb24
-rw-r--r--spec/ruby/core/module/protected_method_defined_spec.rb88
-rw-r--r--spec/ruby/core/module/protected_spec.rb24
-rw-r--r--spec/ruby/core/module/public_class_method_spec.rb16
-rw-r--r--spec/ruby/core/module/public_spec.rb25
-rw-r--r--spec/ruby/core/module/refine_spec.rb665
-rw-r--r--spec/ruby/core/module/remove_const_spec.rb21
-rw-r--r--spec/ruby/core/module/remove_method_spec.rb22
-rw-r--r--spec/ruby/core/module/ruby2_keywords_spec.rb319
-rw-r--r--spec/ruby/core/module/shared/class_eval.rb21
-rw-r--r--spec/ruby/core/module/to_s_spec.rb23
-rw-r--r--spec/ruby/core/nil/match_spec.rb30
-rw-r--r--spec/ruby/core/nil/to_s_spec.rb12
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb7
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb11
-rw-r--r--spec/ruby/core/numeric/shared/step.rb5
-rw-r--r--spec/ruby/core/numeric/step_spec.rb32
-rw-r--r--spec/ruby/core/objectspace/_id2ref_spec.rb41
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb24
-rw-r--r--spec/ruby/core/objectspace/garbage_collect_spec.rb4
-rw-r--r--spec/ruby/core/objectspace/weakmap/element_set_spec.rb53
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/include.rb16
-rw-r--r--spec/ruby/core/proc/block_pass_spec.rb22
-rw-r--r--spec/ruby/core/proc/compose_spec.rb222
-rw-r--r--spec/ruby/core/proc/eql_spec.rb2
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/proc/new_spec.rb39
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb27
-rw-r--r--spec/ruby/core/proc/ruby2_keywords_spec.rb78
-rw-r--r--spec/ruby/core/proc/shared/call.rb3
-rw-r--r--spec/ruby/core/proc/shared/compose.rb51
-rw-r--r--spec/ruby/core/proc/shared/to_s.rb10
-rw-r--r--spec/ruby/core/process/_fork_spec.rb24
-rw-r--r--spec/ruby/core/process/clock_gettime_spec.rb101
-rw-r--r--spec/ruby/core/process/constants_spec.rb1
-rw-r--r--spec/ruby/core/process/daemon_spec.rb3
-rw-r--r--spec/ruby/core/process/detach_spec.rb29
-rw-r--r--spec/ruby/core/process/egid_spec.rb41
-rw-r--r--spec/ruby/core/process/euid_spec.rb12
-rw-r--r--spec/ruby/core/process/spawn_spec.rb79
-rw-r--r--spec/ruby/core/process/status/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/process/status/exited_spec.rb7
-rw-r--r--spec/ruby/core/process/status/exitstatus_spec.rb4
-rw-r--r--spec/ruby/core/process/status/signaled_spec.rb6
-rw-r--r--spec/ruby/core/process/status/success_spec.rb14
-rw-r--r--spec/ruby/core/process/status/termsig_spec.rb4
-rw-r--r--spec/ruby/core/process/status/to_i_spec.rb4
-rw-r--r--spec/ruby/core/process/status/wait_spec.rb102
-rw-r--r--spec/ruby/core/process/times_spec.rb14
-rw-r--r--spec/ruby/core/process/wait2_spec.rb9
-rw-r--r--spec/ruby/core/queue/initialize_spec.rb49
-rw-r--r--spec/ruby/core/random/bytes_spec.rb8
-rw-r--r--spec/ruby/core/random/default_spec.rb51
-rw-r--r--spec/ruby/core/random/rand_spec.rb5
-rw-r--r--spec/ruby/core/random/random_number_spec.rb4
-rw-r--r--spec/ruby/core/random/raw_seed_spec.rb6
-rw-r--r--spec/ruby/core/random/shared/urandom.rb23
-rw-r--r--spec/ruby/core/random/urandom_spec.rb25
-rw-r--r--spec/ruby/core/range/bsearch_spec.rb400
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb32
-rw-r--r--spec/ruby/core/range/clone_spec.rb26
-rw-r--r--spec/ruby/core/range/count_spec.rb16
-rw-r--r--spec/ruby/core/range/dup_spec.rb10
-rw-r--r--spec/ruby/core/range/each_spec.rb64
-rw-r--r--spec/ruby/core/range/equal_value_spec.rb12
-rw-r--r--spec/ruby/core/range/first_spec.rb6
-rw-r--r--spec/ruby/core/range/frozen_spec.rb27
-rw-r--r--spec/ruby/core/range/inspect_spec.rb36
-rw-r--r--spec/ruby/core/range/last_spec.rb12
-rw-r--r--spec/ruby/core/range/max_spec.rb18
-rw-r--r--spec/ruby/core/range/min_spec.rb20
-rw-r--r--spec/ruby/core/range/minmax_spec.rb124
-rw-r--r--spec/ruby/core/range/new_spec.rb48
-rw-r--r--spec/ruby/core/range/percent_spec.rb24
-rw-r--r--spec/ruby/core/range/shared/cover.rb136
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb13
-rw-r--r--spec/ruby/core/range/shared/equal_value.rb10
-rw-r--r--spec/ruby/core/range/size_spec.rb41
-rw-r--r--spec/ruby/core/range/step_spec.rb220
-rw-r--r--spec/ruby/core/range/to_a_spec.rb17
-rw-r--r--spec/ruby/core/range/to_s_spec.rb23
-rw-r--r--spec/ruby/core/rational/minus_spec.rb48
-rw-r--r--spec/ruby/core/rational/rational_spec.rb4
-rw-r--r--spec/ruby/core/refinement/append_features_spec.rb21
-rw-r--r--spec/ruby/core/refinement/extend_object_spec.rb21
-rw-r--r--spec/ruby/core/refinement/import_methods_spec.rb34
-rw-r--r--spec/ruby/core/refinement/include_spec.rb27
-rw-r--r--spec/ruby/core/refinement/prepend_features_spec.rb21
-rw-r--r--spec/ruby/core/refinement/prepend_spec.rb27
-rw-r--r--spec/ruby/core/regexp/case_compare_spec.rb10
-rw-r--r--spec/ruby/core/regexp/compile_spec.rb4
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb2
-rw-r--r--spec/ruby/core/regexp/new_spec.rb14
-rw-r--r--spec/ruby/core/regexp/shared/new.rb192
-rw-r--r--spec/ruby/core/regexp/shared/quote.rb10
-rw-r--r--spec/ruby/core/regexp/source_spec.rb22
-rw-r--r--spec/ruby/core/regexp/timeout_spec.rb35
-rw-r--r--spec/ruby/core/signal/trap_spec.rb143
-rw-r--r--spec/ruby/core/string/allocate_spec.rb2
-rw-r--r--spec/ruby/core/string/append_spec.rb5
-rw-r--r--spec/ruby/core/string/b_spec.rb9
-rw-r--r--spec/ruby/core/string/byteindex_spec.rb16
-rw-r--r--spec/ruby/core/string/bytesize_spec.rb2
-rw-r--r--spec/ruby/core/string/byteslice_spec.rb6
-rw-r--r--spec/ruby/core/string/capitalize_spec.rb16
-rw-r--r--spec/ruby/core/string/center_spec.rb18
-rw-r--r--spec/ruby/core/string/chars_spec.rb7
-rw-r--r--spec/ruby/core/string/chomp_spec.rb62
-rw-r--r--spec/ruby/core/string/chop_spec.rb16
-rw-r--r--spec/ruby/core/string/clone_spec.rb4
-rw-r--r--spec/ruby/core/string/comparison_spec.rb4
-rw-r--r--spec/ruby/core/string/crypt_spec.rb30
-rw-r--r--spec/ruby/core/string/dedup_spec.rb8
-rw-r--r--spec/ruby/core/string/delete_prefix_spec.rb11
-rw-r--r--spec/ruby/core/string/delete_spec.rb13
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb11
-rw-r--r--spec/ruby/core/string/downcase_spec.rb16
-rw-r--r--spec/ruby/core/string/dump_spec.rb22
-rw-r--r--spec/ruby/core/string/dup_spec.rb13
-rw-r--r--spec/ruby/core/string/each_grapheme_cluster_spec.rb8
-rw-r--r--spec/ruby/core/string/element_set_spec.rb34
-rw-r--r--spec/ruby/core/string/encode_spec.rb50
-rw-r--r--spec/ruby/core/string/encoding_spec.rb1
-rw-r--r--spec/ruby/core/string/fixtures/iso-8859-9-encoding.rb2
-rw-r--r--spec/ruby/core/string/fixtures/to_c.rb5
-rw-r--r--spec/ruby/core/string/force_encoding_spec.rb2
-rw-r--r--spec/ruby/core/string/gsub_spec.rb181
-rw-r--r--spec/ruby/core/string/include_spec.rb14
-rw-r--r--spec/ruby/core/string/index_spec.rb9
-rw-r--r--spec/ruby/core/string/insert_spec.rb21
-rw-r--r--spec/ruby/core/string/inspect_spec.rb38
-rw-r--r--spec/ruby/core/string/lines_spec.rb1
-rw-r--r--spec/ruby/core/string/ljust_spec.rb18
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb49
-rw-r--r--spec/ruby/core/string/modulo_spec.rb62
-rw-r--r--spec/ruby/core/string/ord_spec.rb5
-rw-r--r--spec/ruby/core/string/partition_spec.rb25
-rw-r--r--spec/ruby/core/string/plus_spec.rb13
-rw-r--r--spec/ruby/core/string/prepend_spec.rb10
-rw-r--r--spec/ruby/core/string/reverse_spec.rb37
-rw-r--r--spec/ruby/core/string/rindex_spec.rb23
-rw-r--r--spec/ruby/core/string/rjust_spec.rb18
-rw-r--r--spec/ruby/core/string/rpartition_spec.rb38
-rw-r--r--spec/ruby/core/string/rstrip_spec.rb57
-rw-r--r--spec/ruby/core/string/scan_spec.rb54
-rw-r--r--spec/ruby/core/string/scrub_spec.rb76
-rw-r--r--spec/ruby/core/string/setbyte_spec.rb6
-rw-r--r--spec/ruby/core/string/shared/chars.rb14
-rw-r--r--spec/ruby/core/string/shared/concat.rb12
-rw-r--r--spec/ruby/core/string/shared/dedup.rb57
-rw-r--r--spec/ruby/core/string/shared/each_line.rb14
-rw-r--r--spec/ruby/core/string/shared/eql.rb6
-rw-r--r--spec/ruby/core/string/shared/length.rb26
-rw-r--r--spec/ruby/core/string/shared/partition.rb51
-rw-r--r--spec/ruby/core/string/shared/replace.rb30
-rw-r--r--spec/ruby/core/string/shared/slice.rb161
-rw-r--r--spec/ruby/core/string/shared/strip.rb24
-rw-r--r--spec/ruby/core/string/shared/succ.rb8
-rw-r--r--spec/ruby/core/string/shared/to_s.rb7
-rw-r--r--spec/ruby/core/string/shared/to_sym.rb9
-rw-r--r--spec/ruby/core/string/slice_spec.rb85
-rw-r--r--spec/ruby/core/string/split_spec.rb323
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb15
-rw-r--r--spec/ruby/core/string/start_with_spec.rb10
-rw-r--r--spec/ruby/core/string/strip_spec.rb37
-rw-r--r--spec/ruby/core/string/sub_spec.rb136
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb11
-rw-r--r--spec/ruby/core/string/to_c_spec.rb108
-rw-r--r--spec/ruby/core/string/tr_s_spec.rb13
-rw-r--r--spec/ruby/core/string/tr_spec.rb13
-rw-r--r--spec/ruby/core/string/uminus_spec.rb77
-rw-r--r--spec/ruby/core/string/undump_spec.rb12
-rw-r--r--spec/ruby/core/string/unpack/b_spec.rb34
-rw-r--r--spec/ruby/core/string/unpack/c_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/h_spec.rb28
-rw-r--r--spec/ruby/core/string/unpack/m_spec.rb5
-rw-r--r--spec/ruby/core/string/unpack/p_spec.rb12
-rw-r--r--spec/ruby/core/string/unpack/shared/basic.rb8
-rw-r--r--spec/ruby/core/string/unpack/shared/float.rb60
-rw-r--r--spec/ruby/core/string/unpack/shared/integer.rb88
-rw-r--r--spec/ruby/core/string/unpack/shared/taint.rb81
-rw-r--r--spec/ruby/core/string/unpack/shared/unicode.rb14
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/z_spec.rb5
-rw-r--r--spec/ruby/core/string/unpack1_spec.rb26
-rw-r--r--spec/ruby/core/string/unpack_spec.rb34
-rw-r--r--spec/ruby/core/string/upcase_spec.rb16
-rw-r--r--spec/ruby/core/string/valid_encoding/utf_8_spec.rb214
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb8
-rw-r--r--spec/ruby/core/struct/deconstruct_keys_spec.rb146
-rw-r--r--spec/ruby/core/struct/deconstruct_spec.rb12
-rw-r--r--spec/ruby/core/struct/dig_spec.rb10
-rw-r--r--spec/ruby/core/struct/filter_spec.rb10
-rw-r--r--spec/ruby/core/struct/hash_spec.rb4
-rw-r--r--spec/ruby/core/struct/initialize_spec.rb8
-rw-r--r--spec/ruby/core/struct/keyword_init_spec.rb21
-rw-r--r--spec/ruby/core/struct/new_spec.rb45
-rw-r--r--spec/ruby/core/struct/to_h_spec.rb78
-rw-r--r--spec/ruby/core/struct/values_at_spec.rb55
-rw-r--r--spec/ruby/core/symbol/end_with_spec.rb6
-rw-r--r--spec/ruby/core/symbol/name_spec.rb19
-rw-r--r--spec/ruby/core/symbol/shared/id2name.rb7
-rw-r--r--spec/ruby/core/symbol/shared/slice.rb20
-rw-r--r--spec/ruby/core/symbol/start_with_spec.rb6
-rw-r--r--spec/ruby/core/symbol/to_proc_spec.rb31
-rw-r--r--spec/ruby/core/thread/backtrace/limit_spec.rb15
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb27
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/subdir/absolute_path_main_chdir.rb11
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/subdir/sibling.rb1
-rw-r--r--spec/ruby/core/thread/backtrace_locations_spec.rb16
-rw-r--r--spec/ruby/core/thread/handle_interrupt_spec.rb125
-rw-r--r--spec/ruby/core/thread/ignore_deadlock_spec.rb21
-rw-r--r--spec/ruby/core/thread/native_thread_id_spec.rb17
-rw-r--r--spec/ruby/core/thread/pending_interrupt_spec.rb32
-rw-r--r--spec/ruby/core/thread/raise_spec.rb24
-rw-r--r--spec/ruby/core/thread/report_on_exception_spec.rb51
-rw-r--r--spec/ruby/core/thread/shared/exit.rb22
-rw-r--r--spec/ruby/core/thread/shared/to_s.rb4
-rw-r--r--spec/ruby/core/thread/shared/wakeup.rb3
-rw-r--r--spec/ruby/core/time/at_spec.rb107
-rw-r--r--spec/ruby/core/time/ceil_spec.rb64
-rw-r--r--spec/ruby/core/time/floor_spec.rb52
-rw-r--r--spec/ruby/core/time/getlocal_spec.rb102
-rw-r--r--spec/ruby/core/time/inspect_spec.rb34
-rw-r--r--spec/ruby/core/time/localtime_spec.rb16
-rw-r--r--spec/ruby/core/time/minus_spec.rb14
-rw-r--r--spec/ruby/core/time/new_spec.rb445
-rw-r--r--spec/ruby/core/time/now_spec.rb45
-rw-r--r--spec/ruby/core/time/plus_spec.rb14
-rw-r--r--spec/ruby/core/time/shared/gmtime.rb4
-rw-r--r--spec/ruby/core/time/shared/local.rb11
-rw-r--r--spec/ruby/core/time/shared/now.rb12
-rw-r--r--spec/ruby/core/time/shared/time_params.rb11
-rw-r--r--spec/ruby/core/time/strftime_spec.rb41
-rw-r--r--spec/ruby/core/time/succ_spec.rb14
-rw-r--r--spec/ruby/core/time/utc_spec.rb41
-rw-r--r--spec/ruby/core/time/zone_spec.rb20
-rw-r--r--spec/ruby/core/tracepoint/allow_reentry_spec.rb32
-rw-r--r--spec/ruby/core/tracepoint/enable_spec.rb599
-rw-r--r--spec/ruby/core/tracepoint/eval_script_spec.rb30
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb21
-rw-r--r--spec/ruby/core/tracepoint/parameters_spec.rb42
-rw-r--r--spec/ruby/core/true/to_s_spec.rb12
-rw-r--r--spec/ruby/core/unboundmethod/bind_call_spec.rb74
-rw-r--r--spec/ruby/core/unboundmethod/equal_value_spec.rb76
-rw-r--r--spec/ruby/core/unboundmethod/fixtures/classes.rb16
-rw-r--r--spec/ruby/core/unboundmethod/hash_spec.rb7
-rw-r--r--spec/ruby/core/unboundmethod/owner_spec.rb7
-rw-r--r--spec/ruby/core/unboundmethod/private_spec.rb21
-rw-r--r--spec/ruby/core/unboundmethod/protected_spec.rb21
-rw-r--r--spec/ruby/core/unboundmethod/public_spec.rb21
-rw-r--r--spec/ruby/core/unboundmethod/shared/to_s.rb16
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb23
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb16
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb44
-rw-r--r--spec/ruby/core/warning/warn_spec.rb3
-rw-r--r--spec/ruby/fixtures/class.rb4
-rw-r--r--spec/ruby/fixtures/code/a/load_fixture.dylib1
-rw-r--r--spec/ruby/fixtures/code/c/load_fixture.rb1
-rw-r--r--spec/ruby/fixtures/code/concurrent.rb2
-rw-r--r--spec/ruby/fixtures/code/concurrent_require_fixture.rb4
-rw-r--r--spec/ruby/fixtures/code/load_fixture.dylib1
-rw-r--r--spec/ruby/fixtures/code/load_fixture.ext.dylib1
-rw-r--r--spec/ruby/fixtures/code/load_wrap_fixture.rb12
-rw-r--r--spec/ruby/fixtures/code/wrap_fixture.rb9
-rw-r--r--spec/ruby/fixtures/constants.rb21
-rw-r--r--spec/ruby/language/alias_spec.rb13
-rw-r--r--spec/ruby/language/block_spec.rb182
-rw-r--r--spec/ruby/language/case_spec.rb13
-rw-r--r--spec/ruby/language/class_spec.rb13
-rw-r--r--spec/ruby/language/class_variable_spec.rb32
-rw-r--r--spec/ruby/language/comment_spec.rb16
-rw-r--r--spec/ruby/language/constants_spec.rb145
-rw-r--r--spec/ruby/language/def_spec.rb33
-rw-r--r--spec/ruby/language/defined_spec.rb67
-rw-r--r--spec/ruby/language/delegation_spec.rb62
-rw-r--r--spec/ruby/language/ensure_spec.rb4
-rw-r--r--spec/ruby/language/file_spec.rb12
-rw-r--r--spec/ruby/language/fixtures/constant_visibility.rb18
-rw-r--r--spec/ruby/language/fixtures/defined.rb3
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb2
-rw-r--r--spec/ruby/language/fixtures/return.rb8
-rw-r--r--spec/ruby/language/fixtures/squiggly_heredoc.rb8
-rw-r--r--spec/ruby/language/hash_spec.rb113
-rw-r--r--spec/ruby/language/heredoc_spec.rb23
-rw-r--r--spec/ruby/language/keyword_arguments_spec.rb397
-rw-r--r--spec/ruby/language/lambda_spec.rb76
-rw-r--r--spec/ruby/language/method_spec.rb478
-rw-r--r--spec/ruby/language/module_spec.rb15
-rw-r--r--spec/ruby/language/numbered_parameters_spec.rb174
-rw-r--r--spec/ruby/language/numbers_spec.rb6
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb143
-rw-r--r--spec/ruby/language/pattern_matching_spec.rb2022
-rw-r--r--spec/ruby/language/precedence_spec.rb78
-rw-r--r--spec/ruby/language/predefined_spec.rb506
-rw-r--r--spec/ruby/language/proc_spec.rb27
-rw-r--r--spec/ruby/language/range_spec.rb22
-rw-r--r--spec/ruby/language/regexp/back-references_spec.rb5
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb5
-rw-r--r--spec/ruby/language/regexp/empty_checks_spec.rb135
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb17
-rw-r--r--spec/ruby/language/regexp/escapes_spec.rb84
-rw-r--r--spec/ruby/language/regexp/grouping_spec.rb35
-rw-r--r--spec/ruby/language/regexp/interpolation_spec.rb2
-rw-r--r--spec/ruby/language/regexp/repetition_spec.rb11
-rw-r--r--spec/ruby/language/regexp_spec.rb30
-rw-r--r--spec/ruby/language/rescue_spec.rb64
-rw-r--r--spec/ruby/language/return_spec.rb61
-rw-r--r--spec/ruby/language/safe_spec.rb147
-rw-r--r--spec/ruby/language/send_spec.rb18
-rw-r--r--spec/ruby/language/singleton_class_spec.rb17
-rw-r--r--spec/ruby/language/source_encoding_spec.rb4
-rw-r--r--spec/ruby/language/string_spec.rb32
-rw-r--r--spec/ruby/language/variables_spec.rb113
-rw-r--r--spec/ruby/language/yield_spec.rb38
-rw-r--r--spec/ruby/library/base64/decode64_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/BigDecimal_spec.rb57
-rw-r--r--spec/ruby/library/bigdecimal/exponent_spec.rb11
-rw-r--r--spec/ruby/library/bigdecimal/round_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/to_r_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/util_spec.rb6
-rw-r--r--spec/ruby/library/cgi/cookie/name_spec.rb12
-rw-r--r--spec/ruby/library/cgi/cookie/parse_spec.rb10
-rw-r--r--spec/ruby/library/cmath/math/acos_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/acosh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/asin_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/asinh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atan2_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atan_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/atanh_spec.rb20
-rw-r--r--spec/ruby/library/cmath/math/cos_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/cosh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/exp_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/fixtures/classes.rb4
-rw-r--r--spec/ruby/library/cmath/math/log10_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/log_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/shared/acos.rb41
-rw-r--r--spec/ruby/library/cmath/math/shared/acosh.rb37
-rw-r--r--spec/ruby/library/cmath/math/shared/asin.rb47
-rw-r--r--spec/ruby/library/cmath/math/shared/asinh.rb32
-rw-r--r--spec/ruby/library/cmath/math/shared/atan.rb32
-rw-r--r--spec/ruby/library/cmath/math/shared/atan2.rb34
-rw-r--r--spec/ruby/library/cmath/math/shared/atanh.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/cos.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/cosh.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/exp.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/log.rb39
-rw-r--r--spec/ruby/library/cmath/math/shared/log10.rb41
-rw-r--r--spec/ruby/library/cmath/math/shared/sin.rb30
-rw-r--r--spec/ruby/library/cmath/math/shared/sinh.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/sqrt.rb34
-rw-r--r--spec/ruby/library/cmath/math/shared/tan.rb28
-rw-r--r--spec/ruby/library/cmath/math/shared/tanh.rb32
-rw-r--r--spec/ruby/library/cmath/math/sin_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/sinh_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/sqrt_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/tan_spec.rb18
-rw-r--r--spec/ruby/library/cmath/math/tanh_spec.rb18
-rw-r--r--spec/ruby/library/coverage/result_spec.rb77
-rw-r--r--spec/ruby/library/coverage/running_spec.rb20
-rw-r--r--spec/ruby/library/coverage/start_spec.rb8
-rw-r--r--spec/ruby/library/date/civil_spec.rb7
-rw-r--r--spec/ruby/library/date/iso8601_spec.rb9
-rw-r--r--spec/ruby/library/date/parse_spec.rb2
-rw-r--r--spec/ruby/library/date/shared/valid_jd.rb20
-rw-r--r--spec/ruby/library/date/strftime_spec.rb15
-rw-r--r--spec/ruby/library/datetime/strftime_spec.rb16
-rw-r--r--spec/ruby/library/datetime/to_time_spec.rb18
-rw-r--r--spec/ruby/library/delegate/delegator/taint_spec.rb17
-rw-r--r--spec/ruby/library/delegate/delegator/trust_spec.rb16
-rw-r--r--spec/ruby/library/delegate/delegator/untaint_spec.rb18
-rw-r--r--spec/ruby/library/delegate/delegator/untrust_spec.rb17
-rw-r--r--spec/ruby/library/erb/fixtures/classes.rb6
-rw-r--r--spec/ruby/library/erb/new_spec.rb35
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb12
-rw-r--r--spec/ruby/library/fiddle/handle/initialize_spec.rb10
-rw-r--r--spec/ruby/library/io-wait/wait_readable_spec.rb27
-rw-r--r--spec/ruby/library/io-wait/wait_writable_spec.rb20
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb41
-rw-r--r--spec/ruby/library/logger/device/close_spec.rb4
-rw-r--r--spec/ruby/library/logger/device/write_spec.rb4
-rw-r--r--spec/ruby/library/matrix/I_spec.rb9
-rw-r--r--spec/ruby/library/matrix/antisymmetric_spec.rb5
-rw-r--r--spec/ruby/library/matrix/build_spec.rb117
-rw-r--r--spec/ruby/library/matrix/clone_spec.rb37
-rw-r--r--spec/ruby/library/matrix/coerce_spec.rb11
-rw-r--r--spec/ruby/library/matrix/collect_spec.rb9
-rw-r--r--spec/ruby/library/matrix/column_size_spec.rb19
-rw-r--r--spec/ruby/library/matrix/column_spec.rb53
-rw-r--r--spec/ruby/library/matrix/column_vector_spec.rb37
-rw-r--r--spec/ruby/library/matrix/column_vectors_spec.rb37
-rw-r--r--spec/ruby/library/matrix/columns_spec.rb67
-rw-r--r--spec/ruby/library/matrix/conj_spec.rb9
-rw-r--r--spec/ruby/library/matrix/conjugate_spec.rb9
-rw-r--r--spec/ruby/library/matrix/constructor_spec.rb103
-rw-r--r--spec/ruby/library/matrix/det_spec.rb11
-rw-r--r--spec/ruby/library/matrix/determinant_spec.rb11
-rw-r--r--spec/ruby/library/matrix/diagonal_spec.rb105
-rw-r--r--spec/ruby/library/matrix/divide_spec.rb83
-rw-r--r--spec/ruby/library/matrix/each_spec.rb119
-rw-r--r--spec/ruby/library/matrix/each_with_index_spec.rb133
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalue_matrix_spec.rb13
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvalues_spec.rb35
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvector_matrix_spec.rb33
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/eigenvectors_spec.rb37
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/initialize_spec.rb39
-rw-r--r--spec/ruby/library/matrix/eigenvalue_decomposition/to_a_spec.rb27
-rw-r--r--spec/ruby/library/matrix/element_reference_spec.rb31
-rw-r--r--spec/ruby/library/matrix/empty_spec.rb107
-rw-r--r--spec/ruby/library/matrix/eql_spec.rb15
-rw-r--r--spec/ruby/library/matrix/equal_value_spec.rb15
-rw-r--r--spec/ruby/library/matrix/exponent_spec.rb94
-rw-r--r--spec/ruby/library/matrix/find_index_spec.rb221
-rw-r--r--spec/ruby/library/matrix/hash_spec.rb21
-rw-r--r--spec/ruby/library/matrix/hermitian_spec.rb53
-rw-r--r--spec/ruby/library/matrix/identity_spec.rb9
-rw-r--r--spec/ruby/library/matrix/imag_spec.rb9
-rw-r--r--spec/ruby/library/matrix/imaginary_spec.rb9
-rw-r--r--spec/ruby/library/matrix/inspect_spec.rb39
-rw-r--r--spec/ruby/library/matrix/inv_spec.rb11
-rw-r--r--spec/ruby/library/matrix/inverse_from_spec.rb9
-rw-r--r--spec/ruby/library/matrix/inverse_spec.rb11
-rw-r--r--spec/ruby/library/matrix/lower_triangular_spec.rb39
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/determinant_spec.rb33
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/initialize_spec.rb21
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/l_spec.rb27
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/p_spec.rb27
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/solve_spec.rb85
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/to_a_spec.rb53
-rw-r--r--spec/ruby/library/matrix/lup_decomposition/u_spec.rb27
-rw-r--r--spec/ruby/library/matrix/map_spec.rb9
-rw-r--r--spec/ruby/library/matrix/minor_spec.rb135
-rw-r--r--spec/ruby/library/matrix/minus_spec.rb65
-rw-r--r--spec/ruby/library/matrix/multiply_spec.rb105
-rw-r--r--spec/ruby/library/matrix/new_spec.rb11
-rw-r--r--spec/ruby/library/matrix/normal_spec.rb41
-rw-r--r--spec/ruby/library/matrix/orthogonal_spec.rb41
-rw-r--r--spec/ruby/library/matrix/permutation_spec.rb51
-rw-r--r--spec/ruby/library/matrix/plus_spec.rb65
-rw-r--r--spec/ruby/library/matrix/rank_spec.rb29
-rw-r--r--spec/ruby/library/matrix/real_spec.rb63
-rw-r--r--spec/ruby/library/matrix/rect_spec.rb9
-rw-r--r--spec/ruby/library/matrix/rectangular_spec.rb9
-rw-r--r--spec/ruby/library/matrix/regular_spec.rb45
-rw-r--r--spec/ruby/library/matrix/round_spec.rb31
-rw-r--r--spec/ruby/library/matrix/row_size_spec.rb19
-rw-r--r--spec/ruby/library/matrix/row_spec.rb55
-rw-r--r--spec/ruby/library/matrix/row_vector_spec.rb33
-rw-r--r--spec/ruby/library/matrix/row_vectors_spec.rb37
-rw-r--r--spec/ruby/library/matrix/rows_spec.rb65
-rw-r--r--spec/ruby/library/matrix/scalar/Fail_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/Raise_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/divide_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/exponent_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/included_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/initialize_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/minus_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/multiply_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar/plus_spec.rb9
-rw-r--r--spec/ruby/library/matrix/scalar_spec.rb93
-rw-r--r--spec/ruby/library/matrix/singular_spec.rb47
-rw-r--r--spec/ruby/library/matrix/square_spec.rb41
-rw-r--r--spec/ruby/library/matrix/symmetric_spec.rb45
-rw-r--r--spec/ruby/library/matrix/t_spec.rb9
-rw-r--r--spec/ruby/library/matrix/to_a_spec.rb17
-rw-r--r--spec/ruby/library/matrix/to_s_spec.rb9
-rw-r--r--spec/ruby/library/matrix/tr_spec.rb11
-rw-r--r--spec/ruby/library/matrix/trace_spec.rb11
-rw-r--r--spec/ruby/library/matrix/transpose_spec.rb9
-rw-r--r--spec/ruby/library/matrix/unit_spec.rb9
-rw-r--r--spec/ruby/library/matrix/unitary_spec.rb51
-rw-r--r--spec/ruby/library/matrix/upper_triangular_spec.rb39
-rw-r--r--spec/ruby/library/matrix/vector/cross_product_spec.rb21
-rw-r--r--spec/ruby/library/matrix/vector/each2_spec.rb81
-rw-r--r--spec/ruby/library/matrix/vector/eql_spec.rb23
-rw-r--r--spec/ruby/library/matrix/vector/inner_product_spec.rb33
-rw-r--r--spec/ruby/library/matrix/vector/normalize_spec.rb29
-rw-r--r--spec/ruby/library/matrix/zero_spec.rb75
-rw-r--r--spec/ruby/library/monitor/enter_spec.rb28
-rw-r--r--spec/ruby/library/monitor/new_cond_spec.rb88
-rw-r--r--spec/ruby/library/monitor/synchronize_spec.rb41
-rw-r--r--spec/ruby/library/monitor/try_enter_spec.rb39
-rw-r--r--spec/ruby/library/net/FTPError_spec.rb11
-rw-r--r--spec/ruby/library/net/FTPPermError_spec.rb17
-rw-r--r--spec/ruby/library/net/FTPProtoError_spec.rb17
-rw-r--r--spec/ruby/library/net/FTPReplyError_spec.rb17
-rw-r--r--spec/ruby/library/net/FTPTempError_spec.rb17
-rw-r--r--spec/ruby/library/net/ftp/abort_spec.rb97
-rw-r--r--spec/ruby/library/net/ftp/acct_spec.rb111
-rw-r--r--spec/ruby/library/net/ftp/binary_spec.rb33
-rw-r--r--spec/ruby/library/net/ftp/chdir_spec.rb145
-rw-r--r--spec/ruby/library/net/ftp/close_spec.rb47
-rw-r--r--spec/ruby/library/net/ftp/closed_spec.rb31
-rw-r--r--spec/ruby/library/net/ftp/connect_spec.rb93
-rw-r--r--spec/ruby/library/net/ftp/debug_mode_spec.rb33
-rw-r--r--spec/ruby/library/net/ftp/default_passive_spec.rb11
-rw-r--r--spec/ruby/library/net/ftp/delete_spec.rb113
-rw-r--r--spec/ruby/library/net/ftp/dir_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/get_spec.rb31
-rw-r--r--spec/ruby/library/net/ftp/getbinaryfile_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/getdir_spec.rb11
-rw-r--r--spec/ruby/library/net/ftp/gettextfile_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/help_spec.rb103
-rw-r--r--spec/ruby/library/net/ftp/initialize_spec.rb557
-rw-r--r--spec/ruby/library/net/ftp/last_response_code_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/last_response_spec.rb39
-rw-r--r--spec/ruby/library/net/ftp/lastresp_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/list_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/login_spec.rb379
-rw-r--r--spec/ruby/library/net/ftp/ls_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/mdtm_spec.rb59
-rw-r--r--spec/ruby/library/net/ftp/mkdir_spec.rb97
-rw-r--r--spec/ruby/library/net/ftp/mtime_spec.rb73
-rw-r--r--spec/ruby/library/net/ftp/nlst_spec.rb141
-rw-r--r--spec/ruby/library/net/ftp/noop_spec.rb59
-rw-r--r--spec/ruby/library/net/ftp/open_spec.rb73
-rw-r--r--spec/ruby/library/net/ftp/passive_spec.rb39
-rw-r--r--spec/ruby/library/net/ftp/put_spec.rb31
-rw-r--r--spec/ruby/library/net/ftp/putbinaryfile_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/puttextfile_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/pwd_spec.rb101
-rw-r--r--spec/ruby/library/net/ftp/quit_spec.rb51
-rw-r--r--spec/ruby/library/net/ftp/rename_spec.rb159
-rw-r--r--spec/ruby/library/net/ftp/resume_spec.rb33
-rw-r--r--spec/ruby/library/net/ftp/retrbinary_spec.rb47
-rw-r--r--spec/ruby/library/net/ftp/retrlines_spec.rb55
-rw-r--r--spec/ruby/library/net/ftp/return_code_spec.rb35
-rw-r--r--spec/ruby/library/net/ftp/rmdir_spec.rb111
-rw-r--r--spec/ruby/library/net/ftp/sendcmd_spec.rb103
-rw-r--r--spec/ruby/library/net/ftp/set_socket_spec.rb13
-rw-r--r--spec/ruby/library/net/ftp/site_spec.rb101
-rw-r--r--spec/ruby/library/net/ftp/size_spec.rb91
-rw-r--r--spec/ruby/library/net/ftp/status_spec.rb105
-rw-r--r--spec/ruby/library/net/ftp/storbinary_spec.rb73
-rw-r--r--spec/ruby/library/net/ftp/storlines_spec.rb65
-rw-r--r--spec/ruby/library/net/ftp/system_spec.rb91
-rw-r--r--spec/ruby/library/net/ftp/voidcmd_spec.rb103
-rw-r--r--spec/ruby/library/net/ftp/welcome_spec.rb39
-rw-r--r--spec/ruby/library/net/http/HTTPClientExcepton_spec.rb14
-rw-r--r--spec/ruby/library/net/http/HTTPServerException_spec.rb24
-rw-r--r--spec/ruby/library/net/http/http/fixtures/http_server.rb150
-rw-r--r--spec/ruby/library/net/http/http/get_spec.rb1
-rw-r--r--spec/ruby/library/net/http/http/post_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/send_request_spec.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpresponse/error_type_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpresponse/exception_type_spec.rb7
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_body_spec.rb1
-rw-r--r--spec/ruby/library/net/http/httpresponse/read_new_spec.rb1
-rw-r--r--spec/ruby/library/net/http/httpresponse/shared/body.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/value_spec.rb7
-rw-r--r--spec/ruby/library/objectspace/fixtures/trace.rb5
-rw-r--r--spec/ruby/library/objectspace/memsize_of_all_spec.rb22
-rw-r--r--spec/ruby/library/objectspace/memsize_of_spec.rb2
-rw-r--r--spec/ruby/library/objectspace/trace_object_allocations_spec.rb149
-rw-r--r--spec/ruby/library/objectspace/trace_spec.rb15
-rw-r--r--spec/ruby/library/openssl/x509/name/verify_spec.rb78
-rw-r--r--spec/ruby/library/openstruct/method_missing_spec.rb8
-rw-r--r--spec/ruby/library/openstruct/to_h_spec.rb60
-rw-r--r--spec/ruby/library/pathname/birthtime_spec.rb16
-rw-r--r--spec/ruby/library/pathname/glob_spec.rb53
-rw-r--r--spec/ruby/library/pathname/inspect_spec.rb10
-rw-r--r--spec/ruby/library/pathname/new_spec.rb7
-rw-r--r--spec/ruby/library/pathname/pathname_spec.rb19
-rw-r--r--spec/ruby/library/pp/pp_spec.rb7
-rw-r--r--spec/ruby/library/prime/each_spec.rb247
-rw-r--r--spec/ruby/library/prime/instance_spec.rb31
-rw-r--r--spec/ruby/library/prime/int_from_prime_division_spec.rb19
-rw-r--r--spec/ruby/library/prime/integer/each_prime_spec.rb19
-rw-r--r--spec/ruby/library/prime/integer/from_prime_division_spec.rb19
-rw-r--r--spec/ruby/library/prime/integer/prime_division_spec.rb31
-rw-r--r--spec/ruby/library/prime/integer/prime_spec.rb27
-rw-r--r--spec/ruby/library/prime/next_spec.rb11
-rw-r--r--spec/ruby/library/prime/prime_division_spec.rb37
-rw-r--r--spec/ruby/library/prime/prime_spec.rb27
-rw-r--r--spec/ruby/library/prime/succ_spec.rb11
-rw-r--r--spec/ruby/library/rbconfig/rbconfig_spec.rb19
-rw-r--r--spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb19
-rw-r--r--spec/ruby/library/rbconfig/unicode_version_spec.rb25
-rw-r--r--spec/ruby/library/readline/history/delete_at_spec.rb9
-rw-r--r--spec/ruby/library/readline/history/each_spec.rb8
-rw-r--r--spec/ruby/library/readline/history/element_reference_spec.rb7
-rw-r--r--spec/ruby/library/readline/history/pop_spec.rb9
-rw-r--r--spec/ruby/library/readline/history/shift_spec.rb9
-rw-r--r--spec/ruby/library/readline/readline_spec.rb7
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb4
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb2
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb2
-rw-r--r--spec/ruby/library/rubygems/gem/load_path_insert_index_spec.rb10
-rw-r--r--spec/ruby/library/scanf/io/block_scanf_spec.rb10
-rw-r--r--spec/ruby/library/scanf/io/fixtures/date.txt4
-rw-r--r--spec/ruby/library/scanf/io/fixtures/helloworld.txt1
-rw-r--r--spec/ruby/library/scanf/io/scanf_spec.rb38
-rw-r--r--spec/ruby/library/scanf/io/shared/block_scanf.rb28
-rw-r--r--spec/ruby/library/scanf/string/block_scanf_spec.rb10
-rw-r--r--spec/ruby/library/scanf/string/scanf_spec.rb56
-rw-r--r--spec/ruby/library/scanf/string/shared/block_scanf.rb25
-rw-r--r--spec/ruby/library/set/comparison_spec.rb29
-rw-r--r--spec/ruby/library/set/filter_spec.rb6
-rw-r--r--spec/ruby/library/set/initialize_clone_spec.rb18
-rw-r--r--spec/ruby/library/set/initialize_spec.rb25
-rw-r--r--spec/ruby/library/set/join_spec.rb31
-rw-r--r--spec/ruby/library/set/pretty_print_spec.rb20
-rw-r--r--spec/ruby/library/set/sortedset/filter_spec.rb6
-rw-r--r--spec/ruby/library/set/sortedset/sortedset_spec.rb22
-rw-r--r--spec/ruby/library/socket/addrinfo/initialize_spec.rb2
-rw-r--r--spec/ruby/library/socket/basicsocket/local_address_spec.rb10
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb21
-rw-r--r--spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb15
-rw-r--r--spec/ruby/library/socket/basicsocket/remote_address_spec.rb10
-rw-r--r--spec/ruby/library/socket/basicsocket/send_spec.rb8
-rw-r--r--spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb7
-rw-r--r--spec/ruby/library/socket/shared/address.rb249
-rw-r--r--spec/ruby/library/socket/shared/pack_sockaddr.rb7
-rw-r--r--spec/ruby/library/socket/socket/accept_nonblock_spec.rb3
-rw-r--r--spec/ruby/library/socket/socket/bind_spec.rb4
-rw-r--r--spec/ruby/library/socket/socket/udp_server_loop_spec.rb4
-rw-r--r--spec/ruby/library/socket/tcpsocket/initialize_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/new_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/recv_nonblock_spec.rb14
-rw-r--r--spec/ruby/library/socket/tcpsocket/shared/new.rb23
-rw-r--r--spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb7
-rw-r--r--spec/ruby/library/stringio/append_spec.rb7
-rw-r--r--spec/ruby/library/stringio/each_line_spec.rb4
-rw-r--r--spec/ruby/library/stringio/each_spec.rb8
-rw-r--r--spec/ruby/library/stringio/gets_spec.rb4
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb85
-rw-r--r--spec/ruby/library/stringio/new_spec.rb8
-rw-r--r--spec/ruby/library/stringio/open_spec.rb12
-rw-r--r--spec/ruby/library/stringio/printf_spec.rb27
-rw-r--r--spec/ruby/library/stringio/putc_spec.rb15
-rw-r--r--spec/ruby/library/stringio/puts_spec.rb14
-rw-r--r--spec/ruby/library/stringio/read_nonblock_spec.rb11
-rw-r--r--spec/ruby/library/stringio/readline_spec.rb20
-rw-r--r--spec/ruby/library/stringio/readlines_spec.rb18
-rw-r--r--spec/ruby/library/stringio/reopen_spec.rb17
-rw-r--r--spec/ruby/library/stringio/shared/each.rb58
-rw-r--r--spec/ruby/library/stringio/shared/read.rb6
-rw-r--r--spec/ruby/library/stringio/shared/write.rb40
-rw-r--r--spec/ruby/library/stringio/truncate_spec.rb12
-rw-r--r--spec/ruby/library/stringio/ungetbyte_spec.rb38
-rw-r--r--spec/ruby/library/stringio/write_nonblock_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/check_spec.rb9
-rw-r--r--spec/ruby/library/stringscanner/check_until_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/exist_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/matched_size_spec.rb21
-rw-r--r--spec/ruby/library/stringscanner/scan_spec.rb44
-rw-r--r--spec/ruby/library/stringscanner/scan_until_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/search_full_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range.rb13
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range_matched.rb11
-rw-r--r--spec/ruby/library/stringscanner/shared/matched_size.rb21
-rw-r--r--spec/ruby/library/stringscanner/shared/peek.rb10
-rw-r--r--spec/ruby/library/stringscanner/size_spec.rb17
-rw-r--r--spec/ruby/library/stringscanner/skip_until_spec.rb6
-rw-r--r--spec/ruby/library/time/to_datetime_spec.rb18
-rw-r--r--spec/ruby/library/weakref/fixtures/classes.rb6
-rw-r--r--spec/ruby/library/yaml/fixtures/common.rb6
-rw-r--r--spec/ruby/library/yaml/load_spec.rb135
-rw-r--r--spec/ruby/library/yaml/shared/load.rb136
-rw-r--r--spec/ruby/library/yaml/to_yaml_spec.rb12
-rw-r--r--spec/ruby/library/yaml/unsafe_load_spec.rb9
-rw-r--r--spec/ruby/library/zlib/crc_table_spec.rb143
-rw-r--r--spec/ruby/library/zlib/deflate/deflate_spec.rb5
-rw-r--r--spec/ruby/library/zlib/inflate/inflate_spec.rb7
-rw-r--r--spec/ruby/optional/capi/array_spec.rb8
-rw-r--r--spec/ruby/optional/capi/binding_spec.rb21
-rw-r--r--spec/ruby/optional/capi/class_spec.rb70
-rw-r--r--spec/ruby/optional/capi/data_spec.rb7
-rw-r--r--spec/ruby/optional/capi/debug_spec.rb66
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb105
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb44
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c22
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c37
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/debug_spec.c93
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c33
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/fiber_spec.c69
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c35
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c34
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c54
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c42
-rw-r--r--spec/ruby/optional/capi/ext/module_spec.c41
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c70
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c59
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c32
-rw-r--r--spec/ruby/optional/capi/ext/regexp_spec.c13
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h34
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c149
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c11
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c38
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c21
-rw-r--r--spec/ruby/optional/capi/fiber_spec.rb89
-rw-r--r--spec/ruby/optional/capi/fixtures/class.rb13
-rw-r--r--spec/ruby/optional/capi/fixtures/module.rb4
-rw-r--r--spec/ruby/optional/capi/fixtures/object.rb29
-rw-r--r--spec/ruby/optional/capi/fixtures/read.txt1
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb30
-rw-r--r--spec/ruby/optional/capi/globals_spec.rb54
-rw-r--r--spec/ruby/optional/capi/io_spec.rb41
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb106
-rw-r--r--spec/ruby/optional/capi/module_spec.rb53
-rw-r--r--spec/ruby/optional/capi/object_spec.rb193
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb60
-rw-r--r--spec/ruby/optional/capi/rbasic_spec.rb20
-rw-r--r--spec/ruby/optional/capi/regexp_spec.rb45
-rw-r--r--spec/ruby/optional/capi/shared/rbasic.rb58
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb13
-rw-r--r--spec/ruby/optional/capi/string_spec.rb292
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb8
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb52
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb11
-rw-r--r--spec/ruby/optional/capi/util_spec.rb24
-rw-r--r--spec/ruby/security/cve_2010_1330_spec.rb2
-rw-r--r--spec/ruby/security/cve_2013_4164_spec.rb4
-rw-r--r--spec/ruby/security/cve_2014_8080_spec.rb1
-rw-r--r--spec/ruby/security/cve_2017_17742_spec.rb57
-rw-r--r--spec/ruby/security/cve_2018_16396_spec.rb18
-rw-r--r--spec/ruby/security/cve_2018_8778_spec.rb2
-rw-r--r--spec/ruby/security/cve_2019_8321_spec.rb26
-rw-r--r--spec/ruby/security/cve_2019_8322_spec.rb24
-rw-r--r--spec/ruby/security/cve_2019_8323_spec.rb48
-rw-r--r--spec/ruby/security/cve_2019_8325_spec.rb58
-rw-r--r--spec/ruby/security/cve_2020_10663_spec.rb26
-rw-r--r--spec/ruby/shared/file/executable.rb35
-rw-r--r--spec/ruby/shared/file/executable_real.rb35
-rw-r--r--spec/ruby/shared/file/readable.rb16
-rw-r--r--spec/ruby/shared/file/readable_real.rb16
-rw-r--r--spec/ruby/shared/file/writable.rb16
-rw-r--r--spec/ruby/shared/file/writable_real.rb16
-rw-r--r--spec/ruby/shared/kernel/complex.rb133
-rw-r--r--spec/ruby/shared/kernel/raise.rb52
-rw-r--r--spec/ruby/shared/process/exit.rb16
-rw-r--r--spec/ruby/shared/queue/deque.rb62
-rw-r--r--spec/ruby/shared/rational/Rational.rb102
-rw-r--r--spec/ruby/shared/rational/divmod.rb6
-rw-r--r--spec/ruby/shared/rational/exponent.rb8
-rw-r--r--spec/ruby/shared/rational/minus.rb48
-rw-r--r--spec/ruby/shared/rational/to_f.rb6
-rw-r--r--spec/ruby/shared/sizedqueue/enque.rb63
-rw-r--r--spec/ruby/shared/sizedqueue/new.rb9
-rw-r--r--spec/ruby/shared/string/end_with.rb9
-rw-r--r--spec/ruby/shared/string/start_with.rb4
-rw-r--r--spec/ruby/shared/string/times.rb12
-rw-r--r--spec/ruby/shared/time/strftime_for_time.rb8
-rw-r--r--spec/ruby/spec_helper.rb10
-rw-r--r--spec/syntax_suggest/fixtures/derailed_require_tree.rb.txt74
-rwxr-xr-xspec/syntax_suggest/fixtures/rexe.rb.txt569
-rw-r--r--spec/syntax_suggest/fixtures/routes.rb.txt121
-rw-r--r--spec/syntax_suggest/fixtures/ruby_buildpack.rb.txt1344
-rw-r--r--spec/syntax_suggest/fixtures/syntax_tree.rb.txt9234
-rw-r--r--spec/syntax_suggest/fixtures/this_project_extra_def.rb.txt64
-rw-r--r--spec/syntax_suggest/fixtures/webmock.rb.txt35
-rw-r--r--spec/syntax_suggest/integration/exe_cli_spec.rb27
-rw-r--r--spec/syntax_suggest/integration/ruby_command_line_spec.rb193
-rw-r--r--spec/syntax_suggest/integration/syntax_suggest_spec.rb239
-rw-r--r--spec/syntax_suggest/spec_helper.rb104
-rw-r--r--spec/syntax_suggest/unit/api_spec.rb108
-rw-r--r--spec/syntax_suggest/unit/around_block_scan_spec.rb165
-rw-r--r--spec/syntax_suggest/unit/block_expand_spec.rb230
-rw-r--r--spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb47
-rw-r--r--spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb44
-rw-r--r--spec/syntax_suggest/unit/capture_code_context_spec.rb229
-rw-r--r--spec/syntax_suggest/unit/clean_document_spec.rb260
-rw-r--r--spec/syntax_suggest/unit/cli_spec.rb224
-rw-r--r--spec/syntax_suggest/unit/code_block_spec.rb77
-rw-r--r--spec/syntax_suggest/unit/code_frontier_spec.rb135
-rw-r--r--spec/syntax_suggest/unit/code_line_spec.rb165
-rw-r--r--spec/syntax_suggest/unit/code_search_spec.rb505
-rw-r--r--spec/syntax_suggest/unit/core_ext_spec.rb34
-rw-r--r--spec/syntax_suggest/unit/display_invalid_blocks_spec.rb174
-rw-r--r--spec/syntax_suggest/unit/explain_syntax_spec.rb255
-rw-r--r--spec/syntax_suggest/unit/lex_all_spec.rb29
-rw-r--r--spec/syntax_suggest/unit/pathname_from_message_spec.rb56
-rw-r--r--spec/syntax_suggest/unit/priority_queue_spec.rb95
-rw-r--r--spec/syntax_suggest/unit/scan_history_spec.rb114
-rw-r--r--sprintf.c1380
-rw-r--r--st.c728
-rw-r--r--strftime.c19
-rw-r--r--string.c9129
-rw-r--r--string.rb552
-rw-r--r--struct.c1789
-rw-r--r--symbol.c508
-rw-r--r--symbol.h20
-rw-r--r--symbol.rb15
-rw-r--r--template/Doxyfile.tmpl2543
-rw-r--r--template/GNUmakefile.in20
-rw-r--r--template/Makefile.in142
-rw-r--r--template/encdb.h.tmpl17
-rw-r--r--template/extinit.c.tmpl2
-rw-r--r--template/exts.mk.tmpl9
-rw-r--r--template/fake.rb.in39
-rw-r--r--template/id.c.tmpl5
-rw-r--r--template/id.h.tmpl10
-rw-r--r--template/prelude.c.tmpl129
-rw-r--r--template/ruby.pc.in16
-rw-r--r--template/sizes.c.tmpl2
-rw-r--r--test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb52
-rw-r--r--test/-ext-/array/test_resize.rb6
-rw-r--r--test/-ext-/array/test_to_ary_concat.rb20
-rw-r--r--test/-ext-/bignum/test_big2str.rb38
-rw-r--r--test/-ext-/bignum/test_bigzero.rb20
-rw-r--r--test/-ext-/bignum/test_div.rb38
-rw-r--r--test/-ext-/bignum/test_mul.rb260
-rw-r--r--test/-ext-/bignum/test_pack.rb737
-rw-r--r--test/-ext-/bignum/test_str2big.rb52
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb15
-rw-r--r--test/-ext-/debug/test_profile_frames.rb24
-rw-r--r--test/-ext-/econv/test_append.rb23
-rw-r--r--test/-ext-/eval/test_eval.rb12
-rw-r--r--test/-ext-/float/test_nextafter.rb4
-rw-r--r--test/-ext-/funcall/test_funcall.rb11
-rw-r--r--test/-ext-/funcall/test_passing_block.rb5
-rw-r--r--test/-ext-/gvl/test_last_thread.rb2
-rw-r--r--test/-ext-/gvl/test_ubf_async_safe.rb4
-rw-r--r--test/-ext-/integer/test_integer.rb10
-rw-r--r--test/-ext-/iseq_load/test_iseq_load.rb6
-rw-r--r--test/-ext-/num2int/test_num2int.rb4
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb7
-rw-r--r--test/-ext-/rational/test_rat.rb26
-rw-r--r--test/-ext-/string/test_capacity.rb42
-rw-r--r--test/-ext-/string/test_cstr.rb6
-rw-r--r--test/-ext-/string/test_enc_str_buf_cat.rb9
-rw-r--r--test/-ext-/string/test_fstring.rb38
-rw-r--r--test/-ext-/string/test_rb_str_dup.rb6
-rw-r--r--test/-ext-/string/test_set_len.rb39
-rw-r--r--test/-ext-/symbol/test_type.rb14
-rw-r--r--test/-ext-/test_abi.rb47
-rw-r--r--test/-ext-/test_printf.rb4
-rw-r--r--test/-ext-/test_random.rb26
-rw-r--r--test/-ext-/thread/test_instrumentation_api.rb91
-rw-r--r--test/-ext-/thread_fd/test_thread_fd_close.rb24
-rw-r--r--test/-ext-/thread_fd_close/test_thread_fd_close.rb25
-rw-r--r--test/-ext-/wait/test_wait.rb36
-rw-r--r--test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb49
-rw-r--r--test/-ext-/win32/test_console_attr.rb14
-rw-r--r--test/benchmark/test_benchmark.rb11
-rw-r--r--test/bigdecimal/helper.rb39
-rw-r--r--test/bigdecimal/test_bigdecimal.rb276
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb34
-rw-r--r--test/bigdecimal/test_bigmath.rb2
-rw-r--r--test/bigdecimal/test_ractor.rb4
-rw-r--r--test/bigdecimal/testbase.rb28
-rw-r--r--test/cgi/test_cgi_cookie.rb90
-rw-r--r--test/cgi/test_cgi_header.rb8
-rw-r--r--test/cgi/test_cgi_util.rb118
-rw-r--r--test/coverage/autostart.rb2
-rw-r--r--test/coverage/main.rb1
-rw-r--r--test/coverage/test_coverage.rb231
-rw-r--r--test/csv/interface/test_read.rb48
-rw-r--r--test/csv/interface/test_read_write.rb9
-rw-r--r--test/csv/interface/test_write.rb43
-rw-r--r--test/csv/parse/test_convert.rb57
-rw-r--r--test/csv/parse/test_general.rb84
-rw-r--r--test/csv/parse/test_header.rb9
-rw-r--r--test/csv/parse/test_inputs_scanner.rb63
-rw-r--r--test/csv/parse/test_invalid.rb13
-rw-r--r--test/csv/parse/test_liberal_parsing.rb11
-rw-r--r--test/csv/parse/test_read.rb27
-rw-r--r--test/csv/parse/test_strip.rb29
-rw-r--r--test/csv/test_data_converters.rb84
-rw-r--r--test/csv/test_encodings.rb31
-rw-r--r--test/csv/test_patterns.rb27
-rw-r--r--test/csv/test_table.rb75
-rw-r--r--test/date/test_date.rb41
-rw-r--r--test/date/test_date_conv.rb17
-rw-r--r--test/date/test_date_parse.rb85
-rw-r--r--test/date/test_date_ractor.rb2
-rw-r--r--test/date/test_date_strftime.rb4
-rw-r--r--test/date/test_date_strptime.rb9
-rw-r--r--test/dbm/test_dbm.rb634
-rw-r--r--test/did_you_mean/core_ext/test_name_error_extension.rb23
-rw-r--r--test/did_you_mean/helper.rb14
-rw-r--r--test/did_you_mean/spell_checking/test_key_name_check.rb14
-rw-r--r--test/did_you_mean/spell_checking/test_method_name_check.rb38
-rw-r--r--test/did_you_mean/spell_checking/test_pattern_key_name_check.rb20
-rw-r--r--test/did_you_mean/spell_checking/test_require_path_check.rb6
-rw-r--r--test/did_you_mean/spell_checking/test_uncorrectable_name_check.rb2
-rw-r--r--test/did_you_mean/spell_checking/test_variable_name_check.rb36
-rw-r--r--test/did_you_mean/test_ractor_compatibility.rb117
-rw-r--r--test/did_you_mean/test_spell_checker.rb1
-rw-r--r--test/did_you_mean/test_verbose_formatter.rb23
-rw-r--r--test/did_you_mean/tree_spell/test_change_word.rb2
-rw-r--r--test/digest/test_digest_extend.rb13
-rw-r--r--test/digest/test_ractor.rb6
-rw-r--r--test/drb/drbtest.rb8
-rw-r--r--test/drb/test_drb.rb13
-rw-r--r--test/drb/test_drbssl.rb10
-rw-r--r--test/dtrace/helper.rb2
-rw-r--r--test/erb/test_erb.rb42
-rw-r--r--test/erb/test_erb_command.rb22
-rw-r--r--test/error_highlight/test_error_highlight.rb1290
-rw-r--r--test/etc/test_etc.rb1
-rw-r--r--test/excludes/TestArray.rb1
-rw-r--r--test/excludes/TestGem.rb4
-rw-r--r--test/excludes/TestThread.rb12
-rw-r--r--test/excludes/TestThreadQueue.rb9
-rw-r--r--test/fiber/autoload.rb3
-rw-r--r--test/fiber/http.rb11
-rw-r--r--test/fiber/scheduler.rb217
-rw-r--r--test/fiber/test_address_resolve.rb278
-rw-r--r--test/fiber/test_enumerator.rb16
-rw-r--r--test/fiber/test_io.rb171
-rw-r--r--test/fiber/test_io_buffer.rb158
-rw-r--r--test/fiber/test_mutex.rb40
-rw-r--r--test/fiber/test_process.rb36
-rw-r--r--test/fiber/test_queue.rb54
-rw-r--r--test/fiber/test_ractor.rb2
-rw-r--r--test/fiber/test_scheduler.rb154
-rw-r--r--test/fiber/test_sleep.rb25
-rw-r--r--test/fiber/test_storage.rb115
-rw-r--r--test/fiber/test_thread.rb130
-rw-r--r--test/fiber/test_timeout.rb51
-rw-r--r--test/fiddle/helper.rb30
-rw-r--r--test/fiddle/test_c_struct_builder.rb69
-rw-r--r--test/fiddle/test_closure.rb106
-rw-r--r--test/fiddle/test_cparser.rb58
-rw-r--r--test/fiddle/test_fiddle.rb41
-rw-r--r--test/fiddle/test_func.rb57
-rw-r--r--test/fiddle/test_function.rb116
-rw-r--r--test/fiddle/test_handle.rb42
-rw-r--r--test/fiddle/test_import.rb23
-rw-r--r--test/fiddle/test_memory_view.rb36
-rw-r--r--test/fiddle/test_pack.rb37
-rw-r--r--test/fiddle/test_pinned.rb1
-rw-r--r--test/fiddle/test_pointer.rb24
-rw-r--r--test/fileutils/clobber.rb5
-rw-r--r--test/fileutils/test_dryrun.rb2
-rw-r--r--test/fileutils/test_fileutils.rb93
-rw-r--r--test/fileutils/test_nowrite.rb2
-rw-r--r--test/fileutils/test_verbose.rb2
-rw-r--r--test/fileutils/visibility_tests.rb5
-rw-r--r--test/gdbm/test_gdbm.rb734
-rw-r--r--test/io/console/test_io_console.rb73
-rw-r--r--test/io/nonblock/test_flush.rb2
-rw-r--r--test/io/wait/test_io_wait.rb36
-rw-r--r--test/io/wait/test_io_wait_uncommon.rb38
-rw-r--r--test/io/wait/test_ractor.rb17
-rw-r--r--test/irb/helper.rb76
-rw-r--r--test/irb/test_cmd.rb787
-rw-r--r--test/irb/test_color.rb146
-rw-r--r--test/irb/test_color_printer.rb69
-rw-r--r--test/irb/test_completion.rb328
-rw-r--r--test/irb/test_context.rb523
-rw-r--r--test/irb/test_debug_cmd.rb303
-rw-r--r--test/irb/test_history.rb106
-rw-r--r--test/irb/test_init.rb138
-rw-r--r--test/irb/test_input_method.rb79
-rw-r--r--test/irb/test_option.rb4
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb45
-rw-r--r--test/irb/test_ruby_lex.rb430
-rw-r--r--test/irb/test_workspace.rb32
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb249
-rw-r--r--test/json/json_addition_test.rb2
-rw-r--r--test/json/json_parser_test.rb5
-rw-r--r--test/lib/jit_support.rb47
-rw-r--r--test/logger/helper.rb13
-rw-r--r--test/logger/test_formatter.rb35
-rw-r--r--test/logger/test_logdevice.rb5
-rw-r--r--test/logger/test_logger.rb8
-rw-r--r--test/logger/test_logperiod.rb2
-rw-r--r--test/logger/test_severity.rb2
-rw-r--r--test/matrix/test_matrix.rb832
-rw-r--r--test/matrix/test_vector.rb335
-rw-r--r--test/mkmf/base.rb226
-rw-r--r--test/mkmf/test_config.rb16
-rw-r--r--test/mkmf/test_constant.rb60
-rw-r--r--test/mkmf/test_convertible.rb48
-rw-r--r--test/mkmf/test_egrep_cpp.rb13
-rw-r--r--test/mkmf/test_find_executable.rb82
-rw-r--r--test/mkmf/test_flags.rb92
-rw-r--r--test/mkmf/test_framework.rb70
-rw-r--r--test/mkmf/test_have_func.rb18
-rw-r--r--test/mkmf/test_have_library.rb84
-rw-r--r--test/mkmf/test_have_macro.rb46
-rw-r--r--test/mkmf/test_install.rb28
-rw-r--r--test/mkmf/test_libs.rb153
-rw-r--r--test/mkmf/test_mkmf.rb14
-rw-r--r--test/mkmf/test_pkg_config.rb66
-rw-r--r--test/mkmf/test_signedness.rb38
-rw-r--r--test/mkmf/test_sizeof.rb74
-rw-r--r--test/monitor/test_monitor.rb31
-rw-r--r--test/net/fixtures/Makefile6
-rw-r--r--test/net/fixtures/cacert.pem44
-rw-r--r--test/net/fixtures/server.crt99
-rw-r--r--test/net/fixtures/server.key55
-rw-r--r--test/net/ftp/test_buffered_socket.rb48
-rw-r--r--test/net/ftp/test_ftp.rb2585
-rw-r--r--test/net/ftp/test_mlsx_entry.rb98
-rw-r--r--test/net/http/test_http.rb164
-rw-r--r--test/net/http/test_http_request.rb6
-rw-r--r--test/net/http/test_httpheader.rb27
-rw-r--r--test/net/http/test_httpresponse.rb289
-rw-r--r--test/net/http/test_https.rb80
-rw-r--r--test/net/http/test_https_proxy.rb2
-rw-r--r--test/net/imap/test_imap.rb844
-rw-r--r--test/net/imap/test_imap_response_parser.rb311
-rw-r--r--test/net/pop/test_pop.rb166
-rw-r--r--test/net/protocol/test_protocol.rb37
-rw-r--r--test/net/smtp/test_response.rb100
-rw-r--r--test/net/smtp/test_smtp.rb301
-rw-r--r--test/net/smtp/test_ssl_socket.rb99
-rw-r--r--test/net/smtp/test_sslcontext.rb129
-rw-r--r--test/net/smtp/test_starttls.rb122
-rw-r--r--test/objspace/test_objspace.rb296
-rw-r--r--test/objspace/test_ractor.rb17
-rw-r--r--test/open-uri/test_open-uri.rb263
-rw-r--r--test/open-uri/test_ssl.rb19
-rw-r--r--test/openssl/fixtures/pkey/certificate.derbin0 -> 1325 bytes-rw-r--r--test/openssl/fixtures/pkey/empty.der0
-rw-r--r--test/openssl/fixtures/pkey/empty.pem0
-rw-r--r--test/openssl/fixtures/pkey/fullchain.pem56
-rw-r--r--test/openssl/fixtures/pkey/garbage.txt1
-rw-r--r--test/openssl/fixtures/pkey/p256_too_large.pem5
-rw-r--r--test/openssl/fixtures/pkey/p384_invalid.pem6
-rw-r--r--test/openssl/test_asn1.rb31
-rw-r--r--test/openssl/test_bn.rb120
-rw-r--r--test/openssl/test_cipher.rb69
-rw-r--r--test/openssl/test_config.rb166
-rw-r--r--test/openssl/test_digest.rb2
-rw-r--r--test/openssl/test_hmac.rb21
-rw-r--r--test/openssl/test_ns_spki.rb2
-rw-r--r--test/openssl/test_ocsp.rb11
-rw-r--r--test/openssl/test_pair.rb5
-rw-r--r--test/openssl/test_pkcs12.rb297
-rw-r--r--test/openssl/test_pkcs7.rb18
-rw-r--r--test/openssl/test_pkey.rb149
-rw-r--r--test/openssl/test_pkey_dh.rb100
-rw-r--r--test/openssl/test_pkey_dsa.rb94
-rw-r--r--test/openssl/test_pkey_ec.rb201
-rw-r--r--test/openssl/test_pkey_rsa.rb308
-rw-r--r--test/openssl/test_ssl.rb719
-rw-r--r--test/openssl/test_ssl_session.rb11
-rw-r--r--test/openssl/test_ts.rb23
-rw-r--r--test/openssl/test_x509cert.rb48
-rw-r--r--test/openssl/test_x509crl.rb20
-rw-r--r--test/openssl/test_x509req.rb30
-rw-r--r--test/openssl/test_x509store.rb412
-rw-r--r--test/openssl/ut_eof.rb4
-rw-r--r--test/openssl/utils.rb50
-rw-r--r--test/optparse/test_acceptable.rb3
-rw-r--r--test/optparse/test_autoconf.rb4
-rw-r--r--test/optparse/test_bash_completion.rb4
-rw-r--r--test/optparse/test_cclass.rb2
-rw-r--r--test/optparse/test_did_you_mean.rb22
-rw-r--r--test/optparse/test_getopts.rb4
-rw-r--r--test/optparse/test_kwargs.rb4
-rw-r--r--test/optparse/test_load.rb141
-rw-r--r--test/optparse/test_noarg.rb6
-rw-r--r--test/optparse/test_optarg.rb2
-rw-r--r--test/optparse/test_optparse.rb45
-rw-r--r--test/optparse/test_placearg.rb8
-rw-r--r--test/optparse/test_reqarg.rb10
-rw-r--r--test/optparse/test_summary.rb25
-rw-r--r--test/optparse/test_zsh_completion.rb4
-rw-r--r--test/ostruct/test_ostruct.rb88
-rw-r--r--test/pathname/test_pathname.rb105
-rw-r--r--test/pathname/test_ractor.rb2
-rw-r--r--test/psych/helper.rb40
-rw-r--r--test/psych/test_alias_and_anchor.rb12
-rw-r--r--test/psych/test_array.rb22
-rw-r--r--test/psych/test_class.rb4
-rw-r--r--test/psych/test_coder.rb141
-rw-r--r--test/psych/test_date_time.rb24
-rw-r--r--test/psych/test_deprecated.rb4
-rw-r--r--test/psych/test_document.rb2
-rw-r--r--test/psych/test_emitter.rb10
-rw-r--r--test/psych/test_encoding.rb11
-rw-r--r--test/psych/test_exception.rb48
-rw-r--r--test/psych/test_hash.rb80
-rw-r--r--test/psych/test_marshalable.rb12
-rw-r--r--test/psych/test_merge_keys.rb24
-rw-r--r--test/psych/test_numeric.rb12
-rw-r--r--test/psych/test_object.rb15
-rw-r--r--test/psych/test_object_references.rb12
-rw-r--r--test/psych/test_omap.rb4
-rw-r--r--test/psych/test_parser.rb24
-rw-r--r--test/psych/test_psych.rb106
-rw-r--r--test/psych/test_ractor.rb4
-rw-r--r--test/psych/test_safe_load.rb93
-rw-r--r--test/psych/test_scalar_scanner.rb74
-rw-r--r--test/psych/test_serialize_subclasses.rb4
-rw-r--r--test/psych/test_set.rb6
-rw-r--r--test/psych/test_string.rb27
-rw-r--r--test/psych/test_struct.rb6
-rw-r--r--test/psych/test_yaml.rb16
-rw-r--r--test/psych/test_yaml_special_cases.rb6
-rw-r--r--test/psych/test_yamlstore.rb47
-rw-r--r--test/psych/visitors/test_to_ruby.rb4
-rw-r--r--test/psych/visitors/test_yaml_tree.rb13
-rw-r--r--test/racc/assets/mof.y6
-rw-r--r--test/racc/case.rb111
-rw-r--r--test/racc/helper.rb115
-rw-r--r--test/racc/regress/cast1223
-rw-r--r--test/racc/regress/huia619
-rw-r--r--test/racc/regress/mof6
-rw-r--r--test/racc/regress/nasl1122
-rw-r--r--test/racc/regress/opal7426
-rw-r--r--test/racc/regress/riml1922
-rw-r--r--test/racc/regress/ruby187193
-rw-r--r--test/racc/regress/ruby227654
-rw-r--r--test/racc/test_chk_y.rb2
-rw-r--r--test/racc/test_grammar_file_parser.rb2
-rw-r--r--test/racc/test_racc_command.rb2
-rw-r--r--test/racc/test_scan_y.rb2
-rw-r--r--test/rdoc/helper.rb6
-rw-r--r--test/rdoc/support/test_case.rb23
-rw-r--r--test/rdoc/test_rdoc_alias.rb3
-rw-r--r--test/rdoc/test_rdoc_any_method.rb64
-rw-r--r--test/rdoc/test_rdoc_class_module.rb11
-rw-r--r--test/rdoc/test_rdoc_code_object.rb2
-rw-r--r--test/rdoc/test_rdoc_constant.rb2
-rw-r--r--test/rdoc/test_rdoc_context.rb4
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb58
-rw-r--r--test/rdoc/test_rdoc_extend.rb11
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb116
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb16
-rw-r--r--test/rdoc/test_rdoc_include.rb14
-rw-r--r--test/rdoc/test_rdoc_markdown.rb86
-rw-r--r--test/rdoc/test_rdoc_markdown_test.rb4
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb27
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb151
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb9
-rw-r--r--test/rdoc/test_rdoc_method_attr.rb3
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb7
-rw-r--r--test/rdoc/test_rdoc_normal_module.rb3
-rw-r--r--test/rdoc/test_rdoc_options.rb134
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb266
-rw-r--r--test/rdoc/test_rdoc_parser_changelog.rb167
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb71
-rw-r--r--test/rdoc/test_rdoc_rd_block_parser.rb21
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb91
-rw-r--r--test/rdoc/test_rdoc_require.rb3
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb75
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb83
-rw-r--r--test/rdoc/test_rdoc_servlet.rb4
-rw-r--r--test/rdoc/test_rdoc_store.rb11
-rw-r--r--test/rdoc/test_rdoc_task.rb5
-rw-r--r--test/rdoc/test_rdoc_text.rb10
-rw-r--r--test/rdoc/test_rdoc_top_level.rb10
-rw-r--r--test/rdoc/xref_data.rb17
-rw-r--r--test/rdoc/xref_test_case.rb8
-rw-r--r--test/readline/helper.rb5
-rw-r--r--test/readline/test_readline.rb151
-rw-r--r--test/readline/test_readline_history.rb7
-rw-r--r--test/reline/helper.rb44
-rw-r--r--test/reline/test_config.rb87
-rw-r--r--test/reline/test_history.rb11
-rw-r--r--test/reline/test_key_actor_emacs.rb274
-rw-r--r--test/reline/test_key_actor_vi.rb90
-rw-r--r--test/reline/test_key_stroke.rb32
-rw-r--r--test/reline/test_macro.rb4
-rw-r--r--test/reline/test_reline.rb171
-rw-r--r--test/reline/test_reline_key.rb53
-rw-r--r--test/reline/test_string_processing.rb60
-rw-r--r--test/reline/test_terminfo.rb61
-rw-r--r--test/reline/test_unicode.rb9
-rw-r--r--test/reline/test_within_pipe.rb22
-rw-r--r--test/reline/windows/test_key_event_record.rb41
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl215
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb30
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb813
-rw-r--r--test/resolv/test_addr.rb4
-rw-r--r--test/resolv/test_dns.rb45
-rw-r--r--test/rinda/test_rinda.rb98
-rw-r--r--test/ripper/test_lexer.rb109
-rw-r--r--test/ripper/test_parser_events.rb85
-rw-r--r--test/ripper/test_ripper.rb31
-rw-r--r--test/ripper/test_scanner_events.rb48
-rw-r--r--test/ripper/test_sexp.rb22
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb2
-rw-r--r--test/ruby/enc/test_cesu8.rb4
-rw-r--r--test/ruby/enc/test_emoji_breaks.rb205
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb117
-rw-r--r--test/ruby/enc/test_regex_casefold.rb2
-rw-r--r--test/ruby/marshaltestlib.rb2
-rw-r--r--test/ruby/test_alias.rb39
-rw-r--r--test/ruby/test_argf.rb86
-rw-r--r--test/ruby/test_arity.rb44
-rw-r--r--test/ruby/test_array.rb253
-rw-r--r--test/ruby/test_assignment.rb176
-rw-r--r--test/ruby/test_ast.rb694
-rw-r--r--test/ruby/test_autoload.rb131
-rw-r--r--test/ruby/test_backtrace.rb85
-rw-r--r--test/ruby/test_bignum.rb59
-rw-r--r--test/ruby/test_call.rb7
-rw-r--r--test/ruby/test_case.rb12
-rw-r--r--test/ruby/test_class.rb95
-rw-r--r--test/ruby/test_clone.rb53
-rw-r--r--test/ruby/test_complex.rb119
-rw-r--r--test/ruby/test_complex2.rb2
-rw-r--r--test/ruby/test_complexrational.rb4
-rw-r--r--test/ruby/test_data.rb249
-rw-r--r--test/ruby/test_default_gems.rb2
-rw-r--r--test/ruby/test_defined.rb99
-rw-r--r--test/ruby/test_dir.rb99
-rw-r--r--test/ruby/test_dup.rb110
-rw-r--r--test/ruby/test_econv.rb2
-rw-r--r--test/ruby/test_encoding.rb23
-rw-r--r--test/ruby/test_enum.rb81
-rw-r--r--test/ruby/test_enumerator.rb146
-rw-r--r--test/ruby/test_env.rb928
-rw-r--r--test/ruby/test_eval.rb70
-rw-r--r--test/ruby/test_exception.rb265
-rw-r--r--test/ruby/test_fiber.rb24
-rw-r--r--test/ruby/test_file.rb54
-rw-r--r--test/ruby/test_file_exhaustive.rb169
-rw-r--r--test/ruby/test_float.rb46
-rw-r--r--test/ruby/test_frozen.rb30
-rw-r--r--test/ruby/test_gc.rb223
-rw-r--r--test/ruby/test_gc_compact.rb351
-rw-r--r--test/ruby/test_hash.rb438
-rw-r--r--test/ruby/test_inlinecache.rb2
-rw-r--r--test/ruby/test_insns_leaf.rb46
-rw-r--r--test/ruby/test_integer.rb94
-rw-r--r--test/ruby/test_io.rb305
-rw-r--r--test/ruby/test_io_buffer.rb562
-rw-r--r--test/ruby/test_io_m17n.rb10
-rw-r--r--test/ruby/test_io_timeout.rb58
-rw-r--r--test/ruby/test_iseq.rb216
-rw-r--r--test/ruby/test_jit.rb1212
-rw-r--r--test/ruby/test_jit_debug.rb17
-rw-r--r--test/ruby/test_keyword.rb309
-rw-r--r--test/ruby/test_lambda.rb103
-rw-r--r--test/ruby/test_lazy_enumerator.rb24
-rw-r--r--test/ruby/test_literal.rb59
-rw-r--r--test/ruby/test_m17n.rb61
-rw-r--r--test/ruby/test_m17n_comb.rb15
-rw-r--r--test/ruby/test_marshal.rb142
-rw-r--r--test/ruby/test_math.rb54
-rw-r--r--test/ruby/test_method.rb256
-rw-r--r--test/ruby/test_method_cache.rb11
-rw-r--r--test/ruby/test_mjit.rb1327
-rw-r--r--test/ruby/test_mjit_debug.rb17
-rw-r--r--test/ruby/test_module.rb536
-rw-r--r--test/ruby/test_name_error.rb2
-rw-r--r--test/ruby/test_nomethod_error.rb18
-rw-r--r--test/ruby/test_numeric.rb32
-rw-r--r--test/ruby/test_object.rb33
-rw-r--r--test/ruby/test_objectspace.rb48
-rw-r--r--test/ruby/test_optimization.rb104
-rw-r--r--test/ruby/test_pack.rb94
-rw-r--r--test/ruby/test_parse.rb145
-rw-r--r--test/ruby/test_pattern_matching.rb264
-rw-r--r--test/ruby/test_proc.rb181
-rw-r--r--test/ruby/test_process.rb321
-rw-r--r--test/ruby/test_rand.rb14
-rw-r--r--test/ruby/test_random_formatter.rb123
-rw-r--r--test/ruby/test_range.rb108
-rw-r--r--test/ruby/test_rational.rb9
-rw-r--r--test/ruby/test_refinement.rb372
-rw-r--r--test/ruby/test_regexp.rb526
-rw-r--r--test/ruby/test_require.rb196
-rw-r--r--test/ruby/test_require_lib.rb5
-rw-r--r--test/ruby/test_rubyoptions.rb143
-rw-r--r--test/ruby/test_rubyvm.rb57
-rw-r--r--test/ruby/test_rubyvm_mjit.rb38
-rw-r--r--test/ruby/test_settracefunc.rb652
-rw-r--r--test/ruby/test_shapes.rb441
-rw-r--r--test/ruby/test_signal.rb5
-rw-r--r--test/ruby/test_sprintf.rb40
-rw-r--r--test/ruby/test_string.rb852
-rw-r--r--test/ruby/test_struct.rb78
-rw-r--r--test/ruby/test_super.rb66
-rw-r--r--test/ruby/test_symbol.rb13
-rw-r--r--test/ruby/test_syntax.rb279
-rw-r--r--test/ruby/test_thread.rb152
-rw-r--r--test/ruby/test_thread_cv.rb63
-rw-r--r--test/ruby/test_thread_queue.rb159
-rw-r--r--test/ruby/test_time.rb214
-rw-r--r--test/ruby/test_time_tz.rb42
-rw-r--r--test/ruby/test_transcode.rb36
-rw-r--r--test/ruby/test_undef.rb16
-rw-r--r--test/ruby/test_variable.rb86
-rw-r--r--test/ruby/test_vm_dump.rb4
-rw-r--r--test/ruby/test_weakmap.rb57
-rw-r--r--test/ruby/test_yjit.rb1333
-rw-r--r--test/ruby/test_yjit_exit_locations.rb110
-rw-r--r--test/rubygems/alternate_cert.pem28
-rw-r--r--test/rubygems/alternate_cert_32.pem30
-rw-r--r--test/rubygems/alternate_key.pem50
-rw-r--r--test/rubygems/bad_rake.rb1
-rw-r--r--test/rubygems/bogussources.rb9
-rw-r--r--test/rubygems/bundler_test_gem.rb421
-rw-r--r--test/rubygems/child_cert.pem31
-rw-r--r--test/rubygems/child_cert_32.pem31
-rw-r--r--test/rubygems/child_key.pem50
-rw-r--r--test/rubygems/data/excon-0.7.7.gemspec.rzbin0 -> 388 bytes-rw-r--r--test/rubygems/data/null-required-ruby-version.gemspec.rzbin0 -> 403 bytes-rw-r--r--test/rubygems/data/null-required-rubygems-version.gemspec.rzbin0 -> 421 bytes-rw-r--r--test/rubygems/data/null-type.gemspec.rzbin554 -> 0 bytes-rw-r--r--test/rubygems/data/pry-0.4.7.gemspec.rzbin0 -> 433 bytes-rw-r--r--test/rubygems/encrypted_private_key.pem52
-rw-r--r--test/rubygems/expired_cert.pem30
-rw-r--r--test/rubygems/fake_certlib/openssl.rb1
-rw-r--r--test/rubygems/future_cert.pem30
-rw-r--r--test/rubygems/future_cert_32.pem30
-rw-r--r--test/rubygems/good_rake.rb1
-rw-r--r--test/rubygems/grandchild_cert.pem31
-rw-r--r--test/rubygems/grandchild_cert_32.pem31
-rw-r--r--test/rubygems/grandchild_key.pem50
-rw-r--r--test/rubygems/helper.rb1643
-rw-r--r--test/rubygems/installer_test_case.rb248
-rw-r--r--test/rubygems/invalid_issuer_cert.pem32
-rw-r--r--test/rubygems/invalid_issuer_cert_32.pem32
-rw-r--r--test/rubygems/invalid_key.pem50
-rw-r--r--test/rubygems/invalid_signer_cert.pem30
-rw-r--r--test/rubygems/invalid_signer_cert_32.pem30
-rw-r--r--test/rubygems/invalidchild_cert.pem31
-rw-r--r--test/rubygems/invalidchild_cert_32.pem31
-rw-r--r--test/rubygems/invalidchild_key.pem50
-rw-r--r--test/rubygems/multifactor_auth_utilities.rb111
-rw-r--r--test/rubygems/package/tar_test_case.rb175
-rw-r--r--test/rubygems/packages/Bluebie-legs-0.6.2.gembin0 -> 14336 bytes-rw-r--r--test/rubygems/packages/ascii_binder-0.1.10.1.gembin0 -> 244736 bytes-rw-r--r--test/rubygems/packages/ill-formatted-platform-1.0.0.10.gembin0 -> 10240 bytes-rw-r--r--test/rubygems/plugin/exception/rubygems_plugin.rb3
-rw-r--r--test/rubygems/plugin/load/rubygems_plugin.rb1
-rw-r--r--test/rubygems/plugin/standarderror/rubygems_plugin.rb3
-rw-r--r--test/rubygems/private_ec_key.pem9
-rw-r--r--test/rubygems/private_key.pem50
-rw-r--r--test/rubygems/public_cert.pem32
-rw-r--r--test/rubygems/public_cert_32.pem30
-rw-r--r--test/rubygems/public_key.pem14
-rw-r--r--test/rubygems/rubygems/commands/crash_command.rb1
-rw-r--r--test/rubygems/rubygems_plugin.rb5
-rw-r--r--test/rubygems/simple_gem.rb3
-rw-r--r--test/rubygems/specifications/bar-0.0.2.gemspec2
-rw-r--r--test/rubygems/specifications/rubyforge-0.0.1.gemspec10
-rw-r--r--test/rubygems/test_bundled_ca.rb29
-rw-r--r--test/rubygems/test_config.rb13
-rw-r--r--test/rubygems/test_deprecate.rb63
-rw-r--r--test/rubygems/test_exit.rb17
-rw-r--r--test/rubygems/test_gem.rb1307
-rw-r--r--test/rubygems/test_gem_available_set.rb43
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb81
-rw-r--r--test/rubygems/test_gem_command.rb99
-rw-r--r--test/rubygems/test_gem_command_manager.rb160
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb151
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb296
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb19
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb129
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb63
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb77
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb55
-rw-r--r--test/rubygems/test_gem_commands_exec_command.rb853
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb196
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb15
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb34
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb31
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb466
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb11
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb23
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb5
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb28
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb31
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb283
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb240
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb273
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb161
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb55
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb337
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb200
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb6
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb110
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb77
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb9
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb188
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb65
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb341
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb19
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb207
-rw-r--r--test/rubygems/test_gem_config_file.rb195
-rw-r--r--test/rubygems/test_gem_dependency.rb175
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb472
-rw-r--r--test/rubygems/test_gem_dependency_list.rb95
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb9
-rw-r--r--test/rubygems/test_gem_doctor.rb97
-rw-r--r--test/rubygems/test_gem_ext_builder.rb170
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb167
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore1
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock233
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs27
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb3
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore1
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock247
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs51
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb34
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_unit.rb60
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb45
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb39
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb124
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb33
-rw-r--r--test/rubygems/test_gem_gem_runner.rb24
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb272
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb9
-rw-r--r--test/rubygems/test_gem_indexer.rb158
-rw-r--r--test/rubygems/test_gem_install_update_options.rb39
-rw-r--r--test/rubygems/test_gem_installer.rb1133
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb23
-rw-r--r--test/rubygems/test_gem_name_tuple.rb9
-rw-r--r--test/rubygems/test_gem_package.rb602
-rw-r--r--test/rubygems/test_gem_package_old.rb37
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb105
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb64
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb194
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb189
-rw-r--r--test/rubygems/test_gem_package_task.rb39
-rw-r--r--test/rubygems/test_gem_path_support.rb35
-rw-r--r--test/rubygems/test_gem_platform.rb557
-rw-r--r--test/rubygems/test_gem_rdoc.rb39
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb407
-rw-r--r--test/rubygems/test_gem_request.rb180
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb61
-rw-r--r--test/rubygems/test_gem_request_set.rb208
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb453
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb179
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb123
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb133
-rw-r--r--test/rubygems/test_gem_requirement.rb184
-rw-r--r--test/rubygems/test_gem_resolver.rb290
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb13
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb67
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb95
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb60
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb3
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb25
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb31
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb45
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb44
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb25
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb33
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb11
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb133
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb15
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb25
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb35
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb3
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb17
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb17
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb21
-rw-r--r--test/rubygems/test_gem_security.rb171
-rw-r--r--test/rubygems/test_gem_security_policy.rb198
-rw-r--r--test/rubygems/test_gem_security_signer.rb83
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb21
-rw-r--r--test/rubygems/test_gem_server.rb608
-rw-r--r--test/rubygems/test_gem_silent_ui.rb89
-rw-r--r--test/rubygems/test_gem_source.rb93
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb25
-rw-r--r--test/rubygems/test_gem_source_git.rb142
-rw-r--r--test/rubygems/test_gem_source_installed.rb33
-rw-r--r--test/rubygems/test_gem_source_list.rb11
-rw-r--r--test/rubygems/test_gem_source_local.rb29
-rw-r--r--test/rubygems/test_gem_source_lock.rb63
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb37
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb15
-rw-r--r--test/rubygems/test_gem_source_vendor.rb27
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb145
-rw-r--r--test/rubygems/test_gem_specification.rb1859
-rw-r--r--test/rubygems/test_gem_stream_ui.rb77
-rw-r--r--test/rubygems/test_gem_stub_specification.rb89
-rw-r--r--test/rubygems/test_gem_text.rb9
-rw-r--r--test/rubygems/test_gem_uninstaller.rb276
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb7
-rw-r--r--test/rubygems/test_gem_update_suggestion.rb209
-rw-r--r--test/rubygems/test_gem_uri.rb41
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb29
-rw-r--r--test/rubygems/test_gem_util.rb65
-rw-r--r--test/rubygems/test_gem_validator.rb18
-rw-r--r--test/rubygems/test_gem_version.rb61
-rw-r--r--test/rubygems/test_gem_version_option.rb31
-rw-r--r--test/rubygems/test_kernel.rb109
-rw-r--r--test/rubygems/test_project_sanity.rb39
-rw-r--r--test/rubygems/test_remote_fetch_error.rb17
-rw-r--r--test/rubygems/test_require.rb321
-rw-r--r--test/rubygems/test_rubygems.rb76
-rw-r--r--test/rubygems/test_webauthn_listener.rb143
-rw-r--r--test/rubygems/test_webauthn_listener_response.rb93
-rw-r--r--test/rubygems/test_webauthn_poller.rb124
-rw-r--r--test/rubygems/utilities.rb435
-rw-r--r--test/rubygems/wrong_key_cert.pem30
-rw-r--r--test/rubygems/wrong_key_cert_32.pem30
-rw-r--r--test/runner.rb15
-rw-r--r--test/socket/test_addrinfo.rb15
-rw-r--r--test/socket/test_basicsocket.rb4
-rw-r--r--test/socket/test_nonblock.rb12
-rw-r--r--test/socket/test_socket.rb21
-rw-r--r--test/socket/test_sockopt.rb2
-rw-r--r--test/socket/test_tcp.rb27
-rw-r--r--test/socket/test_udp.rb2
-rw-r--r--test/socket/test_unix.rb147
-rw-r--r--test/stringio/test_stringio.rb102
-rw-r--r--test/strscan/test_ractor.rb2
-rw-r--r--test/strscan/test_stringscanner.rb80
-rw-r--r--test/test_extlibs.rb2
-rw-r--r--test/test_find.rb16
-rw-r--r--test/test_getoptlong.rb163
-rw-r--r--test/test_ipaddr.rb86
-rw-r--r--test/test_open3.rb13
-rw-r--r--test/test_pp.rb21
-rw-r--r--test/test_prime.rb299
-rw-r--r--test/test_pstore.rb36
-rw-r--r--test/test_pty.rb30
-rw-r--r--test/test_rbconfig.rb9
-rw-r--r--test/test_securerandom.rb121
-rw-r--r--test/test_set.rb52
-rw-r--r--test/test_time.rb18
-rw-r--r--test/test_timeout.rb65
-rw-r--r--test/test_tmpdir.rb26
-rw-r--r--test/test_tracer.rb234
-rw-r--r--test/test_trick.rb23
-rw-r--r--test/uri/test_common.rb119
-rw-r--r--test/uri/test_generic.rb38
-rw-r--r--test/uri/test_http.rb31
-rw-r--r--test/uri/test_ldap.rb6
-rw-r--r--test/uri/test_parser.rb43
-rw-r--r--test/uri/test_wss.rb71
-rw-r--r--test/win32ole/test_err_in_callback.rb2
-rw-r--r--test/win32ole/test_win32ole.rb2
-rw-r--r--test/win32ole/test_win32ole_event.rb5
-rw-r--r--test/win32ole/test_win32ole_method_event.rb2
-rw-r--r--test/win32ole/test_win32ole_param_event.rb2
-rw-r--r--test/win32ole/test_win32ole_record.rb2
-rw-r--r--test/win32ole/test_win32ole_type_event.rb2
-rw-r--r--test/win32ole/test_win32ole_variable.rb4
-rw-r--r--test/win32ole/test_win32ole_variant.rb2
-rw-r--r--test/win32ole/test_win32ole_variant_outarg.rb2
-rw-r--r--test/win32ole/test_word.rb2
-rw-r--r--test/yaml/test_store.rb6
-rw-r--r--test/zlib/test_zlib.rb148
-rw-r--r--thread.c2102
-rw-r--r--thread_none.c284
-rw-r--r--thread_none.h20
-rw-r--r--thread_pthread.c1046
-rw-r--r--thread_pthread.h92
-rw-r--r--thread_sync.c658
-rw-r--r--thread_sync.rb68
-rw-r--r--thread_win32.c431
-rw-r--r--thread_win32.h24
-rw-r--r--time.c2713
-rw-r--r--timev.h11
-rw-r--r--timev.rb456
-rw-r--r--tool/annocheck/Dockerfile4
-rw-r--r--tool/annocheck/Dockerfile-copy7
-rw-r--r--tool/bundler/dev_gems.rb19
-rw-r--r--tool/bundler/dev_gems.rb.lock57
-rw-r--r--tool/bundler/rubocop_gems.rb12
-rw-r--r--tool/bundler/rubocop_gems.rb.lock73
-rw-r--r--tool/bundler/standard_gems.rb12
-rw-r--r--tool/bundler/standard_gems.rb.lock81
-rw-r--r--tool/bundler/test_gems.rb5
-rw-r--r--tool/bundler/test_gems.rb.lock23
-rwxr-xr-xtool/checksum.rb4
-rw-r--r--tool/ci_functions.sh29
-rwxr-xr-xtool/disable_ipv6.sh9
-rw-r--r--tool/downloader.rb112
-rwxr-xr-xtool/enc-case-folding.rb416
-rw-r--r--tool/enc-emoji-citrus-gen.rb4
-rwxr-xr-xtool/enc-unicode.rb35
-rwxr-xr-xtool/expand-config.rb14
-rwxr-xr-xtool/extlibs.rb178
-rw-r--r--tool/fake.rb13
-rwxr-xr-xtool/fetch-bundled_gems.rb6
-rwxr-xr-xtool/file2lastrev.rb91
-rwxr-xr-xtool/format-release39
-rw-r--r--tool/gem-unpack.rb19
-rwxr-xr-xtool/gen-mailmap.rb4
-rw-r--r--tool/generic_erb.rb44
-rw-r--r--tool/gperf.sed1
-rwxr-xr-xtool/id2token.rb11
-rwxr-xr-xtool/ifchange29
-rwxr-xr-xtool/intern_ids.rb35
-rw-r--r--tool/lib/-test-/integer.rb4
-rw-r--r--tool/lib/bundled_gem.rb68
-rw-r--r--tool/lib/colorize.rb6
-rw-r--r--tool/lib/core_assertions.rb821
-rw-r--r--tool/lib/envutil.rb31
-rw-r--r--tool/lib/gc_checker.rb36
-rw-r--r--tool/lib/gc_compact_checker.rb10
-rw-r--r--tool/lib/leakchecker.rb34
-rw-r--r--tool/lib/memory_status.rb6
-rw-r--r--tool/lib/minitest/README.txt457
-rw-r--r--tool/lib/minitest/autorun.rb14
-rw-r--r--tool/lib/minitest/benchmark.rb418
-rw-r--r--tool/lib/minitest/mock.rb196
-rw-r--r--tool/lib/minitest/unit.rb1475
-rw-r--r--tool/lib/output.rb57
-rw-r--r--tool/lib/profile_test_all.rb2
-rw-r--r--tool/lib/test/unit.rb780
-rw-r--r--tool/lib/test/unit/assertions.rb574
-rw-r--r--tool/lib/test/unit/core_assertions.rb763
-rw-r--r--tool/lib/test/unit/parallel.rb45
-rw-r--r--tool/lib/test/unit/testcase.rb282
-rw-r--r--tool/lib/vcs.rb234
-rw-r--r--tool/lib/vpath.rb7
-rw-r--r--tool/lib/webrick/httpserver.rb1
-rw-r--r--tool/lib/webrick/httputils.rb2
-rwxr-xr-xtool/ln_sr.rb131
-rw-r--r--tool/m4/_colorize_result_prepare.m43
-rw-r--r--tool/m4/ac_msg_result.m42
-rw-r--r--tool/m4/colorize_result.m42
-rw-r--r--tool/m4/ruby_append_option.m42
-rw-r--r--tool/m4/ruby_append_options.m42
-rw-r--r--tool/m4/ruby_check_builtin_func.m42
-rw-r--r--tool/m4/ruby_check_builtin_setjmp.m410
-rw-r--r--tool/m4/ruby_check_printf_prefix.m411
-rw-r--r--tool/m4/ruby_check_setjmp.m410
-rw-r--r--tool/m4/ruby_check_signedness.m42
-rw-r--r--tool/m4/ruby_check_sizeof.m42
-rw-r--r--tool/m4/ruby_check_sysconf.m48
-rw-r--r--tool/m4/ruby_cppoutfile.m46
-rw-r--r--tool/m4/ruby_decl_attribute.m46
-rw-r--r--tool/m4/ruby_default_arch.m47
-rw-r--r--tool/m4/ruby_define_if.m412
-rw-r--r--tool/m4/ruby_defint.m42
-rw-r--r--tool/m4/ruby_dtrace_available.m44
-rw-r--r--tool/m4/ruby_dtrace_postprocess.m44
-rw-r--r--tool/m4/ruby_func_attribute.m42
-rw-r--r--tool/m4/ruby_mingw32.m46
-rw-r--r--tool/m4/ruby_prepend_option.m42
-rw-r--r--tool/m4/ruby_prog_gnu_ld.m42
-rw-r--r--tool/m4/ruby_prog_makedirs.m49
-rw-r--r--tool/m4/ruby_replace_funcs.m412
-rw-r--r--tool/m4/ruby_replace_type.m414
-rw-r--r--tool/m4/ruby_require_funcs.m413
-rw-r--r--tool/m4/ruby_rm_recursive.m42
-rw-r--r--tool/m4/ruby_setjmp_type.m42
-rw-r--r--tool/m4/ruby_stack_grow_direction.m46
-rw-r--r--tool/m4/ruby_thread.m480
-rw-r--r--tool/m4/ruby_try_cflags.m411
-rw-r--r--tool/m4/ruby_try_cxxflags.m44
-rw-r--r--tool/m4/ruby_try_ldflags.m44
-rw-r--r--tool/m4/ruby_type_attribute.m42
-rw-r--r--tool/m4/ruby_universal_arch.m436
-rw-r--r--tool/m4/ruby_wasm_tools.m424
-rw-r--r--tool/m4/ruby_werror_flag.m42
-rwxr-xr-xtool/make-snapshot49
-rw-r--r--tool/make_hgraph.rb7
-rwxr-xr-xtool/merger.rb192
-rwxr-xr-xtool/mjit/bindgen.rb435
-rw-r--r--tool/mjit_tabs.rb8
-rw-r--r--tool/mk_builtin_loader.rb74
-rwxr-xr-xtool/mkconfig.rb33
-rwxr-xr-xtool/mkrunnable.rb20
-rwxr-xr-xtool/outdate-bundled-gems.rb135
-rwxr-xr-xtool/pure_parser.rb24
-rwxr-xr-xtool/rbinstall.rb393
-rw-r--r--tool/rbs_skip_tests11
-rwxr-xr-xtool/redmine-backporter.rb171
-rwxr-xr-xtool/releng/gen-mail.rb13
-rw-r--r--tool/ruby_vm/controllers/application_controller.rb5
-rw-r--r--tool/ruby_vm/helpers/dumper.rb7
-rw-r--r--tool/ruby_vm/models/typemap.rb1
-rw-r--r--tool/ruby_vm/scripts/insns2vm.rb12
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb2
-rw-r--r--tool/ruby_vm/views/_insn_len_info.erb23
-rw-r--r--tool/ruby_vm/views/_insn_name_info.erb30
-rw-r--r--tool/ruby_vm/views/_insn_operand_info.erb29
-rw-r--r--tool/ruby_vm/views/_insn_type_chars.erb19
-rw-r--r--tool/ruby_vm/views/_leaf_helpers.erb1
-rw-r--r--tool/ruby_vm/views/_mjit_compile_getinlinecache.erb36
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb92
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb129
-rw-r--r--tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb29
-rw-r--r--tool/ruby_vm/views/_mjit_compile_ivar.erb101
-rw-r--r--tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb38
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb117
-rw-r--r--tool/ruby_vm/views/_trace_instruction.erb7
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb40
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb111
-rw-r--r--tool/ruby_vm/views/mjit_sp_inc.inc.erb17
-rw-r--r--tool/ruby_vm/views/optinsn.inc.erb4
-rwxr-xr-xtool/runruby.rb20
-rwxr-xr-xtool/strip-rdoc.rb30
-rwxr-xr-x[-rw-r--r--]tool/sync_default_gems.rb1162
-rwxr-xr-xtool/test-annocheck.sh33
-rw-r--r--tool/test-bundled-gems.rb74
-rw-r--r--tool/test/minitest/metametameta.rb71
-rw-r--r--tool/test/minitest/test_minitest_benchmark.rb131
-rw-r--r--tool/test/minitest/test_minitest_mock.rb404
-rw-r--r--tool/test/minitest/test_minitest_unit.rb1793
-rw-r--r--tool/test/runner.rb2
-rwxr-xr-xtool/test/test_sync_default_gems.rb76
-rw-r--r--tool/test/testunit/metametameta.rb70
-rw-r--r--tool/test/testunit/test4test_hideskip.rb8
-rw-r--r--tool/test/testunit/test4test_sorting.rb2
-rw-r--r--tool/test/testunit/test_assertion.rb26
-rw-r--r--tool/test/testunit/test_hideskip.rb4
-rw-r--r--tool/test/testunit/test_minitest_unit.rb1488
-rw-r--r--tool/test/testunit/test_parallel.rb31
-rw-r--r--tool/test/testunit/test_redefinition.rb13
-rw-r--r--tool/test/testunit/test_sorting.rb57
-rw-r--r--tool/test/testunit/tests_for_parallel/test4test_hungup.rb15
-rw-r--r--tool/test/webrick/test_filehandler.rb5
-rw-r--r--tool/test/webrick/test_httpproxy.rb1
-rw-r--r--tool/test/webrick/test_httprequest.rb2
-rw-r--r--tool/test/webrick/test_httpresponse.rb8
-rw-r--r--tool/test/webrick/utils.rb2
-rw-r--r--tool/transcode-tblgen.rb2
-rw-r--r--tool/transform_mjit_header.rb15
-rwxr-xr-xtool/travis_wait.sh18
-rw-r--r--tool/update-NEWS-refs.rb37
-rwxr-xr-x[-rw-r--r--]tool/update-bundled_gems.rb13
-rwxr-xr-xtool/update-deps22
-rwxr-xr-xtool/wasm-clangw9
-rw-r--r--trace_point.rb100
-rw-r--r--transcode.c784
-rw-r--r--transcode_data.h32
-rw-r--r--transient_heap.c12
-rw-r--r--util.c196
-rw-r--r--variable.c2708
-rw-r--r--variable.h11
-rw-r--r--version.c67
-rw-r--r--version.h64
-rw-r--r--vm.c2173
-rw-r--r--vm_args.c641
-rw-r--r--vm_backtrace.c1108
-rw-r--r--vm_callinfo.h152
-rw-r--r--vm_core.h610
-rw-r--r--vm_debug.h46
-rw-r--r--vm_dump.c1112
-rw-r--r--vm_eval.c1277
-rw-r--r--vm_exec.c31
-rw-r--r--vm_exec.h25
-rw-r--r--vm_insnhelper.c3730
-rw-r--r--vm_insnhelper.h33
-rw-r--r--vm_method.c1432
-rw-r--r--vm_sync.c16
-rw-r--r--vm_sync.h3
-rw-r--r--vm_trace.c678
-rw-r--r--vsnprintf.c23
-rw-r--r--wasm/GNUmakefile.in32
-rw-r--r--wasm/README.md70
-rw-r--r--wasm/asyncify.h23
-rw-r--r--wasm/fiber.c83
-rw-r--r--wasm/fiber.h43
-rw-r--r--wasm/machine.c62
-rw-r--r--wasm/machine.h25
-rw-r--r--wasm/machine_core.S25
-rw-r--r--wasm/missing.c199
-rw-r--r--wasm/runtime.c47
-rw-r--r--wasm/setjmp.c204
-rw-r--r--wasm/setjmp.h95
-rw-r--r--wasm/setjmp_core.S27
-rw-r--r--wasm/tests/fiber_test.c66
-rw-r--r--wasm/tests/machine_test.c115
-rw-r--r--wasm/tests/setjmp_test.c108
-rwxr-xr-xwasm/wasm-opt36
-rw-r--r--win32/Makefile.sub262
-rwxr-xr-xwin32/configure.bat51
-rw-r--r--win32/dir.h2
-rw-r--r--win32/file.c619
-rw-r--r--win32/file.h38
-rwxr-xr-xwin32/ifchange.bat31
-rwxr-xr-xwin32/mkexports.rb16
-rwxr-xr-xwin32/resource.rb4
-rw-r--r--win32/ruby.manifest8
-rw-r--r--win32/setup.mak107
-rw-r--r--win32/win32.c6056
-rw-r--r--win32/winmain.c4
-rw-r--r--yjit.c1109
-rw-r--r--yjit.h70
-rw-r--r--yjit.rb356
-rw-r--r--yjit/.gitignore2
-rw-r--r--yjit/Cargo.lock49
-rw-r--r--yjit/Cargo.toml47
-rw-r--r--yjit/bindgen/Cargo.lock311
-rw-r--r--yjit/bindgen/Cargo.toml10
-rw-r--r--yjit/bindgen/src/main.rs430
-rw-r--r--yjit/not_gmake.mk14
-rw-r--r--yjit/src/asm/arm64/README.md16
-rw-r--r--yjit/src/asm/arm64/arg/bitmask_imm.rs255
-rw-r--r--yjit/src/asm/arm64/arg/condition.rs52
-rw-r--r--yjit/src/asm/arm64/arg/inst_offset.rs47
-rw-r--r--yjit/src/asm/arm64/arg/mod.rs18
-rw-r--r--yjit/src/asm/arm64/arg/sf.rs19
-rw-r--r--yjit/src/asm/arm64/arg/shifted_imm.rs81
-rw-r--r--yjit/src/asm/arm64/arg/sys_reg.rs6
-rw-r--r--yjit/src/asm/arm64/arg/truncate.rs66
-rw-r--r--yjit/src/asm/arm64/inst/atomic.rs86
-rw-r--r--yjit/src/asm/arm64/inst/branch.rs100
-rw-r--r--yjit/src/asm/arm64/inst/branch_cond.rs78
-rw-r--r--yjit/src/asm/arm64/inst/breakpoint.rs55
-rw-r--r--yjit/src/asm/arm64/inst/call.rs104
-rw-r--r--yjit/src/asm/arm64/inst/conditional.rs73
-rw-r--r--yjit/src/asm/arm64/inst/data_imm.rs143
-rw-r--r--yjit/src/asm/arm64/inst/data_reg.rs192
-rw-r--r--yjit/src/asm/arm64/inst/halfword_imm.rs179
-rw-r--r--yjit/src/asm/arm64/inst/load_literal.rs89
-rw-r--r--yjit/src/asm/arm64/inst/load_register.rs108
-rw-r--r--yjit/src/asm/arm64/inst/load_store.rs249
-rw-r--r--yjit/src/asm/arm64/inst/load_store_exclusive.rs109
-rw-r--r--yjit/src/asm/arm64/inst/logical_imm.rs154
-rw-r--r--yjit/src/asm/arm64/inst/logical_reg.rs207
-rw-r--r--yjit/src/asm/arm64/inst/mod.rs50
-rw-r--r--yjit/src/asm/arm64/inst/mov.rs155
-rw-r--r--yjit/src/asm/arm64/inst/nop.rs44
-rw-r--r--yjit/src/asm/arm64/inst/pc_rel.rs107
-rw-r--r--yjit/src/asm/arm64/inst/reg_pair.rs212
-rw-r--r--yjit/src/asm/arm64/inst/sbfm.rs103
-rw-r--r--yjit/src/asm/arm64/inst/shift_imm.rs147
-rw-r--r--yjit/src/asm/arm64/inst/sys_reg.rs86
-rw-r--r--yjit/src/asm/arm64/inst/test_bit.rs133
-rw-r--r--yjit/src/asm/arm64/mod.rs1580
-rw-r--r--yjit/src/asm/arm64/opnd.rs195
-rw-r--r--yjit/src/asm/mod.rs792
-rw-r--r--yjit/src/asm/x86_64/mod.rs1415
-rw-r--r--yjit/src/asm/x86_64/tests.rs449
-rw-r--r--yjit/src/backend/arm64/mod.rs1491
-rw-r--r--yjit/src/backend/ir.rs1576
-rw-r--r--yjit/src/backend/mod.rs8
-rw-r--r--yjit/src/backend/tests.rs331
-rw-r--r--yjit/src/backend/x86_64/mod.rs895
-rw-r--r--yjit/src/codegen.rs7721
-rw-r--r--yjit/src/core.rs2400
-rw-r--r--yjit/src/cruby.rs715
-rw-r--r--yjit/src/cruby_bindings.inc.rs1310
-rw-r--r--yjit/src/disasm.rs269
-rw-r--r--yjit/src/invariants.rs567
-rw-r--r--yjit/src/lib.rs18
-rw-r--r--yjit/src/options.rs174
-rw-r--r--yjit/src/stats.rs640
-rw-r--r--yjit/src/utils.rs274
-rw-r--r--yjit/src/virtualmem.rs443
-rw-r--r--yjit/src/yjit.rs136
-rw-r--r--yjit/yjit.mk69
4659 files changed, 828659 insertions, 259329 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000000..05ff204541
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,134 @@
+---
+version: '{build}'
+init:
+ - git config --global user.name git
+ - git config --global user.email svn-admin@ruby-lang.org
+ - git config --global core.autocrlf false
+ - git config --global core.eol lf
+ - git config --global advice.detachedHead 0
+shallow_clone: true
+clone_depth: 10
+platform:
+ - x64
+skip_commits:
+ message: /\[DOC\]/
+ files:
+ - doc/*
+ - '**/*.md'
+ - '**/*.rdoc'
+ - '**/.document'
+ - '**/*.[1-8]'
+ - '**/*.ronn'
+environment:
+ ruby_version: "24-%Platform%"
+ matrix:
+ # Test only the oldest supported version because AppVeyor is unstable, its concurrency
+ # is limited, and compatibility issues that happen only in newer versions are rare.
+ # You may test some other stuff on GitHub Actions instead.
+ - build: vs
+ vs: 120 # Visual Studio 2013
+ ssl: OpenSSL-v111
+ # The worker image name. This is NOT the Visual Studio version we're using here.
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ GEMS_FOR_TEST: ""
+ RELINE_TEST_ENCODING: "UTF-8"
+cache:
+ - c:\Tools\vcpkg\installed\
+for:
+-
+ matrix:
+ only:
+ - build: vs
+ install:
+ - ver
+ - chcp
+ - SET BITS=%Platform:x86=32%
+ - SET BITS=%BITS:x=%
+ - SET OPENSSL_DIR=C:\%ssl%-Win%BITS%
+ - cd C:\Tools\vcpkg
+ - git pull -q
+ - .\bootstrap-vcpkg.bat
+ - ps: Start-FileDownload 'https://github.com/microsoft/vcpkg-tool/releases/download/2023-08-09/vcpkg.exe' -FileName 'C:\Tools\vcpkg\vcpkg.exe'
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - vcpkg --triplet %Platform%-windows install --x-use-aria2 libffi libyaml readline zlib
+ - CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
+ - SET vcvars
+ - '"%vcvars%" %Platform:x64=amd64%'
+ - SET ruby_path=C:\Ruby%ruby_version:-x86=%
+ - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
+ - ruby --version
+ - 'cl'
+ - echo> Makefile srcdir=.
+ - echo>> Makefile MSC_VER=0
+ - echo>> Makefile RT=none
+ - echo>> Makefile RT_VER=0
+ - echo>> Makefile BUILTIN_ENCOBJS=nul
+ - type win32\Makefile.sub >> Makefile
+ - nmake %mflags% up VCSUP="echo Update OK"
+ - nmake %mflags% extract-extlibs
+ - del Makefile
+ - mkdir \usr\local\bin
+ - mkdir \usr\local\include
+ - mkdir \usr\local\lib
+ - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I
+ - for %%I in (c:\Tools\vcpkg\installed\%Platform%-windows\bin\*.dll) do (
+ if not %%~nI == readline mklink \usr\local\bin\%%~nxI %%I
+ )
+ - attrib +r /s /d
+ - mkdir %Platform%-mswin_%vs%
+ build_script:
+ - set HAVE_GIT=no
+ - cd %APPVEYOR_BUILD_FOLDER%
+ - cd %Platform%-mswin_%vs%
+ - >-
+ ..\win32\configure.bat
+ --with-opt-dir="/usr/local;c:/Tools/vcpkg/installed/%Platform%-windows"
+ --with-openssl-dir=%OPENSSL_DIR:\=/%
+ - nmake -l
+ - nmake install-nodoc
+ - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')"
+ - if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST%
+ - \usr\bin\ruby -ropenssl -e "puts 'Build ' + OpenSSL::OPENSSL_VERSION, 'Runtime ' + OpenSSL::OPENSSL_LIBRARY_VERSION"
+ test_script:
+ - set /a JOBS=%NUMBER_OF_PROCESSORS%
+ - nmake -l "TESTOPTS=-v -q" btest
+ - nmake -l "TESTOPTS=-v -q" test-basic
+ - >-
+ nmake -l "TESTOPTS=--timeout-scale=3.0
+ --excludes=../test/excludes/_appveyor -j%JOBS%
+ --exclude win32ole
+ --exclude test_bignum
+ --exclude test_syntax
+ --exclude test_open-uri
+ --exclude test_bundled_ca
+ " test-all
+ # separately execute tests without -j which may crash worker with -j.
+ - >-
+ nmake -l
+ "TESTOPTS=--timeout-scale=3.0 --excludes=../test/excludes/_appveyor"
+ TESTS="
+ ../test/win32ole
+ ../test/ruby/test_bignum.rb
+ ../test/ruby/test_syntax.rb
+ ../test/open-uri/test_open-uri.rb
+ ../test/rubygems/test_bundled_ca.rb
+ " test-all
+ - nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows
+notifications:
+ - provider: Webhook
+ method: POST
+ url:
+ secure: CcFlJNDJ/a6to7u3Z4Fnz6dScEPNx7hTha2GkSRlV+1U6dqmxY/7uBcLXYb9gR3jfQk6w+2o/HrjNAyXMNGU/JOka3s2WRI4VKitzM+lQ08owvJIh0R7LxrGH0J2e81U # ruby-lang slack: ruby/simpler-alerts-bot
+ body: >-
+ {{^isPullRequest}}
+ {
+ "ci": "AppVeyor CI",
+ "env": "Visual Studio 2013",
+ "url": "{{buildUrl}}",
+ "commit": "{{commitId}}",
+ "branch": "{{branch}}"
+ }
+ {{/isPullRequest}}
+ on_build_success: false
+ on_build_failure: true
+ on_build_status_changed: false
diff --git a/.document b/.document
index 8616203552..3a6b0c238c 100644
--- a/.document
+++ b/.document
@@ -10,17 +10,26 @@
# prelude
prelude.rb
rbconfig.rb
+
array.rb
ast.rb
dir.rb
gc.rb
-integer.rb
io.rb
kernel.rb
+marshal.rb
+mjit.rb
+numeric.rb
+nilclass.rb
pack.rb
+ractor.rb
+string.rb
+symbol.rb
+timev.rb
+thread_sync.rb
trace_point.rb
warning.rb
-ractor.rb
+yjit.rb
# the lib/ directory (which has its own .document file)
lib
@@ -36,7 +45,6 @@ README.ja.md
COPYING
COPYING.ja
-CONTRIBUTING.md
LEGAL
diff --git a/.gdbinit b/.gdbinit
index 49380951b8..34d044caf6 100644
--- a/.gdbinit
+++ b/.gdbinit
@@ -544,13 +544,13 @@ end
define rp_class
printf "(struct RClass *) %p", (void*)$arg0
- if ((struct RClass *)($arg0))->ptr.origin_ != $arg0
- printf " -> %p", ((struct RClass *)($arg0))->ptr.origin_
+ if RCLASS_ORIGIN((struct RClass *)($arg0)) != $arg0
+ printf " -> %p", RCLASS_ORIGIN((struct RClass *)($arg0))
end
printf "\n"
rb_classname $arg0
print/x *(struct RClass *)($arg0)
- print *((struct RClass *)($arg0))->ptr
+ print *RCLASS_EXT((struct RClass *)($arg0))
end
document rp_class
Print the content of a Class/Module.
@@ -979,8 +979,8 @@ end
define rb_ps_vm
print $ps_vm = (rb_vm_t*)$arg0
- set $ps_thread_ln = $ps_vm->living_threads.n.next
- set $ps_thread_ln_last = $ps_vm->living_threads.n.prev
+ set $ps_thread_ln = $ps_vm->ractor.main_ractor.threads.set.n.next
+ set $ps_thread_ln_last = $ps_vm->ractor.main_ractor.threads.set.n.prev
while 1
set $ps_thread_th = (rb_thread_t *)$ps_thread_ln
set $ps_thread = (VALUE)($ps_thread_th->self)
@@ -1102,11 +1102,11 @@ define print_id
set $arylen = $ary->as.heap.len
end
set $result = $aryptr[($serial % ID_ENTRY_UNIT) * ID_ENTRY_SIZE + $t]
- if $result != RUBY_Qnil
+ if $result != RUBY_Qnil
print_string $result
- else
- echo undef
- end
+ else
+ echo undef
+ end
end
end
end
@@ -1324,8 +1324,7 @@ define print_flags
printf "RUBY_FL_PROMOTED0 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_PROMOTED0 ? "1" : "0"
printf "RUBY_FL_PROMOTED1 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_PROMOTED1 ? "1" : "0"
printf "RUBY_FL_FINALIZE : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_FINALIZE ? "1" : "0"
- printf "RUBY_FL_TAINT : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_TAINT ? "1" : "0"
- printf "RUBY_FL_UNTRUSTED : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_UNTRUSTED ? "1" : "0"
+ printf "RUBY_FL_SHAREABLE : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_SHAREABLE ? "1" : "0"
printf "RUBY_FL_EXIVAR : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_EXIVAR ? "1" : "0"
printf "RUBY_FL_FREEZE : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_FREEZE ? "1" : "0"
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000000..6c5eac5a0f
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,23 @@
+# This is a file used by GitHub to ignore the following commits on `git blame`.
+#
+# You can also do the same thing in your local repository with:
+# $ git config --local blame.ignoreRevsFile .git-blame-ignore-revs
+
+# Expand tabs
+5b21e94bebed90180d8ff63dad03b8b948361089
+
+# Enable Style/StringLiterals cop for RubyGems/Bundler
+d7ffd3fea402239b16833cc434404a7af82d44f3
+
+# [ruby/digest] Revert tab-expansion in external files
+48b09aae7ec5632209229dcc294dd0d75a93a17f
+8a65cf3b61c60e4cb886f59a73ff6db44364bfa9
+39dc9f9093901d40d2998653948d5da38b18ee2c
+
+# [ruby/io-nonblock] Revert tab expansion
+f28287d34c03f472ffe90ea262bdde9affd4b965
+0d842fecb4f75ab3b1d4097ebdb8e88f51558041
+4ba2c66761d6a293abdfba409241d31063cefd62
+
+# Make benchmark indentation consistent
+fc4acf8cae82e5196186d3278d831f2438479d91
diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
index 7196708b21..91f82b842b 100644
--- a/.github/codeql/codeql-config.yml
+++ b/.github/codeql/codeql-config.yml
@@ -1,4 +1,3 @@
name: "CodeQL config for the Ruby language"
-paths-ignore:
- - '/ext/**/*/conftest.c'
+languages: cpp
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000..bc63aca35b
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: 'github-actions'
+ directory: '/'
+ schedule:
+ interval: 'monthly'
diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml
index bdb9011f25..ebaafe3bf0 100644
--- a/.github/workflows/baseruby.yml
+++ b/.github/workflows/baseruby.yml
@@ -1,12 +1,40 @@
name: BASERUBY Check
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
jobs:
baseruby:
name: BASERUBY
- runs-on: ubuntu-20.04
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
strategy:
matrix:
ruby:
@@ -15,24 +43,29 @@ jobs:
# - ruby-2.4
# - ruby-2.5
# - ruby-2.6
- - ruby-2.7
+# - ruby-2.7
+ - ruby-3.0
+ - ruby-3.1
steps:
- - uses: actions/checkout@v2
- - uses: ruby/setup-ruby@v1
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
- - run: echo "make=make -sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - run: sudo apt-get install build-essential autoconf bison
- - run: autoconf
+ - run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: sudo apt-get install build-essential autoconf bison libyaml-dev
+ - run: ./autogen.sh
- run: ./configure --disable-install-doc
- - run: $make update-unicode
- - run: $make common-srcs
- - run: $make incs
- - run: $make all
- - run: $make test
- - uses: k0kubun/action-slack@v2.0.0
+ - run: make common-srcs
+ - run: make incs
+ - run: make all
+ - run: make test
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
@@ -40,8 +73,8 @@ jobs:
"env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml
new file mode 100644
index 0000000000..070c0fa1dd
--- /dev/null
+++ b/.github/workflows/bundled_gems.yml
@@ -0,0 +1,166 @@
+name: bundled_gems
+
+on:
+ push:
+ branches: [ "master" ]
+ paths:
+ - '.github/workflows/bundled_gems.yml'
+ - 'gems/bundled_gems'
+ pull_request:
+ branches: [ "master" ]
+ paths:
+ - '.github/workflows/bundled_gems.yml'
+ - 'gems/bundled_gems'
+ merge_group:
+ branches: [ "master" ]
+ paths:
+ - '.github/workflows/bundled_gems.yml'
+ - 'gems/bundled_gems'
+ schedule:
+ - cron: '45 6 * * *'
+ workflow_dispatch:
+
+permissions: # added using https://github.com/step-security/secure-workflows
+ contents: read
+
+jobs:
+ update:
+ permissions:
+ contents: write # for Git to git push
+ if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }}
+ name: update ${{ github.workflow }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ echo "TODAY=$(date +%F)" >> $GITHUB_ENV
+
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache-${{ github.sha }}
+ restore-keys: |
+ downloaded-cache
+
+ - name: Download previous gems list
+ run: |
+ data=bundled_gems.json
+ mkdir -p .downloaded-cache
+ ln -s .downloaded-cache/$data .
+ curl -O -R -z ./$data https://stdgems.org/$data
+
+ - name: Update bundled gems list
+ run: |
+ ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems
+
+ - name: Maintain updated gems list in NEWS
+ run: |
+ #!ruby
+ require 'json'
+ news = File.read("NEWS.md")
+ prev = news[/since the \*+(\d+\.\d+\.\d+)\*+/, 1]
+ prevs = [prev, prev.sub(/\.\d+\z/, '')]
+ %W[bundled].each do |type|
+ last = JSON.parse(File.read("#{type}_gems.json"))['gems'].filter_map do |g|
+ v = g['versions'].values_at(*prevs).compact.first
+ g = g['gem']
+ g = 'RubyGems' if g == 'rubygems'
+ [g, v] if v
+ end.to_h
+ changed = File.foreach("gems/#{type}_gems").filter_map do |l|
+ next if l.start_with?("#")
+ g, v = l.split(" ", 3)
+ [g, v] unless last[g] == v
+ end
+ changed, added = changed.partition {|g, _| last[g]}
+ news.sub!(/^\*( +)The following #{type} gems? are updated\.\n+\K(?: \1\*( +).*\n)*/) do
+ mark = "#{$1} *#{$2}"
+ changed.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
+ end or next
+ news.sub!(/^\*( +)The following default gems are now bundled gems\.\n+\K(?: \1\*( +).*\n)*/) do
+ mark = "#{$1} *#{$2}"
+ added.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
+ end or next unless added.empty?
+ File.write("NEWS.md", news)
+ end
+ shell: ruby {0}
+
+ - name: Check diffs
+ id: diff
+ run: |
+ git add -- NEWS.md
+ git diff --no-ext-diff --ignore-submodules --quiet -- gems/bundled_gems
+ continue-on-error: true
+
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
+ if: ${{ steps.diff.outcome == 'failure' }}
+
+ - name: Build
+ run: |
+ ./autogen.sh
+ ./configure -C --disable-install-doc
+ make
+ if: ${{ steps.diff.outcome == 'failure' }}
+
+ - name: Prepare bundled gems
+ run: |
+ make -s prepare-gems
+ if: ${{ steps.diff.outcome == 'failure' }}
+
+ - name: Test bundled gems
+ run: |
+ make -s test-bundled-gems
+ git add -- gems/bundled_gems
+ timeout-minutes: 30
+ env:
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ if: ${{ steps.diff.outcome == 'failure' }}
+
+ - name: Show diffs
+ id: show
+ run: |
+ git diff --cached --color --no-ext-diff --ignore-submodules --exit-code --
+ continue-on-error: true
+
+ - name: Commit
+ run: |
+ git pull --ff-only origin ${GITHUB_REF#refs/heads/}
+ message="Update bundled gems list at "
+ if [ ${{ steps.diff.outcome }} = success ]; then
+ git commit --message="${message}${GITHUB_SHA:0:30} [ci skip]"
+ else
+ git commit --message="${message}${TODAY}"
+ fi
+ git push origin ${GITHUB_REF#refs/heads/}
+ env:
+ EMAIL: svn-admin@ruby-lang.org
+ GIT_AUTHOR_NAME: git
+ GIT_COMMITTER_NAME: git
+ if: ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && steps.show.outcome == 'failure' }}
+
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / update",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/check_branch.yml b/.github/workflows/check_branch.yml
deleted file mode 100644
index 37cf3a9a8f..0000000000
--- a/.github/workflows/check_branch.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-# We bidirectionally synchronize github.com/ruby/ruby.git's master branch and
-# git.ruby-lang.org/ruby.git's master branch.
-# We can use a pull request's merge button only on the master branch.
-#
-# Therefore, we require to pass this "check_branch" on all protected branches
-# to prevent us from accidentally pushing commits to GitHub directly.
-#
-# Details: https://bugs.ruby-lang.org/issues/16094
-name: Pull Request
-on: [pull_request]
-jobs:
- check_branch:
- runs-on: ubuntu-latest
- steps:
- - name: Check if branch is master
- run: |
- if [ "$BASE_REF" != master ]; then
- echo "Only master branch accepts a pull request, but it's '$BASE_REF'."
- exit 1
- fi
- env:
- BASE_REF: ${{ github.base_ref }}
diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml
index c878caddeb..79b2916feb 100644
--- a/.github/workflows/check_dependencies.yml
+++ b/.github/workflows/check_dependencies.yml
@@ -1,36 +1,69 @@
name: Check Dependencies
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
jobs:
update-deps:
strategy:
matrix:
- os: [ubuntu-20.04, macos-latest]
+ os: [ubuntu-22.04]
fail-fast: true
runs-on: ${{ matrix.os }}
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- name: Install libraries
run: |
set -x
sudo apt-get update -q || :
- sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
- if: "contains(matrix.os, 'ubuntu')"
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
+ if: ${{ contains(matrix.os, 'ubuntu') }}
- name: Install libraries
run: |
- brew upgrade
- brew install gdbm gmp libffi openssl@1.1 zlib autoconf automake libtool readline
- if: "contains(matrix.os, 'macos')"
+ brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline
+ if: ${{ contains(matrix.os, 'macos') }}
- name: git config
run: |
git config --global advice.detachedHead 0
- - uses: actions/checkout@v2
- - run: autoconf
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
+ - run: ./autogen.sh
- name: Run configure
run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g'
- run: make all golf
- run: ruby tool/update-deps --fix
- run: git diff --no-ext-diff --ignore-submodules --exit-code
- - uses: k0kubun/action-slack@v2.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
@@ -38,8 +71,8 @@ jobs:
"env": "${{ matrix.os }} / Dependencies need to update",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
deleted file mode 100644
index 2f4bbc7093..0000000000
--- a/.github/workflows/check_misc.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: Miscellaneous checks
-on: [push, pull_request]
-
-jobs:
- checks:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Check if C-sources are US-ASCII
- run: |
- ! grep -r -n '[^ -~]' *.[chy] include internal win32/*.[ch]
- - name: Check for header macros
- run: |
- ! for header in ruby/*.h; do \
- git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null || echo $header
- done | grep -F .
- working-directory: include
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 9fbabd35c6..8dba76fbe2 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,43 +1,75 @@
name: "Code scanning - action"
on:
- push:
- pull_request:
+ # push:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
+ # pull_request:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
schedule:
- - cron: '0 12 * * 4'
+ - cron: '0 12 * * *'
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions: # added using https://github.com/step-security/secure-workflows
+ contents: read
jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest and windows-latest
+ permissions:
+ actions: read # for github/codeql-action/init to get workflow details
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/autobuild to send a status report
runs-on: ubuntu-latest
+ # CodeQL fails to run pull requests from dependabot due to missing write access to upload results.
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') && github.event.head_commit.pusher.name != 'dependabot[bot]' }}
+
+ env:
+ enable_install_doc: no
steps:
- name: Install libraries
run: |
set -x
sudo apt-get update -q || :
- sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
- name: Checkout repository
- uses: actions/checkout@v2
- with:
- fetch-depth: 2
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - run: git checkout HEAD^2
- if: ${{ github.event_name == 'pull_request' }}
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: .downloaded-cache
+ key: downloaded-cache
- name: Remove an obsolete rubygems vendored file
run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
- name: Initialize CodeQL
- uses: github/codeql-action/init@v1
+ uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
with:
- languages: cpp
config-file: ./.github/codeql/codeql-config.yml
+ trap-caching: false
+
+ - name: Set ENV
+ run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml
index a133ac6ef4..caf12cc0f4 100644
--- a/.github/workflows/compilers.yml
+++ b/.github/workflows/compilers.yml
@@ -1,17 +1,39 @@
name: Compilations
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.rdoc'
+ - '**/.document'
-# Github actions does not support YAML anchors. This creative use of
-# environment variables (plus the "echo ::set-env" hack) is to reroute that
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+# GitHub actions does not support YAML anchors. This creative use of
+# environment variables (plus the "echo $GITHUB_ENV" hack) is to reroute that
# restriction.
env:
- default_cc: clang-11
+ default_cc: clang-15
append_cc: ''
- crosshost: ''
# -O1 is faster than -O3 in our tests... Majority of time are consumed trying
- # to optimize binaries. Also Github Actions runs on a relatively modern CPU
+ # to optimize binaries. Also GitHub Actions run on relatively modern CPUs
# compared to, say, GCC 4 or Clang 3. We don't specify `-march=native`
# because compilers tend not understand what the CPU is.
optflags: '-O1'
@@ -41,164 +63,206 @@ env:
--color=always
--tty=no
+permissions:
+ contents: read
+
jobs:
compile:
strategy:
fail-fast: false
matrix:
+ env:
+ - {}
entry:
- - { key: default_cc, name: gcc-10, value: gcc-10 }
-# - { key: default_cc, name: gcc-9, value: gcc-9 }
-# - { key: default_cc, name: gcc-8, value: gcc-8 }
-# - { key: default_cc, name: gcc-7, value: gcc-7 }
-# - { key: default_cc, name: gcc-6, value: gcc-6 }
-# - { key: default_cc, name: gcc-5, value: gcc-5 }
- - { key: default_cc, name: gcc-4.8, value: gcc-4.8 }
- - { key: default_cc, name: clang-12, value: clang-12 }
-# - { key: default_cc, name: clang-11, value: clang-11 }
-# - { key: default_cc, name: clang-10, value: clang-10 }
-# - { key: default_cc, name: clang-9, value: clang-9 }
-# - { key: default_cc, name: clang-8, value: clang-8 }
-# - { key: default_cc, name: clang-7, value: clang-7 }
-# - { key: default_cc, name: clang-6.0, value: clang-6.0 }
-# - { key: default_cc, name: clang-5.0, value: clang-5.0 }
-# - { key: default_cc, name: clang-4.0, value: clang-4.0 }
- - { key: default_cc, name: clang-3.9, value: clang-3.9 }
-
- - { key: crosshost, name: aarch64-linux-gnu, value: aarch64-linux-gnu }
-# - { key: crosshost, name: arm-linux-gnueabi, value: arm-linux-gnueabi }
-# - { key: crosshost, name: arm-linux-gnueabihf, value: arm-linux-gnueabihf }
-# - { key: crosshost, name: i686-w64-mingw32, value: i686-w64-mingw32 }
-# - { key: crosshost, name: powerpc-linux-gnu, value: powerpc-linux-gnu }
- - { key: crosshost, name: powerpc64le-linux-gnu, value: powerpc64le-linux-gnu }
- - { key: crosshost, name: s390x-linux-gnu, value: s390x-linux-gnu }
- - { key: crosshost, name: x86_64-w64-mingw32, value: x86_64-w64-mingw32 }
-
- - { key: append_cc, name: c99, value: '-std=c99 -Werror=pedantic -pedantic-errors' }
-# - { key: append_cc, name: c11, value: '-std=c11 -Werror=pedantic -pedantic-errors' }
-# - { key: append_cc, name: c17, value: '-std=c17 -Werror=pedantic -pedantic-errors' }
- - { key: append_cc, name: c2x, value: '-std=c2x -Werror=pedantic -pedantic-errors' }
- - { key: CXXFLAGS, name: c++98, value: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
-# - { key: CXXFLAGS, name: c++11, value: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
-# - { key: CXXFLAGS, name: c++14, value: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
-# - { key: CXXFLAGS, name: c++17, value: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
- - { key: CXXFLAGS, name: c++2a, value: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }
-
- - { key: optflags, name: '-O0', value: '-O0 -march=x86-64 -mtune=generic' }
-# - { key: optflags, name: '-O3', value: '-O3 -march=x86-64 -mtune=generic' }
-
- - { key: append_configure, name: gmp, value: '--with-gmp' }
- - { key: append_configure, name: jemalloc, value: '--with-jemalloc' }
- - { key: append_configure, name: valgrind, value: '--with-valgrind' }
- - { key: append_configure, name: 'coroutine=ucontext', value: '--with-coroutine=ucontext' }
- - { key: append_configure, name: 'coroutine=copy', value: '--with-coroutine=copy' }
- - { key: append_configure, name: disable-jit-support, value: '--disable-jit-support' }
- - { key: append_configure, name: disable-dln, value: '--disable-dln' }
- - { key: append_configure, name: disable-rubygems, value: '--disable-rubygems' }
-
- - { key: cppflags, name: OPT_THREADED_CODE=1, value: '-DOPT_THREADED_CODE=1' }
- - { key: cppflags, name: OPT_THREADED_CODE=2, value: '-DOPT_THREADED_CODE=2' }
- - { key: cppflags, name: OPT_THREADED_CODE=3, value: '-DOPT_THREADED_CODE=3' }
-
- - { key: cppflags, name: NDEBUG, value: '-DNDEBUG' }
- - { key: cppflags, name: RUBY_DEBUG, value: '-DRUBY_DEBUG' }
-# - { key: cppflags, name: ARRAY_DEBUG, value: '-DARRAY_DEBUG' }
-# - { key: cppflags, name: BIGNUM_DEBUG, value: '-DBIGNUM_DEBUG' }
-# - { key: cppflags, name: CCAN_LIST_DEBUG, value: '-DCCAN_LIST_DEBUG' }
-# - { key: cppflags, name: CPDEBUG=-1, value: '-DCPDEBUG=-1' }
-# - { key: cppflags, name: ENC_DEBUG, value: '-DENC_DEBUG' }
-# - { key: cppflags, name: GC_DEBUG, value: '-DGC_DEBUG' }
-# - { key: cppflags, name: HASH_DEBUG, value: '-DHASH_DEBUG' }
-# - { key: cppflags, name: ID_TABLE_DEBUG, value: '-DID_TABLE_DEBUG' }
-# - { key: cppflags, name: RGENGC_DEBUG=-1, value: '-DRGENGC_DEBUG=-1' }
-# - { key: cppflags, name: SYMBOL_DEBUG, value: '-DSYMBOL_DEBUG' }
-# - { key: cppflags, name: THREAD_DEBUG=-1, value: '-DTHREAD_DEBUG=-1' }
-
-# - { key: cppflags, name: RGENGC_CHECK_MODE, value: '-DRGENGC_CHECK_MODE' }
-# - { key: cppflags, name: TRANSIENT_HEAP_CHECK_MODE, value: '-DTRANSIENT_HEAP_CHECK_MODE' }
-# - { key: cppflags, name: VM_CHECK_MODE, value: '-DVM_CHECK_MODE' }
-
- - { key: cppflags, name: USE_EMBED_CI=0, value: '-DUSE_EMBED_CI=0' }
- - { key: cppflags, name: USE_FLONUM=0, value: '-DUSE_FLONUM=0' }
-# - { key: cppflags, name: USE_GC_MALLOC_OBJ_INFO_DETAILS, value: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' }
- - { key: cppflags, name: USE_LAZY_LOAD, value: '-DUSE_LAZY_LOAD' }
-# - { key: cppflags, name: USE_RINCGC=0, value: '-DUSE_RINCGC=0' }
-# - { key: cppflags, name: USE_SYMBOL_GC=0, value: '-DUSE_SYMBOL_GC=0' }
-# - { key: cppflags, name: USE_THREAD_CACHE=0, value: '-DUSE_THREAD_CACHE=0' }
-# - { key: cppflags, name: USE_TRANSIENT_HEAP=0, value: '-DUSE_TRANSIENT_HEAP=0' }
-# - { key: cppflags, name: USE_RUBY_DEBUG_LOG=1, value: '-DUSE_RUBY_DEBUG_LOG=1' }
-
- - { key: cppflags, name: DEBUG_FIND_TIME_NUMGUESS, value: '-DDEBUG_FIND_TIME_NUMGUESS' }
- - { key: cppflags, name: DEBUG_INTEGER_PACK, value: '-DDEBUG_INTEGER_PACK' }
- - { key: cppflags, name: ENABLE_PATH_CHECK, value: '-DENABLE_PATH_CHECK' }
-
- - { key: cppflags, name: GC_DEBUG_STRESS_TO_CLASS, value: '-DGC_DEBUG_STRESS_TO_CLASS' }
-# - { key: cppflags, name: GC_ENABLE_LAZY_SWEEP=0, value: '-DGC_ENABLE_LAZY_SWEEP=0' }
-# - { key: cppflags, name: GC_PROFILE_DETAIL_MEMOTY, value: '-DGC_PROFILE_DETAIL_MEMOTY' }
-# - { key: cppflags, name: GC_PROFILE_MORE_DETAIL, value: '-DGC_PROFILE_MORE_DETAIL' }
-
-# - { key: cppflags, name: CALC_EXACT_MALLOC_SIZE, value: '-DCALC_EXACT_MALLOC_SIZE' }
-# - { key: cppflags, name: MALLOC_ALLOCATED_SIZE_CHECK, value: '-DMALLOC_ALLOCATED_SIZE_CHECK' }
-
-# - { key: cppflags, name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, value: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' }
-
-# - { key: cppflags, name: RGENGC_ESTIMATE_OLDMALLOC, value: '-DRGENGC_ESTIMATE_OLDMALLOC' }
-# - { key: cppflags, name: RGENGC_FORCE_MAJOR_GC, value: '-DRGENGC_FORCE_MAJOR_GC' }
-# - { key: cppflags, name: RGENGC_OBJ_INFO, value: '-DRGENGC_OBJ_INFO' }
-# - { key: cppflags, name: RGENGC_OLD_NEWOBJ_CHECK, value: '-DRGENGC_OLD_NEWOBJ_CHECK' }
-# - { key: cppflags, name: RGENGC_PROFILE, value: '-DRGENGC_PROFILE' }
-
-# - { key: cppflags, name: VM_DEBUG_BP_CHECK, value: '-DVM_DEBUG_BP_CHECK' }
-# - { key: cppflags, name: VM_DEBUG_VERIFY_METHOD_CACHE, value: '-DVM_DEBUG_VERIFY_METHOD_CACHE' }
-
- - { key: cppflags, name: MJIT_FORCE_ENABLE, value: '-DMJIT_FORCE_ENABLE' }
+ - { name: gcc-12, env: { default_cc: gcc-12 } }
+ - { name: gcc-11, env: { default_cc: gcc-11 } }
+ - { name: gcc-10, env: { default_cc: gcc-10 } }
+ - { name: gcc-9, env: { default_cc: gcc-9 } }
+ - { name: gcc-8, env: { default_cc: gcc-8 } }
+ - { name: gcc-7, env: { default_cc: gcc-7 } }
+ - name: 'gcc-13 LTO'
+ container: gcc-13
+ env:
+ default_cc: 'gcc-13 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch'
+ optflags: '-O2'
+ shared: disable
+ # check: true
+ - { name: clang-16, env: { default_cc: clang-16 } }
+ - { name: clang-15, env: { default_cc: clang-15 } }
+ - { name: clang-14, env: { default_cc: clang-14 } }
+ - { name: clang-13, env: { default_cc: clang-13 } }
+ - { name: clang-12, env: { default_cc: clang-12 } }
+ - { name: clang-11, env: { default_cc: clang-11 } }
+ - { name: clang-10, env: { default_cc: clang-10 } }
+ # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o.
+ - { name: clang-9, env: { default_cc: clang-9, append_configure: '--disable-yjit' } }
+ - { name: clang-8, env: { default_cc: clang-8, append_configure: '--disable-yjit' } }
+ - { name: clang-7, env: { default_cc: clang-7, append_configure: '--disable-yjit' } }
+ - { name: clang-6.0, env: { default_cc: clang-6.0, append_configure: '--disable-yjit' } }
+ - name: 'clang-16 LTO'
+ container: clang-16
+ env:
+ default_cc: 'clang-16 -flto=auto'
+ optflags: '-O2'
+ shared: disable
+ # check: true
+
+# - { name: aarch64-linux-gnu, crosshost: aarch64-linux-gnu, container: crossbuild-essential-arm64 }
+# - { name: arm-linux-gnueabi, crosshost: arm-linux-gnueabi }
+# - { name: arm-linux-gnueabihf, crosshost: arm-linux-gnueabihf }
+# - { name: i686-w64-mingw32, crosshost: i686-w64-mingw32 }
+# - { name: powerpc-linux-gnu, crosshost: powerpc-linux-gnu }
+# - { name: powerpc64le-linux-gnu, crosshost: powerpc64le-linux-gnu, container: crossbuild-essential-ppc64el }
+# - { name: s390x-linux-gnu, crosshost: s390x-linux-gnu, container: crossbuild-essential-s390x }
+# - { name: x86_64-w64-mingw32, crosshost: x86_64-w64-mingw32, container: mingw-w64 }
+
+ # -Wno-strict-prototypes is necessary with current clang-15 since
+ # older autoconf generate functions without prototype and -pedantic
+ # now implies strict-prototypes. Disabling the error but leaving the
+ # warning generates a lot of noise from use of ANYARGS in
+ # rb_define_method() and friends.
+ # See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94
+ - { name: c99, env: { append_cc: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+# - { name: c11, env: { append_cc: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+# - { name: c17, env: { append_cc: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+ - { name: c2x, env: { append_cc: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } }
+ - { name: c++98, env: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+# - { name: c++11, env: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+# - { name: c++14, env: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+# - { name: c++17, env: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+ - { name: c++2a, env: { CXXFLAGS: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } }
+
+ - { name: '-O0', env: { optflags: '-O0 -march=x86-64 -mtune=generic' } }
+# - { name: '-O3', env: { optflags: '-O3 -march=x86-64 -mtune=generic' }, check: true }
+
+ - { name: gmp, env: { append_configure: '--with-gmp' } }
+ - { name: jemalloc, env: { append_configure: '--with-jemalloc' } }
+ - { name: valgrind, env: { append_configure: '--with-valgrind' } }
+ - { name: 'coroutine=ucontext', env: { append_configure: '--with-coroutine=ucontext' } }
+ - { name: 'coroutine=pthread', env: { append_configure: '--with-coroutine=pthread' } }
+ - { name: disable-jit-support, env: { append_configure: '--disable-jit-support' } }
+ - { name: disable-dln, env: { append_configure: '--disable-dln' } }
+ - { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } }
+ - { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } }
+ - { name: RUBY_DEVEL, env: { append_configure: '--enable-devel' } }
+
+ - { name: OPT_THREADED_CODE=1, env: { cppflags: '-DOPT_THREADED_CODE=1' } }
+ - { name: OPT_THREADED_CODE=2, env: { cppflags: '-DOPT_THREADED_CODE=2' } }
+ - { name: OPT_THREADED_CODE=3, env: { cppflags: '-DOPT_THREADED_CODE=3' } }
+
+ - { name: NDEBUG, env: { cppflags: '-DNDEBUG' } }
+ - { name: RUBY_DEBUG, env: { cppflags: '-DRUBY_DEBUG' } }
+# - { name: ARRAY_DEBUG, env: { cppflags: '-DARRAY_DEBUG' } }
+# - { name: BIGNUM_DEBUG, env: { cppflags: '-DBIGNUM_DEBUG' } }
+# - { name: CCAN_LIST_DEBUG, env: { cppflags: '-DCCAN_LIST_DEBUG' } }
+# - { name: CPDEBUG=-1, env: { cppflags: '-DCPDEBUG=-1' } }
+# - { name: ENC_DEBUG, env: { cppflags: '-DENC_DEBUG' } }
+# - { name: GC_DEBUG, env: { cppflags: '-DGC_DEBUG' } }
+# - { name: HASH_DEBUG, env: { cppflags: '-DHASH_DEBUG' } }
+# - { name: ID_TABLE_DEBUG, env: { cppflags: '-DID_TABLE_DEBUG' } }
+# - { name: RGENGC_DEBUG=-1, env: { cppflags: '-DRGENGC_DEBUG=-1' } }
+# - { name: SYMBOL_DEBUG, env: { cppflags: '-DSYMBOL_DEBUG' } }
+
+# - { name: RGENGC_CHECK_MODE, env: { cppflags: '-DRGENGC_CHECK_MODE' } }
+# - { name: TRANSIENT_HEAP_CHECK_MODE, env: { cppflags: '-DTRANSIENT_HEAP_CHECK_MODE' } }
+# - { name: VM_CHECK_MODE, env: { cppflags: '-DVM_CHECK_MODE' } }
+
+ - { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=0' } }
+ - name: USE_FLONUM=0,
+ env:
+ cppflags: '-DUSE_FLONUM=0'
+ # yjit requires FLONUM for the pointer tagging scheme
+ append_configure: '--disable-yjit'
+# - { name: USE_GC_MALLOC_OBJ_INFO_DETAILS, env: { cppflags: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' } }
+ - { name: USE_LAZY_LOAD, env: { cppflags: '-DUSE_LAZY_LOAD' } }
+# - { name: USE_RINCGC=0, env: { cppflags: '-DUSE_RINCGC=0' } }
+# - { name: USE_SYMBOL_GC=0, env: { cppflags: '-DUSE_SYMBOL_GC=0' } }
+# - { name: USE_THREAD_CACHE=0, env: { cppflags: '-DUSE_THREAD_CACHE=0' } }
+# - { name: USE_TRANSIENT_HEAP=0, env: { cppflags: '-DUSE_TRANSIENT_HEAP=0' } }
+# - { name: USE_RUBY_DEBUG_LOG=1, env: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } }
+ - { name: USE_RVARGC=0, env: { cppflags: '-DUSE_RVARGC=0' } }
+# - { name: USE_RVARGC=1, env: { cppflags: '-DUSE_RVARGC=1' } }
+# - { name: USE_DEBUG_COUNTER, env: { cppflags: '-DUSE_DEBUG_COUNTER=1', RUBY_DEBUG_COUNTER_DISABLE: '1' } }
+
+ - { name: DEBUG_FIND_TIME_NUMGUESS, env: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } }
+ - { name: DEBUG_INTEGER_PACK, env: { cppflags: '-DDEBUG_INTEGER_PACK' } }
+# - { name: ENABLE_PATH_CHECK, env: { cppflags: '-DENABLE_PATH_CHECK' } }
+
+ - { name: GC_DEBUG_STRESS_TO_CLASS, env: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } }
+# - { name: GC_ENABLE_LAZY_SWEEP=0, env: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } }
+# - { name: GC_PROFILE_DETAIL_MEMOTY, env: { cppflags: '-DGC_PROFILE_DETAIL_MEMOTY' } }
+# - { name: GC_PROFILE_MORE_DETAIL, env: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } }
+
+# - { name: CALC_EXACT_MALLOC_SIZE, env: { cppflags: '-DCALC_EXACT_MALLOC_SIZE' } }
+# - { name: MALLOC_ALLOCATED_SIZE_CHECK, env: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' } }
+
+# - { name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, env: { cppflags: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' } }
+
+# - { name: RGENGC_ESTIMATE_OLDMALLOC, env: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } }
+# - { name: RGENGC_FORCE_MAJOR_GC, env: { cppflags: '-DRGENGC_FORCE_MAJOR_GC' } }
+# - { name: RGENGC_OBJ_INFO, env: { cppflags: '-DRGENGC_OBJ_INFO' } }
+# - { name: RGENGC_OLD_NEWOBJ_CHECK, env: { cppflags: '-DRGENGC_OLD_NEWOBJ_CHECK' } }
+# - { name: RGENGC_PROFILE, env: { cppflags: '-DRGENGC_PROFILE' } }
+
+# - { name: VM_DEBUG_BP_CHECK, env: { cppflags: '-DVM_DEBUG_BP_CHECK' } }
+# - { name: VM_DEBUG_VERIFY_METHOD_CACHE, env: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } }
+
+ - { name: MJIT_FORCE_ENABLE, env: { cppflags: '-DMJIT_FORCE_ENABLE' } }
+ - { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' } }
name: ${{ matrix.entry.name }}
runs-on: ubuntu-latest
- container: ghcr.io/ruby/ruby-ci-image:latest
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ container:
+ image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || matrix.entry.env.default_cc || 'clang-15' }}
+ options: --user root
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ env: ${{ matrix.entry.env || matrix.env }}
steps:
+ - run: id
+ working-directory:
- run: mkdir build
working-directory:
- name: setenv
run: |
- echo "${{ matrix.entry.key }}=${{ matrix.entry.value }}" >> $GITHUB_ENV
- echo "make=make -sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - uses: actions/checkout@v2
+ echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - run: autoconf
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - run: ./autogen.sh
working-directory: src
- name: Run configure
- run: |
- if [ -n "${crosshost}" ]; then
- ../src/configure -C \
- ${default_configure} \
- ${append_configure} \
- --host="${crosshost}"
- else
- ../src/configure -C \
- ${default_configure} \
- ${append_configure} \
- --with-gcc="${default_cc} ${append_cc}"
- fi
- - run: $make extract-extlibs
- - run: $make incs
- - run: $make
- - run: $make leaked-globals
- - run: $make test
- - run: $make install
- if: "matrix.entry.name == '-O3'"
- - run: /usr/local/bin/gem install --no-doc timezone tzinfo
- if: "matrix.entry.name == '-O3'"
- - run: $make test-tool
- if: "matrix.entry.name == '-O3'"
- - run: $make test-all TESTS='-- ruby -ext-'
- if: "matrix.entry.name == '-O3'"
- - run: $make test-spec
- if: "matrix.entry.name == '-O3'"
-
- - uses: k0kubun/action-slack@v2.0.0
+ run: >
+ ../src/configure -C ${default_configure} ${append_configure}
+ --${{
+ matrix.entry.crosshost && 'host' || 'with-gcc'
+ }}=${{
+ matrix.entry.crosshost || '"${default_cc}${append_cc:+ $append_cc}"'
+ }}
+ --${{ matrix.entry.shared || 'enable' }}-shared
+ - run: make extract-extlibs
+ - run: make incs
+ - run: make showflags
+ - run: make
+ - run: make leaked-globals
+ - run: make test
+ - run: make install
+ if: ${{ matrix.entry.check }}
+ - run: make test-tool
+ if: ${{ matrix.entry.check }}
+ - run: make test-all TESTS='-- ruby -ext-'
+ if: ${{ matrix.entry.check }}
+ - run: make test-spec
+ env:
+ CHECK_LEAKS: true
+ if: ${{ matrix.entry.check }}
+ - run: make test-annocheck
+ if: ${{ matrix.entry.check && endsWith(matrix.entry.name, 'annocheck') }}
+
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
@@ -206,11 +270,11 @@ jobs:
"env": "${{ github.workflow }} / ${{ matrix.entry.name }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index f8572eb18f..d8dc58b119 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -1,65 +1,112 @@
name: macOS
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
jobs:
make:
- runs-on: macos-latest
strategy:
matrix:
- test_task: [ "check", "test-bundler-parallel", "test-bundled-gems" ]
+ test_task: ["check"] # "test-bundler-parallel", "test-bundled-gems"
+ os:
+ - macos-13
+ - macos-14
+ - macos-15
fail-fast: false
env:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ runs-on: ${{ matrix.os }}
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
working-directory:
- - name: Disable Firewall
- run: |
- sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
- sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
- name: git config
run: |
git config --global advice.detachedHead 0
- - uses: actions/checkout@v2
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: Install libraries
run: |
- export WAITS='5 60'
- tool/travis_retry.sh brew upgrade
- tool/travis_retry.sh brew install gdbm gmp libffi openssl@1.1 zlib autoconf automake libtool readline
+ brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline bison
working-directory: src
- name: Set ENV
run: |
- echo "JOBS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
- - run: autoconf
+ echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
+ echo "PATH="/usr/local/opt/bison/bin:/opt/homebrew/opt/bison/bin:$PATH"" >> $GITHUB_ENV
+ - run: ./autogen.sh
working-directory: src
- name: Run configure
run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline)
- - run: make $JOBS incs
- - run: make $JOBS
- - run: make leaked-globals
- if: matrix.test_task == 'check'
+ - run: make incs
- run: make prepare-gems
- if: matrix.test_task == 'check'
- - run: make $JOBS -s ${{ matrix.test_task }}
- timeout-minutes: 60
+ if: ${{ matrix.test_task == 'test-bundled-gems' }}
+ - run: make
+ - run: make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
+ - name: make ${{ matrix.test_task }}
+ run: |
+ make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
+ timeout-minutes: 40
env:
RUBY_TESTOPTS: "-q --tty=no"
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: "rexml"
- - uses: k0kubun/action-slack@v2.0.0
+ TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }}
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ PRECHECK_BUNDLED_GEMS: "no"
+ - name: make skipped tests
+ run: |
+ make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'`
+ env:
+ GNUMAKEFLAGS: ""
+ RUBY_TESTOPTS: "-v --tty=no"
+ TESTS: ${{ matrix.skipped_tests }}
+ PRECHECK_BUNDLED_GEMS: "no"
+ if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
+ continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
"ci": "GitHub Actions",
- "env": "${{ github.workflow }} / ${{ matrix.test_task }}",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml
index bdbcf3887e..0df917d3d8 100644
--- a/.github/workflows/mingw.yml
+++ b/.github/workflows/mingw.yml
@@ -1,143 +1,179 @@
name: MinGW
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
# Notes:
# Actions console encoding causes issues, see test-all & test-spec steps
#
jobs:
make:
- runs-on: windows-2019
+ runs-on: windows-2022
+ name: ${{ github.workflow }} (${{ matrix.msystem }})
env:
- MSYSTEM: MINGW64
- MSYSTEM_PREFIX: /mingw64
+ MSYSTEM: ${{ matrix.msystem }}
MSYS2_ARCH: x86_64
CHOST: "x86_64-w64-mingw32"
- CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong"
+ CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe"
CXXFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe"
CPPFLAGS: "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048"
- LDFLAGS: "-pipe -fstack-protector-strong"
+ LDFLAGS: "-pipe"
UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
strategy:
matrix:
- test_task: [ "check" ] # to make job names consistent
+ include:
+ # To mitigate flakiness of MinGW CI, we test only one runtime that newer MSYS2 uses.
+ - msystem: "UCRT64"
+ base_ruby: head
+ test_task: "check"
+ test-all-opts: "--name=!/TestObjSpace#test_reachable_objects_during_iteration/"
fail-fast: false
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
working-directory:
- name: git config
run: |
- git config --system core.autocrlf false
- git config --system core.eol lf
- git config --system advice.detachedHead 0
- - uses: actions/checkout@v2
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: Set up Ruby & MSYS2
- uses: MSP-Greg/setup-ruby-pkgs@v1
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
- ruby-version: 2.6
- mingw: _upgrade_ gdbm gmp libffi libyaml openssl ragel readline
- msys2: automake1.16 bison
+ ruby-version: ${{ matrix.base_ruby }}
+ - name: set env
+ run: |
+ echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV
+
- name: where check
run: |
# show where
- Write-Host
- $where = 'gcc.exe', 'ragel.exe', 'make.exe', 'bison.exe', 'libcrypto-1_1-x64.dll', 'libssl-1_1-x64.dll'
- foreach ($e in $where) {
- $rslt = where.exe $e 2>&1 | Out-String
- if ($rslt.contains($e)) { Write-Host $rslt }
- else { Write-Host "`nCan't find $e" }
- }
- - name: misc setup, autoreconf
+ mv /c/Windows/System32/libcrypto-1_1-x64.dll /c/Windows/System32/libcrypto-1_1-x64.dll_
+ mv /c/Windows/System32/libssl-1_1-x64.dll /c/Windows/System32/libssl-1_1-x64.dll_
+ result=true
+ for e in gcc.exe ragel.exe make.exe bison.exe libcrypto-1_1-x64.dll libssl-1_1-x64.dll; do
+ echo '##['group']'$'\033[93m'$e$'\033[m'
+ where $e || result=false
+ echo '##['endgroup']'
+ done
+ $result
+
+ - name: version check
run: |
- mkdir install
- mkdir temp
- cd src
- sh -c "autoreconf -fi"
- working-directory:
+ # show version
+ result=true
+ for e in gcc ragel make bison "openssl version"; do
+ case "$e" in *" "*) ;; *) e="$e --version";; esac
+ echo '##['group']'$'\033[93m'$e$'\033[m'
+ $e || result=false
+ echo '##['endgroup']'
+ done
+ $result
- - name: configure
+ - name: autogen
run: |
- # Actions uses UTF8, causes test failures, similar to normal OS setup
- $PSDefaultParameterValues['*:Encoding'] = 'utf8'
- [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- $config_args = "--build=$env:CHOST --host=$env:CHOST --target=$env:CHOST"
- Write-Host $config_args
- sh -c "../src/configure --disable-install-doc --prefix=/install $config_args"
- # Write-Host "-------------------------------------- config.log"
- # Get-Content ./config.log | foreach {Write-Output $_}
+ ./autogen.sh
+ working-directory: src
+
+ - name: configure
+ run: >
+ ../src/configure --disable-install-doc --prefix=/.
+ --build=$CHOST --host=$CHOST --target=$CHOST
- name: update
run: |
- $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
- make -j $jobs incs
+ make incs
- name: download gems
run: |
- $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
- make -j $jobs update-gems
+ make update-gems
- name: make all
- timeout-minutes: 40
+ timeout-minutes: 30
run: |
- $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS)
- make -j $jobs
+ make
- run: make leaked-globals
- name: make install
run: |
- # Actions uses UTF8, causes test failures, similar to normal OS setup
- $PSDefaultParameterValues['*:Encoding'] = 'utf8'
- [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- make DESTDIR=.. install-nodoc
+ make DESTDIR=../install install-nodoc
- name: test
timeout-minutes: 5
run: |
make test
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test'}}
- name: test-all
- timeout-minutes: 60
+ timeout-minutes: 45
run: |
# Actions uses UTF8, causes test failures, similar to normal OS setup
- $PSDefaultParameterValues['*:Encoding'] = 'utf8'
- [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- $jobs = [int](1.5 * $env:NUMBER_OF_PROCESSORS)
- if ($env:BUNDLER_VERSION) { Remove-Item env:\BUNDLER_VERSION }
- make test-all TESTOPTS="-j $jobs --retry --job-status=normal --show-skip --timeout-scale=1.5"
+ chcp.com 437
+ make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }}
+ env:
+ RUBY_TESTOPTS: >-
+ --retry --job-status=normal --show-skip --timeout-scale=1.5
+ ${{ matrix.test-all-opts }}
+ BUNDLER_VERSION:
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/')}}
- name: test-spec
timeout-minutes: 10
- working-directory: src/spec/ruby
run: |
- $env:Path = "$pwd/../../../install/bin;$env:Path"
- # Actions uses UTF8, causes test failures, similar to normal OS setup
- $PSDefaultParameterValues['*:Encoding'] = 'utf8'
- [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437")
- ruby -v
- ruby ../mspec/bin/mspec -I../../tool/lib -j
+ make ${{ StartsWith(matrix.test_task, 'spec/') && matrix.test_task || 'test-spec' }}
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/')}}
- - uses: k0kubun/action-slack@v2.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
"ci": "GitHub Actions",
- "env": "${{ github.workflow }} / ${{ matrix.test_task }}",
+ "env": "${{ github.workflow }} ${{ matrix.msystem }} / ${{ matrix.test_task }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
working-directory: build
+ shell: sh
diff --git a/.github/workflows/mjit-bindgen.yml b/.github/workflows/mjit-bindgen.yml
new file mode 100644
index 0000000000..26f8a1b2aa
--- /dev/null
+++ b/.github/workflows/mjit-bindgen.yml
@@ -0,0 +1,104 @@
+name: MJIT bindgen
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
+jobs:
+ make:
+ strategy:
+ matrix:
+ include:
+ - task: mjit-bindgen
+ fail-fast: false
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y \
+ build-essential \
+ libssl-dev libyaml-dev libreadline6-dev \
+ zlib1g-dev libncurses5-dev libffi-dev \
+ libclang1-14 \
+ bison autoconf
+ sudo apt-get install -q -y pkg-config || :
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
+ with:
+ ruby-version: '3.1'
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug
+ - run: make incs
+ - run: make
+ - run: make install
+ - run: make ${{ matrix.task }}
+ - run: git diff --exit-code
+ working-directory: src
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml
index 68889ecf3d..6f7181489a 100644
--- a/.github/workflows/mjit.yml
+++ b/.github/workflows/mjit.yml
@@ -1,17 +1,49 @@
name: MJIT
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ - '**.[1-8]'
+ - '**.ronn'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ - '**.[1-8]'
+ - '**.ronn'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
jobs:
make:
strategy:
matrix:
- test_task: [ "check" ] # to make job names consistent
- jit_opts: [ "--jit", "--jit-wait" ]
+ test_task: [check] # to make job names consistent
+ mjit_opts: [--mjit-wait]
fail-fast: false
runs-on: ubuntu-latest
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
env:
TESTOPTS: '-q --tty=no'
- RUN_OPTS: '--disable-gems ${{ matrix.jit_opts }} --jit-debug=-ggdb3'
+ RUN_OPTS: '--disable-gems ${{ matrix.mjit_opts }} --mjit-debug=-ggdb3'
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
steps:
- run: mkdir build
@@ -20,13 +52,18 @@ jobs:
run: |
set -x
sudo apt-get update -q || :
- sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
- name: git config
run: |
git config --global advice.detachedHead 0
- - uses: actions/checkout@v2
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: Fixed world writable dirs
run: |
chmod -v go-w $HOME $HOME/.config
@@ -34,43 +71,42 @@ jobs:
sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
- name: Set ENV
run: |
- echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - run: autoconf
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
working-directory: src
- name: Run configure
- run: ../src/configure -C --disable-install-doc
- - run: make $JOBS incs
- - run: make $JOBS
- - run: sudo make $JOBS -s install
- - run: sudo apt-get install gdb # used by test / test-all failure
+ run: ../src/configure -C --disable-install-doc cppflags=-DVM_CHECK_MODE
+ - run: make incs
+ - run: make
+ - run: sudo make -s install
- name: Run test
run: |
- ulimit -c unlimited
- make $JOBS -s test RUN_OPTS="$RUN_OPTS"
- timeout-minutes: 60
- - name: Run test-all
- run: |
- ulimit -c unlimited
- make $JOBS -s test-all RUN_OPTS="$RUN_OPTS"
+ unset GNUMAKEFLAGS
+ make -s test RUN_OPTS="$RUN_OPTS"
timeout-minutes: 60
+ # - name: Run test-all
+ # run: |
+ # ulimit -c unlimited
+ # make -s test-all RUN_OPTS="$RUN_OPTS"
+ # timeout-minutes: 60
- name: Run test-spec
run: |
- ulimit -c unlimited
- make $JOBS -s test-spec RUN_OPTS="$RUN_OPTS"
+ unset GNUMAKEFLAGS
+ make -s test-spec RUN_OPTS="$RUN_OPTS"
timeout-minutes: 60
- - uses: k0kubun/action-slack@v2.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
"ci": "GitHub Actions",
- "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.jit_opts }}",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.mjit_opts }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000000..5d4474d978
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,18 @@
+name: Start release workflow
+on:
+ push:
+ tags:
+ - '*'
+
+jobs:
+ notify:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build release package
+ run: |
+ curl -L -X POST \
+ -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/ruby/actions/dispatches \
+ -d '{"event_type": "${{ github.ref }}"}'
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
new file mode 100644
index 0000000000..c12a95362d
--- /dev/null
+++ b/.github/workflows/scorecards.yml
@@ -0,0 +1,72 @@
+# This workflow uses actions that are not certified by GitHub. They are provided
+# by a third-party and are governed by separate terms of service, privacy
+# policy, and support documentation.
+
+name: Scorecards supply-chain security
+on:
+ # For Branch-Protection check. Only the default branch is supported. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
+ branch_protection_rule:
+ # To guarantee Maintained check is occasionally updated. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
+ schedule:
+ - cron: '22 4 * * 2'
+ push:
+ branches: [ "master" ]
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecards analysis
+ runs-on: ubuntu-latest
+ permissions:
+ # Needed to upload the results to code-scanning dashboard.
+ security-events: write
+ # Needed to publish results and get a badge (see publish_results below).
+ id-token: write
+ # Uncomment the permissions below if installing in a private repository.
+ # contents: read
+ # actions: read
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@ea651e62978af7915d09fe2e282747c798bf2dab # v2.4.1
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if:
+ # - you want to enable the Branch-Protection check on a *public* repository, or
+ # - you are installing Scorecards on a *private* repository
+ # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
+ repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
+
+ # Public repositories:
+ # - Publish results to OpenSSF REST API for easy access by consumers
+ # - Allows the repository to include the Scorecard badge.
+ # - See https://github.com/ossf/scorecard-action#publishing-results.
+ # For private repositories:
+ # - `publish_results` will always be set to `false`, regardless
+ # of the value entered here.
+ publish_results: true
+
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
+ # format to the repository Actions tab.
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.27
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml
index bf053cdd05..4521195a2b 100644
--- a/.github/workflows/spec_guards.yml
+++ b/.github/workflows/spec_guards.yml
@@ -1,32 +1,62 @@
name: Rubyspec Version Guards Check
-on: [push, pull_request]
+on:
+ push:
+ paths:
+ - 'spec/**'
+ - '!spec/*.md'
+ pull_request:
+ paths:
+ - 'spec/**'
+ - '!spec/*.md'
+ merge_group:
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
jobs:
rubyspec:
name: Rubyspec
- runs-on: ubuntu-20.04
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+
+ runs-on: ubuntu-22.04
+
+ if: >-
+ ${{!(false
+ || contains(github.event.head_commit.message, '[DOC]')
+ || contains(github.event.head_commit.message, 'Document')
+ || contains(github.event.pull_request.title, '[DOC]')
+ || contains(github.event.pull_request.title, 'Document')
+ || contains(github.event.pull_request.labels.*.name, 'Document')
+ || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
+ )}}
+
strategy:
matrix:
# Specs from ruby/spec should still run on all supported Ruby versions.
# This also ensures the needed ruby_version_is guards are there, see spec/README.md.
ruby:
- - ruby-2.5
-# - ruby-2.6
- - ruby-2.7
- - ruby-3.0
+ - ruby-3.1
+ - ruby-3.2
steps:
- - uses: actions/checkout@v2
- - uses: ruby/setup-ruby@v1
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
+
- run: gem install webrick
+
- run: ruby ../mspec/bin/mspec
working-directory: spec/ruby
- - uses: k0kubun/action-slack@v2.0.0
+ env:
+ CHECK_LEAKS: true
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
@@ -34,8 +64,8 @@ jobs:
"env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() }}
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index 4bbedc867d..4fbca1170e 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -1,86 +1,145 @@
name: Ubuntu
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
jobs:
make:
strategy:
matrix:
- test_task: [ "check", "test-bundler-parallel", "test-bundled-gems", "test-all TESTS=--repeat-count=2" ]
- os:
- - ubuntu-20.04
-# - ubuntu-18.04
-# - ubuntu-16.04
- debug: ["", "-DRUBY_DEBUG"]
- exclude:
+ # main variables included in the job name
+ test_task: [check]
+ configure: [cppflags=-DRUBY_DEBUG] # default to use more assertions
+ arch: ['']
+ # specify all jobs with `include` to avoid testing duplicated things
+ include:
+ - test_task: check
+ - test_task: check
+ arch: i686
+ configure: '' # test without -DRUBY_DEBUG as well
+ - test_task: check
+ configure: "--enable-shared --enable-load-relative"
+ - test_task: test-all TESTS=--repeat-count=2
- test_task: test-bundler-parallel
- os: ubuntu-16.04
- test_task: test-bundled-gems
- os: ubuntu-16.04
- - test_task: "test-all TESTS=--repeat-count=2"
- os: ubuntu-16.04
- - os: ubuntu-16.04
- debug: -DRUBY_DEBUG
- - test_task: "test-all TESTS=--repeat-count=2"
- debug: -DRUBY_DEBUG
fail-fast: false
env:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
RUBY_DEBUG: ci
- runs-on: ${{ matrix.os }}
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }}
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
working-directory:
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- name: Install libraries
+ env:
+ arch: ${{matrix.arch}}
run: |
set -x
+ arch=${arch:+:${arch/i[3-6]86/i386}}
+ ${arch:+sudo dpkg --add-architecture ${arch#:}}
sudo apt-get update -q || :
- sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby
+ sudo apt-get install --no-install-recommends -q -y \
+ ${arch:+cross}build-essential${arch/:/-} \
+ libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \
+ zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \
+ bison autoconf ruby
+ sudo apt-get install -q -y pkg-config${arch} || :
- name: git config
run: |
git config --global advice.detachedHead 0
- - uses: actions/checkout@v2
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
- name: Fixed world writable dirs
run: |
chmod -v go-w $HOME $HOME/.config
sudo chmod -R go-w /usr/share
sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
- - name: Set ENV
- run: |
- echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - run: autoconf
+ - run: ./autogen.sh
working-directory: src
- name: Run configure
- run: ../src/configure -C --disable-install-doc cppflags=${{ matrix.debug }}
- - run: make $JOBS incs
- - run: make $JOBS
- - run: make leaked-globals
- if: matrix.test_task == 'check'
- - run: make prepare-gems
- if: matrix.test_task == 'check'
+ env:
+ arch: ${{matrix.arch}}
+ run: >-
+ $SETARCH ../src/configure -C --disable-install-doc ${{ matrix.configure }}
+ ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE}
+ - run: $SETARCH make incs
+ - run: $SETARCH make prepare-gems
+ if: ${{ matrix.test_task == 'test-bundled-gems' }}
+ - run: $SETARCH make
+ - run: $SETARCH make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
- name: Create dummy files in build dir
run: |
- ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
- if: matrix.test_task == 'check'
- - run: make $JOBS -s ${{ matrix.test_task }}
- timeout-minutes: 30
+ $SETARCH ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
+ if: ${{ matrix.test_task == 'check' }}
+ - name: make ${{ matrix.test_task }}
+ run: |
+ $SETARCH make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`}
+ timeout-minutes: 40
env:
RUBY_TESTOPTS: "-q --tty=no"
+ TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }}
TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
- - uses: k0kubun/action-slack@v2.0.0
+ PRECHECK_BUNDLED_GEMS: "no"
+ - name: make skipped tests
+ run: |
+ $SETARCH make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'`
+ env:
+ GNUMAKEFLAGS: ""
+ RUBY_TESTOPTS: "-v --tty=no"
+ TESTS: ${{ matrix.skipped_tests }}
+ if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
+ continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
"ci": "GitHub Actions",
- "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.debug }}",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml
new file mode 100644
index 0000000000..27920b5821
--- /dev/null
+++ b/.github/workflows/wasm.yml
@@ -0,0 +1,146 @@
+name: WebAssembly
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions: # added using https://github.com/step-security/secure-workflows
+ contents: read
+
+jobs:
+ make:
+ strategy:
+ matrix:
+ entry:
+# # wasmtime can't compile non-optimized Asyncified binary due to locals explosion
+# - { name: O0-debuginfo, optflags: "-O0", debugflags: "-g", wasmoptflags: "-O1" }
+# - { name: O1, optflags: "-O1", debugflags: "" , wasmoptflags: "-O1" }
+ - { name: O2, optflags: "-O2", debugflags: "" , wasmoptflags: "-O2" }
+# - { name: O3, optflags: "-O3", debugflags: "" , wasmoptflags: "-O3" }
+# # -O4 is equivalent to -O3 in clang, but it's different in wasm-opt
+# - { name: O4, optflags: "-O3", debugflags: "" , wasmoptflags: "-O4" }
+# - { name: Oz, optflags: "-Oz", debugflags: "" , wasmoptflags: "-Oz" }
+ fail-fast: false
+ env:
+ RUBY_TESTOPTS: '-q --tty=no'
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ WASI_SDK_VERSION_MAJOR: 14
+ WASI_SDK_VERSION_MINOR: 0
+ BINARYEN_VERSION: 109
+ WASMTIME_VERSION: v0.33.0
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - name: Install libraries
+ run: |
+ set -ex
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y ruby bison make autoconf git wget
+
+ wasi_sdk_deb="wasi-sdk_${WASI_SDK_VERSION_MAJOR}.${WASI_SDK_VERSION_MINOR}_amd64.deb"
+ wget "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION_MAJOR}/${wasi_sdk_deb}"
+ sudo dpkg -i "$wasi_sdk_deb"
+ rm -f "$wasi_sdk_deb"
+
+ mkdir build-sdk
+ pushd build-sdk
+
+ wasmtime_url="https://github.com/bytecodealliance/wasmtime/releases/download/${WASMTIME_VERSION}/wasmtime-${WASMTIME_VERSION}-x86_64-linux.tar.xz"
+ wget -O - "$wasmtime_url" | tar xJf -
+ sudo ln -fs "$PWD/wasmtime-${WASMTIME_VERSION}-x86_64-linux/wasmtime" /usr/local/bin/wasmtime
+
+ binaryen_tarball="binaryen-version_${BINARYEN_VERSION}-x86_64-linux.tar.gz"
+ binaryen_url="https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VERSION}/${binaryen_tarball}"
+ wget -O - "$binaryen_url" | tar xfz -
+ sudo ln -fs "$PWD/binaryen-version_${BINARYEN_VERSION}/bin/wasm-opt" /usr/local/bin/wasm-opt
+ working-directory: src
+ - name: Set ENV
+ run: |
+ echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
+ echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
+ with:
+ ruby-version: '3.0'
+ bundler: none
+
+ - name: Download config.guess with wasi version
+ run: |
+ rm tool/config.guess tool/config.sub
+ ruby tool/downloader.rb -d tool -e gnu config.guess config.sub
+ working-directory: src
+
+ - name: Run configure
+ run: |
+ ../src/configure \
+ --host wasm32-unknown-wasi \
+ --with-static-linked-ext \
+ LDFLAGS=" \
+ -Xlinker --stack-first \
+ -Xlinker -z -Xlinker stack-size=16777216 \
+ " \
+ optflags="${{ matrix.entry.optflags }}" \
+ debugflags="${{ matrix.entry.debugflags }}" \
+ wasmoptflags="${{ matrix.entry.wasmoptflags }} ${{ matrix.entry.debugflags }}"
+
+ # miniruby may not be built when cross-compling
+ - run: make mini ruby
+ - name: Run basictest
+ run: wasmtime run ./../build/miniruby --mapdir /::./ -- basictest/test.rb
+ working-directory: src
+ - name: Run bootstraptest (no thread)
+ run: |
+ NO_THREAD_TESTS="$(grep -L Thread -R ./bootstraptest | awk -F/ '{ print $NF }' | uniq | sed -n 's/test_\(.*\).rb/\1/p' | paste -s -d, -)"
+ ruby ./bootstraptest/runner.rb --ruby="$(which wasmtime) run $PWD/../build/ruby --mapdir /::./ -- " --verbose "--sets=$NO_THREAD_TESTS"
+ working-directory: src
+
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.name }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 98e59ae188..c2bd4881c2 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -1,78 +1,147 @@
name: Windows
-on: [push, pull_request]
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
jobs:
make:
strategy:
matrix:
- test_task: [test]
- os: [windows-2019]
- vs: [2019]
+ include:
+ - vs: 2022
+ vcvers: -vcvars_ver=14.2
fail-fast: false
- runs-on: ${{ matrix.os }}
+ runs-on: windows-${{ matrix.vs }}
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ name: VisualStudio ${{ matrix.vs }}
env:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
- VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ PATCH: C:\msys64\usr\bin\patch.exe
+ OS_VER: windows-${{ matrix.vs }}
steps:
- run: md build
working-directory:
- - uses: actions/cache@v2
+ - uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0
+ id: setup-msys2
with:
- path: C:\vcpkg\downloads
- key: ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-
- ${{ runner.os }}-vcpkg-download-
- - name: Install libraries with vcpkg
- run: |
- vcpkg --triplet x64-windows install readline zlib
- - uses: actions/cache@v2
+ update: true
+ install: bison patch
+ - name: patch path
+ shell: msys2 {0}
+ run: echo PATCH=$(cygpath -wa $(command -v patch)) >> $GITHUB_ENV
+ if: ${{ steps.setup-msys2.outcome == 'success' }}
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
- path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
- key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
+ path: C:\vcpkg\installed
+ key: ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-${{ github.sha }}
restore-keys: |
- ${{ runner.os }}-chocolatey-${{ matrix.os }}-
- ${{ runner.os }}-chocolatey-
- - name: Install libraries with chocolatey
+ ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-
+ ${{ runner.os }}-vcpkg-installed-windows-
+ - name: Install libraries with vcpkg
run: |
- choco install --no-progress openssl
- choco install --no-progress winflexbison3 --version=2.5.18.20190508
+ iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
+ Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
+ scoop install cmake@3.31.6
+ vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib
+ shell:
+ pwsh
- name: git config
run: |
- git config --system advice.detachedHead 0
- - uses: actions/checkout@v2
+ git config --global core.autocrlf false
+ git config --global core.eol lf
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - name: Configure
- run: |
- call "%VCVARS%"
- ../src/win32/configure.bat --disable-install-doc --without-ext=+,dbm,gdbm --enable-bundled-libffi --with-opt-dir=C:/vcpkg/installed/x64-windows --with-openssl-dir="C:/Program Files/OpenSSL-Win64"
- - name: nmake
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: setup env
+ # %TEMP% is inconsistent with %TMP% and test-all expects they are consistent.
+ # https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302
+ # msys2/setup-msys2 installs MSYS2 to D:/a/_temp/msys64/usr/bin
run: |
- call "%VCVARS%"
- set YACC=win_bison
- echo on
- nmake incs
- nmake extract-extlibs
- nmake
- - name: nmake test
- timeout-minutes: 30
+ set Path=D:/a/_temp/msys64/usr/bin;%Path%
+ if not "%VCVARS%" == "" goto :vcset
+ set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ :vcset
+ set | C:\msys64\usr\bin\sort > old.env
+ call %VCVARS% ${{ matrix.vcvers || ''}}
+ set TMP=%USERPROFILE%\AppData\Local\Temp
+ set TEMP=%USERPROFILE%\AppData\Local\Temp
+ set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul
+ set | C:\msys64\usr\bin\sort > new.env
+ C:\msys64\usr\bin\comm -13 old.env new.env >> %GITHUB_ENV%
+ del *.env
+ - name: compiler version
+ run: cl
+ - name: link libraries
run: |
- call "%VCVARS%"
- nmake ${{ matrix.test_task }}
- - uses: k0kubun/action-slack@v2.0.0
+ for %%I in (C:\vcpkg\installed\x64-windows\bin\*.dll) do (
+ if not %%~nI == readline mklink %%~nxI %%I
+ )
+ for %%I in (libcrypto-1_1-x64 libssl-1_1-x64) do (
+ ren c:\Windows\System32\%%I.dll %%I.dll_
+ )
+ - name: Configure
+ run: >-
+ ../src/win32/configure.bat --disable-install-doc
+ --with-opt-dir=C:/vcpkg/installed/x64-windows
+ - run: nmake incs
+ - run: nmake extract-extlibs
+ - run: nmake
+ env:
+ YACC: bison.exe
+ - run: nmake test
+ timeout-minutes: 5
+ - run: nmake test-spec
+ timeout-minutes: 10
+ - run: nmake test-all
+ env:
+ RUBY_TESTOPTS: -j${{env.TEST_JOBS}} --job-status=normal
+ timeout-minutes: 60
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
"ci": "GitHub Actions",
- "env": "${{ matrix.os }} / ${{ matrix.test_task }}",
+ "env": "VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }}",
"url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
- "branch": "${{ github.ref }}".split('/').reverse()[0]
+ "branch": "${{ github.ref_name }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: failure() && github.event_name == 'push'
+ if: ${{ failure() && github.event_name == 'push' }}
defaults:
run:
diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml
new file mode 100644
index 0000000000..0b7b9046e9
--- /dev/null
+++ b/.github/workflows/yjit-ubuntu.yml
@@ -0,0 +1,170 @@
+name: YJIT Ubuntu
+on:
+ push:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+
+concurrency:
+ group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
+ cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
+
+permissions:
+ contents: read
+
+jobs:
+ cargo:
+ name: Rust cargo test
+ # GitHub Action's image seems to already contain a Rust 1.58.0.
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ # For now we can't run cargo test --offline because it complains about the
+ # capstone dependency, even though the dependency is optional
+ #- run: cargo test --offline
+ - run: RUST_BACKTRACE=1 cargo test
+ working-directory: yjit
+ # Also compile and test with all features enabled
+ - run: RUST_BACKTRACE=1 cargo test --all-features
+ working-directory: yjit
+ # Check that we can build in release mode too
+ - run: cargo build --release
+ working-directory: yjit
+ make:
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - test_task: 'yjit-bindgen'
+ hint: 'To fix: use patch in logs'
+ configure: '--with-gcc=clang-14 --enable-yjit=dev'
+ libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1'
+
+ - test_task: "check"
+ # YJIT should be automatically built in release mode on x86-64 Linux with rustc present
+ #configure: "--enable-yjit RUSTC='rustc +1.58.0'"
+ configure: "RUSTC='rustc +1.58.0'"
+ rust_version: "1.58.0"
+
+ - test_task: "check"
+ configure: "--enable-yjit=dev"
+
+ - test_task: "check"
+ configure: "--enable-yjit=dev"
+ yjit_opts: "--yjit-call-threshold=1 --yjit-verify-ctx"
+
+ - test_task: "test-all TESTS=--repeat-count=2"
+ configure: "--enable-yjit=dev"
+
+ - test_task: "test-bundled-gems"
+ configure: "--enable-yjit=dev"
+
+ - test_task: "yjit-bench"
+ configure: "--enable-yjit=dev"
+ yjit_bench_opts: "--yjit-stats"
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ RUN_OPTS: ${{ matrix.yjit_opts }}
+ YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }}
+ RUBY_DEBUG: ci
+ BUNDLE_JOBS: 8 # for yjit-bench
+ runs-on: ubuntu-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ steps:
+ - run: mkdir build
+ working-directory:
+ - name: Install libraries
+ run: |
+ set -x
+ sudo apt-get update -q || :
+ sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
+ - name: Install Rust
+ if: ${{ matrix.rust_version }}
+ run: rustup install ${{ matrix.rust_version }} --profile minimal
+ - name: git config
+ run: |
+ git config --global advice.detachedHead 0
+ git config --global init.defaultBranch garbage
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ path: src
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ with:
+ path: src/.downloaded-cache
+ key: downloaded-cache
+ - name: Fixed world writable dirs
+ run: |
+ chmod -v go-w $HOME $HOME/.config
+ sudo chmod -R go-w /usr/share
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - name: Set ENV
+ run: |
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }}
+ - run: make incs
+ - run: make prepare-gems
+ if: ${{ matrix.test_task == 'test-bundled-gems' }}
+ - run: make -j
+ - run: make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
+ - name: Create dummy files in build dir
+ run: |
+ ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}'
+ if: ${{ matrix.test_task == 'check' }}
+ - name: Enable YJIT through ENV
+ run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV
+ # Check that the binary was built with YJIT
+ - name: Check YJIT enabled
+ run: ./miniruby --yjit -v | grep "+YJIT"
+ - name: make ${{ matrix.test_task }}
+ run: make -s -j ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS"
+ timeout-minutes: 60
+ env:
+ RUBY_TESTOPTS: "-q --tty=no"
+ TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
+ PRECHECK_BUNDLED_GEMS: "no"
+ LIBCLANG_PATH: ${{ matrix.libclang_path }}
+ continue-on-error: ${{ matrix.test_task == 'yjit-bench' }}
+ - name: Show ${{ github.event.pull_request.base.ref }} GitHub URL for yjit-bench comparison
+ run: echo "https://github.com/${BASE_REPO}/commit/${BASE_SHA}"
+ env:
+ BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }}
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
+ if: ${{ matrix.test_task == 'yjit-bench' && startsWith(github.event_name, 'pull') }}
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}",
+ "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
+ "commit": "${{ github.sha }}",
+ "branch": "${{ github.ref_name }}"
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
+ if: ${{ failure() && github.event_name == 'push' }}
+
+defaults:
+ run:
+ working-directory: build
diff --git a/.gitignore b/.gitignore
index 8d11d7278a..99d32a1825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,9 +10,11 @@
*.dylib
*.elc
*.i
+*.ii
*.inc
*.log
*.o
+*.o.tmp
*.obj
*.old
*.orig
@@ -24,6 +26,7 @@
*.sav
*.sl
*.so
+*.so.*
*.swp
*.yarb
*~
@@ -126,6 +129,7 @@ lcov*.info
/ruby-runner
/ruby-runner.h
/ruby-man.rd.gz
+/rubyspec_temp
/run.gdb
/sizes.c
/static-ruby
@@ -143,6 +147,8 @@ lcov*.info
/bin/*.exe
/bin/*.dll
+/bin/goruby
+/bin/ruby
# /benchmark/
/benchmark/bm_require.data
@@ -182,6 +188,9 @@ lcov*.info
/ext/-test-/win32/dln/dlntest.exp
/ext/-test-/win32/dln/dlntest.lib
+# /ext/-test-/gems
+/ext/-test-/gems
+
# /ext/etc/
/ext/etc/constdefs.h
@@ -214,6 +223,9 @@ lcov*.info
/lib/ruby/[1-9]*.*
/lib/ruby/vendor_ruby
+# /misc/
+/misc/**/__pycache__
+
# /spec/bundler
/.rspec_status
@@ -225,6 +237,14 @@ lcov*.info
/win32/*.ico
# MJIT
-/rb_mjit_header.h
-/mjit_config.h
/include/ruby-*/*/rb_mjit_min_header-*.h
+/lib/ruby_vm/mjit/instruction.rb
+/mjit_config.h
+/rb_mjit_header.h
+
+# YJIT
+/yjit-bench
+/yjit_exit_locations.dump
+
+# /wasm/
+/wasm/tests/*.wasm
diff --git a/.indent.pro b/.indent.pro
new file mode 100644
index 0000000000..1d61cbcad1
--- /dev/null
+++ b/.indent.pro
@@ -0,0 +1,32 @@
+-bap
+-nbbb
+-nbc
+-br
+-brs
+-nbs
+-ncdb
+-nce
+-cdw
+-cli2
+-cbi2
+-ndj
+-ncs
+-nfc1
+-i4
+-l120
+-lp
+-npcs
+-psl
+-sc
+-sob
+-sbi4
+-nut
+-par
+
+-TID
+-TVALUE
+-Tst_data_t
+-Tst_index_t
+-Tst_table
+-Trb_data_type_t
+-TFILE
diff --git a/.rdoc_options b/.rdoc_options
new file mode 100644
index 0000000000..760507c7a2
--- /dev/null
+++ b/.rdoc_options
@@ -0,0 +1,4 @@
+---
+page_dir: doc
+main_page: README.md
+title: Documentation for Ruby development version
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d480307dd6..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,291 +0,0 @@
-# -*- YAML -*-
-# Copyright (C) 2011 Urabe, Shyouhei. All rights reserved.
-#
-# This file is a part of the programming language Ruby. Permission is hereby
-# granted, to either redistribute or modify this file, provided that the
-# conditions mentioned in the file COPYING are met. Consult the file for
-# details.
-
-# This is a Travis-CI build configuration file. The list of configurations
-# available is located in
-#
-# http://about.travis-ci.org/docs/user/build-configuration/
-#
-# and as Ruby itself is a project written in C language,
-#
-# http://about.travis-ci.org/docs/user/languages/c/
-#
-# is also a good place to look at.
-
-language: c
-
-os: linux
-
-dist: xenial
-
-git:
- quiet: true
-
-cache:
- ccache: true
- directories:
- - $HOME/config_2nd
- - $HOME/.downloaded-cache
-
-env:
- global:
- # Reset timestamps early
- - _=$(touch NEWS && find . -type f -exec touch -r NEWS {} +)
- - CONFIGURE_TTY=no
- - CCACHE_COMPILERCHECK=none
- - CCACHE_NOCOMPRESS=1
- - CCACHE_MAXSIZE=512Mi
- - NPROC="`nproc`"
- # JOBS and SETARCH are overridden when necessary; see below.
- - JOBS=-j$((1+${NPROC}))
- - SETARCH=
- - RUBY_PREFIX=/tmp/ruby-prefix
- - GEMS_FOR_TEST='timezone tzinfo'
- - UPDATE_UNICODE="UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
- - BEFORE_INSTALL=true
- # https://github.com/travis-ci/travis-build/blob/e411371dda21430a60f61b8f3f57943d2fe4d344/lib/travis/build/bash/travis_apt_get_options.bash#L7
- - travis_apt_get_options='--allow-downgrades --allow-remove-essential --allow-change-held-packages'
- - travis_apt_get_options="-yq --no-install-suggests --no-install-recommends $travis_apt_get_options"
-
-.org.ruby-lang.ci.matrix-definitions:
-
- - &make-test-only
- script:
- - $SETARCH make -s test TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"
-
- - &gcc-8
- compiler: gcc-8
- # # Not using addon to control retries
- # addons:
- # apt:
- # sources:
- # - ubuntu-toolchain-r-test
- before_install:
- - bash -cx "${BEFORE_INSTALL}"
- - tool/travis_retry.sh sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- ccache
- gcc-8
- g++-8
- libffi-dev
- libgdbm-dev
- libncurses5-dev
- libncursesw5-dev
- libreadline6-dev
- libssl-dev
- libyaml-dev
- openssl
- zlib1g-dev
-
- - &clang-8
- compiler: clang-8
- addons:
- apt:
- # Not doing this manually unlike other sources, because it has been stable.
- sources:
- - llvm-toolchain-xenial-8
- config:
- retries: true
- before_install:
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- clang-8
- llvm-8-tools
- libffi-dev
- libgdbm-dev
- libncurses5-dev
- libncursesw5-dev
- libreadline6-dev
- libssl-dev
- libyaml-dev
- openssl
- zlib1g-dev
-
- # --------
-
- - &x86_64-linux
- name: x86_64-linux
- <<: *gcc-8
-
- - &arm64-linux
- name: arm64-linux
- arch: arm64
- <<: *gcc-8
-
- - &s390x-linux
- name: s390x-linux
- arch: s390x
- <<: *gcc-8
-
- - &i686-linux
- name: i686-linux
- compiler: gcc-8
- env:
- - GCC_FLAGS=-m32
- - CXX='g++-8 -m32'
- - debugflags=-g0
- - SETARCH='setarch i686 --verbose --3gb'
- # # Not using addon to control retries
- # addons:
- # apt:
- # sources:
- # - ubuntu-toolchain-r-test
- before_install:
- - tool/travis_retry.sh sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- gcc-8-multilib
- g++-8
- g++-8-multilib
- libstdc++-8-dev:i386
- libffi-dev:i386
- libffi6:i386
- libgdbm-dev:i386
- libgdbm3:i386
- libncurses5-dev:i386
- libncurses5:i386
- libncursesw5-dev:i386
- libreadline6-dev:i386
- libreadline6:i386
- libssl-dev:i386
- libssl1.0.0:i386
- linux-libc-dev:i386
- zlib1g-dev:i386
- zlib1g:i386
-
- - &arm32-linux
- name: arm32-linux
- arch: arm64
- # https://packages.ubuntu.com/xenial/crossbuild-essential-armhf
- compiler: arm-linux-gnueabihf-gcc
- env:
- - debugflags=-g0
- - SETARCH='setarch linux32 --verbose --32bit'
- before_install:
- - sudo dpkg --add-architecture armhf
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- ccache
- crossbuild-essential-armhf
- libc6:armhf
- libstdc++-5-dev:armhf
- libffi-dev:armhf
- libffi6:armhf
- libgdbm-dev:armhf
- libgdbm3:armhf
- libncurses5-dev:armhf
- libncurses5:armhf
- libncursesw5-dev:armhf
- libreadline6-dev:armhf
- libreadline6:armhf
- libssl-dev:armhf
- libssl1.0.0:armhf
- linux-libc-dev:armhf
- zlib1g-dev:armhf
- zlib1g:armhf
-
-matrix:
- include:
- # Build every commit:
- - <<: *i686-linux
- # Build every commit (Allowed Failures):
- - <<: *arm32-linux
- - <<: *arm64-linux
- - <<: *s390x-linux
- allow_failures:
- - name: arm32-linux
- - name: arm64-linux
- - name: s390x-linux
- fast_finish: true
-
-before_script:
- - rm -fr .ext autom4te.cache
- - |-
- [ -d ~/.downloaded-cache ] ||
- mkdir ~/.downloaded-cache
- - ln -s ~/.downloaded-cache
- - "> config.status"
- - "> .rbconfig.time"
- - sed -f tool/prereq.status template/Makefile.in common.mk > Makefile
- - make touch-unicode-files
- - make -s $JOBS $UPDATE_UNICODE up
- - make -s $JOBS srcs
- - rm -f config.status Makefile rbconfig.rb .rbconfig.time
- - |-
- if [ -d ~/config_2nd ]; then
- cp -pr ~/config_2nd build
- else
- mkdir build
- fi
- - mkdir config_1st config_2nd
- - chmod -R a-w .
- - chmod -R u+w build config_1st config_2nd
- - cd build
- - |-
- case "$CC" in
- gcc*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-diagnostics-color";;
- clang*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-color-diagnostics";;
- esac
- - |-
- [ ! -f config.cache ] ||
- [ "$CC" = "`sed -n s/^ac_cv_prog_CC=//p config.cache`" ] ||
- (set -x; exec rm config.cache)
- - $SETARCH ../configure -C --disable-install-doc --prefix=$RUBY_PREFIX $CONFIG_FLAG
- - cp -pr config.cache config.status .ext/include ../config_1st
- - $SETARCH make reconfig
- - cp -pr config.cache config.status .ext/include ../config_2nd
- - (cd .. && exec diff -ru config_1st config_2nd)
- - chmod u+w ..
- - rm -rf ~/config_2nd
- - mv ../config_2nd ~
- - chmod u-w ..
- - $SETARCH make -s $JOBS
- - make -s install
- - |-
- [ -z "${GEMS_FOR_TEST}" ] ||
- $RUBY_PREFIX/bin/gem install --no-document $GEMS_FOR_TEST
- - echo "raise 'do not load ~/.irbrc in test'" > ~/.irbrc
-
-script:
- - $SETARCH make -s test -o showflags TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"
- - travis_wait 50 $SETARCH make -s test-all -o exts TESTOPTS="${TESTOPTS} ${TEST_ALL_OPTS}" RUBYOPT="-w"
- - $SETARCH make -s test-spec MSPECOPT=-ff # not using `-j` because sometimes `mspec -j` silently dies
- - $SETARCH make -s -o showflags leaked-globals
-
-# Branch matrix. Not all branches are Travis-ready so we limit branches here.
-branches:
- only:
- - master
- - ruby_2_4
- - ruby_2_5
- - ruby_2_6
- - ruby_2_7
-
-# We want to be notified when something happens.
-notifications:
- irc:
- channels:
- - "chat.freenode.net#ruby-core"
- on_success: change # [always|never|change] # default: always
- on_failure: always # [always|never|change] # default: always
- template:
- - "%{message} by @%{author}: See %{build_url}"
-
- webhooks:
- urls:
- - secure: mRsoS/UbqDkKkW5p3AEqM27d4SZnV6Gsylo3bm8T/deltQzTsGzZwrm7OIBXZv0UFZdE68XmPlyHfZFLSP2V9QZ7apXMf9/vw0GtcSe1gchtnjpAPF6lYBn7nMCbVPPx9cS0dwL927fjdRM1vj7IKZ2bk4F0lAJ25R25S6teqdk= # ruby-lang slack: ruby/simpler-alerts-bot (travis)
- on_success: never
- on_failure: always
-
- email:
- - ko1c-failure@atdot.net
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ffdf2dd4b8..13df6087ca 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1 @@
-Please see the [official issue tracker] and wiki [HowToContribute].
-
-[official issue tracker]: https://bugs.ruby-lang.org
-[HowToContribute]: https://bugs.ruby-lang.org/projects/ruby/wiki/HowToContribute
+See ["Contributing to Ruby"](https://docs.ruby-lang.org/en/master/contributing_md.html), which includes setup and build instructions.
diff --git a/LEGAL b/LEGAL
index 2a7964e771..0423d57ac9 100644
--- a/LEGAL
+++ b/LEGAL
@@ -314,17 +314,6 @@ mentioned below.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
-[aclocal.m4]
-
- This file is free software.
-
- >>>
- Copyright (C) 1996-2020:: Free Software Foundation, Inc.
-
- This file is free software; the Free Software Foundation
- gives unlimited permission to copy and/or distribute it,
- with or without modifications, as long as this notice is preserved.
-
[tool/config.guess]
[tool/config.sub]
@@ -354,6 +343,34 @@ mentioned below.
program. This Exception is an additional permission under section 7
of the GNU General Public License, version 3 ("GPLv3").
+[tool/lib/test/*]
+[tool/lib/core_assertions.rb]
+
+ Some of methods on these files are based on MiniTest 4. MiniTest 4 is
+ distributed under the MIT License.
+
+ >>>
+ Copyright (c) Ryan Davis, seattle.rb
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ 'Software'), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
[parse.c]
[parse.h]
@@ -451,7 +468,8 @@ mentioned below.
>>>
A C-program for MT19937, with initialization improved 2002/2/10.::
- Coded by Takuji Nishimura and Makoto Matsumoto.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
@@ -542,12 +560,8 @@ mentioned below.
[include/ruby/st.h]
[missing/acosh.c]
[missing/alloca.c]
-[missing/dup2.c]
[missing/erf.c]
-[missing/finite.c]
[missing/hypot.c]
-[missing/isinf.c]
-[missing/isnan.c]
[missing/lgamma_r.c]
[missing/memcmp.c]
[missing/memmove.c]
@@ -945,9 +959,7 @@ mentioned below.
[lib/bundler]
[lib/bundler.rb]
-[lib/bundler.gemspec]
[spec/bundler]
-[man/bundle-*,gemfile.*]
Bundler is under the following license.
@@ -957,6 +969,51 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License]
+[lib/bundler/vendor/thor]
+
+ Thor is under the following license.
+
+ >>>
+ Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al.
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[lib/rubygems/resolver/molinillo]
+
+ molinillo is under the following license.
+
+ >>>
+ Copyright (c) 2014 Samuel E. Giddins segiddins@segiddins.me
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[lib/bundler/vendor/pub_grub]
+
+ pub_grub is under the following license.
+
+ >>>
+ Copyright (c) 2018 John Hawthorn
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[lib/bundler/vendor/connection_pool]
+
+ connection_pool is under the following license.
+
+ >>>
+ Copyright (c) 2011 Mike Perham
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
+[lib/bundler/vendor/net-http-persistent]
+
+ net-http-persistent is under the following license.
+
+ >>>
+ Copyright (c) Eric Hodel, Aaron Patterson
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
[lib/did_you_mean]
[lib/did_you_mean.rb]
[test/did_you_mean]
@@ -968,6 +1025,17 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License]
+[lib/error_highlight]
+[lib/error_highlight.rb]
+[test/error_highlight]
+
+ error_highlight is under the following license.
+
+ >>>
+ Copyright (c) 2021 Yusuke Endoh
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
[benchmark/so_ackermann.rb]
[benchmark/so_array.rb]
[benchmark/so_binary_trees.rb]
diff --git a/NEWS.md b/NEWS.md
index ccbf60ca60..f6c3c6fc97 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,41 +1,820 @@
-# NEWS for Ruby 3.1.0
+# NEWS for Ruby 3.2.0
-This document is a list of user visible feature changes
-since the **3.0.0** release, except for bug fixes.
+This document is a list of user-visible feature changes
+since the **3.1.0** release, except for bug fixes.
-Note that each entry is kept so brief that no reason behind or reference
-information is supplied with. For a full list of changes with all
-sufficient information, see the ChangeLog file or Redmine
-(e.g. `https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER`).
+Note that each entry is kept to a minimum, see links for details.
## Language changes
-## Command line options
+* Anonymous rest and keyword rest arguments can now be passed as
+ arguments, instead of just used in method parameters.
+ [[Feature #18351]]
+
+ ```ruby
+ def foo(*)
+ bar(*)
+ end
+ def baz(**)
+ quux(**)
+ end
+ ```
+
+* A proc that accepts a single positional argument and keywords will
+ no longer autosplat. [[Bug #18633]]
+
+ ```ruby
+ proc{|a, **k| a}.call([1, 2])
+ # Ruby 3.1 and before
+ # => 1
+ # Ruby 3.2 and after
+ # => [1, 2]
+ ```
+
+* Constant assignment evaluation order for constants set on explicit
+ objects has been made consistent with single attribute assignment
+ evaluation order. With this code:
+
+ ```ruby
+ foo::BAR = baz
+ ```
+
+ `foo` is now called before `baz`. Similarly, for multiple assignments
+ to constants, left-to-right evaluation order is used. With this
+ code:
+
+ ```ruby
+ foo1::BAR1, foo2::BAR2 = baz1, baz2
+ ```
+
+ The following evaluation order is now used:
+
+ 1. `foo1`
+ 2. `foo2`
+ 3. `baz1`
+ 4. `baz2`
+
+ [[Bug #15928]]
+
+* "Find pattern" is no longer experimental.
+ [[Feature #18585]]
+
+* Methods taking a rest parameter (like `*args`) and wishing to delegate keyword
+ arguments through `foo(*args)` must now be marked with `ruby2_keywords`
+ (if not already the case). In other words, all methods wishing to delegate
+ keyword arguments through `*args` must now be marked with `ruby2_keywords`,
+ with no exception. This will make it easier to transition to other ways of
+ delegation once a library can require Ruby 3+. Previously, the `ruby2_keywords`
+ flag was kept if the receiving method took `*args`, but this was a bug and an
+ inconsistency. A good technique to find the potentially-missing `ruby2_keywords`
+ is to run the test suite, for where it fails find the last method which must
+ receive keyword arguments, use `puts nil, caller, nil` there, and check each
+ method/block on the call chain which must delegate keywords is correctly marked
+ as `ruby2_keywords`. [[Bug #18625]] [[Bug #16466]]
+
+ ```ruby
+ def target(**kw)
+ end
+
+ # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords
+ # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on
+ # both #foo and #bar when migrating away from ruby2_keywords.
+ ruby2_keywords def bar(*args)
+ target(*args)
+ end
+
+ ruby2_keywords def foo(*args)
+ bar(*args)
+ end
+
+ foo(k: 1)
+ ```
## Core classes updates
-Outstanding ones only.
+Note: We're only listing outstanding class updates.
+
+* Fiber
+
+ * Introduce Fiber.[] and Fiber.[]= for inheritable fiber storage.
+ Introduce Fiber#storage and Fiber#storage= (experimental) for
+ getting and resetting the current storage. Introduce
+ `Fiber.new(storage:)` for setting the storage when creating a
+ fiber. [[Feature #19078]]
+
+ Existing Thread and Fiber local variables can be tricky to use.
+ Thread-local variables are shared between all fibers, making it
+ hard to isolate, while Fiber-local variables can be hard to
+ share. It is often desirable to define unit of execution
+ ("execution context") such that some state is shared between all
+ fibers and threads created in that context. This is what Fiber
+ storage provides.
+
+ ```ruby
+ def log(message)
+ puts "#{Fiber[:request_id]}: #{message}"
+ end
+
+ def handle_requests
+ while request = read_request
+ Fiber.schedule do
+ Fiber[:request_id] = SecureRandom.uuid
+
+ request.messages.each do |message|
+ Fiber.schedule do
+ log("Handling #{message}") # Log includes inherited request_id.
+ end
+ end
+ end
+ end
+ end
+ ```
+
+ You should generally consider Fiber storage for any state which
+ you want to be shared implicitly between all fibers and threads
+ created in a given context, e.g. a connection pool, a request
+ id, a logger level, environment variables, configuration, etc.
+
+* Fiber::Scheduler
+
+ * Introduce `Fiber::Scheduler#io_select` for non-blocking IO.select.
+ [[Feature #19060]]
+
+* IO
+
+ * Introduce IO#timeout= and IO#timeout which can cause
+ IO::TimeoutError to be raised if a blocking operation exceeds the
+ specified timeout. [[Feature #18630]]
+
+ ```ruby
+ STDIN.timeout = 1
+ STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
+ ```
+
+ * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`.
+ [[Feature #19036]]
+
+* Class
+
+ * Class#attached_object, which returns the object for which
+ the receiver is the singleton class. Raises TypeError if the
+ receiver is not a singleton class.
+ [[Feature #12084]]
+
+ ```ruby
+ class Foo; end
+
+ Foo.singleton_class.attached_object #=> Foo
+ Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370>
+ Foo.attached_object #=> TypeError: `Foo' is not a singleton class
+ nil.singleton_class.attached_object #=> TypeError: `NilClass' is not a singleton class
+ ```
+
+* Data
+
+ * New core class to represent simple immutable value object. The class is
+ similar to Struct and partially shares an implementation, but has more
+ lean and strict API. [[Feature #16122]]
+
+ ```ruby
+ Measure = Data.define(:amount, :unit)
+ distance = Measure.new(100, 'km') #=> #<data Measure amount=100, unit="km">
+ weight = Measure.new(amount: 50, unit: 'kg') #=> #<data Measure amount=50, unit="kg">
+ weight.with(amount: 40) #=> #<data Measure amount=40, unit="kg">
+ weight.amount #=> 50
+ weight.amount = 40 #=> NoMethodError: undefined method `amount='
+ ```
+
+* Encoding
+
+ * Encoding#replicate has been deprecated and will be removed in 3.3. [[Feature #18949]]
+ * The dummy `Encoding::UTF_16` and `Encoding::UTF_32` encodings no longer
+ try to dynamically guess the endian based on a byte order mark.
+ Use `Encoding::UTF_16BE`/`UTF_16LE` and `Encoding::UTF_32BE`/`UTF_32LE` instead.
+ This change speeds up getting the encoding of a String. [[Feature #18949]]
+ * Limit maximum encoding set size by 256.
+ If exceeding maximum size, `EncodingError` will be raised. [[Feature #18949]]
+
+* Enumerator
+
+ * Enumerator.product has been added. Enumerator::Product is the implementation. [[Feature #18685]]
+
+* Exception
+
+ * Exception#detailed_message has been added.
+ The default error printer calls this method on the Exception object
+ instead of #message. [[Feature #18564]]
+
+* Hash
+
+ * Hash#shift now always returns nil if the hash is
+ empty, instead of returning the default value or
+ calling the default proc. [[Bug #16908]]
+
+* Integer
+
+ * Integer#ceildiv has been added. [[Feature #18809]]
+
+* Kernel
+
+ * Kernel#binding raises RuntimeError if called from a non-Ruby frame
+ (such as a method defined in C). [[Bug #18487]]
+
+* MatchData
+
+ * MatchData#byteoffset has been added. [[Feature #13110]]
+ * MatchData#deconstruct has been added. [[Feature #18821]]
+ * MatchData#deconstruct_keys has been added. [[Feature #18821]]
+
+* Module
+
+ * Module.used_refinements has been added. [[Feature #14332]]
+ * Module#refinements has been added. [[Feature #12737]]
+ * Module#const_added has been added. [[Feature #17881]]
+ * Module#undefined_instance_methods has been added. [[Feature #12655]]
+
+* Proc
+
+ * Proc#dup returns an instance of subclass. [[Bug #17545]]
+ * Proc#parameters now accepts lambda keyword. [[Feature #15357]]
+
+* Process
+ * Added `RLIMIT_NPTS` constant to FreeBSD platform
+
+* Regexp
+
+ * The cache-based optimization is introduced.
+ Many (but not all) Regexp matching is now in linear time, which
+ will prevent regular expression denial of service (ReDoS)
+ vulnerability. [[Feature #19104]]
+
+ * Regexp.linear_time? is introduced. [[Feature #19194]]
+
+ * Regexp.new now supports passing the regexp flags not only as an Integer,
+ but also as a String. Unknown flags raise ArgumentError.
+ Otherwise, anything other than `true`, `false`, `nil` or Integer will be warned.
+ [[Feature #18788]]
+
+ * Regexp.timeout= has been added. Also, Regexp.new new supports timeout keyword.
+ See [[Feature #17837]]
+
+* Refinement
+
+ * Refinement#refined_class has been added. [[Feature #12737]]
+
+* RubyVM::AbstractSyntaxTree
+
+ * Add `error_tolerant` option for `parse`, `parse_file` and `of`. [[Feature #19013]]
+ With this option
+
+ 1. SyntaxError is suppressed
+ 2. AST is returned for invalid input
+ 3. `end` is complemented when a parser reaches to the end of input but `end` is insufficient
+ 4. `end` is treated as keyword based on indent
+
+ ```ruby
+ # Without error_tolerant option
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY)
+ def m
+ a = 10
+ if
+ end
+ RUBY
+ # => <internal:ast>:33:in `parse': syntax error, unexpected `end' (SyntaxError)
+
+ # With error_tolerant option
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
+ def m
+ a = 10
+ if
+ end
+ RUBY
+ p root # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-4:3>
+
+ # `end` is treated as keyword based on indent
+ root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true)
+ module Z
+ class Foo
+ foo.
+ end
+
+ def bar
+ end
+ end
+ RUBY
+ p root.children[-1].children[-1].children[-1].children[-2..-1]
+ # => [#<RubyVM::AbstractSyntaxTree::Node:CLASS@2:2-4:5>, #<RubyVM::AbstractSyntaxTree::Node:DEFN@6:2-7:5>]
+ ```
+
+ * Add `keep_tokens` option for `parse`, `parse_file` and `of`. Add `#tokens` and `#all_tokens`
+ for RubyVM::AbstractSyntaxTree::Node [[Feature #19070]]
+
+ ```ruby
+ root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true)
+ root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
+ root.tokens.map{_1[2]}.join # => "x = 1 + 2"
+ ```
+
+* Set
+
+ * Set is now available as a built-in class without the need for `require "set"`. [[Feature #16989]]
+ It is currently autoloaded via the Set constant or a call to Enumerable#to_set.
+
+* String
+
+ * String#byteindex and String#byterindex have been added. [[Feature #13110]]
+ * Update Unicode to Version 15.0.0 and Emoji Version 15.0. [[Feature #18639]]
+ (also applies to Regexp)
+ * String#bytesplice has been added. [[Feature #18598]]
+ * String#dedup has been added as an alias to String#-@. [[Feature #18595]]
+
+* Struct
+
+ * A Struct class can also be initialized with keyword arguments
+ without `keyword_init: true` on Struct.new [[Feature #16806]]
+
+ ```ruby
+ Post = Struct.new(:id, :name)
+ Post.new(1, "hello") #=> #<struct Post id=1, name="hello">
+ # From Ruby 3.2, the following code also works without keyword_init: true.
+ Post.new(id: 1, name: "hello") #=> #<struct Post id=1, name="hello">
+ ```
+
+* Thread
+
+ * Thread.each_caller_location is added. [[Feature #16663]]
+
+* Thread::Queue
+
+ * Thread::Queue#pop(timeout: sec) is added. [[Feature #18774]]
+
+* Thread::SizedQueue
+
+ * Thread::SizedQueue#pop(timeout: sec) is added. [[Feature #18774]]
+ * Thread::SizedQueue#push(timeout: sec) is added. [[Feature #18944]]
+
+* Time
+
+ * Time#deconstruct_keys is added, allowing to use Time instances
+ in pattern-matching expressions [[Feature #19071]]
+
+ * Time.new now can parse a string like generated by Time#inspect
+ and return a Time instance based on the given argument.
+ [[Feature #18033]]
+
+* SyntaxError
+ * SyntaxError#path has been added. [[Feature #19138]]
+
+* TracePoint
+
+ * TracePoint#binding now returns `nil` for `c_call`/`c_return` TracePoints.
+ [[Bug #18487]]
+ * TracePoint#enable `target_thread` keyword argument now defaults to the
+ current thread if a block is given and `target` and `target_line` keyword
+ arguments are not passed. [[Bug #16889]]
+
+* UnboundMethod
+
+ * `UnboundMethod#==` returns `true` if the actual method is same. For example,
+ `String.instance_method(:object_id) == Array.instance_method(:object_id)`
+ returns `true`. [[Feature #18798]]
+
+ * `UnboundMethod#inspect` does not show the receiver of `instance_method`.
+ For example `String.instance_method(:object_id).inspect` returns
+ `"#<UnboundMethod: Kernel#object_id()>"`
+ (was `"#<UnboundMethod: String(Kernel)#object_id()>"`).
+
+* GC
+
+ * Expose `need_major_gc` via `GC.latest_gc_info`. [GH-6791]
+
+* ObjectSpace
+
+ * `ObjectSpace.dump_all` dump shapes as well. [GH-6868]
## Stdlib updates
-Outstanding ones only.
+* Bundler
+
+ * Bundler now uses [PubGrub] resolver instead of [Molinillo] for performance improvement.
+ * Add --ext=rust support to bundle gem for creating simple gems with Rust extensions.
+ [[GH-rubygems-6149]]
+ * Make cloning git repos faster [[GH-rubygems-4475]]
+
+* RubyGems
+
+ * Add mswin support for cargo builder. [[GH-rubygems-6167]]
+
+* CGI
+
+ * `CGI.escapeURIComponent` and `CGI.unescapeURIComponent` are added.
+ [[Feature #18822]]
+
+* Coverage
+
+ * `Coverage.setup` now accepts `eval: true`. By this, `eval` and related methods are
+ able to generate code coverage. [[Feature #19008]]
+
+ * `Coverage.supported?(mode)` enables detection of what coverage modes are
+ supported. [[Feature #19026]]
+
+* Date
+
+ * Added `Date#deconstruct_keys` and `DateTime#deconstruct_keys` same as [[Feature #19071]]
+
+* ERB
+
+ * `ERB::Util.html_escape` is made faster than `CGI.escapeHTML`.
+ * It no longer allocates a String object when no character needs to be escaped.
+ * It skips calling `#to_s` method when an argument is already a String.
+ * `ERB::Escape.html_escape` is added as an alias to `ERB::Util.html_escape`,
+ which has not been monkey-patched by Rails.
+ * `ERB::Util.url_encode` is made faster using `CGI.escapeURIComponent`.
+ * `-S` option is removed from `erb` command.
+
+* FileUtils
+
+ * Add FileUtils.ln_sr method and `relative:` option to FileUtils.ln_s.
+ [[Feature #18925]]
+
+* IRB
+
+ * debug.gem integration commands have been added: `debug`, `break`, `catch`,
+ `next`, `delete`, `step`, `continue`, `finish`, `backtrace`, `info`
+ * They work even if you don't have `gem "debug"` in your Gemfile.
+ * See also: [What's new in Ruby 3.2's IRB?](https://st0012.dev/whats-new-in-ruby-3-2-irb)
+ * More Pry-like commands and features have been added.
+ * `edit` and `show_cmds` (like Pry's `help`) are added.
+ * `ls` takes `-g` or `-G` option to filter out outputs.
+ * `show_source` is aliased from `$` and accepts unquoted inputs.
+ * `whereami` is aliased from `@`.
+
+* Net::Protocol
+
+ * Improve `Net::BufferedIO` performance. [[GH-net-protocol-14]]
+
+* Pathname
+
+ * Added `Pathname#lutime`. [[GH-pathname-20]]
+
+* Socket
+
+ * Added the following constants for supported platforms.
+ * `SO_INCOMING_CPU`
+ * `SO_INCOMING_NAPI_ID`
+ * `SO_RTABLE`
+ * `SO_SETFIB`
+ * `SO_USER_COOKIE`
+ * `TCP_KEEPALIVE`
+ * `TCP_CONNECTION_INFO`
+
+* SyntaxSuggest
+
+ * The feature of `syntax_suggest` formerly `dead_end` is integrated in Ruby.
+ [[Feature #18159]]
+
+* UNIXSocket
+
+ * Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
+ support for File.socket? and File::Stat#socket? where possible.
+ [[Feature #19135]]
+
+* The following default gems are updated.
+
+ * RubyGems 3.4.1
+ * abbrev 0.1.1
+ * benchmark 0.2.1
+ * bigdecimal 3.1.3
+ * bundler 2.4.1
+ * cgi 0.3.6
+ * csv 3.2.6
+ * date 3.3.3
+ * delegate 0.3.0
+ * did_you_mean 1.6.3
+ * digest 3.1.1
+ * drb 2.1.1
+ * english 0.7.2
+ * erb 4.0.2
+ * error_highlight 0.5.1
+ * etc 1.4.2
+ * fcntl 1.0.2
+ * fiddle 1.1.1
+ * fileutils 1.7.0
+ * forwardable 1.3.3
+ * getoptlong 0.2.0
+ * io-console 0.6.0
+ * io-nonblock 0.2.0
+ * io-wait 0.3.0
+ * ipaddr 1.2.5
+ * irb 1.6.2
+ * json 2.6.3
+ * logger 1.5.3
+ * mutex_m 0.1.2
+ * net-http 0.4.0
+ * net-protocol 0.2.1
+ * nkf 0.1.2
+ * open-uri 0.3.0
+ * open3 0.1.2
+ * openssl 3.1.0
+ * optparse 0.3.1
+ * ostruct 0.5.5
+ * pathname 0.2.1
+ * pp 0.4.0
+ * pstore 0.1.2
+ * psych 5.0.1
+ * racc 1.6.2
+ * rdoc 6.5.0
+ * readline-ext 0.1.5
+ * reline 0.3.2
+ * resolv 0.2.2
+ * resolv-replace 0.1.1
+ * securerandom 0.2.2
+ * set 1.0.3
+ * stringio 3.0.4
+ * strscan 3.0.5
+ * syntax_suggest 1.0.2
+ * syslog 0.1.1
+ * tempfile 0.1.3
+ * time 0.2.1
+ * timeout 0.3.1
+ * tmpdir 0.1.3
+ * tsort 0.1.1
+ * un 0.2.1
+ * uri 0.12.0
+ * weakref 0.1.2
+ * win32ole 1.8.9
+ * yaml 0.2.1
+ * zlib 3.0.0
+
+* The following bundled gems are updated.
+
+ * minitest 5.16.3
+ * power_assert 2.0.3
+ * test-unit 3.5.7
+ * net-ftp 0.2.0
+ * net-imap 0.3.4
+ * net-pop 0.1.2
+ * net-smtp 0.3.3
+ * rbs 2.8.2
+ * typeprof 0.21.3
+ * debug 1.7.1
+
+See GitHub releases like [GitHub Releases of Logger](https://github.com/ruby/logger/releases) or changelog for details of the default gems or bundled gems.
+
+## Supported platforms
+
+* WebAssembly/WASI is added. See [wasm/README.md] and [ruby.wasm] for more details. [[Feature #18462]]
## Compatibility issues
-Excluding feature bug fixes.
+* `String#to_c` currently treat a sequence of underscores as an end of Complex
+ string. [[Bug #19087]]
+
+* Now `ENV.clone` raises `TypeError` as well as `ENV.dup` [[Bug #17767]]
+
+### Removed constants
+
+The following deprecated constants are removed.
+
+* `Fixnum` and `Bignum` [[Feature #12005]]
+* `Random::DEFAULT` [[Feature #17351]]
+* `Struct::Group`
+* `Struct::Passwd`
+
+### Removed methods
+
+The following deprecated methods are removed.
+
+* `Dir.exists?` [[Feature #17391]]
+* `File.exists?` [[Feature #17391]]
+* `Kernel#=~` [[Feature #15231]]
+* `Kernel#taint`, `Kernel#untaint`, `Kernel#tainted?`
+ [[Feature #16131]]
+* `Kernel#trust`, `Kernel#untrust`, `Kernel#untrusted?`
+ [[Feature #16131]]
+* `Method#public?`, `Method#private?`, `Method#protected?`,
+ `UnboundMethod#public?`, `UnboundMethod#private?`, `UnboundMethod#protected?`
+ [[Bug #18729]] [[Bug #18751]] [[Bug #18435]]
+
+### Source code incompatibility of extension libraries
+
+* Extension libraries provide PRNG, subclasses of Random, need updates.
+ See [PRNG update] below for more information. [[Bug #19100]]
+
+### Error printer
+
+* Ruby no longer escapes control characters and backslashes in an
+ error message. [[Feature #18367]]
+
+### Constant lookup when defining a class/module
+
+* When defining a class/module directly under the Object class by class/module
+ statement, if there is already a class/module defined by `Module#include`
+ with the same name, the statement was handled as "open class" in Ruby 3.1 or before.
+ Since Ruby 3.2, a new class is defined instead. [[Feature #18832]]
## Stdlib compatibility issues
+* Psych no longer bundles libyaml sources.
+ And also Fiddle no longer bundles libffi sources.
+ Users need to install the libyaml/libffi library themselves via the package
+ manager like apt, yum, brew, etc.
+
+ Psych and fiddle supported the static build with specific version of libyaml
+ and libffi sources. You can build psych with libyaml-0.2.5 like this.
+
+ ```bash
+ $ ./configure --with-libyaml-source-dir=/path/to/libyaml-0.2.5
+ ```
+
+ And you can build fiddle with libffi-3.4.4 like this.
+
+ ```bash
+ $ ./configure --with-libffi-source-dir=/path/to/libffi-3.4.4
+ ```
+
+ [[Feature #18571]]
+
+* Check cookie name/path/domain characters in `CGI::Cookie`. [[CVE-2021-33621]]
+
+* `URI.parse` return empty string in host instead of nil. [[sec-156615]]
+
## C API updates
+### Updated C APIs
+
+The following APIs are updated.
+
+* PRNG update
+
+ `rb_random_interface_t` in ruby/random.h updated and versioned.
+ Extension libraries which use this interface and built for older
+ versions need to rebuild with adding `init_int32` function.
+
+### Added C APIs
+
+* `VALUE rb_hash_new_capa(long capa)` was added to created hashes with the desired capacity.
+* `rb_internal_thread_add_event_hook` and `rb_internal_thread_add_event_hook` were added to instrument threads scheduling.
+ The following events are available:
+ * `RUBY_INTERNAL_THREAD_EVENT_STARTED`
+ * `RUBY_INTERNAL_THREAD_EVENT_READY`
+ * `RUBY_INTERNAL_THREAD_EVENT_RESUMED`
+ * `RUBY_INTERNAL_THREAD_EVENT_SUSPENDED`
+ * `RUBY_INTERNAL_THREAD_EVENT_EXITED`
+* `rb_debug_inspector_current_depth` and `rb_debug_inspector_frame_depth` are added for debuggers.
+
+### Removed C APIs
+
+The following deprecated APIs are removed.
+
+* `rb_cData` variable.
+* "taintedness" and "trustedness" functions. [[Feature #16131]]
+
## Implementation improvements
-### JIT
+* Fixed several race conditions in Kernel#autoload. [[Bug #18782]]
+* Cache invalidation for expressions referencing constants is now
+ more fine-grained. `RubyVM.stat(:global_constant_state)` was
+ removed because it was closely tied to the previous caching scheme
+ where setting any constant invalidates all caches in the system.
+ New keys, `:constant_cache_invalidations` and `:constant_cache_misses`,
+ were introduced to help with use cases for `:global_constant_state`.
+ [[Feature #18589]]
+* The cache-based optimization for Regexp matching is introduced.
+ [[Feature #19104]]
+* [Variable Width Allocation](https://shopify.engineering/ruby-variable-width-allocation)
+ is now enabled by default. [[Feature #18239]]
+* Added a new instance variable caching mechanism, called object shapes, which
+ improves inline cache hits for most objects and allows us to generate very
+ efficient JIT code. Objects whose instance variables are defined in a
+ consistent order will see the most performance benefits.
+ [[Feature #18776]]
+* Speed up marking instruction sequences by using a bitmap to find "markable"
+ objects. This change results in faster major collections.
+ [[Feature #18875]]
+
+## JIT
+
+### YJIT
-## Static analysis
+* YJIT is no longer experimental
+ * Has been tested on production workloads for over a year and proven to be quite stable.
+* YJIT now supports both x86-64 and arm64/aarch64 CPUs on Linux, MacOS, BSD and other UNIX platforms.
+ * This release brings support for Mac M1/M2, AWS Graviton and Raspberry Pi 4.
+* Building YJIT now requires Rust 1.58.0+. [[Feature #18481]]
+ * In order to ensure that CRuby is built with YJIT, please install `rustc` >= 1.58.0
+ before running `./configure`
+ * Please reach out to the YJIT team should you run into any issues.
+* Physical memory for JIT code is lazily allocated. Unlike Ruby 3.1,
+ the RSS of a Ruby process is minimized because virtual memory pages
+ allocated by `--yjit-exec-mem-size` will not be mapped to physical
+ memory pages until actually utilized by JIT code.
+* Introduce Code GC that frees all code pages when the memory consumption
+ by JIT code reaches `--yjit-exec-mem-size`.
+ * `RubyVM::YJIT.runtime_stats` returns Code GC metrics in addition to
+ existing `inline_code_size` and `outlined_code_size` keys:
+ `code_gc_count`, `live_page_count`, `freed_page_count`, and `freed_code_size`.
+* Most of the statistics produced by `RubyVM::YJIT.runtime_stats` are now available in release builds.
+ * Simply run ruby with `--yjit-stats` to compute and dump stats (incurs some run-time overhead).
+* YJIT is now optimized to take advantage of object shapes. [[Feature #18776]]
+* Take advantage of finer-grained constant invalidation to invalidate less code when defining new constants. [[Feature #18589]]
+* The default `--yjit-exec-mem-size` is changed to 64 (MiB).
+* The default `--yjit-call-threshold` is changed to 30.
-### RBS
+### MJIT
-### TypeProf
+* The MJIT compiler is re-implemented in Ruby as `ruby_vm/mjit/compiler`.
+* MJIT compiler is executed under a forked Ruby process instead of
+ doing it in a native thread called MJIT worker. [[Feature #18968]]
+ * As a result, Microsoft Visual Studio (MSWIN) is no longer supported.
+* MinGW is no longer supported. [[Feature #18824]]
+* Rename `--mjit-min-calls` to `--mjit-call-threshold`.
+* Change default `--mjit-max-cache` back from 10000 to 100.
-## Miscellaneous changes
+[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
+[Feature #12084]: https://bugs.ruby-lang.org/issues/12084
+[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
+[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
+[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
+[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
+[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
+[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
+[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
+[Feature #16122]: https://bugs.ruby-lang.org/issues/16122
+[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
+[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
+[Feature #16663]: https://bugs.ruby-lang.org/issues/16663
+[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
+[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
+[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
+[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
+[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
+[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
+[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
+[Bug #17767]: https://bugs.ruby-lang.org/issues/17767
+[Feature #17837]: https://bugs.ruby-lang.org/issues/17837
+[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
+[Feature #18033]: https://bugs.ruby-lang.org/issues/18033
+[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
+[Feature #18239]: https://bugs.ruby-lang.org/issues/18239#note-17
+[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
+[Feature #18367]: https://bugs.ruby-lang.org/issues/18367
+[Bug #18435]: https://bugs.ruby-lang.org/issues/18435
+[Feature #18462]: https://bugs.ruby-lang.org/issues/18462
+[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
+[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
+[Feature #18564]: https://bugs.ruby-lang.org/issues/18564
+[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
+[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
+[Feature #18589]: https://bugs.ruby-lang.org/issues/18589
+[Feature #18595]: https://bugs.ruby-lang.org/issues/18595
+[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
+[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
+[Feature #18630]: https://bugs.ruby-lang.org/issues/18630
+[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
+[Feature #18639]: https://bugs.ruby-lang.org/issues/18639
+[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
+[Bug #18729]: https://bugs.ruby-lang.org/issues/18729
+[Bug #18751]: https://bugs.ruby-lang.org/issues/18751
+[Feature #18774]: https://bugs.ruby-lang.org/issues/18774
+[Feature #18776]: https://bugs.ruby-lang.org/issues/18776
+[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
+[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
+[Feature #18798]: https://bugs.ruby-lang.org/issues/18798
+[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
+[Feature #18821]: https://bugs.ruby-lang.org/issues/18821
+[Feature #18822]: https://bugs.ruby-lang.org/issues/18822
+[Feature #18824]: https://bugs.ruby-lang.org/issues/18824
+[Feature #18832]: https://bugs.ruby-lang.org/issues/18832
+[Feature #18875]: https://bugs.ruby-lang.org/issues/18875
+[Feature #18925]: https://bugs.ruby-lang.org/issues/18925
+[Feature #18944]: https://bugs.ruby-lang.org/issues/18944
+[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
+[Feature #18968]: https://bugs.ruby-lang.org/issues/18968
+[Feature #19008]: https://bugs.ruby-lang.org/issues/19008
+[Feature #19013]: https://bugs.ruby-lang.org/issues/19013
+[Feature #19026]: https://bugs.ruby-lang.org/issues/19026
+[Feature #19036]: https://bugs.ruby-lang.org/issues/19036
+[Feature #19060]: https://bugs.ruby-lang.org/issues/19060
+[Feature #19070]: https://bugs.ruby-lang.org/issues/19070
+[Feature #19071]: https://bugs.ruby-lang.org/issues/19071
+[Feature #19078]: https://bugs.ruby-lang.org/issues/19078
+[Bug #19087]: https://bugs.ruby-lang.org/issues/19087
+[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
+[Feature #19104]: https://bugs.ruby-lang.org/issues/19104
+[Feature #19135]: https://bugs.ruby-lang.org/issues/19135
+[Feature #19138]: https://bugs.ruby-lang.org/issues/19138
+[Feature #19194]: https://bugs.ruby-lang.org/issues/19194
+[Molinillo]: https://github.com/CocoaPods/Molinillo
+[PubGrub]: https://github.com/jhawthorn/pub_grub
+[GH-net-protocol-14]: https://github.com/ruby/net-protocol/pull/14
+[GH-pathname-20]: https://github.com/ruby/pathname/pull/20
+[GH-6791]: https://github.com/ruby/ruby/pull/6791
+[GH-6868]: https://github.com/ruby/ruby/pull/6868
+[GH-rubygems-4475]: https://github.com/rubygems/rubygems/pull/4475
+[GH-rubygems-6149]: https://github.com/rubygems/rubygems/pull/6149
+[GH-rubygems-6167]: https://github.com/rubygems/rubygems/pull/6167
+[sec-156615]: https://hackerone.com/reports/156615
+[CVE-2021-33621]: https://www.ruby-lang.org/en/news/2022/11/22/http-response-splitting-in-cgi-cve-2021-33621/
+[wasm/README.md]: https://github.com/ruby/ruby/blob/master/wasm/README.md
+[ruby.wasm]: https://github.com/ruby/ruby.wasm
diff --git a/README.ja.md b/README.ja.md
index a1dba33b43..93c0131690 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -1,10 +1,9 @@
-[![Build Status](https://travis-ci.org/ruby/ruby.svg?branch=master)](https://travis-ci.org/ruby/ruby)
-[![Build status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
-[![Actions Status: macOS](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
[![Actions Status: MinGW](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
[![Actions Status: MJIT](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
[![Actions Status: Ubuntu](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
+[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
+[![Travis Status](https://app.travis-ci.com/ruby/ruby.svg?branch=master)](https://app.travis-ci.com/ruby/ruby)
# Rubyとは
@@ -52,11 +51,11 @@ Rubyリポジトリの本来のmasterは https://git.ruby-lang.org/ruby.git に
### Subversion
-古いRubyのバージョンのソースコードは次のコマンドで取得できます.
+古いRubyのバージョンのソースコードは次のコマンドでも取得できます.
$ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby
-他に開発中のブランチの一覧は次のコマンドで見られます.
+他のブランチの一覧は次のコマンドで見られます.
$ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
@@ -71,31 +70,26 @@ https://www.ruby-lang.org/
## メーリングリスト
-Rubyのメーリングリストがあります.参加希望の方は
-
-mailto:ruby-list-request@ruby-lang.org
-
-まで本文に
+Rubyのメーリングリストがあります.参加希望の方は [ruby-list-request@ruby-lang.org] まで本文に
subscribe
と書いて送って下さい.
-Ruby開発者向けメーリングリストもあります.こちらではrubyのバグ,将来の仕様拡張など実装上の問題について議論されています. 参加希望の方は
-
-mailto:ruby-dev-request@ruby-lang.org
-
-までruby-listと同様の方法でメールしてください.
+Ruby開発者向けメーリングリストもあります.こちらではrubyのバグ,将来の仕様拡張など実装上の問題について議論されています.
+参加希望の方は [ruby-dev-request@ruby-lang.org] までruby-listと同様の方法でメールしてください.
Ruby拡張モジュールについて話し合うruby-extメーリングリストと数学関係の話題について話し合うruby-mathメーリングリストと
英語でrubyについて話し合うruby-talkメーリングリストもあります.参加方法はどれも同じです.
+[ruby-list-request@ruby-lang.org]: mailto:ruby-list-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
+[ruby-dev-request@ruby-lang.org]: mailto:ruby-dev-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
+
## コンパイル・インストール
以下の手順で行ってください.
-1. もし `configure` ファイルが見つからない,もしくは `configure.ac` より古いようなら, `autoconf` を実行して
- 新しく `configure` を生成する
+1. (Gitリポジトリから取得したソースをビルドする場合) `./autogen.sh` を実行して新しく `configure` を生成する
2. `configure` を実行して `Makefile` などを生成する
@@ -172,11 +166,14 @@ UNIXであれば `configure` がほとんどの差異を吸収してくれるは
## フィードバック
-Rubyに関する質問は Ruby-Talk(英語)や Ruby-List(日本語) (https://www.ruby-lang.org/ja/community/mailing-lists) や,
-stackoverflow (https://ja.stackoverflow.com/) などのWebサイトに投稿してください.
+Rubyに関する質問は [Ruby-Talk](英語)や [Ruby-List](日本語)や,
+[stackoverflow] などのWebサイトに投稿してください.
バグ報告は https://bugs.ruby-lang.org で受け付けています.
+[Ruby-Talk]: https://www.ruby-lang.org/en/community/mailing-lists
+[Ruby-List]: https://www.ruby-lang.org/ja/community/mailing-lists
+[stackoverflow]: https://ja.stackoverflow.com/
## 著者
diff --git a/README.md b/README.md
index dd7ca3327b..c445448c71 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,11 @@
-[![Build Status](https://travis-ci.org/ruby/ruby.svg?branch=master)](https://travis-ci.org/ruby/ruby)
-[![Build status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
-[![Actions Status: macOS](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
[![Actions Status: MinGW](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
[![Actions Status: MJIT](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
[![Actions Status: Ubuntu](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
+[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
+[![Travis Status](https://app.travis-ci.com/ruby/ruby.svg?branch=master)](https://app.travis-ci.com/ruby/ruby)
-# What's Ruby
+# What is Ruby?
Ruby is an interpreted object-oriented programming language often
used for web development. It also offers many scripting features
@@ -15,28 +14,25 @@ It is simple, straightforward, and extensible.
## Features of Ruby
-* Simple Syntax
-* **Normal** Object-oriented Features (e.g. class, method calls)
-* **Advanced** Object-oriented Features (e.g. mix-in, singleton-method)
-* Operator Overloading
-* Exception Handling
-* Iterators and Closures
-* Garbage Collection
-* Dynamic Loading of Object Files (on some architectures)
-* Highly Portable (works on many Unix-like/POSIX compatible platforms as
- well as Windows, macOS, etc.) cf.
- https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#label-Platform+Maintainers
+* Simple Syntax
+* **Normal** Object-oriented Features (e.g. class, method calls)
+* **Advanced** Object-oriented Features (e.g. mix-in, singleton-method)
+* Operator Overloading
+* Exception Handling
+* Iterators and Closures
+* Garbage Collection
+* Dynamic Loading of Object Files (on some architectures)
+* Highly Portable (works on many Unix-like/POSIX compatible platforms as
+ well as Windows, macOS, etc.) cf.
+ https://github.com/ruby/ruby/blob/master/doc/maintainers.rdoc#label-Platform+Maintainers
-
-## How to get Ruby
+## How to get Ruby with Git
For a complete list of ways to install Ruby, including using third-party tools
like rvm, see:
https://www.ruby-lang.org/en/downloads/
-### Git
-
The mirror of the Ruby source tree can be checked out with the following command:
$ git clone https://github.com/ruby/ruby.git
@@ -49,21 +45,19 @@ to see the list of branches:
You may also want to use https://git.ruby-lang.org/ruby.git (actual master of Ruby source)
if you are a committer.
-### Subversion
-
-Stable branches for older Ruby versions can be checked out with the following command:
-
- $ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby
-
-Try the following command to see the list of branches:
-
- $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/
+## How to build
+see [Building Ruby](doc/contributing/building_ruby.md)
## Ruby home page
https://www.ruby-lang.org/
+## Documentation
+
+- [English](https://docs.ruby-lang.org/en/master/index.html)
+- [Japanese](https://docs.ruby-lang.org/ja/master/index.html)
+
## Mailing list
There is a mailing list to discuss Ruby. To subscribe to this list, please
@@ -71,98 +65,24 @@ send the following phrase:
subscribe
-in the mail body (not subject) to the address
-[ruby-talk-request@ruby-lang.org](mailto:ruby-talk-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe).
-
-## How to compile and install
-
-1. If you want to use Microsoft Visual C++ to compile Ruby, read
- [win32/README.win32](win32/README.win32) instead of this document.
-
-2. If `./configure` does not exist or is older than `configure.ac`, run
- `autoconf` to (re)generate configure.
-
-3. Run `./configure`, which will generate `config.h` and `Makefile`.
-
- Some C compiler flags may be added by default depending on your
- environment. Specify `optflags=..` and `warnflags=..` as necessary to
- override them.
-
-4. Edit `include/ruby/defines.h` if you need. Usually this step will not be needed.
-
-5. Remove comment mark(`#`) before the module names from `ext/Setup` (or add
- module names if not present), if you want to link modules statically.
+in the mail body (not subject) to the address [ruby-talk-request@ruby-lang.org].
- If you don't want to compile non static extension modules (probably on
- architectures which do not allow dynamic loading), remove comment mark
- from the line "`#option nodynamic`" in `ext/Setup`.
-
- Usually this step will not be needed.
-
-6. Run `make`.
-
- * On Mac, set RUBY\_CODESIGN environment variable with a signing identity.
- It uses the identity to sign `ruby` binary. See also codesign(1).
-
-7. Optionally, run '`make check`' to check whether the compiled Ruby
- interpreter works well. If you see the message "`check succeeded`", your
- Ruby works as it should (hopefully).
-
-8. Run '`make install`'.
-
- This command will create the following directories and install files into
- them.
-
- * `${DESTDIR}${prefix}/bin`
- * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}`
- * `${DESTDIR}${prefix}/include/ruby-${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
- * `${DESTDIR}${prefix}/lib`
- * `${DESTDIR}${prefix}/lib/ruby`
- * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}`
- * `${DESTDIR}${prefix}/lib/ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
- * `${DESTDIR}${prefix}/lib/ruby/site_ruby`
- * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}`
- * `${DESTDIR}${prefix}/lib/ruby/site_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
- * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby`
- * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}`
- * `${DESTDIR}${prefix}/lib/ruby/vendor_ruby/${MAJOR}.${MINOR}.${TEENY}/${PLATFORM}`
- * `${DESTDIR}${prefix}/lib/ruby/gems/${MAJOR}.${MINOR}.${TEENY}`
- * `${DESTDIR}${prefix}/share/man/man1`
- * `${DESTDIR}${prefix}/share/ri/${MAJOR}.${MINOR}.${TEENY}/system`
-
-
- If Ruby's API version is '*x.y.z*', the `${MAJOR}` is '*x*', the
- `${MINOR}` is '*y*', and the `${TEENY}` is '*z*'.
-
- **NOTE**: teeny of the API version may be different from one of Ruby's
- program version
-
- You may have to be a super user to install Ruby.
-
-If you fail to compile Ruby, please send the detailed error report with the
-error log and machine/OS type, to help others.
-
-Some extension libraries may not get compiled because of lack of necessary
-external libraries and/or headers, then you will need to run '`make distclean-ext`'
-to remove old configuration after installing them in such case.
+[ruby-talk-request@ruby-lang.org]: mailto:ruby-talk-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe
## Copying
-See the file [COPYING](COPYING).
+See the file [COPYING](rdoc-ref:COPYING).
## Feedback
-Questions about the Ruby language can be asked on the Ruby-Talk mailing list
-(https://www.ruby-lang.org/en/community/mailing-lists) or on websites like
-(https://stackoverflow.com).
-
-Bugs should be reported at https://bugs.ruby-lang.org. Read [HowToReport] for more information.
+Questions about the Ruby language can be asked on the [Ruby-Talk](https://www.ruby-lang.org/en/community/mailing-lists) mailing list
+or on websites like https://stackoverflow.com.
-[HowToReport]: https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport
+Bugs should be reported at https://bugs.ruby-lang.org. Read ["Reporting Issues"](https://docs.ruby-lang.org/en/master/contributing/reporting_issues_md.html) for more information.
## Contributing
-See the file [CONTRIBUTING.md](CONTRIBUTING.md)
+See ["Contributing to Ruby"](https://docs.ruby-lang.org/en/master/contributing_md.html), which includes setup and build instructions.
## The Author
diff --git a/aclocal.m4 b/aclocal.m4
index 940d91e83f..e69de29bb2 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,48 +0,0 @@
-# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
-
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-m4_include([tool/m4/_colorize_result_prepare.m4])
-m4_include([tool/m4/ac_msg_result.m4])
-m4_include([tool/m4/colorize_result.m4])
-m4_include([tool/m4/ruby_append_option.m4])
-m4_include([tool/m4/ruby_append_options.m4])
-m4_include([tool/m4/ruby_check_builtin_func.m4])
-m4_include([tool/m4/ruby_check_builtin_setjmp.m4])
-m4_include([tool/m4/ruby_check_printf_prefix.m4])
-m4_include([tool/m4/ruby_check_setjmp.m4])
-m4_include([tool/m4/ruby_check_signedness.m4])
-m4_include([tool/m4/ruby_check_sizeof.m4])
-m4_include([tool/m4/ruby_check_sysconf.m4])
-m4_include([tool/m4/ruby_cppoutfile.m4])
-m4_include([tool/m4/ruby_decl_attribute.m4])
-m4_include([tool/m4/ruby_default_arch.m4])
-m4_include([tool/m4/ruby_define_if.m4])
-m4_include([tool/m4/ruby_defint.m4])
-m4_include([tool/m4/ruby_dtrace_available.m4])
-m4_include([tool/m4/ruby_dtrace_postprocess.m4])
-m4_include([tool/m4/ruby_func_attribute.m4])
-m4_include([tool/m4/ruby_mingw32.m4])
-m4_include([tool/m4/ruby_prepend_option.m4])
-m4_include([tool/m4/ruby_prog_gnu_ld.m4])
-m4_include([tool/m4/ruby_replace_funcs.m4])
-m4_include([tool/m4/ruby_replace_type.m4])
-m4_include([tool/m4/ruby_rm_recursive.m4])
-m4_include([tool/m4/ruby_setjmp_type.m4])
-m4_include([tool/m4/ruby_stack_grow_direction.m4])
-m4_include([tool/m4/ruby_try_cflags.m4])
-m4_include([tool/m4/ruby_try_cxxflags.m4])
-m4_include([tool/m4/ruby_try_ldflags.m4])
-m4_include([tool/m4/ruby_type_attribute.m4])
-m4_include([tool/m4/ruby_universal_arch.m4])
-m4_include([tool/m4/ruby_werror_flag.m4])
diff --git a/addr2line.c b/addr2line.c
index dc4364aaf5..e5f25293e2 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -159,11 +159,15 @@ typedef struct obj_info {
struct dwarf_section debug_info;
struct dwarf_section debug_line;
struct dwarf_section debug_ranges;
+ struct dwarf_section debug_str_offsets;
+ struct dwarf_section debug_addr;
+ struct dwarf_section debug_rnglists;
struct dwarf_section debug_str;
+ struct dwarf_section debug_line_str;
struct obj_info *next;
} obj_info_t;
-#define DWARF_SECTION_COUNT 5
+#define DWARF_SECTION_COUNT 9
static struct dwarf_section *
obj_dwarf_section_at(obj_info_t *obj, int n)
@@ -173,7 +177,11 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
&obj->debug_info,
&obj->debug_line,
&obj->debug_ranges,
- &obj->debug_str
+ &obj->debug_str_offsets,
+ &obj->debug_addr,
+ &obj->debug_rnglists,
+ &obj->debug_str,
+ &obj->debug_line_str
};
if (n < 0 || DWARF_SECTION_COUNT <= n) {
abort();
@@ -190,12 +198,12 @@ struct debug_section_definition {
static char binary_filename[PATH_MAX + 1];
static unsigned long
-uleb128(char **p)
+uleb128(const char **p)
{
unsigned long r = 0;
int s = 0;
for (;;) {
- unsigned char b = *(unsigned char *)(*p)++;
+ unsigned char b = (unsigned char)*(*p)++;
if (b < 0x80) {
r += (unsigned long)b << s;
break;
@@ -207,12 +215,12 @@ uleb128(char **p)
}
static long
-sleb128(char **p)
+sleb128(const char **p)
{
long r = 0;
int s = 0;
for (;;) {
- unsigned char b = *(unsigned char *)(*p)++;
+ unsigned char b = (unsigned char)*(*p)++;
if (b < 0x80) {
if (b & 0x40) {
r -= (0x80 - b) << s;
@@ -229,7 +237,7 @@ sleb128(char **p)
}
static const char *
-get_nth_dirname(unsigned long dir, char *p)
+get_nth_dirname(unsigned long dir, const char *p)
{
if (!dir--) {
return "";
@@ -246,39 +254,51 @@ get_nth_dirname(unsigned long dir, char *p)
return p;
}
+static const char *parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index);
+
static void
-fill_filename(int file, char *include_directories, char *filenames, line_info_t *line, obj_info_t *obj)
+fill_filename(int file, uint8_t format, uint16_t version, const char *include_directories, const char *filenames, line_info_t *line, obj_info_t *obj)
{
int i;
- char *p = filenames;
- char *filename;
+ const char *p = filenames;
+ const char *filename;
unsigned long dir;
- for (i = 1; i <= file; i++) {
- filename = p;
- if (!*p) {
- /* Need to output binary file name? */
- kprintf("Unexpected file number %d in %s at %tx\n",
- file, binary_filename, filenames - obj->mapped);
- return;
- }
- while (*p) p++;
- p++;
- dir = uleb128(&p);
- /* last modified. */
- uleb128(&p);
- /* size of the file. */
- uleb128(&p);
-
- if (i == file) {
- line->filename = filename;
- line->dirname = get_nth_dirname(dir, include_directories);
- }
+ if (version >= 5) {
+ const char *path;
+ uint64_t directory_index = -1;
+ parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index);
+ line->filename = path;
+ parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL);
+ line->dirname = path;
+ }
+ else {
+ for (i = 1; i <= file; i++) {
+ filename = p;
+ if (!*p) {
+ /* Need to output binary file name? */
+ kprintf("Unexpected file number %d in %s at %tx\n",
+ file, binary_filename, filenames - obj->mapped);
+ return;
+ }
+ while (*p) p++;
+ p++;
+ dir = uleb128(&p);
+ /* last modified. */
+ uleb128(&p);
+ /* size of the file. */
+ uleb128(&p);
+
+ if (i == file) {
+ line->filename = filename;
+ line->dirname = get_nth_dirname(dir, include_directories);
+ }
+ }
}
}
static void
fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
- char *include_directories, char *filenames,
+ uint8_t format, uint16_t version, const char *include_directories, const char *filenames,
obj_info_t *obj, line_info_t *lines, int offset)
{
int i;
@@ -288,7 +308,7 @@ fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
/* We assume one line code doesn't result >100 bytes of native code.
We may want more reliable way eventually... */
if (addr < a && a < addr + 100) {
- fill_filename(file, include_directories, filenames, &lines[i], obj);
+ fill_filename(file, format, version, include_directories, filenames, &lines[i], obj);
lines[i].line = line;
}
}
@@ -313,7 +333,7 @@ struct LineNumberProgramHeader {
};
static int
-parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
+parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header)
{
const char *p = *pp;
header->unit_length = *(uint32_t *)p;
@@ -330,7 +350,13 @@ parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
header->version = *(uint16_t *)p;
p += sizeof(uint16_t);
- if (header->version > 4) return -1;
+ if (header->version > 5) return -1;
+
+ if (header->version >= 5) {
+ /* address_size = *(uint8_t *)p++; */
+ /* segment_selector_size = *(uint8_t *)p++; */
+ p += 2;
+ }
header->header_length = header->format == 4 ? *(uint32_t *)p : *(uint64_t *)p;
p += header->format;
@@ -351,20 +377,27 @@ parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
/* header->standard_opcode_lengths = (uint8_t *)p - 1; */
p += header->opcode_base - 1;
- header->include_directories = p;
+ if (header->version >= 5) {
+ header->include_directories = p;
+ p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL);
+ header->filenames = p;
+ }
+ else {
+ header->include_directories = p;
- /* temporary measure for compress-debug-sections */
- if (p >= header->cu_end) return -1;
+ /* temporary measure for compress-debug-sections */
+ if (p >= header->cu_end) return -1;
- /* skip include directories */
- while (*p) {
- p = memchr(p, '\0', header->cu_end - p);
- if (!p) return -1;
- p++;
- }
- p++;
+ /* skip include directories */
+ while (*p) {
+ p = memchr(p, '\0', header->cu_end - p);
+ if (!p) return -1;
+ p++;
+ }
+ p++;
- header->filenames = p;
+ header->filenames = p;
+ }
*pp = header->cu_start;
@@ -372,7 +405,7 @@ parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
}
static int
-parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
+parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
obj_info_t *obj, line_info_t *lines, int offset)
{
const char *p = (const char *)*debug_line;
@@ -390,15 +423,17 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
/* int epilogue_begin = 0; */
/* unsigned int isa = 0; */
- if (parse_debug_line_header(&p, &header))
+ if (parse_debug_line_header(obj, &p, &header))
return -1;
is_stmt = header.default_is_stmt;
#define FILL_LINE() \
do { \
fill_line(num_traces, traces, addr, file, line, \
- (char *)header.include_directories, \
- (char *)header.filenames, \
+ header.format, \
+ header.version, \
+ header.include_directories, \
+ header.filenames, \
obj, lines, offset); \
/*basic_block = prologue_end = epilogue_begin = 0;*/ \
} while (0)
@@ -411,19 +446,19 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
FILL_LINE();
break;
case DW_LNS_advance_pc:
- a = uleb128((char **)&p);
+ a = uleb128(&p) * header.minimum_instruction_length;
addr += a;
break;
case DW_LNS_advance_line: {
- long a = sleb128((char **)&p);
+ long a = sleb128(&p);
line += a;
break;
}
case DW_LNS_set_file:
- file = (unsigned int)uleb128((char **)&p);
+ file = (unsigned int)uleb128(&p);
break;
case DW_LNS_set_column:
- /*column = (unsigned int)*/(void)uleb128((char **)&p);
+ /*column = (unsigned int)*/(void)uleb128(&p);
break;
case DW_LNS_negate_stmt:
is_stmt = !is_stmt;
@@ -437,7 +472,8 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
addr += a;
break;
case DW_LNS_fixed_advance_pc:
- a = *(unsigned char *)p++;
+ a = *(uint16_t *)p;
+ p += sizeof(uint16_t);
addr += a;
break;
case DW_LNS_set_prologue_end:
@@ -447,10 +483,10 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
/* epilogue_begin = 1; */
break;
case DW_LNS_set_isa:
- /* isa = (unsigned int)*/(void)uleb128((char **)&p);
+ /* isa = (unsigned int)*/(void)uleb128(&p);
break;
case 0:
- a = *(unsigned char *)p++;
+ a = uleb128(&p);
op = *p++;
switch (op) {
case DW_LNE_end_sequence:
@@ -474,7 +510,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
break;
case DW_LNE_set_discriminator:
/* TODO:currently ignore */
- uleb128((char **)&p);
+ uleb128(&p);
break;
default:
kprintf("Unknown extended opcode: %d in %s\n",
@@ -497,10 +533,10 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
static int
parse_debug_line(int num_traces, void **traces,
- char *debug_line, unsigned long size,
+ const char *debug_line, unsigned long size,
obj_info_t *obj, line_info_t *lines, int offset)
{
- char *debug_line_end = debug_line + size;
+ const char *debug_line_end = debug_line + size;
while (debug_line < debug_line_end) {
if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
return -1;
@@ -807,32 +843,51 @@ enum
DW_FORM_addrx4 = 0x2c
};
+/* Range list entry encodings */
+enum {
+ DW_RLE_end_of_list = 0x00,
+ DW_RLE_base_addressx = 0x01,
+ DW_RLE_startx_endx = 0x02,
+ DW_RLE_startx_length = 0x03,
+ DW_RLE_offset_pair = 0x04,
+ DW_RLE_base_address = 0x05,
+ DW_RLE_start_end = 0x06,
+ DW_RLE_start_length = 0x07
+};
+
enum {
VAL_none = 0,
VAL_cstr = 1,
VAL_data = 2,
VAL_uint = 3,
- VAL_int = 4
+ VAL_int = 4,
+ VAL_addr = 5
};
# define ABBREV_TABLE_SIZE 256
typedef struct {
obj_info_t *obj;
- char *file;
- char *current_cu;
+ const char *file;
+ uint8_t current_version;
+ const char *current_cu;
uint64_t current_low_pc;
- char *debug_line_cu_end;
- char *debug_line_files;
- char *debug_line_directories;
- char *p;
- char *cu_end;
- char *pend;
- char *q0;
- char *q;
+ uint64_t current_str_offsets_base;
+ uint64_t current_addr_base;
+ uint64_t current_rnglists_base;
+ const char *debug_line_cu_end;
+ uint8_t debug_line_format;
+ uint16_t debug_line_version;
+ const char *debug_line_files;
+ const char *debug_line_directories;
+ const char *p;
+ const char *cu_end;
+ const char *pend;
+ const char *q0;
+ const char *q;
int format; // 4 or 8
uint8_t address_size;
int level;
- char *abbrev_table[ABBREV_TABLE_SIZE];
+ const char *abbrev_table[ABBREV_TABLE_SIZE];
} DebugInfoReader;
typedef struct {
@@ -843,9 +898,10 @@ typedef struct {
typedef struct {
union {
- char *ptr;
+ const char *ptr;
uint64_t uint64;
int64_t int64;
+ uint64_t addr_idx;
} as;
uint64_t off;
uint64_t at;
@@ -854,8 +910,11 @@ typedef struct {
int type;
} DebugInfoValue;
-/* TODO: Big Endian */
+#if defined(WORDS_BIGENDIAN)
+#define MERGE_2INTS(a,b,sz) (((uint64_t)(a)<<sz)|(b))
+#else
#define MERGE_2INTS(a,b,sz) (((uint64_t)(b)<<sz)|(a))
+#endif
static uint16_t
get_uint16(const uint8_t *p)
@@ -876,39 +935,39 @@ get_uint64(const uint8_t *p)
}
static uint8_t
-read_uint8(char **ptr)
+read_uint8(const char **ptr)
{
- const unsigned char *p = (const unsigned char *)*ptr;
- *ptr = (char *)(p + 1);
- return *p;
+ const char *p = *ptr;
+ *ptr = (p + 1);
+ return (uint8_t)*p;
}
static uint16_t
-read_uint16(char **ptr)
+read_uint16(const char **ptr)
{
- const unsigned char *p = (const unsigned char *)*ptr;
- *ptr = (char *)(p + 2);
- return get_uint16(p);
+ const char *p = *ptr;
+ *ptr = (p + 2);
+ return get_uint16((const uint8_t *)p);
}
static uint32_t
-read_uint24(char **ptr)
+read_uint24(const char **ptr)
{
- const unsigned char *p = (const unsigned char *)*ptr;
- *ptr = (char *)(p + 3);
- return (*p << 16) | get_uint16(p+1);
+ const char *p = *ptr;
+ *ptr = (p + 3);
+ return ((uint8_t)*p << 16) | get_uint16((const uint8_t *)p+1);
}
static uint32_t
-read_uint32(char **ptr)
+read_uint32(const char **ptr)
{
- const unsigned char *p = (const unsigned char *)*ptr;
- *ptr = (char *)(p + 4);
- return get_uint32(p);
+ const char *p = *ptr;
+ *ptr = (p + 4);
+ return get_uint32((const uint8_t *)p);
}
static uint64_t
-read_uint64(char **ptr)
+read_uint64(const char **ptr)
{
const unsigned char *p = (const unsigned char *)*ptr;
*ptr = (char *)(p + 8);
@@ -916,7 +975,7 @@ read_uint64(char **ptr)
}
static uintptr_t
-read_uintptr(char **ptr)
+read_uintptr(const char **ptr)
{
const unsigned char *p = (const unsigned char *)*ptr;
*ptr = (char *)(p + SIZEOF_VOIDP);
@@ -958,13 +1017,33 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
reader->pend = obj->debug_info.ptr + obj->debug_info.size;
reader->debug_line_cu_end = obj->debug_line.ptr;
reader->current_low_pc = 0;
+ reader->current_str_offsets_base = 0;
+ reader->current_addr_base = 0;
+ reader->current_rnglists_base = 0;
+}
+
+static void
+di_skip_die_attributes(const char **p)
+{
+ for (;;) {
+ uint64_t at = uleb128(p);
+ uint64_t form = uleb128(p);
+ if (!at && !form) break;
+ switch (form) {
+ default:
+ break;
+ case DW_FORM_implicit_const:
+ sleb128(p);
+ break;
+ }
+ }
}
static void
di_read_debug_abbrev_cu(DebugInfoReader *reader)
{
uint64_t prev = 0;
- char *p = reader->q0;
+ const char *p = reader->q0;
for (;;) {
uint64_t abbrev_number = uleb128(&p);
if (abbrev_number <= prev) break;
@@ -974,12 +1053,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
prev = abbrev_number;
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
}
}
@@ -990,10 +1064,12 @@ di_read_debug_line_cu(DebugInfoReader *reader)
struct LineNumberProgramHeader header;
p = (const char *)reader->debug_line_cu_end;
- if (parse_debug_line_header(&p, &header))
+ if (parse_debug_line_header(reader->obj, &p, &header))
return -1;
reader->debug_line_cu_end = (char *)header.cu_end;
+ reader->debug_line_format = header.format;
+ reader->debug_line_version = header.version;
reader->debug_line_directories = (char *)header.include_directories;
reader->debug_line_files = (char *)header.filenames;
@@ -1001,6 +1077,13 @@ di_read_debug_line_cu(DebugInfoReader *reader)
}
static void
+set_addr_idx_value(DebugInfoValue *v, uint64_t n)
+{
+ v->as.addr_idx = n;
+ v->type = VAL_addr;
+}
+
+static void
set_uint_value(DebugInfoValue *v, uint64_t n)
{
v->as.uint64 = n;
@@ -1015,7 +1098,7 @@ set_int_value(DebugInfoValue *v, int64_t n)
}
static void
-set_cstr_value(DebugInfoValue *v, char *s)
+set_cstr_value(DebugInfoValue *v, const char *s)
{
v->as.ptr = s;
v->off = 0;
@@ -1023,7 +1106,7 @@ set_cstr_value(DebugInfoValue *v, char *s)
}
static void
-set_cstrp_value(DebugInfoValue *v, char *s, uint64_t off)
+set_cstrp_value(DebugInfoValue *v, const char *s, uint64_t off)
{
v->as.ptr = s;
v->off = off;
@@ -1031,7 +1114,7 @@ set_cstrp_value(DebugInfoValue *v, char *s, uint64_t off)
}
static void
-set_data_value(DebugInfoValue *v, char *s)
+set_data_value(DebugInfoValue *v, const char *s)
{
v->as.ptr = s;
v->type = VAL_data;
@@ -1047,19 +1130,39 @@ get_cstr_value(DebugInfoValue *v)
}
}
+static const char *
+resolve_strx(DebugInfoReader *reader, uint64_t idx)
+{
+ const char *p = reader->obj->debug_str_offsets.ptr + reader->current_str_offsets_base;
+ uint64_t off;
+ if (reader->format == 4) {
+ off = ((uint32_t *)p)[idx];
+ }
+ else {
+ off = ((uint64_t *)p)[idx];
+ }
+ return reader->obj->debug_str.ptr + off;
+}
+
+static void
+debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v)
+{
+ if (reader->address_size == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->address_size == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+}
+
static void
debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
{
switch (form) {
case DW_FORM_addr:
- if (reader->address_size == 4) {
- set_uint_value(v, read_uint32(&reader->p));
- } else if (reader->address_size == 8) {
- set_uint_value(v, read_uint64(&reader->p));
- } else {
- fprintf(stderr,"unknown address_size:%d", reader->address_size);
- abort();
- }
+ debug_info_reader_read_addr_value(reader, v);
break;
case DW_FORM_block2:
v->size = read_uint16(&reader->p);
@@ -1111,13 +1214,19 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uleb128(reader));
break;
case DW_FORM_ref_addr:
- if (reader->address_size == 4) {
- set_uint_value(v, read_uint32(&reader->p));
- } else if (reader->address_size == 8) {
- set_uint_value(v, read_uint64(&reader->p));
+ if (reader->current_version <= 2) {
+ // DWARF Version 2 specifies that references have
+ // the same size as an address on the target system
+ debug_info_reader_read_addr_value(reader, v);
} else {
- fprintf(stderr,"unknown address_size:%d", reader->address_size);
- abort();
+ if (reader->format == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->format == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown format:%d", reader->format);
+ abort();
+ }
}
break;
case DW_FORM_ref1:
@@ -1159,11 +1268,10 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, 1);
break;
case DW_FORM_strx:
- set_uint_value(v, uleb128(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, uleb128(&reader->p)));
break;
case DW_FORM_addrx:
- /* TODO: read .debug_addr */
- set_uint_value(v, uleb128(&reader->p));
+ set_addr_idx_value(v, uleb128(&reader->p));
break;
case DW_FORM_ref_sup4:
set_uint_value(v, read_uint32(&reader->p));
@@ -1178,8 +1286,7 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
reader->p += v->size;
break;
case DW_FORM_line_strp:
- set_uint_value(v, read_uint(reader));
- /* *p = reader->file + reader->line->sh_offset + ret; */
+ set_cstrp_value(v, reader->obj->debug_line_str.ptr, read_uint(reader));
break;
case DW_FORM_ref_sig8:
set_uint_value(v, read_uint64(&reader->p));
@@ -1197,28 +1304,28 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uint64(&reader->p));
break;
case DW_FORM_strx1:
- set_uint_value(v, read_uint8(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint8(&reader->p)));
break;
case DW_FORM_strx2:
- set_uint_value(v, read_uint16(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint16(&reader->p)));
break;
case DW_FORM_strx3:
- set_uint_value(v, read_uint24(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint24(&reader->p)));
break;
case DW_FORM_strx4:
- set_uint_value(v, read_uint32(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint32(&reader->p)));
break;
case DW_FORM_addrx1:
- set_uint_value(v, read_uint8(&reader->p));
+ set_addr_idx_value(v, read_uint8(&reader->p));
break;
case DW_FORM_addrx2:
- set_uint_value(v, read_uint16(&reader->p));
+ set_addr_idx_value(v, read_uint16(&reader->p));
break;
case DW_FORM_addrx3:
- set_uint_value(v, read_uint24(&reader->p));
+ set_addr_idx_value(v, read_uint24(&reader->p));
break;
case DW_FORM_addrx4:
- set_uint_value(v, read_uint32(&reader->p));
+ set_addr_idx_value(v, read_uint32(&reader->p));
break;
case 0:
goto fail;
@@ -1232,10 +1339,10 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
}
/* find abbrev in current compilation unit */
-static char *
+static const char *
di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
{
- char *p;
+ const char *p;
if (abbrev_number < ABBREV_TABLE_SIZE) {
return reader->abbrev_table[abbrev_number];
}
@@ -1243,12 +1350,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
/* skip 255th record */
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
if (n == 0) {
fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
@@ -1256,12 +1358,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
}
uleb128(&p); /* tag */
p++; /* has_children */
- /* skip content */
- for (;;) {
- uint64_t at = uleb128(&p);
- uint64_t form = uleb128(&p);
- if (!at && !form) break;
- }
+ di_skip_die_attributes(&p);
}
return p;
}
@@ -1275,7 +1372,7 @@ hexdump0(const unsigned char *p, size_t n)
for (i=0; i < n; i++){
switch (i & 15) {
case 0:
- fprintf(stderr, "%02zd: %02X ", i/16, p[i]);
+ fprintf(stderr, "%02" PRIdSIZE ": %02X ", i/16, p[i]);
break;
case 15:
fprintf(stderr, "%02X\n", p[i]);
@@ -1296,16 +1393,16 @@ div_inspect(DebugInfoValue *v)
{
switch (v->type) {
case VAL_uint:
- fprintf(stderr,"%d: type:%d size:%zx v:%lx\n",__LINE__,v->type,v->size,v->as.uint64);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRIx64"\n",__LINE__,v->type,v->size,v->as.uint64);
break;
case VAL_int:
- fprintf(stderr,"%d: type:%d size:%zx v:%ld\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRId64"\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
break;
case VAL_cstr:
- fprintf(stderr,"%d: type:%d size:%zx v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
break;
case VAL_data:
- fprintf(stderr,"%d: type:%d size:%zx v:\n",__LINE__,v->type,v->size);
+ fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size);
hexdump(v->as.ptr, 16);
break;
}
@@ -1356,6 +1453,76 @@ di_skip_records(DebugInfoReader *reader)
}
}
+typedef struct addr_header {
+ const char *ptr;
+ uint64_t unit_length;
+ uint8_t format;
+ uint8_t address_size;
+ /* uint8_t segment_selector_size; */
+} addr_header_t;
+
+static void
+addr_header_init(obj_info_t *obj, addr_header_t *header) {
+ const char *p = obj->debug_addr.ptr;
+
+ header->ptr = p;
+
+ if (!p) return;
+
+ header->unit_length = *(uint32_t *)p;
+ p += sizeof(uint32_t);
+
+ header->format = 4;
+ if (header->unit_length == 0xffffffff) {
+ header->unit_length = *(uint64_t *)p;
+ p += sizeof(uint64_t);
+ header->format = 8;
+ }
+
+ p += 2; /* version */
+ header->address_size = *p++;
+ p++; /* segment_selector_size */
+}
+
+static uint64_t
+read_addr(addr_header_t *header, uint64_t addr_base, uint64_t idx) {
+ if (header->address_size == 4) {
+ return ((uint32_t*)(header->ptr + addr_base))[idx];
+ }
+ else {
+ return ((uint64_t*)(header->ptr + addr_base))[idx];
+ }
+}
+
+typedef struct rnglists_header {
+ uint64_t unit_length;
+ uint8_t format;
+ uint8_t address_size;
+ uint32_t offset_entry_count;
+} rnglists_header_t;
+
+static void
+rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) {
+ const char *p = obj->debug_rnglists.ptr;
+
+ if (!p) return;
+
+ header->unit_length = *(uint32_t *)p;
+ p += sizeof(uint32_t);
+
+ header->format = 4;
+ if (header->unit_length == 0xffffffff) {
+ header->unit_length = *(uint64_t *)p;
+ p += sizeof(uint64_t);
+ header->format = 8;
+ }
+
+ p += 2; /* version */
+ header->address_size = *p++;
+ p++; /* segment_selector_size */
+ header->offset_entry_count = *(uint32_t *)p;
+}
+
typedef struct {
uint64_t low_pc;
uint64_t high_pc;
@@ -1366,31 +1533,53 @@ typedef struct {
} ranges_t;
static void
-ranges_set(ranges_t *ptr, DebugInfoValue *v)
+ranges_set(ranges_t *ptr, DebugInfoValue *v, addr_header_t *addr_header, uint64_t addr_base)
{
+ uint64_t n = 0;
+ if (v->type == VAL_uint) {
+ n = v->as.uint64;
+ }
+ else if (v->type == VAL_addr) {
+ n = read_addr(addr_header, addr_base, v->as.addr_idx);
+ }
switch (v->at) {
case DW_AT_low_pc:
- ptr->low_pc = v->as.uint64;
+ ptr->low_pc = n;
ptr->low_pc_set = true;
break;
case DW_AT_high_pc:
if (v->form == DW_FORM_addr) {
- ptr->high_pc = v->as.uint64;
+ ptr->high_pc = n;
}
else {
- ptr->high_pc = ptr->low_pc + v->as.uint64;
+ ptr->high_pc = ptr->low_pc + n;
}
ptr->high_pc_set = true;
break;
case DW_AT_ranges:
- ptr->ranges = v->as.uint64;
+ ptr->ranges = n;
ptr->ranges_set = true;
break;
}
}
+static uint64_t
+read_dw_form_addr(DebugInfoReader *reader, const char **ptr)
+{
+ const char *p = *ptr;
+ *ptr = p + reader->address_size;
+ if (reader->address_size == 4) {
+ return read_uint32(&p);
+ } else if (reader->address_size == 8) {
+ return read_uint64(&p);
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+}
+
static uintptr_t
-ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
+ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header)
{
if (ptr->high_pc_set) {
if (ptr->ranges_set || !ptr->low_pc_set) {
@@ -1402,8 +1591,66 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
}
else if (ptr->ranges_set) {
/* TODO: support base address selection entry */
- char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
+ const char *p;
uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
+ bool base_valid = true;
+ if (reader->current_version >= 5) {
+ if (rnglists_header->offset_entry_count == 0) {
+ // DW_FORM_sec_offset
+ p = reader->obj->debug_rnglists.ptr + ptr->ranges + reader->current_rnglists_base;
+ }
+ else {
+ // DW_FORM_rnglistx
+ const char *offset_array = reader->obj->debug_rnglists.ptr + reader->current_rnglists_base;
+ if (rnglists_header->format == 4) {
+ p = offset_array + ((uint32_t *)offset_array)[ptr->ranges];
+ }
+ else {
+ p = offset_array + ((uint64_t *)offset_array)[ptr->ranges];
+ }
+ }
+ for (;;) {
+ uint8_t rle = read_uint8(&p);
+ uintptr_t from = 0, to = 0;
+ if (rle == DW_RLE_end_of_list) break;
+ switch (rle) {
+ case DW_RLE_base_addressx:
+ uleb128(&p);
+ base_valid = false; /* not supported yet */
+ break;
+ case DW_RLE_startx_endx:
+ uleb128(&p);
+ uleb128(&p);
+ break;
+ case DW_RLE_startx_length:
+ uleb128(&p);
+ uleb128(&p);
+ break;
+ case DW_RLE_offset_pair:
+ if (!base_valid) break;
+ from = (uintptr_t)base + uleb128(&p);
+ to = (uintptr_t)base + uleb128(&p);
+ break;
+ case DW_RLE_base_address:
+ base = read_dw_form_addr(reader, &p);
+ base_valid = true;
+ break;
+ case DW_RLE_start_end:
+ from = (uintptr_t)read_dw_form_addr(reader, &p);
+ to = (uintptr_t)read_dw_form_addr(reader, &p);
+ break;
+ case DW_RLE_start_length:
+ from = (uintptr_t)read_dw_form_addr(reader, &p);
+ to = from + uleb128(&p);
+ break;
+ }
+ if (from <= addr && addr < to) {
+ return from;
+ }
+ }
+ return false;
+ }
+ p = reader->obj->debug_ranges.ptr + ptr->ranges;
for (;;) {
uintptr_t from = read_uintptr(&p);
uintptr_t to = read_uintptr(&p);
@@ -1413,7 +1660,7 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
base = to;
}
else if (base + from <= addr && addr < base + to) {
- return from;
+ return (uintptr_t)base + from;
}
}
}
@@ -1471,6 +1718,7 @@ di_read_cu(DebugInfoReader *reader)
}
reader->cu_end = reader->p + unit_length;
version = read_uint16(&reader->p);
+ reader->current_version = version;
if (version > 5) {
return -1;
}
@@ -1503,30 +1751,76 @@ di_read_cu(DebugInfoReader *reader)
break;
}
+ reader->current_str_offsets_base = 0;
+ reader->current_addr_base = 0;
+ reader->current_rnglists_base = 0;
+
+ DebugInfoValue low_pc = {{}};
/* enumerate abbrev */
for (;;) {
DebugInfoValue v = {{}};
if (!di_read_record(reader, &v)) break;
switch (v.at) {
case DW_AT_low_pc:
- reader->current_low_pc = v.as.uint64;
+ // clang may output DW_AT_addr_base after DW_AT_low_pc.
+ // We need to resolve the DW_FORM_addr* after DW_AT_addr_base is parsed.
+ low_pc = v;
+ break;
+ case DW_AT_str_offsets_base:
+ reader->current_str_offsets_base = v.as.uint64;
+ break;
+ case DW_AT_addr_base:
+ reader->current_addr_base = v.as.uint64;
+ break;
+ case DW_AT_rnglists_base:
+ reader->current_rnglists_base = v.as.uint64;
break;
}
}
+ // Resolve the DW_FORM_addr of DW_AT_low_pc
+ switch (low_pc.type) {
+ case VAL_uint:
+ reader->current_low_pc = low_pc.as.uint64;
+ break;
+ case VAL_addr:
+ {
+ addr_header_t header;
+ addr_header_init(reader->obj, &header);
+ reader->current_low_pc = read_addr(&header, reader->current_addr_base, low_pc.as.addr_idx);
+ }
+ break;
+ }
} while (0);
#endif
return 0;
}
static void
-read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line)
+read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line)
{
- char *p = reader->p;
- char *q = reader->q;
+ const char *p = reader->p;
+ const char *q = reader->q;
int level = reader->level;
DIE die;
- reader->p = reader->current_cu + abstract_origin;
+ switch (form) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ reader->p = reader->current_cu + abstract_origin;
+ break;
+ case DW_FORM_ref_addr:
+ goto finish; /* not supported yet */
+ case DW_FORM_ref_sig8:
+ goto finish; /* not supported yet */
+ case DW_FORM_ref_sup4:
+ case DW_FORM_ref_sup8:
+ goto finish; /* not supported yet */
+ default:
+ goto finish;
+ }
if (!di_read_die(reader, &die)) goto finish;
/* enumerate abbrev */
@@ -1549,6 +1843,13 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_inf
static void
debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
line_info_t *lines, int offset) {
+
+ addr_header_t addr_header = {};
+ addr_header_init(reader->obj, &addr_header);
+
+ rnglists_header_t rnglists_header = {};
+ rnglists_header_init(reader->obj, &rnglists_header);
+
while (reader->p < reader->cu_end) {
DIE die;
ranges_t ranges = {};
@@ -1575,7 +1876,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
line.sname = get_cstr_value(&v);
break;
case DW_AT_call_file:
- fill_filename((int)v.as.uint64, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
+ fill_filename((int)v.as.uint64, reader->debug_line_format, reader->debug_line_version, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
break;
case DW_AT_call_line:
line.line = (int)v.as.uint64;
@@ -1583,7 +1884,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
case DW_AT_low_pc:
case DW_AT_high_pc:
case DW_AT_ranges:
- ranges_set(&ranges, &v);
+ ranges_set(&ranges, &v, &addr_header, reader->current_addr_base);
break;
case DW_AT_declaration:
goto skip_die;
@@ -1591,7 +1892,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
/* 1 or 3 */
break; /* goto skip_die; */
case DW_AT_abstract_origin:
- read_abstract_origin(reader, v.as.uint64, &line);
+ read_abstract_origin(reader, v.form, v.as.uint64, &line);
break; /* goto skip_die; */
}
}
@@ -1600,9 +1901,9 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
for (int i=offset; i < num_traces; i++) {
uintptr_t addr = (uintptr_t)traces[i];
uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
- uintptr_t saddr = ranges_include(reader, &ranges, offset);
+ uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header);
if (saddr) {
- /* fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
+ /* fprintf(stdout, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
if (lines[i].sname) {
line_info_t *lp = malloc(sizeof(line_info_t));
memcpy(lp, &lines[i], sizeof(line_info_t));
@@ -1621,10 +1922,59 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
}
}
+// This function parses the following attributes of Line Number Program Header in DWARF 5:
+//
+// * directory_entry_format_count
+// * directory_entry_format
+// * directories_count
+// * directories
+//
+// or
+//
+// * file_name_entry_format_count
+// * file_name_entry_format
+// * file_names_count
+// * file_names
+//
+// It records DW_LNCT_path and DW_LNCT_directory_index at the index "idx".
+static const char *
+parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index) {
+ int i, j;
+ int entry_format_count = *(uint8_t *)p++;
+ const char *entry_format = p;
+
+ /* skip the part of entry_format */
+ for (i = 0; i < entry_format_count * 2; i++) uleb128(&p);
+
+ int entry_count = (int)uleb128(&p);
+
+ DebugInfoReader reader;
+ debug_info_reader_init(&reader, obj);
+ reader.format = format;
+ reader.p = p;
+ for (j = 0; j < entry_count; j++) {
+ const char *format = entry_format;
+ for (i = 0; i < entry_format_count; i++) {
+ DebugInfoValue v = {{}};
+ unsigned long dw_lnct = uleb128(&format);
+ unsigned long dw_form = uleb128(&format);
+ debug_info_reader_read_value(&reader, dw_form, &v);
+ if (dw_lnct == 1 /* DW_LNCT_path */ && v.type == VAL_cstr && out_path)
+ *out_path = v.as.ptr + v.off;
+ if (dw_lnct == 2 /* DW_LNCT_directory_index */ && v.type == VAL_uint && out_directory_index)
+ *out_directory_index = v.as.uint64;
+ }
+ if (j == idx) return 0;
+ }
+
+ return reader.p;
+}
+
#ifdef USE_ELF
static unsigned long
uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
{
+ *ptr = NULL;
#ifdef SUPPORT_COMPRESSED_DEBUG_LINE
ElfW(Chdr) *chdr = (ElfW(Chdr) *)(file + shdr->sh_offset);
unsigned long destsize = chdr->ch_size;
@@ -1645,6 +1995,7 @@ uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
fail:
free(*ptr);
+ *ptr = NULL;
#endif
return 0;
}
@@ -1747,7 +2098,11 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
".debug_info",
".debug_line",
".debug_ranges",
- ".debug_str"
+ ".debug_str_offsets",
+ ".debug_addr",
+ ".debug_rnglists",
+ ".debug_str",
+ ".debug_line_str"
};
for (j=0; j < DWARF_SECTION_COUNT; j++) {
@@ -2003,7 +2358,11 @@ found_mach_header:
"__debug_info",
"__debug_line",
"__debug_ranges",
- "__debug_str"
+ "__debug_str_offsets",
+ "__debug_addr",
+ "__debug_rnglists",
+ "__debug_str",
+ "__debug_line_str",
};
struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
if (strcmp(scmd->segname, "__TEXT") == 0) {
@@ -2040,7 +2399,7 @@ found_mach_header:
char *strtab = file + cmd->stroff, *sname = 0;
uint32_t j;
uintptr_t saddr = 0;
- /* kprintf("[%2d]: %x/symtab %p\n", i, cmd->cmd, p); */
+ /* kprintf("[%2d]: %x/symtab %p\n", i, cmd->cmd, (void *)p); */
for (j = 0; j < cmd->nsyms; j++) {
uintptr_t symsize, d;
struct LP(nlist) *e = &nl[j];
@@ -2092,7 +2451,7 @@ fail:
#endif
#define HAVE_MAIN_EXE_PATH
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/sysctl.h>
#endif
/* ssize_t main_exe_path(void)
@@ -2101,17 +2460,21 @@ fail:
* and returns strlen(binary_filename).
* it is NUL terminated.
*/
-#if defined(__linux__)
+#if defined(__linux__) || defined(__NetBSD__)
static ssize_t
main_exe_path(void)
{
-# define PROC_SELF_EXE "/proc/self/exe"
+# if defined(__linux__)
+# define PROC_SELF_EXE "/proc/self/exe"
+# elif defined(__NetBSD__)
+# define PROC_SELF_EXE "/proc/curproc/exe"
+# endif
ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
if (len < 0) return 0;
binary_filename[len] = 0;
return len;
}
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
static ssize_t
main_exe_path(void)
{
@@ -2155,9 +2518,12 @@ print_line0(line_info_t *line, void *address)
else if (!line->path) {
kprintf("[0x%"PRIxPTR"]\n", addr);
}
- else if (!line->saddr || !line->sname) {
+ else if (!line->sname) {
kprintf("%s(0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, addr-line->base_addr, addr);
}
+ else if (!line->saddr) {
+ kprintf("%s(%s) [0x%"PRIxPTR"]\n", line->path, line->sname, addr);
+ }
else if (line->line <= 0) {
kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, line->sname,
d, addr);
@@ -2194,6 +2560,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
obj_info_t *obj = NULL;
/* 2 is NULL + main executable */
void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
+
#ifdef HAVE_MAIN_EXE_PATH
char *main_path = NULL; /* used on printing backtrace */
ssize_t len;
@@ -2224,8 +2591,8 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
/* if the binary is strip-ed, this may effect */
for (p=dladdr_fbases; *p; p++) {
if (*p == info.dli_fbase) {
- lines[i].path = info.dli_fname;
- lines[i].sname = info.dli_sname;
+ if (info.dli_fname) lines[i].path = info.dli_fname;
+ if (info.dli_sname) lines[i].sname = info.dli_sname;
goto next_line;
}
}
@@ -2235,9 +2602,11 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
obj->base_addr = (uintptr_t)info.dli_fbase;
path = info.dli_fname;
obj->path = path;
- lines[i].path = path;
- lines[i].sname = info.dli_sname;
- lines[i].saddr = (uintptr_t)info.dli_saddr;
+ if (path) lines[i].path = path;
+ if (info.dli_sname) {
+ lines[i].sname = info.dli_sname;
+ lines[i].saddr = (uintptr_t)info.dli_saddr;
+ }
strlcpy(binary_filename, path, PATH_MAX);
if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
break;
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index d31d4b2df9..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,96 +0,0 @@
----
-version: '{build}'
-init:
- - git config --global user.name git
- - git config --global user.email svn-admin@ruby-lang.org
-clone_depth: 10
-platform:
- - x64
-environment:
- ruby_version: "24-%Platform%"
- zlib_version: "1.2.11"
- matrix:
- - build: vs
- vs: 120
- ssl: OpenSSL
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- GEMS_FOR_TEST: ""
- - build: vs
- vs: 140
- ssl: OpenSSL-v111
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- GEMS_FOR_TEST: ""
- RELINE_TEST_ENCODING: "Windows-31J"
- UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=."
-for:
--
- matrix:
- only:
- - build: vs
- install:
- - ver
- - chcp
- - SET BITS=%Platform:x86=32%
- - SET BITS=%BITS:x=%
- - SET OPENSSL_DIR=C:\%ssl%-Win%BITS%
- - CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
- - SET vcvars
- - '"%vcvars%" %Platform:x64=amd64%'
- - SET ruby_path=C:\Ruby%ruby_version:-x86=%
- - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin
- - ruby --version
- - 'cl'
- - echo> Makefile srcdir=.
- - echo>> Makefile MSC_VER=0
- - echo>> Makefile RT=none
- - echo>> Makefile RT_VER=0
- - echo>> Makefile BUILTIN_ENCOBJS=nul
- - type win32\Makefile.sub >> Makefile
- - nmake %mflags% touch-unicode-files
- - nmake %mflags% %UPDATE_UNICODE% incs
- - nmake %mflags% extract-extlibs
- - del Makefile
- - mkdir \usr\local\bin
- - mkdir \usr\local\include
- - mkdir \usr\local\lib
- - SET ZLIB_ZIP=.downloaded-cache\zlib%zlib_version:.=%.zip
- - if not exist %ZLIB_ZIP% curl -fsSL -o %ZLIB_ZIP% --retry 10 https://zlib.net/zlib%zlib_version:.=%.zip
- - 7z x -aos -o%APPVEYOR_BUILD_FOLDER%\ext\zlib %ZLIB_ZIP%
- - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I
- - attrib +r /s /d
- - mkdir %Platform%-mswin_%vs%
- build_script:
- - cd %APPVEYOR_BUILD_FOLDER%
- - cd %Platform%-mswin_%vs%
- - ..\win32\configure.bat --without-ext=+,dbm,gdbm,readline --with-opt-dir=/usr/local --with-openssl-dir=%OPENSSL_DIR:\=/%
- - nmake -l
- - nmake install-nodoc
- - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')"
- - if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST%
- - \usr\bin\ruby -ropenssl -e "puts 'Build ' + OpenSSL::OPENSSL_VERSION, 'Runtime ' + OpenSSL::OPENSSL_LIBRARY_VERSION"
- test_script:
- - set /a JOBS=%NUMBER_OF_PROCESSORS%
- - nmake -l "TESTOPTS=-v -q" btest
- - nmake -l "TESTOPTS=-v -q" test-basic
- - nmake -l "TESTOPTS=-v --timeout-scale=3.0 --excludes=../test/excludes/_appveyor -j%JOBS% --exclude readline --exclude win32ole --exclude test_bignum --exclude test_syntax --exclude test_open-uri --exclude test_bundled_ca" test-all
- # separately execute tests without -j which may crash worker with -j.
- - nmake -l "TESTOPTS=-v --timeout-scale=3.0 --excludes=../test/excludes/_appveyor" test-all TESTS="../test/win32ole ../test/ruby/test_bignum.rb ../test/ruby/test_syntax.rb ../test/open-uri/test_open-uri.rb ../test/rubygems/test_bundled_ca.rb"
- - nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows
-notifications:
- - provider: Webhook
- method: POST
- url:
- secure: CcFlJNDJ/a6to7u3Z4Fnz6dScEPNx7hTha2GkSRlV+1U6dqmxY/7uBcLXYb9gR3jfQk6w+2o/HrjNAyXMNGU/JOka3s2WRI4VKitzM+lQ08owvJIh0R7LxrGH0J2e81U # ruby-lang slack: ruby/simpler-alerts-bot
- body: >-
- {{^isPullRequest}}
- {
- "ci": "AppVeyor CI",
- "env": "Visual Studio 2013 / 2015",
- "url": "{{buildUrl}}",
- "commit": "{{commitId}}",
- "branch": "{{branch}}"
- }
- {{/isPullRequest}}
- on_build_success: false
- on_build_failure: true
- on_build_status_changed: false
diff --git a/array.c b/array.c
index ea84473fdf..b76e9a64a3 100644
--- a/array.c
+++ b/array.c
@@ -39,6 +39,37 @@
VALUE rb_cArray;
+/* Flags of RArray
+ *
+ * 1: RARRAY_EMBED_FLAG
+ * The array is embedded (its contents follow the header, rather than
+ * being on a separately allocated buffer).
+ * 2: RARRAY_SHARED_FLAG (equal to ELTS_SHARED)
+ * The array is shared. The buffer this array points to is owned by
+ * another array (the shared root).
+ * if USE_RVARGC
+ * 3-9: RARRAY_EMBED_LEN
+ * The length of the array when RARRAY_EMBED_FLAG is set.
+ * else
+ * 3-4: RARRAY_EMBED_LEN
+ * The length of the array when RARRAY_EMBED_FLAG is set.
+ * endif
+ * 12: RARRAY_SHARED_ROOT_FLAG
+ * The array is a shared root that does reference counting. The buffer
+ * this array points to is owned by this array but may be pointed to
+ * by other arrays.
+ * Note: Frozen arrays may be a shared root without this flag being
+ * set. Frozen arrays do not have reference counting because
+ * they cannot be modified. Not updating the reference count
+ * improves copy-on-write performance. Their reference count is
+ * assumed to be infinity.
+ * 13: RARRAY_TRANSIENT_FLAG
+ * The buffer of the array is allocated on the transient heap.
+ * 14: RARRAY_PTR_IN_USE_FLAG
+ * The buffer of the array is in use. This is only used during
+ * debugging.
+ */
+
/* for OPTIMIZED_CMP: */
#define id_cmp idCmp
@@ -53,23 +84,6 @@ should_be_T_ARRAY(VALUE ary)
return RB_TYPE_P(ary, T_ARRAY);
}
-RBIMPL_ATTR_MAYBE_UNUSED()
-static int
-should_not_be_shared_and_embedded(VALUE ary)
-{
- return !FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG);
-}
-
-#define ARY_SHARED_P(ary) \
- (assert(should_be_T_ARRAY((VALUE)(ary))), \
- assert(should_not_be_shared_and_embedded((VALUE)ary)), \
- FL_TEST_RAW((ary),ELTS_SHARED)!=0)
-
-#define ARY_EMBED_P(ary) \
- (assert(should_be_T_ARRAY((VALUE)(ary))), \
- assert(should_not_be_shared_and_embedded((VALUE)ary)), \
- FL_TEST_RAW((ary), RARRAY_EMBED_FLAG) != 0)
-
#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
#define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
@@ -79,11 +93,11 @@ should_not_be_shared_and_embedded(VALUE ary)
#define ARY_EMBED_LEN(a) \
(assert(ARY_EMBED_P(a)), \
(long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
- (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
+ (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
#define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
- !FL_TEST_RAW((a), ELTS_SHARED|RARRAY_EMBED_FLAG))
+ !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG))
#define FL_SET_EMBED(a) do { \
assert(!ARY_SHARED_P(a)); \
@@ -95,9 +109,9 @@ should_not_be_shared_and_embedded(VALUE ary)
#define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
#define FL_SET_SHARED(ary) do { \
assert(!ARY_EMBED_P(ary)); \
- FL_SET((ary), ELTS_SHARED); \
+ FL_SET((ary), RARRAY_SHARED_FLAG); \
} while (0)
-#define FL_UNSET_SHARED(ary) FL_UNSET((ary), ELTS_SHARED)
+#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
#define ARY_SET_PTR(ary, p) do { \
assert(!ARY_EMBED_P(ary)); \
@@ -107,7 +121,6 @@ should_not_be_shared_and_embedded(VALUE ary)
#define ARY_SET_EMBED_LEN(ary, n) do { \
long tmp_n = (n); \
assert(ARY_EMBED_P(ary)); \
- assert(!OBJ_FROZEN(ary)); \
RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
} while (0)
@@ -139,7 +152,7 @@ should_not_be_shared_and_embedded(VALUE ary)
} \
} while (0)
-#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \
+#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
#define ARY_SET_CAPA(ary, n) do { \
assert(!ARY_EMBED_P(ary)); \
@@ -148,26 +161,25 @@ should_not_be_shared_and_embedded(VALUE ary)
RARRAY(ary)->as.heap.aux.capa = (n); \
} while (0)
-#define ARY_SHARED_ROOT(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared_root)
#define ARY_SET_SHARED(ary, value) do { \
const VALUE _ary_ = (ary); \
const VALUE _value_ = (value); \
assert(!ARY_EMBED_P(_ary_)); \
assert(ARY_SHARED_P(_ary_)); \
- assert(ARY_SHARED_ROOT_P(_value_)); \
+ assert(!OBJ_FROZEN(_ary_)); \
+ assert(ARY_SHARED_ROOT_P(_value_) || OBJ_FROZEN(_value_)); \
RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
} while (0)
-#define RARRAY_SHARED_ROOT_FLAG FL_USER5
-#define ARY_SHARED_ROOT_P(ary) (assert(should_be_T_ARRAY((VALUE)(ary))), \
- FL_TEST_RAW((ary), RARRAY_SHARED_ROOT_FLAG))
-#define ARY_SHARED_ROOT_REFCNT(ary) \
- (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
-#define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1)
+
+#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
assert(ARY_SHARED_ROOT_P(ary)); \
+ assert(!OBJ_FROZEN(ary)); \
+ assert((value) >= 0); \
RARRAY(ary)->as.heap.aux.capa = (value); \
} while (0)
#define FL_SET_SHARED_ROOT(ary) do { \
+ assert(!OBJ_FROZEN(ary)); \
assert(!ARY_EMBED_P(ary)); \
assert(!RARRAY_TRANSIENT_P(ary)); \
FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
@@ -183,6 +195,65 @@ ARY_SET(VALUE a, long i, VALUE v)
}
#undef RARRAY_ASET
+static long
+ary_embed_capa(VALUE ary)
+{
+#if USE_RVARGC
+ size_t size = rb_gc_obj_slot_size(ary) - offsetof(struct RArray, as.ary);
+ assert(size % sizeof(VALUE) == 0);
+ return size / sizeof(VALUE);
+#else
+ return RARRAY_EMBED_LEN_MAX;
+#endif
+}
+
+static size_t
+ary_embed_size(long capa)
+{
+ return offsetof(struct RArray, as.ary) + (sizeof(VALUE) * capa);
+}
+
+static bool
+ary_embeddable_p(long capa)
+{
+#if USE_RVARGC
+ return rb_gc_size_allocatable_p(ary_embed_size(capa));
+#else
+ return capa <= RARRAY_EMBED_LEN_MAX;
+#endif
+}
+
+bool
+rb_ary_embeddable_p(VALUE ary)
+{
+ /* An array cannot be turned embeddable when the array is:
+ * - Shared root: other objects may point to the buffer of this array
+ * so we cannot make it embedded.
+ * - Frozen: this array may also be a shared root without the shared root
+ * flag.
+ * - Shared: we don't want to re-embed an array that points to a shared
+ * root (to save memory).
+ */
+ return !(ARY_SHARED_ROOT_P(ary) || OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
+}
+
+size_t
+rb_ary_size_as_embedded(VALUE ary)
+{
+ size_t real_size;
+
+ if (ARY_EMBED_P(ary)) {
+ real_size = ary_embed_size(ARY_EMBED_LEN(ary));
+ }
+ else if (rb_ary_embeddable_p(ary)) {
+ real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
+ }
+ else {
+ real_size = sizeof(struct RArray);
+ }
+ return real_size;
+}
+
#if ARRAY_DEBUG
#define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
@@ -192,19 +263,19 @@ ary_verify_(VALUE ary, const char *file, int line)
{
assert(RB_TYPE_P(ary, T_ARRAY));
- if (FL_TEST(ary, ELTS_SHARED)) {
- VALUE root = RARRAY(ary)->as.heap.aux.shared_root;
+ if (ARY_SHARED_P(ary)) {
+ VALUE root = ARY_SHARED_ROOT(ary);
const VALUE *ptr = ARY_HEAP_PTR(ary);
const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root);
- assert(FL_TEST(root, RARRAY_SHARED_ROOT_FLAG));
+ assert(ARY_SHARED_ROOT_P(root) || OBJ_FROZEN(root));
assert(root_ptr <= ptr && ptr + len <= root_ptr + root_len);
ary_verify(root);
}
else if (ARY_EMBED_P(ary)) {
assert(!RARRAY_TRANSIENT_P(ary));
assert(!ARY_SHARED_P(ary));
- assert(RARRAY_LEN(ary) <= RARRAY_EMBED_LEN_MAX);
+ assert(RARRAY_LEN(ary) <= ary_embed_capa(ary));
}
else {
#if 1
@@ -260,7 +331,7 @@ void
rb_mem_clear(VALUE *mem, long size)
{
while (size--) {
- *mem++ = Qnil;
+ *mem++ = Qnil;
}
}
@@ -268,7 +339,7 @@ static void
ary_mem_clear(VALUE ary, long beg, long size)
{
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- rb_mem_clear(ptr + beg, size);
+ rb_mem_clear(ptr + beg, size);
});
}
@@ -276,7 +347,7 @@ static inline void
memfill(register VALUE *mem, register long size, register VALUE val)
{
while (size--) {
- *mem++ = val;
+ *mem++ = val;
}
}
@@ -284,8 +355,8 @@ static void
ary_memfill(VALUE ary, long beg, long size, VALUE val)
{
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- memfill(ptr + beg, size, val);
- RB_OBJ_WRITTEN(ary, Qundef, val);
+ memfill(ptr + beg, size, val);
+ RB_OBJ_WRITTEN(ary, Qundef, val);
});
}
@@ -354,14 +425,16 @@ ary_heap_free(VALUE ary)
}
}
-static void
+static size_t
ary_heap_realloc(VALUE ary, size_t new_capa)
{
+ size_t alloc_capa = new_capa;
size_t old_capa = ARY_HEAP_CAPA(ary);
if (RARRAY_TRANSIENT_P(ary)) {
if (new_capa <= old_capa) {
/* do nothing */
+ alloc_capa = old_capa;
}
else {
VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa);
@@ -379,6 +452,8 @@ ary_heap_realloc(VALUE ary, size_t new_capa)
SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa);
}
ary_verify(ary);
+
+ return alloc_capa;
}
#if USE_TRANSIENT_HEAP
@@ -386,14 +461,11 @@ static inline void
rb_ary_transient_heap_evacuate_(VALUE ary, int transient, int promote)
{
if (transient) {
+ assert(!ARY_SHARED_ROOT_P(ary));
+
VALUE *new_ptr;
const VALUE *old_ptr = ARY_HEAP_PTR(ary);
long capa = ARY_HEAP_CAPA(ary);
- long len = ARY_HEAP_LEN(ary);
-
- if (ARY_SHARED_ROOT_P(ary)) {
- capa = len;
- }
assert(ARY_OWNS_HEAP_P(ary));
assert(RARRAY_TRANSIENT_P(ary));
@@ -435,6 +507,27 @@ rb_ary_detransient(VALUE ary)
}
#endif
+void
+rb_ary_make_embedded(VALUE ary)
+{
+ assert(rb_ary_embeddable_p(ary));
+ if (!ARY_EMBED_P(ary)) {
+ const VALUE *buf = ARY_HEAP_PTR(ary);
+ long len = ARY_HEAP_LEN(ary);
+ bool was_transient = RARRAY_TRANSIENT_P(ary);
+
+ // FL_SET_EMBED also unsets the transient flag
+ FL_SET_EMBED(ary);
+ ARY_SET_EMBED_LEN(ary, len);
+
+ MEMCPY((void *)ARY_EMBED_PTR(ary), (void *)buf, VALUE, len);
+
+ if (!was_transient) {
+ ary_heap_free_ptr(ary, buf, len * sizeof(VALUE));
+ }
+ }
+}
+
static void
ary_resize_capa(VALUE ary, long capacity)
{
@@ -442,7 +535,8 @@ ary_resize_capa(VALUE ary, long capacity)
assert(!OBJ_FROZEN(ary));
assert(!ARY_SHARED_P(ary));
- if (capacity > RARRAY_EMBED_LEN_MAX) {
+ if (capacity > ary_embed_capa(ary)) {
+ size_t new_capa = capacity;
if (ARY_EMBED_P(ary)) {
long len = ARY_EMBED_LEN(ary);
VALUE *ptr = ary_heap_alloc(ary, capacity);
@@ -453,9 +547,9 @@ ary_resize_capa(VALUE ary, long capacity)
ARY_SET_HEAP_LEN(ary, len);
}
else {
- ary_heap_realloc(ary, capacity);
+ new_capa = ary_heap_realloc(ary, capacity);
}
- ARY_SET_CAPA(ary, capacity);
+ ARY_SET_CAPA(ary, new_capa);
}
else {
if (!ARY_EMBED_P(ary)) {
@@ -493,10 +587,10 @@ ary_double_capa(VALUE ary, long min)
long new_capa = ARY_CAPA(ary) / 2;
if (new_capa < ARY_DEFAULT_SIZE) {
- new_capa = ARY_DEFAULT_SIZE;
+ new_capa = ARY_DEFAULT_SIZE;
}
if (new_capa >= ARY_MAX_SIZE - min) {
- new_capa = (ARY_MAX_SIZE - min) / 2;
+ new_capa = (ARY_MAX_SIZE - min) / 2;
}
new_capa += min;
ary_resize_capa(ary, new_capa);
@@ -507,39 +601,40 @@ ary_double_capa(VALUE ary, long min)
static void
rb_ary_decrement_share(VALUE shared_root)
{
- if (shared_root) {
- long num = ARY_SHARED_ROOT_REFCNT(shared_root) - 1;
- if (num == 0) {
- rb_ary_free(shared_root);
- rb_gc_force_recycle(shared_root);
- }
- else if (num > 0) {
- ARY_SET_SHARED_ROOT_REFCNT(shared_root, num);
- }
+ if (!OBJ_FROZEN(shared_root)) {
+ long num = ARY_SHARED_ROOT_REFCNT(shared_root);
+ ARY_SET_SHARED_ROOT_REFCNT(shared_root, num - 1);
}
}
static void
rb_ary_unshare(VALUE ary)
{
- VALUE shared_root = RARRAY(ary)->as.heap.aux.shared_root;
+ VALUE shared_root = ARY_SHARED_ROOT(ary);
rb_ary_decrement_share(shared_root);
FL_UNSET_SHARED(ary);
}
-static inline void
-rb_ary_unshare_safe(VALUE ary)
+static void
+rb_ary_reset(VALUE ary)
{
- if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
- rb_ary_unshare(ary);
+ if (ARY_OWNS_HEAP_P(ary)) {
+ ary_heap_free(ary);
+ }
+ else if (ARY_SHARED_P(ary)) {
+ rb_ary_unshare(ary);
}
+
+ FL_SET_EMBED(ary);
+ ARY_SET_EMBED_LEN(ary, 0);
}
static VALUE
rb_ary_increment_share(VALUE shared_root)
{
- long num = ARY_SHARED_ROOT_REFCNT(shared_root);
- if (num >= 0) {
+ if (!OBJ_FROZEN(shared_root)) {
+ long num = ARY_SHARED_ROOT_REFCNT(shared_root);
+ assert(num >= 0);
ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1);
}
return shared_root;
@@ -570,7 +665,7 @@ rb_ary_cancel_sharing(VALUE ary)
ary_verify(shared_root);
- if (len <= RARRAY_EMBED_LEN_MAX) {
+ if (len <= ary_embed_capa(ary)) {
const VALUE *ptr = ARY_HEAP_PTR(ary);
FL_UNSET_SHARED(ary);
FL_SET_EMBED(ary);
@@ -617,40 +712,40 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
long capa;
if (old_len > ARY_MAX_SIZE - add_len) {
- rb_raise(rb_eIndexError, "index %ld too big", new_len);
+ rb_raise(rb_eIndexError, "index %ld too big", new_len);
}
if (ARY_SHARED_P(ary)) {
- if (new_len > RARRAY_EMBED_LEN_MAX) {
+ if (new_len > ary_embed_capa(ary)) {
VALUE shared_root = ARY_SHARED_ROOT(ary);
if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
- rb_ary_modify_check(ary);
+ rb_ary_modify_check(ary);
ary_verify(ary);
ary_verify(shared_root);
return shared_root;
- }
- else {
- /* if array is shared, then it is likely it participate in push/shift pattern */
- rb_ary_modify(ary);
- capa = ARY_CAPA(ary);
- if (new_len > capa - (capa >> 6)) {
- ary_double_capa(ary, new_len);
- }
+ }
+ else {
+ /* if array is shared, then it is likely it participate in push/shift pattern */
+ rb_ary_modify(ary);
+ capa = ARY_CAPA(ary);
+ if (new_len > capa - (capa >> 6)) {
+ ary_double_capa(ary, new_len);
+ }
ary_verify(ary);
- return ary;
- }
- }
- }
+ return ary;
+ }
+ }
+ }
ary_verify(ary);
rb_ary_modify(ary);
}
else {
- rb_ary_modify_check(ary);
+ rb_ary_modify_check(ary);
}
capa = ARY_CAPA(ary);
if (new_len > capa) {
- ary_double_capa(ary, new_len);
+ ary_double_capa(ary, new_len);
}
ary_verify(ary);
@@ -662,6 +757,7 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
* array.freeze -> self
*
* Freezes +self+; returns +self+:
+ *
* a = []
* a.frozen? # => false
* a.freeze
@@ -687,18 +783,25 @@ VALUE
rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
{
if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
- !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
- RARRAY(ary1)->as.heap.aux.shared_root == RARRAY(ary2)->as.heap.aux.shared_root &&
- RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) {
- return Qtrue;
+ !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
+ ARY_SHARED_ROOT(ary1) == ARY_SHARED_ROOT(ary2) &&
+ ARY_HEAP_LEN(ary1) == ARY_HEAP_LEN(ary2)) {
+ return Qtrue;
}
return Qfalse;
}
static VALUE
-ary_alloc(VALUE klass)
+ary_alloc_embed(VALUE klass, long capa)
{
- NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
+ size_t size = ary_embed_size(capa);
+ assert(rb_gc_size_allocatable_p(size));
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RArray));
+#endif
+ RVARGC_NEWOBJ_OF(ary, struct RArray, klass,
+ T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ size);
/* Created array is:
* FL_SET_EMBED((VALUE)ary);
* ARY_SET_EMBED_LEN((VALUE)ary, 0);
@@ -707,10 +810,19 @@ ary_alloc(VALUE klass)
}
static VALUE
+ary_alloc_heap(VALUE klass)
+{
+ RVARGC_NEWOBJ_OF(ary, struct RArray, klass,
+ T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ sizeof(struct RArray));
+ return (VALUE)ary;
+}
+
+static VALUE
empty_ary_alloc(VALUE klass)
{
RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
- return ary_alloc(klass);
+ return ary_alloc_embed(klass, 0);
}
static VALUE
@@ -719,20 +831,24 @@ ary_new(VALUE klass, long capa)
VALUE ary,*ptr;
if (capa < 0) {
- rb_raise(rb_eArgError, "negative array size (or size too big)");
+ rb_raise(rb_eArgError, "negative array size (or size too big)");
}
if (capa > ARY_MAX_SIZE) {
- rb_raise(rb_eArgError, "array size too big");
+ rb_raise(rb_eArgError, "array size too big");
}
RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
- ary = ary_alloc(klass);
- if (capa > RARRAY_EMBED_LEN_MAX) {
+ if (ary_embeddable_p(capa)) {
+ ary = ary_alloc_embed(klass, capa);
+ }
+ else {
+ ary = ary_alloc_heap(klass);
+ ARY_SET_CAPA(ary, capa);
+ assert(!ARY_EMBED_P(ary));
+
ptr = ary_heap_alloc(ary, capa);
- FL_UNSET_EMBED(ary);
ARY_SET_PTR(ary, ptr);
- ARY_SET_CAPA(ary, capa);
ARY_SET_HEAP_LEN(ary, 0);
}
@@ -748,7 +864,7 @@ rb_ary_new_capa(long capa)
VALUE
rb_ary_new(void)
{
- return rb_ary_new2(RARRAY_EMBED_LEN_MAX);
+ return rb_ary_new_capa(0);
}
VALUE
@@ -762,7 +878,7 @@ VALUE
va_start(ar, n);
for (i=0; i<n; i++) {
- ARY_SET(ary, i, va_arg(ar, VALUE));
+ ARY_SET(ary, i, va_arg(ar, VALUE));
}
va_end(ar);
@@ -777,8 +893,8 @@ rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
ary = ary_new(klass, n);
if (n > 0 && elts) {
- ary_memcpy(ary, 0, n, elts);
- ARY_SET_LEN(ary, n);
+ ary_memcpy(ary, 0, n, elts);
+ ARY_SET_LEN(ary, n);
}
return ary;
@@ -791,9 +907,16 @@ rb_ary_new_from_values(long n, const VALUE *elts)
}
static VALUE
-ec_ary_alloc(rb_execution_context_t *ec, VALUE klass)
+ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa)
{
- RB_EC_NEWOBJ_OF(ec, ary, struct RArray, klass, T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
+ size_t size = ary_embed_size(capa);
+ assert(rb_gc_size_allocatable_p(size));
+#if !USE_RVARGC
+ assert(size <= sizeof(struct RArray));
+#endif
+ RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass,
+ T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ size);
/* Created array is:
* FL_SET_EMBED((VALUE)ary);
* ARY_SET_EMBED_LEN((VALUE)ary, 0);
@@ -802,26 +925,38 @@ ec_ary_alloc(rb_execution_context_t *ec, VALUE klass)
}
static VALUE
+ec_ary_alloc_heap(rb_execution_context_t *ec, VALUE klass)
+{
+ RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass,
+ T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
+ sizeof(struct RArray));
+ return (VALUE)ary;
+}
+
+static VALUE
ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa)
{
VALUE ary,*ptr;
if (capa < 0) {
- rb_raise(rb_eArgError, "negative array size (or size too big)");
+ rb_raise(rb_eArgError, "negative array size (or size too big)");
}
if (capa > ARY_MAX_SIZE) {
- rb_raise(rb_eArgError, "array size too big");
+ rb_raise(rb_eArgError, "array size too big");
}
RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
- ary = ec_ary_alloc(ec, klass);
+ if (ary_embeddable_p(capa)) {
+ ary = ec_ary_alloc_embed(ec, klass, capa);
+ }
+ else {
+ ary = ec_ary_alloc_heap(ec, klass);
+ ARY_SET_CAPA(ary, capa);
+ assert(!ARY_EMBED_P(ary));
- if (capa > RARRAY_EMBED_LEN_MAX) {
ptr = ary_heap_alloc(ary, capa);
- FL_UNSET_EMBED(ary);
ARY_SET_PTR(ary, ptr);
- ARY_SET_CAPA(ary, capa);
ARY_SET_HEAP_LEN(ary, 0);
}
@@ -835,15 +970,15 @@ rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts)
ary = ec_ary_new(ec, rb_cArray, n);
if (n > 0 && elts) {
- ary_memcpy(ary, 0, n, elts);
- ARY_SET_LEN(ary, n);
+ ary_memcpy(ary, 0, n, elts);
+ ARY_SET_LEN(ary, n);
}
return ary;
}
VALUE
-rb_ary_tmp_new(long capa)
+rb_ary_hidden_new(long capa)
{
VALUE ary = ary_new(0, capa);
rb_ary_transient_heap_evacuate(ary, TRUE);
@@ -851,12 +986,11 @@ rb_ary_tmp_new(long capa)
}
VALUE
-rb_ary_tmp_new_fill(long capa)
+rb_ary_hidden_new_fill(long capa)
{
- VALUE ary = ary_new(0, capa);
+ VALUE ary = rb_ary_hidden_new(capa);
ary_memfill(ary, 0, capa, Qnil);
ARY_SET_LEN(ary, capa);
- rb_ary_transient_heap_evacuate(ary, TRUE);
return ary;
}
@@ -894,64 +1028,69 @@ RUBY_FUNC_EXPORTED size_t
rb_ary_memsize(VALUE ary)
{
if (ARY_OWNS_HEAP_P(ary)) {
- return ARY_CAPA(ary) * sizeof(VALUE);
+ return ARY_CAPA(ary) * sizeof(VALUE);
}
else {
- return 0;
+ return 0;
}
}
-static inline void
-ary_discard(VALUE ary)
-{
- rb_ary_free(ary);
- RBASIC(ary)->flags |= RARRAY_EMBED_FLAG;
- RBASIC(ary)->flags &= ~(RARRAY_EMBED_LEN_MASK | RARRAY_TRANSIENT_FLAG);
-}
-
static VALUE
ary_make_shared(VALUE ary)
{
- assert(!ARY_EMBED_P(ary));
+ assert(USE_RVARGC || !ARY_EMBED_P(ary));
ary_verify(ary);
if (ARY_SHARED_P(ary)) {
return ARY_SHARED_ROOT(ary);
}
else if (ARY_SHARED_ROOT_P(ary)) {
- return ary;
+ return ary;
}
else if (OBJ_FROZEN(ary)) {
- rb_ary_transient_heap_evacuate(ary, TRUE);
- ary_shrink_capa(ary);
- FL_SET_SHARED_ROOT(ary);
- ARY_SET_SHARED_ROOT_REFCNT(ary, 1);
- return ary;
+ if (!ARY_EMBED_P(ary)) {
+ rb_ary_transient_heap_evacuate(ary, TRUE);
+ ary_shrink_capa(ary);
+ }
+ return ary;
}
else {
- long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary);
- const VALUE *ptr;
- NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
- VALUE vshared = (VALUE)shared;
-
rb_ary_transient_heap_evacuate(ary, TRUE);
- ptr = ARY_HEAP_PTR(ary);
-
- FL_UNSET_EMBED(vshared);
- ARY_SET_LEN(vshared, capa);
- ARY_SET_PTR(vshared, ptr);
- ary_mem_clear(vshared, len, capa - len);
- FL_SET_SHARED_ROOT(vshared);
- ARY_SET_SHARED_ROOT_REFCNT(vshared, 1);
- FL_SET_SHARED(ary);
+
+ long capa = ARY_CAPA(ary);
+ long len = RARRAY_LEN(ary);
+
+ /* Shared roots cannot be embedded because the reference count
+ * (refcnt) is stored in as.heap.aux.capa. */
+ VALUE shared = ary_alloc_heap(0);
+ FL_SET_SHARED_ROOT(shared);
+
+ if (ARY_EMBED_P(ary)) {
+ /* Cannot use ary_heap_alloc because we don't want to allocate
+ * on the transient heap. */
+ VALUE *ptr = ALLOC_N(VALUE, capa);
+ ARY_SET_PTR(shared, ptr);
+ ary_memcpy(shared, 0, len, RARRAY_PTR(ary));
+
+ FL_UNSET_EMBED(ary);
+ ARY_SET_HEAP_LEN(ary, len);
+ ARY_SET_PTR(ary, ptr);
+ }
+ else {
+ ARY_SET_PTR(shared, RARRAY_PTR(ary));
+ }
+
+ ARY_SET_LEN(shared, capa);
+ ary_mem_clear(shared, len, capa - len);
+ ARY_SET_SHARED_ROOT_REFCNT(shared, 1);
+ FL_SET_SHARED(ary);
RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
- ARY_SET_SHARED(ary, vshared);
- OBJ_FREEZE(vshared);
+ ARY_SET_SHARED(ary, shared);
- ary_verify(vshared);
+ ary_verify(shared);
ary_verify(ary);
- return vshared;
+ return shared;
}
}
@@ -960,8 +1099,10 @@ ary_make_substitution(VALUE ary)
{
long len = RARRAY_LEN(ary);
- if (len <= RARRAY_EMBED_LEN_MAX) {
- VALUE subst = rb_ary_new2(len);
+ if (ary_embeddable_p(len)) {
+ VALUE subst = rb_ary_new_capa(len);
+ assert(ARY_EMBED_P(subst));
+
ary_memcpy(subst, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_EMBED_LEN(subst, len);
return subst;
@@ -996,6 +1137,12 @@ rb_check_to_array(VALUE ary)
return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
}
+VALUE
+rb_to_array(VALUE ary)
+{
+ return rb_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
+}
+
/*
* call-seq:
* Array.try_convert(object) -> object, new_array, or nil
@@ -1016,6 +1163,30 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
return rb_check_array_type(ary);
}
+/* :nodoc: */
+static VALUE
+rb_ary_s_new(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE ary;
+
+ if (klass == rb_cArray) {
+ long size = 0;
+ if (argc > 0 && FIXNUM_P(argv[0])) {
+ size = FIX2LONG(argv[0]);
+ if (size < 0) size = 0;
+ }
+
+ ary = ary_new(klass, size);
+
+ rb_obj_call_init_kw(ary, argc, argv, RB_PASS_CALLED_KEYWORDS);
+ }
+ else {
+ ary = rb_class_new_instance_pass_kw(argc, argv, klass);
+ }
+
+ return ary;
+}
+
/*
* call-seq:
* Array.new -> new_empty_array
@@ -1030,6 +1201,7 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
*
* With no block and a single \Array argument +array+,
* returns a new \Array formed from +array+:
+ *
* a = Array.new([:foo, 'bar', 2])
* a.class # => Array
* a # => [:foo, "bar", 2]
@@ -1037,12 +1209,14 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
* With no block and a single \Integer argument +size+,
* returns a new \Array of the given size
* whose elements are all +nil+:
+ *
* a = Array.new(3)
* a # => [nil, nil, nil]
*
* With no block and arguments +size+ and +default_value+,
* returns an \Array of the given size;
* each element is that same +default_value+:
+ *
* a = Array.new(3, 'x')
* a # => ['x', 'x', 'x']
*
@@ -1050,6 +1224,7 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
* returns an \Array of the given size;
* the block is called with each successive integer +index+;
* the element for that +index+ is the return value from the block:
+ *
* a = Array.new(3) {|index| "Element #{index}" }
* a # => ["Element 0", "Element 1", "Element 2"]
*
@@ -1068,51 +1243,48 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
rb_ary_modify(ary);
if (argc == 0) {
- if (ARY_OWNS_HEAP_P(ary) && ARY_HEAP_PTR(ary) != NULL) {
- ary_heap_free(ary);
- }
- rb_ary_unshare_safe(ary);
- FL_SET_EMBED(ary);
- ARY_SET_EMBED_LEN(ary, 0);
- if (rb_block_given_p()) {
- rb_warning("given block not used");
- }
- return ary;
+ rb_ary_reset(ary);
+ assert(ARY_EMBED_P(ary));
+ assert(ARY_EMBED_LEN(ary) == 0);
+ if (rb_block_given_p()) {
+ rb_warning("given block not used");
+ }
+ return ary;
}
rb_scan_args(argc, argv, "02", &size, &val);
if (argc == 1 && !FIXNUM_P(size)) {
- val = rb_check_array_type(size);
- if (!NIL_P(val)) {
- rb_ary_replace(ary, val);
- return ary;
- }
+ val = rb_check_array_type(size);
+ if (!NIL_P(val)) {
+ rb_ary_replace(ary, val);
+ return ary;
+ }
}
len = NUM2LONG(size);
/* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
if (len < 0) {
- rb_raise(rb_eArgError, "negative array size");
+ rb_raise(rb_eArgError, "negative array size");
}
if (len > ARY_MAX_SIZE) {
- rb_raise(rb_eArgError, "array size too big");
+ rb_raise(rb_eArgError, "array size too big");
}
/* recheck after argument conversion */
rb_ary_modify(ary);
ary_resize_capa(ary, len);
if (rb_block_given_p()) {
- long i;
+ long i;
- if (argc == 2) {
- rb_warn("block supersedes default value argument");
- }
- for (i=0; i<len; i++) {
- rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
- ARY_SET_LEN(ary, i + 1);
- }
+ if (argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
+ for (i=0; i<len; i++) {
+ rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
+ ARY_SET_LEN(ary, i + 1);
+ }
}
else {
- ary_memfill(ary, 0, len, val);
- ARY_SET_LEN(ary, len);
+ ary_memfill(ary, 0, len, val);
+ ARY_SET_LEN(ary, len);
}
return ary;
}
@@ -1143,26 +1315,26 @@ rb_ary_store(VALUE ary, long idx, VALUE val)
long len = RARRAY_LEN(ary);
if (idx < 0) {
- idx += len;
- if (idx < 0) {
- rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
- idx - len, -len);
- }
+ idx += len;
+ if (idx < 0) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ idx - len, -len);
+ }
}
else if (idx >= ARY_MAX_SIZE) {
- rb_raise(rb_eIndexError, "index %ld too big", idx);
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
}
rb_ary_modify(ary);
if (idx >= ARY_CAPA(ary)) {
- ary_double_capa(ary, idx);
+ ary_double_capa(ary, idx);
}
if (idx > len) {
- ary_mem_clear(ary, len, idx - len + 1);
+ ary_mem_clear(ary, len, idx - len + 1);
}
if (idx >= len) {
- ARY_SET_LEN(ary, idx + 1);
+ ARY_SET_LEN(ary, idx + 1);
}
ARY_SET(ary, idx, val);
}
@@ -1174,17 +1346,20 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
assert(len >= 0);
assert(offset+len <= RARRAY_LEN(ary));
- if (len <= RARRAY_EMBED_LEN_MAX) {
- VALUE result = ary_alloc(klass);
+ const size_t rarray_embed_capa_max = (sizeof(struct RArray) - offsetof(struct RArray, as.ary)) / sizeof(VALUE);
+
+ if ((size_t)len <= rarray_embed_capa_max && ary_embeddable_p(len)) {
+ VALUE result = ary_alloc_embed(klass, len);
ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset);
ARY_SET_EMBED_LEN(result, len);
return result;
}
else {
- VALUE shared, result = ary_alloc(klass);
- FL_UNSET_EMBED(result);
+ VALUE shared = ary_make_shared(ary);
+
+ VALUE result = ary_alloc_heap(klass);
+ assert(!ARY_EMBED_P(result));
- shared = ary_make_shared(ary);
ARY_SET_PTR(result, RARRAY_CONST_PTR_TRANSIENT(ary));
ARY_SET_LEN(result, RARRAY_LEN(ary));
rb_ary_set_shared(result, shared);
@@ -1209,21 +1384,25 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary);
const long orig_len = len;
- if ((step > 0 && step >= len) || (step < 0 && (step < -len))) {
+ if (step > 0 && step >= len) {
VALUE result = ary_new(klass, 1);
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
RB_OBJ_WRITE(result, ptr, values[offset]);
ARY_SET_EMBED_LEN(result, 1);
return result;
}
+ else if (step < 0 && step < -len) {
+ step = -len;
+ }
long ustep = (step < 0) ? -step : step;
- len = (len + ustep - 1) / ustep;
+ len = roomof(len, ustep);
long i;
long j = offset + ((step > 0) ? 0 : (orig_len - 1));
+
VALUE result = ary_new(klass, len);
- if (len <= RARRAY_EMBED_LEN_MAX) {
+ if (ARY_EMBED_P(result)) {
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
for (i = 0; i < len; ++i) {
RB_OBJ_WRITE(result, ptr+i, values[j]);
@@ -1272,13 +1451,13 @@ ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos
n = NUM2LONG(argv[0]);
len = RARRAY_LEN(ary);
if (n > len) {
- n = len;
+ n = len;
}
else if (n < 0) {
- rb_raise(rb_eArgError, "negative array size");
+ rb_raise(rb_eArgError, "negative array size");
}
if (last) {
- offset = len - n;
+ offset = len - n;
}
return ary_make_partial(ary, rb_cArray, offset, n);
}
@@ -1288,13 +1467,16 @@ ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos
* array << object -> self
*
* Appends +object+ to +self+; returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a << :baz # => [:foo, "bar", 2, :baz]
*
* Appends +object+ as one element, even if it is another \Array:
+ *
* a = [:foo, 'bar', 2]
* a1 = a << [3, 4]
* a1 # => [:foo, "bar", 2, [3, 4]]
+ *
*/
VALUE
@@ -1303,7 +1485,7 @@ rb_ary_push(VALUE ary, VALUE item)
long idx = RARRAY_LEN((ary_verify(ary), ary));
VALUE target_ary = ary_ensure_room_for_push(ary, 1);
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- RB_OBJ_WRITE(target_ary, &ptr[idx], item);
+ RB_OBJ_WRITE(target_ary, &ptr[idx], item);
});
ARY_SET_LEN(ary, idx + 1);
ary_verify(ary);
@@ -1327,15 +1509,17 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len)
* Appends trailing elements.
*
* Appends each argument in +objects+ to +self+; returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat]
*
* Appends each argument as one element, even if it is another \Array:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.push([:baz, :bat], [:bam, :bad])
* a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
*
- * Array#append is an alias for \Array#push.
+ * Array#append is an alias for Array#push.
*
* Related: #pop, #shift, #unshift.
*/
@@ -1354,10 +1538,10 @@ rb_ary_pop(VALUE ary)
n = RARRAY_LEN(ary);
if (n == 0) return Qnil;
if (ARY_OWNS_HEAP_P(ary) &&
- n * 3 < ARY_CAPA(ary) &&
- ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
+ n * 3 < ARY_CAPA(ary) &&
+ ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
{
- ary_resize_capa(ary, n * 2);
+ ary_resize_capa(ary, n * 2);
}
--n;
ARY_SET_LEN(ary, n);
@@ -1374,6 +1558,7 @@ rb_ary_pop(VALUE ary)
*
* When no argument is given and +self+ is not empty,
* removes and returns the last element:
+ *
* a = [:foo, 'bar', 2]
* a.pop # => 2
* a # => [:foo, "bar"]
@@ -1381,12 +1566,14 @@ rb_ary_pop(VALUE ary)
* Returns +nil+ if the array is empty.
*
* When a non-negative \Integer argument +n+ is given and is in range,
+ *
* removes and returns the last +n+ elements in a new \Array:
* a = [:foo, 'bar', 2]
* a.pop(2) # => ["bar", 2]
*
* If +n+ is positive and out of range,
* removes and returns all elements:
+ *
* a = [:foo, 'bar', 2]
* a.pop(50) # => [:foo, "bar", 2]
*
@@ -1399,7 +1586,7 @@ rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
VALUE result;
if (argc == 0) {
- return rb_ary_pop(ary);
+ return rb_ary_pop(ary);
}
rb_ary_modify_check(ary);
@@ -1415,30 +1602,14 @@ rb_ary_shift(VALUE ary)
VALUE top;
long len = RARRAY_LEN(ary);
- rb_ary_modify_check(ary);
- if (len == 0) return Qnil;
- top = RARRAY_AREF(ary, 0);
- if (!ARY_SHARED_P(ary)) {
- if (len < ARY_DEFAULT_SIZE) {
- RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr, ptr+1, VALUE, len-1);
- }); /* WB: no new reference */
- ARY_INCREASE_LEN(ary, -1);
- ary_verify(ary);
- return top;
- }
- assert(!ARY_EMBED_P(ary)); /* ARY_EMBED_LEN_MAX < ARY_DEFAULT_SIZE */
-
- ARY_SET(ary, 0, Qnil);
- ary_make_shared(ary);
- }
- else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
- RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil);
+ if (len == 0) {
+ rb_ary_modify_check(ary);
+ return Qnil;
}
- ARY_INCREASE_PTR(ary, 1); /* shift ptr */
- ARY_INCREASE_LEN(ary, -1);
- ary_verify(ary);
+ top = RARRAY_AREF(ary, 0);
+
+ rb_ary_behead(ary, 1);
return top;
}
@@ -1451,6 +1622,7 @@ rb_ary_shift(VALUE ary)
* Removes and returns leading elements.
*
* When no argument is given, removes and returns the first element:
+ *
* a = [:foo, 'bar', 2]
* a.shift # => :foo
* a # => ['bar', 2]
@@ -1459,12 +1631,14 @@ rb_ary_shift(VALUE ary)
*
* When positive \Integer argument +n+ is given, removes the first +n+ elements;
* returns those elements in a new \Array:
+ *
* a = [:foo, 'bar', 2]
* a.shift(2) # => [:foo, 'bar']
* a # => [2]
*
* If +n+ is as large as or larger than <tt>self.length</tt>,
* removes all elements; returns those elements in a new \Array:
+ *
* a = [:foo, 'bar', 2]
* a.shift(3) # => [:foo, 'bar', 2]
*
@@ -1480,7 +1654,7 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
long n;
if (argc == 0) {
- return rb_ary_shift(ary);
+ return rb_ary_shift(ary);
}
rb_ary_modify_check(ary);
@@ -1491,48 +1665,37 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
return result;
}
-static VALUE
-behead_shared(VALUE ary, long n)
-{
- assert(ARY_SHARED_P(ary));
- rb_ary_modify_check(ary);
- if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
- ary_mem_clear(ary, 0, n);
- }
- ARY_INCREASE_PTR(ary, n);
- ARY_INCREASE_LEN(ary, -n);
- ary_verify(ary);
- return ary;
-}
-
-static VALUE
-behead_transient(VALUE ary, long n)
-{
- rb_ary_modify_check(ary);
- RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
- }); /* WB: no new reference */
- ARY_INCREASE_LEN(ary, -n);
- ary_verify(ary);
- return ary;
-}
-
MJIT_FUNC_EXPORTED VALUE
rb_ary_behead(VALUE ary, long n)
{
if (n <= 0) {
return ary;
}
- else if (ARY_SHARED_P(ary)) {
- return behead_shared(ary, n);
- }
- else if (RARRAY_LEN(ary) >= ARY_DEFAULT_SIZE) {
+
+ rb_ary_modify_check(ary);
+
+ if (!ARY_SHARED_P(ary)) {
+ if (ARY_EMBED_P(ary) || RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMMOVE(ptr, ptr + n, VALUE, RARRAY_LEN(ary) - n);
+ }); /* WB: no new reference */
+ ARY_INCREASE_LEN(ary, -n);
+ ary_verify(ary);
+ return ary;
+ }
+
+ ary_mem_clear(ary, 0, n);
ary_make_shared(ary);
- return behead_shared(ary, n);
}
- else {
- return behead_transient(ary, n);
+ else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
+ ary_mem_clear(ary, 0, n);
}
+
+ ARY_INCREASE_PTR(ary, n);
+ ARY_INCREASE_LEN(ary, -n);
+ ary_verify(ary);
+
+ return ary;
}
static VALUE
@@ -1563,28 +1726,28 @@ ary_modify_for_unshift(VALUE ary, int argc)
rb_ary_modify(ary);
capa = ARY_CAPA(ary);
if (capa - (capa >> 6) <= new_len) {
- ary_double_capa(ary, new_len);
+ ary_double_capa(ary, new_len);
}
/* use shared array for big "queues" */
- if (new_len > ARY_DEFAULT_SIZE * 4) {
+ if (new_len > ARY_DEFAULT_SIZE * 4 && !ARY_EMBED_P(ary)) {
ary_verify(ary);
/* make a room for unshifted items */
- capa = ARY_CAPA(ary);
- ary_make_shared(ary);
+ capa = ARY_CAPA(ary);
+ ary_make_shared(ary);
head = sharedp = RARRAY_CONST_PTR_TRANSIENT(ary);
return make_room_for_unshift(ary, head, (void *)sharedp, argc, capa, len);
}
else {
- /* sliding items */
+ /* sliding items */
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr + argc, ptr, VALUE, len);
- });
+ MEMMOVE(ptr + argc, ptr, VALUE, len);
+ });
ary_verify(ary);
- return ary;
+ return ary;
}
}
@@ -1625,6 +1788,7 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
* array.unshift(*objects) -> self
*
* Prepends the given +objects+ to +self+:
+ *
* a = [:foo, 'bar', 2]
* a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
*
@@ -1640,8 +1804,8 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
VALUE target_ary;
if (argc == 0) {
- rb_ary_modify_check(ary);
- return ary;
+ rb_ary_modify_check(ary);
+ return ary;
}
target_ary = ary_ensure_room_for_unshift(ary, argc);
@@ -1663,7 +1827,7 @@ rb_ary_elt(VALUE ary, long offset)
long len = RARRAY_LEN(ary);
if (len == 0) return Qnil;
if (offset < 0 || len <= offset) {
- return Qnil;
+ return Qnil;
}
return RARRAY_AREF(ary, offset);
}
@@ -1684,7 +1848,7 @@ rb_ary_subseq_step(VALUE ary, long beg, long len, long step)
if (beg < 0 || len < 0) return Qnil;
if (alen < len || alen < beg + len) {
- len = alen - beg;
+ len = alen - beg;
}
klass = rb_cArray;
if (len == 0) return ary_new(klass, 0);
@@ -1718,12 +1882,14 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
* Returns elements from +self+; does not modify +self+.
*
* When a single \Integer argument +index+ is given, returns the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a[0] # => :foo
* a[2] # => 2
* a # => [:foo, "bar", 2]
*
* If +index+ is negative, counts relative to the end of +self+:
+ *
* a = [:foo, 'bar', 2]
* a[-1] # => 2
* a[-2] # => "bar"
@@ -1732,12 +1898,14 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* When two \Integer arguments +start+ and +length+ are given,
* returns a new \Array of size +length+ containing successive elements beginning at offset +start+:
+ *
* a = [:foo, 'bar', 2]
* a[0, 2] # => [:foo, "bar"]
* a[1, 2] # => ["bar", 2]
*
* If <tt>start + length</tt> is greater than <tt>self.length</tt>,
* returns all elements from offset +start+ to the end:
+ *
* a = [:foo, 'bar', 2]
* a[0, 4] # => [:foo, "bar", 2]
* a[1, 3] # => ["bar", 2]
@@ -1751,6 +1919,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
* When a single \Range argument +range+ is given,
* treats <tt>range.min</tt> as +start+ above
* and <tt>range.size</tt> as +length+ above:
+ *
* a = [:foo, 'bar', 2]
* a[0..1] # => [:foo, "bar"]
* a[1..2] # => ["bar", 2]
@@ -1758,31 +1927,36 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
* Special case: If <tt>range.start == a.size</tt>, returns a new empty \Array.
*
* If <tt>range.end</tt> is negative, calculates the end index from the end:
+ *
* a = [:foo, 'bar', 2]
* a[0..-1] # => [:foo, "bar", 2]
* a[0..-2] # => [:foo, "bar"]
* a[0..-3] # => [:foo]
*
* If <tt>range.start</tt> is negative, calculates the start index from the end:
+ *
* a = [:foo, 'bar', 2]
* a[-1..2] # => [2]
* a[-2..2] # => ["bar", 2]
* a[-3..2] # => [:foo, "bar", 2]
*
* If <tt>range.start</tt> is larger than the array size, returns +nil+.
+ *
* a = [:foo, 'bar', 2]
* a[4..1] # => nil
* a[4..0] # => nil
* a[4..-1] # => nil
*
* When a single Enumerator::ArithmeticSequence argument +aseq+ is given,
- * returns an Array of elements corresponding to the indexes produced by
+ * returns an \Array of elements corresponding to the indexes produced by
* the sequence.
+ *
* a = ['--', 'data1', '--', 'data2', '--', 'data3']
* a[(1..).step(2)] # => ["data1", "data2", "data3"]
*
* Unlike slicing with range, if the start or the end of the arithmetic sequence
* is larger than array size, throws RangeError.
+ *
* a = ['--', 'data1', '--', 'data2', '--', 'data3']
* a[(1..11).step(2)]
* # RangeError (((1..11).step(2)) out of range)
@@ -1791,6 +1965,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* If given a single argument, and its type is not one of the listed, tries to
* convert it to Integer, and raises if it is impossible:
+ *
* a = [:foo, 'bar', 2]
* # Raises TypeError (no implicit conversion of Symbol into Integer):
* a[:foo]
@@ -1803,7 +1978,7 @@ rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
{
rb_check_arity(argc, 1, 2);
if (argc == 2) {
- return rb_ary_aref2(ary, argv[0], argv[1]);
+ return rb_ary_aref2(ary, argv[0], argv[1]);
}
return rb_ary_aref1(ary, argv[0]);
}
@@ -1814,7 +1989,7 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
long beg = NUM2LONG(b);
long len = NUM2LONG(e);
if (beg < 0) {
- beg += RARRAY_LEN(ary);
+ beg += RARRAY_LEN(ary);
}
return rb_ary_subseq(ary, beg, len);
}
@@ -1826,7 +2001,7 @@ rb_ary_aref1(VALUE ary, VALUE arg)
/* special case - speeding up */
if (FIXNUM_P(arg)) {
- return rb_ary_entry(ary, FIX2LONG(arg));
+ return rb_ary_entry(ary, FIX2LONG(arg));
}
/* check if idx is Range or ArithmeticSequence */
switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &len, &step, RARRAY_LEN(ary), 0)) {
@@ -1849,6 +2024,7 @@ rb_ary_aref1(VALUE ary, VALUE arg)
* a = [:foo, 'bar', 2]
* a.at(0) # => :foo
* a.at(2) # => 2
+ *
*/
VALUE
@@ -1865,6 +2041,7 @@ rb_ary_at(VALUE ary, VALUE pos)
* Returns elements from +self+; does not modify +self+.
*
* When no argument is given, returns the first element:
+ *
* a = [:foo, 'bar', 2]
* a.first # => :foo
* a # => [:foo, "bar", 2]
@@ -1873,14 +2050,17 @@ rb_ary_at(VALUE ary, VALUE pos)
*
* When non-negative \Integer argument +n+ is given,
* returns the first +n+ elements in a new \Array:
+ *
* a = [:foo, 'bar', 2]
* a.first(2) # => [:foo, "bar"]
*
* If <tt>n >= array.size</tt>, returns all elements:
+ *
* a = [:foo, 'bar', 2]
* a.first(50) # => [:foo, "bar", 2]
*
* If <tt>n == 0</tt> returns an new empty \Array:
+ *
* a = [:foo, 'bar', 2]
* a.first(0) # []
*
@@ -1890,11 +2070,11 @@ static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
if (argc == 0) {
- if (RARRAY_LEN(ary) == 0) return Qnil;
- return RARRAY_AREF(ary, 0);
+ if (RARRAY_LEN(ary) == 0) return Qnil;
+ return RARRAY_AREF(ary, 0);
}
else {
- return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
+ return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
}
@@ -1906,22 +2086,26 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
* Returns elements from +self+; +self+ is not modified.
*
* When no argument is given, returns the last element:
+ *
* a = [:foo, 'bar', 2]
* a.last # => 2
* a # => [:foo, "bar", 2]
*
* If +self+ is empty, returns +nil+.
*
- * When non-negative \Innteger argument +n+ is given,
+ * When non-negative \Integer argument +n+ is given,
* returns the last +n+ elements in a new \Array:
+ *
* a = [:foo, 'bar', 2]
* a.last(2) # => ["bar", 2]
*
* If <tt>n >= array.size</tt>, returns all elements:
+ *
* a = [:foo, 'bar', 2]
* a.last(50) # => [:foo, "bar", 2]
*
* If <tt>n == 0</tt>, returns an new empty \Array:
+ *
* a = [:foo, 'bar', 2]
* a.last(0) # []
*
@@ -1932,12 +2116,12 @@ VALUE
rb_ary_last(int argc, const VALUE *argv, VALUE ary)
{
if (argc == 0) {
- long len = RARRAY_LEN(ary);
- if (len == 0) return Qnil;
- return RARRAY_AREF(ary, len-1);
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ return RARRAY_AREF(ary, len-1);
}
else {
- return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
+ return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
}
}
@@ -1951,10 +2135,12 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary)
*
* With the single \Integer argument +index+,
* returns the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a.fetch(1) # => "bar"
*
* If +index+ is negative, counts from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a.fetch(-1) # => 2
* a.fetch(-2) # => "bar"
@@ -1962,6 +2148,7 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary)
* With arguments +index+ and +default_value+,
* returns the element at offset +index+ if index is in range,
* otherwise returns +default_value+:
+ *
* a = [:foo, 'bar', 2]
* a.fetch(1, nil) # => "bar"
*
@@ -1972,6 +2159,7 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary)
* a = [:foo, 'bar', 2]
* a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
* a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"
+ *
*/
static VALUE
@@ -1984,20 +2172,20 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
rb_scan_args(argc, argv, "11", &pos, &ifnone);
block_given = rb_block_given_p();
if (block_given && argc == 2) {
- rb_warn("block supersedes default value argument");
+ rb_warn("block supersedes default value argument");
}
idx = NUM2LONG(pos);
if (idx < 0) {
- idx += RARRAY_LEN(ary);
+ idx += RARRAY_LEN(ary);
}
if (idx < 0 || RARRAY_LEN(ary) <= idx) {
- if (block_given) return rb_yield(pos);
- if (argc == 1) {
- rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
- idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
- }
- return ifnone;
+ if (block_given) return rb_yield(pos);
+ if (argc == 1) {
+ rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
+ idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
+ }
+ return ifnone;
}
return RARRAY_AREF(ary, idx);
}
@@ -2013,6 +2201,7 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
* When argument +object+ is given but no block,
* returns the index of the first element +element+
* for which <tt>object == element</tt>:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a.index('bar') # => 1
*
@@ -2021,12 +2210,14 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
* When both argument +object+ and a block are given,
* calls the block with each successive element;
* returns the index of the first element for which the block returns a truthy value:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a.index {|element| element == 'bar' } # => 1
*
* Returns +nil+ if the block never returns a truthy value.
*
* When neither an argument nor a block is given, returns a new Enumerator:
+ *
* a = [:foo, 'bar', 2]
* e = a.index
* e # => #<Enumerator: [:foo, "bar", 2]:index>
@@ -2044,23 +2235,23 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
long i;
if (argc == 0) {
- RETURN_ENUMERATOR(ary, 0, 0);
- for (i=0; i<RARRAY_LEN(ary); i++) {
- if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
- return LONG2NUM(i);
- }
- }
- return Qnil;
+ RETURN_ENUMERATOR(ary, 0, 0);
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+ return LONG2NUM(i);
+ }
+ }
+ return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
- rb_warn("given block not used");
+ rb_warn("given block not used");
for (i=0; i<RARRAY_LEN(ary); i++) {
- VALUE e = RARRAY_AREF(ary, i);
- if (rb_equal(e, val)) {
- return LONG2NUM(i);
- }
+ VALUE e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, val)) {
+ return LONG2NUM(i);
+ }
}
return Qnil;
}
@@ -2074,6 +2265,7 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
* Returns the index of the last element for which <tt>object == element</tt>.
*
* When argument +object+ is given but no block, returns the index of the last such element found:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a.rindex('bar') # => 3
*
@@ -2081,6 +2273,7 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
*
* When a block is given but no argument, calls the block with each successive element;
* returns the index of the last element for which the block returns a truthy value:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a.rindex {|element| element == 'bar' } # => 3
*
@@ -2103,25 +2296,25 @@ rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
long i = RARRAY_LEN(ary), len;
if (argc == 0) {
- RETURN_ENUMERATOR(ary, 0, 0);
- while (i--) {
- if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
- return LONG2NUM(i);
- if (i > (len = RARRAY_LEN(ary))) {
- i = len;
- }
- }
- return Qnil;
+ RETURN_ENUMERATOR(ary, 0, 0);
+ while (i--) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
+ return LONG2NUM(i);
+ if (i > (len = RARRAY_LEN(ary))) {
+ i = len;
+ }
+ }
+ return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
- rb_warn("given block not used");
+ rb_warn("given block not used");
while (i--) {
- VALUE e = RARRAY_AREF(ary, i);
- if (rb_equal(e, val)) {
- return LONG2NUM(i);
- }
+ VALUE e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, val)) {
+ return LONG2NUM(i);
+ }
if (i > RARRAY_LEN(ary)) {
break;
}
@@ -2147,54 +2340,54 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
olen = RARRAY_LEN(ary);
if (beg < 0) {
- beg += olen;
- if (beg < 0) {
- rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
- beg - olen, -olen);
- }
+ beg += olen;
+ if (beg < 0) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ beg - olen, -olen);
+ }
}
if (olen < len || olen < beg + len) {
- len = olen - beg;
+ len = olen - beg;
}
{
const VALUE *optr = RARRAY_CONST_PTR_TRANSIENT(ary);
- rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
+ rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
}
if (beg >= olen) {
- VALUE target_ary;
- if (beg > ARY_MAX_SIZE - rlen) {
- rb_raise(rb_eIndexError, "index %ld too big", beg);
- }
- target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
- len = beg + rlen;
- ary_mem_clear(ary, olen, beg - olen);
- if (rlen > 0) {
+ VALUE target_ary;
+ if (beg > ARY_MAX_SIZE - rlen) {
+ rb_raise(rb_eIndexError, "index %ld too big", beg);
+ }
+ target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
+ len = beg + rlen;
+ ary_mem_clear(ary, olen, beg - olen);
+ if (rlen > 0) {
if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
- ary_memcpy0(ary, beg, rlen, rptr, target_ary);
- }
- ARY_SET_LEN(ary, len);
+ ary_memcpy0(ary, beg, rlen, rptr, target_ary);
+ }
+ ARY_SET_LEN(ary, len);
}
else {
- long alen;
-
- if (olen - len > ARY_MAX_SIZE - rlen) {
- rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
- }
- rb_ary_modify(ary);
- alen = olen + rlen - len;
- if (alen >= ARY_CAPA(ary)) {
- ary_double_capa(ary, alen);
- }
-
- if (len != rlen) {
+ long alen;
+
+ if (olen - len > ARY_MAX_SIZE - rlen) {
+ rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
+ }
+ rb_ary_modify(ary);
+ alen = olen + rlen - len;
+ if (alen >= ARY_CAPA(ary)) {
+ ary_double_capa(ary, alen);
+ }
+
+ if (len != rlen) {
RARRAY_PTR_USE_TRANSIENT(ary, ptr,
MEMMOVE(ptr + beg + rlen, ptr + beg + len,
VALUE, olen - (beg + len)));
- ARY_SET_LEN(ary, alen);
- }
- if (rlen > 0) {
+ ARY_SET_LEN(ary, alen);
+ }
+ if (rlen > 0) {
if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
/* give up wb-protected ary */
RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
@@ -2204,7 +2397,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
*/
RARRAY_PTR_USE_TRANSIENT(ary, ptr,
MEMMOVE(ptr + beg, rptr, VALUE, rlen));
- }
+ }
}
}
@@ -2215,22 +2408,14 @@ rb_ary_set_len(VALUE ary, long len)
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
- rb_raise(rb_eRuntimeError, "can't set length of shared ");
+ rb_raise(rb_eRuntimeError, "can't set length of shared ");
}
if (len > (capa = (long)ARY_CAPA(ary))) {
- rb_bug("probable buffer overflow: %ld for %ld", len, capa);
+ rb_bug("probable buffer overflow: %ld for %ld", len, capa);
}
ARY_SET_LEN(ary, len);
}
-/*!
- * expands or shrinks \a ary to \a len elements.
- * expanded region will be filled with Qnil.
- * \param ary an array
- * \param len new size
- * \return \a ary
- * \post the size of \a ary is \a len.
- */
VALUE
rb_ary_resize(VALUE ary, long len)
{
@@ -2240,31 +2425,37 @@ rb_ary_resize(VALUE ary, long len)
olen = RARRAY_LEN(ary);
if (len == olen) return ary;
if (len > ARY_MAX_SIZE) {
- rb_raise(rb_eIndexError, "index %ld too big", len);
+ rb_raise(rb_eIndexError, "index %ld too big", len);
}
if (len > olen) {
- if (len >= ARY_CAPA(ary)) {
- ary_double_capa(ary, len);
- }
- ary_mem_clear(ary, olen, len - olen);
- ARY_SET_LEN(ary, len);
+ if (len >= ARY_CAPA(ary)) {
+ ary_double_capa(ary, len);
+ }
+ ary_mem_clear(ary, olen, len - olen);
+ ARY_SET_LEN(ary, len);
}
else if (ARY_EMBED_P(ary)) {
ARY_SET_EMBED_LEN(ary, len);
}
- else if (len <= RARRAY_EMBED_LEN_MAX) {
- VALUE tmp[RARRAY_EMBED_LEN_MAX];
- MEMCPY(tmp, ARY_HEAP_PTR(ary), VALUE, len);
- ary_discard(ary);
- MEMCPY((VALUE *)ARY_EMBED_PTR(ary), tmp, VALUE, len); /* WB: no new reference */
+ else if (len <= ary_embed_capa(ary)) {
+ const VALUE *ptr = ARY_HEAP_PTR(ary);
+ long ptr_capa = ARY_HEAP_SIZE(ary);
+ bool is_malloc_ptr = !ARY_SHARED_P(ary) && !RARRAY_TRANSIENT_P(ary);
+
+ FL_UNSET(ary, RARRAY_TRANSIENT_FLAG);
+ FL_SET_EMBED(ary);
+
+ MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); /* WB: no new reference */
ARY_SET_EMBED_LEN(ary, len);
+
+ if (is_malloc_ptr) ruby_sized_xfree((void *)ptr, ptr_capa);
}
else {
- if (olen > len + ARY_DEFAULT_SIZE) {
- ary_heap_realloc(ary, len);
- ARY_SET_CAPA(ary, len);
- }
- ARY_SET_HEAP_LEN(ary, len);
+ if (olen > len + ARY_DEFAULT_SIZE) {
+ size_t new_capa = ary_heap_realloc(ary, len);
+ ARY_SET_CAPA(ary, new_capa);
+ }
+ ARY_SET_HEAP_LEN(ary, len);
}
ary_verify(ary);
return ary;
@@ -2297,16 +2488,19 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* When \Integer argument +index+ is given, assigns +object+ to an element in +self+.
*
* If +index+ is non-negative, assigns +object+ the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a[0] = 'foo' # => "foo"
* a # => ["foo", "bar", 2]
*
* If +index+ is greater than <tt>self.length</tt>, extends the array:
+ *
* a = [:foo, 'bar', 2]
* a[7] = 'foo' # => "foo"
* a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
*
* If +index+ is negative, counts backwards from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a[-1] = 'two' # => "two"
* a # => [:foo, "bar", "two"]
@@ -2314,11 +2508,13 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* When \Integer arguments +start+ and +length+ are given and +object+ is not an \Array,
* removes <tt>length - 1</tt> elements beginning at offset +start+,
* and assigns +object+ at offset +start+:
+ *
* a = [:foo, 'bar', 2]
* a[0, 2] = 'foo' # => "foo"
* a # => ["foo", 2]
*
* If +start+ is negative, counts backwards from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a[-2, 2] = 'foo' # => "foo"
* a # => [:foo, "foo"]
@@ -2326,17 +2522,20 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* If +start+ is non-negative and outside the array (<tt> >= self.size</tt>),
* extends the array with +nil+, assigns +object+ at offset +start+,
* and ignores +length+:
+ *
* a = [:foo, 'bar', 2]
* a[6, 50] = 'foo' # => "foo"
* a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
*
* If +length+ is zero, shifts elements at and following offset +start+
* and assigns +object+ at offset +start+:
+ *
* a = [:foo, 'bar', 2]
* a[1, 0] = 'foo' # => "foo"
* a # => [:foo, "foo", "bar", 2]
*
* If +length+ is too large for the existing array, does not extend the array:
+ *
* a = [:foo, 'bar', 2]
* a[1, 5] = 'foo' # => "foo"
* a # => [:foo, "foo"]
@@ -2344,29 +2543,34 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
* When \Range argument +range+ is given and +object+ is an \Array,
* removes <tt>length - 1</tt> elements beginning at offset +start+,
* and assigns +object+ at offset +start+:
+ *
* a = [:foo, 'bar', 2]
* a[0..1] = 'foo' # => "foo"
* a # => ["foo", 2]
*
* if <tt>range.begin</tt> is negative, counts backwards from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a[-2..2] = 'foo' # => "foo"
* a # => [:foo, "foo"]
*
* If the array length is less than <tt>range.begin</tt>,
* assigns +object+ at offset <tt>range.begin</tt>, and ignores +length+:
+ *
* a = [:foo, 'bar', 2]
* a[6..50] = 'foo' # => "foo"
* a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
*
* If <tt>range.end</tt> is zero, shifts elements at and following offset +start+
* and assigns +object+ at offset +start+:
+ *
* a = [:foo, 'bar', 2]
* a[1..0] = 'foo' # => "foo"
* a # => [:foo, "foo", "bar", 2]
*
* If <tt>range.end</tt> is negative, assigns +object+ at offset +start+,
* retains <tt>range.end.abs -1</tt> elements past that, and removes those beyond:
+ *
* a = [:foo, 'bar', 2]
* a[1..-1] = 'foo' # => "foo"
* a # => [:foo, "foo"]
@@ -2380,9 +2584,11 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
*
* If <tt>range.end</tt> is too large for the existing array,
* replaces array elements, but does not extend the array with +nil+ values:
+ *
* a = [:foo, 'bar', 2]
* a[1..5] = 'foo' # => "foo"
* a # => [:foo, "foo"]
+ *
*/
static VALUE
@@ -2393,16 +2599,16 @@ rb_ary_aset(int argc, VALUE *argv, VALUE ary)
rb_check_arity(argc, 2, 3);
rb_ary_modify_check(ary);
if (argc == 3) {
- beg = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
+ beg = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
}
if (FIXNUM_P(argv[0])) {
- offset = FIX2LONG(argv[0]);
+ offset = FIX2LONG(argv[0]);
return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
- /* check if idx is Range */
+ /* check if idx is Range */
return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
}
@@ -2419,15 +2625,18 @@ rb_ary_aset(int argc, VALUE *argv, VALUE ary)
*
* When +index+ is non-negative, inserts all given +objects+
* before the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a.insert(1, :bat, :bam) # => [:foo, :bat, :bam, "bar", 2]
*
* Extends the array if +index+ is beyond the array (<tt>index >= self.size</tt>):
+ *
* a = [:foo, 'bar', 2]
* a.insert(5, :bat, :bam)
* a # => [:foo, "bar", 2, nil, nil, :bat, :bam]
*
* Does nothing if no objects given:
+ *
* a = [:foo, 'bar', 2]
* a.insert(1)
* a.insert(50)
@@ -2436,9 +2645,11 @@ rb_ary_aset(int argc, VALUE *argv, VALUE ary)
*
* When +index+ is negative, inserts all given +objects+
* _after_ the element at offset <tt>index+self.size</tt>:
+ *
* a = [:foo, 'bar', 2]
* a.insert(-2, :bat, :bam)
* a # => [:foo, "bar", :bat, :bam, 2]
+ *
*/
static VALUE
@@ -2451,15 +2662,15 @@ rb_ary_insert(int argc, VALUE *argv, VALUE ary)
pos = NUM2LONG(argv[0]);
if (argc == 1) return ary;
if (pos == -1) {
- pos = RARRAY_LEN(ary);
+ pos = RARRAY_LEN(ary);
}
else if (pos < 0) {
- long minpos = -RARRAY_LEN(ary) - 1;
- if (pos < minpos) {
- rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
- pos, minpos);
- }
- pos++;
+ long minpos = -RARRAY_LEN(ary) - 1;
+ if (pos < minpos) {
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
+ pos, minpos);
+ }
+ pos++;
}
rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
return ary;
@@ -2483,29 +2694,35 @@ ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
*
* When a block given, passes each successive array element to the block;
* returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.each {|element| puts "#{element.class} #{element}" }
*
* Output:
+ *
* Symbol foo
* String bar
* Integer 2
*
* Allows the array to be modified during iteration:
+ *
* a = [:foo, 'bar', 2]
* a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }
*
* Output:
+ *
* foo
* bar
*
* When no block given, returns a new \Enumerator:
* a = [:foo, 'bar', 2]
+ *
* e = a.each
* e # => #<Enumerator: [:foo, "bar", 2]:each>
* a1 = e.each {|element| puts "#{element.class} #{element}" }
*
* Output:
+ *
* Symbol foo
* String bar
* Integer 2
@@ -2520,7 +2737,7 @@ rb_ary_each(VALUE ary)
ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
- rb_yield(RARRAY_AREF(ary, i));
+ rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
@@ -2534,29 +2751,35 @@ rb_ary_each(VALUE ary)
*
* When a block given, passes each successive array index to the block;
* returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.each_index {|index| puts "#{index} #{a[index]}" }
*
* Output:
+ *
* 0 foo
* 1 bar
* 2 2
*
* Allows the array to be modified during iteration:
+ *
* a = [:foo, 'bar', 2]
* a.each_index {|index| puts index; a.clear if index > 0 }
*
* Output:
+ *
* 0
* 1
*
* When no block given, returns a new \Enumerator:
+ *
* a = [:foo, 'bar', 2]
* e = a.each_index
* e # => #<Enumerator: [:foo, "bar", 2]:each_index>
* a1 = e.each {|index| puts "#{index} #{a[index]}"}
*
* Output:
+ *
* 0 foo
* 1 bar
* 2 2
@@ -2571,7 +2794,7 @@ rb_ary_each_index(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
- rb_yield(LONG2NUM(i));
+ rb_yield(LONG2NUM(i));
}
return ary;
}
@@ -2585,28 +2808,35 @@ rb_ary_each_index(VALUE ary)
*
* When a block given, passes, in reverse order, each element to the block;
* returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.reverse_each {|element| puts "#{element.class} #{element}" }
*
* Output:
+ *
* Integer 2
* String bar
* Symbol foo
*
* Allows the array to be modified during iteration:
+ *
* a = [:foo, 'bar', 2]
* a.reverse_each {|element| puts element; a.clear if element.to_s.start_with?('b') }
*
* Output:
+ *
* 2
* bar
*
* When no block given, returns a new \Enumerator:
+ *
* a = [:foo, 'bar', 2]
* e = a.reverse_each
* e # => #<Enumerator: [:foo, "bar", 2]:reverse_each>
* a1 = e.each {|element| puts "#{element.class} #{element}" }
+ *
* Output:
+ *
* Integer 2
* String bar
* Symbol foo
@@ -2622,12 +2852,12 @@ rb_ary_reverse_each(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
len = RARRAY_LEN(ary);
while (len--) {
- long nlen;
- rb_yield(RARRAY_AREF(ary, len));
- nlen = RARRAY_LEN(ary);
- if (nlen < len) {
- len = nlen;
- }
+ long nlen;
+ rb_yield(RARRAY_AREF(ary, len));
+ nlen = RARRAY_LEN(ary);
+ if (nlen < len) {
+ len = nlen;
+ }
}
return ary;
}
@@ -2657,9 +2887,7 @@ rb_ary_length(VALUE ary)
static VALUE
rb_ary_empty_p(VALUE ary)
{
- if (RARRAY_LEN(ary) == 0)
- return Qtrue;
- return Qfalse;
+ return RBOOL(RARRAY_LEN(ary) == 0);
}
VALUE
@@ -2695,10 +2923,10 @@ recursive_join(VALUE obj, VALUE argp, int recur)
int *first = (int *)arg[3];
if (recur) {
- rb_raise(rb_eArgError, "recursive array join");
+ rb_raise(rb_eArgError, "recursive array join");
}
else {
- ary_join_1(obj, ary, sep, 0, result, first);
+ ary_join_1(obj, ary, sep, 0, result, first);
}
return Qnil;
}
@@ -2711,11 +2939,11 @@ ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
for (i=0; i<max; i++) {
- val = RARRAY_AREF(ary, i);
+ val = RARRAY_AREF(ary, i);
if (!RB_TYPE_P(val, T_STRING)) break;
- if (i > 0 && !NIL_P(sep))
- rb_str_buf_append(result, sep);
- rb_str_buf_append(result, val);
+ if (i > 0 && !NIL_P(sep))
+ rb_str_buf_append(result, sep);
+ rb_str_buf_append(result, val);
}
return i;
}
@@ -2754,16 +2982,16 @@ ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
VALUE val, tmp;
for (; i<RARRAY_LEN(ary); i++) {
- if (i > 0 && !NIL_P(sep))
- rb_str_buf_append(result, sep);
+ if (i > 0 && !NIL_P(sep))
+ rb_str_buf_append(result, sep);
- val = RARRAY_AREF(ary, i);
- if (RB_TYPE_P(val, T_STRING)) {
+ val = RARRAY_AREF(ary, i);
+ if (RB_TYPE_P(val, T_STRING)) {
ary_join_1_str(result, val, first);
- }
- else if (RB_TYPE_P(val, T_ARRAY)) {
+ }
+ else if (RB_TYPE_P(val, T_ARRAY)) {
ary_join_1_ary(val, ary, sep, result, val, first);
- }
+ }
else if (!NIL_P(tmp = rb_check_string_type(val))) {
ary_join_1_str(result, tmp, first);
}
@@ -2772,7 +3000,7 @@ ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
}
else {
ary_join_1_str(result, rb_obj_as_string(val), first);
- }
+ }
}
}
@@ -2785,26 +3013,26 @@ rb_ary_join(VALUE ary, VALUE sep)
if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
if (!NIL_P(sep)) {
- StringValue(sep);
- len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
+ StringValue(sep);
+ len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
}
for (i=0; i<RARRAY_LEN(ary); i++) {
- val = RARRAY_AREF(ary, i);
- tmp = rb_check_string_type(val);
+ val = RARRAY_AREF(ary, i);
+ tmp = rb_check_string_type(val);
- if (NIL_P(tmp) || tmp != val) {
- int first;
+ if (NIL_P(tmp) || tmp != val) {
+ int first;
long n = RARRAY_LEN(ary);
if (i > n) i = n;
result = rb_str_buf_new(len + (n-i)*10);
- rb_enc_associate(result, rb_usascii_encoding());
+ rb_enc_associate(result, rb_usascii_encoding());
i = ary_join_0(ary, sep, i, result);
- first = i == 0;
- ary_join_1(ary, ary, sep, i, result, &first);
- return result;
- }
+ first = i == 0;
+ ary_join_1(ary, ary, sep, i, result, &first);
+ return result;
+ }
- len += RSTRING_LEN(tmp);
+ len += RSTRING_LEN(tmp);
}
result = rb_str_new(0, len);
@@ -2821,22 +3049,27 @@ rb_ary_join(VALUE ary, VALUE sep)
* array.join(separator = $,) -> new_string
*
* Returns the new \String formed by joining the array elements after conversion.
- * For each element +element+
+ * For each element +element+:
+ *
* - Uses <tt>element.to_s</tt> if +element+ is not a <tt>kind_of?(Array)</tt>.
* - Uses recursive <tt>element.join(separator)</tt> if +element+ is a <tt>kind_of?(Array)</tt>.
*
* With no argument, joins using the output field separator, <tt>$,</tt>:
+ *
* a = [:foo, 'bar', 2]
* $, # => nil
* a.join # => "foobar2"
*
* With \string argument +separator+, joins using that separator:
+ *
* a = [:foo, 'bar', 2]
* a.join("\n") # => "foo\nbar\n2"
*
* Joins recursively for nested Arrays:
+ *
* a = [:foo, [:bar, [:baz, :bat]]]
* a.join # => "foobarbazbat"
+ *
*/
static VALUE
rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
@@ -2862,10 +3095,10 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
if (recur) return rb_usascii_str_new_cstr("[...]");
str = rb_str_buf_new2("[");
for (i=0; i<RARRAY_LEN(ary); i++) {
- s = rb_inspect(RARRAY_AREF(ary, i));
- if (i > 0) rb_str_buf_cat2(str, ", ");
- else rb_enc_copy(str, s);
- rb_str_buf_append(str, s);
+ s = rb_inspect(RARRAY_AREF(ary, i));
+ if (i > 0) rb_str_buf_cat2(str, ", ");
+ else rb_enc_copy(str, s);
+ rb_str_buf_append(str, s);
}
rb_str_buf_cat2(str, "]");
return str;
@@ -2877,6 +3110,7 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
*
* Returns the new \String formed by calling method <tt>#inspect</tt>
* on each array element:
+ *
* a = [:foo, 'bar', 2]
* a.inspect # => "[:foo, \"bar\", 2]"
*
@@ -2901,10 +3135,12 @@ rb_ary_to_s(VALUE ary)
* to_a -> self or new_array
*
* When +self+ is an instance of \Array, returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.to_a # => [:foo, "bar", 2]
*
* Otherwise, returns a new \Array containing the elements of +self+:
+ *
* class MyArray < Array; end
* a = MyArray.new(['foo', 'bar', 'two'])
* a.instance_of?(Array) # => false
@@ -2912,15 +3148,16 @@ rb_ary_to_s(VALUE ary)
* a1 = a.to_a
* a1 # => ["foo", "bar", "two"]
* a1.class # => Array # Not MyArray
+ *
*/
static VALUE
rb_ary_to_a(VALUE ary)
{
if (rb_obj_class(ary) != rb_cArray) {
- VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
- rb_ary_replace(dup, ary);
- return dup;
+ VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
+ rb_ary_replace(dup, ary);
+ return dup;
}
return ary;
}
@@ -2935,16 +3172,19 @@ rb_ary_to_a(VALUE ary)
* When a block is given, calls the block with each array element;
* the block must return a 2-element \Array whose two elements
* form a key-value pair in the returned \Hash:
+ *
* a = ['foo', :bar, 1, [2, 3], {baz: 4}]
* h = a.to_h {|item| [item, item] }
* h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}}
*
* When no block is given, +self+ must be an \Array of 2-element sub-arrays,
* each sub-array is formed into a key-value pair in the new \Hash:
+ *
* [].to_h # => {}
* a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
* h = a.to_h
* h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
+ *
*/
static VALUE
@@ -2955,18 +3195,18 @@ rb_ary_to_h(VALUE ary)
int block_given = rb_block_given_p();
for (i=0; i<RARRAY_LEN(ary); i++) {
- const VALUE e = rb_ary_elt(ary, i);
- const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
- const VALUE key_value_pair = rb_check_array_type(elt);
- if (NIL_P(key_value_pair)) {
- rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
- rb_obj_class(elt), i);
- }
- if (RARRAY_LEN(key_value_pair) != 2) {
- rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
- i, RARRAY_LEN(key_value_pair));
- }
- rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
+ const VALUE e = rb_ary_elt(ary, i);
+ const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
+ const VALUE key_value_pair = rb_check_array_type(elt);
+ if (NIL_P(key_value_pair)) {
+ rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
+ rb_obj_class(elt), i);
+ }
+ if (RARRAY_LEN(key_value_pair) != 2) {
+ rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
+ i, RARRAY_LEN(key_value_pair));
+ }
+ rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
}
return hash;
}
@@ -2988,9 +3228,9 @@ static void
ary_reverse(VALUE *p1, VALUE *p2)
{
while (p1 < p2) {
- VALUE tmp = *p1;
- *p1++ = *p2;
- *p2-- = tmp;
+ VALUE tmp = *p1;
+ *p1++ = *p2;
+ *p2-- = tmp;
}
}
@@ -3005,7 +3245,7 @@ rb_ary_reverse(VALUE ary)
RARRAY_PTR_USE_TRANSIENT(ary, p1, {
p2 = p1 + len - 1; /* points last item */
ary_reverse(p1, p2);
- }); /* WB: no new reference */
+ }); /* WB: no new reference */
}
return ary;
}
@@ -3015,8 +3255,10 @@ rb_ary_reverse(VALUE ary)
* array.reverse! -> self
*
* Reverses +self+ in place:
+ *
* a = ['foo', 'bar', 'two']
* a.reverse! # => ["two", "bar", "foo"]
+ *
*/
static VALUE
@@ -3029,10 +3271,12 @@ rb_ary_reverse_bang(VALUE ary)
* call-seq:
* array.reverse -> new_array
*
- * Returns a new \Array with the elements of +self+ in reverse order.
+ * Returns a new \Array with the elements of +self+ in reverse order:
+ *
* a = ['foo', 'bar', 'two']
* a1 = a.reverse
* a1 # => ["two", "bar", "foo"]
+ *
*/
static VALUE
@@ -3044,7 +3288,7 @@ rb_ary_reverse_m(VALUE ary)
if (len > 0) {
const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
- do *p2-- = *p1++; while (--len > 0);
+ do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
@@ -3063,11 +3307,13 @@ ary_rotate_ptr(VALUE *ptr, long len, long cnt)
VALUE tmp = *ptr;
memmove(ptr, ptr + 1, sizeof(VALUE)*(len - 1));
*(ptr + len - 1) = tmp;
- } else if (cnt == len - 1) {
+ }
+ else if (cnt == len - 1) {
VALUE tmp = *(ptr + len - 1);
memmove(ptr + 1, ptr, sizeof(VALUE)*(len - 1));
*ptr = tmp;
- } else {
+ }
+ else {
--len;
if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
@@ -3098,35 +3344,42 @@ rb_ary_rotate(VALUE ary, long cnt)
* Rotates +self+ in place by moving elements from one end to the other; returns +self+.
*
* When no argument given, rotates the first element to the last position:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a.rotate! # => ["bar", 2, "bar", :foo]
*
* When given a non-negative \Integer +count+,
* rotates +count+ elements from the beginning to the end:
+ *
* a = [:foo, 'bar', 2]
* a.rotate!(2)
* a # => [2, :foo, "bar"]
*
* If +count+ is large, uses <tt>count % array.size</tt> as the count:
+ *
* a = [:foo, 'bar', 2]
* a.rotate!(20)
* a # => [2, :foo, "bar"]
*
* If +count+ is zero, returns +self+ unmodified:
+ *
* a = [:foo, 'bar', 2]
* a.rotate!(0)
* a # => [:foo, "bar", 2]
*
* When given a negative Integer +count+, rotates in the opposite direction,
* from end to beginning:
+ *
* a = [:foo, 'bar', 2]
* a.rotate!(-2)
* a # => ["bar", 2, :foo]
*
* If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
+ *
* a = [:foo, 'bar', 2]
* a.rotate!(-5)
* a # => ["bar", 2, :foo]
+ *
*/
static VALUE
@@ -3147,36 +3400,43 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
*
* When no argument given, returns a new \Array that is like +self+,
* except that the first element has been rotated to the last position:
+ *
* a = [:foo, 'bar', 2, 'bar']
* a1 = a.rotate
* a1 # => ["bar", 2, "bar", :foo]
*
* When given a non-negative \Integer +count+,
* returns a new \Array with +count+ elements rotated from the beginning to the end:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.rotate(2)
* a1 # => [2, :foo, "bar"]
*
* If +count+ is large, uses <tt>count % array.size</tt> as the count:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.rotate(20)
* a1 # => [2, :foo, "bar"]
*
* If +count+ is zero, returns a copy of +self+, unmodified:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.rotate(0)
* a1 # => [:foo, "bar", 2]
*
* When given a negative \Integer +count+, rotates in the opposite direction,
* from end to beginning:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.rotate(-2)
* a1 # => ["bar", 2, :foo]
*
* If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.rotate(-5)
* a1 # => ["bar", 2, :foo]
+ *
*/
static VALUE
@@ -3190,11 +3450,11 @@ rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
len = RARRAY_LEN(ary);
rotated = rb_ary_new2(len);
if (len > 0) {
- cnt = rotate_count(cnt, len);
+ cnt = rotate_count(cnt, len);
ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
- len -= cnt;
- ary_memcpy(rotated, 0, len, ptr + cnt);
- ary_memcpy(rotated, len, cnt, ptr);
+ len -= cnt;
+ ary_memcpy(rotated, 0, len, ptr + cnt);
+ ary_memcpy(rotated, len, cnt, ptr);
}
ARY_SET_LEN(rotated, RARRAY_LEN(ary));
return rotated;
@@ -3202,18 +3462,27 @@ rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
struct ary_sort_data {
VALUE ary;
- struct cmp_opt_data cmp_opt;
+ VALUE receiver;
};
static VALUE
sort_reentered(VALUE ary)
{
if (RBASIC(ary)->klass) {
- rb_raise(rb_eRuntimeError, "sort reentered");
+ rb_raise(rb_eRuntimeError, "sort reentered");
}
return Qnil;
}
+static void
+sort_returned(struct ary_sort_data *data)
+{
+ if (rb_obj_frozen_p(data->receiver)) {
+ rb_raise(rb_eFrozenError, "array frozen during sort");
+ }
+ sort_reentered(data->ary);
+}
+
static int
sort_1(const void *ap, const void *bp, void *dummy)
{
@@ -3227,7 +3496,7 @@ sort_1(const void *ap, const void *bp, void *dummy)
args[1] = b;
retval = rb_yield_values2(2, args);
n = rb_cmpint(retval, a, b);
- sort_reentered(data->ary);
+ sort_returned(data);
return n;
}
@@ -3239,21 +3508,21 @@ sort_2(const void *ap, const void *bp, void *dummy)
VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
int n;
- if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, Integer)) {
- if ((long)a > (long)b) return 1;
- if ((long)a < (long)b) return -1;
- return 0;
+ if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(INTEGER)) {
+ if ((long)a > (long)b) return 1;
+ if ((long)a < (long)b) return -1;
+ return 0;
}
- if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, String)) {
- return rb_str_cmp(a, b);
+ if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) {
+ return rb_str_cmp(a, b);
}
- if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(data->cmp_opt, Float)) {
- return rb_float_cmp(a, b);
+ if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(FLOAT)) {
+ return rb_float_cmp(a, b);
}
retval = rb_funcallv(a, id_cmp, 1, &b);
n = rb_cmpint(retval, a, b);
- sort_reentered(data->ary);
+ sort_returned(data);
return n;
}
@@ -3267,6 +3536,7 @@ sort_2(const void *ap, const void *bp, void *dummy)
*
* With no block, compares elements using operator <tt><=></tt>
* (see Comparable):
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a.sort!
@@ -3274,11 +3544,13 @@ sort_2(const void *ap, const void *bp, void *dummy)
*
* With a block, calls the block with each element pair;
* for each element pair +a+ and +b+, the block should return an integer:
+ *
* - Negative when +b+ is to follow +a+.
* - Zero when +a+ and +b+ are equivalent.
* - Positive when +a+ is to follow +b+.
*
* Example:
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a.sort! {|a, b| a <=> b }
@@ -3288,10 +3560,12 @@ sort_2(const void *ap, const void *bp, void *dummy)
*
* When the block returns zero, the order for +a+ and +b+ is indeterminate,
* and may be unstable:
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a.sort! {|a, b| 0 }
* a # => ["d", "e", "c", "a", "b"]
+ *
*/
VALUE
@@ -3300,24 +3574,23 @@ rb_ary_sort_bang(VALUE ary)
rb_ary_modify(ary);
assert(!ARY_SHARED_P(ary));
if (RARRAY_LEN(ary) > 1) {
- VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
- struct ary_sort_data data;
- long len = RARRAY_LEN(ary);
- RBASIC_CLEAR_CLASS(tmp);
- data.ary = tmp;
- data.cmp_opt.opt_methods = 0;
- data.cmp_opt.opt_inited = 0;
- RARRAY_PTR_USE(tmp, ptr, {
+ VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
+ struct ary_sort_data data;
+ long len = RARRAY_LEN(ary);
+ RBASIC_CLEAR_CLASS(tmp);
+ data.ary = tmp;
+ data.receiver = ary;
+ RARRAY_PTR_USE(tmp, ptr, {
ruby_qsort(ptr, len, sizeof(VALUE),
rb_block_given_p()?sort_1:sort_2, &data);
- }); /* WB: no new reference */
- rb_ary_modify(ary);
+ }); /* WB: no new reference */
+ rb_ary_modify(ary);
if (ARY_EMBED_P(tmp)) {
if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
rb_ary_unshare(ary);
- FL_SET_EMBED(ary);
+ FL_SET_EMBED(ary);
}
- ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
+ ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
}
else {
@@ -3363,6 +3636,7 @@ rb_ary_sort_bang(VALUE ary)
*
* With no block, compares elements using operator <tt><=></tt>
* (see Comparable):
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a1 = a.sort
@@ -3370,11 +3644,13 @@ rb_ary_sort_bang(VALUE ary)
*
* With a block, calls the block with each element pair;
* for each element pair +a+ and +b+, the block should return an integer:
+ *
* - Negative when +b+ is to follow +a+.
* - Zero when +a+ and +b+ are equivalent.
* - Positive when +a+ is to follow +b+.
*
* Example:
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a1 = a.sort {|a, b| a <=> b }
@@ -3384,6 +3660,7 @@ rb_ary_sort_bang(VALUE ary)
*
* When the block returns zero, the order for +a+ and +b+ is indeterminate,
* and may be unstable:
+ *
* a = 'abcde'.split('').shuffle
* a # => ["e", "b", "d", "a", "c"]
* a1 = a.sort {|a, b| 0 }
@@ -3408,89 +3685,8 @@ static VALUE rb_ary_bsearch_index(VALUE ary);
* array.bsearch -> new_enumerator
*
* Returns an element from +self+ selected by a binary search.
- * +self+ should be sorted, but this is not checked.
*
- * By using binary search, finds a value from this array which meets
- * the given condition in <tt>O(log n)</tt> where +n+ is the size of the array.
- *
- * There are two search modes:
- * - <b>Find-minimum mode</b>: the block should return +true+ or +false+.
- * - <b>Find-any mode</b>: the block should return a numeric value.
- *
- * The block should not mix the modes by and sometimes returning +true+ or +false+
- * and sometimes returning a numeric value, but this is not checked.
- *
- * <b>Find-Minimum Mode</b>
- *
- * In find-minimum mode, the block always returns +true+ or +false+.
- * The further requirement (though not checked) is that
- * there are no indexes +i+ and +j+ such that:
- * - <tt>0 <= i < j <= self.size</tt>.
- * - The block returns +true+ for <tt>self[i]</tt> and +false+ for <tt>self[j]</tt>.
- *
- * In find-minimum mode, method bsearch returns the first element for which the block returns true.
- *
- * Examples:
- * a = [0, 4, 7, 10, 12]
- * a.bsearch {|x| x >= 4 } # => 4
- * a.bsearch {|x| x >= 6 } # => 7
- * a.bsearch {|x| x >= -1 } # => 0
- * a.bsearch {|x| x >= 100 } # => nil
- *
- * Less formally: the block is such that all +false+-evaluating elements
- * precede all +true+-evaluating elements.
- *
- * These make sense as blocks in find-minimum mode:
- * a = [0, 4, 7, 10, 12]
- * a.map {|x| x >= 4 } # => [false, true, true, true, true]
- * a.map {|x| x >= 6 } # => [false, false, true, true, true]
- * a.map {|x| x >= -1 } # => [true, true, true, true, true]
- * a.map {|x| x >= 100 } # => [false, false, false, false, false]
- *
- * This would not make sense:
- * a = [0, 4, 7, 10, 12]
- * a.map {|x| x == 7 } # => [false, false, true, false, false]
- *
- * <b>Find-Any Mode</b>
- *
- * In find-any mode, the block always returns a numeric value.
- * The further requirement (though not checked) is that
- * there are no indexes +i+ and +j+ such that:
- * - <tt>0 <= i < j <= self.size</tt>.
- * - The block returns a negative value for <tt>self[i]</tt>
- * and a positive value for <tt>self[j]</tt>.
- * - The block returns a negative value for <tt>self[i]</tt> and zero <tt>self[j]</tt>.
- * - The block returns zero for <tt>self[i]</tt> and a positive value for <tt>self[j]</tt>.
- *
- * In find-any mode, method bsearch returns some element
- * for which the block returns zero, or +nil+ if no such element is found.
- *
- * Examples:
- * a = [0, 4, 7, 10, 12]
- * a.bsearch {|element| 7 <=> element } # => 7
- * a.bsearch {|element| -1 <=> element } # => nil
- * a.bsearch {|element| 5 <=> element } # => nil
- * a.bsearch {|element| 15 <=> element } # => nil
- *
- * Less formally: the block is such that:
- * - All positive-evaluating elements precede all zero-evaluating elements.
- * - All positive-evaluating elements precede all negative-evaluating elements.
- * - All zero-evaluating elements precede all negative-evaluating elements.
- *
- * These make sense as blocks in find-any mode:
- * a = [0, 4, 7, 10, 12]
- * a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
- * a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
- * a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
- * a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]
- *
- * This would not make sense:
- * a = [0, 4, 7, 10, 12]
- * a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]
- *
- * Returns an enumerator if no block given:
- * a = [0, 4, 7, 10, 12]
- * a.bsearch # => #<Enumerator: [0, 4, 7, 10, 12]:bsearch>
+ * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
*/
static VALUE
@@ -3499,7 +3695,7 @@ rb_ary_bsearch(VALUE ary)
VALUE index_result = rb_ary_bsearch_index(ary);
if (FIXNUM_P(index_result)) {
- return rb_ary_entry(ary, FIX2LONG(index_result));
+ return rb_ary_entry(ary, FIX2LONG(index_result));
}
return index_result;
}
@@ -3522,39 +3718,39 @@ rb_ary_bsearch_index(VALUE ary)
RETURN_ENUMERATOR(ary, 0, 0);
while (low < high) {
- mid = low + ((high - low) / 2);
- val = rb_ary_entry(ary, mid);
- v = rb_yield(val);
- if (FIXNUM_P(v)) {
- if (v == INT2FIX(0)) return INT2FIX(mid);
- smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
- }
- else if (v == Qtrue) {
- satisfied = 1;
- smaller = 1;
- }
- else if (v == Qfalse || v == Qnil) {
- smaller = 0;
- }
- else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
- const VALUE zero = INT2FIX(0);
- switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
- case 0: return INT2FIX(mid);
- case 1: smaller = 1; break;
- case -1: smaller = 0;
- }
- }
- else {
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
- " (must be numeric, true, false or nil)",
- rb_obj_class(v));
- }
- if (smaller) {
- high = mid;
- }
- else {
- low = mid + 1;
- }
+ mid = low + ((high - low) / 2);
+ val = rb_ary_entry(ary, mid);
+ v = rb_yield(val);
+ if (FIXNUM_P(v)) {
+ if (v == INT2FIX(0)) return INT2FIX(mid);
+ smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
+ }
+ else if (v == Qtrue) {
+ satisfied = 1;
+ smaller = 1;
+ }
+ else if (!RTEST(v)) {
+ smaller = 0;
+ }
+ else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
+ const VALUE zero = INT2FIX(0);
+ switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
+ case 0: return INT2FIX(mid);
+ case 1: smaller = 0; break;
+ case -1: smaller = 1;
+ }
+ }
+ else {
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
+ " (must be numeric, true, false or nil)",
+ rb_obj_class(v));
+ }
+ if (smaller) {
+ high = mid;
+ }
+ else {
+ low = mid + 1;
+ }
}
if (!satisfied) return Qnil;
return INT2FIX(low);
@@ -3581,6 +3777,7 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
* For duplicates returned by the block, the ordering is indeterminate, and may be unstable.
*
* This example sorts strings based on their sizes:
+ *
* a = ['aaaa', 'bbb', 'cc', 'd']
* a.sort_by! {|element| element.size }
* a # => ["d", "cc", "bbb", "aaaa"]
@@ -3589,6 +3786,7 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
*
* a = ['aaaa', 'bbb', 'cc', 'd']
* a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
+ *
*/
static VALUE
@@ -3611,6 +3809,7 @@ rb_ary_sort_by_bang(VALUE ary)
*
* Calls the block, if given, with each element of +self+;
* returns a new \Array whose elements are the return values from the block:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.map {|element| element.class }
* a1 # => [Symbol, String, Integer]
@@ -3645,10 +3844,12 @@ rb_ary_collect(VALUE ary)
*
* Calls the block, if given, with each element;
* replaces the element with the block's return value:
+ *
* a = [:foo, 'bar', 2]
* a.map! { |element| element.class } # => [Symbol, String, Integer]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2]
* a1 = a.map!
* a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
@@ -3664,7 +3865,7 @@ rb_ary_collect_bang(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
+ rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
}
return ary;
}
@@ -3676,21 +3877,21 @@ rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func
long beg, len, i, j;
for (i=0; i<argc; i++) {
- if (FIXNUM_P(argv[i])) {
- rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
- continue;
- }
- /* check if idx is Range */
- if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
- long end = olen < beg+len ? olen : beg+len;
- for (j = beg; j < end; j++) {
- rb_ary_push(result, (*func)(obj, j));
- }
- if (beg + len > j)
- rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
- continue;
- }
- rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
+ if (FIXNUM_P(argv[i])) {
+ rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
+ continue;
+ }
+ /* check if idx is Range */
+ if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
+ long end = olen < beg+len ? olen : beg+len;
+ for (j = beg; j < end; j++) {
+ rb_ary_push(result, (*func)(obj, j));
+ }
+ if (beg + len > j)
+ rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
+ continue;
+ }
+ rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
}
return result;
}
@@ -3700,25 +3901,25 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
{
long beg, len;
if (FIXNUM_P(idx)) {
- beg = FIX2LONG(idx);
+ beg = FIX2LONG(idx);
}
/* check if idx is Range */
else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
- if (len > 0) {
+ if (len > 0) {
const VALUE *const src = RARRAY_CONST_PTR_TRANSIENT(ary);
- const long end = beg + len;
- const long prevlen = RARRAY_LEN(result);
- if (beg < olen) {
- rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
- }
- if (end > olen) {
- rb_ary_store(result, prevlen + len - 1, Qnil);
- }
- }
- return result;
+ const long end = beg + len;
+ const long prevlen = RARRAY_LEN(result);
+ if (beg < olen) {
+ rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
+ }
+ if (end > olen) {
+ rb_ary_store(result, prevlen + len - 1, Qnil);
+ }
+ }
+ return result;
}
else {
- beg = NUM2LONG(idx);
+ beg = NUM2LONG(idx);
}
return rb_ary_push(result, rb_ary_entry(ary, beg));
}
@@ -3728,33 +3929,42 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
* array.values_at(*indexes) -> new_array
*
* Returns a new \Array whose elements are the elements
- * of +self+ at the given \Integer +indexes+.
+ * of +self+ at the given \Integer or \Range +indexes+.
*
* For each positive +index+, returns the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(0, 2) # => [:foo, 2]
+ * a.values_at(0..1) # => [:foo, "bar"]
*
* The given +indexes+ may be in any order, and may repeat:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(2, 0, 1, 0, 2) # => [2, :foo, "bar", :foo, 2]
+ * a.values_at(1, 0..2) # => ["bar", :foo, "bar", 2]
*
* Assigns +nil+ for an +index+ that is too large:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil]
*
* Returns a new empty \Array if no arguments given.
*
* For each negative +index+, counts backward from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(-1, -3) # => [2, :foo]
*
* Assigns +nil+ for an +index+ that is too small:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2]
*
* The given +indexes+ may have a mixture of signs:
+ *
* a = [:foo, 'bar', 2]
* a.values_at(0, -2, 1, -1) # => [:foo, "bar", "bar", 2]
+ *
*/
static VALUE
@@ -3763,7 +3973,7 @@ rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
long i, olen = RARRAY_LEN(ary);
VALUE result = rb_ary_new_capa(argc);
for (i = 0; i < argc; ++i) {
- append_values_at_single(result, ary, olen, argv[i]);
+ append_values_at_single(result, ary, olen, argv[i]);
}
RB_GC_GUARD(ary);
return result;
@@ -3778,11 +3988,13 @@ rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
* Calls the block, if given, with each element of +self+;
* returns a new \Array containing those elements of +self+
* for which the block returns a truthy value:
+ *
* a = [:foo, 'bar', 2, :bam]
* a1 = a.select {|element| element.to_s.start_with?('b') }
* a1 # => ["bar", :bam]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2, :bam]
* a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
*
@@ -3798,9 +4010,9 @@ rb_ary_select(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
- if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
- rb_ary_push(result, rb_ary_elt(ary, i));
- }
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+ rb_ary_push(result, rb_ary_elt(ary, i));
+ }
}
return result;
}
@@ -3818,12 +4030,12 @@ select_bang_i(VALUE a)
long i1, i2;
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
- VALUE v = RARRAY_AREF(ary, i1);
- if (!RTEST(rb_yield(v))) continue;
- if (i1 != i2) {
- rb_ary_store(ary, i2, v);
- }
- arg->len[1] = ++i2;
+ VALUE v = RARRAY_AREF(ary, i1);
+ if (!RTEST(rb_yield(v))) continue;
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, v);
+ }
+ arg->len[1] = ++i2;
}
return (i1 == i2) ? Qnil : ary;
}
@@ -3837,14 +4049,15 @@ select_bang_ensure(VALUE a)
long i1 = arg->len[0], i2 = arg->len[1];
if (i2 < len && i2 < i1) {
- long tail = 0;
- if (i1 < len) {
- tail = len - i1;
+ long tail = 0;
+ rb_ary_modify(ary);
+ if (i1 < len) {
+ tail = len - i1;
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
- });
- }
- ARY_SET_LEN(ary, i2 + tail);
+ MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
+ });
+ }
+ ARY_SET_LEN(ary, i2 + tail);
}
return ary;
}
@@ -3858,12 +4071,14 @@ select_bang_ensure(VALUE a)
* removes from +self+ those elements for which the block returns +false+ or +nil+.
*
* Returns +self+ if any elements were removed:
+ *
* a = [:foo, 'bar', 2, :bam]
* a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
* Returns +nil+ if no elements were removed.
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2, :bam]
* a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
*
@@ -3890,12 +4105,15 @@ rb_ary_select_bang(VALUE ary)
*
* Retains those elements for which the block returns a truthy value;
* deletes all other elements; returns +self+:
+ *
* a = [:foo, 'bar', 2, :bam]
* a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2, :bam]
* a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
+ *
*/
static VALUE
@@ -3911,11 +4129,11 @@ ary_resize_smaller(VALUE ary, long len)
{
rb_ary_modify(ary);
if (RARRAY_LEN(ary) > len) {
- ARY_SET_LEN(ary, len);
- if (len * 2 < ARY_CAPA(ary) &&
- ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
- ary_resize_capa(ary, len * 2);
- }
+ ARY_SET_LEN(ary, len);
+ if (len * 2 < ARY_CAPA(ary) &&
+ ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
+ ary_resize_capa(ary, len * 2);
+ }
}
}
@@ -3924,11 +4142,12 @@ ary_resize_smaller(VALUE ary, long len)
* array.delete(obj) -> deleted_object
* array.delete(obj) {|nosuch| ... } -> deleted_object or block_return
*
- * Removes zero or more elements from +self+; returns +self+.
+ * Removes zero or more elements from +self+.
*
* When no block is given,
* removes from +self+ each element +ele+ such that <tt>ele == obj</tt>;
* returns the last deleted element:
+ *
* s1 = 'bar'; s2 = 'bar'
* a = [:foo, s1, 2, s2]
* a.delete('bar') # => "bar"
@@ -3941,14 +4160,17 @@ ary_resize_smaller(VALUE ary, long len)
*
* If any such elements are found, ignores the block
* and returns the last deleted element:
+ *
* s1 = 'bar'; s2 = 'bar'
* a = [:foo, s1, 2, s2]
* deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' }
* a # => [:foo, 2]
*
* If no such elements are found, returns the block's return value:
+ *
* a = [:foo, 'bar', 2]
* a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found"
+ *
*/
VALUE
@@ -3958,22 +4180,22 @@ rb_ary_delete(VALUE ary, VALUE item)
long i1, i2;
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
- VALUE e = RARRAY_AREF(ary, i1);
+ VALUE e = RARRAY_AREF(ary, i1);
- if (rb_equal(e, item)) {
- v = e;
- continue;
- }
- if (i1 != i2) {
- rb_ary_store(ary, i2, e);
- }
- i2++;
+ if (rb_equal(e, item)) {
+ v = e;
+ continue;
+ }
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, e);
+ }
+ i2++;
}
if (RARRAY_LEN(ary) == i2) {
- if (rb_block_given_p()) {
- return rb_yield(item);
- }
- return Qnil;
+ if (rb_block_given_p()) {
+ return rb_yield(item);
+ }
+ return Qnil;
}
ary_resize_smaller(ary, i2);
@@ -3988,18 +4210,18 @@ rb_ary_delete_same(VALUE ary, VALUE item)
long i1, i2;
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
- VALUE e = RARRAY_AREF(ary, i1);
+ VALUE e = RARRAY_AREF(ary, i1);
- if (e == item) {
- continue;
- }
- if (i1 != i2) {
- rb_ary_store(ary, i2, e);
- }
- i2++;
+ if (e == item) {
+ continue;
+ }
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, e);
+ }
+ i2++;
}
if (RARRAY_LEN(ary) == i2) {
- return;
+ return;
}
ary_resize_smaller(ary, i2);
@@ -4013,8 +4235,8 @@ rb_ary_delete_at(VALUE ary, long pos)
if (pos >= len) return Qnil;
if (pos < 0) {
- pos += len;
- if (pos < 0) return Qnil;
+ pos += len;
+ if (pos < 0) return Qnil;
}
rb_ary_modify(ary);
@@ -4034,6 +4256,7 @@ rb_ary_delete_at(VALUE ary, long pos)
* Deletes an element from +self+, per the given \Integer +index+.
*
* When +index+ is non-negative, deletes the element at offset +index+:
+ *
* a = [:foo, 'bar', 2]
* a.delete_at(1) # => "bar"
* a # => [:foo, 2]
@@ -4041,6 +4264,7 @@ rb_ary_delete_at(VALUE ary, long pos)
* If index is too large, returns +nil+.
*
* When +index+ is negative, counts backward from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a.delete_at(-2) # => "bar"
* a # => [:foo, 2]
@@ -4071,7 +4295,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
else if (orig_len < pos) {
return Qnil;
}
- else if (orig_len < pos + len) {
+ if (orig_len < pos + len) {
len = orig_len - pos;
}
if (len == 0) {
@@ -4094,11 +4318,13 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
*
* When the only argument is an \Integer +n+,
* removes and returns the _nth_ element in +self+:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(1) # => "bar"
* a # => [:foo, 2]
*
* If +n+ is negative, counts backwards from the end of +self+:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(-1) # => 2
* a # => [:foo, "bar"]
@@ -4107,13 +4333,15 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
*
* When the only arguments are Integers +start+ and +length+,
* removes +length+ elements from +self+ beginning at offset +start+;
- * returns the deleted objects in a new Array:
+ * returns the deleted objects in a new \Array:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(0, 2) # => [:foo, "bar"]
* a # => [2]
*
* If <tt>start + length</tt> exceeds the array size,
* removes and returns all elements from offset +start+ to the end:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(1, 50) # => ["bar", 2]
* a # => [:foo]
@@ -4125,8 +4353,9 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
*
* When the only argument is a \Range object +range+,
* treats <tt>range.min</tt> as +start+ above and <tt>range.size</tt> as +length+ above:
+ *
* a = [:foo, 'bar', 2]
- * a.slice!(1..2) # => ["bar", 2]
+ * a.slice!(1..2) # => ["bar", 2]
* a # => [:foo]
*
* If <tt>range.start == a.size</tt>, returns a new empty \Array.
@@ -4134,15 +4363,18 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
* If <tt>range.start</tt> is larger than the array size, returns +nil+.
*
* If <tt>range.end</tt> is negative, counts backwards from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(0..-2) # => [:foo, "bar"]
* a # => [2]
*
* If <tt>range.start</tt> is negative,
* calculates the start index backwards from the end of the array:
+ *
* a = [:foo, 'bar', 2]
* a.slice!(-2..2) # => ["bar", 2]
* a # => [:foo]
+ *
*/
static VALUE
@@ -4156,23 +4388,23 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
arg1 = argv[0];
if (argc == 2) {
- pos = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
+ pos = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
}
if (!FIXNUM_P(arg1)) {
- switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
- case Qtrue:
- /* valid range */
+ switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
+ case Qtrue:
+ /* valid range */
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
- case Qnil:
- /* invalid range */
- return Qnil;
- default:
- /* not a range */
- break;
- }
+ case Qnil:
+ /* invalid range */
+ return Qnil;
+ default:
+ /* not a range */
+ break;
+ }
}
return rb_ary_delete_at(ary, NUM2LONG(arg1));
@@ -4184,11 +4416,11 @@ ary_reject(VALUE orig, VALUE result)
long i;
for (i = 0; i < RARRAY_LEN(orig); i++) {
- VALUE v = RARRAY_AREF(orig, i);
+ VALUE v = RARRAY_AREF(orig, i);
if (!RTEST(rb_yield(v))) {
- rb_ary_push(result, v);
- }
+ rb_ary_push(result, v);
+ }
}
return result;
}
@@ -4201,12 +4433,12 @@ reject_bang_i(VALUE a)
long i1, i2;
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
- VALUE v = RARRAY_AREF(ary, i1);
- if (RTEST(rb_yield(v))) continue;
- if (i1 != i2) {
- rb_ary_store(ary, i2, v);
- }
- arg->len[1] = ++i2;
+ VALUE v = RARRAY_AREF(ary, i1);
+ if (RTEST(rb_yield(v))) continue;
+ if (i1 != i2) {
+ rb_ary_store(ary, i2, v);
+ }
+ arg->len[1] = ++i2;
}
return (i1 == i2) ? Qnil : ary;
}
@@ -4229,14 +4461,17 @@ ary_reject_bang(VALUE ary)
* Removes each element for which the block returns a truthy value.
*
* Returns +self+ if any elements removed:
+ *
* a = [:foo, 'bar', 2, 'bat']
* a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
* Returns +nil+ if no elements removed.
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2]
* a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
+ *
*/
static VALUE
@@ -4254,13 +4489,16 @@ rb_ary_reject_bang(VALUE ary)
*
* Returns a new \Array whose elements are all those from +self+
* for which the block returns +false+ or +nil+:
+ *
* a = [:foo, 'bar', 2, 'bat']
* a1 = a.reject {|element| element.to_s.start_with?('b') }
* a1 # => [:foo, 2]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2]
* a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
+ *
*/
static VALUE
@@ -4281,13 +4519,16 @@ rb_ary_reject(VALUE ary)
*
* Removes each element in +self+ for which the block returns a truthy value;
* returns +self+:
+ *
* a = [:foo, 'bar', 2, 'bat']
* a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [:foo, 'bar', 2]
* a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
- */
+ *
+3 */
static VALUE
rb_ary_delete_if(VALUE ary)
@@ -4302,10 +4543,9 @@ static VALUE
take_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, cbarg))
{
VALUE *args = (VALUE *)cbarg;
- if (args[1] == 0) rb_iter_break();
- else args[1]--;
if (argc > 1) val = rb_ary_new4(argc, argv);
rb_ary_push(args[0], val);
+ if (--args[1] == 0) rb_iter_break();
return Qnil;
}
@@ -4315,12 +4555,13 @@ take_items(VALUE obj, long n)
VALUE result = rb_check_array_type(obj);
VALUE args[2];
+ if (n == 0) return result;
if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
result = rb_ary_new2(n);
args[0] = result; args[1] = (VALUE)n;
- if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
- rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
- rb_obj_class(obj));
+ if (UNDEF_P(rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args)))
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
+ rb_obj_class(obj));
return result;
}
@@ -4335,10 +4576,12 @@ take_items(VALUE obj, long n)
*
* Each nested array <tt>new_array[n]</tt> is of size <tt>other_arrays.size+1</tt>,
* and contains:
+ *
* - The _nth_ element of +self+.
* - The _nth_ element of each of the +other_arrays+.
*
* If all +other_arrays+ and +self+ are the same size:
+ *
* a = [:a0, :a1, :a2, :a3]
* b = [:b0, :b1, :b2, :b3]
* c = [:c0, :c1, :c2, :c3]
@@ -4347,6 +4590,7 @@ take_items(VALUE obj, long n)
*
* If any array in +other_arrays+ is smaller than +self+,
* fills to <tt>self.size</tt> with +nil+:
+ *
* a = [:a0, :a1, :a2, :a3]
* b = [:b0, :b1, :b2]
* c = [:c0, :c1]
@@ -4355,23 +4599,27 @@ take_items(VALUE obj, long n)
*
* If any array in +other_arrays+ is larger than +self+,
* its trailing elements are ignored:
+ *
* a = [:a0, :a1, :a2, :a3]
* b = [:b0, :b1, :b2, :b3, :b4]
* c = [:c0, :c1, :c2, :c3, :c4, :c5]
* d = a.zip(b, c)
* d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
*
- * When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil
+ * When a block is given, calls the block with each of the sub-arrays (formed as above); returns +nil+:
+ *
* a = [:a0, :a1, :a2, :a3]
* b = [:b0, :b1, :b2, :b3]
* c = [:c0, :c1, :c2, :c3]
* a.zip(b, c) {|sub_array| p sub_array} # => nil
*
* Output:
+ *
* [:a0, :b0, :c0]
* [:a1, :b1, :c1]
* [:a2, :b2, :c2]
* [:a3, :b3, :c3]
+ *
*/
static VALUE
@@ -4382,51 +4630,51 @@ rb_ary_zip(int argc, VALUE *argv, VALUE ary)
VALUE result = Qnil;
for (i=0; i<argc; i++) {
- argv[i] = take_items(argv[i], len);
+ argv[i] = take_items(argv[i], len);
}
if (rb_block_given_p()) {
- int arity = rb_block_arity();
-
- if (arity > 1) {
- VALUE work, *tmp;
-
- tmp = ALLOCV_N(VALUE, work, argc+1);
-
- for (i=0; i<RARRAY_LEN(ary); i++) {
- tmp[0] = RARRAY_AREF(ary, i);
- for (j=0; j<argc; j++) {
- tmp[j+1] = rb_ary_elt(argv[j], i);
- }
- rb_yield_values2(argc+1, tmp);
- }
-
- if (work) ALLOCV_END(work);
- }
- else {
- for (i=0; i<RARRAY_LEN(ary); i++) {
- VALUE tmp = rb_ary_new2(argc+1);
-
- rb_ary_push(tmp, RARRAY_AREF(ary, i));
- for (j=0; j<argc; j++) {
- rb_ary_push(tmp, rb_ary_elt(argv[j], i));
- }
- rb_yield(tmp);
- }
- }
+ int arity = rb_block_arity();
+
+ if (arity > 1) {
+ VALUE work, *tmp;
+
+ tmp = ALLOCV_N(VALUE, work, argc+1);
+
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ tmp[0] = RARRAY_AREF(ary, i);
+ for (j=0; j<argc; j++) {
+ tmp[j+1] = rb_ary_elt(argv[j], i);
+ }
+ rb_yield_values2(argc+1, tmp);
+ }
+
+ if (work) ALLOCV_END(work);
+ }
+ else {
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ VALUE tmp = rb_ary_new2(argc+1);
+
+ rb_ary_push(tmp, RARRAY_AREF(ary, i));
+ for (j=0; j<argc; j++) {
+ rb_ary_push(tmp, rb_ary_elt(argv[j], i));
+ }
+ rb_yield(tmp);
+ }
+ }
}
else {
- result = rb_ary_new_capa(len);
+ result = rb_ary_new_capa(len);
- for (i=0; i<len; i++) {
- VALUE tmp = rb_ary_new_capa(argc+1);
+ for (i=0; i<len; i++) {
+ VALUE tmp = rb_ary_new_capa(argc+1);
- rb_ary_push(tmp, RARRAY_AREF(ary, i));
- for (j=0; j<argc; j++) {
- rb_ary_push(tmp, rb_ary_elt(argv[j], i));
- }
- rb_ary_push(result, tmp);
- }
+ rb_ary_push(tmp, RARRAY_AREF(ary, i));
+ for (j=0; j<argc; j++) {
+ rb_ary_push(tmp, rb_ary_elt(argv[j], i));
+ }
+ rb_ary_push(result, tmp);
+ }
}
return result;
@@ -4438,8 +4686,10 @@ rb_ary_zip(int argc, VALUE *argv, VALUE ary)
*
* Transposes the rows and columns in an \Array of Arrays;
* the nested Arrays must all be the same size:
+ *
* a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
* a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
+ *
*/
static VALUE
@@ -4451,21 +4701,21 @@ rb_ary_transpose(VALUE ary)
alen = RARRAY_LEN(ary);
if (alen == 0) return rb_ary_dup(ary);
for (i=0; i<alen; i++) {
- tmp = to_ary(rb_ary_elt(ary, i));
- if (elen < 0) { /* first element */
- elen = RARRAY_LEN(tmp);
- result = rb_ary_new2(elen);
- for (j=0; j<elen; j++) {
- rb_ary_store(result, j, rb_ary_new2(alen));
- }
- }
- else if (elen != RARRAY_LEN(tmp)) {
- rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
- RARRAY_LEN(tmp), elen);
- }
- for (j=0; j<elen; j++) {
- rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
- }
+ tmp = to_ary(rb_ary_elt(ary, i));
+ if (elen < 0) { /* first element */
+ elen = RARRAY_LEN(tmp);
+ result = rb_ary_new2(elen);
+ for (j=0; j<elen; j++) {
+ rb_ary_store(result, j, rb_ary_new2(alen));
+ }
+ }
+ else if (elen != RARRAY_LEN(tmp)) {
+ rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
+ RARRAY_LEN(tmp), elen);
+ }
+ for (j=0; j<elen; j++) {
+ rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
+ }
}
return result;
}
@@ -4475,8 +4725,10 @@ rb_ary_transpose(VALUE ary)
* array.replace(other_array) -> self
*
* Replaces the content of +self+ with the content of +other_array+; returns +self+:
+ *
* a = [:foo, 'bar', 2]
* a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
+ *
*/
VALUE
@@ -4486,31 +4738,35 @@ rb_ary_replace(VALUE copy, VALUE orig)
orig = to_ary(orig);
if (copy == orig) return copy;
- if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
- VALUE shared_root = 0;
+ rb_ary_reset(copy);
- if (ARY_OWNS_HEAP_P(copy)) {
- ary_heap_free(copy);
- }
- else if (ARY_SHARED_P(copy)) {
- shared_root = ARY_SHARED_ROOT(copy);
- FL_UNSET_SHARED(copy);
- }
- FL_SET_EMBED(copy);
+ /* orig has enough space to embed the contents of orig. */
+ if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
+ assert(ARY_EMBED_P(copy));
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
- if (shared_root) {
- rb_ary_decrement_share(shared_root);
- }
- ARY_SET_LEN(copy, RARRAY_LEN(orig));
+ ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
+ }
+#if USE_RVARGC
+ /* orig is embedded but copy does not have enough space to embed the
+ * contents of orig. */
+ else if (ARY_EMBED_P(orig)) {
+ long len = ARY_EMBED_LEN(orig);
+ VALUE *ptr = ary_heap_alloc(copy, len);
+
+ FL_UNSET_EMBED(copy);
+ ARY_SET_PTR(copy, ptr);
+ ARY_SET_LEN(copy, len);
+ ARY_SET_CAPA(copy, len);
+
+ // No allocation and exception expected that could leave `copy` in a
+ // bad state from the edits above.
+ ary_memcpy(copy, 0, len, RARRAY_CONST_PTR_TRANSIENT(orig));
}
+#endif
+ /* Otherwise, orig is on heap and copy does not have enough space to embed
+ * the contents of orig. */
else {
VALUE shared_root = ary_make_shared(orig);
- if (ARY_OWNS_HEAP_P(copy)) {
- ary_heap_free(copy);
- }
- else {
- rb_ary_unshare_safe(copy);
- }
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
@@ -4525,8 +4781,10 @@ rb_ary_replace(VALUE copy, VALUE orig)
* array.clear -> self
*
* Removes all elements from +self+:
+ *
* a = [:foo, 'bar', 2]
* a.clear # => []
+ *
*/
VALUE
@@ -4534,11 +4792,11 @@ rb_ary_clear(VALUE ary)
{
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
- if (!ARY_EMBED_P(ary)) {
- rb_ary_unshare(ary);
- FL_SET_EMBED(ary);
+ if (!ARY_EMBED_P(ary)) {
+ rb_ary_unshare(ary);
+ FL_SET_EMBED(ary);
ARY_SET_EMBED_LEN(ary, 0);
- }
+ }
}
else {
ARY_SET_LEN(ary, 0);
@@ -4564,6 +4822,7 @@ rb_ary_clear(VALUE ary)
* Replaces specified elements in +self+ with specified objects; returns +self+.
*
* With argument +obj+ and no block given, replaces all elements with that one object:
+ *
* a = ['a', 'b', 'c', 'd']
* a # => ["a", "b", "c", "d"]
* a.fill(:X) # => [:X, :X, :X, :X]
@@ -4573,20 +4832,24 @@ rb_ary_clear(VALUE ary)
*
* If +start+ is in range (<tt>0 <= start < array.size</tt>),
* replaces all elements from offset +start+ through the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 2) # => ["a", "b", :X, :X]
*
* If +start+ is too large (<tt>start >= array.size</tt>), does nothing:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 4) # => ["a", "b", "c", "d"]
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 5) # => ["a", "b", "c", "d"]
*
* If +start+ is negative, counts from the end (starting index is <tt>start + array.size</tt>):
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, -2) # => ["a", "b", :X, :X]
*
* If +start+ is too small (less than and far from zero), replaces all elements:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, -6) # => [:X, :X, :X, :X]
* a = ['a', 'b', 'c', 'd']
@@ -4596,20 +4859,24 @@ rb_ary_clear(VALUE ary)
* replaces elements based on the given +start+ and +length+.
*
* If +start+ is in range, replaces +length+ elements beginning at offset +start+:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 1, 1) # => ["a", :X, "c", "d"]
*
* If +start+ is negative, counts from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, -2, 1) # => ["a", "b", :X, "d"]
*
* If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil]
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X]
*
* If +length+ is zero or negative, replaces no elements:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, 1, 0) # => ["a", "b", "c", "d"]
* a.fill(:X, 1, -1) # => ["a", "b", "c", "d"]
@@ -4619,14 +4886,17 @@ rb_ary_clear(VALUE ary)
*
* If the range is positive and ascending (<tt>0 < range.begin <= range.end</tt>),
* replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, (1..1)) # => ["a", :X, "c", "d"]
*
* If <tt>range.first</tt> is negative, replaces no elements:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"]
*
* If <tt>range.last</tt> is negative, counts from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"]
* a = ['a', 'b', 'c', 'd']
@@ -4634,6 +4904,7 @@ rb_ary_clear(VALUE ary)
*
* If <tt>range.last</tt> and <tt>range.last</tt> are both negative,
* both count from the end of the array:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X]
* a = ['a', 'b', 'c', 'd']
@@ -4641,29 +4912,34 @@ rb_ary_clear(VALUE ary)
*
* With no arguments and a block given, calls the block with each index;
* replaces the corresponding element with the block's return value:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
*
* With argument +start+ and a block given, calls the block with each index
* from offset +start+ to the end; replaces the corresponding element
- * with the block's return value:
+ * with the block's return value.
*
* If start is in range (<tt>0 <= start < array.size</tt>),
* replaces from offset +start+ to the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"]
*
* If +start+ is too large(<tt>start >= array.size</tt>), does nothing:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
* a = ['a', 'b', 'c', 'd']
* a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
*
* If +start+ is negative, counts from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"]
*
* If start is too small (<tt>start <= -array.size</tt>, replaces all elements:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
* a = ['a', 'b', 'c', 'd']
@@ -4674,20 +4950,24 @@ rb_ary_clear(VALUE ary)
* replaces the corresponding element with the block's return value.
*
* If +start+ is in range, replaces +length+ elements beginning at offset +start+:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
*
* If start is negative, counts from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
*
* If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil]
* a = ['a', 'b', 'c', 'd']
* a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"]
*
* If +length+ is zero or less, replaces no elements:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
* a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
@@ -4698,14 +4978,17 @@ rb_ary_clear(VALUE ary)
*
* If the range is positive and ascending (<tt>range 0 < range.begin <= range.end</tt>,
* replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
*
* If +range.first+ is negative, does nothing:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
*
* If <tt>range.last</tt> is negative, counts from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"]
* a = ['a', 'b', 'c', 'd']
@@ -4713,10 +4996,12 @@ rb_ary_clear(VALUE ary)
*
* If <tt>range.first</tt> and <tt>range.last</tt> are both negative,
* both count from the end:
+ *
* a = ['a', 'b', 'c', 'd']
* a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"]
* a = ['a', 'b', 'c', 'd']
* a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
+ *
*/
static VALUE
@@ -4726,59 +5011,59 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary)
long beg = 0, end = 0, len = 0;
if (rb_block_given_p()) {
- rb_scan_args(argc, argv, "02", &arg1, &arg2);
- argc += 1; /* hackish */
+ rb_scan_args(argc, argv, "02", &arg1, &arg2);
+ argc += 1; /* hackish */
}
else {
- rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
+ rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
}
switch (argc) {
case 1:
- beg = 0;
- len = RARRAY_LEN(ary);
- break;
+ beg = 0;
+ len = RARRAY_LEN(ary);
+ break;
case 2:
- if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
- break;
- }
- /* fall through */
+ if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
+ break;
+ }
+ /* fall through */
case 3:
- beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
- if (beg < 0) {
- beg = RARRAY_LEN(ary) + beg;
- if (beg < 0) beg = 0;
- }
- len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
- break;
+ beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
+ if (beg < 0) {
+ beg = RARRAY_LEN(ary) + beg;
+ if (beg < 0) beg = 0;
+ }
+ len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
+ break;
}
rb_ary_modify(ary);
if (len < 0) {
return ary;
}
if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
- rb_raise(rb_eArgError, "argument too big");
+ rb_raise(rb_eArgError, "argument too big");
}
end = beg + len;
if (RARRAY_LEN(ary) < end) {
- if (end >= ARY_CAPA(ary)) {
- ary_resize_capa(ary, end);
- }
- ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
- ARY_SET_LEN(ary, end);
+ if (end >= ARY_CAPA(ary)) {
+ ary_resize_capa(ary, end);
+ }
+ ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
+ ARY_SET_LEN(ary, end);
}
- if (item == Qundef) {
- VALUE v;
- long i;
+ if (UNDEF_P(item)) {
+ VALUE v;
+ long i;
- for (i=beg; i<end; i++) {
- v = rb_yield(LONG2NUM(i));
- if (i>=RARRAY_LEN(ary)) break;
- ARY_SET(ary, i, v);
- }
+ for (i=beg; i<end; i++) {
+ v = rb_yield(LONG2NUM(i));
+ if (i>=RARRAY_LEN(ary)) break;
+ ARY_SET(ary, i, v);
+ }
}
else {
- ary_memfill(ary, beg, len, item);
+ ary_memfill(ary, beg, len, item);
}
return ary;
}
@@ -4789,6 +5074,7 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary)
*
* Returns a new \Array containing all elements of +array+
* followed by all elements of +other_array+:
+ *
* a = [0, 1] + [2, 3]
* a # => [0, 1, 2, 3]
*
@@ -4820,6 +5106,7 @@ ary_append(VALUE x, VALUE y)
if (n > 0) {
rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR_TRANSIENT(y), n);
}
+ RB_GC_GUARD(y);
return x;
}
@@ -4828,6 +5115,7 @@ ary_append(VALUE x, VALUE y)
* array.concat(*other_arrays) -> self
*
* Adds to +array+ all elements from each \Array in +other_arrays+; returns +self+:
+ *
* a = [0, 1]
* a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]
*/
@@ -4838,15 +5126,15 @@ rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
rb_ary_modify_check(ary);
if (argc == 1) {
- rb_ary_concat(ary, argv[0]);
+ rb_ary_concat(ary, argv[0]);
}
else if (argc > 1) {
- int i;
- VALUE args = rb_ary_tmp_new(argc);
- for (i = 0; i < argc; i++) {
- rb_ary_concat(args, argv[i]);
- }
- ary_append(ary, args);
+ int i;
+ VALUE args = rb_ary_hidden_new(argc);
+ for (i = 0; i < argc; i++) {
+ rb_ary_concat(args, argv[i]);
+ }
+ ary_append(ary, args);
}
ary_verify(ary);
@@ -4866,12 +5154,15 @@ rb_ary_concat(VALUE x, VALUE y)
*
* When non-negative argument \Integer +n+ is given,
* returns a new \Array built by concatenating the +n+ copies of +self+:
+ *
* a = ['x', 'y']
* a * 3 # => ["x", "y", "x", "y", "x", "y"]
*
* When \String argument +string_separator+ is given,
* equivalent to <tt>array.join(string_separator)</tt>:
+ *
* [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
+ *
*/
static VALUE
@@ -4883,19 +5174,19 @@ rb_ary_times(VALUE ary, VALUE times)
tmp = rb_check_string_type(times);
if (!NIL_P(tmp)) {
- return rb_ary_join(ary, tmp);
+ return rb_ary_join(ary, tmp);
}
len = NUM2LONG(times);
if (len == 0) {
ary2 = ary_new(rb_cArray, 0);
- goto out;
+ goto out;
}
if (len < 0) {
- rb_raise(rb_eArgError, "negative argument");
+ rb_raise(rb_eArgError, "negative argument");
}
if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
- rb_raise(rb_eArgError, "argument too big");
+ rb_raise(rb_eArgError, "argument too big");
}
len *= RARRAY_LEN(ary);
@@ -4905,8 +5196,8 @@ rb_ary_times(VALUE ary, VALUE times)
ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
t = RARRAY_LEN(ary);
if (0 < t) {
- ary_memcpy(ary2, 0, t, ptr);
- while (t <= len/2) {
+ ary_memcpy(ary2, 0, t, ptr);
+ while (t <= len/2) {
ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2));
t *= 2;
}
@@ -4924,6 +5215,7 @@ rb_ary_times(VALUE ary, VALUE times)
*
* Returns the first element in +self+ that is an \Array
* whose first element <tt>==</tt> +obj+:
+ *
* a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
* a.assoc(4) # => [4, 5, 6]
*
@@ -4939,10 +5231,10 @@ rb_ary_assoc(VALUE ary, VALUE key)
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
- v = rb_check_array_type(RARRAY_AREF(ary, i));
- if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
- rb_equal(RARRAY_AREF(v, 0), key))
- return v;
+ v = rb_check_array_type(RARRAY_AREF(ary, i));
+ if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
+ rb_equal(RARRAY_AREF(v, 0), key))
+ return v;
}
return Qnil;
}
@@ -4953,6 +5245,7 @@ rb_ary_assoc(VALUE ary, VALUE key)
*
* Returns the first element in +self+ that is an \Array
* whose second element <tt>==</tt> +obj+:
+ *
* a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
* a.rassoc(4) # => [2, 4]
*
@@ -4968,11 +5261,11 @@ rb_ary_rassoc(VALUE ary, VALUE value)
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
- v = RARRAY_AREF(ary, i);
- if (RB_TYPE_P(v, T_ARRAY) &&
- RARRAY_LEN(v) > 1 &&
- rb_equal(RARRAY_AREF(v, 1), value))
- return v;
+ v = RARRAY_AREF(ary, i);
+ if (RB_TYPE_P(v, T_ARRAY) &&
+ RARRAY_LEN(v) > 1 &&
+ rb_equal(RARRAY_AREF(v, 1), value))
+ return v;
}
return Qnil;
}
@@ -4991,22 +5284,22 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
len1 = RARRAY_LEN(ary1);
for (i = 0; i < len1; i++) {
- if (*p1 != *p2) {
- if (rb_equal(*p1, *p2)) {
- len1 = RARRAY_LEN(ary1);
- if (len1 != RARRAY_LEN(ary2))
- return Qfalse;
- if (len1 < i)
- return Qtrue;
+ if (*p1 != *p2) {
+ if (rb_equal(*p1, *p2)) {
+ len1 = RARRAY_LEN(ary1);
+ if (len1 != RARRAY_LEN(ary2))
+ return Qfalse;
+ if (len1 < i)
+ return Qtrue;
p1 = RARRAY_CONST_PTR(ary1) + i;
p2 = RARRAY_CONST_PTR(ary2) + i;
- }
- else {
- return Qfalse;
- }
- }
- p1++;
- p2++;
+ }
+ else {
+ return Qfalse;
+ }
+ }
+ p1++;
+ p2++;
}
return Qtrue;
}
@@ -5017,6 +5310,7 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur)
*
* Returns +true+ if both <tt>array.size == other_array.size</tt>
* and for each index +i+ in +array+, <tt>array[i] == other_array[i]</tt>:
+ *
* a0 = [:foo, 'bar', 2]
* a1 = [:foo, 'bar', 2.0]
* a1 == a0 # => true
@@ -5033,10 +5327,10 @@ rb_ary_equal(VALUE ary1, VALUE ary2)
{
if (ary1 == ary2) return Qtrue;
if (!RB_TYPE_P(ary2, T_ARRAY)) {
- if (!rb_respond_to(ary2, idTo_ary)) {
- return Qfalse;
- }
- return rb_equal(ary2, ary1);
+ if (!rb_respond_to(ary2, idTo_ary)) {
+ return Qfalse;
+ }
+ return rb_equal(ary2, ary1);
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
@@ -5050,8 +5344,8 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur)
if (recur) return Qtrue; /* Subtle! */
for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
- return Qfalse;
+ if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
+ return Qfalse;
}
return Qtrue;
}
@@ -5062,13 +5356,14 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur)
*
* Returns +true+ if +self+ and +other_array+ are the same size,
* and if, for each index +i+ in +self+, <tt>self[i].eql? other_array[i]</tt>:
+ *
* a0 = [:foo, 'bar', 2]
* a1 = [:foo, 'bar', 2]
* a1.eql?(a0) # => true
*
* Otherwise, returns +false+.
*
- * This method is different from method {Array#==}[#method-i-3D-3D],
+ * This method is different from method Array#==,
* which compares using method <tt>Object#==</tt>.
*/
@@ -5089,8 +5384,10 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
* Returns the integer hash value for +self+.
*
* Two arrays with the same content will have the same hash code (and will compare using eql?):
+ *
* [0, 1, 2].hash == [0, 1, 2].hash # => true
* [0, 1, 2].hash == [0, 1, 3].hash # => false
+ *
*/
static VALUE
@@ -5103,8 +5400,8 @@ rb_ary_hash(VALUE ary)
h = rb_hash_start(RARRAY_LEN(ary));
h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
for (i=0; i<RARRAY_LEN(ary); i++) {
- n = rb_hash(RARRAY_AREF(ary, i));
- h = rb_hash_uint(h, NUM2LONG(n));
+ n = rb_hash(RARRAY_AREF(ary, i));
+ h = rb_hash_uint(h, NUM2LONG(n));
}
h = rb_hash_end(h);
return ST2FIX(h);
@@ -5116,6 +5413,7 @@ rb_ary_hash(VALUE ary)
*
* Returns +true+ if for some index +i+ in +self+, <tt>obj == self[i]</tt>;
* otherwise +false+:
+ *
* [0, 1, 2].include?(2) # => true
* [0, 1, 2].include?(3) # => false
*/
@@ -5127,10 +5425,10 @@ rb_ary_includes(VALUE ary, VALUE item)
VALUE e;
for (i=0; i<RARRAY_LEN(ary); i++) {
- e = RARRAY_AREF(ary, i);
- if (rb_equal(e, item)) {
- return Qtrue;
- }
+ e = RARRAY_AREF(ary, i);
+ if (rb_equal(e, item)) {
+ return Qtrue;
+ }
}
return Qfalse;
}
@@ -5142,10 +5440,10 @@ rb_ary_includes_by_eql(VALUE ary, VALUE item)
VALUE e;
for (i=0; i<RARRAY_LEN(ary); i++) {
- e = RARRAY_AREF(ary, i);
- if (rb_eql(item, e)) {
- return Qtrue;
- }
+ e = RARRAY_AREF(ary, i);
+ if (rb_eql(item, e)) {
+ return Qtrue;
+ }
}
return Qfalse;
}
@@ -5158,14 +5456,14 @@ recursive_cmp(VALUE ary1, VALUE ary2, int recur)
if (recur) return Qundef; /* Subtle! */
len = RARRAY_LEN(ary1);
if (len > RARRAY_LEN(ary2)) {
- len = RARRAY_LEN(ary2);
+ len = RARRAY_LEN(ary2);
}
for (i=0; i<len; i++) {
- VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
- VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
- if (v != INT2FIX(0)) {
- return v;
- }
+ VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
+ VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
+ if (v != INT2FIX(0)) {
+ return v;
+ }
}
return Qundef;
}
@@ -5178,18 +5476,27 @@ recursive_cmp(VALUE ary1, VALUE ary2, int recur)
* For each index +i+ in +self+, evaluates <tt>result = self[i] <=> other_array[i]</tt>.
*
* Returns -1 if any result is -1:
+ *
* [0, 1, 2] <=> [0, 1, 3] # => -1
*
* Returns 1 if any result is 1:
+ *
* [0, 1, 2] <=> [0, 1, 1] # => 1
*
* When all results are zero:
+ *
* - Returns -1 if +array+ is smaller than +other_array+:
+ *
* [0, 1, 2] <=> [0, 1, 2, 3] # => -1
+ *
* - Returns 1 if +array+ is larger than +other_array+:
+ *
* [0, 1, 2] <=> [0, 1] # => 1
+ *
* - Returns 0 if +array+ and +other_array+ are the same size:
+ *
* [0, 1, 2] <=> [0, 1, 2] # => 0
+ *
*/
VALUE
@@ -5202,7 +5509,7 @@ rb_ary_cmp(VALUE ary1, VALUE ary2)
if (NIL_P(ary2)) return Qnil;
if (ary1 == ary2) return INT2FIX(0);
v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
- if (v != Qundef) return v;
+ if (!UNDEF_P(v)) return v;
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
if (len == 0) return INT2FIX(0);
if (len > 0) return INT2FIX(1);
@@ -5215,8 +5522,8 @@ ary_add_hash(VALUE hash, VALUE ary)
long i;
for (i=0; i<RARRAY_LEN(ary); i++) {
- VALUE elt = RARRAY_AREF(ary, i);
- rb_hash_add_new_element(hash, elt, elt);
+ VALUE elt = RARRAY_AREF(ary, i);
+ rb_hash_add_new_element(hash, elt, elt);
}
return hash;
}
@@ -5244,8 +5551,8 @@ ary_add_hash_by(VALUE hash, VALUE ary)
long i;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
- VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
- rb_hash_add_new_element(hash, k, v);
+ VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
+ rb_hash_add_new_element(hash, k, v);
}
return hash;
}
@@ -5263,7 +5570,7 @@ ary_recycle_hash(VALUE hash)
assert(RBASIC_CLASS(hash) == 0);
if (RHASH_ST_TABLE_P(hash)) {
st_table *tbl = RHASH_ST_TABLE(hash);
- st_free_table(tbl);
+ st_free_table(tbl);
RHASH_ST_CLEAR(hash);
}
}
@@ -5276,6 +5583,7 @@ ary_recycle_hash(VALUE hash)
* that are not found in \Array +other_array+;
* items are compared using <tt>eql?</tt>;
* the order from +array+ is preserved:
+ *
* [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3]
* [0, 1, 2, 3] - [3, 0] # => [1, 2]
* [0, 1, 2] - [4] # => [0, 1, 2]
@@ -5283,7 +5591,7 @@ ary_recycle_hash(VALUE hash)
* Related: Array#difference.
*/
-static VALUE
+VALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
VALUE ary3;
@@ -5291,21 +5599,22 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
long i;
ary2 = to_ary(ary2);
+ if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
ary3 = rb_ary_new();
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
- for (i=0; i<RARRAY_LEN(ary1); i++) {
- VALUE elt = rb_ary_elt(ary1, i);
- if (rb_ary_includes_by_eql(ary2, elt)) continue;
- rb_ary_push(ary3, elt);
- }
- return ary3;
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ VALUE elt = rb_ary_elt(ary1, i);
+ if (rb_ary_includes_by_eql(ary2, elt)) continue;
+ rb_ary_push(ary3, elt);
+ }
+ return ary3;
}
hash = ary_make_hash(ary2);
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
- rb_ary_push(ary3, rb_ary_elt(ary1, i));
+ rb_ary_push(ary3, rb_ary_elt(ary1, i));
}
ary_recycle_hash(hash);
return ary3;
@@ -5318,6 +5627,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
* Returns a new \Array containing only those elements from +self+
* that are not found in any of the Arrays +other_arrays+;
* items are compared using <tt>eql?</tt>; order from +self+ is preserved:
+ *
* [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3]
* [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2]
* [0, 1, 2].difference([4]) # => [0, 1, 2]
@@ -5370,10 +5680,12 @@ rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
*
* Returns a new \Array containing each element found in both +array+ and \Array +other_array+;
* duplicates are omitted; items are compared using <tt>eql?</tt>:
+ *
* [0, 1, 2, 3] & [1, 2] # => [1, 2]
* [0, 1, 0, 1] & [0, 1] # => [0, 1]
*
* Preserves order from +array+:
+ *
* [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
*
* Related: Array#intersection.
@@ -5392,23 +5704,23 @@ rb_ary_and(VALUE ary1, VALUE ary2)
if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
- for (i=0; i<RARRAY_LEN(ary1); i++) {
- v = RARRAY_AREF(ary1, i);
- if (!rb_ary_includes_by_eql(ary2, v)) continue;
- if (rb_ary_includes_by_eql(ary3, v)) continue;
- rb_ary_push(ary3, v);
- }
- return ary3;
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ v = RARRAY_AREF(ary1, i);
+ if (!rb_ary_includes_by_eql(ary2, v)) continue;
+ if (rb_ary_includes_by_eql(ary3, v)) continue;
+ rb_ary_push(ary3, v);
+ }
+ return ary3;
}
hash = ary_make_hash(ary2);
for (i=0; i<RARRAY_LEN(ary1); i++) {
- v = RARRAY_AREF(ary1, i);
- vv = (st_data_t)v;
+ v = RARRAY_AREF(ary1, i);
+ vv = (st_data_t)v;
if (rb_hash_stlike_delete(hash, &vv, 0)) {
- rb_ary_push(ary3, v);
- }
+ rb_ary_push(ary3, v);
+ }
}
ary_recycle_hash(hash);
@@ -5422,10 +5734,12 @@ rb_ary_and(VALUE ary1, VALUE ary2)
* Returns a new \Array containing each element found both in +self+
* and in all of the given Arrays +other_arrays+;
* duplicates are omitted; items are compared using <tt>eql?</tt>:
+ *
* [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
* [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
*
* Preserves order from +self+:
+ *
* [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
*
* Returns a copy of +self+ if no arguments given.
@@ -5484,6 +5798,7 @@ rb_ary_union_hash(VALUE hash, VALUE ary2)
* Returns the union of +array+ and \Array +other_array+;
* duplicates are removed; order is preserved;
* items are compared using <tt>eql?</tt>:
+ *
* [0, 1] | [2, 3] # => [0, 1, 2, 3]
* [0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3]
* [0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3]
@@ -5498,10 +5813,10 @@ rb_ary_or(VALUE ary1, VALUE ary2)
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
- ary3 = rb_ary_new();
+ ary3 = rb_ary_new();
rb_ary_union(ary3, ary1);
rb_ary_union(ary3, ary2);
- return ary3;
+ return ary3;
}
hash = ary_make_hash(ary1);
@@ -5518,6 +5833,7 @@ rb_ary_or(VALUE ary1, VALUE ary2)
*
* Returns a new \Array that is the union of +self+ and all given Arrays +other_arrays+;
* duplicates are removed; order is preserved; items are compared using <tt>eql?</tt>:
+ *
* [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
* [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
* [0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]
@@ -5557,6 +5873,62 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
return ary_union;
}
+/*
+ * call-seq:
+ * ary.intersect?(other_ary) -> true or false
+ *
+ * Returns +true+ if the array and +other_ary+ have at least one element in
+ * common, otherwise returns +false+:
+ *
+ * a = [ 1, 2, 3 ]
+ * b = [ 3, 4, 5 ]
+ * c = [ 5, 6, 7 ]
+ * a.intersect?(b) #=> true
+ * a.intersect?(c) #=> false
+ *
+ */
+
+static VALUE
+rb_ary_intersect_p(VALUE ary1, VALUE ary2)
+{
+ VALUE hash, v, result, shorter, longer;
+ st_data_t vv;
+ long i;
+
+ ary2 = to_ary(ary2);
+ if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;
+
+ if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ v = RARRAY_AREF(ary1, i);
+ if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
+ }
+ return Qfalse;
+ }
+
+ shorter = ary1;
+ longer = ary2;
+ if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
+ longer = ary1;
+ shorter = ary2;
+ }
+
+ hash = ary_make_hash(shorter);
+ result = Qfalse;
+
+ for (i=0; i<RARRAY_LEN(longer); i++) {
+ v = RARRAY_AREF(longer, i);
+ vv = (st_data_t)v;
+ if (rb_hash_stlike_lookup(hash, vv, 0)) {
+ result = Qtrue;
+ break;
+ }
+ }
+ ary_recycle_hash(hash);
+
+ return result;
+}
+
static VALUE
ary_max_generic(VALUE ary, long i, VALUE vmax)
{
@@ -5654,6 +6026,7 @@ ary_max_opt_string(VALUE ary, long i, VALUE vmax)
* array.max(n) {|a, b| ... } -> new_array
*
* Returns one of the following:
+ *
* - The maximum-valued element from +self+.
* - A new \Array of maximum-valued elements selected from +self+.
*
@@ -5662,27 +6035,31 @@ ary_max_opt_string(VALUE ary, long i, VALUE vmax)
*
* With no argument and no block, returns the element in +self+
* having the maximum value per method <tt><=></tt>:
+ *
* [0, 1, 2].max # => 2
*
* With an argument \Integer +n+ and no block, returns a new \Array with at most +n+ elements,
* in descending order per method <tt><=></tt>:
+ *
* [0, 1, 2, 3].max(3) # => [3, 2, 1]
- * [0, 1, 2, 3].max(6) # => [3, 2, 1]
+ * [0, 1, 2, 3].max(6) # => [3, 2, 1, 0]
*
* When a block is given, the block must return an \Integer.
*
* With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements;
* returns the element having the maximum value per the block:
+ *
* ['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000"
*
* With an argument +n+ and a block, returns a new \Array with at most +n+ elements,
* in descending order per the block:
+ *
* ['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"]
+ *
*/
static VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
- struct cmp_opt_data cmp_opt = { 0, 0 };
VALUE result = Qundef, v;
VALUE num;
long i;
@@ -5692,23 +6069,23 @@ rb_ary_max(int argc, VALUE *argv, VALUE ary)
const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
- result = v;
- }
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
+ result = v;
+ }
+ }
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
- if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_max_opt_fixnum(ary, 1, result);
}
- else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
+ else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_max_opt_string(ary, 1, result);
}
- else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
+ else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_max_opt_float(ary, 1, result);
}
else {
@@ -5716,7 +6093,7 @@ rb_ary_max(int argc, VALUE *argv, VALUE ary)
}
}
}
- if (result == Qundef) return Qnil;
+ if (UNDEF_P(result)) return Qnil;
return result;
}
@@ -5817,6 +6194,7 @@ ary_min_opt_string(VALUE ary, long i, VALUE vmin)
* array.min(n) { |a, b| ... } -> new_array
*
* Returns one of the following:
+ *
* - The minimum-valued element from +self+.
* - A new \Array of minimum-valued elements selected from +self+.
*
@@ -5825,10 +6203,12 @@ ary_min_opt_string(VALUE ary, long i, VALUE vmin)
*
* With no argument and no block, returns the element in +self+
* having the minimum value per method <tt><=></tt>:
+ *
* [0, 1, 2].min # => 0
*
* With \Integer argument +n+ and no block, returns a new \Array with at most +n+ elements,
* in ascending order per method <tt><=></tt>:
+ *
* [0, 1, 2, 3].min(3) # => [0, 1, 2]
* [0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
*
@@ -5836,17 +6216,18 @@ ary_min_opt_string(VALUE ary, long i, VALUE vmin)
*
* With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements;
* returns the element having the minimum value per the block:
+ *
* ['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0"
*
* With an argument +n+ and a block, returns a new \Array with at most +n+ elements,
* in ascending order per the block:
- * [0, 1, 2, 3].min(3) # => [0, 1, 2]
- * [0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
+ *
+ * ['0', '00', '000'].min(2) {|a, b| a.size <=> b.size } # => ["0", "00"]
+ *
*/
static VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
{
- struct cmp_opt_data cmp_opt = { 0, 0 };
VALUE result = Qundef, v;
VALUE num;
long i;
@@ -5856,23 +6237,23 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
- result = v;
- }
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
+ result = v;
+ }
+ }
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
- if (FIXNUM_P(result) && CMP_OPTIMIZABLE(cmp_opt, Integer)) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_min_opt_fixnum(ary, 1, result);
}
- else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
+ else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_min_opt_string(ary, 1, result);
}
- else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
+ else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_min_opt_float(ary, 1, result);
}
else {
@@ -5880,7 +6261,7 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
}
}
}
- if (result == Qundef) return Qnil;
+ if (UNDEF_P(result)) return Qnil;
return result;
}
@@ -5896,13 +6277,16 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
* with an \Integer;
* returns a new 2-element \Array containing the minimum and maximum values
* from +self+, per method <tt><=></tt>:
+ *
* [0, 1, 2].minmax # => [0, 2]
*
* When a block is given, the block must return an \Integer;
* the block is called <tt>self.size-1</tt> times to compare elements;
* returns a new 2-element \Array containing the minimum and maximum values
* from +self+, per the block:
+ *
* ['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"]
+ *
*/
static VALUE
rb_ary_minmax(VALUE ary)
@@ -5932,6 +6316,7 @@ push_value(st_data_t key, st_data_t val, st_data_t ary)
* to compare.
*
* Returns +self+ if any elements removed:
+ *
* a = [0, 0, 1, 1, 2, 2]
* a.uniq! # => [0, 1, 2]
*
@@ -5942,6 +6327,7 @@ push_value(st_data_t key, st_data_t val, st_data_t ary)
* elements for which the block returns duplicate values.
*
* Returns +self+ if any elements removed:
+ *
* a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
* a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa']
*
@@ -5957,19 +6343,19 @@ rb_ary_uniq_bang(VALUE ary)
if (RARRAY_LEN(ary) <= 1)
return Qnil;
if (rb_block_given_p())
- hash = ary_make_hash_by(ary);
+ hash = ary_make_hash_by(ary);
else
- hash = ary_make_hash(ary);
+ hash = ary_make_hash(ary);
hash_size = RHASH_SIZE(hash);
if (RARRAY_LEN(ary) == hash_size) {
- return Qnil;
+ return Qnil;
}
rb_ary_modify_check(ary);
ARY_SET_LEN(ary, 0);
if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
- rb_ary_unshare(ary);
- FL_SET_EMBED(ary);
+ rb_ary_unshare(ary);
+ FL_SET_EMBED(ary);
}
ary_resize_capa(ary, hash_size);
rb_hash_foreach(hash, push_value, ary);
@@ -5987,15 +6373,18 @@ rb_ary_uniq_bang(VALUE ary)
* the first occurrence always being retained.
*
* With no block given, identifies and omits duplicates using method <tt>eql?</tt>
- * to compare.
+ * to compare:
+ *
* a = [0, 0, 1, 1, 2, 2]
* a.uniq # => [0, 1, 2]
*
* With a block given, calls the block for each element;
* identifies (using method <tt>eql?</tt>) and omits duplicate values,
* that is, those elements for which the block returns the same value:
+ *
* a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
* a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
+ *
*/
static VALUE
@@ -6008,12 +6397,12 @@ rb_ary_uniq(VALUE ary)
uniq = rb_ary_dup(ary);
}
else if (rb_block_given_p()) {
- hash = ary_make_hash_by(ary);
- uniq = rb_hash_values(hash);
+ hash = ary_make_hash_by(ary);
+ uniq = rb_hash_values(hash);
}
else {
- hash = ary_make_hash(ary);
- uniq = rb_hash_values(hash);
+ hash = ary_make_hash(ary);
+ uniq = rb_hash_values(hash);
}
if (hash) {
ary_recycle_hash(hash);
@@ -6042,12 +6431,12 @@ rb_ary_compact_bang(VALUE ary)
end = p + RARRAY_LEN(ary);
while (t < end) {
- if (NIL_P(*t)) t++;
- else *p++ = *t++;
+ if (NIL_P(*t)) t++;
+ else *p++ = *t++;
}
n = p - RARRAY_CONST_PTR_TRANSIENT(ary);
if (RARRAY_LEN(ary) == n) {
- return Qnil;
+ return Qnil;
}
ary_resize_smaller(ary, n);
@@ -6059,6 +6448,7 @@ rb_ary_compact_bang(VALUE ary)
* array.compact -> new_array
*
* Returns a new \Array containing all non-+nil+ elements from +self+:
+ *
* a = [nil, 0, nil, 1, nil, 2, nil]
* a.compact # => [0, 1, 2]
*/
@@ -6080,19 +6470,22 @@ rb_ary_compact(VALUE ary)
* Returns a count of specified elements.
*
* With no argument and no block, returns the count of all elements:
+ *
* [0, 1, 2].count # => 3
* [].count # => 0
*
- * With argument +obj+, returns the count of elements <tt>eql?</tt> to +obj+:
- * [0, 1, 2, 0].count(0) # => 2
+ * With argument +obj+, returns the count of elements <tt>==</tt> to +obj+:
+ *
+ * [0, 1, 2, 0.0].count(0) # => 2
* [0, 1, 2].count(3) # => 0
*
* With no argument and a block given, calls the block with each element;
* returns the count of elements for which the block returns a truthy value:
+ *
* [0, 1, 2, 3].count {|element| element > 1} # => 2
*
* With argument +obj+ and a block given, issues a warning, ignores the block,
- * and returns the count of elements <tt>eql?</tt> to +obj+:
+ * and returns the count of elements <tt>==</tt> to +obj+.
*/
static VALUE
@@ -6101,25 +6494,25 @@ rb_ary_count(int argc, VALUE *argv, VALUE ary)
long i, n = 0;
if (rb_check_arity(argc, 0, 1) == 0) {
- VALUE v;
+ VALUE v;
- if (!rb_block_given_p())
- return LONG2NUM(RARRAY_LEN(ary));
+ if (!rb_block_given_p())
+ return LONG2NUM(RARRAY_LEN(ary));
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (RTEST(rb_yield(v))) n++;
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ v = RARRAY_AREF(ary, i);
+ if (RTEST(rb_yield(v))) n++;
+ }
}
else {
VALUE obj = argv[0];
- if (rb_block_given_p()) {
- rb_warn("given block not used");
- }
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
- }
+ if (rb_block_given_p()) {
+ rb_warn("given block not used");
+ }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
+ }
}
return LONG2NUM(n);
@@ -6153,64 +6546,64 @@ flatten(VALUE ary, int level)
rb_ary_push(stack, LONG2NUM(i + 1));
if (level < 0) {
- vmemo = rb_hash_new();
- RBASIC_CLEAR_CLASS(vmemo);
- memo = st_init_numtable();
- rb_hash_st_table_set(vmemo, memo);
- st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
- st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue);
+ vmemo = rb_hash_new();
+ RBASIC_CLEAR_CLASS(vmemo);
+ memo = st_init_numtable();
+ rb_hash_st_table_set(vmemo, memo);
+ st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
+ st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue);
}
ary = tmp;
i = 0;
while (1) {
- while (i < RARRAY_LEN(ary)) {
- elt = RARRAY_AREF(ary, i++);
- if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
- rb_ary_push(result, elt);
- continue;
- }
- tmp = rb_check_array_type(elt);
- if (RBASIC(result)->klass) {
- if (memo) {
- RB_GC_GUARD(vmemo);
- st_clear(memo);
- }
- rb_raise(rb_eRuntimeError, "flatten reentered");
- }
- if (NIL_P(tmp)) {
- rb_ary_push(result, elt);
- }
- else {
- if (memo) {
- id = (st_data_t)tmp;
- if (st_is_member(memo, id)) {
- st_clear(memo);
- rb_raise(rb_eArgError, "tried to flatten recursive array");
- }
- st_insert(memo, id, (st_data_t)Qtrue);
- }
- rb_ary_push(stack, ary);
- rb_ary_push(stack, LONG2NUM(i));
- ary = tmp;
- i = 0;
- }
- }
- if (RARRAY_LEN(stack) == 0) {
- break;
- }
- if (memo) {
- id = (st_data_t)ary;
- st_delete(memo, &id, 0);
- }
- tmp = rb_ary_pop(stack);
- i = NUM2LONG(tmp);
- ary = rb_ary_pop(stack);
+ while (i < RARRAY_LEN(ary)) {
+ elt = RARRAY_AREF(ary, i++);
+ if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
+ rb_ary_push(result, elt);
+ continue;
+ }
+ tmp = rb_check_array_type(elt);
+ if (RBASIC(result)->klass) {
+ if (memo) {
+ RB_GC_GUARD(vmemo);
+ st_clear(memo);
+ }
+ rb_raise(rb_eRuntimeError, "flatten reentered");
+ }
+ if (NIL_P(tmp)) {
+ rb_ary_push(result, elt);
+ }
+ else {
+ if (memo) {
+ id = (st_data_t)tmp;
+ if (st_is_member(memo, id)) {
+ st_clear(memo);
+ rb_raise(rb_eArgError, "tried to flatten recursive array");
+ }
+ st_insert(memo, id, (st_data_t)Qtrue);
+ }
+ rb_ary_push(stack, ary);
+ rb_ary_push(stack, LONG2NUM(i));
+ ary = tmp;
+ i = 0;
+ }
+ }
+ if (RARRAY_LEN(stack) == 0) {
+ break;
+ }
+ if (memo) {
+ id = (st_data_t)ary;
+ st_delete(memo, &id, 0);
+ }
+ tmp = rb_ary_pop(stack);
+ i = NUM2LONG(tmp);
+ ary = rb_ary_pop(stack);
}
if (memo) {
- st_clear(memo);
+ st_clear(memo);
}
RBASIC_SET_CLASS(result, rb_cArray);
@@ -6226,6 +6619,7 @@ flatten(VALUE ary, int level)
* returns +self+ if any changes, +nil+ otherwise.
*
* With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
+ *
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
@@ -6235,6 +6629,7 @@ flatten(VALUE ary, int level)
* [0, 1, 2].flatten!(1) # => nil
*
* With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels:
+ *
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten! # => [0, 1, 2, 3, 4, 5]
* [0, 1, 2].flatten! # => nil
@@ -6243,6 +6638,7 @@ flatten(VALUE ary, int level)
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten!(-2) # => [0, 1, 2, 3, 4, 5]
* [0, 1, 2].flatten!(-1) # => nil
+ *
*/
static VALUE
@@ -6258,7 +6654,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
result = flatten(ary, level);
if (result == ary) {
- return Qnil;
+ return Qnil;
}
if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
rb_ary_replace(ary, result);
@@ -6277,6 +6673,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
* - Each \Array is replaced by its individual elements.
*
* With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
+ *
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten(0) # => [0, [1, [2, 3], 4], 5]
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
@@ -6287,6 +6684,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
* a.flatten(3) # => [0, 1, 2, 3, 4, 5]
*
* With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels:
+ *
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten # => [0, 1, 2, 3, 4, 5]
* [0, 1, 2].flatten # => [0, 1, 2]
@@ -6295,6 +6693,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
* a = [ 0, [ 1, [2, 3], 4 ], 5 ]
* a.flatten(-2) # => [0, 1, 2, 3, 4, 5]
* [0, 1, 2].flatten(-1) # => [0, 1, 2]
+ *
*/
static VALUE
@@ -6326,16 +6725,16 @@ rb_ary_shuffle_bang(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
rb_ary_modify(ary);
i = len = RARRAY_LEN(ary);
RARRAY_PTR_USE(ary, ptr, {
- while (i) {
- long j = RAND_UPTO(i);
- VALUE tmp;
+ while (i) {
+ long j = RAND_UPTO(i);
+ VALUE tmp;
if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR_TRANSIENT(ary)) {
rb_raise(rb_eRuntimeError, "modified during shuffle");
- }
- tmp = ptr[--i];
- ptr[i] = ptr[j];
- ptr[j] = tmp;
- }
+ }
+ tmp = ptr[--i];
+ ptr[i] = ptr[j];
+ ptr[j] = tmp;
+ }
}); /* WB: no new reference */
return ary;
}
@@ -6349,7 +6748,7 @@ rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
}
static VALUE
-rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
+ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
{
VALUE result;
long n, len, i, j, k, idx[10];
@@ -6358,120 +6757,120 @@ rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VA
len = RARRAY_LEN(ary);
if (!to_array) {
- if (len < 2)
- i = 0;
- else
- i = RAND_UPTO(len);
+ if (len < 2)
+ i = 0;
+ else
+ i = RAND_UPTO(len);
- return rb_ary_elt(ary, i);
+ return rb_ary_elt(ary, i);
}
n = NUM2LONG(nv);
if (n < 0) rb_raise(rb_eArgError, "negative sample number");
if (n > len) n = len;
if (n <= numberof(idx)) {
- for (i = 0; i < n; ++i) {
- rnds[i] = RAND_UPTO(len - i);
- }
+ for (i = 0; i < n; ++i) {
+ rnds[i] = RAND_UPTO(len - i);
+ }
}
k = len;
len = RARRAY_LEN(ary);
if (len < k && n <= numberof(idx)) {
- for (i = 0; i < n; ++i) {
- if (rnds[i] >= len) return rb_ary_new_capa(0);
- }
+ for (i = 0; i < n; ++i) {
+ if (rnds[i] >= len) return rb_ary_new_capa(0);
+ }
}
if (n > len) n = len;
switch (n) {
case 0:
- return rb_ary_new_capa(0);
+ return rb_ary_new_capa(0);
case 1:
- i = rnds[0];
- return rb_ary_new_from_args(1, RARRAY_AREF(ary, i));
+ i = rnds[0];
+ return rb_ary_new_from_args(1, RARRAY_AREF(ary, i));
case 2:
- i = rnds[0];
- j = rnds[1];
- if (j >= i) j++;
- return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
+ i = rnds[0];
+ j = rnds[1];
+ if (j >= i) j++;
+ return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
case 3:
- i = rnds[0];
- j = rnds[1];
- k = rnds[2];
- {
- long l = j, g = i;
- if (j >= i) l = i, g = ++j;
- if (k >= l && (++k >= g)) ++k;
- }
- return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
+ i = rnds[0];
+ j = rnds[1];
+ k = rnds[2];
+ {
+ long l = j, g = i;
+ if (j >= i) l = i, g = ++j;
+ if (k >= l && (++k >= g)) ++k;
+ }
+ return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
}
memo_threshold =
- len < 2560 ? len / 128 :
- len < 5120 ? len / 64 :
- len < 10240 ? len / 32 :
- len / 16;
+ len < 2560 ? len / 128 :
+ len < 5120 ? len / 64 :
+ len < 10240 ? len / 32 :
+ len / 16;
if (n <= numberof(idx)) {
- long sorted[numberof(idx)];
- sorted[0] = idx[0] = rnds[0];
- for (i=1; i<n; i++) {
- k = rnds[i];
- for (j = 0; j < i; ++j) {
- if (k < sorted[j]) break;
- ++k;
- }
- memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
- sorted[j] = idx[i] = k;
- }
- result = rb_ary_new_capa(n);
+ long sorted[numberof(idx)];
+ sorted[0] = idx[0] = rnds[0];
+ for (i=1; i<n; i++) {
+ k = rnds[i];
+ for (j = 0; j < i; ++j) {
+ if (k < sorted[j]) break;
+ ++k;
+ }
+ memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
+ sorted[j] = idx[i] = k;
+ }
+ result = rb_ary_new_capa(n);
RARRAY_PTR_USE_TRANSIENT(result, ptr_result, {
- for (i=0; i<n; i++) {
- ptr_result[i] = RARRAY_AREF(ary, idx[i]);
- }
- });
+ for (i=0; i<n; i++) {
+ ptr_result[i] = RARRAY_AREF(ary, idx[i]);
+ }
+ });
}
else if (n <= memo_threshold / 2) {
- long max_idx = 0;
+ long max_idx = 0;
#undef RUBY_UNTYPED_DATA_WARNING
#define RUBY_UNTYPED_DATA_WARNING 0
- VALUE vmemo = Data_Wrap_Struct(0, 0, st_free_table, 0);
- st_table *memo = st_init_numtable_with_size(n);
- DATA_PTR(vmemo) = memo;
- result = rb_ary_new_capa(n);
- RARRAY_PTR_USE(result, ptr_result, {
- for (i=0; i<n; i++) {
- long r = RAND_UPTO(len-i) + i;
- ptr_result[i] = r;
- if (r > max_idx) max_idx = r;
- }
- len = RARRAY_LEN(ary);
- if (len <= max_idx) n = 0;
- else if (n > len) n = len;
+ VALUE vmemo = Data_Wrap_Struct(0, 0, st_free_table, 0);
+ st_table *memo = st_init_numtable_with_size(n);
+ DATA_PTR(vmemo) = memo;
+ result = rb_ary_new_capa(n);
+ RARRAY_PTR_USE(result, ptr_result, {
+ for (i=0; i<n; i++) {
+ long r = RAND_UPTO(len-i) + i;
+ ptr_result[i] = r;
+ if (r > max_idx) max_idx = r;
+ }
+ len = RARRAY_LEN(ary);
+ if (len <= max_idx) n = 0;
+ else if (n > len) n = len;
RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, {
- for (i=0; i<n; i++) {
- long j2 = j = ptr_result[i];
- long i2 = i;
- st_data_t value;
- if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
- if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
- st_insert(memo, (st_data_t)j, (st_data_t)i2);
- ptr_result[i] = ptr_ary[j2];
- }
- });
- });
- DATA_PTR(vmemo) = 0;
- st_free_table(memo);
+ for (i=0; i<n; i++) {
+ long j2 = j = ptr_result[i];
+ long i2 = i;
+ st_data_t value;
+ if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
+ if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
+ st_insert(memo, (st_data_t)j, (st_data_t)i2);
+ ptr_result[i] = ptr_ary[j2];
+ }
+ });
+ });
+ DATA_PTR(vmemo) = 0;
+ st_free_table(memo);
}
else {
- result = rb_ary_dup(ary);
- RBASIC_CLEAR_CLASS(result);
- RB_GC_GUARD(ary);
- RARRAY_PTR_USE(result, ptr_result, {
- for (i=0; i<n; i++) {
- j = RAND_UPTO(len-i) + i;
- nv = ptr_result[j];
- ptr_result[j] = ptr_result[i];
- ptr_result[i] = nv;
- }
- });
- RBASIC_SET_CLASS_RAW(result, rb_cArray);
+ result = rb_ary_dup(ary);
+ RBASIC_CLEAR_CLASS(result);
+ RB_GC_GUARD(ary);
+ RARRAY_PTR_USE(result, ptr_result, {
+ for (i=0; i<n; i++) {
+ j = RAND_UPTO(len-i) + i;
+ nv = ptr_result[j];
+ ptr_result[j] = ptr_result[i];
+ ptr_result[i] = nv;
+ }
+ });
+ RBASIC_SET_CLASS_RAW(result, rb_cArray);
}
ARY_SET_LEN(result, n);
@@ -6479,15 +6878,21 @@ rb_ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VA
}
static VALUE
+ary_sample0(rb_execution_context_t *ec, VALUE ary)
+{
+ return ary_sample(ec, ary, rb_cRandom, Qfalse, Qfalse);
+}
+
+static VALUE
rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
{
long mul;
VALUE n = Qnil;
if (args && (RARRAY_LEN(args) > 0)) {
- n = RARRAY_AREF(args, 0);
+ n = RARRAY_AREF(args, 0);
}
if (RARRAY_LEN(self) == 0) return INT2FIX(0);
- if (n == Qnil) return DBL2NUM(HUGE_VAL);
+ if (NIL_P(n)) return DBL2NUM(HUGE_VAL);
mul = NUM2LONG(n);
if (mul <= 0) return INT2FIX(0);
n = LONG2FIX(mul);
@@ -6504,15 +6909,18 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
* When called with positive \Integer argument +count+ and a block,
* calls the block with each element, then does so again,
* until it has done so +count+ times; returns +nil+:
+ *
* output = []
* [0, 1].cycle(2) {|element| output.push(element) } # => nil
* output # => [0, 1, 0, 1]
*
* If +count+ is zero or negative, does not call the block:
+ *
* [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil
* [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil
*
* When a block is given, and argument is omitted or +nil+, cycles forever:
+ *
* # Prints 0 and 1 forever.
* [0, 1].cycle {|element| puts element }
* [0, 1].cycle(nil) {|element| puts element }
@@ -6522,6 +6930,7 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
* [0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)>
* [0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle>
* [0, 1].cycle.first(5) # => [0, 1, 0, 1, 0]
+ *
*/
static VALUE
rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
@@ -6547,9 +6956,6 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
return Qnil;
}
-#define tmpary(n) rb_ary_tmp_new(n)
-#define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
-
/*
* Build a ruby array of the corresponding values and yield it to the
* associated block.
@@ -6585,32 +6991,32 @@ permute0(const long n, const long r, long *const p, char *const used, const VALU
long i = 0, index = 0;
for (;;) {
- const char *const unused = memchr(&used[i], 0, n-i);
- if (!unused) {
- if (!index) break;
- i = p[--index]; /* pop index */
- used[i++] = 0; /* index unused */
- }
- else {
- i = unused - used;
- p[index] = i;
- used[i] = 1; /* mark index used */
- ++index;
- if (index < r-1) { /* if not done yet */
- p[index] = i = 0;
- continue;
- }
- for (i = 0; i < n; ++i) {
- if (used[i]) continue;
- p[index] = i;
- if (!yield_indexed_values(values, r, p)) {
- rb_raise(rb_eRuntimeError, "permute reentered");
- }
- }
- i = p[--index]; /* pop index */
- used[i] = 0; /* index unused */
- p[index] = ++i;
- }
+ const char *const unused = memchr(&used[i], 0, n-i);
+ if (!unused) {
+ if (!index) break;
+ i = p[--index]; /* pop index */
+ used[i++] = 0; /* index unused */
+ }
+ else {
+ i = unused - used;
+ p[index] = i;
+ used[i] = 1; /* mark index used */
+ ++index;
+ if (index < r-1) { /* if not done yet */
+ p[index] = i = 0;
+ continue;
+ }
+ for (i = 0; i < n; ++i) {
+ if (used[i]) continue;
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "permute reentered");
+ }
+ }
+ i = p[--index]; /* pop index */
+ used[i] = 0; /* index unused */
+ p[index] = ++i;
+ }
}
}
@@ -6623,14 +7029,14 @@ descending_factorial(long from, long how_many)
{
VALUE cnt;
if (how_many > 0) {
- cnt = LONG2FIX(from);
- while (--how_many > 0) {
- long v = --from;
- cnt = rb_int_mul(cnt, LONG2FIX(v));
- }
+ cnt = LONG2FIX(from);
+ while (--how_many > 0) {
+ long v = --from;
+ cnt = rb_int_mul(cnt, LONG2FIX(v));
+ }
}
else {
- cnt = LONG2FIX(how_many == 0);
+ cnt = LONG2FIX(how_many == 0);
}
return cnt;
}
@@ -6641,18 +7047,18 @@ binomial_coefficient(long comb, long size)
VALUE r;
long i;
if (comb > size-comb) {
- comb = size-comb;
+ comb = size-comb;
}
if (comb < 0) {
- return LONG2FIX(0);
+ return LONG2FIX(0);
}
else if (comb == 0) {
- return LONG2FIX(1);
+ return LONG2FIX(1);
}
r = LONG2FIX(size);
for (i = 1; i < comb; ++i) {
- r = rb_int_mul(r, LONG2FIX(size - i));
- r = rb_int_idiv(r, LONG2FIX(i + 1));
+ r = rb_int_mul(r, LONG2FIX(size - i));
+ r = rb_int_idiv(r, LONG2FIX(i + 1));
}
return r;
}
@@ -6680,19 +7086,26 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* are given, calls the block with all +n+-tuple permutations of +self+.
*
* Example:
+ *
* a = [0, 1, 2]
* a.permutation(2) {|permutation| p permutation }
+ *
* Output:
+ *
* [0, 1]
* [0, 2]
* [1, 0]
* [1, 2]
* [2, 0]
* [2, 1]
+ *
* Another example:
+ *
* a = [0, 1, 2]
* a.permutation(3) {|permutation| p permutation }
+ *
* Output:
+ *
* [0, 1, 2]
* [0, 2, 1]
* [1, 0, 2]
@@ -6701,22 +7114,29 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* [2, 1, 0]
*
* When +n+ is zero, calls the block once with a new empty \Array:
+ *
* a = [0, 1, 2]
* a.permutation(0) {|permutation| p permutation }
+ *
* Output:
+ *
* []
*
* When +n+ is out of range (negative or larger than <tt>self.size</tt>),
* does not call the block:
+ *
* a = [0, 1, 2]
* a.permutation(-1) {|permutation| fail 'Cannot happen' }
* a.permutation(4) {|permutation| fail 'Cannot happen' }
*
* When a block given but no argument,
* behaves the same as <tt>a.permutation(a.size)</tt>:
+ *
* a = [0, 1, 2]
* a.permutation {|permutation| p permutation }
+ *
* Output:
+ *
* [0, 1, 2]
* [0, 2, 1]
* [1, 0, 2]
@@ -6725,9 +7145,11 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* [2, 1, 0]
*
* Returns a new \Enumerator if no block given:
+ *
* a = [0, 1, 2]
* a.permutation # => #<Enumerator: [0, 1, 2]:permutation>
* a.permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
+ *
*/
static VALUE
@@ -6742,28 +7164,28 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
r = NUM2LONG(argv[0]); /* Permutation size from argument */
if (r < 0 || n < r) {
- /* no permutations: yield nothing */
+ /* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
- rb_yield(rb_ary_new2(0));
+ rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
}
else { /* this is the general case */
- volatile VALUE t0;
- long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
- char *used = (char*)(p + r);
- VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
- RBASIC_CLEAR_CLASS(ary0);
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
+ char *used = (char*)(p + r);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
- MEMZERO(used, char, n); /* initialize array */
+ MEMZERO(used, char, n); /* initialize array */
- permute0(n, r, p, used, ary0); /* compute and yield permutations */
- ALLOCV_END(t0);
- RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ permute0(n, r, p, used, ary0); /* compute and yield permutations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
@@ -6776,16 +7198,16 @@ combinate0(const long len, const long n, long *const stack, const VALUE values)
MEMZERO(stack+1, long, n);
stack[0] = -1;
for (;;) {
- for (lev++; lev < n; lev++) {
- stack[lev+1] = stack[lev]+1;
- }
- if (!yield_indexed_values(values, n, stack+1)) {
- rb_raise(rb_eRuntimeError, "combination reentered");
- }
- do {
- if (lev == 0) return;
- stack[lev--]++;
- } while (stack[lev+1]+n == len+lev+1);
+ for (lev++; lev < n; lev++) {
+ stack[lev+1] = stack[lev]+1;
+ }
+ if (!yield_indexed_values(values, n, stack+1)) {
+ rb_raise(rb_eRuntimeError, "combination reentered");
+ }
+ do {
+ if (lev == 0) return;
+ stack[lev--]++;
+ } while (stack[lev+1]+n == len+lev+1);
}
}
@@ -6810,34 +7232,46 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
* are given, calls the block with all +n+-tuple combinations of +self+.
*
* Example:
+ *
* a = [0, 1, 2]
* a.combination(2) {|combination| p combination }
+ *
* Output:
+ *
* [0, 1]
* [0, 2]
* [1, 2]
*
* Another example:
+ *
* a = [0, 1, 2]
* a.combination(3) {|combination| p combination }
+ *
* Output:
+ *
* [0, 1, 2]
*
* When +n+ is zero, calls the block once with a new empty \Array:
+ *
* a = [0, 1, 2]
* a1 = a.combination(0) {|combination| p combination }
+ *
* Output:
+ *
* []
*
* When +n+ is out of range (negative or larger than <tt>self.size</tt>),
* does not call the block:
+ *
* a = [0, 1, 2]
* a.combination(-1) {|combination| fail 'Cannot happen' }
* a.combination(4) {|combination| fail 'Cannot happen' }
*
* Returns a new \Enumerator if no block given:
+ *
* a = [0, 1, 2]
* a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
+ *
*/
static VALUE
@@ -6849,25 +7283,25 @@ rb_ary_combination(VALUE ary, VALUE num)
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
len = RARRAY_LEN(ary);
if (n < 0 || len < n) {
- /* yield nothing */
+ /* yield nothing */
}
else if (n == 0) {
- rb_yield(rb_ary_new2(0));
+ rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
}
else {
- VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
- volatile VALUE t0;
- long *stack = ALLOCV_N(long, t0, n+1);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ volatile VALUE t0;
+ long *stack = ALLOCV_N(long, t0, n+1);
- RBASIC_CLEAR_CLASS(ary0);
- combinate0(len, n, stack, ary0);
- ALLOCV_END(t0);
- RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ RBASIC_CLEAR_CLASS(ary0);
+ combinate0(len, n, stack, ary0);
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
@@ -6891,19 +7325,19 @@ rpermute0(const long n, const long r, long *const p, const VALUE values)
p[index] = i;
for (;;) {
- if (++index < r-1) {
- p[index] = i = 0;
- continue;
- }
- for (i = 0; i < n; ++i) {
- p[index] = i;
- if (!yield_indexed_values(values, r, p)) {
- rb_raise(rb_eRuntimeError, "repeated permute reentered");
- }
- }
- do {
- if (index <= 0) return;
- } while ((i = ++p[--index]) >= n);
+ if (++index < r-1) {
+ p[index] = i = 0;
+ continue;
+ }
+ for (i = 0; i < n; ++i) {
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "repeated permute reentered");
+ }
+ }
+ do {
+ if (index <= 0) return;
+ } while ((i = ++p[--index]) >= n);
}
}
@@ -6914,10 +7348,10 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
long k = NUM2LONG(RARRAY_AREF(args, 0));
if (k < 0) {
- return LONG2FIX(0);
+ return LONG2FIX(0);
}
if (n <= 0) {
- return LONG2FIX(!k);
+ return LONG2FIX(!k);
}
return rb_int_positive_pow(n, (unsigned long)k);
}
@@ -6936,16 +7370,22 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* The number of permutations is <tt>self.size**n</tt>.
*
* +n+ = 1:
+ *
* a = [0, 1, 2]
* a.repeated_permutation(1) {|permutation| p permutation }
+ *
* Output:
+ *
* [0]
* [1]
* [2]
*
* +n+ = 2:
+ *
* a.repeated_permutation(2) {|permutation| p permutation }
+ *
* Output:
+ *
* [0, 0]
* [0, 1]
* [0, 2]
@@ -6959,14 +7399,17 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* If +n+ is zero, calls the block once with an empty \Array.
*
* If +n+ is negative, does not call the block:
+ *
* a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
*
* Returns a new \Enumerator if no block given:
+ *
* a = [0, 1, 2]
* a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
*
* Using Enumerators, it's convenient to show the permutations and counts
* for some values of +n+:
+ *
* e = a.repeated_permutation(0)
* e.size # => 1
* e.to_a # => [[]]
@@ -6976,6 +7419,7 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
* e = a.repeated_permutation(2)
* e.size # => 9
* e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
+ *
*/
static VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
@@ -6987,25 +7431,25 @@ rb_ary_repeated_permutation(VALUE ary, VALUE num)
r = NUM2LONG(num); /* Permutation size from argument */
if (r < 0) {
- /* no permutations: yield nothing */
+ /* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
- rb_yield(rb_ary_new2(0));
+ rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
}
else { /* this is the general case */
- volatile VALUE t0;
- long *p = ALLOCV_N(long, t0, r);
- VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
- RBASIC_CLEAR_CLASS(ary0);
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, r);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
- rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
- ALLOCV_END(t0);
- RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
@@ -7017,19 +7461,19 @@ rcombinate0(const long n, const long r, long *const p, const long rest, const VA
p[index] = i;
for (;;) {
- if (++index < r-1) {
- p[index] = i;
- continue;
- }
- for (; i < n; ++i) {
- p[index] = i;
- if (!yield_indexed_values(values, r, p)) {
- rb_raise(rb_eRuntimeError, "repeated combination reentered");
- }
- }
- do {
- if (index <= 0) return;
- } while ((i = ++p[--index]) >= n);
+ if (++index < r-1) {
+ p[index] = i;
+ continue;
+ }
+ for (; i < n; ++i) {
+ p[index] = i;
+ if (!yield_indexed_values(values, r, p)) {
+ rb_raise(rb_eRuntimeError, "repeated combination reentered");
+ }
+ }
+ do {
+ if (index <= 0) return;
+ } while ((i = ++p[--index]) >= n);
}
}
@@ -7039,7 +7483,7 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
long n = RARRAY_LEN(ary);
long k = NUM2LONG(RARRAY_AREF(args, 0));
if (k == 0) {
- return LONG2FIX(1);
+ return LONG2FIX(1);
}
return binomial_coefficient(k, n + k - 1);
}
@@ -7058,16 +7502,22 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
* The number of combinations is <tt>(n+1)(n+2)/2</tt>.
*
* +n+ = 1:
+ *
* a = [0, 1, 2]
* a.repeated_combination(1) {|combination| p combination }
+ *
* Output:
+ *
* [0]
* [1]
* [2]
*
* +n+ = 2:
+ *
* a.repeated_combination(2) {|combination| p combination }
+ *
* Output:
+ *
* [0, 0]
* [0, 1]
* [0, 2]
@@ -7078,14 +7528,17 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
* If +n+ is zero, calls the block once with an empty \Array.
*
* If +n+ is negative, does not call the block:
+ *
* a.repeated_combination(-1) {|combination| fail 'Cannot happen' }
*
* Returns a new \Enumerator if no block given:
+ *
* a = [0, 1, 2]
* a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
*
* Using Enumerators, it's convenient to show the combinations and counts
* for some values of +n+:
+ *
* e = a.repeated_combination(0)
* e.size # => 1
* e.to_a # => [[]]
@@ -7095,6 +7548,7 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
* e = a.repeated_combination(2)
* e.size # => 6
* e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
+ *
*/
static VALUE
@@ -7106,28 +7560,28 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
len = RARRAY_LEN(ary);
if (n < 0) {
- /* yield nothing */
+ /* yield nothing */
}
else if (n == 0) {
- rb_yield(rb_ary_new2(0));
+ rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
- }
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
+ }
}
else if (len == 0) {
- /* yield nothing */
+ /* yield nothing */
}
else {
- volatile VALUE t0;
- long *p = ALLOCV_N(long, t0, n);
- VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
- RBASIC_CLEAR_CLASS(ary0);
+ volatile VALUE t0;
+ long *p = ALLOCV_N(long, t0, n);
+ VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
+ RBASIC_CLEAR_CLASS(ary0);
- rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
- ALLOCV_END(t0);
- RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
+ rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
+ ALLOCV_END(t0);
+ RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
@@ -7138,12 +7592,14 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
* array.product(*other_arrays) {|combination| ... } -> self
*
* Computes and returns or yields all combinations of elements from all the Arrays,
- * including both +self+ and +other_arrays+.
+ * including both +self+ and +other_arrays+:
+ *
* - The number of combinations is the product of the sizes of all the arrays,
* including both +self+ and +other_arrays+.
* - The order of the returned combinations is indeterminate.
*
* When no block is given, returns the combinations as an \Array of Arrays:
+ *
* a = [0, 1, 2]
* a1 = [3, 4]
* a2 = [5, 6]
@@ -7158,11 +7614,15 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
*
* If no argument is given, returns an \Array of 1-element Arrays,
* each containing an element of +self+:
+ *
* a.product # => [[0], [1], [2]]
*
* When a block is given, yields each combination as an \Array; returns +self+:
+ *
* a.product(a1) {|combination| p combination }
+ *
* Output:
+ *
* [0, 3]
* [0, 4]
* [1, 3]
@@ -7171,21 +7631,26 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
* [2, 4]
*
* If any argument is an empty \Array, does not call the block:
+ *
* a.product(a1, a2, []) {|combination| fail 'Cannot happen' }
*
* If no argument is given, yields each element of +self+ as a 1-element \Array:
+ *
* a.product {|combination| p combination }
+ *
* Output:
+ *
* [0]
* [1]
* [2]
+ *
*/
static VALUE
rb_ary_product(int argc, VALUE *argv, VALUE ary)
{
int n = argc+1; /* How many arrays we're operating on */
- volatile VALUE t0 = tmpary(n);
+ volatile VALUE t0 = rb_ary_hidden_new(n);
volatile VALUE t1 = Qundef;
VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
@@ -7206,64 +7671,64 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary)
/* Otherwise, allocate and fill in an array of results */
if (rb_block_given_p()) {
- /* Make defensive copies of arrays; exit if any is empty */
- for (i = 0; i < n; i++) {
- if (RARRAY_LEN(arrays[i]) == 0) goto done;
- arrays[i] = ary_make_shared_copy(arrays[i]);
- }
+ /* Make defensive copies of arrays; exit if any is empty */
+ for (i = 0; i < n; i++) {
+ if (RARRAY_LEN(arrays[i]) == 0) goto done;
+ arrays[i] = ary_make_shared_copy(arrays[i]);
+ }
}
else {
- /* Compute the length of the result array; return [] if any is empty */
- for (i = 0; i < n; i++) {
- long k = RARRAY_LEN(arrays[i]);
- if (k == 0) {
- result = rb_ary_new2(0);
- goto done;
- }
+ /* Compute the length of the result array; return [] if any is empty */
+ for (i = 0; i < n; i++) {
+ long k = RARRAY_LEN(arrays[i]);
+ if (k == 0) {
+ result = rb_ary_new2(0);
+ goto done;
+ }
if (MUL_OVERFLOW_LONG_P(resultlen, k))
- rb_raise(rb_eRangeError, "too big to product");
- resultlen *= k;
- }
- result = rb_ary_new2(resultlen);
+ rb_raise(rb_eRangeError, "too big to product");
+ resultlen *= k;
+ }
+ result = rb_ary_new2(resultlen);
}
for (;;) {
- int m;
- /* fill in one subarray */
- VALUE subarray = rb_ary_new2(n);
- for (j = 0; j < n; j++) {
- rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
- }
-
- /* put it on the result array */
- if (NIL_P(result)) {
- FL_SET(t0, FL_USER5);
- rb_yield(subarray);
- if (! FL_TEST(t0, FL_USER5)) {
- rb_raise(rb_eRuntimeError, "product reentered");
- }
- else {
- FL_UNSET(t0, FL_USER5);
- }
- }
- else {
- rb_ary_push(result, subarray);
- }
-
- /*
- * Increment the last counter. If it overflows, reset to 0
- * and increment the one before it.
- */
- m = n-1;
- counters[m]++;
- while (counters[m] == RARRAY_LEN(arrays[m])) {
- counters[m] = 0;
- /* If the first counter overflows, we are done */
- if (--m < 0) goto done;
- counters[m]++;
- }
+ int m;
+ /* fill in one subarray */
+ VALUE subarray = rb_ary_new2(n);
+ for (j = 0; j < n; j++) {
+ rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
+ }
+
+ /* put it on the result array */
+ if (NIL_P(result)) {
+ FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
+ rb_yield(subarray);
+ if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
+ rb_raise(rb_eRuntimeError, "product reentered");
+ }
+ else {
+ FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
+ }
+ }
+ else {
+ rb_ary_push(result, subarray);
+ }
+
+ /*
+ * Increment the last counter. If it overflows, reset to 0
+ * and increment the one before it.
+ */
+ m = n-1;
+ counters[m]++;
+ while (counters[m] == RARRAY_LEN(arrays[m])) {
+ counters[m] = 0;
+ /* If the first counter overflows, we are done */
+ if (--m < 0) goto done;
+ counters[m]++;
+ }
}
+
done:
- tmpary_discard(t0);
ALLOCV_END(t1);
return NIL_P(result) ? ary : result;
@@ -7278,11 +7743,13 @@ done:
* does not modify +self+.
*
* Examples:
+ *
* a = [0, 1, 2, 3, 4, 5]
* a.take(1) # => [0]
* a.take(2) # => [0, 1]
* a.take(50) # => [0, 1, 2, 3, 4, 5]
* a # => [0, 1, 2, 3, 4, 5]
+ *
*/
static VALUE
@@ -7290,7 +7757,7 @@ rb_ary_take(VALUE obj, VALUE n)
{
long len = NUM2LONG(n);
if (len < 0) {
- rb_raise(rb_eArgError, "attempt to take negative size");
+ rb_raise(rb_eArgError, "attempt to take negative size");
}
return rb_ary_subseq(obj, 0, len);
}
@@ -7305,14 +7772,17 @@ rb_ary_take(VALUE obj, VALUE n)
*
* With a block given, calls the block with each successive element of +self+;
* stops if the block returns +false+ or +nil+;
- * returns a new Array containing those elements for which the block returned a truthy value:
+ * returns a new \Array containing those elements for which the block returned a truthy value:
+ *
* a = [0, 1, 2, 3, 4, 5]
* a.take_while {|element| element < 3 } # => [0, 1, 2]
* a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5]
* a # => [0, 1, 2, 3, 4, 5]
*
* With no block given, returns a new \Enumerator:
+ *
* [0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
+ *
*/
static VALUE
@@ -7322,7 +7792,7 @@ rb_ary_take_while(VALUE ary)
RETURN_ENUMERATOR(ary, 0, 0);
for (i = 0; i < RARRAY_LEN(ary); i++) {
- if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
+ if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
}
return rb_ary_take(ary, LONG2FIX(i));
}
@@ -7336,10 +7806,12 @@ rb_ary_take_while(VALUE ary)
* does not modify +self+.
*
* Examples:
+ *
* a = [0, 1, 2, 3, 4, 5]
* a.drop(0) # => [0, 1, 2, 3, 4, 5]
* a.drop(1) # => [1, 2, 3, 4, 5]
* a.drop(2) # => [2, 3, 4, 5]
+ *
*/
static VALUE
@@ -7348,11 +7820,11 @@ rb_ary_drop(VALUE ary, VALUE n)
VALUE result;
long pos = NUM2LONG(n);
if (pos < 0) {
- rb_raise(rb_eArgError, "attempt to drop negative size");
+ rb_raise(rb_eArgError, "attempt to drop negative size");
}
result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
- if (result == Qnil) result = rb_ary_new();
+ if (NIL_P(result)) result = rb_ary_new();
return result;
}
@@ -7366,12 +7838,15 @@ rb_ary_drop(VALUE ary, VALUE n)
*
* With a block given, calls the block with each successive element of +self+;
* stops if the block returns +false+ or +nil+;
- * returns a new Array _omitting_ those elements for which the block returned a truthy value:
+ * returns a new \Array _omitting_ those elements for which the block returned a truthy value:
+ *
* a = [0, 1, 2, 3, 4, 5]
* a.drop_while {|element| element < 3 } # => [3, 4, 5]
*
* With no block given, returns a new \Enumerator:
+ *
* [0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
+ *
*/
static VALUE
@@ -7381,7 +7856,7 @@ rb_ary_drop_while(VALUE ary)
RETURN_ENUMERATOR(ary, 0, 0);
for (i = 0; i < RARRAY_LEN(ary); i++) {
- if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
+ if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
}
return rb_ary_drop(ary, LONG2FIX(i));
}
@@ -7396,17 +7871,20 @@ rb_ary_drop_while(VALUE ary)
*
* With no block given and no argument, returns +true+ if +self+ has any truthy element,
* +false+ otherwise:
+ *
* [nil, 0, false].any? # => true
* [nil, false].any? # => false
* [].any? # => false
*
* With a block given and no argument, calls the block with each element in +self+;
* returns +true+ if the block returns any truthy value, +false+ otherwise:
+ *
* [0, 1, 2].any? {|element| element > 1 } # => true
* [0, 1, 2].any? {|element| element > 2 } # => false
*
* If argument +obj+ is given, returns +true+ if +obj+.<tt>===</tt> any element,
* +false+ otherwise:
+ *
* ['food', 'drink'].any?(/foo/) # => true
* ['food', 'drink'].any?(/bar/) # => false
* [].any?(/foo/) # => false
@@ -7427,9 +7905,9 @@ rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
if (rb_block_given_p()) {
rb_warn("given block not used");
}
- for (i = 0; i < RARRAY_LEN(ary); ++i) {
- if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
- }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
+ }
}
else if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) {
@@ -7437,9 +7915,9 @@ rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
}
}
else {
- for (i = 0; i < RARRAY_LEN(ary); ++i) {
- if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
- }
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
+ }
}
return Qfalse;
}
@@ -7454,16 +7932,19 @@ rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
*
* With no block given and no argument, returns +true+ if +self+ contains only truthy elements,
* +false+ otherwise:
+ *
* [0, 1, :foo].all? # => true
* [0, nil, 2].all? # => false
* [].all? # => true
*
* With a block given and no argument, calls the block with each element in +self+;
* returns +true+ if the block returns only truthy values, +false+ otherwise:
+ *
* [0, 1, 2].all? { |element| element < 3 } # => true
* [0, 1, 2].all? { |element| element < 2 } # => false
*
* If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> every element, +false+ otherwise:
+ *
* ['food', 'fool', 'foot'].all?(/foo/) # => true
* ['food', 'drink'].all?(/bar/) # => false
* [].all?(/foo/) # => true
@@ -7511,16 +7992,19 @@ rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
*
* With no block given and no argument, returns +true+ if +self+ has no truthy elements,
* +false+ otherwise:
+ *
* [nil, false].none? # => true
* [nil, 0, false].none? # => false
* [].none? # => true
*
* With a block given and no argument, calls the block with each element in +self+;
* returns +true+ if the block returns no truthy value, +false+ otherwise:
+ *
* [0, 1, 2].none? {|element| element > 3 } # => true
* [0, 1, 2].none? {|element| element > 1 } # => false
*
* If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> no element, +false+ otherwise:
+ *
* ['food', 'drink'].none?(/bar/) # => true
* ['food', 'drink'].none?(/foo/) # => false
* [].none?(/foo/) # => true
@@ -7568,6 +8052,7 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
*
* With no block given and no argument, returns +true+ if +self+ has exactly one truthy element,
* +false+ otherwise:
+ *
* [nil, 0].one? # => true
* [0, 0].one? # => false
* [nil, nil].one? # => false
@@ -7575,12 +8060,14 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
*
* With a block given and no argument, calls the block with each element in +self+;
* returns +true+ if the block a truthy value for exactly one element, +false+ otherwise:
+ *
* [0, 1, 2].one? {|element| element > 0 } # => false
* [0, 1, 2].one? {|element| element > 1 } # => true
* [0, 1, 2].one? {|element| element > 2 } # => false
*
* If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> exactly one element,
* +false+ otherwise:
+ *
* [0, 1, 2].one?(0) # => true
* [0, 0, 1].one?(0) # => false
* [1, 1, 2].one?(0) # => false
@@ -7636,14 +8123,16 @@ rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
* Finds and returns the object in nested objects
* that is specified by +index+ and +identifiers+.
* The nested objects may be instances of various classes.
- * See {Dig Methods}[rdoc-ref:doc/dig_methods.rdoc].
+ * See {Dig Methods}[rdoc-ref:dig_methods.rdoc].
*
* Examples:
+ *
* a = [:foo, [:bar, :baz, [:bat, :bam]]]
* a.dig(1) # => [:bar, :baz, [:bat, :bam]]
* a.dig(1, 2) # => [:bat, :bam]
* a.dig(1, 2, 0) # => :bat
* a.dig(1, 2, 3) # => nil
+ *
*/
static VALUE
@@ -7661,7 +8150,7 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
{
if (n != 0)
v = rb_fix_plus(LONG2FIX(n), v);
- if (r != Qundef) {
+ if (!UNDEF_P(r)) {
v = rb_rational_plus(r, v);
}
else if (!n && z) {
@@ -7676,31 +8165,38 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
* array.sum(init = 0) {|element| ... } -> object
*
* When no block is given, returns the object equivalent to:
+ *
* sum = init
* array.each {|element| sum += element }
* sum
- * For example, <tt>[e1, e2, e3].sum</tt> returns </tt>init + e1 + e2 + e3</tt>.
+ *
+ * For example, <tt>[e1, e2, e3].sum</tt> returns <tt>init + e1 + e2 + e3</tt>.
*
* Examples:
+ *
* a = [0, 1, 2, 3]
* a.sum # => 6
* a.sum(100) # => 106
*
* The elements need not be numeric, but must be <tt>+</tt>-compatible
* with each other and with +init+:
+ *
* a = ['abc', 'def', 'ghi']
* a.sum('jkl') # => "jklabcdefghi"
*
* When a block is given, it is called with each element
* and the block's return value (instead of the element itself) is used as the addend:
+ *
* a = ['zero', 1, :two]
* s = a.sum('Coerced and concatenated: ') {|element| element.to_s }
* s # => "Coerced and concatenated: zero1two"
*
* Notes:
+ *
* - Array#join and Array#flatten may be faster than Array#sum
* for an \Array of Strings or an \Array of Arrays.
* - Array#sum method may not respect method redefinition of "+" methods such as Integer#+.
+ *
*/
static VALUE
@@ -7730,10 +8226,10 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
n = 0;
}
}
- else if (RB_TYPE_P(e, T_BIGNUM))
+ else if (RB_BIGNUM_TYPE_P(e))
v = rb_big_plus(e, v);
else if (RB_TYPE_P(e, T_RATIONAL)) {
- if (r == Qundef)
+ if (UNDEF_P(r))
r = e;
else
r = rb_rational_plus(r, e);
@@ -7767,7 +8263,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
x = RFLOAT_VALUE(e);
else if (FIXNUM_P(e))
x = FIX2LONG(e);
- else if (RB_TYPE_P(e, T_BIGNUM))
+ else if (RB_BIGNUM_TYPE_P(e))
x = rb_big2dbl(e);
else if (RB_TYPE_P(e, T_RATIONAL))
x = rb_num2dbl(e);
@@ -7820,75 +8316,128 @@ rb_ary_deconstruct(VALUE ary)
}
/*
- * An \Array is an ordered, integer-indexed collection of objects,
- * called _elements_. Any object may be an \Array element.
+ * An \Array is an ordered, integer-indexed collection of objects, called _elements_.
+ * Any object (even another array) may be an array element,
+ * and an array can contain objects of different types.
*
* == \Array Indexes
*
* \Array indexing starts at 0, as in C or Java.
*
* A positive index is an offset from the first element:
+ *
* - Index 0 indicates the first element.
* - Index 1 indicates the second element.
* - ...
*
* A negative index is an offset, backwards, from the end of the array:
+ *
* - Index -1 indicates the last element.
* - Index -2 indicates the next-to-last element.
* - ...
*
- * A non-negative index is <i>in range</i> if it is smaller than
+ * A non-negative index is <i>in range</i> if and only if it is smaller than
* the size of the array. For a 3-element array:
+ *
* - Indexes 0 through 2 are in range.
* - Index 3 is out of range.
*
- * A negative index is <i>in range</i> if its absolute value is
+ * A negative index is <i>in range</i> if and only if its absolute value is
* not larger than the size of the array. For a 3-element array:
+ *
* - Indexes -1 through -3 are in range.
* - Index -4 is out of range.
*
+ * Although the effective index into an array is always an integer,
+ * some methods (both within and outside of class \Array)
+ * accept one or more non-integer arguments that are
+ * {integer-convertible objects}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects].
+ *
+ *
* == Creating Arrays
*
- * A new array can be created by using the literal constructor
- * <code>[]</code>. Arrays can contain different types of objects. For
- * example, the array below contains an Integer, a String and a Float:
+ * You can create an \Array object explicitly with:
+ *
+ * - An {array literal}[rdoc-ref:literals.rdoc@Array+Literals]:
+ *
+ * [1, 'one', :one, [2, 'two', :two]]
+ *
+ * - A {%w or %W: string-array Literal}[rdoc-ref:literals.rdoc@25w+and+-25W-3A+String-Array+Literals]:
*
- * ary = [1, "two", 3.0] #=> [1, "two", 3.0]
+ * %w[foo bar baz] # => ["foo", "bar", "baz"]
+ * %w[1 % *] # => ["1", "%", "*"]
*
- * An array can also be created by explicitly calling Array.new with zero, one
- * (the initial size of the Array) or two arguments (the initial size and a
- * default object).
+ * - A {%i pr %I: symbol-array Literal}[rdoc-ref:literals.rdoc@25i+and+-25I-3A+Symbol-Array+Literals]:
*
- * ary = Array.new #=> []
- * Array.new(3) #=> [nil, nil, nil]
- * Array.new(3, true) #=> [true, true, true]
+ * %i[foo bar baz] # => [:foo, :bar, :baz]
+ * %i[1 % *] # => [:"1", :%, :*]
*
- * Note that the second argument populates the array with references to the
- * same object. Therefore, it is only recommended in cases when you need to
- * instantiate arrays with natively immutable objects such as Symbols,
- * numbers, true or false.
+ * - \Method Kernel#Array:
*
- * To create an array with separate objects a block can be passed instead.
- * This method is safe to use with mutable objects such as hashes, strings or
- * other arrays:
+ * Array(["a", "b"]) # => ["a", "b"]
+ * Array(1..5) # => [1, 2, 3, 4, 5]
+ * Array(key: :value) # => [[:key, :value]]
+ * Array(nil) # => []
+ * Array(1) # => [1]
+ * Array({:a => "a", :b => "b"}) # => [[:a, "a"], [:b, "b"]]
*
- * Array.new(4) {Hash.new} #=> [{}, {}, {}, {}]
- * Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
+ * - \Method Array.new:
*
- * This is also a quick way to build up multi-dimensional arrays:
+ * Array.new # => []
+ * Array.new(3) # => [nil, nil, nil]
+ * Array.new(4) {Hash.new} # => [{}, {}, {}, {}]
+ * Array.new(3, true) # => [true, true, true]
*
- * empty_table = Array.new(3) {Array.new(3)}
- * #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
+ * Note that the last example above populates the array
+ * with references to the same object.
+ * This is recommended only in cases where that object is a natively immutable object
+ * such as a symbol, a numeric, +nil+, +true+, or +false+.
*
- * An array can also be created by using the Array() method, provided by
- * Kernel, which tries to call #to_ary, then #to_a on its argument.
+ * Another way to create an array with various objects, using a block;
+ * this usage is safe for mutable objects such as hashes, strings or
+ * other arrays:
*
- * Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
+ * Array.new(4) {|i| i.to_s } # => ["0", "1", "2", "3"]
+ *
+ * Here is a way to create a multi-dimensional array:
+ *
+ * Array.new(3) {Array.new(3)}
+ * # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
+ *
+ * A number of Ruby methods, both in the core and in the standard library,
+ * provide instance method +to_a+, which converts an object to an array.
+ *
+ * - ARGF#to_a
+ * - Array#to_a
+ * - Enumerable#to_a
+ * - Hash#to_a
+ * - MatchData#to_a
+ * - NilClass#to_a
+ * - OptionParser#to_a
+ * - Range#to_a
+ * - Set#to_a
+ * - Struct#to_a
+ * - Time#to_a
+ * - Benchmark::Tms#to_a
+ * - CSV::Table#to_a
+ * - Enumerator::Lazy#to_a
+ * - Gem::List#to_a
+ * - Gem::NameTuple#to_a
+ * - Gem::Platform#to_a
+ * - Gem::RequestSet::Lockfile::Tokenizer#to_a
+ * - Gem::SourceList#to_a
+ * - OpenSSL::X509::Extension#to_a
+ * - OpenSSL::X509::Name#to_a
+ * - Racc::ISet#to_a
+ * - Rinda::RingFinger#to_a
+ * - Ripper::Lexer::Elem#to_a
+ * - RubyVM::InstructionSequence#to_a
+ * - YAML::DBM#to_a
*
* == Example Usage
*
* In addition to the methods it mixes in through the Enumerable module, the
- * Array class has proprietary methods for accessing, searching and otherwise
+ * \Array class has proprietary methods for accessing, searching and otherwise
* manipulating arrays.
*
* Some of the more common ones are illustrated below.
@@ -7936,7 +8485,7 @@ rb_ary_deconstruct(VALUE ary)
*
* arr.drop(3) #=> [4, 5, 6]
*
- * == Obtaining Information about an Array
+ * == Obtaining Information about an \Array
*
* Arrays keep track of their own length at all times. To query an array
* about the number of elements it contains, use #length, #count or #size.
@@ -7974,7 +8523,7 @@ rb_ary_deconstruct(VALUE ary)
* arr.insert(3, 'orange', 'pear', 'grapefruit')
* #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
*
- * == Removing Items from an Array
+ * == Removing Items from an \Array
*
* The method #pop removes the last element in an array and returns it:
*
@@ -8016,9 +8565,9 @@ rb_ary_deconstruct(VALUE ary)
*
* == Iterating over Arrays
*
- * Like all classes that include the Enumerable module, Array has an each
+ * Like all classes that include the Enumerable module, \Array has an each
* method, which defines what elements should be iterated over and how. In
- * case of Array's #each, all elements in the Array instance are yielded to
+ * case of Array's #each, all elements in the \Array instance are yielded to
* the supplied block in sequence.
*
* Note that this operation leaves the array unchanged.
@@ -8044,7 +8593,8 @@ rb_ary_deconstruct(VALUE ary)
* arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25]
* arr #=> [1, 4, 9, 16, 25]
*
- * == Selecting Items from an Array
+ *
+ * == Selecting Items from an \Array
*
* Elements can be selected from an array according to criteria defined in a
* block. The selection can happen in a destructive or a non-destructive
@@ -8074,6 +8624,189 @@ rb_ary_deconstruct(VALUE ary)
* arr = [1, 2, 3, 4, 5, 6]
* arr.keep_if {|a| a < 4} #=> [1, 2, 3]
* arr #=> [1, 2, 3]
+ *
+ * == What's Here
+ *
+ * First, what's elsewhere. \Class \Array:
+ *
+ * - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
+ * - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
+ * which provides dozens of additional methods.
+ *
+ * Here, class \Array provides methods that are useful for:
+ *
+ * - {Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]
+ * - {Querying}[rdoc-ref:Array@Methods+for+Querying]
+ * - {Comparing}[rdoc-ref:Array@Methods+for+Comparing]
+ * - {Fetching}[rdoc-ref:Array@Methods+for+Fetching]
+ * - {Assigning}[rdoc-ref:Array@Methods+for+Assigning]
+ * - {Deleting}[rdoc-ref:Array@Methods+for+Deleting]
+ * - {Combining}[rdoc-ref:Array@Methods+for+Combining]
+ * - {Iterating}[rdoc-ref:Array@Methods+for+Iterating]
+ * - {Converting}[rdoc-ref:Array@Methods+for+Converting]
+ * - {And more....}[rdoc-ref:Array@Other+Methods]
+ *
+ * === Methods for Creating an \Array
+ *
+ * - ::[]: Returns a new array populated with given objects.
+ * - ::new: Returns a new array.
+ * - ::try_convert: Returns a new array created from a given object.
+ *
+ * === Methods for Querying
+ *
+ * - #length, #size: Returns the count of elements.
+ * - #include?: Returns whether any element <tt>==</tt> a given object.
+ * - #empty?: Returns whether there are no elements.
+ * - #all?: Returns whether all elements meet a given criterion.
+ * - #any?: Returns whether any element meets a given criterion.
+ * - #none?: Returns whether no element <tt>==</tt> a given object.
+ * - #one?: Returns whether exactly one element <tt>==</tt> a given object.
+ * - #count: Returns the count of elements that meet a given criterion.
+ * - #find_index, #index: Returns the index of the first element that meets a given criterion.
+ * - #rindex: Returns the index of the last element that meets a given criterion.
+ * - #hash: Returns the integer hash code.
+ *
+ * === Methods for Comparing
+ *
+ * - #<=>: Returns -1, 0, or 1 * as +self+ is less than, equal to, or
+ * greater than a given object.
+ * - #==: Returns whether each element in +self+ is <tt>==</tt> to the corresponding element
+ * in a given object.
+ * - #eql?: Returns whether each element in +self+ is <tt>eql?</tt> to the corresponding
+ * element in a given object.
+
+ * === Methods for Fetching
+ *
+ * These methods do not modify +self+.
+ *
+ * - #[]: Returns one or more elements.
+ * - #fetch: Returns the element at a given offset.
+ * - #first: Returns one or more leading elements.
+ * - #last: Returns one or more trailing elements.
+ * - #max: Returns one or more maximum-valued elements,
+ * as determined by <tt><=></tt> or a given block.
+ * - #min: Returns one or more minimum-valued elements,
+ * as determined by <tt><=></tt> or a given block.
+ * - #minmax: Returns the minimum-valued and maximum-valued elements,
+ * as determined by <tt><=></tt> or a given block.
+ * - #assoc: Returns the first element that is an array
+ * whose first element <tt>==</tt> a given object.
+ * - #rassoc: Returns the first element that is an array
+ * whose second element <tt>==</tt> a given object.
+ * - #at: Returns the element at a given offset.
+ * - #values_at: Returns the elements at given offsets.
+ * - #dig: Returns the object in nested objects
+ * that is specified by a given index and additional arguments.
+ * - #drop: Returns trailing elements as determined by a given index.
+ * - #take: Returns leading elements as determined by a given index.
+ * - #drop_while: Returns trailing elements as determined by a given block.
+ * - #take_while: Returns leading elements as determined by a given block.
+ * - #slice: Returns consecutive elements as determined by a given argument.
+ * - #sort: Returns all elements in an order determined by <tt><=></tt> or a given block.
+ * - #reverse: Returns all elements in reverse order.
+ * - #compact: Returns an array containing all non-+nil+ elements.
+ * - #select, #filter: Returns an array containing elements selected by a given block.
+ * - #uniq: Returns an array containing non-duplicate elements.
+ * - #rotate: Returns all elements with some rotated from one end to the other.
+ * - #bsearch: Returns an element selected via a binary search
+ * as determined by a given block.
+ * - #bsearch_index: Returns the index of an element selected via a binary search
+ * as determined by a given block.
+ * - #sample: Returns one or more random elements.
+ * - #shuffle: Returns elements in a random order.
+ *
+ * === Methods for Assigning
+ *
+ * These methods add, replace, or reorder elements in +self+.
+ *
+ * - #[]=: Assigns specified elements with a given object.
+ * - #push, #append, #<<: Appends trailing elements.
+ * - #unshift, #prepend: Prepends leading elements.
+ * - #insert: Inserts given objects at a given offset; does not replace elements.
+ * - #concat: Appends all elements from given arrays.
+ * - #fill: Replaces specified elements with specified objects.
+ * - #replace: Replaces the content of +self+ with the content of a given array.
+ * - #reverse!: Replaces +self+ with its elements reversed.
+ * - #rotate!: Replaces +self+ with its elements rotated.
+ * - #shuffle!: Replaces +self+ with its elements in random order.
+ * - #sort!: Replaces +self+ with its elements sorted,
+ * as determined by <tt><=></tt> or a given block.
+ * - #sort_by!: Replaces +self+ with its elements sorted, as determined by a given block.
+ *
+ * === Methods for Deleting
+ *
+ * Each of these methods removes elements from +self+:
+ *
+ * - #pop: Removes and returns the last element.
+ * - #shift: Removes and returns the first element.
+ * - #compact!: Removes all +nil+ elements.
+ * - #delete: Removes elements equal to a given object.
+ * - #delete_at: Removes the element at a given offset.
+ * - #delete_if: Removes elements specified by a given block.
+ * - #keep_if: Removes elements not specified by a given block.
+ * - #reject!: Removes elements specified by a given block.
+ * - #select!, #filter!: Removes elements not specified by a given block.
+ * - #slice!: Removes and returns a sequence of elements.
+ * - #uniq!: Removes duplicates.
+ *
+ * === Methods for Combining
+ *
+ * - #&: Returns an array containing elements found both in +self+ and a given array.
+ * - #intersection: Returns an array containing elements found both in +self+
+ * and in each given array.
+ * - #+: Returns an array containing all elements of +self+ followed by all elements of a given array.
+ * - #-: Returns an array containing all elements of +self+ that are not found in a given array.
+ * - #|: Returns an array containing all elements of +self+ and all elements of a given array,
+ * duplicates removed.
+ * - #union: Returns an array containing all elements of +self+ and all elements of given arrays,
+ * duplicates removed.
+ * - #difference: Returns an array containing all elements of +self+ that are not found
+ * in any of the given arrays..
+ * - #product: Returns or yields all combinations of elements from +self+ and given arrays.
+ *
+ * === Methods for Iterating
+ *
+ * - #each: Passes each element to a given block.
+ * - #reverse_each: Passes each element, in reverse order, to a given block.
+ * - #each_index: Passes each element index to a given block.
+ * - #cycle: Calls a given block with each element, then does so again,
+ * for a specified number of times, or forever.
+ * - #combination: Calls a given block with combinations of elements of +self+;
+ * a combination does not use the same element more than once.
+ * - #permutation: Calls a given block with permutations of elements of +self+;
+ * a permutation does not use the same element more than once.
+ * - #repeated_combination: Calls a given block with combinations of elements of +self+;
+ * a combination may use the same element more than once.
+ * - #repeated_permutation: Calls a given block with permutations of elements of +self+;
+ * a permutation may use the same element more than once.
+ *
+ * === Methods for Converting
+ *
+ * - #map, #collect: Returns an array containing the block return-value for each element.
+ * - #map!, #collect!: Replaces each element with a block return-value.
+ * - #flatten: Returns an array that is a recursive flattening of +self+.
+ * - #flatten!: Replaces each nested array in +self+ with the elements from that array.
+ * - #inspect, #to_s: Returns a new String containing the elements.
+ * - #join: Returns a newsString containing the elements joined by the field separator.
+ * - #to_a: Returns +self+ or a new array containing all elements.
+ * - #to_ary: Returns +self+.
+ * - #to_h: Returns a new hash formed from the elements.
+ * - #transpose: Transposes +self+, which must be an array of arrays.
+ * - #zip: Returns a new array of arrays containing +self+ and given arrays;
+ * follow the link for details.
+ *
+ * === Other Methods
+ *
+ * - #*: Returns one of the following:
+ *
+ * - With integer argument +n+, a new array that is the concatenation
+ * of +n+ copies of +self+.
+ * - With string argument +field_separator+, a new string that is equivalent to
+ * <tt>join(field_separator)</tt>.
+ *
+ * - #abbrev: Returns a hash of unambiguous abbreviations for elements.
+ * - #pack: Packs the elements into a binary sequence.
+ * - #sum: Returns a sum of elements according to either <tt>+</tt> or a given block.
*/
void
@@ -8083,6 +8816,7 @@ Init_Array(void)
rb_include_module(rb_cArray, rb_mEnumerable);
rb_define_alloc_func(rb_cArray, empty_ary_alloc);
+ rb_define_singleton_method(rb_cArray, "new", rb_ary_s_new, -1);
rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1);
rb_define_singleton_method(rb_cArray, "try_convert", rb_ary_s_try_convert, 1);
rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
@@ -8108,6 +8842,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
rb_define_method(rb_cArray, "intersection", rb_ary_intersection_multi, -1);
+ rb_define_method(rb_cArray, "intersect?", rb_ary_intersect_p, 1);
rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
rb_define_alias(rb_cArray, "append", "push");
@@ -8120,7 +8855,7 @@ Init_Array(void)
rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
rb_define_method(rb_cArray, "length", rb_ary_length, 0);
- rb_define_alias(rb_cArray, "size", "length");
+ rb_define_method(rb_cArray, "size", rb_ary_length, 0);
rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
rb_define_method(rb_cArray, "index", rb_ary_index, -1);
diff --git a/array.rb b/array.rb
index a43a3b27b1..b9fa9844e6 100644
--- a/array.rb
+++ b/array.rb
@@ -49,6 +49,8 @@ class Array
# But +self+ may contain duplicates:
# a = [1, 1, 1, 2, 2, 3]
# a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2]
+ # The argument +n+ must be a non-negative numeric value.
+ # The order of the result array is unrelated to the order of +self+.
# Returns a new empty \Array if +self+ is empty.
#
# The optional +random+ argument will be used as the random number generator:
@@ -56,6 +58,12 @@ class Array
# a.sample(random: Random.new(1)) #=> 6
# a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
def sample(n = (ary = false), random: Random)
- Primitive.rb_ary_sample(random, n, ary)
+ if Primitive.mandatory_only?
+ # Primitive.cexpr! %{ rb_ary_sample(self, rb_cRandom, Qfalse, Qfalse) }
+ Primitive.ary_sample0
+ else
+ # Primitive.cexpr! %{ rb_ary_sample(self, random, n, ary) }
+ Primitive.ary_sample(random, n, ary)
+ end
end
end
diff --git a/ast.c b/ast.c
index 2af0b3e530..adb7287ed3 100644
--- a/ast.c
+++ b/ast.c
@@ -64,9 +64,8 @@ ast_new_internal(rb_ast_t *ast, const NODE *node)
return obj;
}
-static VALUE rb_ast_parse_str(VALUE str);
-static VALUE rb_ast_parse_file(VALUE path);
-static VALUE rb_ast_parse_array(VALUE array);
+static VALUE rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens);
+static VALUE rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens);
static VALUE
ast_parse_new(void)
@@ -86,29 +85,33 @@ ast_parse_done(rb_ast_t *ast)
}
static VALUE
-ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str)
+ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
{
- return rb_ast_parse_str(str);
+ return rb_ast_parse_str(str, keep_script_lines, error_tolerant, keep_tokens);
}
static VALUE
-rb_ast_parse_str(VALUE str)
+rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
{
rb_ast_t *ast = 0;
StringValue(str);
- ast = rb_parser_compile_string_path(ast_parse_new(), Qnil, str, 1);
+ VALUE vparser = ast_parse_new();
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
+ if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
+ ast = rb_parser_compile_string_path(vparser, Qnil, str, 1);
return ast_parse_done(ast);
}
static VALUE
-ast_s_parse_file(rb_execution_context_t *ec, VALUE module, VALUE path)
+ast_s_parse_file(rb_execution_context_t *ec, VALUE module, VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
{
- return rb_ast_parse_file(path);
+ return rb_ast_parse_file(path, keep_script_lines, error_tolerant, keep_tokens);
}
static VALUE
-rb_ast_parse_file(VALUE path)
+rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
{
VALUE f;
rb_ast_t *ast = 0;
@@ -117,7 +120,11 @@ rb_ast_parse_file(VALUE path)
FilePathValue(path);
f = rb_file_open_str(path, "r");
rb_funcall(f, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
- ast = rb_parser_compile_file_path(ast_parse_new(), Qnil, f, 1);
+ VALUE vparser = ast_parse_new();
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
+ if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
+ ast = rb_parser_compile_file_path(vparser, Qnil, f, 1);
rb_io_close(f);
return ast_parse_done(ast);
}
@@ -136,12 +143,16 @@ lex_array(VALUE array, int index)
}
static VALUE
-rb_ast_parse_array(VALUE array)
+rb_ast_parse_array(VALUE array, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
{
rb_ast_t *ast = 0;
array = rb_check_array_type(array);
- ast = rb_parser_compile_generic(ast_parse_new(), lex_array, Qnil, array, 1);
+ VALUE vparser = ast_parse_new();
+ if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
+ if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser);
+ ast = rb_parser_compile_generic(vparser, lex_array, Qnil, array, 1);
return ast_parse_done(ast);
}
@@ -188,35 +199,69 @@ script_lines(VALUE path)
}
static VALUE
-ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body)
+node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location)
{
- VALUE path, node, lines;
int node_id;
- const rb_iseq_t *iseq = NULL;
- if (rb_obj_is_proc(body)) {
- iseq = vm_proc_iseq(body);
+ if (!rb_frame_info_p(location)) {
+ rb_raise(rb_eTypeError, "Thread::Backtrace::Location object expected");
+ }
- if (!rb_obj_is_iseq((VALUE)iseq)) {
- iseq = NULL;
- }
+ node_id = rb_get_node_id_from_frame_info(location);
+ if (node_id == -1) {
+ return Qnil;
+ }
+
+ return INT2NUM(node_id);
+}
+
+static VALUE
+ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens)
+{
+ VALUE node, lines = Qnil;
+ const rb_iseq_t *iseq;
+ int node_id;
+
+ if (rb_frame_info_p(body)) {
+ iseq = rb_get_iseq_from_frame_info(body);
+ node_id = rb_get_node_id_from_frame_info(body);
}
else {
- iseq = rb_method_iseq(body);
+ iseq = NULL;
+
+ if (rb_obj_is_proc(body)) {
+ iseq = vm_proc_iseq(body);
+
+ if (!rb_obj_is_iseq((VALUE)iseq)) return Qnil;
+ }
+ else {
+ iseq = rb_method_iseq(body);
+ }
+ if (iseq) {
+ node_id = ISEQ_BODY(iseq)->location.node_id;
+ }
}
- if (!iseq) return Qnil;
+ if (!iseq) {
+ return Qnil;
+ }
+ lines = ISEQ_BODY(iseq)->variable.script_lines;
+
+ VALUE path = rb_iseq_path(iseq);
+ int e_option = RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0;
- path = rb_iseq_path(iseq);
- node_id = iseq->body->location.node_id;
- if (!NIL_P(lines = script_lines(path))) {
- node = rb_ast_parse_array(lines);
+ if (NIL_P(lines) && rb_iseq_from_eval_p(iseq) && !e_option) {
+ rb_raise(rb_eArgError, "cannot get AST for method defined in eval");
}
- else if (RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0) {
- node = rb_ast_parse_str(rb_e_script);
+
+ if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) {
+ node = rb_ast_parse_array(lines, keep_script_lines, error_tolerant, keep_tokens);
+ }
+ else if (e_option) {
+ node = rb_ast_parse_str(rb_e_script, keep_script_lines, error_tolerant, keep_tokens);
}
else {
- node = rb_ast_parse_file(path);
+ node = rb_ast_parse_file(path, keep_script_lines, error_tolerant, keep_tokens);
}
return node_find(node, node_id);
@@ -246,6 +291,15 @@ ast_node_type(rb_execution_context_t *ec, VALUE self)
return rb_sym_intern_ascii_cstr(node_type_to_str(data->node));
}
+static VALUE
+ast_node_node_id(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return INT2FIX(nd_node_id(data->node));
+}
+
#define NEW_CHILD(ast, node) node ? ast_new_internal(ast, node) : Qnil
static VALUE
@@ -274,7 +328,7 @@ dump_block(rb_ast_t *ast, const NODE *node)
do {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
} while (node->nd_next &&
- nd_type(node->nd_next) == NODE_BLOCK &&
+ nd_type_p(node->nd_next, NODE_BLOCK) &&
(node = node->nd_next, 1));
if (node->nd_next) {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
@@ -289,7 +343,7 @@ dump_array(rb_ast_t *ast, const NODE *node)
VALUE ary = rb_ary_new();
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
- while (node->nd_next && nd_type(node->nd_next) == NODE_LIST) {
+ while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) {
node = node->nd_next;
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
}
@@ -346,7 +400,7 @@ node_children(rb_ast_t *ast, const NODE *node)
case NODE_WHILE:
case NODE_UNTIL:
return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body),
- (node->nd_state ? Qtrue : Qfalse));
+ RBOOL(node->nd_state));
case NODE_ITER:
case NODE_FOR:
return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body);
@@ -375,7 +429,7 @@ node_children(rb_ast_t *ast, const NODE *node)
while (1) {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st));
- if (!node->nd_2nd || nd_type(node->nd_2nd) != (int)type)
+ if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type))
break;
node = node->nd_2nd;
}
@@ -393,7 +447,6 @@ node_children(rb_ast_t *ast, const NODE *node)
}
case NODE_LASGN:
case NODE_DASGN:
- case NODE_DASGN_CURR:
case NODE_IASGN:
case NODE_CVASGN:
case NODE_GASGN:
@@ -413,7 +466,7 @@ node_children(rb_ast_t *ast, const NODE *node)
NEW_CHILD(ast, node->nd_args->nd_body));
case NODE_OP_ASGN2:
return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv),
- node->nd_next->nd_aid ? Qtrue : Qfalse,
+ RBOOL(node->nd_next->nd_aid),
ID2SYM(node->nd_next->nd_vid),
ID2SYM(node->nd_next->nd_mid),
NEW_CHILD(ast, node->nd_value));
@@ -576,11 +629,11 @@ node_children(rb_ast_t *ast, const NODE *node)
}
case NODE_SCOPE:
{
- ID *tbl = node->nd_tbl;
- int i, size = tbl ? (int)*tbl++ : 0;
+ rb_ast_id_table_t *tbl = node->nd_tbl;
+ int i, size = tbl ? tbl->size : 0;
VALUE locals = rb_ary_new_capa(size);
for (i = 0; i < size; i++) {
- rb_ary_push(locals, var_name(tbl[i]));
+ rb_ary_push(locals, var_name(tbl->ids[i]));
}
return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body));
}
@@ -615,6 +668,8 @@ node_children(rb_ast_t *ast, const NODE *node)
NEW_CHILD(ast, node->nd_pkwargs),
kwrest);
}
+ case NODE_ERROR:
+ return rb_ary_new_from_node_args(ast, 0);
case NODE_ARGS_AUX:
case NODE_LAST:
break;
@@ -669,6 +724,15 @@ ast_node_last_column(rb_execution_context_t *ec, VALUE self)
}
static VALUE
+ast_node_all_tokens(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return rb_ast_tokens(data->ast);
+}
+
+static VALUE
ast_node_inspect(rb_execution_context_t *ec, VALUE self)
{
VALUE str;
@@ -688,6 +752,16 @@ ast_node_inspect(rb_execution_context_t *ec, VALUE self)
return str;
}
+static VALUE
+ast_node_script_lines(rb_execution_context_t *ec, VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+ VALUE ret = data->ast->body.script_lines;
+ if (!RB_TYPE_P(ret, T_ARRAY)) return Qnil;
+ return ret;
+}
+
#include "ast.rbinc"
void
diff --git a/ast.rb b/ast.rb
index 34fa645671..f3f72c747f 100644
--- a/ast.rb
+++ b/ast.rb
@@ -1,145 +1,275 @@
# for ast.c
-class RubyVM
+# AbstractSyntaxTree provides methods to parse Ruby code into
+# abstract syntax trees. The nodes in the tree
+# are instances of RubyVM::AbstractSyntaxTree::Node.
+#
+# This module is MRI specific as it exposes implementation details
+# of the MRI abstract syntax tree.
+#
+# This module is experimental and its API is not stable, therefore it might
+# change without notice. As examples, the order of children nodes is not
+# guaranteed, the number of children nodes might change, there is no way to
+# access children nodes by name, etc.
+#
+# If you are looking for a stable API or an API working under multiple Ruby
+# implementations, consider using the _parser_ gem or Ripper. If you would
+# like to make RubyVM::AbstractSyntaxTree stable, please join the discussion
+# at https://bugs.ruby-lang.org/issues/14844.
+#
+module RubyVM::AbstractSyntaxTree
- # AbstractSyntaxTree provides methods to parse Ruby code into
- # abstract syntax trees. The nodes in the tree
- # are instances of RubyVM::AbstractSyntaxTree::Node.
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
- # This module is MRI specific as it exposes implementation details
- # of the MRI abstract syntax tree.
+ # Parses the given _string_ into an abstract syntax tree,
+ # returning the root node of that tree.
#
- # This module is experimental and its API is not stable, therefore it might
- # change without notice. As examples, the order of children nodes is not
- # guaranteed, the number of children nodes might change, there is no way to
- # access children nodes by name, etc.
+ # RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
#
- # If you are looking for a stable API or an API working under multiple Ruby
- # implementations, consider using the _parser_ gem or Ripper. If you would
- # like to make RubyVM::AbstractSyntaxTree stable, please join the discussion
- # at https://bugs.ruby-lang.org/issues/14844.
+ # If <tt>keep_script_lines: true</tt> option is provided, the text of the parsed
+ # source is associated with nodes and is available via Node#script_lines.
#
- module AbstractSyntaxTree
+ # If <tt>keep_tokens: true</tt> option is provided, Node#tokens are populated.
+ #
+ # SyntaxError is raised if the given _string_ is invalid syntax. To overwrite this
+ # behavior, <tt>error_tolerant: true</tt> can be provided. In this case, the parser
+ # will produce a tree where expressions with syntax errors would be represented by
+ # Node with <tt>type=:ERROR</tt>.
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2")
+ # # <internal:ast>:33:in `parse': syntax error, unexpected ';', expecting ')' (SyntaxError)
+ # # x = 1; p(x; y=2
+ # # ^
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2", error_tolerant: true)
+ # # (SCOPE@1:0-1:15
+ # # tbl: [:x, :y]
+ # # args: nil
+ # # body: (BLOCK@1:0-1:15 (LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)) (ERROR@1:7-1:11) (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))))
+ # root.children.last.children
+ # # [(LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)),
+ # # (ERROR@1:7-1:11),
+ # # (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))]
+ #
+ # Note that parsing continues even after the errored expresion.
+ #
+ def self.parse string, keep_script_lines: false, error_tolerant: false, keep_tokens: false
+ Primitive.ast_s_parse string, keep_script_lines, error_tolerant, keep_tokens
+ end
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.parse_file(pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ #
+ # Reads the file from _pathname_, then parses it like ::parse,
+ # returning the root node of the abstract syntax tree.
+ #
+ # SyntaxError is raised if _pathname_'s contents are not
+ # valid Ruby syntax.
+ #
+ # RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
+ #
+ # See ::parse for explanation of keyword argument meaning and usage.
+ def self.parse_file pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false
+ Primitive.ast_s_parse_file pathname, keep_script_lines, error_tolerant, keep_tokens
+ end
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ #
+ # Returns AST nodes of the given _proc_ or _method_.
+ #
+ # RubyVM::AbstractSyntaxTree.of(proc {1 + 2})
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42>
+ #
+ # def hello
+ # puts "hello, world"
+ # end
+ #
+ # RubyVM::AbstractSyntaxTree.of(method(:hello))
+ # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
+ #
+ # See ::parse for explanation of keyword argument meaning and usage.
+ def self.of body, keep_script_lines: false, error_tolerant: false, keep_tokens: false
+ Primitive.ast_s_of body, keep_script_lines, error_tolerant, keep_tokens
+ end
+
+ # call-seq:
+ # RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(backtrace_location) -> integer
+ #
+ # Returns the node id for the given backtrace location.
+ #
+ # begin
+ # raise
+ # rescue => e
+ # loc = e.backtrace_locations.first
+ # RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ # end # => 0
+ def self.node_id_for_backtrace_location backtrace_location
+ Primitive.node_id_for_backtrace_location backtrace_location
+ end
+
+ # RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in
+ # RubyVM::AbstractSyntaxTree.
+ #
+ # This class is MRI specific.
+ #
+ class Node
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse(string) -> RubyVM::AbstractSyntaxTree::Node
+ # node.type -> symbol
#
- # Parses the given _string_ into an abstract syntax tree,
- # returning the root node of that tree.
+ # Returns the type of this node as a symbol.
#
- # SyntaxError is raised if the given _string_ is invalid syntax.
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
+ # root.type # => :SCOPE
+ # lasgn = root.children[2]
+ # lasgn.type # => :LASGN
+ # call = lasgn.children[1]
+ # call.type # => :OPCALL
+ def type
+ Primitive.ast_node_type
+ end
+
+ # call-seq:
+ # node.first_lineno -> integer
#
- # RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
- # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
- def self.parse string
- Primitive.ast_s_parse string
+ # The line number in the source code where this AST's text began.
+ def first_lineno
+ Primitive.ast_node_first_lineno
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse_file(pathname) -> RubyVM::AbstractSyntaxTree::Node
+ # node.first_column -> integer
#
- # Reads the file from _pathname_, then parses it like ::parse,
- # returning the root node of the abstract syntax tree.
+ # The column number in the source code where this AST's text began.
+ def first_column
+ Primitive.ast_node_first_column
+ end
+
+ # call-seq:
+ # node.last_lineno -> integer
#
- # SyntaxError is raised if _pathname_'s contents are not
- # valid Ruby syntax.
+ # The line number in the source code where this AST's text ended.
+ def last_lineno
+ Primitive.ast_node_last_lineno
+ end
+
+ # call-seq:
+ # node.last_column -> integer
#
- # RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
- # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
- def self.parse_file pathname
- Primitive.ast_s_parse_file pathname
+ # The column number in the source code where this AST's text ended.
+ def last_column
+ Primitive.ast_node_last_column
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.of(proc) -> RubyVM::AbstractSyntaxTree::Node
- # RubyVM::AbstractSyntaxTree.of(method) -> RubyVM::AbstractSyntaxTree::Node
+ # node.tokens -> array
#
- # Returns AST nodes of the given _proc_ or _method_.
+ # Returns tokens corresponding to the location of the node.
+ # Returns +nil+ if +keep_tokens+ is not enabled when #parse method is called.
#
- # RubyVM::AbstractSyntaxTree.of(proc {1 + 2})
- # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:35-1:42>
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true)
+ # root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
+ # root.tokens.map{_1[2]}.join # => "x = 1 + 2"
#
- # def hello
- # puts "hello, world"
- # end
+ # Token is an array of:
#
- # RubyVM::AbstractSyntaxTree.of(method(:hello))
- # # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
- def self.of body
- Primitive.ast_s_of body
- end
+ # - id
+ # - token type
+ # - source code text
+ # - location [ first_lineno, first_column, last_lineno, last_column ]
+ def tokens
+ return nil unless all_tokens
- # RubyVM::AbstractSyntaxTree::Node instances are created by parse methods in
- # RubyVM::AbstractSyntaxTree.
- #
- # This class is MRI specific.
- #
- class Node
-
- # call-seq:
- # node.type -> symbol
- #
- # Returns the type of this node as a symbol.
- #
- # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
- # root.type # => :SCOPE
- # lasgn = root.children[2]
- # lasgn.type # => :LASGN
- # call = lasgn.children[1]
- # call.type # => :OPCALL
- def type
- Primitive.ast_node_type
+ all_tokens.each_with_object([]) do |token, a|
+ loc = token.last
+ if ([first_lineno, first_column] <=> [loc[0], loc[1]]) <= 0 &&
+ ([last_lineno, last_column] <=> [loc[2], loc[3]]) >= 0
+ a << token
+ end
end
+ end
- # call-seq:
- # node.first_lineno -> integer
- #
- # The line number in the source code where this AST's text began.
- def first_lineno
- Primitive.ast_node_first_lineno
- end
+ # call-seq:
+ # node.all_tokens -> array
+ #
+ # Returns all tokens for the input script regardless the receiver node.
+ # Returns +nil+ if +keep_tokens+ is not enabled when #parse method is called.
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true)
+ # root.all_tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
+ # root.children[-1].all_tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...]
+ def all_tokens
+ Primitive.ast_node_all_tokens
+ end
- # call-seq:
- # node.first_column -> integer
- #
- # The column number in the source code where this AST's text began.
- def first_column
- Primitive.ast_node_first_column
- end
+ # call-seq:
+ # node.children -> array
+ #
+ # Returns AST nodes under this one. Each kind of node
+ # has different children, depending on what kind of node it is.
+ #
+ # The returned array may contain other nodes or <code>nil</code>.
+ def children
+ Primitive.ast_node_children
+ end
- # call-seq:
- # node.last_lineno -> integer
- #
- # The line number in the source code where this AST's text ended.
- def last_lineno
- Primitive.ast_node_last_lineno
- end
+ # call-seq:
+ # node.inspect -> string
+ #
+ # Returns debugging information about this node as a string.
+ def inspect
+ Primitive.ast_node_inspect
+ end
- # call-seq:
- # node.last_column -> integer
- #
- # The column number in the source code where this AST's text ended.
- def last_column
- Primitive.ast_node_last_column
- end
+ # call-seq:
+ # node.node_id -> integer
+ #
+ # Returns an internal node_id number.
+ # Note that this is an API for ruby internal use, debugging,
+ # and research. Do not use this for any other purpose.
+ # The compatibility is not guaranteed.
+ def node_id
+ Primitive.ast_node_node_id
+ end
- # call-seq:
- # node.children -> array
- #
- # Returns AST nodes under this one. Each kind of node
- # has different children, depending on what kind of node it is.
- #
- # The returned array may contain other nodes or <code>nil</code>.
- def children
- Primitive.ast_node_children
- end
+ # call-seq:
+ # node.script_lines -> array
+ #
+ # Returns the original source code as an array of lines.
+ #
+ # Note that this is an API for ruby internal use, debugging,
+ # and research. Do not use this for any other purpose.
+ # The compatibility is not guaranteed.
+ def script_lines
+ Primitive.ast_node_script_lines
+ end
- # call-seq:
- # node.inspect -> string
- #
- # Returns debugging information about this node as a string.
- def inspect
- Primitive.ast_node_inspect
+ # call-seq:
+ # node.source -> string
+ #
+ # Returns the code fragment that corresponds to this AST.
+ #
+ # Note that this is an API for ruby internal use, debugging,
+ # and research. Do not use this for any other purpose.
+ # The compatibility is not guaranteed.
+ #
+ # Also note that this API may return an incomplete code fragment
+ # that does not parse; for example, a here document following
+ # an expression may be dropped.
+ def source
+ lines = script_lines
+ if lines
+ lines = lines[first_lineno - 1 .. last_lineno - 1]
+ lines[-1] = lines[-1][0...last_column]
+ lines[0] = lines[0][first_column..-1]
+ lines.join
+ else
+ nil
end
end
end
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000000..f8cdf3c0c1
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+PWD=
+case "$0" in
+*/*) srcdir=`dirname $0`;;
+*) srcdir="";;
+esac
+
+symlink='--install --symlink'
+case " $* " in
+ *" -i "*|*" --install "*)
+ # reset to copy missing standard auxiliary files, instead of symlinks
+ symlink=
+ ;;
+esac
+
+exec ${AUTORECONF:-autoreconf} ${symlink} "$@" ${srcdir:+"$srcdir"}
diff --git a/basictest/test.rb b/basictest/test.rb
index 52008b78db..95875b52a6 100755
--- a/basictest/test.rb
+++ b/basictest/test.rb
@@ -1960,6 +1960,8 @@ test_ok(p1.call == 5)
test_ok(i7 == nil)
end
+# WASI doesn't support spawning a new process for now.
+unless /wasi/ =~ RUBY_PLATFORM
test_check "system"
test_ok(`echo foobar` == "foobar\n")
test_ok(`./miniruby -e 'print "foobar"'` == 'foobar')
@@ -2010,6 +2012,7 @@ test_ok(done)
File.unlink script_tmp or `/bin/rm -f "#{script_tmp}"`
File.unlink "#{script_tmp}.bak" or `/bin/rm -f "#{script_tmp}.bak"`
+end # not /wasi/ =~ RUBY_PLATFORM
test_check "const"
TEST1 = 1
diff --git a/benchmark/README.md b/benchmark/README.md
index 39a5aa139b..e11381cad9 100644
--- a/benchmark/README.md
+++ b/benchmark/README.md
@@ -28,15 +28,17 @@ See also:
```console
Usage: benchmark-driver [options] RUBY|YAML...
- -r, --runner TYPE Specify runner type: ips, time, memory, once (default: ips)
- -o, --output TYPE Specify output type: compare, simple, markdown, record (default: compare)
+ -r, --runner TYPE Specify runner type: ips, time, memory, once, block (default: ips)
+ -o, --output TYPE Specify output type: compare, simple, markdown, record, all (default: compare)
-e, --executables EXECS Ruby executables (e1::path1 arg1; e2::path2 arg2;...)
--rbenv VERSIONS Ruby executables in rbenv (x.x.x arg1;y.y.y arg2;...)
--repeat-count NUM Try benchmark NUM times and use the fastest result or the worst memory usage
--repeat-result TYPE Yield "best", "average" or "worst" result with --repeat-count (default: best)
+ --alternate Alternate executables instead of running the same executable in a row with --repeat-count
--bundler Install and use gems specified in Gemfile
--filter REGEXP Filter out benchmarks with given regexp
--run-duration SECONDS Warmup estimates loop_count to run for this duration (default: 3)
+ --timeout SECONDS Timeout ruby command execution with timeout(1)
-v, --verbose Verbose mode. Multiple -v options increase visilibity (max: 2)
```
diff --git a/benchmark/array_sample.yml b/benchmark/array_sample.yml
new file mode 100644
index 0000000000..1cd2b34794
--- /dev/null
+++ b/benchmark/array_sample.yml
@@ -0,0 +1,4 @@
+prelude: ary = (1..10_000).to_a
+benchmark:
+ - ary.sample
+ - ary.sample(2)
diff --git a/benchmark/array_sort_int.yml b/benchmark/array_sort_int.yml
new file mode 100644
index 0000000000..7b9027ebf7
--- /dev/null
+++ b/benchmark/array_sort_int.yml
@@ -0,0 +1,15 @@
+prelude: |
+ ary2 = 2.times.to_a.shuffle
+ ary10 = 10.times.to_a.shuffle
+ ary100 = 100.times.to_a.shuffle
+ ary1000 = 1000.times.to_a.shuffle
+ ary10000 = 10000.times.to_a.shuffle
+
+benchmark:
+ ary2.sort: ary2.sort
+ ary10.sort: ary10.sort
+ ary100.sort: ary100.sort
+ ary1000.sort: ary1000.sort
+ ary10000.sort: ary10000.sort
+
+loop_count: 10000
diff --git a/benchmark/attr_accessor.yml b/benchmark/attr_accessor.yml
new file mode 100644
index 0000000000..82134cdf9b
--- /dev/null
+++ b/benchmark/attr_accessor.yml
@@ -0,0 +1,29 @@
+prelude: |
+ class C
+ attr_accessor :x
+ def initialize
+ @x = nil
+ end
+ class_eval <<-END
+ def ar
+ #{'x;'*256}
+ end
+ def aw
+ #{'self.x = nil;'*256}
+ end
+ def arm
+ m = method(:x)
+ #{'m.call;'*256}
+ end
+ def awm
+ m = method(:x=)
+ #{'m.call(nil);'*256}
+ end
+ END
+ end
+ obj = C.new
+benchmark:
+ attr_reader: "obj.ar"
+ attr_writer: "obj.aw"
+ attr_reader_method: "obj.arm"
+ attr_writer_method: "obj.awm"
diff --git a/benchmark/buffer_each.yml b/benchmark/buffer_each.yml
new file mode 100644
index 0000000000..417941104e
--- /dev/null
+++ b/benchmark/buffer_each.yml
@@ -0,0 +1,27 @@
+prelude: |
+ # frozen_string_literal: true
+ Warning[:experimental] = false
+ string = "The quick brown fox jumped over the lazy dog."
+ array = string.bytes
+ buffer = IO::Buffer.for(string)
+benchmark:
+ string.each_byte: |
+ upcased = String.new
+ string.each_byte do |byte|
+ upcased << (byte ^ 32)
+ end
+ array.each: |
+ upcased = String.new
+ array.each do |byte|
+ upcased << (byte ^ 32)
+ end
+ buffer.each: |
+ upcased = String.new
+ buffer.each(:U8) do |offset, byte|
+ upcased << (byte ^ 32)
+ end
+ buffer.each_byte: |
+ upcased = String.new
+ buffer.each_byte do |byte|
+ upcased << (byte ^ 32)
+ end
diff --git a/benchmark/buffer_get.yml b/benchmark/buffer_get.yml
new file mode 100644
index 0000000000..9e1f99d64e
--- /dev/null
+++ b/benchmark/buffer_get.yml
@@ -0,0 +1,25 @@
+prelude: |
+ # frozen_string_literal: true
+ Warning[:experimental] = false
+ string = "The quick brown fox jumped over the lazy dog."
+ buffer = IO::Buffer.for(string)
+ format = [:U32, :U32, :U32, :U32]
+benchmark:
+ string.unpack1: |
+ [
+ string.unpack1("N"),
+ string.unpack1("N", offset: 4),
+ string.unpack1("N", offset: 8),
+ string.unpack1("N", offset: 12),
+ ]
+ buffer.get_value: |
+ [
+ buffer.get_value(:U32, 0),
+ buffer.get_value(:U32, 4),
+ buffer.get_value(:U32, 8),
+ buffer.get_value(:U32, 12),
+ ]
+ buffer.get_values: |
+ buffer.get_values(format, 0)
+ string.unpack: |
+ string.unpack("NNNN")
diff --git a/benchmark/cgi_escape_html.yml b/benchmark/cgi_escape_html.yml
index af6abd08ac..655be9d7d8 100644
--- a/benchmark/cgi_escape_html.yml
+++ b/benchmark/cgi_escape_html.yml
@@ -1,32 +1,23 @@
-prelude: require 'cgi/escape'
+prelude: |
+ # frozen_string_literal: true
+ require 'cgi/escape'
benchmark:
- - name: escape_html_blank
- prelude: str = ""
- script: CGI.escapeHTML(str)
+ - script: CGI.escapeHTML("")
loop_count: 20000000
- - name: escape_html_short_none
- prelude: str = "abcde"
- script: CGI.escapeHTML(str)
+ - script: CGI.escapeHTML("abcde")
loop_count: 20000000
- - name: escape_html_short_one
- prelude: str = "abcd<"
- script: CGI.escapeHTML(str)
+ - script: CGI.escapeHTML("abcd<")
loop_count: 20000000
- - name: escape_html_short_all
- prelude: str = "'&\"<>"
- script: CGI.escapeHTML(str)
+ - script: CGI.escapeHTML("'&\"<>")
loop_count: 5000000
- - name: escape_html_long_none
- prelude: str = "abcde" * 300
- script: CGI.escapeHTML(str)
+ - prelude: long_no_escape = "abcde" * 300
+ script: CGI.escapeHTML(long_no_escape)
loop_count: 1000000
- - name: escape_html_long_all
- prelude: str = "'&\"<>" * 10
- script: CGI.escapeHTML(str)
+ - prelude: long_all_escape = "'&\"<>" * 10
+ script: CGI.escapeHTML(long_all_escape)
loop_count: 1000000
- - name: escape_html_real
- prelude: | # http://example.com/
- str = <<~HTML
+ - prelude: | # http://example.com/
+ example_html = <<~HTML
<body>
<div>
<h1>Example Domain</h1>
@@ -36,5 +27,5 @@ benchmark:
</div>
</body>
HTML
- script: CGI.escapeHTML(str)
+ script: CGI.escapeHTML(example_html)
loop_count: 1000000
diff --git a/benchmark/constant_invalidation.rb b/benchmark/constant_invalidation.rb
new file mode 100644
index 0000000000..a95ec6f37e
--- /dev/null
+++ b/benchmark/constant_invalidation.rb
@@ -0,0 +1,22 @@
+$VERBOSE = nil
+
+CONSTANT1 = 1
+CONSTANT2 = 1
+CONSTANT3 = 1
+CONSTANT4 = 1
+CONSTANT5 = 1
+
+def constants
+ [CONSTANT1, CONSTANT2, CONSTANT3, CONSTANT4, CONSTANT5]
+end
+
+500_000.times do
+ constants
+
+ # With previous behavior, this would cause all of the constant caches
+ # associated with the constant lookups listed above to invalidate, meaning
+ # they would all have to be fetched again. With current behavior, it only
+ # invalidates when a name matches, so the following constant set shouldn't
+ # impact the constant lookups listed above.
+ INVALIDATE = true
+end
diff --git a/benchmark/enum_minmax.yml b/benchmark/enum_minmax.yml
new file mode 100644
index 0000000000..9d01731abb
--- /dev/null
+++ b/benchmark/enum_minmax.yml
@@ -0,0 +1,25 @@
+prelude: |
+ set2 = 2.times.to_a.shuffle.to_set
+ set10 = 10.times.to_a.shuffle.to_set
+ set100 = 100.times.to_a.shuffle.to_set
+ set1000 = 1000.times.to_a.shuffle.to_set
+ set10000 = 10000.times.to_a.shuffle.to_set
+
+benchmark:
+ set2.min: set2.min
+ set10.min: set10.min
+ set100.min: set100.min
+ set1000.min: set1000.min
+ set10000.min: set10000.min
+ set2.max: set2.max
+ set10.max: set10.max
+ set100.max: set100.max
+ set1000.max: set1000.max
+ set10000.max: set10000.max
+ set2.minmax: set2.minmax
+ set10.minmax: set10.minmax
+ set100.minmax: set100.minmax
+ set1000.minmax: set1000.minmax
+ set10000.minmax: set10000.minmax
+
+loop_count: 10000
diff --git a/benchmark/enum_sort.yml b/benchmark/enum_sort.yml
new file mode 100644
index 0000000000..6f26e748c6
--- /dev/null
+++ b/benchmark/enum_sort.yml
@@ -0,0 +1,15 @@
+prelude: |
+ set2 = 2.times.to_a.shuffle.to_set
+ set10 = 10.times.to_a.shuffle.to_set
+ set100 = 100.times.to_a.shuffle.to_set
+ set1000 = 1000.times.to_a.shuffle.to_set
+ set10000 = 10000.times.to_a.shuffle.to_set
+
+benchmark:
+ set2.sort_by: set2.sort_by { 0 }
+ set10.sort_by: set10.sort_by { 0 }
+ set100.sort_by: set100.sort_by { 0 }
+ set1000.sort_by: set1000.sort_by { 0 }
+ set10000.sort_by: set10000.sort_by { 0 }
+
+loop_count: 10000
diff --git a/benchmark/enum_tally.yml b/benchmark/enum_tally.yml
new file mode 100644
index 0000000000..edd2e040a0
--- /dev/null
+++ b/benchmark/enum_tally.yml
@@ -0,0 +1,4 @@
+prelude: |
+ list = ("aaa".."zzz").to_a*10
+benchmark:
+ tally: list.tally
diff --git a/benchmark/erb_escape_html.yml b/benchmark/erb_escape_html.yml
new file mode 100644
index 0000000000..ca28d756e7
--- /dev/null
+++ b/benchmark/erb_escape_html.yml
@@ -0,0 +1,31 @@
+prelude: |
+ # frozen_string_literal: true
+ require 'erb'
+benchmark:
+ - script: ERB::Util.html_escape("")
+ loop_count: 20000000
+ - script: ERB::Util.html_escape("abcde")
+ loop_count: 20000000
+ - script: ERB::Util.html_escape("abcd<")
+ loop_count: 20000000
+ - script: ERB::Util.html_escape("'&\"<>")
+ loop_count: 5000000
+ - prelude: long_no_escape = "abcde" * 300
+ script: ERB::Util.html_escape(long_no_escape)
+ loop_count: 1000000
+ - prelude: long_all_escape = "'&\"<>" * 10
+ script: ERB::Util.html_escape(long_all_escape)
+ loop_count: 1000000
+ - prelude: | # http://example.com/
+ example_html = <<~HTML
+ <body>
+ <div>
+ <h1>Example Domain</h1>
+ <p>This domain is established to be used for illustrative examples in documents. You may use this
+ domain in examples without prior coordination or asking for permission.</p>
+ <p><a href="http://www.iana.org/domains/example">More information...</a></p>
+ </div>
+ </body>
+ HTML
+ script: ERB::Util.html_escape(example_html)
+ loop_count: 1000000
diff --git a/benchmark/float_methods.yml b/benchmark/float_methods.yml
new file mode 100644
index 0000000000..56ea41effc
--- /dev/null
+++ b/benchmark/float_methods.yml
@@ -0,0 +1,14 @@
+prelude: |
+ flo = 4.2
+benchmark:
+ to_f: |
+ flo.to_f
+ abs: |
+ flo.abs
+ magnitude: |
+ flo.magnitude
+ -@: |
+ -flo
+ zero?: |
+ flo.zero?
+loop_count: 20000000
diff --git a/benchmark/float_neg_posi.yml b/benchmark/float_neg_posi.yml
new file mode 100644
index 0000000000..172db1bf6d
--- /dev/null
+++ b/benchmark/float_neg_posi.yml
@@ -0,0 +1,8 @@
+prelude: |
+ flo = 4.2
+benchmark:
+ negative?: |
+ flo.negative?
+ positive?: |
+ flo.positive?
+loop_count: 20000000
diff --git a/benchmark/float_to_s.yml b/benchmark/float_to_s.yml
new file mode 100644
index 0000000000..0abae5cdb8
--- /dev/null
+++ b/benchmark/float_to_s.yml
@@ -0,0 +1,7 @@
+prelude: |
+ floats = [*0.0.step(1.0, 0.0001)]
+
+benchmark:
+ to_s: floats.each {|f| f.to_s}
+
+loop_count: 1000
diff --git a/benchmark/hash_aref_array.rb b/benchmark/hash_aref_array.rb
new file mode 100644
index 0000000000..ac7a683d95
--- /dev/null
+++ b/benchmark/hash_aref_array.rb
@@ -0,0 +1,5 @@
+h = {}
+arrays = (0..99).each_slice(10).to_a
+#STDERR.puts arrays.inspect
+arrays.each { |s| h[s] = s }
+200_000.times { arrays.each { |s| h[s] } }
diff --git a/benchmark/hash_first.yml b/benchmark/hash_first.yml
new file mode 100644
index 0000000000..c26df1a7ed
--- /dev/null
+++ b/benchmark/hash_first.yml
@@ -0,0 +1,11 @@
+prelude: |
+ hash1 = 1_000_000.times.to_h { [rand, true]}
+ hash2 = hash1.dup
+ hash2.keys[1..100_000].each { hash2.delete _1 }
+ hash2.delete hash2.first[0]
+
+benchmark:
+ hash1: hash1.first
+ hash2: hash2.first
+
+loop_count: 100_000
diff --git a/benchmark/io_write.rb b/benchmark/io_write.rb
new file mode 100644
index 0000000000..cdb409948b
--- /dev/null
+++ b/benchmark/io_write.rb
@@ -0,0 +1,22 @@
+#!/usr/bin/env ruby
+
+require 'benchmark'
+
+i, o = IO.pipe
+o.sync = true
+
+DOT = ".".freeze
+
+chunks = 100_000.times.collect{DOT}
+
+thread = Thread.new do
+ while i.read(1024)
+ end
+end
+
+100.times do
+ o.write(*chunks)
+end
+
+o.close
+thread.join
diff --git a/benchmark/iseq_load_from_binary.yml b/benchmark/iseq_load_from_binary.yml
new file mode 100644
index 0000000000..7e9d73bdd4
--- /dev/null
+++ b/benchmark/iseq_load_from_binary.yml
@@ -0,0 +1,25 @@
+prelude: |
+ symbol = RubyVM::InstructionSequence.compile(":foo; :bar; :baz; :egg; :spam").to_binary
+
+ define_method = RubyVM::InstructionSequence.compile(%{
+ def foo; end
+ def bar; end
+ def baz; end
+ def egg; end
+ def spam; end
+ }).to_binary
+
+ all = RubyVM::InstructionSequence.compile(%{
+ module Foo; def foo; :foo; end; end
+ module Bar; def bar; :bar; end; end
+ module Baz; def baz; :baz; end; end
+ class Egg; def egg; :egg; end; end
+ class Spaml; def spam; :spam; end; end
+ }).to_binary
+
+benchmark:
+ symbol: RubyVM::InstructionSequence.load_from_binary(symbol)
+ define_method: RubyVM::InstructionSequence.load_from_binary(define_method)
+ all: RubyVM::InstructionSequence.load_from_binary(all)
+
+loop_count: 100_000
diff --git a/benchmark/ivar_extend.yml b/benchmark/ivar_extend.yml
new file mode 100644
index 0000000000..eb9ee923f5
--- /dev/null
+++ b/benchmark/ivar_extend.yml
@@ -0,0 +1,23 @@
+prelude: |
+ class Embedded
+ def initialize
+ @a = 1
+ @b = 1
+ @c = 1
+ end
+ end
+
+ class Extended
+ def initialize
+ @a = 1
+ @b = 1
+ @c = 1
+ @d = 1
+ @e = 1
+ @f = 1
+ end
+ end
+benchmark:
+ embedded: Embedded.new
+ extended: Extended.new
+loop_count: 20_000_000
diff --git a/benchmark/lib/benchmark_driver/runner/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb
index 1d4693e8be..3a58a620de 100644
--- a/benchmark/lib/benchmark_driver/runner/mjit.rb
+++ b/benchmark/lib/benchmark_driver/runner/mjit.rb
@@ -16,7 +16,7 @@ class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips
job.prelude = "#{job.prelude}\n#{<<~EOS}"
if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
__bmdv_ruby_i = 0
- while __bmdv_ruby_i < 10000 # jit_min_calls
+ while __bmdv_ruby_i < 10000 # MJIT call threshold
#{job.script}
__bmdv_ruby_i += 1
end
diff --git a/benchmark/lib/benchmark_driver/runner/mjit_exec.rb b/benchmark/lib/benchmark_driver/runner/mjit_exec.rb
deleted file mode 100644
index eac3dfba84..0000000000
--- a/benchmark/lib/benchmark_driver/runner/mjit_exec.rb
+++ /dev/null
@@ -1,237 +0,0 @@
-require 'benchmark_driver/struct'
-require 'benchmark_driver/metric'
-require 'erb'
-
-# A special runner dedicated for measuring mjit_exec overhead.
-class BenchmarkDriver::Runner::MjitExec
- METRIC = BenchmarkDriver::Metric.new(name: 'Iteration per second', unit: 'i/s')
-
- # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
- Job = ::BenchmarkDriver::Struct.new(
- :name, # @param [String] name - This is mandatory for all runner
- :metrics, # @param [Array<BenchmarkDriver::Metric>]
- :num_methods, # @param [Integer] num_methods - The number of methods to be defined
- :loop_count, # @param [Integer] loop_count
- :from_jit, # @param [TrueClass,FalseClass] from_jit - Whether the mjit_exec() is from JIT or not
- :to_jit, # @param [TrueClass,FalseClass] to_jit - Whether the mjit_exec() is to JIT or not
- )
- # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
- class << JobParser = Module.new
- # @param [Array,String] num_methods
- # @param [Integer] loop_count
- # @param [TrueClass,FalseClass] from_jit
- # @param [TrueClass,FalseClass] to_jit
- def parse(num_methods:, loop_count:, from_jit:, to_jit:)
- if num_methods.is_a?(String)
- num_methods = eval(num_methods)
- end
-
- num_methods.map do |num|
- if num_methods.size > 1
- suffix = "[#{'%4d' % num}]"
- else
- suffix = "_#{num}"
- end
- Job.new(
- name: "mjit_exec_#{from_jit ? 'JT' : 'VM'}2#{to_jit ? 'JT' : 'VM'}#{suffix}",
- metrics: [METRIC],
- num_methods: num,
- loop_count: loop_count,
- from_jit: from_jit,
- to_jit: to_jit,
- )
- end
- end
- end
-
- # @param [BenchmarkDriver::Config::RunnerConfig] config
- # @param [BenchmarkDriver::Output] output
- # @param [BenchmarkDriver::Context] contexts
- def initialize(config:, output:, contexts:)
- @config = config
- @output = output
- @contexts = contexts
- end
-
- # This method is dynamically called by `BenchmarkDriver::JobRunner.run`
- # @param [Array<BenchmarkDriver::Runner::Peak::Job>] jobs
- def run(jobs)
- @output.with_benchmark do
- jobs.each do |job|
- @output.with_job(name: job.name) do
- @contexts.each do |context|
- result = BenchmarkDriver::Repeater.with_repeat(config: @config, larger_better: true, rest_on_average: :average) do
- run_benchmark(job, context: context)
- end
- value, duration = result.value
- @output.with_context(name: context.name, executable: context.executable, gems: context.gems, prelude: context.prelude) do
- @output.report(values: { METRIC => value }, duration: duration, loop_count: job.loop_count)
- end
- end
- end
- end
- end
- end
-
- private
-
- # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil
- # @param [BenchmarkDriver::Context] context
- # @return [BenchmarkDriver::Metrics]
- def run_benchmark(job, context:)
- if job.from_jit
- if job.to_jit
- benchmark = BenchmarkJT2JT.new(num_methods: job.num_methods, loop_count: job.loop_count)
- else
- raise NotImplementedError, "JT2VM is not implemented yet"
- end
- else
- if job.to_jit
- benchmark = BenchmarkVM2JT.new(num_methods: job.num_methods, loop_count: job.loop_count)
- else
- benchmark = BenchmarkVM2VM.new(num_methods: job.num_methods, loop_count: job.loop_count)
- end
- end
-
- duration = Tempfile.open(['benchmark_driver-result', '.txt']) do |f|
- with_script(benchmark.render(result: f.path)) do |path|
- opt = []
- if context.executable.command.any? { |c| c.start_with?('--jit') }
- opt << '--jit-min-calls=2'
- end
- IO.popen([*context.executable.command, '--disable-gems', *opt, path], &:read)
- if $?.success?
- Float(f.read)
- else
- BenchmarkDriver::Result::ERROR
- end
- end
- end
-
- [job.loop_count.to_f / duration, duration]
- end
-
- def with_script(script)
- if @config.verbose >= 2
- sep = '-' * 30
- $stdout.puts "\n\n#{sep}[Script begin]#{sep}\n#{script}#{sep}[Script end]#{sep}\n\n"
- end
-
- Tempfile.open(['benchmark_driver-', '.rb']) do |f|
- f.puts script
- f.close
- return yield(f.path)
- end
- end
-
- # @param [Integer] num_methods
- # @param [Integer] loop_count
- BenchmarkVM2VM = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
- # @param [String] result - A file to write result
- def render(result:)
- ERB.new(<<~EOS, trim_mode: '%').result(binding)
- % num_methods.times do |i|
- def a<%= i %>
- nil
- end
- % end
- RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
-
- def vm
- t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- i = 0
- while i < <%= loop_count / 1000 %>
- % 1000.times do |i|
- a<%= i % num_methods %>
- % end
- i += 1
- end
- % (loop_count % 1000).times do |i|
- a<%= i % num_methods %>
- % end
- Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
- end
-
- vm # warmup call cache
- File.write(<%= result.dump %>, vm)
- EOS
- end
- end
- private_constant :BenchmarkVM2VM
-
- # @param [Integer] num_methods
- # @param [Integer] loop_count
- BenchmarkVM2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
- # @param [String] result - A file to write result
- def render(result:)
- ERB.new(<<~EOS, trim_mode: '%').result(binding)
- % num_methods.times do |i|
- def a<%= i %>
- nil
- end
- a<%= i %>
- a<%= i %> # --jit-min-calls=2
- % end
- RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
-
- def vm
- t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- i = 0
- while i < <%= loop_count / 1000 %>
- % 1000.times do |i|
- a<%= i % num_methods %>
- % end
- i += 1
- end
- % (loop_count % 1000).times do |i|
- a<%= i % num_methods %>
- % end
- Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
- end
-
- vm # warmup call cache
- File.write(<%= result.dump %>, vm)
- EOS
- end
- end
- private_constant :BenchmarkVM2JT
-
- # @param [Integer] num_methods
- # @param [Integer] loop_count
- BenchmarkJT2JT = ::BenchmarkDriver::Struct.new(:num_methods, :loop_count) do
- # @param [String] result - A file to write result
- def render(result:)
- ERB.new(<<~EOS, trim_mode: '%').result(binding)
- % num_methods.times do |i|
- def a<%= i %>
- nil
- end
- % end
-
- # You may need to:
- # * Increase `JIT_ISEQ_SIZE_THRESHOLD` to 10000000 in mjit.h
- # * Always return false in `inlinable_iseq_p()` of mjit_compile.c
- def jit
- t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
- i = 0
- while i < <%= loop_count / 1000 %>
- % 1000.times do |i|
- a<%= i % num_methods %>
- % end
- i += 1
- end
- % (loop_count % 1000).times do |i|
- a<%= i % num_methods %>
- % end
- Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
- end
-
- jit
- jit
- RubyVM::MJIT.pause if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
- File.write(<%= result.dump %>, jit)
- EOS
- end
- end
- private_constant :BenchmarkJT2JT
-end
diff --git a/benchmark/lib/benchmark_driver/runner/ractor.rb b/benchmark/lib/benchmark_driver/runner/ractor.rb
new file mode 100644
index 0000000000..c730b8e4a5
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/ractor.rb
@@ -0,0 +1,122 @@
+require 'erb'
+
+# A runner to measure performance *inside* Ractor
+class BenchmarkDriver::Runner::Ractor < BenchmarkDriver::Runner::Ips
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob) do
+ attr_accessor :ractor
+ end
+
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{
+ def parse(ractor: 1, **kwargs)
+ super(**kwargs).each do |job|
+ job.ractor = ractor
+ end
+ end
+ })
+
+ private
+
+ unless private_instance_methods.include?(:run_benchmark)
+ raise "#run_benchmark is no longer defined in BenchmarkDriver::Runner::Ips"
+ end
+
+ # @param [BenchmarkDriver::Runner::Ips::Job] job - loop_count is not nil
+ # @param [BenchmarkDriver::Context] context
+ # @return [BenchmarkDriver::Metrics]
+ def run_benchmark(job, context:)
+ benchmark = BenchmarkScript.new(
+ preludes: [context.prelude, job.prelude],
+ script: job.script,
+ teardown: job.teardown,
+ loop_count: job.loop_count,
+ )
+
+ results = job.ractor.times.map do
+ Tempfile.open('benchmark_driver_result')
+ end
+ duration = with_script(benchmark.render(results: results.map(&:path))) do |path|
+ success = execute(*context.executable.command, path, exception: false)
+ if success && ((value = results.map { |f| Float(f.read) }.max) > 0)
+ value
+ else
+ BenchmarkDriver::Result::ERROR
+ end
+ end
+ results.each(&:close)
+
+ value_duration(
+ loop_count: job.loop_count,
+ duration: duration,
+ )
+ end
+
+ # @param [String] prelude
+ # @param [String] script
+ # @param [String] teardown
+ # @param [Integer] loop_count
+ BenchmarkScript = ::BenchmarkDriver::Struct.new(:preludes, :script, :teardown, :loop_count) do
+ # @param [String] result - A file to write result
+ def render(results:)
+ prelude = preludes.reject(&:nil?).reject(&:empty?).join("\n")
+ ERB.new(<<-RUBY).result_with_hash(results: results)
+Warning[:experimental] = false
+# shareable-constant-value: experimental_everything
+#{prelude}
+
+if #{loop_count} == 1
+ __bmdv_loop_before = 0
+ __bmdv_loop_after = 0
+else
+ __bmdv_loop_before = Time.new
+ #{while_loop('', loop_count, id: 0)}
+ __bmdv_loop_after = Time.new
+end
+
+__bmdv_ractors = []
+<% results.size.times do %>
+__bmdv_ractors << Ractor.new(__bmdv_loop_after - __bmdv_loop_before) { |__bmdv_loop_time|
+ __bmdv_time = Time
+ __bmdv_script_before = __bmdv_time.new
+ #{while_loop(script, loop_count, id: 1)}
+ __bmdv_script_after = __bmdv_time.new
+
+ (__bmdv_script_after - __bmdv_script_before) - __bmdv_loop_time
+}
+<% end %>
+
+# Wait for all Ractors before executing code to write results
+__bmdv_ractors.map!(&:take)
+
+<% results.each do |result| %>
+File.write(<%= result.dump %>, __bmdv_ractors.shift)
+<% end %>
+
+#{teardown}
+ RUBY
+ end
+
+ private
+
+ # id is to prevent:
+ # can not isolate a Proc because it accesses outer variables (__bmdv_i)
+ def while_loop(content, times, id:)
+ if !times.is_a?(Integer) || times <= 0
+ raise ArgumentError.new("Unexpected times: #{times.inspect}")
+ elsif times == 1
+ return content
+ end
+
+ # TODO: execute in batch
+ <<-RUBY
+__bmdv_i#{id} = 0
+while __bmdv_i#{id} < #{times}
+ #{content}
+ __bmdv_i#{id} += 1
+end
+ RUBY
+ end
+ end
+ private_constant :BenchmarkScript
+end
diff --git a/benchmark/marshal_dump_load_integer.yml b/benchmark/marshal_dump_load_integer.yml
new file mode 100644
index 0000000000..78ebf823d2
--- /dev/null
+++ b/benchmark/marshal_dump_load_integer.yml
@@ -0,0 +1,22 @@
+prelude: |
+ smallint_array = 1000.times.map { |x| x }
+ bigint32_array = 1000.times.map { |x| x + 2**32 }
+ bigint64_array = 1000.times.map { |x| x + 2**64 }
+
+ smallint_dump = Marshal.dump(smallint_array)
+ bigint32_dump = Marshal.dump(bigint32_array)
+ bigint64_dump = Marshal.dump(bigint64_array)
+benchmark:
+ marshal_dump_integer_small: |
+ Marshal.dump(smallint_array)
+ marshal_dump_integer_over_32_bit: |
+ Marshal.dump(bigint32_array)
+ marshal_dump_integer_over_64_bit: |
+ Marshal.dump(bigint64_array)
+ marshal_load_integer_small: |
+ Marshal.load(smallint_dump)
+ marshal_load_integer_over_32_bit: |
+ Marshal.load(bigint32_dump)
+ marshal_load_integer_over_64_bit: |
+ Marshal.load(bigint64_dump)
+loop_count: 4000
diff --git a/benchmark/masgn.yml b/benchmark/masgn.yml
new file mode 100644
index 0000000000..31cb8ee4a3
--- /dev/null
+++ b/benchmark/masgn.yml
@@ -0,0 +1,53 @@
+prelude: |
+ a = [nil] * 3
+ b = Class.new{attr_writer :a, :b, :c}.new
+ c = d = e = f = g = h = i = nil
+benchmark:
+ array2_2: "c = (a[0], a[1] = 1, 2)"
+ array2_3: "c = (a[0], a[1] = 1, 2, 3)"
+ array3_2: "c = (a[0], a[1], a[2] = 1, 2)"
+ array3_3: "c = (a[0], a[1], a[2] = 1, 2, 3)"
+ attr2_2: "c = (b.a, b.b = 1, 2)"
+ attr2_3: "c = (b.a, b.b = 1, 2, 3)"
+ attr3_2: "c = (b.a, b.b, b.c = 1, 2)"
+ attr3_3: "c = (b.a, b.b, b.c = 1, 2, 3)"
+ lvar2_2: "c = (d, e = 1, 2)"
+ lvar2_3: "c = (d, e = 1, 2, 3)"
+ lvar3_2: "c = (d, e, f = 1, 2)"
+ lvar3_3: "c = (d, e, f = 1, 2, 3)"
+ array2_2p: "(a[0], a[1] = 1, 2; nil)"
+ array2_3p: "(a[0], a[1] = 1, 2, 3; nil)"
+ array3_2p: "(a[0], a[1], a[2] = 1, 2; nil)"
+ array3_3p: "(a[0], a[1], a[2] = 1, 2, 3; nil)"
+ attr2_2p: "(b.a, b.b = 1, 2; nil)"
+ attr2_3p: "(b.a, b.b = 1, 2, 3; nil)"
+ attr3_2p: "(b.a, b.b, b.c = 1, 2; nil)"
+ attr3_3p: "(b.a, b.b, b.c = 1, 2, 3; nil)"
+ lvar2_2p: "(d, e = 1, 2; nil)"
+ lvar2_3p: "(d, e = 1, 2, 3; nil)"
+ lvar3_2p: "(d, e, f = 1, 2; nil)"
+ lvar3_3p: "(d, e, f = 1, 2, 3; nil)"
+ array2_2lv: "c = (a[0], a[1] = g, h)"
+ array2_ilv: "c = (a[0], a[1] = g, h, i)"
+ arrayi_2lv: "c = (a[0], a[1], a[2] = g, h)"
+ arrayi_ilv: "c = (a[0], a[1], a[2] = g, h, i)"
+ attr2_2lv: "c = (b.a, b.b = g, h)"
+ attr2_ilv: "c = (b.a, b.b = g, h, i)"
+ attri_2lv: "c = (b.a, b.b, b.c = g, h)"
+ attri_ilv: "c = (b.a, b.b, b.c = g, h, i)"
+ lvar2_2lv: "c = (d, e = g, h)"
+ lvar2_ilv: "c = (d, e = g, h, i)"
+ lvari_2lv: "c = (d, e, f = g, h)"
+ lvari_ilv: "c = (d, e, f = g, h, i)"
+ array2_2plv: "(a[0], a[1] = g, h; nil)"
+ array2_iplv: "(a[0], a[1] = g, h, i; nil)"
+ arrayi_2plv: "(a[0], a[1], a[2] = g, h; nil)"
+ arrayi_iplv: "(a[0], a[1], a[2] = g, h, i; nil)"
+ attr2_2plv: "(b.a, b.b = g, h; nil)"
+ attr2_iplv: "(b.a, b.b = g, h, i; nil)"
+ attri_2plv: "(b.a, b.b, b.c = g, h; nil)"
+ attri_iplv: "(b.a, b.b, b.c = g, h, i; nil)"
+ lvar2_2plv: "(d, e = g, h; nil)"
+ lvar2_iplv: "(d, e = g, h, i; nil)"
+ lvari_2plv: "(d, e, f = g, h; nil)"
+ lvari_iplv: "(d, e, f = g, h, i; nil)"
diff --git a/benchmark/method_bind_call.yml b/benchmark/method_bind_call.yml
new file mode 100644
index 0000000000..9e0e046ed4
--- /dev/null
+++ b/benchmark/method_bind_call.yml
@@ -0,0 +1,16 @@
+prelude: |
+ named_module = Kernel
+
+ module FakeName
+ def self.name
+ "NotMyame".freeze
+ end
+ end
+
+ MOD_NAME = Module.instance_method(:name)
+
+benchmark:
+ fastpath: MOD_NAME.bind_call(Kernel)
+ slowpath: MOD_NAME.bind_call(FakeName)
+
+loop_count: 100_000
diff --git a/benchmark/mjit_exec_jt2jt.yml b/benchmark/mjit_exec_jt2jt.yml
deleted file mode 100644
index 6c303c7a44..0000000000
--- a/benchmark/mjit_exec_jt2jt.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-type: lib/benchmark_driver/runner/mjit_exec
-num_methods: [1]
-#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
-loop_count: 50000000
-from_jit: true
-to_jit: true
diff --git a/benchmark/mjit_exec_vm2jt.yml b/benchmark/mjit_exec_vm2jt.yml
deleted file mode 100644
index 764883f070..0000000000
--- a/benchmark/mjit_exec_vm2jt.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-type: lib/benchmark_driver/runner/mjit_exec
-num_methods: [1]
-#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
-loop_count: 50000000
-from_jit: false
-to_jit: true
diff --git a/benchmark/mjit_exec_vm2vm.yml b/benchmark/mjit_exec_vm2vm.yml
deleted file mode 100644
index 030aa76c1c..0000000000
--- a/benchmark/mjit_exec_vm2vm.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-type: lib/benchmark_driver/runner/mjit_exec
-num_methods: [1]
-#num_methods: (1..100).to_a + [200, 300, 400, 500, 600, 700, 800, 900, 1000]
-loop_count: 50000000
-from_jit: false
-to_jit: false
diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml
index edc3556479..a6b5c9ee16 100644
--- a/benchmark/mjit_integer.yml
+++ b/benchmark/mjit_integer.yml
@@ -8,6 +8,7 @@ prelude: |
def mjit_magnitude(int) int.magnitude end
def mjit_odd?(int) int.odd? end
def mjit_ord(int) int.ord end
+ def mjit_size(int) int.size end
def mjit_to_i(int) int.to_i end
def mjit_to_int(int) int.to_int end
def mjit_uminus(int) -int end
@@ -22,6 +23,7 @@ benchmark:
- mjit_magnitude(-1)
- mjit_odd?(1)
- mjit_ord(1)
+ - mjit_size(1)
- mjit_to_i(1)
- mjit_to_int(1)
- mjit_uminus(1)
diff --git a/benchmark/module_eqq.yml b/benchmark/module_eqq.yml
new file mode 100644
index 0000000000..a561fb86dc
--- /dev/null
+++ b/benchmark/module_eqq.yml
@@ -0,0 +1,27 @@
+prelude: |
+ class SimpleClass; end
+ class MediumClass
+ 10.times { include Module.new }
+ end
+ class LargeClass
+ 100.times { include Module.new }
+ end
+ class HugeClass
+ 300.times { include Module.new }
+ end
+ SimpleObj = SimpleClass.new
+ MediumObj = MediumClass.new
+ LargeObj = LargeClass.new
+ HugeObj = HugeClass.new
+benchmark:
+ simple_class_eqq_simple_obj: |
+ SimpleClass === SimpleObj
+ medium_class_eqq_simple_obj: |
+ MediumClass === SimpleObj
+ simple_class_eqq_medium_obj: |
+ SimpleClass === MediumObj
+ simple_class_eqq_large_obj: |
+ SimpleClass === LargeObj
+ simple_class_eqq_huge_obj: |
+ SimpleClass === HugeObj
+loop_count: 20000000
diff --git a/benchmark/nilclass.yml b/benchmark/nilclass.yml
new file mode 100644
index 0000000000..fba67a5f6a
--- /dev/null
+++ b/benchmark/nilclass.yml
@@ -0,0 +1,6 @@
+benchmark:
+ to_i: |
+ nil.to_i
+ to_f: |
+ nil.to_f
+loop_count: 100000
diff --git a/benchmark/numeric_methods.yml b/benchmark/numeric_methods.yml
new file mode 100644
index 0000000000..1384902935
--- /dev/null
+++ b/benchmark/numeric_methods.yml
@@ -0,0 +1,29 @@
+prelude: |
+ int = 42
+ flo = 4.2
+benchmark:
+ real?: |
+ int.real?
+ integer?: |
+ flo.integer?
+ finite?: |
+ int.finite?
+ infinite?: |
+ int.infinite?
+ integer_real: |
+ int.real
+ float_real: |
+ flo.real
+ integr_imag: |
+ int.imag
+ float_imag: |
+ flo.imag
+ integer_conj: |
+ int.conj
+ float_conj: |
+ flo.conj
+ integer_numerator: |
+ int.numerator
+ integer_denominator: |
+ int.denominator
+loop_count: 20000000
diff --git a/benchmark/ractor_const.yml b/benchmark/ractor_const.yml
new file mode 100644
index 0000000000..d7ab74bdca
--- /dev/null
+++ b/benchmark/ractor_const.yml
@@ -0,0 +1,4 @@
+type: lib/benchmark_driver/runner/ractor
+benchmark:
+ ractor_const: Object
+ractor: 1
diff --git a/benchmark/ractor_float_to_s.yml b/benchmark/ractor_float_to_s.yml
new file mode 100644
index 0000000000..8f492be668
--- /dev/null
+++ b/benchmark/ractor_float_to_s.yml
@@ -0,0 +1,8 @@
+type: lib/benchmark_driver/runner/ractor
+prelude: |
+ FLOATS = [*0.0.step(1.0, 0.001)]
+benchmark:
+ ractor_float_to_s: |
+ FLOATS.each {|f| f.to_s}
+loop_count: 100
+ractor: 2
diff --git a/benchmark/range_min.yml b/benchmark/range_min.yml
new file mode 100644
index 0000000000..9e60dd7308
--- /dev/null
+++ b/benchmark/range_min.yml
@@ -0,0 +1,2 @@
+benchmark:
+ - (1..10).min
diff --git a/benchmark/so_nbody.rb b/benchmark/so_nbody.rb
index d6c5bb9e61..9884fc4edc 100644
--- a/benchmark/so_nbody.rb
+++ b/benchmark/so_nbody.rb
@@ -12,38 +12,38 @@ def _puts *args
end
class Planet
- attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass
+ attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass
- def initialize(x, y, z, vx, vy, vz, mass)
- @x, @y, @z = x, y, z
- @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR
- @mass = mass * SOLAR_MASS
- end
-
- def move_from_i(bodies, nbodies, dt, i)
- while i < nbodies
- b2 = bodies[i]
- dx = @x - b2.x
- dy = @y - b2.y
- dz = @z - b2.z
-
- distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
- mag = dt / (distance * distance * distance)
- b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag
-
- @vx -= dx * b2_mass_mag
- @vy -= dy * b2_mass_mag
- @vz -= dz * b2_mass_mag
- b2.vx += dx * b_mass_mag
- b2.vy += dy * b_mass_mag
- b2.vz += dz * b_mass_mag
- i += 1
+ def initialize(x, y, z, vx, vy, vz, mass)
+ @x, @y, @z = x, y, z
+ @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR
+ @mass = mass * SOLAR_MASS
end
- @x += dt * @vx
- @y += dt * @vy
- @z += dt * @vz
- end
+ def move_from_i(bodies, nbodies, dt, i)
+ while i < nbodies
+ b2 = bodies[i]
+ dx = @x - b2.x
+ dy = @y - b2.y
+ dz = @z - b2.z
+
+ distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
+ mag = dt / (distance * distance * distance)
+ b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag
+
+ @vx -= dx * b2_mass_mag
+ @vy -= dy * b2_mass_mag
+ @vz -= dz * b2_mass_mag
+ b2.vx += dx * b_mass_mag
+ b2.vy += dy * b_mass_mag
+ b2.vz += dz * b_mass_mag
+ i += 1
+ end
+
+ @x += dt * @vx
+ @y += dt * @vy
+ @z += dt * @vz
+ end
end
def energy(bodies)
diff --git a/benchmark/string_concat.yml b/benchmark/string_concat.yml
new file mode 100644
index 0000000000..e65c00cca9
--- /dev/null
+++ b/benchmark/string_concat.yml
@@ -0,0 +1,45 @@
+prelude: |
+ CHUNK = "a" * 64
+ UCHUNK = "é" * 32
+ GC.disable # GC causes a lot of variance
+benchmark:
+ binary_concat_7bit: |
+ buffer = String.new(capacity: 4096, encoding: Encoding::BINARY)
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ utf8_concat_7bit: |
+ buffer = String.new(capacity: 4096, encoding: Encoding::UTF_8)
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK
+ utf8_concat_UTF8: |
+ buffer = String.new(capacity: 4096, encoding: Encoding::UTF_8)
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ buffer << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK << UCHUNK
+ interpolation: |
+ buffer = "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \
+ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}"
diff --git a/benchmark/time_at.yml b/benchmark/time_at.yml
new file mode 100644
index 0000000000..3247efbe77
--- /dev/null
+++ b/benchmark/time_at.yml
@@ -0,0 +1,7 @@
+prelude: |
+ # frozen_string_literal: true
+benchmark:
+ - 'Time.at(0)'
+ - 'Time.at(0, 500)'
+ - 'Time.at(0, in: "+09:00")'
+ - 'Time.at(0, 500, in: "+09:00")'
diff --git a/benchmark/time_new.yml b/benchmark/time_new.yml
new file mode 100644
index 0000000000..5947dd3a41
--- /dev/null
+++ b/benchmark/time_new.yml
@@ -0,0 +1,4 @@
+benchmark:
+ - 'Time.new(2021)'
+ - 'Time.new(2021, 8, 22)'
+ - 'Time.new(2021, 8, 22, in: "+09:00")'
diff --git a/benchmark/time_now.yml b/benchmark/time_now.yml
new file mode 100644
index 0000000000..f6d6a31489
--- /dev/null
+++ b/benchmark/time_now.yml
@@ -0,0 +1,3 @@
+benchmark:
+ - 'Time.now'
+ - 'Time.now(in: "+09:00")'
diff --git a/benchmark/time_parse.yml b/benchmark/time_parse.yml
new file mode 100644
index 0000000000..6060b58bc6
--- /dev/null
+++ b/benchmark/time_parse.yml
@@ -0,0 +1,10 @@
+prelude: |
+ require 'time'
+ inspect = "2021-08-23 09:57:02 +0900"
+ iso8601 = "2021-08-23T09:57:02+09:00"
+benchmark:
+ - Time.iso8601(iso8601)
+ - Time.parse(iso8601)
+ - Time.parse(inspect)
+ - Time.new(iso8601) rescue Time.iso8601(iso8601)
+ - Time.new(inspect) rescue Time.parse(inspect)
diff --git a/benchmark/vm_case_classes.yml b/benchmark/vm_case_classes.yml
new file mode 100644
index 0000000000..cacc4f0464
--- /dev/null
+++ b/benchmark/vm_case_classes.yml
@@ -0,0 +1,9 @@
+benchmark:
+ vm_case_classes: |
+ case :foo
+ when Hash
+ raise
+ when Array
+ raise
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_const.yml b/benchmark/vm_const.yml
index 6064d4eed0..8939ca0cd3 100644
--- a/benchmark/vm_const.yml
+++ b/benchmark/vm_const.yml
@@ -1,7 +1,13 @@
prelude: |
Const = 1
+ A = B = C = D = E = F = G = H = I = J = K = L = M = N = O = P = Q = R = S = T = U = V = W = X = Y = Z = 1
+ def foo
+ A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z
+ end
benchmark:
vm_const: |
j = Const
k = Const
+ vm_const_many: |
+ foo
loop_count: 30000000
diff --git a/benchmark/vm_cvar.yml b/benchmark/vm_cvar.yml
new file mode 100644
index 0000000000..1d0e161829
--- /dev/null
+++ b/benchmark/vm_cvar.yml
@@ -0,0 +1,20 @@
+prelude: |
+ class A
+ @@foo = 1
+
+ def self.foo
+ @@foo
+ end
+
+ ("A".."Z").each do |module_name|
+ eval <<-EOM
+ module #{module_name}
+ end
+
+ include #{module_name}
+ EOM
+ end
+ end
+benchmark:
+ vm_cvar: A.foo
+loop_count: 600000
diff --git a/benchmark/vm_dstr_ary.rb b/benchmark/vm_dstr_ary.rb
new file mode 100644
index 0000000000..1d3aa3b97b
--- /dev/null
+++ b/benchmark/vm_dstr_ary.rb
@@ -0,0 +1,6 @@
+i = 0
+x = y = []
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_bool.rb b/benchmark/vm_dstr_bool.rb
new file mode 100644
index 0000000000..631ca54755
--- /dev/null
+++ b/benchmark/vm_dstr_bool.rb
@@ -0,0 +1,7 @@
+i = 0
+x = true
+y = false
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_class_module.rb b/benchmark/vm_dstr_class_module.rb
new file mode 100644
index 0000000000..becf0861c7
--- /dev/null
+++ b/benchmark/vm_dstr_class_module.rb
@@ -0,0 +1,10 @@
+i = 0
+class A; end unless defined?(A)
+module B; end unless defined?(B)
+x = A
+y = B
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
+
diff --git a/benchmark/vm_dstr_digit.rb b/benchmark/vm_dstr_digit.rb
new file mode 100644
index 0000000000..caaa395192
--- /dev/null
+++ b/benchmark/vm_dstr_digit.rb
@@ -0,0 +1,7 @@
+i = 0
+x = 0
+y = 9
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_int.rb b/benchmark/vm_dstr_int.rb
new file mode 100644
index 0000000000..ed380d7595
--- /dev/null
+++ b/benchmark/vm_dstr_int.rb
@@ -0,0 +1,5 @@
+i = 0
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{i}bar#{i}baz"
+end
diff --git a/benchmark/vm_dstr_nil.rb b/benchmark/vm_dstr_nil.rb
new file mode 100644
index 0000000000..ec4f5d6c67
--- /dev/null
+++ b/benchmark/vm_dstr_nil.rb
@@ -0,0 +1,6 @@
+i = 0
+x = y = nil
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_obj.rb b/benchmark/vm_dstr_obj.rb
new file mode 100644
index 0000000000..fb78637ead
--- /dev/null
+++ b/benchmark/vm_dstr_obj.rb
@@ -0,0 +1,6 @@
+i = 0
+x = y = Object.new
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_obj_def.rb b/benchmark/vm_dstr_obj_def.rb
new file mode 100644
index 0000000000..99ff7b98fb
--- /dev/null
+++ b/benchmark/vm_dstr_obj_def.rb
@@ -0,0 +1,8 @@
+i = 0
+o = Object.new
+def o.to_s; -""; end
+x = y = o
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_str.rb b/benchmark/vm_dstr_str.rb
new file mode 100644
index 0000000000..45fc107892
--- /dev/null
+++ b/benchmark/vm_dstr_str.rb
@@ -0,0 +1,6 @@
+i = 0
+x = y = ""
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_dstr_sym.rb b/benchmark/vm_dstr_sym.rb
new file mode 100644
index 0000000000..484b8f8150
--- /dev/null
+++ b/benchmark/vm_dstr_sym.rb
@@ -0,0 +1,6 @@
+i = 0
+x = y = :z
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ str = "foo#{x}bar#{y}baz"
+end
diff --git a/benchmark/vm_freezeobj.yml b/benchmark/vm_freezeobj.yml
new file mode 100644
index 0000000000..69a795a354
--- /dev/null
+++ b/benchmark/vm_freezeobj.yml
@@ -0,0 +1,6 @@
+prelude: |
+ objs = 100000.times.map { Object.new }
+benchmark:
+ vm_freeze_obj: |
+ objs.map(&:freeze)
+loop_count: 600
diff --git a/benchmark/vm_ivar_embedded_obj_init.yml b/benchmark/vm_ivar_embedded_obj_init.yml
new file mode 100644
index 0000000000..74fe20a630
--- /dev/null
+++ b/benchmark/vm_ivar_embedded_obj_init.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ def set_ivars
+ @a = nil
+ @b = nil
+ @c = nil
+ end
+ end
+
+ c = C.new
+benchmark:
+ vm_ivar_embedded_obj_init: |
+ c.set_ivars
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_extended_obj_init.yml b/benchmark/vm_ivar_extended_obj_init.yml
new file mode 100644
index 0000000000..f054bab282
--- /dev/null
+++ b/benchmark/vm_ivar_extended_obj_init.yml
@@ -0,0 +1,16 @@
+prelude: |
+ class C
+ def set_ivars
+ @a = nil
+ @b = nil
+ @c = nil
+ @d = nil
+ @e = nil
+ end
+ end
+
+ c = C.new
+benchmark:
+ vm_ivar_extended_obj_init: |
+ c.set_ivars
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_generic_get.yml b/benchmark/vm_ivar_generic_get.yml
new file mode 100644
index 0000000000..dae2d37671
--- /dev/null
+++ b/benchmark/vm_ivar_generic_get.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class C < Array
+ attr_reader :a, :b, :c
+ def initialize
+ @a = nil
+ @b = nil
+ @c = nil
+ end
+ end
+
+ c = C.new
+benchmark:
+ vm_ivar_generic_get: |
+ c.a
+ c.b
+ c.c
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_generic_set.yml b/benchmark/vm_ivar_generic_set.yml
new file mode 100644
index 0000000000..102a6577fb
--- /dev/null
+++ b/benchmark/vm_ivar_generic_set.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C < Array
+ def set_ivars
+ @a = nil
+ @b = nil
+ @c = nil
+ end
+ end
+
+ c = C.new
+benchmark:
+ vm_ivar_generic_set: |
+ c.set_ivars
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_get.yml b/benchmark/vm_ivar_get.yml
new file mode 100644
index 0000000000..9174af6965
--- /dev/null
+++ b/benchmark/vm_ivar_get.yml
@@ -0,0 +1,37 @@
+prelude: |
+ class Example
+ def initialize
+ @v0 = 1
+ @v1 = 2
+ @v3 = 3
+ @levar = 1
+ end
+
+ def get_value_loop
+ sum = 0
+
+ i = 0
+ while i < 1000000
+ # 10 times to de-emphasize loop overhead
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ sum += @levar
+ i += 1
+ end
+
+ return sum
+ end
+ end
+
+ obj = Example.new
+benchmark:
+ vm_ivar_get: |
+ obj.get_value_loop
+loop_count: 100
diff --git a/benchmark/vm_ivar_get_unintialized.yml b/benchmark/vm_ivar_get_unintialized.yml
new file mode 100644
index 0000000000..a1ccfb06ce
--- /dev/null
+++ b/benchmark/vm_ivar_get_unintialized.yml
@@ -0,0 +1,12 @@
+prelude: |
+ class Example
+ def read
+ @uninitialized
+ end
+ end
+
+ obj = Example.new
+benchmark:
+ vm_ivar_get_uninitialized: |
+ obj.read
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_init.yml b/benchmark/vm_ivar_init.yml
deleted file mode 100644
index c6f1633907..0000000000
--- a/benchmark/vm_ivar_init.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-prelude: |
- class C
- def initialize
- @a = nil
- @b = nil
- @c = nil
- @d = nil
- @e = nil
- end
- end
-benchmark:
- vm_ivar_init: |
- C.new
-loop_count: 30000000
diff --git a/benchmark/vm_ivar_lazy_set.yml b/benchmark/vm_ivar_lazy_set.yml
new file mode 100644
index 0000000000..7372ffcfbc
--- /dev/null
+++ b/benchmark/vm_ivar_lazy_set.yml
@@ -0,0 +1,12 @@
+prelude: |
+ class Example
+ def lazy_set
+ @uninitialized ||= 123
+ end
+ end
+
+ objs = 10000000.times.map { Example.new }
+benchmark:
+ vm_ivar_lazy_set: |
+ objs.each(&:lazy_set)
+loop_count: 1
diff --git a/benchmark/vm_ivar_of_class.yml b/benchmark/vm_ivar_of_class.yml
new file mode 100644
index 0000000000..172e28b2fd
--- /dev/null
+++ b/benchmark/vm_ivar_of_class.yml
@@ -0,0 +1,12 @@
+prelude: |
+ class C
+ @a = 1
+ def self.a
+ _a = @a; _a = @a; _a = @a; _a = @a; _a = @a;
+ _a = @a; _a = @a; _a = @a; _a = @a; _a = @a;
+ end
+ end
+benchmark:
+ vm_ivar_of_class: |
+ a = C.a
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_of_class_set.yml b/benchmark/vm_ivar_of_class_set.yml
new file mode 100644
index 0000000000..2ea5199423
--- /dev/null
+++ b/benchmark/vm_ivar_of_class_set.yml
@@ -0,0 +1,11 @@
+prelude: |
+ class C
+ @a = 1
+ def self.a o
+ @a = o; @a = o; @a = o; @a = o; @a = o; @a = o;
+ end
+ end
+benchmark:
+ vm_ivar_of_class_set: |
+ a = C.a(nil)
+loop_count: 30000000
diff --git a/benchmark/vm_ivar_set_on_instance.yml b/benchmark/vm_ivar_set_on_instance.yml
new file mode 100644
index 0000000000..91857b7742
--- /dev/null
+++ b/benchmark/vm_ivar_set_on_instance.yml
@@ -0,0 +1,35 @@
+prelude: |
+ class TheClass
+ def initialize
+ @v0 = 1
+ @v1 = 2
+ @v3 = 3
+ @levar = 1
+ end
+
+ def set_value_loop
+ # 1M
+ i = 0
+ while i < 1000000
+ # 10 times to de-emphasize loop overhead
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ @levar = i
+ i += 1
+ end
+ end
+ end
+
+ obj = TheClass.new
+
+benchmark:
+ vm_ivar_set_on_instance: |
+ obj.set_value_loop
+loop_count: 100
diff --git a/benchmark/vm_ivar_set_subclass.yml b/benchmark/vm_ivar_set_subclass.yml
index 2653d36ded..bc8bf5bf6b 100644
--- a/benchmark/vm_ivar_set_subclass.yml
+++ b/benchmark/vm_ivar_set_subclass.yml
@@ -1,6 +1,6 @@
prelude: |
class A
- def initialize
+ def set_ivars
@a = nil
@b = nil
@c = nil
@@ -10,8 +10,11 @@ prelude: |
end
class B < A; end
class C < A; end
+
+ b = B.new
+ c = C.new
benchmark:
vm_ivar_init_subclass: |
- B.new
- C.new
+ b.set_ivars
+ c.set_ivars
loop_count: 3000000
diff --git a/benchmark/vm_lvar_cond_set.yml b/benchmark/vm_lvar_cond_set.yml
new file mode 100644
index 0000000000..1845f9d12e
--- /dev/null
+++ b/benchmark/vm_lvar_cond_set.yml
@@ -0,0 +1,8 @@
+benchmark:
+ vm_lvar_cond_set: |
+ a ||= 1
+ b ||= 1
+ c ||= 1
+ d ||= 1
+ nil
+loop_count: 30000000
diff --git a/benchmark/vm_thread_condvar1.rb b/benchmark/vm_thread_condvar1.rb
index cf5706b23e..feed27c3ad 100644
--- a/benchmark/vm_thread_condvar1.rb
+++ b/benchmark/vm_thread_condvar1.rb
@@ -1,9 +1,9 @@
# two threads, two mutex, two condvar ping-pong
require 'thread'
-m1 = Mutex.new
-m2 = Mutex.new
-cv1 = ConditionVariable.new
-cv2 = ConditionVariable.new
+m1 = Thread::Mutex.new
+m2 = Thread::Mutex.new
+cv1 = Thread::ConditionVariable.new
+cv2 = Thread::ConditionVariable.new
max = 100000
i = 0
wait = nil
diff --git a/benchmark/vm_thread_condvar2.rb b/benchmark/vm_thread_condvar2.rb
index 7c8dc19481..6590c4134b 100644
--- a/benchmark/vm_thread_condvar2.rb
+++ b/benchmark/vm_thread_condvar2.rb
@@ -1,16 +1,16 @@
# many threads, one mutex, many condvars
require 'thread'
-m = Mutex.new
-cv1 = ConditionVariable.new
-cv2 = ConditionVariable.new
+m = Thread::Mutex.new
+cv1 = Thread::ConditionVariable.new
+cv2 = Thread::ConditionVariable.new
max = 1000
n = 100
waiting = 0
scvs = []
waiters = n.times.map do |i|
- start_cv = ConditionVariable.new
+ start_cv = Thread::ConditionVariable.new
scvs << start_cv
- start_mtx = Mutex.new
+ start_mtx = Thread::Mutex.new
start_mtx.synchronize do
th = Thread.new(start_mtx, start_cv) do |sm, scv|
m.synchronize do
diff --git a/bignum.c b/bignum.c
index 7c55366ecb..cb2c3b6f07 100644
--- a/bignum.c
+++ b/bignum.c
@@ -23,8 +23,14 @@
# include <ieeefp.h>
#endif
+#if !defined(USE_GMP)
#if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
-# define USE_GMP
+# define USE_GMP 1
+#else
+# define USE_GMP 0
+#endif
+#endif
+#if USE_GMP
# include <gmp.h>
#endif
@@ -36,15 +42,12 @@
#include "internal/numeric.h"
#include "internal/object.h"
#include "internal/sanitizers.h"
-#include "internal/util.h"
#include "internal/variable.h"
#include "internal/warnings.h"
#include "ruby/thread.h"
#include "ruby/util.h"
#include "ruby_assert.h"
-#define RB_BIGNUM_TYPE_P(x) RB_TYPE_P((x), T_BIGNUM)
-
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
#ifndef SIZEOF_BDIGIT_DBL
@@ -75,7 +78,7 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
#else
# define HOST_BIGENDIAN_P 0
#endif
-/* (!LSHIFTABLE(d, n) ? 0 : (n)) is same as n but suppress a warning, C4293, by Visual Studio. */
+/* (!LSHIFTABLE(d, n) ? 0 : (n)) is the same as n but suppress a warning, C4293, by Visual Studio. */
#define LSHIFTABLE(d, n) ((n) < sizeof(d) * CHAR_BIT)
#define LSHIFTX(d, n) (!LSHIFTABLE(d, n) ? 0 : ((d) << (!LSHIFTABLE(d, n) ? 0 : (n))))
#define CLEAR_LOWBITS(d, numbits) ((d) & LSHIFTX(~((d)*0), (numbits)))
@@ -102,8 +105,8 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
#endif
#define BIGZEROP(x) (BIGNUM_LEN(x) == 0 || \
- (BDIGITS(x)[0] == 0 && \
- (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
+ (BDIGITS(x)[0] == 0 && \
+ (BIGNUM_LEN(x) == 1 || bigzero_p(x))))
#define BIGSIZE(x) (BIGNUM_LEN(x) == 0 ? (size_t)0 : \
BDIGITS(x)[BIGNUM_LEN(x)-1] ? \
(size_t)(BIGNUM_LEN(x)*SIZEOF_BDIGIT - nlz(BDIGITS(x)[BIGNUM_LEN(x)-1])/CHAR_BIT) : \
@@ -148,7 +151,7 @@ STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGIT % SIZEOF_LONG == 0);
#define GMP_DIV_DIGITS 20
#define GMP_BIG2STR_DIGITS 20
#define GMP_STR2BIG_DIGITS 20
-#ifdef USE_GMP
+#if USE_GMP
# define NAIVE_MUL_DIGITS GMP_MUL_DIGITS
#else
# define NAIVE_MUL_DIGITS KARATSUBA_MUL_DIGITS
@@ -159,15 +162,11 @@ typedef void (mulfunc_t)(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, c
static mulfunc_t bary_mul_toom3_start;
static mulfunc_t bary_mul_karatsuba_start;
static BDIGIT bigdivrem_single(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT y);
-static void bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn);
-static VALUE bigmul0(VALUE x, VALUE y);
-static void bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn);
static VALUE bignew_1(VALUE klass, size_t len, int sign);
static inline VALUE bigtrunc(VALUE x);
static VALUE bigsq(VALUE x);
-static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
static inline VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret);
#if SIZEOF_BDIGIT <= SIZEOF_INT
@@ -420,9 +419,9 @@ bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift)
assert(0 <= shift && shift < BITSPERDIG);
for (i=0; i<n; i++) {
- num = num | (BDIGIT_DBL)*xds++ << shift;
- *zds++ = BIGLO(num);
- num = BIGDN(num);
+ num = num | (BDIGIT_DBL)*xds++ << shift;
+ *zds++ = BIGLO(num);
+ num = BIGDN(num);
}
return BIGLO(num);
}
@@ -438,9 +437,9 @@ bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT hi
num = BIGUP(higher_bdigit);
for (i = 0; i < n; i++) {
BDIGIT x = xds[n - i - 1];
- num = (num | x) >> shift;
+ num = (num | x) >> shift;
zds[n - i - 1] = BIGLO(num);
- num = BIGUP(x);
+ num = BIGUP(x);
}
}
@@ -450,7 +449,7 @@ bary_zero_p(const BDIGIT *xds, size_t xn)
if (xn == 0)
return 1;
do {
- if (xds[--xn]) return 0;
+ if (xds[--xn]) return 0;
} while (xn);
return 1;
}
@@ -467,7 +466,6 @@ static int
bary_2comp(BDIGIT *ds, size_t n)
{
size_t i;
- i = 0;
for (i = 0; i < n; i++) {
if (ds[i] != 0) {
goto non_zero;
@@ -979,7 +977,7 @@ integer_unpack_num_bdigits_small(size_t numwords, size_t wordsize, size_t nails,
{
/* nlp_bits stands for number of leading padding bits */
size_t num_bits = (wordsize * CHAR_BIT - nails) * numwords;
- size_t num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG;
+ size_t num_bdigits = roomof(num_bits, BITSPERDIG);
*nlp_bits_ret = (int)(num_bdigits * BITSPERDIG - num_bits);
return num_bdigits;
}
@@ -989,7 +987,7 @@ integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nail
{
/* BITSPERDIG = SIZEOF_BDIGIT * CHAR_BIT */
/* num_bits = (wordsize * CHAR_BIT - nails) * numwords */
- /* num_bdigits = (num_bits + BITSPERDIG - 1) / BITSPERDIG */
+ /* num_bdigits = roomof(num_bits, BITSPERDIG) */
/* num_bits = CHAR_BIT * (wordsize * numwords) - nails * numwords = CHAR_BIT * num_bytes1 - nails * numwords */
size_t num_bytes1 = wordsize * numwords;
@@ -1057,6 +1055,7 @@ integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *
size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
assert(num_bdigits == num_bdigits1);
assert(*nlp_bits_ret == nlp_bits1);
+ (void)num_bdigits1;
}
#endif
}
@@ -1351,9 +1350,9 @@ bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd
num = borrow ? -1 : 0;
for (i = 0; i < sn; i++) {
- num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
if (yn <= xn) {
for (; i < xn; i++) {
@@ -1372,7 +1371,7 @@ bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd
}
if (num == 0) goto num_is_zero;
for (; i < zn; i++) {
- zds[i] = BDIGMAX;
+ zds[i] = BDIGMAX;
}
return 1;
@@ -1380,10 +1379,10 @@ bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd
if (xds == zds && xn == zn)
return 0;
for (; i < xn; i++) {
- zds[i] = xds[i];
+ zds[i] = xds[i];
}
for (; i < zn; i++) {
- zds[i] = 0;
+ zds[i] = 0;
}
return 0;
}
@@ -1410,27 +1409,27 @@ bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd
assert(yn <= zn);
if (xn > yn) {
- const BDIGIT *tds;
- tds = xds; xds = yds; yds = tds;
- i = xn; xn = yn; yn = i;
+ const BDIGIT *tds;
+ tds = xds; xds = yds; yds = tds;
+ i = xn; xn = yn; yn = i;
}
num = carry ? 1 : 0;
for (i = 0; i < xn; i++) {
- num += (BDIGIT_DBL)xds[i] + yds[i];
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ num += (BDIGIT_DBL)xds[i] + yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
for (; i < yn; i++) {
if (num == 0) goto num_is_zero;
- num += yds[i];
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ num += yds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
for (; i < zn; i++) {
if (num == 0) goto num_is_zero;
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
return num != 0;
@@ -1438,10 +1437,10 @@ bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd
if (yds == zds && yn == zn)
return 0;
for (; i < yn; i++) {
- zds[i] = yds[i];
+ zds[i] = yds[i];
}
for (; i < zn; i++) {
- zds[i] = 0;
+ zds[i] = 0;
}
return 0;
}
@@ -1580,7 +1579,7 @@ rb_big_mul_normal(VALUE x, VALUE y)
/* efficient squaring (2 times faster than normal multiplication)
* ref: Handbook of Applied Cryptography, Algorithm 14.16
- * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ * https://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
*/
static void
bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn)
@@ -1598,30 +1597,30 @@ bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn)
return;
for (i = 0; i < xn-1; i++) {
- v = (BDIGIT_DBL)xds[i];
- if (!v)
+ v = (BDIGIT_DBL)xds[i];
+ if (!v)
continue;
- c = (BDIGIT_DBL)zds[i + i] + v * v;
- zds[i + i] = BIGLO(c);
- c = BIGDN(c);
- v *= 2;
+ c = (BDIGIT_DBL)zds[i + i] + v * v;
+ zds[i + i] = BIGLO(c);
+ c = BIGDN(c);
+ v *= 2;
vl = BIGLO(v);
vh = (int)BIGDN(v);
- for (j = i + 1; j < xn; j++) {
- w = (BDIGIT_DBL)xds[j];
- c += (BDIGIT_DBL)zds[i + j] + vl * w;
- zds[i + j] = BIGLO(c);
- c = BIGDN(c);
- if (vh)
+ for (j = i + 1; j < xn; j++) {
+ w = (BDIGIT_DBL)xds[j];
+ c += (BDIGIT_DBL)zds[i + j] + vl * w;
+ zds[i + j] = BIGLO(c);
+ c = BIGDN(c);
+ if (vh)
c += w;
- }
- if (c) {
- c += (BDIGIT_DBL)zds[i + xn];
- zds[i + xn] = BIGLO(c);
- c = BIGDN(c);
+ }
+ if (c) {
+ c += (BDIGIT_DBL)zds[i + xn];
+ zds[i + xn] = BIGLO(c);
+ c = BIGDN(c);
if (c)
zds[i + xn + 1] += (BDIGIT)c;
- }
+ }
}
/* i == xn-1 */
@@ -1646,13 +1645,21 @@ rb_big_sq_fast(VALUE x)
return z;
}
+static inline size_t
+max_size(size_t a, size_t b)
+{
+ return (a > b ? a : b);
+}
+
/* balancing multiplication by slicing larger argument */
static void
-bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, BDIGIT *wds, size_t wn, mulfunc_t *mulfunc)
+bary_mul_balance_with_mulfunc(BDIGIT *const zds, const size_t zn,
+ const BDIGIT *const xds, const size_t xn,
+ const BDIGIT *const yds, const size_t yn,
+ BDIGIT *wds, size_t wn, mulfunc_t *const mulfunc)
{
VALUE work = 0;
- size_t yn0 = yn;
- size_t r, n;
+ size_t n;
assert(xn + yn <= zn);
assert(xn <= yn);
@@ -1660,14 +1667,26 @@ bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t
BDIGITS_ZERO(zds, xn);
+ if (wn < xn) {
+ /* The condition when a new buffer is needed:
+ * 1. (2(xn+r) > zn-(yn-r)) => (2xn+r > zn-yn), at the last
+ * iteration (or r == 0)
+ * 2. (2(xn+xn) > zn-(yn-r-xn)) => (3xn-r > zn-yn), at the
+ * previous iteration.
+ */
+ const size_t r = yn % xn;
+ if (2*xn + yn + max_size(xn-r, r) > zn) {
+ wn = xn;
+ wds = ALLOCV_N(BDIGIT, work, wn);
+ }
+ }
+
n = 0;
- while (yn > 0) {
- BDIGIT *tds;
- size_t tn;
- r = xn > yn ? yn : xn;
- tn = xn + r;
+ while (yn > n) {
+ const size_t r = (xn > (yn - n) ? (yn - n) : xn);
+ const size_t tn = (xn + r);
if (2 * (xn + r) <= zn - n) {
- tds = zds + n + xn + r;
+ BDIGIT *const tds = zds + n + xn + r;
mulfunc(tds, tn, xds, xn, yds + n, r, wds, wn);
BDIGITS_ZERO(zds + n + xn, r);
bary_add(zds + n, tn,
@@ -1675,21 +1694,25 @@ bary_mul_balance_with_mulfunc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t
tds, tn);
}
else {
+ BDIGIT *const tds = zds + n;
if (wn < xn) {
+ /* xn is invariant, only once here */
+#if 0
wn = xn;
wds = ALLOCV_N(BDIGIT, work, wn);
+#else
+ rb_bug("wds is not enough: %" PRIdSIZE " for %" PRIdSIZE, wn, xn);
+#endif
}
- tds = zds + n;
MEMCPY(wds, zds + n, BDIGIT, xn);
mulfunc(tds, tn, xds, xn, yds + n, r, wds+xn, wn-xn);
bary_add(zds + n, tn,
zds + n, tn,
wds, xn);
}
- yn -= r;
- n += r;
+ n += r;
}
- BDIGITS_ZERO(zds+xn+yn0, zn - (xn+yn0));
+ BDIGITS_ZERO(zds+xn+yn, zn - (xn+yn));
if (work)
ALLOCV_END(work);
@@ -2079,21 +2102,21 @@ bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGI
v3n = u3n; v3ds = u3ds; v3p = u3p;
}
else {
- /* v1 <- y0 + y2 */
+ /* v1 <- y0 + y2 */
bary_add(v1ds, v1n, y0ds, y0n, y2ds, y2n);
v1p = 1;
- /* y(-1) : v2 <- v1 - y1 = y0 - y1 + y2 */
+ /* y(-1) : v2 <- v1 - y1 = y0 - y1 + y2 */
v2p = 1;
if (bary_sub(v2ds, v2n, v1ds, v1n, y1ds, y1n)) {
bary_2comp(v2ds, v2n);
v2p = 0;
}
- /* y(1) : v1 <- v1 + y1 = y0 + y1 + y2 */
+ /* y(1) : v1 <- v1 + y1 = y0 + y1 + y2 */
bary_add(v1ds, v1n, v1ds, v1n, y1ds, y1n);
- /* y(-2) : v3 <- 2 * (v2 + y2) - y0 = y0 - 2 * (y1 - 2 * y2) */
+ /* y(-2) : v3 <- 2 * (v2 + y2) - y0 = y0 - 2 * (y1 - 2 * y2) */
v3p = 1;
if (v2p) {
bary_add(v3ds, v3n, v2ds, v2n, y2ds, y2n);
@@ -2286,7 +2309,7 @@ rb_big_mul_toom3(VALUE x, VALUE y)
return z;
}
-#ifdef USE_GMP
+#if USE_GMP
static inline void
bdigits_to_mpz(mpz_t mp, const BDIGIT *digits, size_t len)
{
@@ -2424,8 +2447,8 @@ bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp,
if (xn > yn) {
const BDIGIT *tds;
size_t tn;
- tds = xds; xds = yds; yds = tds;
- tn = xn; xn = yn; yn = tn;
+ tds = xds; xds = yds; yds = tds;
+ tn = xn; xn = yn; yn = tn;
}
assert(xn <= yn);
@@ -2551,7 +2574,7 @@ bary_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds
}
}
-#ifdef USE_GMP
+#if USE_GMP
bary_mul_gmp(zds, zn, xds, xn, yds, yn);
#else
bary_mul_toom3_start(zds, zn, xds, xn, yds, yn, NULL, 0);
@@ -2575,26 +2598,26 @@ bigdivrem1(void *ptr)
BDIGIT q;
do {
- if (bds->stop) {
- bds->zn = zn;
- return 0;
+ if (bds->stop) {
+ bds->zn = zn;
+ return 0;
}
- if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
- else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
- if (q) {
+ if (zds[zn-1] == yds[yn-1]) q = BDIGMAX;
+ else q = (BDIGIT)((BIGUP(zds[zn-1]) + zds[zn-2])/yds[yn-1]);
+ if (q) {
num = bigdivrem_mulsub(zds+zn-(yn+1), yn+1,
q,
yds, yn);
- while (num) { /* "add back" required */
- q--;
+ while (num) { /* "add back" required */
+ q--;
num = bary_add(zds+zn-(yn+1), yn,
zds+zn-(yn+1), yn,
yds, yn);
num--;
- }
- }
+ }
+ }
zn--;
- zds[zn] = q;
+ zds[zn] = q;
} while (zn > yn);
return 0;
}
@@ -2663,16 +2686,16 @@ bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn)
bds.zn = zn - ynzero;
if (bds.zn > 10000 || bds.yn > 10000) {
retry:
- bds.stop = Qfalse;
+ bds.stop = Qfalse;
rb_nogvl(bigdivrem1, &bds, rb_big_stop, &bds, RB_NOGVL_UBF_ASYNC_SAFE);
- if (bds.stop == Qtrue) {
- /* execute trap handler, but exception was not raised. */
- goto retry;
- }
+ if (bds.stop == Qtrue) {
+ /* execute trap handler, but exception was not raised. */
+ goto retry;
+ }
}
else {
- bigdivrem1(&bds);
+ bigdivrem1(&bds);
}
}
@@ -2771,7 +2794,7 @@ rb_big_divrem_normal(VALUE x, VALUE y)
return rb_assoc_new(q, r);
}
-#ifdef USE_GMP
+#if USE_GMP
static void
bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
@@ -2855,7 +2878,7 @@ rb_big_divrem_gmp(VALUE x, VALUE y)
static void
bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn)
{
-#ifdef USE_GMP
+#if USE_GMP
if (GMP_DIV_DIGITS < xn) {
bary_divmod_gmp(qds, qn, rds, rn, xds, xn, yds, yn);
return;
@@ -2930,7 +2953,7 @@ int
rb_cmpint(VALUE val, VALUE a, VALUE b)
{
if (NIL_P(val)) {
- rb_cmperr(a, b);
+ rb_cmperr(a, b);
}
if (FIXNUM_P(val)) {
long l = FIX2LONG(val);
@@ -2939,9 +2962,9 @@ rb_cmpint(VALUE val, VALUE a, VALUE b)
return 0;
}
if (RB_BIGNUM_TYPE_P(val)) {
- if (BIGZEROP(val)) return 0;
- if (BIGNUM_SIGN(val)) return 1;
- return -1;
+ if (BIGZEROP(val)) return 0;
+ if (BIGNUM_SIGN(val)) return 1;
+ return -1;
}
if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
@@ -2951,8 +2974,8 @@ rb_cmpint(VALUE val, VALUE a, VALUE b)
#define BIGNUM_SET_LEN(b,l) \
(BIGNUM_EMBED_P(b) ? \
(void)(RBASIC(b)->flags = \
- (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
- ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
+ (RBASIC(b)->flags & ~BIGNUM_EMBED_LEN_MASK) | \
+ ((l) << BIGNUM_EMBED_LEN_SHIFT)) : \
(void)(RBIGNUM(b)->as.heap.len = (l)))
static void
@@ -2960,33 +2983,33 @@ rb_big_realloc(VALUE big, size_t len)
{
BDIGIT *ds;
if (BIGNUM_EMBED_P(big)) {
- if (BIGNUM_EMBED_LEN_MAX < len) {
- ds = ALLOC_N(BDIGIT, len);
- MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
- RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
- RBIGNUM(big)->as.heap.digits = ds;
+ if (BIGNUM_EMBED_LEN_MAX < len) {
+ ds = ALLOC_N(BDIGIT, len);
+ MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, BIGNUM_EMBED_LEN_MAX);
+ RBIGNUM(big)->as.heap.len = BIGNUM_LEN(big);
+ RBIGNUM(big)->as.heap.digits = ds;
FL_UNSET_RAW(big, BIGNUM_EMBED_FLAG);
- }
+ }
}
else {
- if (len <= BIGNUM_EMBED_LEN_MAX) {
- ds = RBIGNUM(big)->as.heap.digits;
+ if (len <= BIGNUM_EMBED_LEN_MAX) {
+ ds = RBIGNUM(big)->as.heap.digits;
FL_SET_RAW(big, BIGNUM_EMBED_FLAG);
- BIGNUM_SET_LEN(big, len);
+ BIGNUM_SET_LEN(big, len);
(void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
- if (ds) {
- MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
- xfree(ds);
- }
- }
- else {
- if (BIGNUM_LEN(big) == 0) {
- RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
- }
- else {
- REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT, len);
- }
- }
+ if (ds) {
+ MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
+ xfree(ds);
+ }
+ }
+ else {
+ if (BIGNUM_LEN(big) == 0) {
+ RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
+ }
+ else {
+ REALLOC_N(RBIGNUM(big)->as.heap.digits, BDIGIT, len);
+ }
+ }
}
}
@@ -3072,7 +3095,7 @@ abs2twocomp(VALUE *xp, long *n_ret)
MEMCPY(BDIGITS(z), ds, BDIGIT, n);
bary_2comp(BDIGITS(z), n);
hibits = BDIGMAX;
- *xp = z;
+ *xp = z;
}
*n_ret = n;
return hibits;
@@ -3096,7 +3119,7 @@ bigtrunc(VALUE x)
if (len == 0) return x;
while (--len && !ds[len]);
if (BIGNUM_LEN(x) > len+1) {
- rb_big_resize(x, len+1);
+ rb_big_resize(x, len+1);
}
return x;
}
@@ -3149,7 +3172,7 @@ static VALUE
bignorm(VALUE x)
{
if (RB_BIGNUM_TYPE_P(x)) {
- x = bigfixize(x);
+ x = bigfixize(x);
}
return x;
}
@@ -3171,8 +3194,8 @@ rb_uint2big(uintptr_t n)
digits[0] = n;
#else
for (i = 0; i < bdigit_roomof(SIZEOF_VALUE); i++) {
- digits[i] = BIGLO(n);
- n = BIGDN(n);
+ digits[i] = BIGLO(n);
+ n = BIGDN(n);
}
#endif
@@ -3191,14 +3214,14 @@ rb_int2big(intptr_t n)
if (n < 0) {
u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */
- neg = 1;
+ neg = 1;
}
else {
u = n;
}
big = rb_uint2big(u);
if (neg) {
- BIGNUM_SET_NEGATIVE_SIGN(big);
+ BIGNUM_SET_NEGATIVE_SIGN(big);
}
return big;
}
@@ -3357,7 +3380,7 @@ absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_num
if (sign == 2) {
#if defined __GNUC__ && (__GNUC__ == 4 && __GNUC_MINOR__ == 4)
- *nlz_bits_ret = 0;
+ *nlz_bits_ret = 0;
#endif
return (size_t)-1;
}
@@ -3405,6 +3428,7 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0);
assert(numwords0 == numwords);
assert(nlz_bits0 == nlz_bits);
+ (void)numwords0;
}
#endif
}
@@ -3676,7 +3700,7 @@ rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t na
}
else if (num_bdigits == numberof(fixbuf)) {
val = bignew((long)num_bdigits+1, 0);
- MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
+ MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
BDIGITS(val)[num_bdigits++] = 1;
}
else {
@@ -3688,11 +3712,11 @@ rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t na
BDIGIT_DBL u = fixbuf[0] + BIGUP(fixbuf[1]);
if (u == 0)
return LONG2FIX(0);
- if (0 < sign && POSFIXABLE(u))
- return LONG2FIX(u);
- if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
+ if (0 < sign && POSFIXABLE(u))
+ return LONG2FIX((long)u);
+ if (sign < 0 && BDIGIT_MSB(fixbuf[1]) == 0 &&
NEGFIXABLE(-(BDIGIT_DBL_SIGNED)u))
- return LONG2FIX(-(BDIGIT_DBL_SIGNED)u);
+ return LONG2FIX((long)-(BDIGIT_DBL_SIGNED)u);
val = bignew((long)num_bdigits, 0 <= sign);
MEMCPY(BDIGITS(val), fixbuf, BDIGIT, num_bdigits);
}
@@ -3742,41 +3766,41 @@ str2big_scan_digits(const char *s, const char *str, int base, int badcheck, size
int c;
if (!len) {
- *num_digits_p = 0;
- *len_p = 0;
- return TRUE;
+ *num_digits_p = 0;
+ *len_p = 0;
+ return TRUE;
}
if (badcheck && *str == '_') return FALSE;
while ((c = *str++) != 0) {
- if (c == '_') {
- if (nondigit) {
+ if (c == '_') {
+ if (nondigit) {
if (badcheck) return FALSE;
- break;
- }
- nondigit = (char) c;
- }
- else if ((c = conv_digit(c)) < 0 || c >= base) {
- break;
- }
- else {
- nondigit = 0;
- num_digits++;
- digits_end = str;
- }
- if (len > 0 && !--len) break;
+ break;
+ }
+ nondigit = (char) c;
+ }
+ else if ((c = conv_digit(c)) < 0 || c >= base) {
+ break;
+ }
+ else {
+ nondigit = 0;
+ num_digits++;
+ digits_end = str;
+ }
+ if (len > 0 && !--len) break;
}
if (badcheck && nondigit) return FALSE;
if (badcheck && len) {
- str--;
- while (*str && ISSPACE(*str)) {
- str++;
- if (len > 0 && !--len) break;
- }
- if (len && *str) {
- return FALSE;
- }
+ str--;
+ while (*str && ISSPACE(*str)) {
+ str++;
+ if (len > 0 && !--len) break;
+ }
+ if (len && *str) {
+ return FALSE;
+ }
}
*num_digits_p = num_digits;
*len_p = digits_end - digits_start;
@@ -3951,7 +3975,7 @@ str2big_karatsuba(
return z;
}
-#ifdef USE_GMP
+#if USE_GMP
static VALUE
str2big_gmp(
int sign,
@@ -4018,8 +4042,8 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
char *end;
VALUE ret = rb_cstr_parse_inum(str, -1, (badcheck ? NULL : &end), base);
if (NIL_P(ret)) {
- if (badcheck) rb_invalid_str(str, "Integer()");
- ret = INT2FIX(0);
+ if (badcheck) rb_invalid_str(str, "Integer()");
+ ret = INT2FIX(0);
}
return ret;
}
@@ -4043,7 +4067,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
VALUE
rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
- int base, int flags)
+ int base, int flags)
{
const char *const s = str;
char sign = 1;
@@ -4060,82 +4084,82 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
const int badcheck = !endp;
#define ADV(n) do {\
- if (len > 0 && len <= (n)) goto bad; \
- str += (n); \
- len -= (n); \
+ if (len > 0 && len <= (n)) goto bad; \
+ str += (n); \
+ len -= (n); \
} while (0)
#define ASSERT_LEN() do {\
- assert(len != 0); \
- if (len0 >= 0) assert(s + len0 == str + len); \
+ assert(len != 0); \
+ if (len0 >= 0) assert(s + len0 == str + len); \
} while (0)
if (!str) {
goto bad;
}
if (len && (flags & RB_INT_PARSE_SIGN)) {
- while (ISSPACE(*str)) ADV(1);
+ while (ISSPACE(*str)) ADV(1);
- if (str[0] == '+') {
- ADV(1);
- }
- else if (str[0] == '-') {
- ADV(1);
- sign = 0;
- }
- ASSERT_LEN();
+ if (str[0] == '+') {
+ ADV(1);
+ }
+ else if (str[0] == '-') {
+ ADV(1);
+ sign = 0;
+ }
+ ASSERT_LEN();
}
if (base <= 0) {
- if (str[0] == '0' && len > 1) {
- switch (str[1]) {
- case 'x': case 'X':
- base = 16;
- ADV(2);
- break;
- case 'b': case 'B':
- base = 2;
- ADV(2);
- break;
- case 'o': case 'O':
- base = 8;
- ADV(2);
- break;
- case 'd': case 'D':
- base = 10;
- ADV(2);
- break;
- default:
- base = 8;
- }
- }
- else if (base < -1) {
- base = -base;
- }
- else {
- base = 10;
- }
+ if (str[0] == '0' && len > 1) {
+ switch (str[1]) {
+ case 'x': case 'X':
+ base = 16;
+ ADV(2);
+ break;
+ case 'b': case 'B':
+ base = 2;
+ ADV(2);
+ break;
+ case 'o': case 'O':
+ base = 8;
+ ADV(2);
+ break;
+ case 'd': case 'D':
+ base = 10;
+ ADV(2);
+ break;
+ default:
+ base = 8;
+ }
+ }
+ else if (base < -1) {
+ base = -base;
+ }
+ else {
+ base = 10;
+ }
}
else if (len == 1 || !(flags & RB_INT_PARSE_PREFIX)) {
- /* no prefix */
+ /* no prefix */
}
else if (base == 2) {
- if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
- ADV(2);
- }
+ if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
+ ADV(2);
+ }
}
else if (base == 8) {
- if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
- ADV(2);
- }
+ if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
+ ADV(2);
+ }
}
else if (base == 10) {
- if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
- ADV(2);
- }
+ if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
+ ADV(2);
+ }
}
else if (base == 16) {
- if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
- ADV(2);
- }
+ if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
+ ADV(2);
+ }
}
if (!valid_radix_p(base)) {
invalid_radix(base);
@@ -4143,80 +4167,79 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
if (!len) goto bad;
num_digits = str - s;
if (*str == '0' && len != 1) { /* squeeze preceding 0s */
- int us = 0;
- const char *end = len < 0 ? NULL : str + len;
- ++num_digits;
- while ((c = *++str) == '0' ||
- ((flags & RB_INT_PARSE_UNDERSCORE) && c == '_')) {
- if (c == '_') {
- if (++us >= 2)
- break;
- }
- else {
- ++num_digits;
- us = 0;
- }
- if (str == end) break;
- }
- if (!c || ISSPACE(c)) --str;
- if (end) len = end - str;
- ASSERT_LEN();
+ int us = 0;
+ const char *end = len < 0 ? NULL : str + len;
+ ++num_digits;
+ while ((c = *++str) == '0' ||
+ ((flags & RB_INT_PARSE_UNDERSCORE) && c == '_')) {
+ if (c == '_') {
+ if (++us >= 2)
+ break;
+ }
+ else {
+ ++num_digits;
+ us = 0;
+ }
+ if (str == end) break;
+ }
+ if (!c || ISSPACE(c)) --str;
+ if (end) len = end - str;
}
c = *str;
c = conv_digit(c);
if (c < 0 || c >= base) {
- if (!badcheck && num_digits) z = INT2FIX(0);
- goto bad;
+ if (!badcheck && num_digits) z = INT2FIX(0);
+ goto bad;
}
if (ndigits) *ndigits = num_digits;
val = ruby_scan_digits(str, len, base, &num_digits, &ov);
if (!ov) {
- const char *end = &str[num_digits];
- if (num_digits > 0 && *end == '_' && (flags & RB_INT_PARSE_UNDERSCORE))
- goto bigparse;
- if (endp) *endp = (char *)end;
- if (ndigits) *ndigits += num_digits;
- if (badcheck) {
- if (num_digits == 0) return Qnil; /* no number */
- while (len < 0 ? *end : end < str + len) {
- if (!ISSPACE(*end)) return Qnil; /* trailing garbage */
- end++;
- }
- }
-
- if (POSFIXABLE(val)) {
- if (sign) return LONG2FIX(val);
- else {
- long result = -(long)val;
- return LONG2FIX(result);
- }
- }
- else {
- VALUE big = rb_uint2big(val);
- BIGNUM_SET_SIGN(big, sign);
- return bignorm(big);
- }
+ const char *end = &str[num_digits];
+ if (num_digits > 0 && *end == '_' && (flags & RB_INT_PARSE_UNDERSCORE))
+ goto bigparse;
+ if (endp) *endp = (char *)end;
+ if (ndigits) *ndigits += num_digits;
+ if (badcheck) {
+ if (num_digits == 0) return Qnil; /* no number */
+ while (len < 0 ? *end : end < str + len) {
+ if (!ISSPACE(*end)) return Qnil; /* trailing garbage */
+ end++;
+ }
+ }
+
+ if (POSFIXABLE(val)) {
+ if (sign) return LONG2FIX(val);
+ else {
+ long result = -(long)val;
+ return LONG2FIX(result);
+ }
+ }
+ else {
+ VALUE big = rb_uint2big(val);
+ BIGNUM_SET_SIGN(big, sign);
+ return bignorm(big);
+ }
}
bigparse:
digits_start = str;
if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
- goto bad;
+ goto bad;
if (endp) *endp = (char *)(str + len);
if (ndigits) *ndigits += num_digits;
digits_end = digits_start + len;
if (POW2_P(base)) {
z = str2big_poweroftwo(sign, digits_start, digits_end, num_digits,
- bit_length(base-1));
+ bit_length(base-1));
}
else {
int digits_per_bdigits_dbl;
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
num_bdigits = roomof(num_digits, digits_per_bdigits_dbl)*2;
-#ifdef USE_GMP
+#if USE_GMP
if (GMP_STR2BIG_DIGITS < num_bdigits) {
z = str2big_gmp(sign, digits_start, digits_end, num_digits,
num_bdigits, base);
@@ -4245,7 +4268,7 @@ static VALUE
rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base)
{
return rb_int_parse_cstr(str, len, endp, NULL, base,
- RB_INT_PARSE_DEFAULT);
+ RB_INT_PARSE_DEFAULT);
}
VALUE
@@ -4294,14 +4317,14 @@ rb_str2big_poweroftwo(VALUE arg, int base, int badcheck)
s = str = StringValueCStr(arg);
len = RSTRING_LEN(arg);
if (*str == '-') {
- len--;
+ len--;
str++;
positive_p = 0;
}
digits_start = str;
if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
- invalid_integer(arg);
+ invalid_integer(arg);
digits_end = digits_start + len;
z = str2big_poweroftwo(positive_p, digits_start, digits_end, num_digits,
@@ -4333,14 +4356,14 @@ rb_str2big_normal(VALUE arg, int base, int badcheck)
s = str = StringValuePtr(arg);
len = RSTRING_LEN(arg);
if (len > 0 && *str == '-') {
- len--;
+ len--;
str++;
positive_p = 0;
}
digits_start = str;
if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
- invalid_integer(arg);
+ invalid_integer(arg);
digits_end = digits_start + len;
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
@@ -4375,14 +4398,14 @@ rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
s = str = StringValuePtr(arg);
len = RSTRING_LEN(arg);
if (len > 0 && *str == '-') {
- len--;
+ len--;
str++;
positive_p = 0;
}
digits_start = str;
if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
- invalid_integer(arg);
+ invalid_integer(arg);
digits_end = digits_start + len;
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
@@ -4396,7 +4419,7 @@ rb_str2big_karatsuba(VALUE arg, int base, int badcheck)
return bignorm(z);
}
-#ifdef USE_GMP
+#if USE_GMP
VALUE
rb_str2big_gmp(VALUE arg, int base, int badcheck)
{
@@ -4418,14 +4441,14 @@ rb_str2big_gmp(VALUE arg, int base, int badcheck)
s = str = StringValuePtr(arg);
len = RSTRING_LEN(arg);
if (len > 0 && *str == '-') {
- len--;
+ len--;
str++;
positive_p = 0;
}
digits_start = str;
if (!str2big_scan_digits(s, str, base, badcheck, &num_digits, &len))
- invalid_integer(arg);
+ invalid_integer(arg);
digits_end = digits_start + len;
maxpow_in_bdigit_dbl(base, &digits_per_bdigits_dbl);
@@ -4452,8 +4475,8 @@ rb_ull2big(unsigned LONG_LONG n)
digits[0] = n;
#else
for (i = 0; i < bdigit_roomof(SIZEOF_LONG_LONG); i++) {
- digits[i] = BIGLO(n);
- n = BIGDN(n);
+ digits[i] = BIGLO(n);
+ n = BIGDN(n);
}
#endif
@@ -4472,14 +4495,14 @@ rb_ll2big(LONG_LONG n)
if (n < 0) {
u = 1 + (unsigned LONG_LONG)(-(n + 1)); /* u = -n avoiding overflow */
- neg = 1;
+ neg = 1;
}
else {
u = n;
}
big = rb_ull2big(u);
if (neg) {
- BIGNUM_SET_NEGATIVE_SIGN(big);
+ BIGNUM_SET_NEGATIVE_SIGN(big);
}
return big;
}
@@ -4487,14 +4510,14 @@ rb_ll2big(LONG_LONG n)
VALUE
rb_ull2inum(unsigned LONG_LONG n)
{
- if (POSFIXABLE(n)) return LONG2FIX(n);
+ if (POSFIXABLE(n)) return LONG2FIX((long)n);
return rb_ull2big(n);
}
VALUE
rb_ll2inum(LONG_LONG n)
{
- if (FIXABLE(n)) return LONG2FIX(n);
+ if (FIXABLE(n)) return LONG2FIX((long)n);
return rb_ll2big(n);
}
@@ -4509,7 +4532,7 @@ rb_uint128t2big(uint128_t n)
BDIGIT *digits = BDIGITS(big);
for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) {
- digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
+ digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i));
}
i = bdigit_roomof(SIZEOF_INT128_T);
@@ -4527,14 +4550,14 @@ rb_int128t2big(int128_t n)
if (n < 0) {
u = 1 + (uint128_t)(-(n + 1)); /* u = -n avoiding overflow */
- neg = 1;
+ neg = 1;
}
else {
u = n;
}
big = rb_uint128t2big(u);
if (neg) {
- BIGNUM_SET_NEGATIVE_SIGN(big);
+ BIGNUM_SET_NEGATIVE_SIGN(big);
}
return big;
}
@@ -4563,11 +4586,14 @@ big_shift3(VALUE x, int lshift_p, size_t shift_numdigits, int shift_numbits)
if (lshift_p) {
if (LONG_MAX < shift_numdigits) {
- rb_raise(rb_eArgError, "too big number");
+ too_big:
+ rb_raise(rb_eRangeError, "shift width too big");
}
s1 = shift_numdigits;
s2 = shift_numbits;
+ if ((size_t)s1 != shift_numdigits) goto too_big;
xn = BIGNUM_LEN(x);
+ if (LONG_MAX/SIZEOF_BDIGIT <= xn+s1) goto too_big;
z = bignew(xn+s1+1, BIGNUM_SIGN(x));
zds = BDIGITS(z);
BDIGITS_ZERO(zds, s1);
@@ -4697,7 +4723,7 @@ power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
rb_obj_hide(power);
base36_power_cache[base - 2][power_level] = power;
base36_numdigits_cache[base - 2][power_level] = numdigits;
- rb_gc_register_mark_object(power);
+ rb_gc_register_mark_object(power);
}
if (numdigits_ret)
*numdigits_ret = base36_numdigits_cache[base - 2][power_level];
@@ -4748,7 +4774,7 @@ big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t tail
} while (num);
len = sizeof(buf) - j;
big2str_alloc(b2s, len + taillen);
- MEMCPY(b2s->ptr, buf + j, char, len);
+ MEMCPY(b2s->ptr, buf + j, char, len);
}
else {
p = b2s->ptr;
@@ -4765,7 +4791,7 @@ big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t tail
static void
big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn,
- int power_level, size_t taillen)
+ int power_level, size_t taillen)
{
VALUE b;
size_t half_numdigits, lower_numdigits;
@@ -4795,17 +4821,17 @@ big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn,
*/
if (xn == 0 || bary_zero_p(xds, xn)) {
- if (b2s->ptr) {
+ if (b2s->ptr) {
/* When x is zero, power_cache_get_power(base, power_level) should be cached already. */
power_cache_get_power(b2s->base, power_level, &len);
- memset(b2s->ptr, '0', len);
+ memset(b2s->ptr, '0', len);
b2s->ptr += len;
- }
+ }
return;
}
if (power_level == 0) {
- big2str_2bdigits(b2s, xds, xn, taillen);
+ big2str_2bdigits(b2s, xds, xn, taillen);
return;
}
@@ -4833,7 +4859,7 @@ big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn,
memset(b2s->ptr, '0', len);
b2s->ptr += len;
}
- big2str_2bdigits(b2s, xds, xn, taillen);
+ big2str_2bdigits(b2s, xds, xn, taillen);
}
else {
BDIGIT *qds, *rds;
@@ -4937,11 +4963,11 @@ big2str_generic(VALUE x, int base)
BARY_TRUNC(xds, xn);
if (xn == 0) {
- return rb_usascii_str_new2("0");
+ return rb_usascii_str_new2("0");
}
if (!valid_radix_p(base))
- invalid_radix(base);
+ invalid_radix(base);
if (xn >= LONG_MAX/BITSPERDIG) {
rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
@@ -4978,7 +5004,7 @@ big2str_generic(VALUE x, int base)
b2s_data.ptr = NULL;
if (power_level == 0) {
- big2str_2bdigits(&b2s_data, xds, xn, 0);
+ big2str_2bdigits(&b2s_data, xds, xn, 0);
}
else {
VALUE tmpw = 0;
@@ -4987,7 +5013,7 @@ big2str_generic(VALUE x, int base)
wn = power_level * BIGDIVREM_EXTRA_WORDS + BIGNUM_LEN(power);
wds = ALLOCV_N(BDIGIT, tmpw, xn + wn);
MEMCPY(wds, xds, BDIGIT, xn);
- big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
+ big2str_karatsuba(&b2s_data, wds, xn, wn, power_level, 0);
if (tmpw)
ALLOCV_END(tmpw);
}
@@ -5006,7 +5032,7 @@ rb_big2str_generic(VALUE x, int base)
return big2str_generic(x, base);
}
-#ifdef USE_GMP
+#if USE_GMP
static VALUE
big2str_gmp(VALUE x, int base)
{
@@ -5053,7 +5079,7 @@ rb_big2str1(VALUE x, int base)
size_t xn;
if (FIXNUM_P(x)) {
- return rb_fix2str(x, base);
+ return rb_fix2str(x, base);
}
bigtrunc(x);
@@ -5062,11 +5088,11 @@ rb_big2str1(VALUE x, int base)
BARY_TRUNC(xds, xn);
if (xn == 0) {
- return rb_usascii_str_new2("0");
+ return rb_usascii_str_new2("0");
}
if (!valid_radix_p(base))
- invalid_radix(base);
+ invalid_radix(base);
if (xn >= LONG_MAX/BITSPERDIG) {
rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
@@ -5077,7 +5103,7 @@ rb_big2str1(VALUE x, int base)
return big2str_base_poweroftwo(x, base);
}
-#ifdef USE_GMP
+#if USE_GMP
if (GMP_BIG2STR_DIGITS < xn) {
return big2str_gmp(x, base);
}
@@ -5113,7 +5139,7 @@ big2ulong(VALUE x, const char *type)
#else
num = 0;
for (i = 0; i < len; i++) {
- num <<= BITSPERDIG;
+ num <<= BITSPERDIG;
num += (unsigned long)ds[len - i - 1]; /* overflow is already checked */
}
#endif
@@ -5166,13 +5192,13 @@ big2ull(VALUE x, const char *type)
if (len == 0)
return 0;
if (BIGSIZE(x) > SIZEOF_LONG_LONG)
- rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
+ rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
#if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT
num = (unsigned LONG_LONG)ds[0];
#else
num = 0;
for (i = 0; i < len; i++) {
- num = BIGUP(num);
+ num = BIGUP(num);
num += ds[len - i - 1];
}
#endif
@@ -5222,23 +5248,23 @@ dbl2big(double d)
double u = (d < 0)?-d:d;
if (isinf(d)) {
- rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
+ rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
}
if (isnan(d)) {
- rb_raise(rb_eFloatDomainError, "NaN");
+ rb_raise(rb_eFloatDomainError, "NaN");
}
while (1.0 <= u) {
- u /= (double)(BIGRAD);
- i++;
+ u /= (double)(BIGRAD);
+ i++;
}
z = bignew(i, d>=0);
digits = BDIGITS(z);
while (i--) {
- u *= BIGRAD;
- c = (BDIGIT)u;
- u -= c;
- digits[i] = c;
+ u *= BIGRAD;
+ c = (BDIGIT)u;
+ u -= c;
+ digits[i] = c;
}
return z;
@@ -5258,28 +5284,28 @@ big2dbl(VALUE x)
BDIGIT *ds = BDIGITS(x), dl;
if (i) {
- bits = i * BITSPERDIG - nlz(ds[i-1]);
- if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
- d = HUGE_VAL;
- }
- else {
- if (bits > DBL_MANT_DIG+1)
- lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
- else
- bits = 0;
- while (--i > lo) {
- d = ds[i] + BIGRAD*d;
- }
- dl = ds[i];
- if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
- int carry = (dl & ~(BDIGMAX << bits)) != 0;
- if (!carry) {
- while (i-- > 0) {
- carry = ds[i] != 0;
- if (carry) break;
- }
- }
- if (carry) {
+ bits = i * BITSPERDIG - nlz(ds[i-1]);
+ if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
+ d = HUGE_VAL;
+ }
+ else {
+ if (bits > DBL_MANT_DIG+1)
+ lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
+ else
+ bits = 0;
+ while (--i > lo) {
+ d = ds[i] + BIGRAD*d;
+ }
+ dl = ds[i];
+ if (bits && (dl & ((BDIGIT)1 << (bits %= BITSPERDIG)))) {
+ int carry = (dl & ~(BDIGMAX << bits)) != 0;
+ if (!carry) {
+ while (i-- > 0) {
+ carry = ds[i] != 0;
+ if (carry) break;
+ }
+ }
+ if (carry) {
BDIGIT mask = BDIGMAX;
BDIGIT bit = 1;
mask <<= bits;
@@ -5287,19 +5313,19 @@ big2dbl(VALUE x)
dl &= mask;
dl += bit;
dl = BIGLO(dl);
- if (!dl) d += 1;
- }
- }
- d = dl + BIGRAD*d;
- if (lo) {
- if (lo > INT_MAX / BITSPERDIG)
- d = HUGE_VAL;
- else if (lo < INT_MIN / BITSPERDIG)
- d = 0.0;
- else
- d = ldexp(d, (int)(lo * BITSPERDIG));
- }
- }
+ if (!dl) d += 1;
+ }
+ }
+ d = dl + BIGRAD*d;
+ if (lo) {
+ if (lo > INT_MAX / BITSPERDIG)
+ d = HUGE_VAL;
+ else if (lo < INT_MIN / BITSPERDIG)
+ d = 0.0;
+ else
+ d = ldexp(d, (int)(lo * BITSPERDIG));
+ }
+ }
}
if (BIGNUM_NEGATIVE_P(x)) d = -d;
return d;
@@ -5311,11 +5337,11 @@ rb_big2dbl(VALUE x)
double d = big2dbl(x);
if (isinf(d)) {
- rb_warning("Bignum out of Float range");
- if (d < 0.0)
- d = -HUGE_VAL;
- else
- d = HUGE_VAL;
+ rb_warning("Integer out of Float range");
+ if (d < 0.0)
+ d = -HUGE_VAL;
+ else
+ d = HUGE_VAL;
}
return d;
}
@@ -5385,7 +5411,7 @@ rb_integer_float_eq(VALUE x, VALUE y)
double yd = RFLOAT_VALUE(y);
double yi, yf;
- if (isnan(yd) || isinf(yd))
+ if (!isfinite(yd))
return Qfalse;
yf = modf(yd, &yi);
if (yf != 0)
@@ -5393,18 +5419,14 @@ rb_integer_float_eq(VALUE x, VALUE y)
if (FIXNUM_P(x)) {
#if SIZEOF_LONG * CHAR_BIT < DBL_MANT_DIG /* assume FLT_RADIX == 2 */
double xd = (double)FIX2LONG(x);
- if (xd != yd)
- return Qfalse;
- return Qtrue;
+ return RBOOL(xd == yd);
#else
long xn, yn;
if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
return Qfalse;
xn = FIX2LONG(x);
yn = (long)yi;
- if (xn != yn)
- return Qfalse;
- return Qtrue;
+ return RBOOL(xn == yn);
#endif
}
y = rb_dbl2big(yi);
@@ -5416,26 +5438,26 @@ VALUE
rb_big_cmp(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
- x = bigfixize(x);
+ x = bigfixize(x);
if (FIXNUM_P(x)) {
- /* SIGNED_VALUE and Fixnum have same sign-bits, same
- * order */
- SIGNED_VALUE sx = (SIGNED_VALUE)x, sy = (SIGNED_VALUE)y;
- if (sx < sy) return INT2FIX(-1);
- return INT2FIX(sx > sy);
+ /* SIGNED_VALUE and Fixnum have same sign-bits, same
+ * order */
+ SIGNED_VALUE sx = (SIGNED_VALUE)x, sy = (SIGNED_VALUE)y;
+ if (sx < sy) return INT2FIX(-1);
+ return INT2FIX(sx > sy);
}
}
else if (RB_BIGNUM_TYPE_P(y)) {
- if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
- int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
- return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
- }
+ if (BIGNUM_SIGN(x) == BIGNUM_SIGN(y)) {
+ int cmp = bary_cmp(BDIGITS(x), BIGNUM_LEN(x), BDIGITS(y), BIGNUM_LEN(y));
+ return INT2FIX(BIGNUM_SIGN(x) ? cmp : -cmp);
+ }
}
else if (RB_FLOAT_TYPE_P(y)) {
return rb_integer_float_cmp(x, y);
}
else {
- return rb_num_coerce_cmp(x, y, idCmp);
+ return rb_num_coerce_cmp(x, y, idCmp);
}
return INT2FIX(BIGNUM_SIGN(x) ? 1 : -1);
}
@@ -5454,30 +5476,30 @@ big_op(VALUE x, VALUE y, enum big_op_t op)
int n;
if (RB_INTEGER_TYPE_P(y)) {
- rel = rb_big_cmp(x, y);
+ rel = rb_big_cmp(x, y);
}
else if (RB_FLOAT_TYPE_P(y)) {
rel = rb_integer_float_cmp(x, y);
}
else {
- ID id = 0;
- switch (op) {
- case big_op_gt: id = '>'; break;
- case big_op_ge: id = idGE; break;
- case big_op_lt: id = '<'; break;
- case big_op_le: id = idLE; break;
- }
- return rb_num_coerce_relop(x, y, id);
+ ID id = 0;
+ switch (op) {
+ case big_op_gt: id = '>'; break;
+ case big_op_ge: id = idGE; break;
+ case big_op_lt: id = '<'; break;
+ case big_op_le: id = idLE; break;
+ }
+ return rb_num_coerce_relop(x, y, id);
}
if (NIL_P(rel)) return Qfalse;
n = FIX2INT(rel);
switch (op) {
- case big_op_gt: return n > 0 ? Qtrue : Qfalse;
- case big_op_ge: return n >= 0 ? Qtrue : Qfalse;
- case big_op_lt: return n < 0 ? Qtrue : Qfalse;
- case big_op_le: return n <= 0 ? Qtrue : Qfalse;
+ case big_op_gt: return RBOOL(n > 0);
+ case big_op_ge: return RBOOL(n >= 0);
+ case big_op_lt: return RBOOL(n < 0);
+ case big_op_le: return RBOOL(n <= 0);
}
return Qundef;
}
@@ -5521,7 +5543,7 @@ VALUE
rb_big_eq(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
- return bignorm(x) == y ? Qtrue : Qfalse;
+ return RBOOL(bignorm(x) == y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
@@ -5529,12 +5551,11 @@ rb_big_eq(VALUE x, VALUE y)
return rb_integer_float_eq(x, y);
}
else {
- return rb_equal(y, x);
+ return rb_equal(y, x);
}
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
- if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
- return Qtrue;
+ return RBOOL(MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
}
VALUE
@@ -5543,8 +5564,7 @@ rb_big_eql(VALUE x, VALUE y)
if (!RB_BIGNUM_TYPE_P(y)) return Qfalse;
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y)) return Qfalse;
if (BIGNUM_LEN(x) != BIGNUM_LEN(y)) return Qfalse;
- if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) != 0) return Qfalse;
- return Qtrue;
+ return RBOOL(MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,BIGNUM_LEN(y)) == 0);
}
VALUE
@@ -5638,10 +5658,10 @@ bigsub_int(VALUE x, long y0)
assert(xn == zn);
num = (BDIGIT_DBL_SIGNED)xds[0] - y;
if (xn == 1 && num < 0) {
- BIGNUM_NEGATE(z);
- zds[0] = (BDIGIT)-num;
- RB_GC_GUARD(x);
- return bignorm(z);
+ BIGNUM_NEGATE(z);
+ zds[0] = (BDIGIT)-num;
+ RB_GC_GUARD(x);
+ return bignorm(z);
}
zds[0] = BIGLO(num);
num = BIGDN(num);
@@ -5653,10 +5673,10 @@ bigsub_int(VALUE x, long y0)
num = 0;
for (i=0; i < xn; i++) {
if (y == 0) goto y_is_zero_x;
- num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
- zds[i] = BIGLO(num);
- num = BIGDN(num);
- y = BIGDN(y);
+ num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
}
for (; i < zn; i++) {
if (y == 0) goto y_is_zero_z;
@@ -5671,9 +5691,9 @@ bigsub_int(VALUE x, long y0)
for (; i < xn; i++) {
y_is_zero_x:
if (num == 0) goto num_is_zero_x;
- num += xds[i];
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ num += xds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
#if SIZEOF_BDIGIT < SIZEOF_LONG
for (; i < zn; i++) {
@@ -5687,7 +5707,7 @@ bigsub_int(VALUE x, long y0)
for (; i < xn; i++) {
num_is_zero_x:
- zds[i] = xds[i];
+ zds[i] = xds[i];
}
#if SIZEOF_BDIGIT < SIZEOF_LONG
for (; i < zn; i++) {
@@ -5701,7 +5721,7 @@ bigsub_int(VALUE x, long y0)
assert(num == 0 || num == -1);
if (num < 0) {
get2comp(z);
- BIGNUM_NEGATE(z);
+ BIGNUM_NEGATE(z);
}
RB_GC_GUARD(x);
return bignorm(z);
@@ -5744,17 +5764,17 @@ bigadd_int(VALUE x, long y)
num = 0;
for (i=0; i < xn; i++) {
if (y == 0) goto y_is_zero_x;
- num += (BDIGIT_DBL)xds[i] + BIGLO(y);
- zds[i] = BIGLO(num);
- num = BIGDN(num);
- y = BIGDN(y);
+ num += (BDIGIT_DBL)xds[i] + BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
}
for (; i < zn; i++) {
if (y == 0) goto y_is_zero_z;
- num += BIGLO(y);
- zds[i] = BIGLO(num);
- num = BIGDN(num);
- y = BIGDN(y);
+ num += BIGLO(y);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
+ y = BIGDN(y);
}
goto finish;
@@ -5763,25 +5783,25 @@ bigadd_int(VALUE x, long y)
for (;i < xn; i++) {
y_is_zero_x:
if (num == 0) goto num_is_zero_x;
- num += (BDIGIT_DBL)xds[i];
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ num += (BDIGIT_DBL)xds[i];
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
for (; i < zn; i++) {
y_is_zero_z:
if (num == 0) goto num_is_zero_z;
- zds[i] = BIGLO(num);
- num = BIGDN(num);
+ zds[i] = BIGLO(num);
+ num = BIGDN(num);
}
goto finish;
for (;i < xn; i++) {
num_is_zero_x:
- zds[i] = xds[i];
+ zds[i] = xds[i];
}
for (; i < zn; i++) {
num_is_zero_z:
- zds[i] = 0;
+ zds[i] = 0;
}
goto finish;
@@ -5798,15 +5818,15 @@ bigadd(VALUE x, VALUE y, int sign)
sign = (sign == BIGNUM_SIGN(y));
if (BIGNUM_SIGN(x) != sign) {
- if (sign) return bigsub(y, x);
- return bigsub(x, y);
+ if (sign) return bigsub(y, x);
+ return bigsub(x, y);
}
if (BIGNUM_LEN(x) > BIGNUM_LEN(y)) {
- len = BIGNUM_LEN(x) + 1;
+ len = BIGNUM_LEN(x) + 1;
}
else {
- len = BIGNUM_LEN(y) + 1;
+ len = BIGNUM_LEN(y) + 1;
}
z = bignew(len, sign);
@@ -5823,26 +5843,26 @@ rb_big_plus(VALUE x, VALUE y)
long n;
if (FIXNUM_P(y)) {
- n = FIX2LONG(y);
- if ((n > 0) != BIGNUM_SIGN(x)) {
- if (n < 0) {
- n = -n;
- }
- return bigsub_int(x, n);
- }
- if (n < 0) {
- n = -n;
- }
- return bigadd_int(x, n);
+ n = FIX2LONG(y);
+ if ((n > 0) != BIGNUM_SIGN(x)) {
+ if (n < 0) {
+ n = -n;
+ }
+ return bigsub_int(x, n);
+ }
+ if (n < 0) {
+ n = -n;
+ }
+ return bigadd_int(x, n);
}
else if (RB_BIGNUM_TYPE_P(y)) {
- return bignorm(bigadd(x, y, 1));
+ return bignorm(bigadd(x, y, 1));
}
else if (RB_FLOAT_TYPE_P(y)) {
- return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
+ return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
}
else {
- return rb_num_coerce_bin(x, y, '+');
+ return rb_num_coerce_bin(x, y, '+');
}
}
@@ -5852,26 +5872,26 @@ rb_big_minus(VALUE x, VALUE y)
long n;
if (FIXNUM_P(y)) {
- n = FIX2LONG(y);
- if ((n > 0) != BIGNUM_SIGN(x)) {
- if (n < 0) {
- n = -n;
- }
- return bigadd_int(x, n);
- }
- if (n < 0) {
- n = -n;
- }
- return bigsub_int(x, n);
+ n = FIX2LONG(y);
+ if ((n > 0) != BIGNUM_SIGN(x)) {
+ if (n < 0) {
+ n = -n;
+ }
+ return bigadd_int(x, n);
+ }
+ if (n < 0) {
+ n = -n;
+ }
+ return bigsub_int(x, n);
}
else if (RB_BIGNUM_TYPE_P(y)) {
- return bignorm(bigadd(x, y, 0));
+ return bignorm(bigadd(x, y, 0));
}
else if (RB_FLOAT_TYPE_P(y)) {
- return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
+ return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
}
else {
- return rb_num_coerce_bin(x, y, '-');
+ return rb_num_coerce_bin(x, y, '-');
}
}
@@ -5930,15 +5950,15 @@ VALUE
rb_big_mul(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
- y = rb_int2big(FIX2LONG(y));
+ y = rb_int2big(FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
- return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
+ return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
}
else {
- return rb_num_coerce_bin(x, y, '*');
+ return rb_num_coerce_bin(x, y, '*');
}
return bignorm(bigmul0(x, y));
@@ -5965,21 +5985,21 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
BARY_TRUNC(xds, xn);
if (xn < yn || (xn == yn && xds[xn - 1] < yds[yn - 1])) {
- if (divp) *divp = rb_int2big(0);
- if (modp) *modp = x;
- return Qnil;
+ if (divp) *divp = rb_int2big(0);
+ if (modp) *modp = x;
+ return Qnil;
}
if (yn == 1) {
- dd = yds[0];
- z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
- zds = BDIGITS(z);
+ dd = yds[0];
+ z = bignew(xn, BIGNUM_SIGN(x)==BIGNUM_SIGN(y));
+ zds = BDIGITS(z);
dd = bigdivrem_single(zds, xds, xn, dd);
- if (modp) {
- *modp = rb_uint2big((uintptr_t)dd);
- BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
- }
- if (divp) *divp = z;
- return Qnil;
+ if (modp) {
+ *modp = rb_uint2big((uintptr_t)dd);
+ BIGNUM_SET_SIGN(*modp, BIGNUM_SIGN(x));
+ }
+ if (divp) *divp = z;
+ return Qnil;
}
if (xn == 2 && yn == 2) {
BDIGIT_DBL x0 = bary2bdigitdbl(xds, 2);
@@ -6044,11 +6064,11 @@ bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
bigdivrem(x, y, divp, &mod);
if (BIGNUM_SIGN(x) != BIGNUM_SIGN(y) && !BIGZEROP(mod)) {
- if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
- if (modp) *modp = bigadd(mod, y, 1);
+ if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
+ if (modp) *modp = bigadd(mod, y, 1);
}
else if (modp) {
- *modp = mod;
+ *modp = mod;
}
}
@@ -6059,25 +6079,25 @@ rb_big_divide(VALUE x, VALUE y, ID op)
VALUE z;
if (FIXNUM_P(y)) {
- y = rb_int2big(FIX2LONG(y));
+ y = rb_int2big(FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
}
else if (RB_FLOAT_TYPE_P(y)) {
- if (op == '/') {
+ if (op == '/') {
double dx = rb_big2dbl(x);
return rb_flo_div_flo(DBL2NUM(dx), y);
- }
- else {
+ }
+ else {
VALUE v;
- double dy = RFLOAT_VALUE(y);
- if (dy == 0.0) rb_num_zerodiv();
+ double dy = RFLOAT_VALUE(y);
+ if (dy == 0.0) rb_num_zerodiv();
v = rb_big_divide(x, y, '/');
return rb_dbl2big(RFLOAT_VALUE(v));
- }
+ }
}
else {
- return rb_num_coerce_bin(x, y, op);
+ return rb_num_coerce_bin(x, y, op);
}
bigdivmod(x, y, &z, 0);
@@ -6102,10 +6122,10 @@ rb_big_modulo(VALUE x, VALUE y)
VALUE z;
if (FIXNUM_P(y)) {
- y = rb_int2big(FIX2LONG(y));
+ y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
- return rb_num_coerce_bin(x, y, '%');
+ return rb_num_coerce_bin(x, y, '%');
}
bigdivmod(x, y, 0, &z);
@@ -6118,10 +6138,10 @@ rb_big_remainder(VALUE x, VALUE y)
VALUE z;
if (FIXNUM_P(y)) {
- y = rb_int2big(FIX2LONG(y));
+ y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
- return rb_num_coerce_bin(x, y, rb_intern("remainder"));
+ return rb_num_coerce_bin(x, y, rb_intern("remainder"));
}
bigdivrem(x, y, 0, &z);
@@ -6134,7 +6154,7 @@ rb_big_divmod(VALUE x, VALUE y)
VALUE div, mod;
if (FIXNUM_P(y)) {
- y = rb_int2big(FIX2LONG(y));
+ y = rb_int2big(FIX2LONG(y));
}
else if (!RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bin(x, y, idDivmod);
@@ -6148,9 +6168,9 @@ static VALUE
big_shift(VALUE x, long n)
{
if (n < 0)
- return big_lshift(x, 1+(unsigned long)(-(n+1)));
+ return big_lshift(x, 1+(unsigned long)(-(n+1)));
else if (n > 0)
- return big_rshift(x, (unsigned long)n);
+ return big_rshift(x, (unsigned long)n);
return x;
}
@@ -6174,9 +6194,9 @@ big_fdiv(VALUE x, VALUE y, long ey)
l = ex - ey;
#if SIZEOF_LONG > SIZEOF_INT
{
- /* Visual C++ can't be here */
- if (l > INT_MAX) return HUGE_VAL;
- if (l < INT_MIN) return 0.0;
+ /* Visual C++ can't be here */
+ if (l > INT_MAX) return HUGE_VAL;
+ if (l < INT_MIN) return 0.0;
}
#endif
return ldexp(big2dbl(z), (int)l);
@@ -6210,19 +6230,19 @@ rb_big_fdiv_double(VALUE x, VALUE y)
dx = big2dbl(x);
if (FIXNUM_P(y)) {
- dy = (double)FIX2LONG(y);
- if (isinf(dx))
- return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
+ dy = (double)FIX2LONG(y);
+ if (isinf(dx))
+ return big_fdiv_int(x, rb_int2big(FIX2LONG(y)));
}
else if (RB_BIGNUM_TYPE_P(y)) {
- return big_fdiv_int(x, y);
+ return big_fdiv_int(x, y);
}
else if (RB_FLOAT_TYPE_P(y)) {
- dy = RFLOAT_VALUE(y);
- if (isnan(dy))
- return dy;
- if (isinf(dx))
- return big_fdiv_float(x, y);
+ dy = RFLOAT_VALUE(y);
+ if (isnan(dy))
+ return dy;
+ if (isinf(dx))
+ return big_fdiv_float(x, y);
}
else {
return NUM2DBL(rb_num_coerce_bin(x, y, idFdiv));
@@ -6247,20 +6267,20 @@ rb_big_pow(VALUE x, VALUE y)
if (y == INT2FIX(0)) return INT2FIX(1);
if (y == INT2FIX(1)) return x;
if (RB_FLOAT_TYPE_P(y)) {
- d = RFLOAT_VALUE(y);
- if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
+ d = RFLOAT_VALUE(y);
+ if ((BIGNUM_NEGATIVE_P(x) && !BIGZEROP(x))) {
return rb_dbl_complex_new_polar_pi(pow(-rb_big2dbl(x), d), d);
- }
+ }
}
else if (RB_BIGNUM_TYPE_P(y)) {
- y = bignorm(y);
- if (FIXNUM_P(y))
- goto again;
- rb_warn("in a**b, b may be too big");
- d = rb_big2dbl(y);
+ y = bignorm(y);
+ if (FIXNUM_P(y))
+ goto again;
+ rb_warn("in a**b, b may be too big");
+ d = rb_big2dbl(y);
}
else if (FIXNUM_P(y)) {
- yy = FIX2LONG(y);
+ yy = FIX2LONG(y);
if (yy < 0) {
x = rb_big_pow(x, LONG2NUM(-yy));
@@ -6269,31 +6289,31 @@ rb_big_pow(VALUE x, VALUE y)
else
return DBL2NUM(1.0 / NUM2DBL(x));
}
- else {