summaryrefslogtreecommitdiff
path: root/ruby_atomic.h
blob: f4dd5db38a6bc761ce1a7e4ee16c6cc02fb37ee7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef RUBY_ATOMIC_H
#define RUBY_ATOMIC_H

#if 0
#elif defined HAVE_GCC_ATOMIC_BUILTINS
/* @shyouhei hack to support atomic operations in case of gcc. Gcc
 * has its own pseudo-insns to support them.  See info, or
 * http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html */

typedef unsigned int rb_atomic_t; /* Anything OK */
# define ATOMIC_SET(var, val)  (void)__sync_lock_test_and_set(&(var), (val))
# define ATOMIC_INC(var) __sync_fetch_and_add(&(var), 1)
# define ATOMIC_DEC(var) __sync_fetch_and_sub(&(var), 1)
# define ATOMIC_OR(var, val) __sync_or_and_fetch(&(var), (val))
# define ATOMIC_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))

# define ATOMIC_SIZE_ADD(var, val) __sync_fetch_and_add(&(var), (val))
# define ATOMIC_SIZE_SUB(var, val) __sync_fetch_and_sub(&(var), (val))
# define ATOMIC_SIZE_INC(var) __sync_fetch_and_add(&(var), 1)
# define ATOMIC_SIZE_DEC(var) __sync_fetch_and_sub(&(var), 1)
# define ATOMIC_SIZE_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))

#elif defined _WIN32
#if defined _MSC_VER && _MSC_VER > 1200
#pragma intrinsic(_InterlockedOr)
#endif
typedef LONG rb_atomic_t;

# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
# define ATOMIC_INC(var) InterlockedIncrement(&(var))
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
#if defined __GNUC__
# define ATOMIC_OR(var, val) __asm__("lock\n\t" "orl\t%1, %0" : "=m"(var) : "Ir"(val))
#elif defined _MSC_VER && _MSC_VER <= 1200
# define ATOMIC_OR(var, val) rb_w32_atomic_or(&(var), (val))
static inline void
rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
{
#ifdef _M_IX86
    __asm mov eax, var;
    __asm mov ecx, val;
    __asm lock or [eax], ecx;
#else
#error unsupported architecture
#endif
}
#else
# define ATOMIC_OR(var, val) _InterlockedOr(&(var), (val))
#endif
# define ATOMIC_EXCHANGE(var, val) InterlockedExchange(&(var), (val))

# ifdef _M_AMD64
#  define ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd64(&(var), (val))
#  define ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd64(&(var), -(val))
#  define ATOMIC_SIZE_INC(var) InterlockedIncrement64(&(var))
#  define ATOMIC_SIZE_DEC(var) InterlockedDecrement64(&(var))
#  define ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange64(&(var), (val))
# else
#  define ATOMIC_SIZE_ADD(var, val) InterlockedExchangeAdd((LONG *)&(var), (val))
#  define ATOMIC_SIZE_SUB(var, val) InterlockedExchangeAdd((LONG *)&(var), -(val))
#  define ATOMIC_SIZE_INC(var) InterlockedIncrement((LONG *)&(var))
#  define ATOMIC_SIZE_DEC(var) InterlockedDecrement((LONG *)&(var))
#  define ATOMIC_SIZE_EXCHANGE(var, val) InterlockedExchange((LONG *)&(var), (val))
# endif

#elif defined(__sun)
#include <atomic.h>
typedef unsigned int rb_atomic_t;

# define ATOMIC_SET(var, val) (void)atomic_swap_uint(&(var), (val))
# define ATOMIC_INC(var) atomic_inc_uint(&(var))
# define ATOMIC_DEC(var) atomic_dec_uint(&(var))
# define ATOMIC_OR(var, val) atomic_or_uint(&(var), (val))
# define ATOMIC_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))

# if SIZEOF_SIZE_T == SIZEOF_LONG
#  define ATOMIC_SIZE_ADD(var, val) atomic_add_long(&(var), (val))
#  define ATOMIC_SIZE_SUB(var, val) atomic_add_long(&(var), -(val))
#  define ATOMIC_SIZE_INC(var) atomic_inc_ulong(&(var))
#  define ATOMIC_SIZE_DEC(var) atomic_dec_ulong(&(var))
#  define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_ulong(&(var), (val))
# else
#  define ATOMIC_SIZE_ADD(var, val) atomic_add_int(&(var), (val))
#  define ATOMIC_SIZE_SUB(var, val) atomic_add_int(&(var), -(val))
#  define ATOMIC_SIZE_INC(var) atomic_inc_uint(&(var))
#  define ATOMIC_SIZE_DEC(var) atomic_dec_uint(&(var))
#  define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_uint(&(var), (val))
# endif

#else
typedef int rb_atomic_t;
#define NEED_RUBY_ATOMIC_EXCHANGE
extern rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val);

# define ATOMIC_SET(var, val) (void)((var) = (val))
# define ATOMIC_INC(var) ((var)++)
# define ATOMIC_DEC(var) ((var)--)
# define ATOMIC_OR(var, val) ((var) |= (val))
# define ATOMIC_EXCHANGE(var, val) ruby_atomic_exchange(&(var), (val))

# define ATOMIC_SIZE_ADD(var, val) (void)((var) += (val))
# define ATOMIC_SIZE_SUB(var, val) (void)((var) -= (val))
# define ATOMIC_SIZE_INC(var) ((var)++)
# define ATOMIC_SIZE_DEC(var) ((var)--)
# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_size_exchange(&(var), (val))
static inline size_t
atomic_size_exchange(size_t *ptr, size_t val)
{
    size_t old = *ptr;
    *ptr = val;
    return old;
}
#endif

#endif /* RUBY_ATOMIC_H */
le='width: 0.0%;'/> -rw-r--r--.github/workflows/spec_guards.yml71
-rw-r--r--.github/workflows/ubuntu.yml206
-rw-r--r--.github/workflows/wasm.yml146
-rw-r--r--.github/workflows/windows.yml194
-rw-r--r--.github/workflows/yjit-ubuntu.yml170
-rw-r--r--.gitignore30
-rw-r--r--.indent.pro32
-rw-r--r--.rdoc_options4
-rw-r--r--.travis.yml567
-rw-r--r--CONTRIBUTING.md5
-rw-r--r--LEGAL758
-rw-r--r--NEWS.md832
-rw-r--r--README.ja.md43
-rw-r--r--README.md151
-rw-r--r--aclocal.m447
-rw-r--r--addr2line.c794
-rw-r--r--addr2line.h5
-rw-r--r--appveyor.yml94
-rw-r--r--array.c6824
-rw-r--r--array.rb79
-rw-r--r--ast.c248
-rw-r--r--ast.rb348
-rwxr-xr-xautogen.sh17
-rwxr-xr-xbasictest/test.rb19
-rw-r--r--benchmark/README.md16
-rw-r--r--benchmark/array_max_float.yml30
-rw-r--r--benchmark/array_max_int.yml31
-rw-r--r--benchmark/array_max_str.yml30
-rw-r--r--benchmark/array_min.yml31
-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_lazy_flat_map.yml16
-rw-r--r--benchmark/enum_lazy_zip.yml22
-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/kernel_clone.yml6
-rw-r--r--benchmark/kernel_float.yml5
-rw-r--r--benchmark/kernel_tap.yml6
-rw-r--r--benchmark/kernel_then.yml6
-rw-r--r--benchmark/keyword_arguments.yml13
-rw-r--r--benchmark/lib/benchmark_driver/runner/mjit.rb34
-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.yml8
-rw-r--r--benchmark/mjit_exec_vm2jt.yml8
-rw-r--r--benchmark/mjit_exec_vm2vm.yml8
-rw-r--r--benchmark/mjit_exivar.yml18
-rw-r--r--benchmark/mjit_integer.yml32
-rw-r--r--benchmark/mjit_kernel.yml20
-rw-r--r--benchmark/mjit_leave.yml8
-rw-r--r--benchmark/mjit_opt_cc_insns.yml27
-rw-r--r--benchmark/mjit_struct_aref.yml10
-rw-r--r--benchmark/module_eqq.yml27
-rw-r--r--benchmark/nilclass.yml6
-rw-r--r--benchmark/num_zero_p.yml8
-rw-r--r--benchmark/numeric_methods.yml29
-rw-r--r--benchmark/object_allocate.yml21
-rw-r--r--benchmark/objspace_dump_all.yml13
-rw-r--r--benchmark/pm_array.yml19
-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_casecmp.yml26
-rw-r--r--benchmark/string_casecmp_p.yml26
-rw-r--r--benchmark/string_concat.yml45
-rw-r--r--benchmark/string_downcase.yml8
-rw-r--r--benchmark/string_split.yml25
-rw-r--r--benchmark/string_swapcase.yml8
-rw-r--r--benchmark/string_upcase.yml8
-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/vm1_attr_ivar.yml14
-rw-r--r--benchmark/vm1_attr_ivar_set.yml14
-rw-r--r--benchmark/vm1_block.yml9
-rw-r--r--benchmark/vm1_blockparam.yml7
-rw-r--r--benchmark/vm1_blockparam_call.yml8
-rw-r--r--benchmark/vm1_blockparam_pass.yml12
-rw-r--r--benchmark/vm1_blockparam_yield.yml8
-rw-r--r--benchmark/vm1_const.yml7
-rw-r--r--benchmark/vm1_ensure.yml14
-rw-r--r--benchmark/vm1_float_simple.yml8
-rw-r--r--benchmark/vm1_gc_short_lived.yml9
-rw-r--r--benchmark/vm1_gc_short_with_complex_long.yml25
-rw-r--r--benchmark/vm1_gc_short_with_long.yml13
-rw-r--r--benchmark/vm1_gc_short_with_symbol.yml13
-rw-r--r--benchmark/vm1_gc_wb_ary.yml12
-rw-r--r--benchmark/vm1_gc_wb_ary_promoted.yml15
-rw-r--r--benchmark/vm1_gc_wb_obj.yml15
-rw-r--r--benchmark/vm1_gc_wb_obj_promoted.yml17
-rw-r--r--benchmark/vm1_ivar.yml6
-rw-r--r--benchmark/vm1_ivar_set.yml5
-rw-r--r--benchmark/vm1_length.yml8
-rw-r--r--benchmark/vm1_lvar_init.yml21
-rw-r--r--benchmark/vm1_lvar_set.yml4
-rw-r--r--benchmark/vm1_neq.yml7
-rw-r--r--benchmark/vm1_not.yml6
-rw-r--r--benchmark/vm1_rescue.yml6
-rw-r--r--benchmark/vm1_simplereturn.yml7
-rw-r--r--benchmark/vm1_swap.yml7
-rw-r--r--benchmark/vm1_yield.yml13
-rw-r--r--benchmark/vm2_array.yml4
-rw-r--r--benchmark/vm2_bigarray.yml105
-rw-r--r--benchmark/vm2_bighash.yml4
-rw-r--r--benchmark/vm2_case.yml13
-rw-r--r--benchmark/vm2_case_lit.yml23
-rw-r--r--benchmark/vm2_defined_method.yml8
-rw-r--r--benchmark/vm2_dstr.yml6
-rw-r--r--benchmark/vm2_eval.yml4
-rw-r--r--benchmark/vm2_fiber_allocate.yml8
-rw-r--r--benchmark/vm2_fiber_count.yml10
-rw-r--r--benchmark/vm2_fiber_reuse.yml14
-rw-r--r--benchmark/vm2_fiber_reuse_gc.yml12
-rw-r--r--benchmark/vm2_fiber_switch.yml9
-rw-r--r--benchmark/vm2_freezestring.yml10
-rw-r--r--benchmark/vm2_method.yml8
-rw-r--r--benchmark/vm2_method_missing.yml11
-rw-r--r--benchmark/vm2_method_with_block.yml8
-rw-r--r--benchmark/vm2_module_ann_const_set.yml4
-rw-r--r--benchmark/vm2_module_const_set.yml8
-rw-r--r--benchmark/vm2_mutex.yml8
-rw-r--r--benchmark/vm2_newlambda.yml4
-rw-r--r--benchmark/vm2_poly_method.yml24
-rw-r--r--benchmark/vm2_poly_method_ov.yml24
-rw-r--r--benchmark/vm2_poly_same_method.yml25
-rw-r--r--benchmark/vm2_poly_singleton.yml18
-rw-r--r--benchmark/vm2_proc.yml12
-rw-r--r--benchmark/vm2_raise1.yml16
-rw-r--r--benchmark/vm2_raise2.yml16
-rw-r--r--benchmark/vm2_regexp.yml8
-rw-r--r--benchmark/vm2_send.yml11
-rw-r--r--benchmark/vm2_string_literal.yml4
-rw-r--r--benchmark/vm2_struct_big_aref_hi.yml7
-rw-r--r--benchmark/vm2_struct_big_aref_lo.yml7
-rw-r--r--benchmark/vm2_struct_big_aset.yml11
-rw-r--r--benchmark/vm2_struct_big_href_hi.yml7
-rw-r--r--benchmark/vm2_struct_big_href_lo.yml7
-rw-r--r--benchmark/vm2_struct_big_hset.yml11
-rw-r--r--benchmark/vm2_struct_small_aref.yml7
-rw-r--r--benchmark/vm2_struct_small_aset.yml11
-rw-r--r--benchmark/vm2_struct_small_href.yml7
-rw-r--r--benchmark/vm2_struct_small_hset.yml7
-rw-r--r--benchmark/vm2_super.yml17
-rw-r--r--benchmark/vm2_unif1.yml7
-rw-r--r--benchmark/vm2_zsuper.yml18
-rw-r--r--benchmark/vm_array.yml4
-rw-r--r--benchmark/vm_attr_ivar.yml14
-rw-r--r--benchmark/vm_attr_ivar_set.yml14
-rw-r--r--benchmark/vm_backtrace.rb (renamed from benchmark/vm3_backtrace.rb)0
-rw-r--r--benchmark/vm_bigarray.yml105
-rw-r--r--benchmark/vm_bighash.yml4
-rw-r--r--benchmark/vm_block.yml9
-rw-r--r--benchmark/vm_block_handler.yml27
-rw-r--r--benchmark/vm_blockparam.yml7
-rw-r--r--benchmark/vm_blockparam_call.yml8
-rw-r--r--benchmark/vm_blockparam_pass.yml12
-rw-r--r--benchmark/vm_blockparam_yield.yml8
-rw-r--r--benchmark/vm_case.yml13
-rw-r--r--benchmark/vm_case_classes.yml9
-rw-r--r--benchmark/vm_case_lit.yml23
-rw-r--r--benchmark/vm_clearmethodcache.rb (renamed from benchmark/vm3_clearmethodcache.rb)0
-rw-r--r--benchmark/vm_const.yml13
-rw-r--r--benchmark/vm_cvar.yml20
-rw-r--r--benchmark/vm_defined_method.yml8
-rw-r--r--benchmark/vm_dstr.yml6
-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_ensure.yml14
-rw-r--r--benchmark/vm_eval.yml4
-rw-r--r--benchmark/vm_fiber_allocate.yml8
-rw-r--r--benchmark/vm_fiber_count.yml10
-rw-r--r--benchmark/vm_fiber_reuse.yml14
-rw-r--r--benchmark/vm_fiber_reuse_gc.yml12
-rw-r--r--benchmark/vm_fiber_switch.yml9
-rw-r--r--benchmark/vm_float_simple.yml8
-rw-r--r--benchmark/vm_freezeobj.yml6
-rw-r--r--benchmark/vm_freezestring.yml10
-rw-r--r--benchmark/vm_gc.rb (renamed from benchmark/vm3_gc.rb)0
-rw-r--r--benchmark/vm_gc_old_full.rb (renamed from benchmark/vm3_gc_old_full.rb)0
-rw-r--r--benchmark/vm_gc_old_immediate.rb (renamed from benchmark/vm3_gc_old_immediate.rb)0
-rw-r--r--benchmark/vm_gc_old_lazy.rb (renamed from benchmark/vm3_gc_old_lazy.rb)0
-rw-r--r--benchmark/vm_gc_short_lived.yml9
-rw-r--r--benchmark/vm_gc_short_with_complex_long.yml25
-rw-r--r--benchmark/vm_gc_short_with_long.yml13
-rw-r--r--benchmark/vm_gc_short_with_symbol.yml13
-rw-r--r--benchmark/vm_gc_wb_ary.yml12
-rw-r--r--benchmark/vm_gc_wb_ary_promoted.yml15
-rw-r--r--benchmark/vm_gc_wb_obj.yml15
-rw-r--r--benchmark/vm_gc_wb_obj_promoted.yml17
-rw-r--r--benchmark/vm_iclass_super.yml20
-rw-r--r--benchmark/vm_ivar.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_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.yml5
-rw-r--r--benchmark/vm_ivar_set_on_instance.yml35
-rw-r--r--benchmark/vm_ivar_set_subclass.yml20
-rw-r--r--benchmark/vm_length.yml8
-rw-r--r--benchmark/vm_lvar_cond_set.yml8
-rw-r--r--benchmark/vm_lvar_init.yml21
-rw-r--r--benchmark/vm_lvar_set.yml4
-rw-r--r--benchmark/vm_method.yml8
-rw-r--r--benchmark/vm_method_missing.yml11
-rw-r--r--benchmark/vm_method_with_block.yml8
-rw-r--r--benchmark/vm_module_ann_const_set.yml4
-rw-r--r--benchmark/vm_module_const_set.yml8
-rw-r--r--benchmark/vm_mutex.yml8
-rw-r--r--benchmark/vm_neq.yml7
-rw-r--r--benchmark/vm_newlambda.yml4
-rw-r--r--benchmark/vm_not.yml6
-rw-r--r--benchmark/vm_poly_method.yml24
-rw-r--r--benchmark/vm_poly_method_ov.yml24
-rw-r--r--benchmark/vm_poly_same_method.yml25
-rw-r--r--benchmark/vm_poly_singleton.yml18
-rw-r--r--benchmark/vm_proc.yml12
-rw-r--r--benchmark/vm_raise1.yml16
-rw-r--r--benchmark/vm_raise2.yml16
-rw-r--r--benchmark/vm_regexp.yml8
-rw-r--r--benchmark/vm_rescue.yml6
-rw-r--r--benchmark/vm_send.yml14
-rw-r--r--benchmark/vm_send_cfunc.yml3
-rw-r--r--benchmark/vm_simplereturn.yml7
-rw-r--r--benchmark/vm_string_literal.yml4
-rw-r--r--benchmark/vm_struct_big_aref_hi.yml7
-rw-r--r--benchmark/vm_struct_big_aref_lo.yml7
-rw-r--r--benchmark/vm_struct_big_aset.yml11
-rw-r--r--benchmark/vm_struct_big_href_hi.yml7
-rw-r--r--benchmark/vm_struct_big_href_lo.yml7
-rw-r--r--benchmark/vm_struct_big_hset.yml11
-rw-r--r--benchmark/vm_struct_small_aref.yml7
-rw-r--r--benchmark/vm_struct_small_aset.yml11
-rw-r--r--benchmark/vm_struct_small_href.yml7
-rw-r--r--benchmark/vm_struct_small_hset.yml7
-rw-r--r--benchmark/vm_super.yml17
-rw-r--r--benchmark/vm_swap.yml7
-rw-r--r--benchmark/vm_thread_condvar1.rb8
-rw-r--r--benchmark/vm_thread_condvar2.rb10
-rw-r--r--benchmark/vm_unif1.yml7
-rw-r--r--benchmark/vm_yield.yml13
-rw-r--r--benchmark/vm_zsuper.yml18
-rw-r--r--bignum.c1375
-rwxr-xr-xbin/bundle27
-rwxr-xr-xbin/bundler27
-rwxr-xr-xbin/erb176
-rwxr-xr-xbin/gem19
-rwxr-xr-xbin/irb27
-rwxr-xr-xbin/racc27
-rwxr-xr-xbin/rdoc27
-rwxr-xr-xbin/ri27
-rw-r--r--bootstraptest/pending.rb23
-rwxr-xr-xbootstraptest/runner.rb833
-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.rb39
-rw-r--r--bootstraptest/test_fiber.rb4
-rw-r--r--bootstraptest/test_flow.rb8
-rw-r--r--bootstraptest/test_insns.rb18
-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_proc.rb4
-rw-r--r--bootstraptest/test_ractor.rb1628
-rw-r--r--bootstraptest/test_syntax.rb8
-rw-r--r--bootstraptest/test_thread.rb25
-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.c30
-rw-r--r--builtin.h91
-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.c1831
-rw-r--r--common.mk15153
-rw-r--r--compar.c58
-rw-r--r--compile.c11691
-rw-r--r--complex.c943
-rw-r--r--configure.ac2027
-rw-r--r--constant.h4
-rw-r--r--cont.c1497
-rw-r--r--coroutine/amd64/Context.S2
-rw-r--r--coroutine/amd64/Context.h31
-rw-r--r--coroutine/arm32/Context.S21
-rw-r--r--coroutine/arm32/Context.h6
-rw-r--r--coroutine/arm64/Context.S20
-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.c141
-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.S9
-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.in57
-rw-r--r--darray.h179
-rw-r--r--debug.c510
-rw-r--r--debug_counter.c63
-rw-r--r--debug_counter.h111
-rw-r--r--defs/gmake.mk286
-rw-r--r--defs/id.def35
-rw-r--r--defs/keywords2
-rw-r--r--defs/lex.c.src2
-rw-r--r--dir.c2179
-rw-r--r--dir.rb314
-rw-r--r--dln.c1425
-rw-r--r--dln.h25
-rw-r--r--dln_find.c284
-rw-r--r--dmyenc.c2
-rw-r--r--doc/.document8
-rw-r--r--doc/ChangeLog-0.60_to_1.110
-rw-r--r--doc/ChangeLog-1.9.332
-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.0530
-rw-r--r--doc/NEWS-2.1.0376
-rw-r--r--doc/NEWS-2.2.0361
-rw-r--r--doc/NEWS-2.3.0404
-rw-r--r--doc/NEWS-2.4.0397
-rw-r--r--doc/NEWS-2.5.0565
-rw-r--r--doc/NEWS-2.6.0662
-rw-r--r--doc/NEWS-2.7.0827
-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.0384
-rw-r--r--doc/NEWS/NEWS-2.4.0399
-rw-r--r--doc/NEWS/NEWS-2.5.0565
-rw-r--r--doc/NEWS/NEWS-2.6.0662
-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.rdoc447
-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/contributors.rdoc793
-rw-r--r--doc/csv/arguments/io.rdoc5
-rw-r--r--doc/csv/options/common/col_sep.rdoc63
-rw-r--r--doc/csv/options/common/quote_char.rdoc42
-rw-r--r--doc/csv/options/common/row_sep.rdoc100
-rw-r--r--doc/csv/options/generating/force_quotes.rdoc17
-rw-r--r--doc/csv/options/generating/quote_empty.rdoc12
-rw-r--r--doc/csv/options/generating/write_converters.rdoc33
-rw-r--r--doc/csv/options/generating/write_empty_value.rdoc15
-rw-r--r--doc/csv/options/generating/write_headers.rdoc29
-rw-r--r--doc/csv/options/generating/write_nil_value.rdoc14
-rw-r--r--doc/csv/options/parsing/converters.rdoc46
-rw-r--r--doc/csv/options/parsing/empty_value.rdoc13
-rw-r--r--doc/csv/options/parsing/field_size_limit.rdoc39
-rw-r--r--doc/csv/options/parsing/header_converters.rdoc43
-rw-r--r--doc/csv/options/parsing/headers.rdoc63
-rw-r--r--doc/csv/options/parsing/liberal_parsing.rdoc19
-rw-r--r--doc/csv/options/parsing/nil_value.rdoc12
-rw-r--r--doc/csv/options/parsing/return_headers.rdoc22
-rw-r--r--doc/csv/options/parsing/skip_blanks.rdoc31
-rw-r--r--doc/csv/options/parsing/skip_lines.rdoc37
-rw-r--r--doc/csv/options/parsing/strip.rdoc15
-rw-r--r--doc/csv/options/parsing/unconverted_fields.rdoc27
-rw-r--r--doc/csv/recipes/filtering.rdoc156
-rw-r--r--doc/csv/recipes/generating.rdoc244
-rw-r--r--doc/csv/recipes/parsing.rdoc543
-rw-r--r--doc/csv/recipes/recipes.rdoc6
-rw-r--r--doc/date/calendars.rdoc62
-rw-r--r--doc/dig_methods.rdoc82
-rw-r--r--doc/dtrace_probes.rdoc78
-rw-r--r--doc/encodings.rdoc479
-rw-r--r--doc/examples/files.rdoc26
-rw-r--r--doc/extension.ja.rdoc79
-rw-r--r--doc/extension.rdoc223
-rw-r--r--doc/fiber.md232
-rw-r--r--doc/format_specifications.rdoc348
-rw-r--r--doc/globals.rdoc3
-rw-r--r--doc/implicit_conversion.rdoc221
-rw-r--r--doc/irb/irb.rd.ja17
-rw-r--r--doc/keywords.rdoc2
-rw-r--r--doc/maintainers.rdoc269
-rw-r--r--doc/make_cheatsheet.md96
-rw-r--r--doc/marshal.rdoc4
-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.md167
-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.md952
-rw-r--r--doc/rdoc/markup_reference.rb1257
-rw-r--r--doc/regexp.rdoc97
-rw-r--r--doc/standard_library.rdoc77
-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.rdoc54
-rw-r--r--doc/syntax/comments.rdoc216
-rw-r--r--doc/syntax/control_expressions.rdoc26
-rw-r--r--doc/syntax/literals.rdoc290
-rw-r--r--doc/syntax/methods.rdoc181
-rw-r--r--doc/syntax/miscellaneous.rdoc30
-rw-r--r--doc/syntax/modules_and_classes.rdoc4
-rw-r--r--doc/syntax/pattern_matching.rdoc281
-rw-r--r--doc/syntax/precedence.rdoc2
-rw-r--r--doc/syntax/refinements.rdoc3
-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.in6
-rw-r--r--enc/ascii.c8
-rw-r--r--enc/cesu_8.c23
-rw-r--r--enc/cp949.c2
-rw-r--r--enc/depend10119
-rw-r--r--enc/encdb.c2
-rw-r--r--enc/encinit.c.erb1
-rw-r--r--enc/euc_jp.c4
-rw-r--r--enc/iso_8859_11.c2
-rw-r--r--enc/iso_8859_6.c2
-rw-r--r--enc/iso_8859_8.c2
-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/shift_jis.c4
-rw-r--r--enc/trans/escape.trans3
-rw-r--r--enc/trans/ibm720-tbl.rb122
-rw-r--r--enc/trans/newline.trans20
-rw-r--r--enc/trans/single_byte.trans3
-rw-r--r--enc/trans/transdb.c2
-rw-r--r--enc/unicode.c4
-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
-rwxr-xr-xenc/unicode/case-folding.rb418
-rw-r--r--enc/utf_16_32.h2
-rw-r--r--enc/windows_1250.c2
-rw-r--r--enc/windows_1251.c2
-rw-r--r--enc/windows_1252.c2
-rw-r--r--enc/windows_1253.c2
-rw-r--r--enc/windows_1254.c2
-rw-r--r--enc/windows_1257.c2
-rw-r--r--enc/windows_31j.c2
-rw-r--r--encindex.h10
-rw-r--r--encoding.c1167
-rw-r--r--enum.c3161
-rw-r--r--enumerator.c1623
-rw-r--r--error.c1525
-rw-r--r--eval.c1339
-rw-r--r--eval_error.c602
-rw-r--r--eval_intern.h113
-rw-r--r--eval_jump.c40
-rw-r--r--ext/-test-/RUBY_ALIGNOF/c.c15
-rw-r--r--ext/-test-/RUBY_ALIGNOF/cpp.cpp9
-rw-r--r--ext/-test-/RUBY_ALIGNOF/depend162
-rw-r--r--ext/-test-/RUBY_ALIGNOF/extconf.rb6
-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/depend148
-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/depend148
-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/depend1054
-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/depend148
-rw-r--r--ext/-test-/bug-3571/depend148
-rw-r--r--ext/-test-/bug-5832/depend148
-rw-r--r--ext/-test-/bug_reporter/depend148
-rw-r--r--ext/-test-/class/depend296
-rw-r--r--ext/-test-/cxxanyargs/cxxanyargs.cpp14
-rw-r--r--ext/-test-/cxxanyargs/depend14
-rw-r--r--ext/-test-/cxxanyargs/extconf.rb4
-rw-r--r--ext/-test-/debug/depend444
-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/depend148
-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/depend601
-rw-r--r--ext/-test-/fatal/depend148
-rw-r--r--ext/-test-/fatal/rb_fatal.c3
-rw-r--r--ext/-test-/file/depend462
-rw-r--r--ext/-test-/file/fs.c16
-rw-r--r--ext/-test-/float/depend296
-rw-r--r--ext/-test-/funcall/depend148
-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/depend148
-rw-r--r--ext/-test-/hash/depend296
-rw-r--r--ext/-test-/integer/core_ext.c16
-rw-r--r--ext/-test-/integer/depend448
-rw-r--r--ext/-test-/iseq_load/depend148
-rw-r--r--ext/-test-/iter/depend444
-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/depend148
-rw-r--r--ext/-test-/marshal/compat/depend148
-rw-r--r--ext/-test-/marshal/internal_ivar/depend148
-rw-r--r--ext/-test-/marshal/internal_ivar/internal_ivar.c5
-rw-r--r--ext/-test-/marshal/usr/depend148
-rw-r--r--ext/-test-/memory_status/depend148
-rw-r--r--ext/-test-/memory_status/memory_status.c31
-rw-r--r--ext/-test-/memory_view/depend163
-rw-r--r--ext/-test-/memory_view/extconf.rb5
-rw-r--r--ext/-test-/memory_view/memory_view.c450
-rw-r--r--ext/-test-/method/depend296
-rw-r--r--ext/-test-/notimplement/depend148
-rw-r--r--ext/-test-/num2int/depend148
-rw-r--r--ext/-test-/num2int/num2int.c26
-rw-r--r--ext/-test-/path_to_class/depend148
-rw-r--r--ext/-test-/popen_deadlock/depend149
-rw-r--r--ext/-test-/postponed_job/depend148
-rw-r--r--ext/-test-/postponed_job/postponed_job.c31
-rw-r--r--ext/-test-/printf/depend157
-rw-r--r--ext/-test-/printf/printf.c64
-rw-r--r--ext/-test-/proc/depend444
-rw-r--r--ext/-test-/proc/super.c2
-rw-r--r--ext/-test-/random/bad_version.c135
-rw-r--r--ext/-test-/random/depend482
-rw-r--r--ext/-test-/random/extconf.rb3
-rw-r--r--ext/-test-/random/init.c11
-rw-r--r--ext/-test-/random/loop.c111
-rw-r--r--ext/-test-/rational/depend153
-rw-r--r--ext/-test-/rational/rat.c15
-rw-r--r--ext/-test-/rb_call_super_kw/depend148
-rw-r--r--ext/-test-/rb_call_super_kw/rb_call_super_kw.c3
-rw-r--r--ext/-test-/recursion/depend148
-rw-r--r--ext/-test-/regexp/depend296
-rw-r--r--ext/-test-/scan_args/depend148
-rw-r--r--ext/-test-/st/foreach/depend148
-rw-r--r--ext/-test-/st/foreach/foreach.c100
-rw-r--r--ext/-test-/st/numhash/depend148
-rw-r--r--ext/-test-/st/numhash/numhash.c18
-rw-r--r--ext/-test-/st/update/depend148
-rw-r--r--ext/-test-/st/update/update.c12
-rw-r--r--ext/-test-/string/capacity.c9
-rw-r--r--ext/-test-/string/coderange.c16
-rw-r--r--ext/-test-/string/cstr.c28
-rw-r--r--ext/-test-/string/depend2473
-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/rb_interned_str.c14
-rw-r--r--ext/-test-/string/set_len.c10
-rw-r--r--ext/-test-/struct/depend592
-rw-r--r--ext/-test-/struct/member.c2
-rw-r--r--ext/-test-/symbol/depend296
-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/depend13
-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/depend445
-rw-r--r--ext/-test-/time/leap_second.c1
-rw-r--r--ext/-test-/tracepoint/depend296
-rw-r--r--ext/-test-/tracepoint/gc_hook.c37
-rw-r--r--ext/-test-/tracepoint/tracepoint.c54
-rw-r--r--ext/-test-/typeddata/depend148
-rw-r--r--ext/-test-/typeddata/typeddata.c4
-rw-r--r--ext/-test-/vm/at_exit.c12
-rw-r--r--ext/-test-/vm/depend148
-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/depend17
-rw-r--r--ext/-test-/wait_for_single_fd/extconf.rb4
-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/.document17
-rw-r--r--ext/Setup1
-rw-r--r--ext/Setup.atheos1
-rw-r--r--ext/Setup.nt1
-rw-r--r--ext/bigdecimal/bigdecimal.c3515
-rw-r--r--ext/bigdecimal/bigdecimal.gemspec19
-rw-r--r--ext/bigdecimal/bigdecimal.h283
-rw-r--r--ext/bigdecimal/bits.h141
-rw-r--r--ext/bigdecimal/depend313
-rw-r--r--ext/bigdecimal/extconf.rb49
-rw-r--r--ext/bigdecimal/feature.h68
-rw-r--r--ext/bigdecimal/lib/bigdecimal/jacobian.rb6
-rw-r--r--ext/bigdecimal/lib/bigdecimal/util.rb41
-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/bigdecimal/static_assert.h54
-rw-r--r--ext/bigdecimal/util/depend14
-rw-r--r--ext/cgi/escape/depend157
-rw-r--r--ext/cgi/escape/escape.c367
-rw-r--r--ext/continuation/depend148
-rw-r--r--ext/coverage/coverage.c508
-rw-r--r--ext/coverage/depend157
-rw-r--r--ext/date/date.gemspec33
-rw-r--r--ext/date/date_core.c2312
-rw-r--r--ext/date/date_parse.c154
-rw-r--r--ext/date/date_strftime.c2
-rw-r--r--ext/date/date_strptime.c106
-rw-r--r--ext/date/depend621
-rw-r--r--ext/date/extconf.rb7
-rw-r--r--ext/date/lib/date.rb9
-rw-r--r--ext/date/prereq.mk9
-rw-r--r--ext/date/update-abbr25
-rw-r--r--ext/date/zonetab.h18
-rw-r--r--ext/date/zonetab.list16
-rw-r--r--ext/dbm/dbm.c1156
-rw-r--r--ext/dbm/dbm.gemspec20
-rw-r--r--ext/dbm/depend14
-rw-r--r--ext/dbm/extconf.rb292
-rw-r--r--ext/digest/bubblebabble/bubblebabble.c2
-rw-r--r--ext/digest/bubblebabble/depend148
-rw-r--r--ext/digest/bubblebabble/extconf.rb2
-rw-r--r--ext/digest/depend148
-rw-r--r--ext/digest/digest.c22
-rw-r--r--ext/digest/digest.gemspec44
-rw-r--r--ext/digest/digest.h10
-rw-r--r--ext/digest/digest_conf.rb71
-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/depend314
-rw-r--r--ext/digest/md5/extconf.rb2
-rw-r--r--ext/digest/md5/md5.c2
-rw-r--r--ext/digest/md5/md5init.c9
-rw-r--r--ext/digest/md5/md5ossl.h15
-rw-r--r--ext/digest/rmd160/depend313
-rw-r--r--ext/digest/rmd160/extconf.rb6
-rw-r--r--ext/digest/rmd160/rmd160init.c9
-rw-r--r--ext/digest/rmd160/rmd160ossl.h20
-rw-r--r--ext/digest/sha1/depend314
-rw-r--r--ext/digest/sha1/extconf.rb4
-rw-r--r--ext/digest/sha1/sha1init.c9
-rw-r--r--ext/digest/sha1/sha1ossl.h22
-rw-r--r--ext/digest/sha2/depend313
-rw-r--r--ext/digest/sha2/extconf.rb4
-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.c8
-rw-r--r--ext/digest/sha2/sha2ossl.h27
-rw-r--r--ext/erb/escape/escape.c95
-rw-r--r--ext/erb/escape/extconf.rb7
-rw-r--r--ext/etc/depend158
-rw-r--r--ext/etc/etc.c178
-rw-r--r--ext/etc/etc.gemspec16
-rw-r--r--ext/etc/extconf.rb3
-rwxr-xr-xext/extmk.rb138
-rw-r--r--ext/fcntl/depend148
-rw-r--r--ext/fcntl/fcntl.c31
-rw-r--r--ext/fcntl/fcntl.gemspec8
-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.c168
-rw-r--r--ext/fiddle/conversions.c241
-rw-r--r--ext/fiddle/conversions.h17
-rw-r--r--ext/fiddle/depend1239
-rw-r--r--ext/fiddle/extconf.rb146
-rw-r--r--ext/fiddle/extlibs5
-rw-r--r--ext/fiddle/fiddle.c357
-rw-r--r--ext/fiddle/fiddle.gemspec54
-rw-r--r--ext/fiddle/fiddle.h152
-rw-r--r--ext/fiddle/function.c357
-rw-r--r--ext/fiddle/handle.c133
-rw-r--r--ext/fiddle/lib/fiddle.rb51
-rw-r--r--ext/fiddle/lib/fiddle/closure.rb25
-rw-r--r--ext/fiddle/lib/fiddle/cparser.rb129
-rw-r--r--ext/fiddle/lib/fiddle/function.rb11
-rw-r--r--ext/fiddle/lib/fiddle/import.rb8
-rw-r--r--ext/fiddle/lib/fiddle/pack.rb35
-rw-r--r--ext/fiddle/lib/fiddle/struct.rb381
-rw-r--r--ext/fiddle/lib/fiddle/types.rb35
-rw-r--r--ext/fiddle/lib/fiddle/version.rb3
-rw-r--r--ext/fiddle/memory_view.c321
-rw-r--r--ext/fiddle/pinned.c123
-rw-r--r--ext/fiddle/pointer.c171
-rwxr-xr-xext/fiddle/win32/libffi-config.rb2
-rw-r--r--ext/gdbm/README1
-rw-r--r--ext/gdbm/depend14
-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.c138
-rw-r--r--ext/io/console/depend160
-rw-r--r--ext/io/console/extconf.rb7
-rw-r--r--ext/io/console/io-console.gemspec24
-rw-r--r--ext/io/console/win32_vk.inc327
-rw-r--r--ext/io/console/win32_vk.list2
-rw-r--r--ext/io/nonblock/depend157
-rw-r--r--ext/io/nonblock/io-nonblock.gemspec25
-rw-r--r--ext/io/nonblock/nonblock.c67
-rw-r--r--ext/io/wait/depend158
-rw-r--r--ext/io/wait/extconf.rb31
-rw-r--r--ext/io/wait/io-wait.gemspec38
-rw-r--r--ext/io/wait/wait.c273
-rw-r--r--ext/json/VERSION1
-rw-r--r--ext/json/extconf.rb1
-rw-r--r--ext/json/generator/depend158
-rw-r--r--ext/json/generator/generator.c89
-rw-r--r--ext/json/generator/generator.h7
-rw-r--r--ext/json/json.gemspec98
-rw-r--r--ext/json/lib/json.rb612
-rw-r--r--ext/json/lib/json/add/complex.rb1
-rw-r--r--ext/json/lib/json/add/rational.rb1
-rw-r--r--ext/json/lib/json/common.rb496
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/depend157
-rw-r--r--ext/json/parser/extconf.rb28
-rw-r--r--ext/json/parser/parser.c4745
-rw-r--r--ext/json/parser/parser.h7
-rw-r--r--ext/json/parser/parser.rl180
-rw-r--r--ext/json/parser/prereq.mk4
-rw-r--r--ext/monitor/depend148
-rw-r--r--ext/monitor/lib/monitor.rb6
-rw-r--r--ext/monitor/monitor.c20
-rw-r--r--ext/nkf/depend157
-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.gemspec24
-rw-r--r--ext/objspace/depend497
-rw-r--r--ext/objspace/lib/objspace.rb142
-rw-r--r--ext/objspace/lib/objspace/trace.rb45
-rw-r--r--ext/objspace/object_tracing.c256
-rw-r--r--ext/objspace/objspace.c640
-rw-r--r--ext/objspace/objspace_dump.c862
-rw-r--r--ext/openssl/History.md308
-rw-r--r--ext/openssl/depend5058
-rw-r--r--ext/openssl/deprecation.rb27
-rw-r--r--ext/openssl/extconf.rb170
-rw-r--r--ext/openssl/lib/openssl.rb6
-rw-r--r--ext/openssl/lib/openssl/buffering.rb11
-rw-r--r--ext/openssl/lib/openssl/config.rb473
-rw-r--r--ext/openssl/lib/openssl/digest.rb15
-rw-r--r--ext/openssl/lib/openssl/hmac.rb65
-rw-r--r--ext/openssl/lib/openssl/marshal.rb30
-rw-r--r--ext/openssl/lib/openssl/pkey.rb446
-rw-r--r--ext/openssl/lib/openssl/ssl.rb21
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/lib/openssl/x509.rb52
-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.c132
-rw-r--r--ext/openssl/ossl.h35
-rw-r--r--ext/openssl/ossl_asn1.c39
-rw-r--r--ext/openssl/ossl_bn.c420
-rw-r--r--ext/openssl/ossl_bn.h3
-rw-r--r--ext/openssl/ossl_cipher.c67
-rw-r--r--ext/openssl/ossl_config.c453
-rw-r--r--ext/openssl/ossl_config.h11
-rw-r--r--ext/openssl/ossl_digest.c91
-rw-r--r--ext/openssl/ossl_engine.c48
-rw-r--r--ext/openssl/ossl_hmac.c191
-rw-r--r--ext/openssl/ossl_kdf.c16
-rw-r--r--ext/openssl/ossl_ns_spki.c2
-rw-r--r--ext/openssl/ossl_ocsp.c60
-rw-r--r--ext/openssl/ossl_pkcs12.c24
-rw-r--r--ext/openssl/ossl_pkcs7.c101
-rw-r--r--ext/openssl/ossl_pkey.c1369
-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_rand.c34
-rw-r--r--ext/openssl/ossl_ssl.c997
-rw-r--r--ext/openssl/ossl_ssl_session.c57
-rw-r--r--ext/openssl/ossl_ts.c109
-rw-r--r--ext/openssl/ossl_x509.c87
-rw-r--r--ext/openssl/ossl_x509cert.c182
-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/depend157
-rw-r--r--ext/pathname/lib/pathname.rb35
-rw-r--r--ext/pathname/pathname.c32
-rw-r--r--ext/pathname/pathname.gemspec25
-rw-r--r--ext/psych/.gitignore1
-rw-r--r--ext/psych/depend799
-rw-r--r--ext/psych/extconf.rb70
-rw-r--r--ext/psych/lib/psych.rb340
-rw-r--r--ext/psych/lib/psych/class_loader.rb18
-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.rb65
-rw-r--r--ext/psych/lib/psych/visitors/visitor.rb20
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb78
-rw-r--r--ext/psych/psych.c9
-rw-r--r--ext/psych/psych.gemspec20
-rw-r--r--ext/psych/psych_parser.c80
-rw-r--r--ext/psych/psych_yaml_tree.c12
-rw-r--r--ext/psych/yaml/api.c1395
-rw-r--r--ext/psych/yaml/config.h10
-rw-r--r--ext/psych/yaml/dumper.c394
-rw-r--r--ext/psych/yaml/emitter.c2324
-rw-r--r--ext/psych/yaml/loader.c444
-rw-r--r--ext/psych/yaml/parser.c1370
-rw-r--r--ext/psych/yaml/reader.c469
-rw-r--r--ext/psych/yaml/scanner.c3578
-rw-r--r--ext/psych/yaml/writer.c141
-rw-r--r--ext/psych/yaml/yaml.h1971
-rw-r--r--ext/psych/yaml/yaml_private.h688
-rw-r--r--ext/pty/depend161
-rw-r--r--ext/pty/extconf.rb8
-rw-r--r--ext/pty/lib/expect.rb16
-rw-r--r--ext/pty/pty.c184
-rw-r--r--ext/racc/cparse/cparse.c40
-rw-r--r--ext/racc/cparse/depend148
-rw-r--r--ext/racc/cparse/extconf.rb3
-rw-r--r--ext/rbconfig/sizeof/depend296
-rw-r--r--ext/readline/depend157
-rw-r--r--ext/readline/depend-gem4
-rw-r--r--ext/readline/readline-ext.gemspec10
-rw-r--r--ext/readline/readline.c23
-rw-r--r--ext/ripper/depend170
-rw-r--r--ext/ripper/eventids2.c11
-rw-r--r--ext/ripper/extconf.rb3
-rw-r--r--ext/ripper/lib/ripper/lexer.rb148
-rw-r--r--ext/ripper/lib/ripper/sexp.rb37
-rw-r--r--ext/ripper/tools/dsl.rb3
-rw-r--r--ext/ripper/tools/preproc.rb2
-rw-r--r--ext/sdbm/_sdbm.c952
-rw-r--r--ext/sdbm/depend27
-rw-r--r--ext/sdbm/extconf.rb5
-rw-r--r--ext/sdbm/init.c1067
-rw-r--r--ext/sdbm/sdbm.gemspec21
-rw-r--r--ext/sdbm/sdbm.h86
-rw-r--r--ext/socket/addrinfo.h36
-rw-r--r--ext/socket/ancdata.c284
-rw-r--r--ext/socket/basicsocket.c151
-rw-r--r--ext/socket/constants.c6
-rw-r--r--ext/socket/depend2430
-rw-r--r--ext/socket/extconf.rb32
-rw-r--r--ext/socket/getaddrinfo.c898
-rw-r--r--ext/socket/getnameinfo.c226
-rw-r--r--ext/socket/ifaddr.c11
-rw-r--r--ext/socket/init.c437
-rw-r--r--ext/socket/ipsocket.c209
-rw-r--r--ext/socket/lib/socket.rb9
-rw-r--r--ext/socket/mkconstants.rb40
-rw-r--r--ext/socket/option.c102
-rw-r--r--ext/socket/raddrinfo.c517
-rw-r--r--ext/socket/rubysocket.h73
-rw-r--r--ext/socket/socket.c630
-rw-r--r--ext/socket/sockssocket.c6
-rw-r--r--ext/socket/tcpserver.c26
-rw-r--r--ext/socket/tcpsocket.c30
-rw-r--r--ext/socket/udpsocket.c55
-rw-r--r--ext/socket/unixserver.c31
-rw-r--r--ext/socket/unixsocket.c154
-rw-r--r--ext/stringio/depend157
-rw-r--r--ext/stringio/stringio.c485
-rw-r--r--ext/stringio/stringio.gemspec22
-rw-r--r--ext/strscan/depend158
-rw-r--r--ext/strscan/extconf.rb11
-rw-r--r--ext/strscan/strscan.c228
-rw-r--r--ext/strscan/strscan.gemspec41
-rw-r--r--ext/syslog/depend148
-rw-r--r--ext/syslog/syslog.c22
-rw-r--r--ext/syslog/syslog.gemspec23
-rw-r--r--ext/win32/lib/Win32API.rb47
-rw-r--r--ext/win32/lib/win32/importer.rb9
-rw-r--r--ext/win32/lib/win32/registry.rb23
-rw-r--r--ext/win32/lib/win32/resolv.rb13
-rw-r--r--ext/win32/lib/win32/resolv9x.rb253
-rw-r--r--ext/win32/lib/win32/sspi.rb627
-rw-r--r--ext/win32/resolv/resolv.c18
-rw-r--r--ext/win32ole/sample/xml.rb12
-rw-r--r--ext/win32ole/win32ole.c190
-rw-r--r--ext/win32ole/win32ole.gemspec22
-rw-r--r--ext/win32ole/win32ole.h4
-rw-r--r--ext/win32ole/win32ole_error.c3
-rw-r--r--ext/win32ole/win32ole_error.h4
-rw-r--r--ext/win32ole/win32ole_event.c21
-rw-r--r--ext/win32ole/win32ole_method.c7
-rw-r--r--ext/win32ole/win32ole_method.h2
-rw-r--r--ext/win32ole/win32ole_param.c3
-rw-r--r--ext/win32ole/win32ole_record.c5
-rw-r--r--ext/win32ole/win32ole_record.h2
-rw-r--r--ext/win32ole/win32ole_type.c7
-rw-r--r--ext/win32ole/win32ole_type.h2
-rw-r--r--ext/win32ole/win32ole_typelib.c21
-rw-r--r--ext/win32ole/win32ole_typelib.h2
-rw-r--r--ext/win32ole/win32ole_variable.c6
-rw-r--r--ext/win32ole/win32ole_variable.h2
-rw-r--r--ext/win32ole/win32ole_variant.c11
-rw-r--r--ext/win32ole/win32ole_variant.h2
-rw-r--r--ext/win32ole/win32ole_variant_m.c4
-rw-r--r--ext/win32ole/win32ole_variant_m.h2
-rw-r--r--ext/zlib/depend157
-rw-r--r--ext/zlib/extconf.rb15
-rw-r--r--ext/zlib/zlib.c379
-rw-r--r--ext/zlib/zlib.gemspec10
-rw-r--r--file.c3560
-rw-r--r--gc.c10216
-rw-r--r--gc.h42
-rw-r--r--gc.rb241
-rw-r--r--gem_prelude.rb28
-rw-r--r--gems/bundled_gems22
-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.c44
-rw-r--r--hash.c4338
-rw-r--r--hrtime.h59
-rw-r--r--id_table.c165
-rw-r--r--id_table.h11
-rw-r--r--include/ruby.h31
-rw-r--r--include/ruby/assert.h254
-rw-r--r--include/ruby/atomic.h890
-rw-r--r--include/ruby/backward.h92
-rw-r--r--include/ruby/backward/2/assume.h56
-rw-r--r--include/ruby/backward/2/attributes.h165
-rw-r--r--include/ruby/backward/2/bool.h36
-rw-r--r--include/ruby/backward/2/gcc_version_since.h37
-rw-r--r--include/ruby/backward/2/inttypes.h131
-rw-r--r--include/ruby/backward/2/limits.h99
-rw-r--r--include/ruby/backward/2/long_long.h73
-rw-r--r--include/ruby/backward/2/r_cast.h32
-rw-r--r--include/ruby/backward/2/rmodule.h36
-rw-r--r--include/ruby/backward/2/stdalign.h30
-rw-r--r--include/ruby/backward/2/stdarg.h69
-rw-r--r--include/ruby/backward/classext.h18
-rw-r--r--include/ruby/backward/cxxanyargs.hpp101
-rw-r--r--include/ruby/backward/rubyio.h6
-rw-r--r--include/ruby/backward/rubysig.h47
-rw-r--r--include/ruby/backward/st.h6
-rw-r--r--include/ruby/backward/util.h6
-rw-r--r--include/ruby/debug.h622
-rw-r--r--include/ruby/defines.h530
-rw-r--r--include/ruby/encoding.h446
-rw-r--r--include/ruby/fiber/scheduler.h374
-rw-r--r--include/ruby/intern.h1069
-rw-r--r--include/ruby/internal/abi.h58
-rw-r--r--include/ruby/internal/anyargs.h398
-rw-r--r--include/ruby/internal/arithmetic.h39
-rw-r--r--include/ruby/internal/arithmetic/char.h81
-rw-r--r--include/ruby/internal/arithmetic/double.h72
-rw-r--r--include/ruby/internal/arithmetic/fixnum.h60
-rw-r--r--include/ruby/internal/arithmetic/gid_t.h41
-rw-r--r--include/ruby/internal/arithmetic/int.h264
-rw-r--r--include/ruby/internal/arithmetic/intptr_t.h74
-rw-r--r--include/ruby/internal/arithmetic/long.h356
-rw-r--r--include/ruby/internal/arithmetic/long_long.h135
-rw-r--r--include/ruby/internal/arithmetic/mode_t.h41
-rw-r--r--include/ruby/internal/arithmetic/off_t.h62
-rw-r--r--include/ruby/internal/arithmetic/pid_t.h41
-rw-r--r--include/ruby/internal/arithmetic/short.h113
-rw-r--r--include/ruby/internal/arithmetic/size_t.h66
-rw-r--r--include/ruby/internal/arithmetic/st_data_t.h75
-rw-r--r--include/ruby/internal/arithmetic/uid_t.h41
-rw-r--r--include/ruby/internal/assume.h87
-rw-r--r--include/ruby/internal/attr/alloc_size.h32
-rw-r--r--include/ruby/internal/attr/artificial.h46
-rw-r--r--include/ruby/internal/attr/cold.h37
-rw-r--r--include/ruby/internal/attr/const.h46
-rw-r--r--include/ruby/internal/attr/constexpr.h84
-rw-r--r--include/ruby/internal/attr/deprecated.h75
-rw-r--r--include/ruby/internal/attr/diagnose_if.h42
-rw-r--r--include/ruby/internal/attr/enum_extensibility.h32
-rw-r--r--include/ruby/internal/attr/error.h32
-rw-r--r--include/ruby/internal/attr/flag_enum.h33
-rw-r--r--include/ruby/internal/attr/forceinline.h40
-rw-r--r--include/ruby/internal/attr/format.h38
-rw-r--r--include/ruby/internal/attr/maybe_unused.h38
-rw-r--r--include/ruby/internal/attr/noalias.h69
-rw-r--r--include/ruby/internal/attr/nodiscard.h45
-rw-r--r--include/ruby/internal/attr/noexcept.h91
-rw-r--r--include/ruby/internal/attr/noinline.h35
-rw-r--r--include/ruby/internal/attr/nonnull.h34
-rw-r--r--include/ruby/internal/attr/nonstring.h32
-rw-r--r--include/ruby/internal/attr/noreturn.h48
-rw-r--r--include/ruby/internal/attr/pure.h43
-rw-r--r--include/ruby/internal/attr/restrict.h44
-rw-r--r--include/ruby/internal/attr/returns_nonnull.h37
-rw-r--r--include/ruby/internal/attr/warning.h32
-rw-r--r--include/ruby/internal/attr/weakref.h32
-rw-r--r--include/ruby/internal/cast.h50
-rw-r--r--include/ruby/internal/compiler_is.h45
-rw-r--r--include/ruby/internal/compiler_is/apple.h40
-rw-r--r--include/ruby/internal/compiler_is/clang.h37
-rw-r--r--include/ruby/internal/compiler_is/gcc.h45
-rw-r--r--include/ruby/internal/compiler_is/intel.h40
-rw-r--r--include/ruby/internal/compiler_is/msvc.h56
-rw-r--r--include/ruby/internal/compiler_is/sunpro.h54
-rw-r--r--include/ruby/internal/compiler_since.h61
-rw-r--r--include/ruby/internal/config.h155
-rw-r--r--include/ruby/internal/constant_p.h38
-rw-r--r--include/ruby/internal/core.h35
-rw-r--r--include/ruby/internal/core/rarray.h585
-rw-r--r--include/ruby/internal/core/rbasic.h158
-rw-r--r--include/ruby/internal/core/rbignum.h80
-rw-r--r--include/ruby/internal/core/rclass.h93
-rw-r--r--include/ruby/internal/core/rdata.h386
-rw-r--r--include/ruby/internal/core/rfile.h51
-rw-r--r--include/ruby/internal/core/rhash.h144
-rw-r--r--include/ruby/internal/core/rmatch.h146
-rw-r--r--include/ruby/internal/core/robject.h176
-rw-r--r--include/ruby/internal/core/rregexp.h168
-rw-r--r--include/ruby/internal/core/rstring.h578
-rw-r--r--include/ruby/internal/core/rstruct.h121
-rw-r--r--include/ruby/internal/core/rtypeddata.h604
-rw-r--r--include/ruby/internal/ctype.h545
-rw-r--r--include/ruby/internal/dllexport.h112
-rw-r--r--include/ruby/internal/dosish.h89
-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.h582
-rw-r--r--include/ruby/internal/eval.h400
-rw-r--r--include/ruby/internal/event.h154
-rw-r--r--include/ruby/internal/fl_type.h948
-rw-r--r--include/ruby/internal/gc.h62
-rw-r--r--include/ruby/internal/glob.h113
-rw-r--r--include/ruby/internal/globals.h209
-rw-r--r--include/ruby/internal/has/attribute.h163
-rw-r--r--include/ruby/internal/has/builtin.h117
-rw-r--r--include/ruby/internal/has/c_attribute.h38
-rw-r--r--include/ruby/internal/has/cpp_attribute.h86
-rw-r--r--include/ruby/internal/has/declspec_attribute.h47
-rw-r--r--include/ruby/internal/has/extension.h33
-rw-r--r--include/ruby/internal/has/feature.h31
-rw-r--r--include/ruby/internal/has/warning.h31
-rw-r--r--include/ruby/internal/intern/array.h657
-rw-r--r--include/ruby/internal/intern/bignum.h846
-rw-r--r--include/ruby/internal/intern/class.h394
-rw-r--r--include/ruby/internal/intern/compar.h62
-rw-r--r--include/ruby/internal/intern/complex.h253
-rw-r--r--include/ruby/internal/intern/cont.h282
-rw-r--r--include/ruby/internal/intern/dir.h42
-rw-r--r--include/ruby/internal/intern/enum.h73
-rw-r--r--include/ruby/internal/intern/enumerator.h259
-rw-r--r--include/ruby/internal/intern/error.h287
-rw-r--r--include/ruby/internal/intern/eval.h222
-rw-r--r--include/ruby/internal/intern/file.h213
-rw-r--r--include/ruby/internal/intern/gc.h392
-rw-r--r--include/ruby/internal/intern/hash.h320
-rw-r--r--include/ruby/internal/intern/io.h661
-rw-r--r--include/ruby/internal/intern/load.h218
-rw-r--r--include/ruby/internal/intern/marshal.h112
-rw-r--r--include/ruby/internal/intern/numeric.h208
-rw-r--r--include/ruby/internal/intern/object.h501
-rw-r--r--include/ruby/internal/intern/parse.h194
-rw-r--r--include/ruby/internal/intern/proc.h353
-rw-r--r--include/ruby/internal/intern/process.h273
-rw-r--r--include/ruby/internal/intern/random.h116
-rw-r--r--include/ruby/internal/intern/range.h89
-rw-r--r--include/ruby/internal/intern/rational.h172
-rw-r--r--include/ruby/internal/intern/re.h249
-rw-r--r--include/ruby/internal/intern/ruby.h77
-rw-r--r--include/ruby/internal/intern/select.h86
-rw-r--r--include/ruby/internal/intern/select/largesize.h214
-rw-r--r--include/ruby/internal/intern/select/posix.h144
-rw-r--r--include/ruby/internal/intern/select/win32.h259
-rw-r--r--include/ruby/internal/intern/signal.h152
-rw-r--r--include/ruby/internal/intern/sprintf.h159
-rw-r--r--include/ruby/internal/intern/string.h1757
-rw-r--r--include/ruby/internal/intern/struct.h203
-rw-r--r--include/ruby/internal/intern/thread.h492
-rw-r--r--include/ruby/internal/intern/time.h161
-rw-r--r--include/ruby/internal/intern/variable.h628
-rw-r--r--include/ruby/internal/intern/vm.h431
-rw-r--r--include/ruby/internal/interpreter.h304
-rw-r--r--include/ruby/internal/iterator.h513
-rw-r--r--include/ruby/internal/memory.h666
-rw-r--r--include/ruby/internal/method.h205
-rw-r--r--include/ruby/internal/module.h177
-rw-r--r--include/ruby/internal/newobj.h195
-rw-r--r--include/ruby/internal/rgengc.h443
-rw-r--r--include/ruby/internal/scan_args.h534
-rw-r--r--include/ruby/internal/special_consts.h362
-rw-r--r--include/ruby/internal/static_assert.h77
-rw-r--r--include/ruby/internal/stdalign.h135
-rw-r--r--include/ruby/internal/stdbool.h51
-rw-r--r--include/ruby/internal/symbol.h332
-rw-r--r--include/ruby/internal/value.h133
-rw-r--r--include/ruby/internal/value_type.h449
-rw-r--r--include/ruby/internal/variable.h337
-rw-r--r--include/ruby/internal/warning_push.h124
-rw-r--r--include/ruby/internal/xmalloc.h392
-rw-r--r--include/ruby/io.h987
-rw-r--r--include/ruby/io/buffer.h92
-rw-r--r--include/ruby/memory_view.h325
-rw-r--r--include/ruby/missing.h240
-rw-r--r--include/ruby/onigmo.h15
-rw-r--r--include/ruby/ractor.h264
-rw-r--r--include/ruby/random.h359
-rw-r--r--include/ruby/re.h198
-rw-r--r--include/ruby/regex.h21
-rw-r--r--include/ruby/ruby.h3058
-rw-r--r--include/ruby/st.h4
-rw-r--r--include/ruby/subst.h9
-rw-r--r--include/ruby/thread.h246
-rw-r--r--include/ruby/thread_native.h187
-rw-r--r--include/ruby/util.h259
-rw-r--r--include/ruby/version.h159
-rw-r--r--include/ruby/vm.h61
-rw-r--r--include/ruby/win32.h157
-rw-r--r--inits.c25
-rw-r--r--insns.def291
-rw-r--r--internal.h50
-rw-r--r--internal/array.h94
-rw-r--r--internal/basic_operators.h64
-rw-r--r--internal/bignum.h18
-rw-r--r--internal/bits.h21
-rw-r--r--internal/class.h117
-rw-r--r--internal/cmdlineopt.h61
-rw-r--r--internal/compar.h45
-rw-r--r--internal/compile.h13
-rw-r--r--internal/compilers.h181
-rw-r--r--internal/complex.h12
-rw-r--r--internal/cont.h21
-rw-r--r--internal/dir.h7
-rw-r--r--internal/enc.h7
-rw-r--r--internal/encoding.h14
-rw-r--r--internal/enum.h7
-rw-r--r--internal/enumerator.h7
-rw-r--r--internal/error.h111
-rw-r--r--internal/eval.h8
-rw-r--r--internal/file.h7
-rw-r--r--internal/fixnum.h15
-rw-r--r--internal/gc.h75
-rw-r--r--internal/hash.h40
-rw-r--r--internal/imemo.h22
-rw-r--r--internal/inits.h7
-rw-r--r--internal/io.h12
-rw-r--r--internal/load.h7
-rw-r--r--internal/loadpath.h7
-rw-r--r--internal/math.h7
-rw-r--r--internal/missing.h9
-rw-r--r--internal/mjit.h29
-rw-r--r--internal/numeric.h46
-rw-r--r--internal/object.h15
-rw-r--r--internal/parse.h10
-rw-r--r--internal/proc.h9
-rw-r--r--internal/process.h33
-rw-r--r--internal/ractor.h6
-rw-r--r--internal/random.h7
-rw-r--r--internal/range.h11
-rw-r--r--internal/rational.h16
-rw-r--r--internal/re.h11
-rw-r--r--internal/sanitizers.h13
-rw-r--r--internal/serial.h9
-rw-r--r--internal/signal.h7
-rw-r--r--internal/static_assert.h26
-rw-r--r--internal/stdbool.h34
-rw-r--r--internal/string.h28
-rw-r--r--internal/struct.h16
-rw-r--r--internal/symbol.h9
-rw-r--r--internal/thread.h12
-rw-r--r--internal/time.h14
-rw-r--r--internal/transcode.h9
-rw-r--r--internal/util.h12
-rw-r--r--internal/variable.h47
-rw-r--r--internal/vm.h54
-rw-r--r--internal/warnings.h49
-rw-r--r--io.c10508
-rw-r--r--io.rb4
-rw-r--r--io_buffer.c3515
-rw-r--r--iseq.c2444
-rw-r--r--iseq.h131
-rw-r--r--kernel.rb178
-rw-r--r--lex.c.blt2
-rw-r--r--lib/.document25
-rw-r--r--lib/English.gemspec9
-rw-r--r--lib/abbrev.gemspec22
-rw-r--r--lib/base64.gemspec20
-rw-r--r--lib/base64.rb6
-rw-r--r--lib/benchmark.rb29
-rw-r--r--lib/benchmark/benchmark.gemspec6
-rw-r--r--lib/benchmark/version.rb3
-rw-r--r--lib/bundler.rb210
-rw-r--r--lib/bundler/.document1
-rw-r--r--lib/bundler/build_metadata.rb10
-rw-r--r--lib/bundler/bundler.gemspec23
-rw-r--r--lib/bundler/cli.rb236
-rw-r--r--lib/bundler/cli/add.rb4
-rw-r--r--lib/bundler/cli/binstubs.rb16
-rw-r--r--lib/bundler/cli/cache.rb11
-rw-r--r--lib/bundler/cli/check.rb8
-rw-r--r--lib/bundler/cli/clean.rb2
-rw-r--r--lib/bundler/cli/common.rb35
-rw-r--r--lib/bundler/cli/config.rb11
-rw-r--r--lib/bundler/cli/console.rb6
-rw-r--r--lib/bundler/cli/doctor.rb29
-rw-r--r--lib/bundler/cli/exec.rb15
-rw-r--r--lib/bundler/cli/fund.rb36
-rw-r--r--lib/bundler/cli/gem.rb303
-rw-r--r--lib/bundler/cli/info.rb46
-rw-r--r--lib/bundler/cli/init.rb10
-rw-r--r--lib/bundler/cli/inject.rb2
-rw-r--r--lib/bundler/cli/install.rb86
-rw-r--r--lib/bundler/cli/issue.rb9
-rw-r--r--lib/bundler/cli/list.rb30
-rw-r--r--lib/bundler/cli/lock.rb15
-rw-r--r--lib/bundler/cli/open.rb13
-rw-r--r--lib/bundler/cli/outdated.rb187
-rw-r--r--lib/bundler/cli/package.rb48
-rw-r--r--lib/bundler/cli/platform.rb14
-rw-r--r--lib/bundler/cli/plugin.rb10
-rw-r--r--lib/bundler/cli/pristine.rb5
-rw-r--r--lib/bundler/cli/remove.rb3
-rw-r--r--lib/bundler/cli/show.rb4
-rw-r--r--lib/bundler/cli/update.rb29
-rw-r--r--lib/bundler/cli/viz.rb2
-rw-r--r--lib/bundler/compact_index_client.rb12
-rw-r--r--lib/bundler/compact_index_client/cache.rb31
-rw-r--r--lib/bundler/compact_index_client/gem_parser.rb28
-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.rb889
-rw-r--r--lib/bundler/dep_proxy.rb48
-rw-r--r--lib/bundler/dependency.rb100
-rw-r--r--lib/bundler/digest.rb71
-rw-r--r--lib/bundler/dsl.rb164
-rw-r--r--lib/bundler/endpoint_specification.rb30
-rw-r--r--lib/bundler/env.rb8
-rw-r--r--lib/bundler/environment_preserver.rb36
-rw-r--r--lib/bundler/errors.rb45
-rw-r--r--lib/bundler/feature_flag.rb10
-rw-r--r--lib/bundler/fetcher.rb69
-rw-r--r--lib/bundler/fetcher/base.rb16
-rw-r--r--lib/bundler/fetcher/compact_index.rb51
-rw-r--r--lib/bundler/fetcher/dependency.rb8
-rw-r--r--lib/bundler/fetcher/downloader.rb24
-rw-r--r--lib/bundler/fetcher/index.rb35
-rw-r--r--lib/bundler/force_platform.rb18
-rw-r--r--lib/bundler/friendly_errors.rb94
-rw-r--r--lib/bundler/gem_helper.rb91
-rw-r--r--lib/bundler/gem_helpers.rb66
-rw-r--r--lib/bundler/gem_remote_fetcher.rb43
-rw-r--r--lib/bundler/gem_version_promoter.rb153
-rw-r--r--lib/bundler/gemdeps.rb29
-rw-r--r--lib/bundler/graph.rb8
-rw-r--r--lib/bundler/index.rb70
-rw-r--r--lib/bundler/injector.rb50
-rw-r--r--lib/bundler/inline.rb33
-rw-r--r--lib/bundler/installer.rb132
-rw-r--r--lib/bundler/installer/gem_installer.rb43
-rw-r--r--lib/bundler/installer/parallel_installer.rb79
-rw-r--r--lib/bundler/installer/standalone.rb73
-rw-r--r--lib/bundler/lazy_specification.rb139
-rw-r--r--lib/bundler/lockfile_generator.rb8
-rw-r--r--lib/bundler/lockfile_parser.rb94
-rw-r--r--lib/bundler/man/.document1
-rw-r--r--lib/bundler/man/bundle-add.182
-rw-r--r--lib/bundler/man/bundle-add.1.ronn58
-rw-r--r--lib/bundler/man/bundle-binstubs.142
-rw-r--r--lib/bundler/man/bundle-binstubs.1.ronn41
-rw-r--r--lib/bundler/man/bundle-cache.161
-rw-r--r--lib/bundler/man/bundle-cache.1.ronn79
-rw-r--r--lib/bundler/man/bundle-check.131
-rw-r--r--lib/bundler/man/bundle-check.1.ronn (renamed from man/bundle-check.ronn)0
-rw-r--r--lib/bundler/man/bundle-clean.124
-rw-r--r--lib/bundler/man/bundle-clean.1.ronn18
-rw-r--r--lib/bundler/man/bundle-config.1512
-rw-r--r--lib/bundler/man/bundle-config.1.ronn405
-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-doctor.1.ronn (renamed from man/bundle-doctor.ronn)0
-rw-r--r--lib/bundler/man/bundle-exec.1165
-rw-r--r--lib/bundler/man/bundle-exec.1.ronn152
-rw-r--r--lib/bundler/man/bundle-gem.1105
-rw-r--r--lib/bundler/man/bundle-gem.1.ronn117
-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.ronn17
-rw-r--r--lib/bundler/man/bundle-init.129
-rw-r--r--lib/bundler/man/bundle-init.1.ronn31
-rw-r--r--lib/bundler/man/bundle-inject.136
-rw-r--r--lib/bundler/man/bundle-inject.1.ronn24
-rw-r--r--lib/bundler/man/bundle-install.1313
-rw-r--r--lib/bundler/man/bundle-install.1.ronn382
-rw-r--r--lib/bundler/man/bundle-list.150
-rw-r--r--lib/bundler/man/bundle-list.1.ronn33
-rw-r--r--lib/bundler/man/bundle-lock.184
-rw-r--r--lib/bundler/man/bundle-lock.1.ronn (renamed from man/bundle-lock.ronn)0
-rw-r--r--lib/bundler/man/bundle-open.152
-rw-r--r--lib/bundler/man/bundle-open.1.ronn27
-rw-r--r--lib/bundler/man/bundle-outdated.1152
-rw-r--r--lib/bundler/man/bundle-outdated.1.ronn105
-rw-r--r--lib/bundler/man/bundle-platform.171
-rw-r--r--lib/bundler/man/bundle-platform.1.ronn49
-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-pristine.1.ronn (renamed from man/bundle-pristine.ronn)0
-rw-r--r--lib/bundler/man/bundle-remove.131
-rw-r--r--lib/bundler/man/bundle-remove.1.ronn (renamed from man/bundle-remove.ronn)0
-rw-r--r--lib/bundler/man/bundle-show.123
-rw-r--r--lib/bundler/man/bundle-show.1.ronn (renamed from man/bundle-show.ronn)0
-rw-r--r--lib/bundler/man/bundle-update.1394
-rw-r--r--lib/bundler/man/bundle-update.1.ronn351
-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.ronn32
-rw-r--r--lib/bundler/man/bundle.1141
-rw-r--r--lib/bundler/man/bundle.1.ronn116
-rw-r--r--lib/bundler/man/gemfile.5736
-rw-r--r--lib/bundler/man/gemfile.5.ronn543
-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.rb16
-rw-r--r--lib/bundler/plugin.rb71
-rw-r--r--lib/bundler/plugin/api/source.rb34
-rw-r--r--lib/bundler/plugin/dsl.rb2
-rw-r--r--lib/bundler/plugin/index.rb24
-rw-r--r--lib/bundler/plugin/installer.rb29
-rw-r--r--lib/bundler/plugin/installer/git.rb4
-rw-r--r--lib/bundler/plugin/installer/rubygems.rb10
-rw-r--r--lib/bundler/plugin/source_list.rb6
-rw-r--r--lib/bundler/process_lock.rb2
-rw-r--r--lib/bundler/psyched_yaml.rb37
-rw-r--r--lib/bundler/remote_specification.rb19
-rw-r--r--lib/bundler/resolver.rb694
-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.rb123
-rw-r--r--lib/bundler/retry.rb4
-rw-r--r--lib/bundler/ruby_dsl.rb8
-rw-r--r--lib/bundler/ruby_version.rb31
-rw-r--r--lib/bundler/rubygems_ext.rb265
-rw-r--r--lib/bundler/rubygems_gem_installer.rb105
-rw-r--r--lib/bundler/rubygems_integration.rb250
-rw-r--r--lib/bundler/runtime.rb56
-rw-r--r--lib/bundler/safe_marshal.rb31
-rw-r--r--lib/bundler/self_manager.rb168
-rw-r--r--lib/bundler/settings.rb221
-rw-r--r--lib/bundler/setup.rb7
-rw-r--r--lib/bundler/shared_helpers.rb55
-rw-r--r--lib/bundler/similarity_detector.rb2
-rw-r--r--lib/bundler/source.rb32
-rw-r--r--lib/bundler/source/git.rb141
-rw-r--r--lib/bundler/source/git/git_proxy.rb400
-rw-r--r--lib/bundler/source/metadata.rb11
-rw-r--r--lib/bundler/source/path.rb26
-rw-r--r--lib/bundler/source/path/installer.rb43
-rw-r--r--lib/bundler/source/rubygems.rb387
-rw-r--r--lib/bundler/source/rubygems/remote.rb2
-rw-r--r--lib/bundler/source/rubygems_aggregate.rb68
-rw-r--r--lib/bundler/source_list.rb172
-rw-r--r--lib/bundler/source_map.rb71
-rw-r--r--lib/bundler/spec_set.rb135
-rw-r--r--lib/bundler/stub_specification.rb40
-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/CODE_OF_CONDUCT.md.tt104
-rw-r--r--lib/bundler/templates/newgem/Cargo.toml.tt7
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt16
-rw-r--r--lib/bundler/templates/newgem/README.md.tt29
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt48
-rw-r--r--lib/bundler/templates/newgem/bin/console.tt5
-rw-r--r--lib/bundler/templates/newgem/circleci/config.yml.tt25
-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.tt3
-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.tt37
-rw-r--r--lib/bundler/templates/newgem/gitignore.tt3
-rw-r--r--lib/bundler/templates/newgem/gitlab-ci.yml.tt18
-rw-r--r--lib/bundler/templates/newgem/lib/newgem.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/lib/newgem/version.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt53
-rw-r--r--lib/bundler/templates/newgem/rubocop.yml.tt13
-rw-r--r--lib/bundler/templates/newgem/sig/newgem.rbs.tt8
-rw-r--r--lib/bundler/templates/newgem/spec/newgem_spec.rb.tt2
-rw-r--r--lib/bundler/templates/newgem/spec/spec_helper.rb.tt3
-rw-r--r--lib/bundler/templates/newgem/standard.yml.tt3
-rw-r--r--lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt13
-rw-r--r--lib/bundler/templates/newgem/test/newgem_test.rb.tt11
-rw-r--r--lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt15
-rw-r--r--lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/test/test_helper.rb.tt4
-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.rb51
-rw-r--r--lib/bundler/ui/silent.rb26
-rw-r--r--lib/bundler/uri_credentials_filter.rb4
-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/fileutils/lib/fileutils/version.rb5
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo.rb12
-rw-r--r--lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb26
-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.rb223
-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.rb837
-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.rb271
-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.rb18
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions.rb10
-rw-r--r--lib/bundler/vendor/thor/lib/thor/actions/create_link.rb3
-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/base.rb9
-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/core_ext/io_binary_read.rb12
-rw-r--r--lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb129
-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/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.rb41
-rw-r--r--lib/bundler/vendored_pub_grub.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.rb37
-rw-r--r--lib/bundler/yaml_serializer.rb2
-rw-r--r--lib/cgi.rb3
-rw-r--r--lib/cgi/cgi.gemspec39
-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/cgi/version.rb3
-rw-r--r--lib/csv.rb2544
-rw-r--r--lib/csv/csv.gemspec52
-rw-r--r--lib/csv/fields_converter.rb15
-rw-r--r--lib/csv/input_record_separator.rb18
-rw-r--r--lib/csv/parser.rb359
-rw-r--r--lib/csv/row.rb633
-rw-r--r--lib/csv/table.rb881
-rw-r--r--lib/csv/version.rb2
-rw-r--r--lib/csv/writer.rb62
-rw-r--r--lib/debug.rb1106
-rw-r--r--lib/delegate.rb25
-rw-r--r--lib/delegate/delegate.gemspec22
-rw-r--r--lib/delegate/version.rb3
-rw-r--r--lib/did_you_mean.rb63
-rw-r--r--lib/did_you_mean/core_ext/name_error.rb54
-rw-r--r--lib/did_you_mean/experimental/initializer_name_correction.rb20
-rw-r--r--lib/did_you_mean/experimental/ivar_name_correction.rb76
-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.rb17
-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.rb39
-rw-r--r--lib/did_you_mean/tree_spell_checker.rb150
-rw-r--r--lib/did_you_mean/verbose.rb6
-rw-r--r--lib/did_you_mean/version.rb2
-rw-r--r--lib/drb/drb.gemspec43
-rw-r--r--lib/drb/drb.rb20
-rw-r--r--lib/drb/extserv.rb4
-rw-r--r--lib/drb/extservm.rb6
-rw-r--r--lib/drb/observer.rb2
-rw-r--r--lib/drb/ssl.rb2
-rw-r--r--lib/drb/version.rb3
-rw-r--r--lib/erb.gemspec38
-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.gemspec4
-rw-r--r--lib/fileutils.rb1755
-rw-r--r--lib/find.gemspec24
-rw-r--r--lib/find.rb4
-rw-r--r--lib/forwardable.rb13
-rw-r--r--lib/forwardable/forwardable.gemspec23
-rw-r--r--lib/forwardable/impl.rb3
-rw-r--r--lib/forwardable/version.rb5
-rw-r--r--lib/getoptlong.rb576
-rw-r--r--lib/getoptlong/getoptlong.gemspec21
-rw-r--r--lib/getoptlong/version.rb3
-rw-r--r--lib/ipaddr.gemspec28
-rw-r--r--lib/ipaddr.rb143
-rw-r--r--lib/irb.rb321
-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.rb11
-rw-r--r--lib/irb/cmd/help.rb23
-rw-r--r--lib/irb/cmd/info.rb21
-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.rb48
-rw-r--r--lib/irb/cmd/next.rb17
-rw-r--r--lib/irb/cmd/nop.rb42
-rw-r--r--lib/irb/cmd/pushws.rb16
-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.rb121
-rw-r--r--lib/irb/color_printer.rb50
-rw-r--r--lib/irb/completion.rb253
-rw-r--r--lib/irb/context.rb141
-rw-r--r--lib/irb/easter-egg.rb3
-rw-r--r--lib/irb/ext/change-ws.rb1
-rw-r--r--lib/irb/ext/history.rb2
-rw-r--r--lib/irb/ext/loader.rb66
-rw-r--r--lib/irb/ext/multi-irb.rb1
-rw-r--r--lib/irb/ext/save-history.rb29
-rw-r--r--lib/irb/ext/tracer.rb1
-rw-r--r--lib/irb/ext/use-loader.rb4
-rw-r--r--lib/irb/ext/workspaces.rb1
-rw-r--r--lib/irb/extend-command.rb207
-rw-r--r--lib/irb/help.rb1
-rw-r--r--lib/irb/init.rb153
-rw-r--r--lib/irb/input-method.rb212
-rw-r--r--lib/irb/inspector.rb28
-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.rb645
-rw-r--r--lib/irb/ruby_logo.aa1
-rw-r--r--lib/irb/version.rb4
-rw-r--r--lib/irb/workspace.rb27
-rw-r--r--lib/irb/xmp.rb2
-rw-r--r--lib/logger.rb776
-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.gemspec7
-rw-r--r--lib/logger/version.rb2
-rw-r--r--lib/matrix.rb2407
-rw-r--r--lib/matrix/eigenvalue_decomposition.rb882
-rw-r--r--lib/matrix/lup_decomposition.rb219
-rw-r--r--lib/matrix/matrix.gemspec28
-rw-r--r--lib/matrix/version.rb5
-rw-r--r--lib/mkmf.rb249
-rw-r--r--lib/mutex_m.gemspec4
-rw-r--r--lib/mutex_m.rb16
-rw-r--r--lib/net/ftp.rb1533
-rw-r--r--lib/net/ftp/net-ftp.gemspec29
-rw-r--r--lib/net/ftp/version.rb5
-rw-r--r--lib/net/http.rb2133
-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.rb759
-rw-r--r--lib/net/http/net-http.gemspec28
-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.rb372
-rw-r--r--lib/net/http/responses.rb1313
-rw-r--r--lib/net/http/status.rb13
-rw-r--r--lib/net/http/version.rb5
-rw-r--r--lib/net/https.rb2
-rw-r--r--lib/net/imap.rb3728
-rw-r--r--lib/net/imap/net-imap.gemspec29
-rw-r--r--lib/net/imap/version.rb5
-rw-r--r--lib/net/net-protocol.gemspec33
-rw-r--r--lib/net/pop.rb1023
-rw-r--r--lib/net/pop/net-pop.gemspec27
-rw-r--r--lib/net/pop/version.rb6
-rw-r--r--lib/net/protocol.rb86
-rw-r--r--lib/net/protocol/net-protocol.gemspec29
-rw-r--r--lib/net/protocol/version.rb5
-rw-r--r--lib/net/smtp.rb1072
-rw-r--r--lib/net/smtp/net-smtp.gemspec27
-rw-r--r--lib/net/smtp/version.rb6
-rw-r--r--lib/observer.rb27
-rw-r--r--lib/observer/observer.gemspec19
-rw-r--r--lib/observer/version.rb3
-rw-r--r--lib/open-uri.gemspec25
-rw-r--r--lib/open-uri.rb71
-rw-r--r--lib/open3.rb12
-rw-r--r--lib/open3/open3.gemspec20
-rw-r--r--lib/open3/version.rb2
-rw-r--r--lib/optparse.rb285
-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.gemspec30
-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.rb273
-rw-r--r--lib/ostruct/ostruct.gemspec21
-rw-r--r--lib/ostruct/version.rb5
-rw-r--r--lib/pp.gemspec27
-rw-r--r--lib/pp.rb130
-rw-r--r--lib/prettyprint.gemspec22
-rw-r--r--lib/prettyprint.rb6
-rw-r--r--lib/prime.gemspec27
-rw-r--r--lib/prime.rb463
-rw-r--r--lib/pstore.rb578
-rw-r--r--lib/pstore/pstore.gemspec19
-rw-r--r--lib/pstore/version.rb3
-rw-r--r--lib/racc/compat.rb7
-rw-r--r--lib/racc/debugflags.rb7
-rw-r--r--lib/racc/exception.rb2
-rw-r--r--lib/racc/grammar.rb42
-rw-r--r--lib/racc/grammarfileparser.rb15
-rw-r--r--lib/racc/info.rb4
-rw-r--r--lib/racc/iset.rb7
-rw-r--r--lib/racc/logfilegenerator.rb7
-rw-r--r--lib/racc/parser-text.rb28
-rw-r--r--lib/racc/parser.rb28
-rw-r--r--lib/racc/parserfilegenerator.rb49
-rw-r--r--lib/racc/pre-setup13
-rw-r--r--lib/racc/racc.gemspec99
-rw-r--r--lib/racc/rdoc/grammar.en.rdoc219
-rw-r--r--lib/racc/sourcetext.rb7
-rw-r--r--lib/racc/state.rb2
-rw-r--r--lib/racc/statetransitiontable.rb23
-rw-r--r--lib/random/formatter.rb245
-rw-r--r--lib/rdoc.rb113
-rw-r--r--lib/rdoc/any_method.rb60
-rw-r--r--lib/rdoc/code_objects.rb3
-rw-r--r--lib/rdoc/context.rb16
-rw-r--r--lib/rdoc/context/section.rb2
-rw-r--r--lib/rdoc/cross_reference.rb66
-rw-r--r--lib/rdoc/erb_partial.rb2
-rw-r--r--lib/rdoc/erbio.rb4
-rw-r--r--lib/rdoc/generator.rb10
-rw-r--r--lib/rdoc/generator/darkfish.rb10
-rw-r--r--lib/rdoc/generator/markup.rb2
-rw-r--r--lib/rdoc/generator/pot.rb6
-rw-r--r--lib/rdoc/generator/template/darkfish/_head.rhtml27
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml4
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml32
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml14
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml4
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml14
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml12
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml10
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml32
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml10
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml8
-rw-r--r--lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml33
-rw-r--r--lib/rdoc/generator/template/darkfish/class.rhtml114
-rw-r--r--lib/rdoc/generator/template/darkfish/css/rdoc.css47
-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.rhtml9
-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/servlet_root.rhtml31
-rw-r--r--lib/rdoc/generator/template/darkfish/table_of_contents.rhtml36
-rw-r--r--lib/rdoc/i18n.rb4
-rw-r--r--lib/rdoc/known_classes.rb9
-rw-r--r--lib/rdoc/markdown.rb786
-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/formatter.rb2
-rw-r--r--lib/rdoc/markup/parser.rb18
-rw-r--r--lib/rdoc/markup/pre_process.rb4
-rw-r--r--lib/rdoc/markup/table.rb47
-rw-r--r--lib/rdoc/markup/to_html.rb78
-rw-r--r--lib/rdoc/markup/to_html_crossref.rb18
-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.rb118
-rw-r--r--lib/rdoc/parser.rb35
-rw-r--r--lib/rdoc/parser/c.rb300
-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.rb91
-rw-r--r--lib/rdoc/ri.rb9
-rw-r--r--lib/rdoc/ri/driver.rb114
-rw-r--r--lib/rdoc/ri/paths.rb20
-rw-r--r--lib/rdoc/ri/task.rb2
-rw-r--r--lib/rdoc/rubygems_hook.rb10
-rw-r--r--lib/rdoc/servlet.rb9
-rw-r--r--lib/rdoc/single_class.rb5
-rw-r--r--lib/rdoc/stats.rb7
-rw-r--r--lib/rdoc/store.rb49
-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.gemspec28
-rw-r--r--lib/readline.rb1
-rw-r--r--lib/reline.rb279
-rw-r--r--lib/reline/ansi.rb281
-rw-r--r--lib/reline/config.rb149
-rw-r--r--lib/reline/general_io.rb40
-rw-r--r--lib/reline/history.rb42
-rw-r--r--lib/reline/key_actor/base.rb12
-rw-r--r--lib/reline/key_actor/emacs.rb16
-rw-r--r--lib/reline/key_actor/vi_command.rb8
-rw-r--r--lib/reline/key_actor/vi_insert.rb4
-rw-r--r--lib/reline/key_stroke.rb80
-rw-r--r--lib/reline/kill_ring.rb12
-rw-r--r--lib/reline/line_editor.rb1820
-rw-r--r--lib/reline/reline.gemspec17
-rw-r--r--lib/reline/terminfo.rb174
-rw-r--r--lib/reline/unicode.rb176
-rw-r--r--lib/reline/unicode/east_asian_width.rb2279
-rw-r--r--lib/reline/version.rb2
-rw-r--r--lib/reline/windows.rb428
-rw-r--r--lib/resolv-replace.gemspec22
-rw-r--r--lib/resolv.gemspec22
-rw-r--r--lib/resolv.rb38
-rw-r--r--lib/rinda/rinda.gemspec28
-rw-r--r--lib/rss.rb94
-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.rb465
-rw-r--r--lib/rubygems/available_set.rb17
-rw-r--r--lib/rubygems/basic_specification.rb39
-rw-r--r--lib/rubygems/bundler_version_finder.rb85
-rw-r--r--lib/rubygems/command.rb112
-rw-r--r--lib/rubygems/command_manager.rb58
-rw-r--r--lib/rubygems/commands/build_command.rb78
-rw-r--r--lib/rubygems/commands/cert_command.rb154
-rw-r--r--lib/rubygems/commands/check_command.rb43
-rw-r--r--lib/rubygems/commands/cleanup_command.rb57
-rw-r--r--lib/rubygems/commands/contents_command.rb35
-rw-r--r--lib/rubygems/commands/dependency_command.rb91
-rw-r--r--lib/rubygems/commands/environment_command.rb22
-rw-r--r--lib/rubygems/commands/exec_command.rb249
-rw-r--r--lib/rubygems/commands/fetch_command.rb50
-rw-r--r--lib/rubygems/commands/generate_index_command.rb37
-rw-r--r--lib/rubygems/commands/help_command.rb19
-rw-r--r--lib/rubygems/commands/info_command.rb8
-rw-r--r--lib/rubygems/commands/install_command.rb61
-rw-r--r--lib/rubygems/commands/list_command.rb11
-rw-r--r--lib/rubygems/commands/lock_command.rb13
-rw-r--r--lib/rubygems/commands/mirror_command.rb9
-rw-r--r--lib/rubygems/commands/open_command.rb25
-rw-r--r--lib/rubygems/commands/outdated_command.rb13
-rw-r--r--lib/rubygems/commands/owner_command.rb49
-rw-r--r--lib/rubygems/commands/pristine_command.rb118
-rw-r--r--lib/rubygems/commands/push_command.rb63
-rw-r--r--lib/rubygems/commands/query_command.rb38
-rw-r--r--lib/rubygems/commands/rdoc_command.rb54
-rw-r--r--lib/rubygems/commands/search_command.rb11
-rw-r--r--lib/rubygems/commands/server_command.rb90
-rw-r--r--lib/rubygems/commands/setup_command.rb474
-rw-r--r--lib/rubygems/commands/signin_command.rb21
-rw-r--r--lib/rubygems/commands/signout_command.rb17
-rw-r--r--lib/rubygems/commands/sources_command.rb53
-rw-r--r--lib/rubygems/commands/specification_command.rb47
-rw-r--r--lib/rubygems/commands/stale_command.rb9
-rw-r--r--lib/rubygems/commands/uninstall_command.rb90
-rw-r--r--lib/rubygems/commands/unpack_command.rb31
-rw-r--r--lib/rubygems/commands/update_command.rb172
-rw-r--r--lib/rubygems/commands/which_command.rb17
-rw-r--r--lib/rubygems/commands/yank_command.rb36
-rw-r--r--lib/rubygems/compatibility.rb6
-rw-r--r--lib/rubygems/config_file.rb102
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb7
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb225
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb67
-rw-r--r--lib/rubygems/core_ext/tcpsocket_init.rb54
-rw-r--r--lib/rubygems/defaults.rb159
-rw-r--r--lib/rubygems/dependency.rb47
-rw-r--r--lib/rubygems/dependency_installer.rb159
-rw-r--r--lib/rubygems/dependency_list.rb29
-rw-r--r--lib/rubygems/deprecate.rb99
-rw-r--r--lib/rubygems/doctor.rb47
-rw-r--r--lib/rubygems/errors.rb28
-rw-r--r--lib/rubygems/exceptions.rb74
-rw-r--r--lib/rubygems/ext.rb14
-rw-r--r--lib/rubygems/ext/build_error.rb3
-rw-r--r--lib/rubygems/ext/builder.rb118
-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.rb15
-rw-r--r--lib/rubygems/ext/configure_builder.rb14
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb110
-rw-r--r--lib/rubygems/ext/rake_builder.rb21
-rw-r--r--lib/rubygems/gem_runner.rb32
-rw-r--r--lib/rubygems/gemcutter_utilities.rb242
-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.rb82
-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.rb138
-rw-r--r--lib/rubygems/installer.rb343
-rw-r--r--lib/rubygems/installer_test_case.rb233
-rw-r--r--lib/rubygems/installer_uninstaller_utils.rb17
-rw-r--r--lib/rubygems/local_remote_options.rb47
-rw-r--r--lib/rubygems/mock_gem_ui.rb11
-rw-r--r--lib/rubygems/name_tuple.rb24
-rw-r--r--lib/rubygems/openssl.rb7
-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.rb230
-rw-r--r--lib/rubygems/package/digest_io.rb3
-rw-r--r--lib/rubygems/package/file_source.rb7
-rw-r--r--lib/rubygems/package/io_source.rb7
-rw-r--r--lib/rubygems/package/old.rb21
-rw-r--r--lib/rubygems/package/source.rb1
-rw-r--r--lib/rubygems/package/tar_header.rb133
-rw-r--r--lib/rubygems/package/tar_reader.rb34
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb101
-rw-r--r--lib/rubygems/package/tar_test_case.rb141
-rw-r--r--lib/rubygems/package/tar_writer.rb27
-rw-r--r--lib/rubygems/package_task.rb17
-rw-r--r--lib/rubygems/path_support.rb12
-rw-r--r--lib/rubygems/platform.rb188
-rw-r--r--lib/rubygems/psych_additions.rb10
-rw-r--r--lib/rubygems/psych_tree.rb5
-rw-r--r--lib/rubygems/query_utils.rb123
-rw-r--r--lib/rubygems/rdoc.rb15
-rw-r--r--lib/rubygems/remote_fetcher.rb109
-rw-r--r--lib/rubygems/request.rb58
-rw-r--r--lib/rubygems/request/connection_pools.rb16
-rw-r--r--lib/rubygems/request/http_pool.rb7
-rw-r--r--lib/rubygems/request/https_pool.rb3
-rw-r--r--lib/rubygems/request_set.rb72
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb258
-rw-r--r--lib/rubygems/request_set/lockfile.rb39
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb57
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb12
-rw-r--r--lib/rubygems/requirement.rb79
-rw-r--r--lib/rubygems/resolver.rb105
-rw-r--r--lib/rubygems/resolver/activation_request.rb19
-rw-r--r--lib/rubygems/resolver/api_set.rb58
-rw-r--r--lib/rubygems/resolver/api_set/gem_parser.rb20
-rw-r--r--lib/rubygems/resolver/api_specification.rb45
-rw-r--r--lib/rubygems/resolver/best_set.rb17
-rw-r--r--lib/rubygems/resolver/composed_set.rb9
-rw-r--r--lib/rubygems/resolver/conflict.rb27
-rw-r--r--lib/rubygems/resolver/current_set.rb3
-rw-r--r--lib/rubygems/resolver/dependency_request.rb9
-rw-r--r--lib/rubygems/resolver/git_set.rb7
-rw-r--r--lib/rubygems/resolver/git_specification.rb15
-rw-r--r--lib/rubygems/resolver/index_set.rb11
-rw-r--r--lib/rubygems/resolver/index_specification.rb46
-rw-r--r--lib/rubygems/resolver/installed_specification.rb11
-rw-r--r--lib/rubygems/resolver/installer_set.rb95
-rw-r--r--lib/rubygems/resolver/local_specification.rb7
-rw-r--r--lib/rubygems/resolver/lock_set.rb15
-rw-r--r--lib/rubygems/resolver/lock_specification.rb11
-rw-r--r--lib/rubygems/resolver/molinillo.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo.rb11
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb8
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb51
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb1
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb13
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb63
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb90
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb14
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb4
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb675
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb5
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/state.rb12
-rw-r--r--lib/rubygems/resolver/requirement_list.rb3
-rw-r--r--lib/rubygems/resolver/set.rb4
-rw-r--r--lib/rubygems/resolver/source_set.rb4
-rw-r--r--lib/rubygems/resolver/spec_specification.rb17
-rw-r--r--lib/rubygems/resolver/specification.rb19
-rw-r--r--lib/rubygems/resolver/stats.rb5
-rw-r--r--lib/rubygems/resolver/vendor_set.rb5
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb9
-rw-r--r--lib/rubygems/s3_uri_signer.rb28
-rw-r--r--lib/rubygems/safe_yaml.rb32
-rw-r--r--lib/rubygems/security.rb154
-rw-r--r--lib/rubygems/security/policies.rb95
-rw-r--r--lib/rubygems/security/policy.rb55
-rw-r--r--lib/rubygems/security/signer.rb28
-rw-r--r--lib/rubygems/security/trust_dir.rb12
-rw-r--r--lib/rubygems/security_option.rb15
-rw-r--r--lib/rubygems/server.rb879
-rw-r--r--lib/rubygems/shellwords.rb3
-rw-r--r--lib/rubygems/source.rb82
-rw-r--r--lib/rubygems/source/git.rb62
-rw-r--r--lib/rubygems/source/installed.rb5
-rw-r--r--lib/rubygems/source/local.rb11
-rw-r--r--lib/rubygems/source/lock.rb3
-rw-r--r--lib/rubygems/source/specific_file.rb5
-rw-r--r--lib/rubygems/source/vendor.rb3
-rw-r--r--lib/rubygems/source_list.rb25
-rw-r--r--lib/rubygems/source_local.rb7
-rw-r--r--lib/rubygems/source_specific_file.rb6
-rw-r--r--lib/rubygems/spec_fetcher.rb98
-rw-r--r--lib/rubygems/specification.rb730
-rw-r--r--lib/rubygems/specification_policy.rb201
-rw-r--r--lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem23
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem25
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem (renamed from lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem)0
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem21
-rw-r--r--lib/rubygems/stub_specification.rb59
-rw-r--r--lib/rubygems/syck_hack.rb79
-rw-r--r--lib/rubygems/test_case.rb1555
-rw-r--r--lib/rubygems/test_utilities.rb380
-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.rb114
-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.rb5
-rw-r--r--lib/rubygems/uri_parser.rb36
-rw-r--r--lib/rubygems/uri_parsing.rb23
-rw-r--r--lib/rubygems/user_interaction.rb95
-rw-r--r--lib/rubygems/util.rb45
-rw-r--r--lib/rubygems/util/licenses.rb126
-rw-r--r--lib/rubygems/util/list.rb3
-rw-r--r--lib/rubygems/validator.rb17
-rw-r--r--lib/rubygems/version.rb53
-rw-r--r--lib/rubygems/version_option.rb17
-rw-r--r--lib/securerandom.gemspec22
-rw-r--r--lib/securerandom.rb272
-rw-r--r--lib/set.rb614
-rw-r--r--lib/set/set.gemspec23
-rw-r--r--lib/set/sorted_set.rb6
-rw-r--r--lib/shellwords.gemspec22
-rw-r--r--lib/shellwords.rb39
-rw-r--r--lib/singleton.rb4
-rw-r--r--lib/singleton/singleton.gemspec19
-rw-r--r--lib/singleton/version.rb3
-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.gemspec13
-rw-r--r--lib/tempfile.rb173
-rw-r--r--lib/time.gemspec24
-rw-r--r--lib/time.rb54
-rw-r--r--lib/timeout.rb171
-rw-r--r--lib/timeout/timeout.gemspec25
-rw-r--r--lib/timeout/version.rb3
-rw-r--r--lib/tmpdir.gemspec13
-rw-r--r--lib/tmpdir.rb45
-rw-r--r--lib/tracer.rb291
-rw-r--r--lib/tracer/tracer.gemspec23
-rw-r--r--lib/tracer/version.rb5
-rw-r--r--lib/tsort.gemspec22
-rw-r--r--lib/tsort.rb20
-rw-r--r--lib/un.gemspec24
-rw-r--r--lib/un.rb61
-rw-r--r--lib/unicode_normalize/normalize.rb2
-rw-r--r--lib/unicode_normalize/tables.rb228
-rw-r--r--lib/uri.rb26
-rw-r--r--lib/uri/common.rb169
-rw-r--r--lib/uri/file.rb8
-rw-r--r--lib/uri/ftp.rb4
-rw-r--r--lib/uri/generic.rb60
-rw-r--r--lib/uri/http.rb43
-rw-r--r--lib/uri/https.rb4
-rw-r--r--lib/uri/ldap.rb4
-rw-r--r--lib/uri/ldaps.rb3
-rw-r--r--lib/uri/mailto.rb5
-rw-r--r--lib/uri/rfc2396_parser.rb39
-rw-r--r--lib/uri/rfc3986_parser.rb30
-rw-r--r--lib/uri/uri.gemspec6
-rw-r--r--lib/uri/version.rb2
-rw-r--r--lib/uri/ws.rb83
-rw-r--r--lib/uri/wss.rb23
-rw-r--r--lib/weakref.rb4
-rw-r--r--lib/weakref/version.rb3
-rw-r--r--lib/weakref/weakref.gemspec27
-rw-r--r--lib/webrick.rb227
-rw-r--r--lib/webrick/httpauth/authenticator.rb117
-rw-r--r--lib/webrick/httpproxy.rb350
-rw-r--r--lib/webrick/httprequest.rb631
-rw-r--r--lib/webrick/httpserver.rb294
-rw-r--r--lib/webrick/httpservlet/filehandler.rb541
-rw-r--r--lib/webrick/httputils.rb511
-rw-r--r--lib/webrick/server.rb378
-rw-r--r--lib/webrick/ssl.rb215
-rw-r--r--lib/webrick/utils.rb270
-rw-r--r--lib/webrick/version.rb18
-rw-r--r--lib/webrick/webrick.gemspec76
-rw-r--r--lib/yaml.rb16
-rw-r--r--lib/yaml/store.rb2
-rw-r--r--lib/yaml/yaml.gemspec6
-rwxr-xr-xlibexec/bundle33
-rwxr-xr-xlibexec/bundler2
-rwxr-xr-xlibexec/erb164
-rwxr-xr-xlibexec/racc60
-rwxr-xr-xlibexec/rdoc1
-rwxr-xr-xlibexec/syntax_suggest7
-rw-r--r--load.c1186
-rw-r--r--localeinit.c17
-rw-r--r--main.c28
-rw-r--r--man/bundle-add.166
-rw-r--r--man/bundle-add.1.txt58
-rw-r--r--man/bundle-add.ronn46
-rw-r--r--man/bundle-binstubs.140
-rw-r--r--man/bundle-binstubs.1.txt48
-rw-r--r--man/bundle-binstubs.ronn43
-rw-r--r--man/bundle-cache.155
-rw-r--r--man/bundle-cache.1.txt78
-rw-r--r--man/bundle-cache.ronn72
-rw-r--r--man/bundle-check.131
-rw-r--r--man/bundle-check.1.txt33
-rw-r--r--man/bundle-clean.124
-rw-r--r--man/bundle-clean.1.txt26
-rw-r--r--man/bundle-clean.ronn18
-rw-r--r--man/bundle-config.1497
-rw-r--r--man/bundle-config.1.txt528
-rw-r--r--man/bundle-config.ronn399
-rw-r--r--man/bundle-doctor.144
-rw-r--r--man/bundle-doctor.1.txt44
-rw-r--r--man/bundle-exec.1165
-rw-r--r--man/bundle-exec.1.txt178
-rw-r--r--man/bundle-exec.ronn152
-rw-r--r--man/bundle-gem.180
-rw-r--r--man/bundle-gem.1.txt91
-rw-r--r--man/bundle-gem.ronn78
-rw-r--r--man/bundle-info.120
-rw-r--r--man/bundle-info.1.txt21
-rw-r--r--man/bundle-info.ronn17
-rw-r--r--man/bundle-init.125
-rw-r--r--man/bundle-init.1.txt34
-rw-r--r--man/bundle-init.ronn29
-rw-r--r--man/bundle-inject.133
-rw-r--r--man/bundle-inject.1.txt32
-rw-r--r--man/bundle-inject.ronn22
-rw-r--r--man/bundle-install.1311
-rw-r--r--man/bundle-install.1.txt401
-rw-r--r--man/bundle-install.ronn383
-rw-r--r--man/bundle-list.150
-rw-r--r--man/bundle-list.1.txt43
-rw-r--r--man/bundle-list.ronn33
-rw-r--r--man/bundle-lock.184
-rw-r--r--man/bundle-lock.1.txt93
-rw-r--r--man/bundle-open.132
-rw-r--r--man/bundle-open.1.txt29
-rw-r--r--man/bundle-open.ronn19
-rw-r--r--man/bundle-outdated.1155
-rw-r--r--man/bundle-outdated.1.txt131
-rw-r--r--man/bundle-outdated.ronn111
-rw-r--r--man/bundle-package.155
-rw-r--r--man/bundle-package.1.txt79
-rw-r--r--man/bundle-package.ronn72
-rw-r--r--man/bundle-platform.161
-rw-r--r--man/bundle-platform.1.txt57
-rw-r--r--man/bundle-platform.ronn42
-rw-r--r--man/bundle-pristine.134
-rw-r--r--man/bundle-pristine.1.txt44
-rw-r--r--man/bundle-remove.131
-rw-r--r--man/bundle-remove.1.txt34
-rw-r--r--man/bundle-show.123
-rw-r--r--man/bundle-show.1.txt27
-rw-r--r--man/bundle-update.1394
-rw-r--r--man/bundle-update.1.txt390
-rw-r--r--man/bundle-update.ronn350
-rw-r--r--man/bundle-viz.139
-rw-r--r--man/bundle-viz.1.txt39
-rw-r--r--man/bundle-viz.ronn30
-rw-r--r--man/bundle.1136
-rw-r--r--man/bundle.1.txt116
-rw-r--r--man/bundle.ronn111
-rw-r--r--man/gemfile.5686
-rw-r--r--man/gemfile.5.ronn517
-rw-r--r--man/gemfile.5.txt649
-rw-r--r--man/irb.149
-rw-r--r--man/ruby.146
-rw-r--r--marshal.c1957
-rw-r--r--marshal.rb40
-rw-r--r--math.c698
-rw-r--r--memory_view.c872
-rw-r--r--method.h46
-rw-r--r--mini_builtin.c15
-rwxr-xr-xmisc/expand_tabs.rb61
-rwxr-xr-xmisc/lldb_cruby.py491
-rw-r--r--misc/lldb_disasm.py250
-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/alloca.c2
-rw-r--r--missing/crypt.h5
-rw-r--r--missing/dtoa.c111
-rw-r--r--missing/dup2.c60
-rw-r--r--missing/erf.c15
-rw-r--r--missing/explicit_bzero.c4
-rw-r--r--missing/file.h3
-rw-r--r--missing/fileblocks.c1
-rw-r--r--missing/finite.c9
-rw-r--r--missing/flock.c11
-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.c17
-rw-r--r--mjit.c1903
-rw-r--r--mjit.h214
-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.c473
-rw-r--r--mjit_worker.c1244
-rw-r--r--nilclass.rb25
-rw-r--r--node.c1609
-rw-r--r--node.h116
-rw-r--r--numeric.c5334
-rw-r--r--numeric.rb405
-rw-r--r--object.c2704
-rw-r--r--pack.c2358
-rw-r--r--pack.rb282
-rw-r--r--parse.y3271
-rw-r--r--prelude.rb24
-rw-r--r--probes.d11
-rw-r--r--probes_helper.h14
-rw-r--r--proc.c1633
-rw-r--r--process.c2939
-rw-r--r--ractor.c3327
-rw-r--r--ractor.rb842
-rw-r--r--ractor_core.h342
-rw-r--r--random.c1129
-rw-r--r--range.c2112
-rw-r--r--rational.c1104
-rw-r--r--re.c3024
-rw-r--r--regcomp.c52
-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.c31
-rw-r--r--ruby-runner.c58
-rw-r--r--ruby.c2575
-rw-r--r--ruby_assert.h23
-rw-r--r--ruby_atomic.h267
-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/drb/name.rb3
-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
-rw-r--r--sample/list.rb5
-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/trick2013/mame/remarks.markdown4
-rw-r--r--sample/trick2015/kinaba/entry.rb6
-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--sample/webrick/demo-app.rb66
-rw-r--r--sample/webrick/demo-multipart.cgi12
-rw-r--r--sample/webrick/demo-servlet.rb6
-rw-r--r--sample/webrick/demo-urlencoded.cgi12
-rw-r--r--sample/webrick/hello.cgi11
-rw-r--r--sample/webrick/hello.rb8
-rw-r--r--sample/webrick/httpd.rb23
-rw-r--r--sample/webrick/httpproxy.rb25
-rw-r--r--sample/webrick/httpsd.rb33
-rw-r--r--scheduler.c687
-rw-r--r--shape.c825
-rw-r--r--shape.h232
-rw-r--r--signal.c612
-rw-r--r--siphash.c105
-rw-r--r--sparc.c4
-rw-r--r--spec/README.md34
-rw-r--r--spec/bundler/bundler/bundler_spec.rb268
-rw-r--r--spec/bundler/bundler/cli_spec.rb135
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb46
-rw-r--r--spec/bundler/bundler/definition_spec.rb125
-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.rb146
-rw-r--r--spec/bundler/bundler/endpoint_specification_spec.rb48
-rw-r--r--spec/bundler/bundler/env_spec.rb60
-rw-r--r--spec/bundler/bundler/fetcher/compact_index_spec.rb5
-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.rb112
-rw-r--r--spec/bundler/bundler/fetcher_spec.rb37
-rw-r--r--spec/bundler/bundler/friendly_errors_spec.rb39
-rw-r--r--spec/bundler/bundler/gem_helper_spec.rb159
-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/mirror_spec.rb2
-rw-r--r--spec/bundler/bundler/plugin/api/source_spec.rb6
-rw-r--r--spec/bundler/bundler/plugin/dsl_spec.rb2
-rw-r--r--spec/bundler/bundler/plugin/index_spec.rb33
-rw-r--r--spec/bundler/bundler/plugin/installer_spec.rb2
-rw-r--r--spec/bundler/bundler/plugin_spec.rb61
-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.rb27
-rw-r--r--spec/bundler/bundler/shared_helpers_spec.rb79
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb66
-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.rb80
-rw-r--r--spec/bundler/bundler/source_spec.rb40
-rw-r--r--spec/bundler/bundler/stub_specification_spec.rb33
-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.rb79
-rw-r--r--spec/bundler/cache/git_spec.rb145
-rw-r--r--spec/bundler/cache/path_spec.rb43
-rw-r--r--spec/bundler/cache/platform_spec.rb4
-rw-r--r--spec/bundler/commands/add_spec.rb128
-rw-r--r--spec/bundler/commands/binstubs_spec.rb221
-rw-r--r--spec/bundler/commands/cache_spec.rb141
-rw-r--r--spec/bundler/commands/check_spec.rb331
-rw-r--r--spec/bundler/commands/clean_spec.rb144
-rw-r--r--spec/bundler/commands/config_spec.rb213
-rw-r--r--spec/bundler/commands/console_spec.rb51
-rw-r--r--spec/bundler/commands/doctor_spec.rb48
-rw-r--r--spec/bundler/commands/exec_spec.rb591
-rw-r--r--spec/bundler/commands/fund_spec.rb82
-rw-r--r--spec/bundler/commands/help_spec.rb33
-rw-r--r--spec/bundler/commands/info_spec.rb124
-rw-r--r--spec/bundler/commands/init_spec.rb72
-rw-r--r--spec/bundler/commands/inject_spec.rb40
-rw-r--r--spec/bundler/commands/install_spec.rb733
-rw-r--r--spec/bundler/commands/licenses_spec.rb10
-rw-r--r--spec/bundler/commands/list_spec.rb39
-rw-r--r--spec/bundler/commands/lock_spec.rb975
-rw-r--r--spec/bundler/commands/newgem_spec.rb1302
-rw-r--r--spec/bundler/commands/open_spec.rb75
-rw-r--r--spec/bundler/commands/outdated_spec.rb1012
-rw-r--r--spec/bundler/commands/platform_spec.rb1307
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb137
-rw-r--r--spec/bundler/commands/pristine_spec.rb78
-rw-r--r--spec/bundler/commands/remove_spec.rb257
-rw-r--r--spec/bundler/commands/show_spec.rb39
-rw-r--r--spec/bundler/commands/update_spec.rb1240
-rw-r--r--spec/bundler/commands/version_spec.rb12
-rw-r--r--spec/bundler/commands/viz_spec.rb25
-rw-r--r--spec/bundler/install/allow_offline_install_spec.rb27
-rw-r--r--spec/bundler/install/binstubs_spec.rb6
-rw-r--r--spec/bundler/install/bundler_spec.rb204
-rw-r--r--spec/bundler/install/deploy_spec.rb315
-rw-r--r--spec/bundler/install/failure_spec.rb101
-rw-r--r--spec/bundler/install/gemfile/eval_gemfile_spec.rb54
-rw-r--r--spec/bundler/install/gemfile/force_ruby_platform_spec.rb118
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb368
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb483
-rw-r--r--spec/bundler/install/gemfile/groups_spec.rb167
-rw-r--r--spec/bundler/install/gemfile/install_if.rb44
-rw-r--r--spec/bundler/install/gemfile/install_if_spec.rb44
-rw-r--r--spec/bundler/install/gemfile/lockfile_spec.rb8
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb365
-rw-r--r--spec/bundler/install/gemfile/platform_spec.rb355
-rw-r--r--spec/bundler/install/gemfile/ruby_spec.rb49
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb1497
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb999
-rw-r--r--spec/bundler/install/gemfile_spec.rb60
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb346
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb199
-rw-r--r--spec/bundler/install/gems/flex_spec.rb167
-rw-r--r--spec/bundler/install/gems/fund_spec.rb164
-rw-r--r--spec/bundler/install/gems/native_extensions_spec.rb79
-rw-r--r--spec/bundler/install/gems/post_install_spec.rb2
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb454
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb358
-rw-r--r--spec/bundler/install/gems/sudo_spec.rb187
-rw-r--r--spec/bundler/install/gems/win32_spec.rb3
-rw-r--r--spec/bundler/install/gemspecs_spec.rb24
-rw-r--r--spec/bundler/install/git_spec.rb119
-rw-r--r--spec/bundler/install/global_cache_spec.rb115
-rw-r--r--spec/bundler/install/path_spec.rb101
-rw-r--r--spec/bundler/install/prereleases_spec.rb21
-rw-r--r--spec/bundler/install/process_lock_spec.rb24
-rw-r--r--spec/bundler/install/redownload_spec.rb21
-rw-r--r--spec/bundler/install/security_policy_spec.rb16
-rw-r--r--spec/bundler/install/yanked_spec.rb174
-rw-r--r--spec/bundler/lock/git_spec.rb128
-rw-r--r--spec/bundler/lock/lockfile_spec.rb839
-rw-r--r--spec/bundler/other/cli_dispatch_spec.rb6
-rw-r--r--spec/bundler/other/ext_spec.rb8
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb437
-rw-r--r--spec/bundler/other/platform_spec.rb1306
-rw-r--r--spec/bundler/plugins/command_spec.rb6
-rw-r--r--spec/bundler/plugins/install_spec.rb104
-rw-r--r--spec/bundler/plugins/source/example_spec.rb100
-rw-r--r--spec/bundler/plugins/source_spec.rb3
-rw-r--r--spec/bundler/plugins/uninstall_spec.rb49
-rw-r--r--spec/bundler/quality_es_spec.rb20
-rw-r--r--spec/bundler/quality_spec.rb180
-rw-r--r--spec/bundler/realworld/dependency_api_spec.rb14
-rw-r--r--spec/bundler/realworld/double_check_spec.rb10
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb461
-rw-r--r--spec/bundler/realworld/ffi_spec.rb57
-rw-r--r--spec/bundler/realworld/fixtures/warbler/.gitignore1
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile7
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock30
-rw-r--r--spec/bundler/realworld/fixtures/warbler/bin/warbler-example.rb3
-rw-r--r--spec/bundler/realworld/fixtures/warbler/demo/demo.gemspec10
-rw-r--r--spec/bundler/realworld/gemfile_source_header_spec.rb12
-rw-r--r--spec/bundler/realworld/git_spec.rb11
-rw-r--r--spec/bundler/realworld/mirror_probe_spec.rb53
-rw-r--r--spec/bundler/realworld/parallel_spec.rb6
-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.rb335
-rw-r--r--spec/bundler/runtime/executable_spec.rb54
-rw-r--r--spec/bundler/runtime/gem_tasks_spec.rb56
-rw-r--r--spec/bundler/runtime/inline_spec.rb355
-rw-r--r--spec/bundler/runtime/load_spec.rb16
-rw-r--r--spec/bundler/runtime/platform_spec.rb327
-rw-r--r--spec/bundler/runtime/require_spec.rb39
-rw-r--r--spec/bundler/runtime/self_management_spec.rb126
-rw-r--r--spec/bundler/runtime/setup_spec.rb576
-rw-r--r--spec/bundler/runtime/with_unbundled_env_spec.rb134
-rw-r--r--spec/bundler/spec_helper.rb89
-rw-r--r--spec/bundler/support/artifice/compact_index.rb116
-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.rb10
-rw-r--r--spec/bundler/support/artifice/compact_index_creds_diff_host.rb8
-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.rb12
-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.rb8
-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/endopint_marshal_fail_basic_authentication.rb15
-rw-r--r--spec/bundler/support/artifice/endpoint.rb98
-rw-r--r--spec/bundler/support/artifice/endpoint_500.rb8
-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.rb8
-rw-r--r--spec/bundler/support/artifice/endpoint_extra.rb14
-rw-r--r--spec/bundler/support/artifice/endpoint_extra_api.rb14
-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.rb15
-rw-r--r--spec/bundler/support/artifice/endpoint_mirror_source.rb6
-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.rb16
-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.rb52
-rw-r--r--spec/bundler/support/artifice/windows.rb12
-rw-r--r--spec/bundler/support/build_metadata.rb49
-rw-r--r--spec/bundler/support/builders.rb340
-rw-r--r--spec/bundler/support/bundle.rb10
-rw-r--r--spec/bundler/support/command_execution.rb13
-rw-r--r--spec/bundler/support/filters.rb23
-rw-r--r--spec/bundler/support/hax.rb71
-rw-r--r--spec/bundler/support/helpers.rb478
-rw-r--r--spec/bundler/support/indexes.rb36
-rw-r--r--spec/bundler/support/matchers.rb135
-rw-r--r--spec/bundler/support/parallel.rb5
-rw-r--r--spec/bundler/support/path.rb190
-rw-r--r--spec/bundler/support/platforms.rb48
-rw-r--r--spec/bundler/support/rubygems_ext.rb190
-rw-r--r--spec/bundler/support/rubygems_version_manager.rb53
-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/support/switch_rubygems.rb4
-rw-r--r--spec/bundler/update/gemfile_spec.rb16
-rw-r--r--spec/bundler/update/gems/fund_spec.rb50
-rw-r--r--spec/bundler/update/gems/post_install_spec.rb8
-rw-r--r--spec/bundler/update/git_spec.rb130
-rw-r--r--spec/bundler/update/path_spec.rb1
-rw-r--r--spec/bundler/update/redownload_spec.rb8
-rw-r--r--spec/default.mspec22
-rw-r--r--spec/mspec/.rspec1
-rw-r--r--spec/mspec/Gemfile4
-rw-r--r--spec/mspec/Gemfile.lock29
-rw-r--r--spec/mspec/README.md6
-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/bug.rb19
-rw-r--r--spec/mspec/lib/mspec/guards/guard.rb2
-rw-r--r--spec/mspec/lib/mspec/guards/platform.rb17
-rw-r--r--spec/mspec/lib/mspec/guards/superuser.rb10
-rw-r--r--spec/mspec/lib/mspec/guards/version.rb65
-rw-r--r--spec/mspec/lib/mspec/helpers.rb1
-rw-r--r--spec/mspec/lib/mspec/helpers/datetime.rb1
-rw-r--r--spec/mspec/lib/mspec/helpers/frozen_error_class.rb17
-rw-r--r--spec/mspec/lib/mspec/helpers/io.rb4
-rw-r--r--spec/mspec/lib/mspec/helpers/numeric.rb12
-rw-r--r--spec/mspec/lib/mspec/helpers/ruby_exe.rb40
-rw-r--r--spec/mspec/lib/mspec/helpers/scratch.rb4
-rw-r--r--spec/mspec/lib/mspec/helpers/tmp.rb13
-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/include.rb4
-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.rb41
-rw-r--r--spec/mspec/lib/mspec/mocks/mock.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/actions/constants_leak_checker.rb11
-rw-r--r--spec/mspec/lib/mspec/runner/actions/leakchecker.rb29
-rw-r--r--spec/mspec/lib/mspec/runner/actions/timeout.rb37
-rw-r--r--spec/mspec/lib/mspec/runner/context.rb34
-rw-r--r--spec/mspec/lib/mspec/runner/example.rb12
-rw-r--r--spec/mspec/lib/mspec/runner/exception.rb31
-rw-r--r--spec/mspec/lib/mspec/runner/formatters.rb1
-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/formatters/method.rb14
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/spinner.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/stats.rb57
-rw-r--r--spec/mspec/lib/mspec/runner/mspec.rb92
-rw-r--r--spec/mspec/lib/mspec/runner/object.rb4
-rw-r--r--spec/mspec/lib/mspec/runner/parallel.rb2
-rw-r--r--spec/mspec/lib/mspec/runner/shared.rb8
-rw-r--r--spec/mspec/lib/mspec/utils/format.rb6
-rw-r--r--spec/mspec/lib/mspec/utils/name_map.rb7
-rw-r--r--spec/mspec/lib/mspec/utils/options.rb31
-rw-r--r--spec/mspec/lib/mspec/utils/script.rb29
-rw-r--r--spec/mspec/lib/mspec/utils/version.rb2
-rw-r--r--spec/mspec/lib/mspec/utils/warnings.rb35
-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/config.mspec2
-rwxr-xr-xspec/mspec/spec/fixtures/my_ruby2
-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.rb222
-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.rb90
-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.rb50
-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.rb12
-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.rb36
-rw-r--r--spec/mspec/spec/integration/tag_spec.rb12
-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.rb127
-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.rb369
-rw-r--r--spec/mspec/spec/runner/example_spec.rb60
-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.rb300
-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.rb491
-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.rb21
-rw-r--r--spec/mspec/tool/sync/sync-rubyspec.rb52
-rwxr-xr-xspec/mspec/tool/tag_from_output.rb39
-rwxr-xr-xspec/mspec/tool/wrap_with_guard.rb28
-rw-r--r--spec/ruby/.mspec.constants5
-rw-r--r--spec/ruby/.rubocop.yml64
-rw-r--r--spec/ruby/.rubocop_todo.yml18
-rw-r--r--spec/ruby/CONTRIBUTING.md106
-rw-r--r--spec/ruby/README.md50
-rw-r--r--spec/ruby/command_line/backtrace_limit_spec.rb48
-rw-r--r--spec/ruby/command_line/dash_e_spec.rb2
-rw-r--r--spec/ruby/command_line/dash_encoding_spec.rb8
-rw-r--r--spec/ruby/command_line/dash_l_spec.rb31
-rw-r--r--spec/ruby/command_line/dash_r_spec.rb19
-rw-r--r--spec/ruby/command_line/dash_upper_e_spec.rb3
-rw-r--r--spec/ruby/command_line/dash_upper_k_spec.rb4
-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.rb24
-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.rb8
-rw-r--r--spec/ruby/command_line/feature_spec.rb29
-rw-r--r--spec/ruby/command_line/fixtures/backtrace.rb35
-rw-r--r--spec/ruby/command_line/fixtures/bin/hybrid_launcher.sh2
-rw-r--r--spec/ruby/command_line/fixtures/freeze_flag_two_literals.rb2
-rw-r--r--spec/ruby/command_line/fixtures/test_file.rb2
-rw-r--r--spec/ruby/command_line/rubyopt_spec.rb58
-rw-r--r--spec/ruby/command_line/syntax_error_spec.rb4
-rw-r--r--spec/ruby/core/argf/binmode_spec.rb2
-rw-r--r--spec/ruby/core/argf/bytes_spec.rb14
-rw-r--r--spec/ruby/core/argf/chars_spec.rb14
-rw-r--r--spec/ruby/core/argf/codepoints_spec.rb14
-rw-r--r--spec/ruby/core/argf/lines_spec.rb14
-rw-r--r--spec/ruby/core/argf/shared/fileno.rb2
-rw-r--r--spec/ruby/core/array/any_spec.rb6
-rw-r--r--spec/ruby/core/array/append_spec.rb10
-rw-r--r--spec/ruby/core/array/bsearch_index_spec.rb2
-rw-r--r--spec/ruby/core/array/clear_spec.rb26
-rw-r--r--spec/ruby/core/array/clone_spec.rb4
-rw-r--r--spec/ruby/core/array/compact_spec.rb34
-rw-r--r--spec/ruby/core/array/concat_spec.rb66
-rw-r--r--spec/ruby/core/array/deconstruct_spec.rb10
-rw-r--r--spec/ruby/core/array/delete_at_spec.rb26
-rw-r--r--spec/ruby/core/array/delete_if_spec.rb24
-rw-r--r--spec/ruby/core/array/delete_spec.rb26
-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.rb124
-rw-r--r--spec/ruby/core/array/empty_spec.rb6
-rw-r--r--spec/ruby/core/array/fill_spec.rb34
-rw-r--r--spec/ruby/core/array/filter_spec.rb18
-rw-r--r--spec/ruby/core/array/fixtures/classes.rb66
-rw-r--r--spec/ruby/core/array/flatten_spec.rb62
-rw-r--r--spec/ruby/core/array/frozen_spec.rb6
-rw-r--r--spec/ruby/core/array/hash_spec.rb2
-rw-r--r--spec/ruby/core/array/initialize_spec.rb6
-rw-r--r--spec/ruby/core/array/insert_spec.rb8
-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/minmax_spec.rb14
-rw-r--r--spec/ruby/core/array/multiply_spec.rb58
-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.rb66
-rw-r--r--spec/ruby/core/array/prepend_spec.rb6
-rw-r--r--spec/ruby/core/array/reject_spec.rb8
-rw-r--r--spec/ruby/core/array/reverse_spec.rb4
-rw-r--r--spec/ruby/core/array/rotate_spec.rb8
-rw-r--r--spec/ruby/core/array/sample_spec.rb34
-rw-r--r--spec/ruby/core/array/shared/clone.rb24
-rw-r--r--spec/ruby/core/array/shared/collect.rb47
-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/keep_if.rb8
-rw-r--r--spec/ruby/core/array/shared/push.rb6
-rw-r--r--spec/ruby/core/array/shared/replace.rb4
-rw-r--r--spec/ruby/core/array/shared/slice.rb445
-rw-r--r--spec/ruby/core/array/shared/union.rb2
-rw-r--r--spec/ruby/core/array/shared/unshift.rb26
-rw-r--r--spec/ruby/core/array/shift_spec.rb24
-rw-r--r--spec/ruby/core/array/shuffle_spec.rb6
-rw-r--r--spec/ruby/core/array/slice_spec.rb94
-rw-r--r--spec/ruby/core/array/sort_by_spec.rb8
-rw-r--r--spec/ruby/core/array/sort_spec.rb22
-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.rb100
-rw-r--r--spec/ruby/core/array/values_at_spec.rb14
-rw-r--r--spec/ruby/core/array/zip_spec.rb6
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb76
-rw-r--r--spec/ruby/core/basicobject/instance_exec_spec.rb8
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb59
-rw-r--r--spec/ruby/core/binding/eval_spec.rb30
-rw-r--r--spec/ruby/core/binding/fixtures/classes.rb14
-rw-r--r--spec/ruby/core/binding/irb_spec.rb22
-rw-r--r--spec/ruby/core/binding/source_location_spec.rb10
-rw-r--r--spec/ruby/core/builtin_constants/builtin_constants_spec.rb22
-rw-r--r--spec/ruby/core/class/allocate_spec.rb2
-rw-r--r--spec/ruby/core/class/attached_object_spec.rb31
-rw-r--r--spec/ruby/core/class/initialize_spec.rb2
-rw-r--r--spec/ruby/core/class/new_spec.rb15
-rw-r--r--spec/ruby/core/class/subclasses_spec.rb60
-rw-r--r--spec/ruby/core/class/superclass_spec.rb2
-rw-r--r--spec/ruby/core/comparable/clamp_spec.rb78
-rw-r--r--spec/ruby/core/comparable/lt_spec.rb6
-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/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/complex/exponent_spec.rb2
-rw-r--r--spec/ruby/core/complex/finite_spec.rb12
-rw-r--r--spec/ruby/core/complex/polar_spec.rb16
-rw-r--r--spec/ruby/core/complex/to_c_spec.rb12
-rw-r--r--spec/ruby/core/complex/to_f_spec.rb2
-rw-r--r--spec/ruby/core/complex/to_i_spec.rb2
-rw-r--r--spec/ruby/core/complex/to_r_spec.rb2
-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.rb77
-rw-r--r--spec/ruby/core/conditionvariable/wait_spec.rb175
-rw-r--r--spec/ruby/core/data/constants_spec.rb32
-rw-r--r--spec/ruby/core/dir/children_spec.rb206
-rw-r--r--spec/ruby/core/dir/each_child_spec.rb147
-rw-r--r--spec/ruby/core/dir/entries_spec.rb6
-rw-r--r--spec/ruby/core/dir/exists_spec.rb15
-rw-r--r--spec/ruby/core/dir/fileno_spec.rb2
-rw-r--r--spec/ruby/core/dir/fixtures/common.rb37
-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.rb49
-rw-r--r--spec/ruby/core/dir/mkdir_spec.rb52
-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.rb217
-rw-r--r--spec/ruby/core/dir/shared/open.rb2
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb2
-rw-r--r--spec/ruby/core/encoding/converter/constants_spec.rb52
-rw-r--r--spec/ruby/core/encoding/converter/new_spec.rb4
-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.rb12
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb97
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb154
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb158
-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/fixtures/classes.rb2
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb42
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb42
-rw-r--r--spec/ruby/core/enumerable/group_by_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/minmax_spec.rb34
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb120
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb142
-rw-r--r--spec/ruby/core/enumerable/shared/collect.rb69
-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/sort_spec.rb2
-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.rb16
-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/initialize_spec.rb10
-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/initialize_spec.rb2
-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.rb108
-rw-r--r--spec/ruby/core/enumerator/next_spec.rb11
-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.rb11
-rw-r--r--spec/ruby/core/enumerator/yielder/to_proc_spec.rb20
-rw-r--r--spec/ruby/core/enumerator/yielder/yield_spec.rb10
-rw-r--r--spec/ruby/core/env/delete_spec.rb7
-rw-r--r--spec/ruby/core/env/element_reference_spec.rb5
-rw-r--r--spec/ruby/core/env/empty_spec.rb6
-rw-r--r--spec/ruby/core/env/except_spec.rb36
-rw-r--r--spec/ruby/core/env/fetch_spec.rb3
-rw-r--r--spec/ruby/core/env/filter_spec.rb16
-rw-r--r--spec/ruby/core/env/fixtures/common.rb9
-rw-r--r--spec/ruby/core/env/index_spec.rb14
-rw-r--r--spec/ruby/core/env/merge_spec.rb6
-rw-r--r--spec/ruby/core/env/shared/key.rb14
-rw-r--r--spec/ruby/core/env/shared/update.rb38
-rw-r--r--spec/ruby/core/env/shift_spec.rb42
-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/env/values_at_spec.rb3
-rw-r--r--spec/ruby/core/exception/backtrace_spec.rb2
-rw-r--r--spec/ruby/core/exception/errno_spec.rb23
-rw-r--r--spec/ruby/core/exception/frozen_error_spec.rb28
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb160
-rw-r--r--spec/ruby/core/exception/hierarchy_spec.rb8
-rw-r--r--spec/ruby/core/exception/interrupt_spec.rb27
-rw-r--r--spec/ruby/core/exception/key_error_spec.rb20
-rw-r--r--spec/ruby/core/exception/name_error_spec.rb12
-rw-r--r--spec/ruby/core/exception/name_spec.rb4
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb32
-rw-r--r--spec/ruby/core/exception/receiver_spec.rb6
-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/success_spec.rb4
-rw-r--r--spec/ruby/core/exception/system_call_error_spec.rb2
-rw-r--r--spec/ruby/core/exception/system_exit_spec.rb59
-rw-r--r--spec/ruby/core/exception/top_level_spec.rb45
-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/fixtures/classes.rb12
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb119
-rw-r--r--spec/ruby/core/fiber/resume_spec.rb37
-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.rb80
-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/exists_spec.rb6
-rw-r--r--spec/ruby/core/file/expand_path_spec.rb6
-rw-r--r--spec/ruby/core/file/extname_spec.rb14
-rw-r--r--spec/ruby/core/file/ftype_spec.rb8
-rw-r--r--spec/ruby/core/file/join_spec.rb9
-rw-r--r--spec/ruby/core/file/lchmod_spec.rb22
-rw-r--r--spec/ruby/core/file/link_spec.rb2
-rw-r--r--spec/ruby/core/file/lstat_spec.rb4
-rw-r--r--spec/ruby/core/file/lutime_spec.rb58
-rw-r--r--spec/ruby/core/file/mtime_spec.rb20
-rw-r--r--spec/ruby/core/file/open_spec.rb66
-rw-r--r--spec/ruby/core/file/realpath_spec.rb6
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb16
-rw-r--r--spec/ruby/core/file/shared/path.rb37
-rw-r--r--spec/ruby/core/file/shared/read.rb4
-rw-r--r--spec/ruby/core/file/size_spec.rb4
-rw-r--r--spec/ruby/core/file/stat/nlink_spec.rb2
-rw-r--r--spec/ruby/core/file/stat/owned_spec.rb4
-rw-r--r--spec/ruby/core/file/stat/pipe_spec.rb4
-rw-r--r--spec/ruby/core/file/stat_spec.rb18
-rw-r--r--spec/ruby/core/file/truncate_spec.rb6
-rw-r--r--spec/ruby/core/file/umask_spec.rb4
-rw-r--r--spec/ruby/core/file/utime_spec.rb51
-rw-r--r--spec/ruby/core/filetest/exists_spec.rb6
-rw-r--r--spec/ruby/core/float/coerce_spec.rb4
-rw-r--r--spec/ruby/core/float/comparison_spec.rb91
-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/finite_spec.rb8
-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/inspect_spec.rb6
-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/nan_spec.rb6
-rw-r--r--spec/ruby/core/float/negative_spec.rb33
-rw-r--r--spec/ruby/core/float/next_float_spec.rb2
-rw-r--r--spec/ruby/core/float/plus_spec.rb2
-rw-r--r--spec/ruby/core/float/positive_spec.rb33
-rw-r--r--spec/ruby/core/float/prev_float_spec.rb2
-rw-r--r--spec/ruby/core/float/round_spec.rb77
-rw-r--r--spec/ruby/core/float/shared/arithmetic_exception_in_coerce.rb32
-rw-r--r--spec/ruby/core/float/shared/comparison_exception_in_coerce.rb34
-rw-r--r--spec/ruby/core/float/shared/equal.rb21
-rw-r--r--spec/ruby/core/float/shared/quo.rb4
-rw-r--r--spec/ruby/core/float/shared/to_i.rb4
-rw-r--r--spec/ruby/core/float/shared/to_s.rb308
-rw-r--r--spec/ruby/core/float/to_s_spec.rb308
-rw-r--r--spec/ruby/core/float/uminus_spec.rb2
-rw-r--r--spec/ruby/core/float/zero_spec.rb6
-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/profiler/disable_spec.rb2
-rw-r--r--spec/ruby/core/gc/profiler/enable_spec.rb2
-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/any_spec.rb4
-rw-r--r--spec/ruby/core/hash/clear_spec.rb6
-rw-r--r--spec/ruby/core/hash/compact_spec.rb4
-rw-r--r--spec/ruby/core/hash/compare_by_identity_spec.rb6
-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/default_proc_spec.rb6
-rw-r--r--spec/ruby/core/hash/default_spec.rb6
-rw-r--r--spec/ruby/core/hash/delete_if_spec.rb6
-rw-r--r--spec/ruby/core/hash/delete_spec.rb6
-rw-r--r--spec/ruby/core/hash/element_reference_spec.rb14
-rw-r--r--spec/ruby/core/hash/empty_spec.rb10
-rw-r--r--spec/ruby/core/hash/except_spec.rb34
-rw-r--r--spec/ruby/core/hash/filter_spec.rb12
-rw-r--r--spec/ruby/core/hash/fixtures/name.rb30
-rw-r--r--spec/ruby/core/hash/hash_spec.rb9
-rw-r--r--spec/ruby/core/hash/index_spec.rb6
-rw-r--r--spec/ruby/core/hash/initialize_spec.rb10
-rw-r--r--spec/ruby/core/hash/keep_if_spec.rb6
-rw-r--r--spec/ruby/core/hash/merge_spec.rb24
-rw-r--r--spec/ruby/core/hash/rehash_spec.rb24
-rw-r--r--spec/ruby/core/hash/reject_spec.rb15
-rw-r--r--spec/ruby/core/hash/ruby2_keywords_hash_spec.rb59
-rw-r--r--spec/ruby/core/hash/shared/each.rb53
-rw-r--r--spec/ruby/core/hash/shared/eql.rb84
-rw-r--r--spec/ruby/core/hash/shared/index.rb22
-rw-r--r--spec/ruby/core/hash/shared/replace.rb8
-rw-r--r--spec/ruby/core/hash/shared/select.rb8
-rw-r--r--spec/ruby/core/hash/shared/store.rb25
-rw-r--r--spec/ruby/core/hash/shared/to_s.rb17
-rw-r--r--spec/ruby/core/hash/shared/update.rb26
-rw-r--r--spec/ruby/core/hash/shift_spec.rb48
-rw-r--r--spec/ruby/core/hash/slice_spec.rb82
-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/to_proc_spec.rb16
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb203
-rw-r--r--spec/ruby/core/hash/transform_values_spec.rb8
-rw-r--r--spec/ruby/core/integer/allbits_spec.rb62
-rw-r--r--spec/ruby/core/integer/anybits_spec.rb60
-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.rb58
-rw-r--r--spec/ruby/core/integer/coerce_spec.rb10
-rw-r--r--spec/ruby/core/integer/comparison_spec.rb24
-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.rb12
-rw-r--r--spec/ruby/core/integer/divide_spec.rb20
-rw-r--r--spec/ruby/core/integer/divmod_spec.rb12
-rw-r--r--spec/ruby/core/integer/downto_spec.rb2
-rw-r--r--spec/ruby/core/integer/element_reference_spec.rb126
-rw-r--r--spec/ruby/core/integer/fdiv_spec.rb51
-rw-r--r--spec/ruby/core/integer/gcd_spec.rb4
-rw-r--r--spec/ruby/core/integer/gcdlcm_spec.rb4
-rw-r--r--spec/ruby/core/integer/gt_spec.rb8
-rw-r--r--spec/ruby/core/integer/gte_spec.rb8
-rw-r--r--spec/ruby/core/integer/integer_spec.rb6
-rw-r--r--spec/ruby/core/integer/lcm_spec.rb4
-rw-r--r--spec/ruby/core/integer/left_shift_spec.rb70
-rw-r--r--spec/ruby/core/integer/lt_spec.rb8
-rw-r--r--spec/ruby/core/integer/lte_spec.rb13
-rw-r--r--spec/ruby/core/integer/minus_spec.rb14
-rw-r--r--spec/ruby/core/integer/multiply_spec.rb14
-rw-r--r--spec/ruby/core/integer/nobits_spec.rb60
-rw-r--r--spec/ruby/core/integer/plus_spec.rb31
-rw-r--r--spec/ruby/core/integer/pow_spec.rb82
-rw-r--r--spec/ruby/core/integer/remainder_spec.rb2
-rw-r--r--spec/ruby/core/integer/right_shift_spec.rb74
-rw-r--r--spec/ruby/core/integer/round_spec.rb26
-rw-r--r--spec/ruby/core/integer/shared/abs.rb4
-rw-r--r--spec/ruby/core/integer/shared/comparison_coerce.rb22
-rw-r--r--spec/ruby/core/integer/shared/equal.rb4
-rw-r--r--spec/ruby/core/integer/shared/exponent.rb20
-rw-r--r--spec/ruby/core/integer/shared/integer_rounding.rb16
-rw-r--r--spec/ruby/core/integer/shared/modulo.rb10
-rw-r--r--spec/ruby/core/integer/sqrt_spec.rb46
-rw-r--r--spec/ruby/core/integer/to_f_spec.rb6
-rw-r--r--spec/ruby/core/integer/to_r_spec.rb2
-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/upto_spec.rb2
-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/bytes_spec.rb66
-rw-r--r--spec/ruby/core/io/chars_spec.rb28
-rw-r--r--spec/ruby/core/io/close_on_exec_spec.rb16
-rw-r--r--spec/ruby/core/io/close_read_spec.rb2
-rw-r--r--spec/ruby/core/io/close_spec.rb53
-rw-r--r--spec/ruby/core/io/close_write_spec.rb2
-rw-r--r--spec/ruby/core/io/codepoints_spec.rb43
-rw-r--r--spec/ruby/core/io/copy_stream_spec.rb40
-rw-r--r--spec/ruby/core/io/dup_spec.rb31
-rw-r--r--spec/ruby/core/io/each_codepoint_spec.rb2
-rw-r--r--spec/ruby/core/io/eof_spec.rb26
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb9
-rw-r--r--spec/ruby/core/io/fixtures/classes.rb33
-rw-r--r--spec/ruby/core/io/fixtures/copy_in_out.rb2
-rw-r--r--spec/ruby/core/io/gets_spec.rb52
-rw-r--r--spec/ruby/core/io/initialize_spec.rb2
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb9
-rw-r--r--spec/ruby/core/io/ioctl_spec.rb4
-rw-r--r--spec/ruby/core/io/lineno_spec.rb45
-rw-r--r--spec/ruby/core/io/lines_spec.rb54
-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.rb23
-rw-r--r--spec/ruby/core/io/popen_spec.rb4
-rw-r--r--spec/ruby/core/io/pread_spec.rb74
-rw-r--r--spec/ruby/core/io/print_spec.rb27
-rw-r--r--spec/ruby/core/io/puts_spec.rb2
-rw-r--r--spec/ruby/core/io/pwrite_spec.rb62
-rw-r--r--spec/ruby/core/io/read_nonblock_spec.rb51
-rw-r--r--spec/ruby/core/io/read_spec.rb27
-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.rb62
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb17
-rw-r--r--spec/ruby/core/io/reopen_spec.rb8
-rw-r--r--spec/ruby/core/io/rewind_spec.rb17
-rw-r--r--spec/ruby/core/io/seek_spec.rb6
-rw-r--r--spec/ruby/core/io/set_encoding_by_bom_spec.rb262
-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.rb26
-rw-r--r--spec/ruby/core/io/shared/pos.rb10
-rw-r--r--spec/ruby/core/io/shared/readlines.rb152
-rw-r--r--spec/ruby/core/io/shared/write.rb10
-rw-r--r--spec/ruby/core/io/sysopen_spec.rb4
-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.rb25
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb12
-rw-r--r--spec/ruby/core/io/write_spec.rb52
-rw-r--r--spec/ruby/core/kernel/Complex_spec.rb151
-rw-r--r--spec/ruby/core/kernel/Float_spec.rb38
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb169
-rw-r--r--spec/ruby/core/kernel/__dir___spec.rb11
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb32
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb19
-rw-r--r--spec/ruby/core/kernel/backtick_spec.rb28
-rw-r--r--spec/ruby/core/kernel/caller_locations_spec.rb26
-rw-r--r--spec/ruby/core/kernel/caller_spec.rb26
-rw-r--r--spec/ruby/core/kernel/class_spec.rb2
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb135
-rw-r--r--spec/ruby/core/kernel/define_singleton_method_spec.rb15
-rw-r--r--spec/ruby/core/kernel/dup_spec.rb2
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb67
-rw-r--r--spec/ruby/core/kernel/extend_spec.rb4
-rw-r--r--spec/ruby/core/kernel/fixtures/Complex.rb5
-rw-r--r--spec/ruby/core/kernel/fixtures/__dir__.rb2
-rw-r--r--spec/ruby/core/kernel/fixtures/at_exit.rb3
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb34
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_core_method.rb14
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require.rb1
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require_caller.rb2
-rw-r--r--spec/ruby/core/kernel/format_spec.rb1
-rw-r--r--spec/ruby/core/kernel/freeze_spec.rb32
-rw-r--r--spec/ruby/core/kernel/frozen_spec.rb40
-rw-r--r--spec/ruby/core/kernel/initialize_clone_spec.rb28
-rw-r--r--spec/ruby/core/kernel/initialize_copy_spec.rb29
-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_of_spec.rb2
-rw-r--r--spec/ruby/core/kernel/instance_variable_get_spec.rb8
-rw-r--r--spec/ruby/core/kernel/instance_variable_set_spec.rb22
-rw-r--r--spec/ruby/core/kernel/instance_variables_spec.rb15
-rw-r--r--spec/ruby/core/kernel/iterator_spec.rb14
-rw-r--r--spec/ruby/core/kernel/lambda_spec.rb44
-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/pp_spec.rb12
-rw-r--r--spec/ruby/core/kernel/print_spec.rb12
-rw-r--r--spec/ruby/core/kernel/printf_spec.rb4
-rw-r--r--spec/ruby/core/kernel/proc_spec.rb26
-rw-r--r--spec/ruby/core/kernel/public_send_spec.rb8
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb40
-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.rb12
-rw-r--r--spec/ruby/core/kernel/respond_to_spec.rb3
-rw-r--r--spec/ruby/core/kernel/shared/dup_clone.rb50
-rw-r--r--spec/ruby/core/kernel/shared/lambda.rb4
-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.rb133
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb174
-rw-r--r--spec/ruby/core/kernel/shared/sprintf_encoding.rb33
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb4
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb8
-rw-r--r--spec/ruby/core/kernel/srand_spec.rb18
-rw-r--r--spec/ruby/core/kernel/system_spec.rb20
-rw-r--r--spec/ruby/core/kernel/taint_spec.rb44
-rw-r--r--spec/ruby/core/kernel/tainted_spec.rb15
-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.rb24
-rw-r--r--spec/ruby/core/kernel/untrusted_spec.rb28
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb240
-rw-r--r--spec/ruby/core/kernel/yield_self_spec.rb6
-rw-r--r--spec/ruby/core/main/fixtures/classes.rb8
-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.rb43
-rw-r--r--spec/ruby/core/main/public_spec.rb40
-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.rb110
-rw-r--r--spec/ruby/core/marshal/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb62
-rw-r--r--spec/ruby/core/marshal/shared/load.rb371
-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/string_spec.rb4
-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/math/tan_spec.rb4
-rw-r--r--spec/ruby/core/method/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/method/compose_spec.rb134
-rw-r--r--spec/ruby/core/method/fixtures/classes.rb36
-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.rb53
-rw-r--r--spec/ruby/core/method/source_location_spec.rb22
-rw-r--r--spec/ruby/core/method/super_method_spec.rb21
-rw-r--r--spec/ruby/core/method/unbind_spec.rb37
-rw-r--r--spec/ruby/core/module/alias_method_spec.rb40
-rw-r--r--spec/ruby/core/module/allocate_spec.rb14
-rw-r--r--spec/ruby/core/module/append_features_spec.rb18
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb48
-rw-r--r--spec/ruby/core/module/attr_reader_spec.rb23
-rw-r--r--spec/ruby/core/module/attr_spec.rb27
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb35
-rw-r--r--spec/ruby/core/module/autoload_spec.rb193
-rw-r--r--spec/ruby/core/module/class_variable_defined_spec.rb2
-rw-r--r--spec/ruby/core/module/class_variable_get_spec.rb2
-rw-r--r--spec/ruby/core/module/class_variable_set_spec.rb8
-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.rb25
-rw-r--r--spec/ruby/core/module/const_source_location_spec.rb225
-rw-r--r--spec/ruby/core/module/constants_spec.rb20
-rw-r--r--spec/ruby/core/module/define_method_spec.rb155
-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/autoload_during_require_current_file.rb5
-rw-r--r--spec/ruby/core/module/fixtures/autoload_location.rb3
-rw-r--r--spec/ruby/core/module/fixtures/autoload_required_directly_no_constant.rb2
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb13
-rw-r--r--spec/ruby/core/module/fixtures/refine.rb12
-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/included_spec.rb2
-rw-r--r--spec/ruby/core/module/instance_method_spec.rb42
-rw-r--r--spec/ruby/core/module/method_added_spec.rb21
-rw-r--r--spec/ruby/core/module/method_defined_spec.rb92
-rw-r--r--spec/ruby/core/module/module_function_spec.rb40
-rw-r--r--spec/ruby/core/module/name_spec.rb50
-rw-r--r--spec/ruby/core/module/prepend_features_spec.rb14
-rw-r--r--spec/ruby/core/module/prepend_spec.rb422
-rw-r--r--spec/ruby/core/module/private_class_method_spec.rb12
-rw-r--r--spec/ruby/core/module/private_method_defined_spec.rb90
-rw-r--r--spec/ruby/core/module/private_spec.rb24
-rw-r--r--spec/ruby/core/module/protected_method_defined_spec.rb90
-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_method_defined_spec.rb2
-rw-r--r--spec/ruby/core/module/public_spec.rb25
-rw-r--r--spec/ruby/core/module/refine_spec.rb713
-rw-r--r--spec/ruby/core/module/remove_const_spec.rb21
-rw-r--r--spec/ruby/core/module/remove_method_spec.rb41
-rw-r--r--spec/ruby/core/module/ruby2_keywords_spec.rb319
-rw-r--r--spec/ruby/core/module/shared/class_eval.rb65
-rw-r--r--spec/ruby/core/module/shared/set_visibility.rb34
-rw-r--r--spec/ruby/core/module/singleton_class_spec.rb10
-rw-r--r--spec/ruby/core/module/to_s_spec.rb23
-rw-r--r--spec/ruby/core/module/undef_method_spec.rb19
-rw-r--r--spec/ruby/core/module/using_spec.rb90
-rw-r--r--spec/ruby/core/mutex/owned_spec.rb12
-rw-r--r--spec/ruby/core/nil/case_compare_spec.rb13
-rw-r--r--spec/ruby/core/nil/match_spec.rb28
-rw-r--r--spec/ruby/core/nil/nil_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_i_spec.rb2
-rw-r--r--spec/ruby/core/nil/to_s_spec.rb12
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb32
-rw-r--r--spec/ruby/core/numeric/dup_spec.rb16
-rw-r--r--spec/ruby/core/numeric/integer_spec.rb2
-rw-r--r--spec/ruby/core/numeric/negative_spec.rb4
-rw-r--r--spec/ruby/core/numeric/positive_spec.rb4
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb11
-rw-r--r--spec/ruby/core/numeric/real_spec.rb2
-rw-r--r--spec/ruby/core/numeric/shared/step.rb91
-rw-r--r--spec/ruby/core/numeric/step_spec.rb120
-rw-r--r--spec/ruby/core/numeric/zero_spec.rb4
-rw-r--r--spec/ruby/core/objectspace/_id2ref_spec.rb41
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb150
-rw-r--r--spec/ruby/core/objectspace/garbage_collect_spec.rb4
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_key_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_pair_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/each_value_spec.rb11
-rw-r--r--spec/ruby/core/objectspace/weakmap/element_reference_spec.rb24
-rw-r--r--spec/ruby/core/objectspace/weakmap/element_set_spec.rb38
-rw-r--r--spec/ruby/core/objectspace/weakmap/include_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/inspect_spec.rb25
-rw-r--r--spec/ruby/core/objectspace/weakmap/key_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/keys_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/length_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/member_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/each.rb10
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/include.rb30
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/members.rb14
-rw-r--r--spec/ruby/core/objectspace/weakmap/shared/size.rb14
-rw-r--r--spec/ruby/core/objectspace/weakmap/size_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap/values_spec.rb6
-rw-r--r--spec/ruby/core/objectspace/weakmap_spec.rb12
-rw-r--r--spec/ruby/core/proc/block_pass_spec.rb22
-rw-r--r--spec/ruby/core/proc/compose_spec.rb224
-rw-r--r--spec/ruby/core/proc/eql_spec.rb8
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb8
-rw-r--r--spec/ruby/core/proc/fixtures/source_location.rb2
-rw-r--r--spec/ruby/core/proc/hash_spec.rb2
-rw-r--r--spec/ruby/core/proc/lambda_spec.rb4
-rw-r--r--spec/ruby/core/proc/new_spec.rb51
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb31
-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/call_arguments.rb2
-rw-r--r--spec/ruby/core/proc/shared/compose.rb51
-rw-r--r--spec/ruby/core/proc/shared/equal.rb14
-rw-r--r--spec/ruby/core/proc/shared/to_s.rb17
-rw-r--r--spec/ruby/core/proc/source_location_spec.rb10
-rw-r--r--spec/ruby/core/process/_fork_spec.rb24
-rw-r--r--spec/ruby/core/process/clock_getres_spec.rb40
-rw-r--r--spec/ruby/core/process/clock_gettime_spec.rb101
-rw-r--r--spec/ruby/core/process/constants_spec.rb23
-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.rb14
-rw-r--r--spec/ruby/core/process/exec_spec.rb20
-rw-r--r--spec/ruby/core/process/fixtures/clocks.rb42
-rw-r--r--spec/ruby/core/process/getpriority_spec.rb8
-rw-r--r--spec/ruby/core/process/getrlimit_spec.rb13
-rw-r--r--spec/ruby/core/process/kill_spec.rb2
-rw-r--r--spec/ruby/core/process/last_status_spec.rb26
-rw-r--r--spec/ruby/core/process/maxgroups_spec.rb2
-rw-r--r--spec/ruby/core/process/pid_spec.rb2
-rw-r--r--spec/ruby/core/process/setrlimit_spec.rb13
-rw-r--r--spec/ruby/core/process/spawn_spec.rb122
-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.rb46
-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.rb42
-rw-r--r--spec/ruby/core/random/new_seed_spec.rb4
-rw-r--r--spec/ruby/core/random/new_spec.rb2
-rw-r--r--spec/ruby/core/random/rand_spec.rb11
-rw-r--r--spec/ruby/core/random/random_number_spec.rb4
-rw-r--r--spec/ruby/core/random/raw_seed_spec.rb9
-rw-r--r--spec/ruby/core/random/shared/urandom.rb23
-rw-r--r--spec/ruby/core/random/urandom_spec.rb26
-rw-r--r--spec/ruby/core/range/bsearch_spec.rb319
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb27
-rw-r--r--spec/ruby/core/range/clone_spec.rb26
-rw-r--r--spec/ruby/core/range/count_spec.rb12
-rw-r--r--spec/ruby/core/range/cover_spec.rb1
-rw-r--r--spec/ruby/core/range/dup_spec.rb14
-rw-r--r--spec/ruby/core/range/each_spec.rb68
-rw-r--r--spec/ruby/core/range/equal_value_spec.rb10
-rw-r--r--spec/ruby/core/range/exclude_end_spec.rb20
-rw-r--r--spec/ruby/core/range/first_spec.rb4
-rw-r--r--spec/ruby/core/range/frozen_spec.rb27
-rw-r--r--spec/ruby/core/range/hash_spec.rb10
-rw-r--r--spec/ruby/core/range/initialize_spec.rb15
-rw-r--r--spec/ruby/core/range/inspect_spec.rb26
-rw-r--r--spec/ruby/core/range/last_spec.rb12
-rw-r--r--spec/ruby/core/range/max_spec.rb21
-rw-r--r--spec/ruby/core/range/min_spec.rb16
-rw-r--r--spec/ruby/core/range/minmax_spec.rb132
-rw-r--r--spec/ruby/core/range/new_spec.rb60
-rw-r--r--spec/ruby/core/range/percent_spec.rb24
-rw-r--r--spec/ruby/core/range/shared/cover.rb138
-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.rb35
-rw-r--r--spec/ruby/core/range/step_spec.rb251
-rw-r--r--spec/ruby/core/range/to_a_spec.rb19
-rw-r--r--spec/ruby/core/range/to_s_spec.rb23
-rw-r--r--spec/ruby/core/rational/comparison_spec.rb2
-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/casefold_spec.rb4
-rw-r--r--spec/ruby/core/regexp/compile_spec.rb4
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb6
-rw-r--r--spec/ruby/core/regexp/last_match_spec.rb44
-rw-r--r--spec/ruby/core/regexp/new_spec.rb14
-rw-r--r--spec/ruby/core/regexp/options_spec.rb6
-rw-r--r--spec/ruby/core/regexp/shared/new.rb196
-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/regexp/union_spec.rb10
-rw-r--r--spec/ruby/core/signal/trap_spec.rb145
-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/bytes_spec.rb6
-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.rb35
-rw-r--r--spec/ruby/core/string/casecmp_spec.rb24
-rw-r--r--spec/ruby/core/string/center_spec.rb37
-rw-r--r--spec/ruby/core/string/chars_spec.rb7
-rw-r--r--spec/ruby/core/string/chomp_spec.rb93
-rw-r--r--spec/ruby/core/string/chop_spec.rb26
-rw-r--r--spec/ruby/core/string/clear_spec.rb6
-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.rb126
-rw-r--r--spec/ruby/core/string/delete_spec.rb31
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb126
-rw-r--r--spec/ruby/core/string/downcase_spec.rb28
-rw-r--r--spec/ruby/core/string/dump_spec.rb34
-rw-r--r--spec/ruby/core/string/dup_spec.rb13
-rw-r--r--spec/ruby/core/string/each_grapheme_cluster_spec.rb16
-rw-r--r--spec/ruby/core/string/element_set_spec.rb48
-rw-r--r--spec/ruby/core/string/empty_spec.rb10
-rw-r--r--spec/ruby/core/string/encode_spec.rb89
-rw-r--r--spec/ruby/core/string/encoding_spec.rb1
-rw-r--r--spec/ruby/core/string/end_with_spec.rb52
-rw-r--r--spec/ruby/core/string/fixtures/classes.rb11
-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.rb6
-rw-r--r--spec/ruby/core/string/grapheme_clusters_spec.rb14
-rw-r--r--spec/ruby/core/string/gsub_spec.rb221
-rw-r--r--spec/ruby/core/string/include_spec.rb14
-rw-r--r--spec/ruby/core/string/index_spec.rb11
-rw-r--r--spec/ruby/core/string/insert_spec.rb27
-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.rb37
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb59
-rw-r--r--spec/ruby/core/string/modulo_spec.rb77
-rw-r--r--spec/ruby/core/string/ord_spec.rb9
-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.rb16
-rw-r--r--spec/ruby/core/string/reverse_spec.rb47
-rw-r--r--spec/ruby/core/string/rindex_spec.rb23
-rw-r--r--spec/ruby/core/string/rjust_spec.rb37
-rw-r--r--spec/ruby/core/string/rpartition_spec.rb38
-rw-r--r--spec/ruby/core/string/rstrip_spec.rb67
-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.rb10
-rw-r--r--spec/ruby/core/string/shared/chars.rb14
-rw-r--r--spec/ruby/core/string/shared/codepoints.rb4
-rw-r--r--spec/ruby/core/string/shared/concat.rb24
-rw-r--r--spec/ruby/core/string/shared/dedup.rb57
-rw-r--r--spec/ruby/core/string/shared/each_line.rb60
-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.rb38
-rw-r--r--spec/ruby/core/string/shared/slice.rb271
-rw-r--r--spec/ruby/core/string/shared/strip.rb24
-rw-r--r--spec/ruby/core/string/shared/succ.rb30
-rw-r--r--spec/ruby/core/string/shared/to_s.rb7
-rw-r--r--spec/ruby/core/string/shared/to_sym.rb11
-rw-r--r--spec/ruby/core/string/slice_spec.rb221
-rw-r--r--spec/ruby/core/string/split_spec.rb309
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb33
-rw-r--r--spec/ruby/core/string/start_with_spec.rb74
-rw-r--r--spec/ruby/core/string/strip_spec.rb47
-rw-r--r--spec/ruby/core/string/sub_spec.rb173
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb30
-rw-r--r--spec/ruby/core/string/to_c_spec.rb108
-rw-r--r--spec/ruby/core/string/to_i_spec.rb18
-rw-r--r--spec/ruby/core/string/tr_s_spec.rb27
-rw-r--r--spec/ruby/core/string/tr_spec.rb27
-rw-r--r--spec/ruby/core/string/uminus_spec.rb72
-rw-r--r--spec/ruby/core/string/undump_spec.rb826
-rw-r--r--spec/ruby/core/string/unicode_normalized_spec.rb8
-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.rb19
-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.rb24
-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.rb28
-rw-r--r--spec/ruby/core/string/uplus_spec.rb2
-rw-r--r--spec/ruby/core/string/upto_spec.rb6
-rw-r--r--spec/ruby/core/string/valid_encoding/utf_8_spec.rb214
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb18
-rw-r--r--spec/ruby/core/struct/deconstruct_keys_spec.rb138
-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.rb22
-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.rb147
-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/all_symbols_spec.rb11
-rw-r--r--spec/ruby/core/symbol/casecmp_spec.rb2
-rw-r--r--spec/ruby/core/symbol/comparison_spec.rb2
-rw-r--r--spec/ruby/core/symbol/end_with_spec.rb8
-rw-r--r--spec/ruby/core/symbol/match_spec.rb17
-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.rb8
-rw-r--r--spec/ruby/core/symbol/to_proc_spec.rb39
-rw-r--r--spec/ruby/core/systemexit/success_spec.rb4
-rw-r--r--spec/ruby/core/thread/alive_spec.rb20
-rw-r--r--spec/ruby/core/thread/backtrace/limit_spec.rb15
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb91
-rw-r--r--spec/ruby/core/thread/backtrace/location/base_label_spec.rb27
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb2
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/path.rb2
-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/location/lineno_spec.rb10
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb35
-rw-r--r--spec/ruby/core/thread/backtrace_locations_spec.rb27
-rw-r--r--spec/ruby/core/thread/backtrace_spec.rb34
-rw-r--r--spec/ruby/core/thread/element_set_spec.rb4
-rw-r--r--spec/ruby/core/thread/exclusive_spec.rb66
-rw-r--r--spec/ruby/core/thread/fetch_spec.rb54
-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/join_spec.rb5
-rw-r--r--spec/ruby/core/thread/list_spec.rb4
-rw-r--r--spec/ruby/core/thread/native_thread_id_spec.rb17
-rw-r--r--spec/ruby/core/thread/new_spec.rb12
-rw-r--r--spec/ruby/core/thread/pending_interrupt_spec.rb32
-rw-r--r--spec/ruby/core/thread/raise_spec.rb26
-rw-r--r--spec/ruby/core/thread/report_on_exception_spec.rb75
-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/thread/stop_spec.rb20
-rw-r--r--spec/ruby/core/thread/to_s_spec.rb6
-rw-r--r--spec/ruby/core/time/_dump_spec.rb4
-rw-r--r--spec/ruby/core/time/at_spec.rb197
-rw-r--r--spec/ruby/core/time/ceil_spec.rb63
-rw-r--r--spec/ruby/core/time/dup_spec.rb4
-rw-r--r--spec/ruby/core/time/floor_spec.rb51
-rw-r--r--spec/ruby/core/time/friday_spec.rb4
-rw-r--r--spec/ruby/core/time/getlocal_spec.rb102
-rw-r--r--spec/ruby/core/time/gmt_spec.rb4
-rw-r--r--spec/ruby/core/time/hash_spec.rb4
-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.rb20
-rw-r--r--spec/ruby/core/time/monday_spec.rb4
-rw-r--r--spec/ruby/core/time/new_spec.rb443
-rw-r--r--spec/ruby/core/time/now_spec.rb45
-rw-r--r--spec/ruby/core/time/plus_spec.rb20
-rw-r--r--spec/ruby/core/time/saturday_spec.rb4
-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.rb22
-rw-r--r--spec/ruby/core/time/shared/time_params.rb11
-rw-r--r--spec/ruby/core/time/shared/to_i.rb7
-rw-r--r--spec/ruby/core/time/strftime_spec.rb41
-rw-r--r--spec/ruby/core/time/subsec_spec.rb2
-rw-r--r--spec/ruby/core/time/succ_spec.rb46
-rw-r--r--spec/ruby/core/time/sunday_spec.rb4
-rw-r--r--spec/ruby/core/time/thursday_spec.rb4
-rw-r--r--spec/ruby/core/time/tuesday_spec.rb4
-rw-r--r--spec/ruby/core/time/utc_spec.rb39
-rw-r--r--spec/ruby/core/time/wednesday_spec.rb4
-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/binding_spec.rb2
-rw-r--r--spec/ruby/core/tracepoint/callee_id_spec.rb1
-rw-r--r--spec/ruby/core/tracepoint/defined_class_spec.rb1
-rw-r--r--spec/ruby/core/tracepoint/disable_spec.rb9
-rw-r--r--spec/ruby/core/tracepoint/enable_spec.rb658
-rw-r--r--spec/ruby/core/tracepoint/enabled_spec.rb5
-rw-r--r--spec/ruby/core/tracepoint/eval_script_spec.rb29
-rw-r--r--spec/ruby/core/tracepoint/event_spec.rb1
-rw-r--r--spec/ruby/core/tracepoint/fixtures/classes.rb6
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb122
-rw-r--r--spec/ruby/core/tracepoint/lineno_spec.rb14
-rw-r--r--spec/ruby/core/tracepoint/method_id_spec.rb10
-rw-r--r--spec/ruby/core/tracepoint/new_spec.rb21
-rw-r--r--spec/ruby/core/tracepoint/parameters_spec.rb37
-rw-r--r--spec/ruby/core/tracepoint/path_spec.rb16
-rw-r--r--spec/ruby/core/tracepoint/raised_exception_spec.rb6
-rw-r--r--spec/ruby/core/tracepoint/return_value_spec.rb6
-rw-r--r--spec/ruby/core/tracepoint/self_spec.rb10
-rw-r--r--spec/ruby/core/tracepoint/trace_spec.rb3
-rw-r--r--spec/ruby/core/true/case_compare_spec.rb13
-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.rb21
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb4
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb23
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb20
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb35
-rw-r--r--spec/ruby/core/warning/warn_spec.rb26
-rw-r--r--spec/ruby/default.mspec1
-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/code_loading.rb15
-rw-r--r--spec/ruby/fixtures/constants.rb39
-rw-r--r--spec/ruby/language/BEGIN_spec.rb5
-rw-r--r--spec/ruby/language/README2
-rw-r--r--spec/ruby/language/alias_spec.rb15
-rw-r--r--spec/ruby/language/block_spec.rb253
-rw-r--r--spec/ruby/language/break_spec.rb18
-rw-r--r--spec/ruby/language/case_spec.rb22
-rw-r--r--spec/ruby/language/class_spec.rb27
-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.rb189
-rw-r--r--spec/ruby/language/def_spec.rb80
-rw-r--r--spec/ruby/language/defined_spec.rb107
-rw-r--r--spec/ruby/language/delegation_spec.rb65
-rw-r--r--spec/ruby/language/ensure_spec.rb108
-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/delegation.rb11
-rw-r--r--spec/ruby/language/fixtures/freeze_magic_comment_two_literals.rb2
-rw-r--r--spec/ruby/language/fixtures/rescue_captures.rb107
-rw-r--r--spec/ruby/language/fixtures/return.rb8
-rw-r--r--spec/ruby/language/fixtures/squiggly_heredoc.rb32
-rw-r--r--spec/ruby/language/fixtures/super.rb46
-rw-r--r--spec/ruby/language/hash_spec.rb121
-rw-r--r--spec/ruby/language/heredoc_spec.rb18
-rw-r--r--spec/ruby/language/keyword_arguments_spec.rb397
-rw-r--r--spec/ruby/language/lambda_spec.rb89
-rw-r--r--spec/ruby/language/method_spec.rb528
-rw-r--r--spec/ruby/language/module_spec.rb35
-rw-r--r--spec/ruby/language/numbered_parameters_spec.rb143
-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.rb1915
-rw-r--r--spec/ruby/language/precedence_spec.rb78
-rw-r--r--spec/ruby/language/predefined_spec.rb545
-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.rb87
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb11
-rw-r--r--spec/ruby/language/regexp/empty_checks_spec.rb135
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb29
-rw-r--r--spec/ruby/language/regexp/escapes_spec.rb100
-rw-r--r--spec/ruby/language/regexp/grouping_spec.rb40
-rw-r--r--spec/ruby/language/regexp/interpolation_spec.rb2
-rw-r--r--spec/ruby/language/regexp/repetition_spec.rb94
-rw-r--r--spec/ruby/language/regexp/subexpression_call_spec.rb50
-rw-r--r--spec/ruby/language/regexp_spec.rb32
-rw-r--r--spec/ruby/language/rescue_spec.rb124
-rw-r--r--spec/ruby/language/return_spec.rb385
-rw-r--r--spec/ruby/language/safe_spec.rb141
-rw-r--r--spec/ruby/language/send_spec.rb54
-rw-r--r--spec/ruby/language/singleton_class_spec.rb4
-rw-r--r--spec/ruby/language/source_encoding_spec.rb4
-rw-r--r--spec/ruby/language/string_spec.rb80
-rw-r--r--spec/ruby/language/super_spec.rb46
-rw-r--r--spec/ruby/language/variables_spec.rb118
-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.rb110
-rw-r--r--spec/ruby/library/bigdecimal/abs_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/add_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/comparison_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/constants_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/div_spec.rb16
-rw-r--r--spec/ruby/library/bigdecimal/divmod_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/exponent_spec.rb11
-rw-r--r--spec/ruby/library/bigdecimal/finite_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/fix_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/frac_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/gt_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/gte_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/lt_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/lte_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/minus_spec.rb18
-rw-r--r--spec/ruby/library/bigdecimal/mode_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/nan_spec.rb22
-rw-r--r--spec/ruby/library/bigdecimal/plus_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/precs_spec.rb39
-rw-r--r--spec/ruby/library/bigdecimal/quo_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/remainder_spec.rb38
-rw-r--r--spec/ruby/library/bigdecimal/round_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/shared/clone.rb17
-rw-r--r--spec/ruby/library/bigdecimal/shared/modulo.rb28
-rw-r--r--spec/ruby/library/bigdecimal/shared/mult.rb20
-rw-r--r--spec/ruby/library/bigdecimal/shared/power.rb4
-rw-r--r--spec/ruby/library/bigdecimal/shared/quo.rb10
-rw-r--r--spec/ruby/library/bigdecimal/shared/to_int.rb2
-rw-r--r--spec/ruby/library/bigdecimal/sub_spec.rb8
-rw-r--r--spec/ruby/library/bigdecimal/to_f_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/to_r_spec.rb12
-rw-r--r--spec/ruby/library/bigdecimal/to_s_spec.rb16
-rw-r--r--spec/ruby/library/bigdecimal/truncate_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/uminus_spec.rb2
-rw-r--r--spec/ruby/library/bigdecimal/util_spec.rb6
-rw-r--r--spec/ruby/library/bigdecimal/zero_spec.rb26
-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/cgi/cookie/to_s_spec.rb13
-rw-r--r--spec/ruby/library/cgi/escapeHTML_spec.rb4
-rw-r--r--spec/ruby/library/cgi/escape_spec.rb16
-rw-r--r--spec/ruby/library/cgi/unescapeHTML_spec.rb5
-rw-r--r--spec/ruby/library/cgi/unescape_spec.rb4
-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/conditionvariable/signal_spec.rb77
-rw-r--r--spec/ruby/library/conditionvariable/wait_spec.rb177
-rw-r--r--spec/ruby/library/coverage/fixtures/eval_code.rb11
-rw-r--r--spec/ruby/library/coverage/result_spec.rb73
-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/csv/liberal_parsing_spec.rb6
-rw-r--r--spec/ruby/library/date/civil_spec.rb7
-rw-r--r--spec/ruby/library/date/constants_spec.rb4
-rw-r--r--spec/ruby/library/date/gregorian_spec.rb2
-rw-r--r--spec/ruby/library/date/infinity_spec.rb14
-rw-r--r--spec/ruby/library/date/iso8601_spec.rb9
-rw-r--r--spec/ruby/library/date/julian_spec.rb4
-rw-r--r--spec/ruby/library/date/parse_spec.rb19
-rw-r--r--spec/ruby/library/date/shared/civil.rb8
-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/eql_spec.rb55
-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/digest/bubblebabble_spec.rb2
-rw-r--r--spec/ruby/library/digest/hexencode_spec.rb2
-rw-r--r--spec/ruby/library/digest/instance/append_spec.rb7
-rw-r--r--spec/ruby/library/digest/instance/new_spec.rb19
-rw-r--r--spec/ruby/library/digest/instance/shared/update.rb8
-rw-r--r--spec/ruby/library/digest/instance/update_spec.rb7
-rw-r--r--spec/ruby/library/digest/sha2/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha256/file_spec.rb4
-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/erb/util/shared/url_encode.rb16
-rw-r--r--spec/ruby/library/etc/getgrgid_spec.rb7
-rw-r--r--spec/ruby/library/etc/struct_group_spec.rb2
-rw-r--r--spec/ruby/library/etc/struct_passwd_spec.rb2
-rw-r--r--spec/ruby/library/fiber/current_spec.rb16
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb33
-rw-r--r--spec/ruby/library/fiber/transfer_spec.rb56
-rw-r--r--spec/ruby/library/fiddle/handle/initialize_spec.rb10
-rw-r--r--spec/ruby/library/getoptlong/shared/get.rb10
-rw-r--r--spec/ruby/library/getoptlong/terminated_spec.rb6
-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/ipv4_conversion_spec.rb8
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb49
-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/logger/logger/debug_spec.rb4
-rw-r--r--spec/ruby/library/logger/logger/error_spec.rb4
-rw-r--r--spec/ruby/library/logger/logger/fatal_spec.rb4
-rw-r--r--spec/ruby/library/logger/logger/info_spec.rb4
-rw-r--r--spec/ruby/library/logger/logger/warn_spec.rb4
-rw-r--r--spec/ruby/library/mathn/bignum/exponent_spec.rb21
-rw-r--r--spec/ruby/library/mathn/complex/Complex_spec.rb14
-rw-r--r--spec/ruby/library/mathn/fixnum/exponent_spec.rb17
-rw-r--r--spec/ruby/library/mathn/float/exponent_spec.rb17
-rw-r--r--spec/ruby/library/mathn/integer/from_prime_division_spec.rb11
-rw-r--r--spec/ruby/library/mathn/integer/prime_division_spec.rb21
-rw-r--r--spec/ruby/library/mathn/math/fixtures/classes.rb3
-rw-r--r--spec/ruby/library/mathn/math/rsqrt_spec.rb17
-rw-r--r--spec/ruby/library/mathn/math/shared/rsqrt.rb21
-rw-r--r--spec/ruby/library/mathn/math/shared/sqrt.rb25
-rw-r--r--spec/ruby/library/mathn/math/sqrt_spec.rb17
-rw-r--r--spec/ruby/library/mathn/mathn_spec.rb13
-rw-r--r--spec/ruby/library/mathn/rational/Rational_spec.rb14
-rw-r--r--spec/ruby/library/mathn/rational/inspect_spec.rb15
-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.rb50
-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.rb559
-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/get2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/get_spec.rb72
-rw-r--r--spec/ruby/library/net/http/http/head2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/post2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/post_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/put2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_get_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_head_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_post_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_put_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/send_request_spec.rb4
-rw-r--r--spec/ruby/library/net/http/http/shared/request_get.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_head.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_post.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_put.rb2
-rw-r--r--spec/ruby/library/net/http/httpresponse/body_permitted_spec.rb12
-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.rb6
-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/config/freeze_spec.rb26
-rw-r--r--spec/ruby/library/openssl/hmac/digest_spec.rb2
-rw-r--r--spec/ruby/library/openssl/hmac/hexdigest_spec.rb2
-rw-r--r--spec/ruby/library/openssl/x509/name/verify_spec.rb78
-rw-r--r--spec/ruby/library/openstruct/frozen_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/marshal_load_spec.rb2
-rw-r--r--spec/ruby/library/openstruct/method_missing_spec.rb35
-rw-r--r--spec/ruby/library/openstruct/to_h_spec.rb60
-rw-r--r--spec/ruby/library/pathname/absolute_spec.rb8
-rw-r--r--spec/ruby/library/pathname/birthtime_spec.rb16
-rw-r--r--spec/ruby/library/pathname/divide_spec.rb6
-rw-r--r--spec/ruby/library/pathname/glob_spec.rb84
-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/pathname/plus_spec.rb6
-rw-r--r--spec/ruby/library/pathname/relative_spec.rb8
-rw-r--r--spec/ruby/library/pathname/root_spec.rb10
-rw-r--r--spec/ruby/library/pathname/shared/plus.rb8
-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.rb53
-rw-r--r--spec/ruby/library/rbconfig/sizeof/limits_spec.rb58
-rw-r--r--spec/ruby/library/rbconfig/unicode_emoji_version_spec.rb19
-rw-r--r--spec/ruby/library/rbconfig/unicode_version_spec.rb31
-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/attribute/clone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/equal_value_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/hash_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/initialize_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/inspect_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/namespace_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/node_type_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/prefix_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/remove_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/to_s_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/to_string_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/value_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/write_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attribute/xpath_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/add_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/append_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/delete_all_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/delete_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/each_attribute_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/each_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/element_set_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_ns_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/get_attribute_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/initialize_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/length_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/namespaces_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/prefixes_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/size_spec.rb2
-rw-r--r--spec/ruby/library/rexml/attributes/to_a_spec.rb2
-rw-r--r--spec/ruby/library/rexml/cdata/clone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/cdata/initialize_spec.rb2
-rw-r--r--spec/ruby/library/rexml/cdata/to_s_spec.rb2
-rw-r--r--spec/ruby/library/rexml/cdata/value_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/add_element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/add_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/clone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/doctype_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/encoding_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/expanded_name_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/new_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/node_type_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/root_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/stand_alone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/version_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/write_spec.rb2
-rw-r--r--spec/ruby/library/rexml/document/xml_decl_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/add_attribute_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/add_attributes_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/add_element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/add_namespace_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/add_text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/attribute_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/attributes_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/cdatas_spec.rb4
-rw-r--r--spec/ruby/library/rexml/element/clone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/comments_spec.rb4
-rw-r--r--spec/ruby/library/rexml/element/delete_attribute_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/delete_element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/delete_namespace_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/document_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb20
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb6
-rw-r--r--spec/ruby/library/rexml/element/element_reference_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/get_text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/has_attributes_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/has_elements_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb4
-rw-r--r--spec/ruby/library/rexml/element/inspect_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/instructions_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/namespace_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/namespaces_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/new_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/next_element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/node_type_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/prefixes_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/previous_element_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/raw_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/root_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/texts_spec.rb2
-rw-r--r--spec/ruby/library/rexml/element/whitespace_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/each_recursive_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/find_first_recursive_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/index_in_parent_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/next_sibling_node_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb10
-rw-r--r--spec/ruby/library/rexml/node/previous_sibling_node_spec.rb2
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb2
-rw-r--r--spec/ruby/library/rexml/text/append_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/clone_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/comparison_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/empty_spec.rb6
-rw-r--r--spec/ruby/library/rexml/text/indent_text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/inspect_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/new_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/node_type_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/normalize_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/read_with_substitution_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/to_s_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/unnormalize_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/value_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/wrap_spec.rb2
-rw-r--r--spec/ruby/library/rexml/text/write_with_substitution_spec.rb2
-rw-r--r--spec/ruby/library/ripper/lex_spec.rb23
-rw-r--r--spec/ruby/library/ripper/sexp_spec.rb13
-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/securerandom/random_number_spec.rb2
-rw-r--r--spec/ruby/library/set/case_compare_spec.rb12
-rw-r--r--spec/ruby/library/set/case_equality_spec.rb6
-rw-r--r--spec/ruby/library/set/compare_by_identity_spec.rb16
-rw-r--r--spec/ruby/library/set/comparison_spec.rb29
-rw-r--r--spec/ruby/library/set/enumerable/to_set_spec.rb10
-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/add_spec.rb59
-rw-r--r--spec/ruby/library/set/sortedset/append_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/case_equality_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/classify_spec.rb41
-rw-r--r--spec/ruby/library/set/sortedset/clear_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/collect_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/constructor_spec.rb21
-rw-r--r--spec/ruby/library/set/sortedset/delete_if_spec.rb57
-rw-r--r--spec/ruby/library/set/sortedset/delete_spec.rb55
-rw-r--r--spec/ruby/library/set/sortedset/difference_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/divide_spec.rb53
-rw-r--r--spec/ruby/library/set/sortedset/each_spec.rb39
-rw-r--r--spec/ruby/library/set/sortedset/empty_spec.rb15
-rw-r--r--spec/ruby/library/set/sortedset/eql_spec.rb23
-rw-r--r--spec/ruby/library/set/sortedset/equal_value_spec.rb19
-rw-r--r--spec/ruby/library/set/sortedset/exclusion_spec.rb27
-rw-r--r--spec/ruby/library/set/sortedset/filter_spec.rb7
-rw-r--r--spec/ruby/library/set/sortedset/flatten_merge_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/flatten_spec.rb67
-rw-r--r--spec/ruby/library/set/sortedset/hash_spec.rb19
-rw-r--r--spec/ruby/library/set/sortedset/include_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/initialize_spec.rb49
-rw-r--r--spec/ruby/library/set/sortedset/inspect_spec.rb15
-rw-r--r--spec/ruby/library/set/sortedset/intersection_spec.rb17
-rw-r--r--spec/ruby/library/set/sortedset/keep_if_spec.rb47
-rw-r--r--spec/ruby/library/set/sortedset/length_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/map_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/member_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/merge_spec.rb29
-rw-r--r--spec/ruby/library/set/sortedset/minus_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/plus_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_cycle_spec.rb15
-rw-r--r--spec/ruby/library/set/sortedset/pretty_print_spec.rb23
-rw-r--r--spec/ruby/library/set/sortedset/proper_subset_spec.rb51
-rw-r--r--spec/ruby/library/set/sortedset/proper_superset_spec.rb51
-rw-r--r--spec/ruby/library/set/sortedset/reject_spec.rb63
-rw-r--r--spec/ruby/library/set/sortedset/replace_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/select_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/size_spec.rb11
-rw-r--r--spec/ruby/library/set/sortedset/sortedset_spec.rb22
-rw-r--r--spec/ruby/library/set/sortedset/subset_spec.rb51
-rw-r--r--spec/ruby/library/set/sortedset/subtract_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/superset_spec.rb51
-rw-r--r--spec/ruby/library/set/sortedset/to_a_spec.rb25
-rw-r--r--spec/ruby/library/set/sortedset/union_spec.rb17
-rw-r--r--spec/ruby/library/set/to_s_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/initialize_spec.rb2
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_loopback_spec.rb8
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_multicast_spec.rb10
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv4_private_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_linklocal_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_global_spec.rb16
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_linklocal_spec.rb14
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_nodelocal_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_orglocal_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_mc_sitelocal_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_multicast_spec.rb20
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_sitelocal_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_unique_local_spec.rb12
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_unspecified_spec.rb6
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_v4compat_spec.rb10
-rw-r--r--spec/ruby/library/socket/addrinfo/ipv6_v4mapped_spec.rb10
-rw-r--r--spec/ruby/library/socket/addrinfo/listen_spec.rb2
-rw-r--r--spec/ruby/library/socket/basicsocket/local_address_spec.rb10
-rw-r--r--spec/ruby/library/socket/basicsocket/read_nonblock_spec.rb64
-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/basicsocket/write_nonblock_spec.rb62
-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/gethostbyaddr_spec.rb22
-rw-r--r--spec/ruby/library/socket/socket/gethostbyname_spec.rb16
-rw-r--r--spec/ruby/library/socket/socket/listen_spec.rb6
-rw-r--r--spec/ruby/library/socket/socket/tcp_server_sockets_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/tcp_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/udp_server_loop_spec.rb4
-rw-r--r--spec/ruby/library/socket/socket/udp_server_sockets_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/unix_spec.rb2
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb2
-rw-r--r--spec/ruby/library/socket/tcpserver/accept_spec.rb20
-rw-r--r--spec/ruby/library/socket/tcpsocket/gethostbyname_spec.rb16
-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/inspect_spec.rb14
-rw-r--r--spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb7
-rw-r--r--spec/ruby/library/socket/unixsocket/open_spec.rb2
-rw-r--r--spec/ruby/library/socket/unixsocket/shared/new.rb2
-rw-r--r--spec/ruby/library/stringio/append_spec.rb9
-rw-r--r--spec/ruby/library/stringio/binmode_spec.rb14
-rw-r--r--spec/ruby/library/stringio/bytes_spec.rb28
-rw-r--r--spec/ruby/library/stringio/chars_spec.rb28
-rw-r--r--spec/ruby/library/stringio/codepoints_spec.rb16
-rw-r--r--spec/ruby/library/stringio/each_char_spec.rb2
-rw-r--r--spec/ruby/library/stringio/each_codepoint_spec.rb2
-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/getpass_spec.rb11
-rw-r--r--spec/ruby/library/stringio/gets_spec.rb4
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb110
-rw-r--r--spec/ruby/library/stringio/inspect_spec.rb19
-rw-r--r--spec/ruby/library/stringio/lines_spec.rb56
-rw-r--r--spec/ruby/library/stringio/new_spec.rb8
-rw-r--r--spec/ruby/library/stringio/open_spec.rb16
-rw-r--r--spec/ruby/library/stringio/printf_spec.rb29
-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.rb27
-rw-r--r--spec/ruby/library/stringio/shared/each.rb58
-rw-r--r--spec/ruby/library/stringio/shared/read.rb10
-rw-r--r--spec/ruby/library/stringio/shared/write.rb42
-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/append_spec.rb2
-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/concat_spec.rb2
-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/syslog/close_spec.rb2
-rw-r--r--spec/ruby/library/syslog/ident_spec.rb2
-rw-r--r--spec/ruby/library/syslog/log_spec.rb6
-rw-r--r--spec/ruby/library/syslog/mask_spec.rb2
-rw-r--r--spec/ruby/library/syslog/shared/log.rb7
-rw-r--r--spec/ruby/library/time/to_datetime_spec.rb18
-rw-r--r--spec/ruby/library/timeout/timeout_spec.rb16
-rw-r--r--spec/ruby/library/weakref/fixtures/classes.rb6
-rw-r--r--spec/ruby/library/weakref/weakref_alive_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_param/input_spec.rb2
-rw-r--r--spec/ruby/library/win32ole/win32ole_variable/value_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_builtin_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_domain_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_private_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/add_ruby_type_spec.rb2
-rw-r--r--spec/ruby/library/yaml/detect_implicit_spec.rb2
-rw-r--r--spec/ruby/library/yaml/dump_spec.rb7
-rw-r--r--spec/ruby/library/yaml/each_node_spec.rb2
-rw-r--r--spec/ruby/library/yaml/emitter_spec.rb2
-rw-r--r--spec/ruby/library/yaml/fixtures/common.rb6
-rw-r--r--spec/ruby/library/yaml/generic_parser_spec.rb2
-rw-r--r--spec/ruby/library/yaml/load_documents_spec.rb10
-rw-r--r--spec/ruby/library/yaml/load_spec.rb135
-rw-r--r--spec/ruby/library/yaml/object_maker_spec.rb2
-rw-r--r--spec/ruby/library/yaml/parse_documents_spec.rb2
-rw-r--r--spec/ruby/library/yaml/parser_spec.rb2
-rw-r--r--spec/ruby/library/yaml/quick_emit_spec.rb2
-rw-r--r--spec/ruby/library/yaml/read_type_class_spec.rb2
-rw-r--r--spec/ruby/library/yaml/shared/load.rb136
-rw-r--r--spec/ruby/library/yaml/tagurize_spec.rb11
-rw-r--r--spec/ruby/library/yaml/to_yaml_spec.rb12
-rw-r--r--spec/ruby/library/yaml/transfer_spec.rb2
-rw-r--r--spec/ruby/library/yaml/try_implicit_spec.rb2
-rw-r--r--spec/ruby/library/yaml/unsafe_load_spec.rb9
-rw-r--r--spec/ruby/library/zlib/adler32_spec.rb2
-rw-r--r--spec/ruby/library/zlib/crc32_spec.rb2
-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/gzipfile/close_spec.rb2
-rw-r--r--spec/ruby/library/zlib/gzipfile/closed_spec.rb4
-rw-r--r--spec/ruby/library/zlib/inflate/inflate_spec.rb7
-rw-r--r--spec/ruby/library/zlib/zstream/flush_next_out_spec.rb2
-rw-r--r--spec/ruby/optional/capi/README9
-rw-r--r--spec/ruby/optional/capi/array_spec.rb46
-rw-r--r--spec/ruby/optional/capi/basic_object_spec.rb24
-rw-r--r--spec/ruby/optional/capi/bignum_spec.rb6
-rw-r--r--spec/ruby/optional/capi/binding_spec.rb28
-rw-r--r--spec/ruby/optional/capi/class_spec.rb136
-rw-r--r--spec/ruby/optional/capi/constants_spec.rb105
-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.rb238
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb89
-rw-r--r--spec/ruby/optional/capi/ext/array_spec.c38
-rw-r--r--spec/ruby/optional/capi/ext/basic_object_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/bignum_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/binding_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/boolean_spec.c2
-rw-r--r--spec/ruby/optional/capi/ext/class_id_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c61
-rw-r--r--spec/ruby/optional/capi/ext/class_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/constants_spec.c383
-rw-r--r--spec/ruby/optional/capi/ext/data_spec.c14
-rw-r--r--spec/ruby/optional/capi/ext/debug_spec.c93
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c137
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c13
-rw-r--r--spec/ruby/optional/capi/ext/fiber_spec.c69
-rw-r--r--spec/ruby/optional/capi/ext/float_spec.c9
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c46
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c47
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c7
-rw-r--r--spec/ruby/optional/capi/ext/integer_spec.c9
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c62
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c65
-rw-r--r--spec/ruby/optional/capi/ext/language_spec.c42
-rw-r--r--spec/ruby/optional/capi/ext/module_spec.c41
-rw-r--r--spec/ruby/optional/capi/ext/module_under_autoload_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/numeric_spec.c7
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c81
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c64
-rw-r--r--spec/ruby/optional/capi/ext/rbasic_spec.c100
-rw-r--r--spec/ruby/optional/capi/ext/regexp_spec.c27
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h17
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c226
-rw-r--r--spec/ruby/optional/capi/ext/struct_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/symbol_spec.c21
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c44
-rw-r--r--spec/ruby/optional/capi/ext/tracepoint_spec.c49
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c72
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c36
-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/float_spec.rb13
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb50
-rw-r--r--spec/ruby/optional/capi/globals_spec.rb79
-rw-r--r--spec/ruby/optional/capi/hash_spec.rb10
-rw-r--r--spec/ruby/optional/capi/integer_spec.rb15
-rw-r--r--spec/ruby/optional/capi/io_spec.rb41
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb207
-rw-r--r--spec/ruby/optional/capi/language_spec.rb37
-rw-r--r--spec/ruby/optional/capi/module_spec.rb67
-rw-r--r--spec/ruby/optional/capi/numeric_spec.rb72
-rw-r--r--spec/ruby/optional/capi/object_spec.rb216
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb79
-rw-r--r--spec/ruby/optional/capi/rbasic_spec.rb42
-rw-r--r--spec/ruby/optional/capi/regexp_spec.rb59
-rw-r--r--spec/ruby/optional/capi/shared/rbasic.rb29
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb45
-rw-r--r--spec/ruby/optional/capi/string_spec.rb385
-rw-r--r--spec/ruby/optional/capi/struct_spec.rb6
-rw-r--r--spec/ruby/optional/capi/symbol_spec.rb34
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb52
-rw-r--r--spec/ruby/optional/capi/time_spec.rb84
-rw-r--r--spec/ruby/optional/capi/tracepoint_spec.rb56
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb28
-rw-r--r--spec/ruby/optional/capi/util_spec.rb64
-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.rb3
-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_2018_8780_spec.rb20
-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.rb39
-rw-r--r--spec/ruby/shared/enumerable/minmax.rb24
-rw-r--r--spec/ruby/shared/enumerator/enum_for.rb7
-rw-r--r--spec/ruby/shared/fiber/resume.rb21
-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/identical.rb6
-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/world_readable.rb12
-rw-r--r--spec/ruby/shared/file/world_writable.rb12
-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/hash/key_error.rb28
-rw-r--r--spec/ruby/shared/io/putc.rb2
-rw-r--r--spec/ruby/shared/kernel/complex.rb133
-rw-r--r--spec/ruby/shared/kernel/raise.rb120
-rw-r--r--spec/ruby/shared/process/exit.rb32
-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/arithmetic_exception_in_coerce.rb32
-rw-r--r--spec/ruby/shared/rational/coerce.rb5
-rw-r--r--spec/ruby/shared/rational/comparison.rb30
-rw-r--r--spec/ruby/shared/rational/divmod.rb6
-rw-r--r--spec/ruby/shared/rational/exponent.rb44
-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.rb61
-rw-r--r--spec/ruby/shared/string/start_with.rb76
-rw-r--r--spec/ruby/shared/string/times.rb28
-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.c1386
-rw-r--r--st.c981
-rw-r--r--strftime.c29
-rw-r--r--string.c10072
-rw-r--r--string.rb552
-rw-r--r--struct.c1793
-rw-r--r--symbol.c914
-rw-r--r--symbol.h27
-rw-r--r--symbol.rb15
-rw-r--r--template/Doxyfile.tmpl2544
-rw-r--r--template/GNUmakefile.in23
-rw-r--r--template/Makefile.in263
-rw-r--r--template/builtin_binary.inc.tmpl30
-rw-r--r--template/call_iseq_optimized.inc.tmpl68
-rw-r--r--template/configure-ext.mk.tmpl6
-rw-r--r--template/encdb.h.tmpl17
-rw-r--r--template/extinit.c.tmpl2
-rw-r--r--template/exts.mk.tmpl22
-rw-r--r--template/fake.rb.in39
-rw-r--r--template/id.c.tmpl7
-rw-r--r--template/id.h.tmpl10
-rw-r--r--template/prelude.c.tmpl159
-rwxr-xr-xtemplate/ruby-gdb.in6
-rwxr-xr-xtemplate/ruby-lldb.in6
-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.rb74
-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.rb14
-rw-r--r--test/-ext-/string/test_ellipsize.rb2
-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_interned_str.rb12
-rw-r--r--test/-ext-/string/test_normalize.rb8
-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_inadvertent_creation.rb8
-rw-r--r--test/-ext-/symbol/test_type.rb14
-rw-r--r--test/-ext-/test_abi.rb47
-rw-r--r--test/-ext-/test_notimplement.rb7
-rw-r--r--test/-ext-/test_printf.rb4
-rw-r--r--test/-ext-/test_random.rb45
-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-/tracepoint/test_tracepoint.rb12
-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.rb461
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb60
-rw-r--r--test/bigdecimal/test_bigmath.rb2
-rw-r--r--test/bigdecimal/test_ractor.rb23
-rw-r--r--test/bigdecimal/testbase.rb28
-rw-r--r--test/cgi/test_cgi_cookie.rb90
-rw-r--r--test/cgi/test_cgi_core.rb4
-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.rb251
-rw-r--r--test/csv/helper.rb24
-rw-r--r--test/csv/interface/test_read.rb110
-rw-r--r--test/csv/interface/test_read_write.rb76
-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_skip_lines.rb13
-rw-r--r--test/csv/parse/test_strip.rb34
-rw-r--r--test/csv/test_data_converters.rb84
-rw-r--r--test/csv/test_encodings.rb53
-rw-r--r--test/csv/test_patterns.rb27
-rw-r--r--test/csv/test_row.rb3
-rw-r--r--test/csv/test_table.rb77
-rw-r--r--test/csv/write/test_converters.rb8
-rw-r--r--test/csv/write/test_force_quotes.rb78
-rw-r--r--test/csv/write/test_general.rb16
-rw-r--r--test/date/test_date.rb41
-rw-r--r--test/date/test_date_conv.rb17
-rw-r--r--test/date/test_date_marshal.rb7
-rw-r--r--test/date/test_date_parse.rb85
-rw-r--r--test/date/test_date_ractor.rb27
-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.rb43
-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.rb32
-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_tree_spell_checker.rb203
-rw-r--r--test/did_you_mean/test_verbose_formatter.rb22
-rw-r--r--test/did_you_mean/tree_spell/human_typo.rb34
-rw-r--r--test/did_you_mean/tree_spell/test_change_word.rb2
-rw-r--r--test/digest/test_digest.rb8
-rw-r--r--test/digest/test_digest_extend.rb13
-rw-r--r--test/digest/test_ractor.rb97
-rw-r--r--test/drb/drbtest.rb8
-rw-r--r--test/drb/test_drb.rb13
-rw-r--r--test/drb/test_drbssl.rb11
-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.rb24
-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.rb54
-rw-r--r--test/fiber/scheduler.rb363
-rw-r--r--test/fiber/test_address_resolve.rb278
-rw-r--r--test/fiber/test_backtrace.rb22
-rw-r--r--test/fiber/test_enumerator.rb53
-rw-r--r--test/fiber/test_io.rb222
-rw-r--r--test/fiber/test_io_buffer.rb158
-rw-r--r--test/fiber/test_mutex.rb240
-rw-r--r--test/fiber/test_process.rb72
-rw-r--r--test/fiber/test_queue.rb54
-rw-r--r--test/fiber/test_ractor.rb23
-rw-r--r--test/fiber/test_scheduler.rb226
-rw-r--r--test/fiber/test_sleep.rb71
-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.rb58
-rw-r--r--test/fiddle/test_c_struct_builder.rb69
-rw-r--r--test/fiddle/test_c_struct_entry.rb130
-rw-r--r--test/fiddle/test_c_union_entity.rb15
-rw-r--r--test/fiddle/test_closure.rb106
-rw-r--r--test/fiddle/test_cparser.rb169
-rw-r--r--test/fiddle/test_fiddle.rb41
-rw-r--r--test/fiddle/test_func.rb108
-rw-r--r--test/fiddle/test_function.rb146
-rw-r--r--test/fiddle/test_handle.rb42
-rw-r--r--test/fiddle/test_import.rb395
-rw-r--r--test/fiddle/test_memory_view.rb143
-rw-r--r--test/fiddle/test_pack.rb37
-rw-r--r--test/fiddle/test_pinned.rb28
-rw-r--r--test/fiddle/test_pointer.rb119
-rw-r--r--test/fileutils/clobber.rb5
-rw-r--r--test/fileutils/test_dryrun.rb2
-rw-r--r--test/fileutils/test_fileutils.rb148
-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/fixtures/fake_sorted_set_gem/sorted_set.rb9
-rw-r--r--test/gdbm/test_gdbm.rb734
-rw-r--r--test/io/console/test_io_console.rb101
-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.rb39
-rw-r--r--test/io/wait/test_ractor.rb17
-rw-r--r--test/irb/helper.rb76
-rw-r--r--test/irb/test_cmd.rb692
-rw-r--r--test/irb/test_color.rb166
-rw-r--r--test/irb/test_color_printer.rb69
-rw-r--r--test/irb/test_completion.rb328
-rw-r--r--test/irb/test_context.rb518
-rw-r--r--test/irb/test_debug_cmd.rb303
-rw-r--r--test/irb/test_history.rb209
-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.rb44
-rw-r--r--test/irb/test_ruby_lex.rb617
-rw-r--r--test/irb/test_workspace.rb33
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb249
-rw-r--r--test/json/fixtures/fail29.json1
-rw-r--r--test/json/fixtures/fail30.json1
-rw-r--r--test/json/fixtures/fail31.json1
-rw-r--r--test/json/fixtures/fail32.json1
-rw-r--r--test/json/json_addition_test.rb6
-rw-r--r--test/json/json_common_interface_test.rb43
-rw-r--r--test/json/json_fixtures_test.rb10
-rw-r--r--test/json/json_generator_test.rb54
-rw-r--r--test/json/json_parser_test.rb30
-rw-r--r--test/json/ractor_test.rb30
-rw-r--r--test/json/test_helper.rb6
-rw-r--r--test/lib/jit_support.rb54
-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.rb20
-rw-r--r--test/logger/test_logperiod.rb2
-rw-r--r--test/logger/test_severity.rb2
-rw-r--r--test/matrix/test_matrix.rb795
-rw-r--r--test/matrix/test_vector.rb335
-rw-r--r--test/misc/test_ruby_mode.rb183
-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.rb13
-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.rb47
-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.rb2570
-rw-r--r--test/net/ftp/test_mlsx_entry.rb98
-rw-r--r--test/net/http/test_http.rb187
-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.rb287
-rw-r--r--test/net/http/test_https.rb104
-rw-r--r--test/net/http/test_https_proxy.rb2
-rw-r--r--test/net/http/utils.rb6
-rw-r--r--test/net/imap/test_imap.rb843
-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.rb200
-rw-r--r--test/net/smtp/test_ssl_socket.rb97
-rw-r--r--test/objspace/test_objspace.rb379
-rw-r--r--test/objspace/test_ractor.rb17
-rw-r--r--test/open-uri/test_open-uri.rb275
-rw-r--r--test/open-uri/test_ssl.rb19
-rw-r--r--test/openssl/fixtures/chain/dh512.pem4
-rw-r--r--test/openssl/fixtures/chain/server.crt13
-rw-r--r--test/openssl/fixtures/chain/server.csr11
-rw-r--r--test/openssl/fixtures/chain/server.key15
-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.rb33
-rw-r--r--test/openssl/test_bn.rb120
-rw-r--r--test/openssl/test_cipher.rb73
-rw-r--r--test/openssl/test_config.rb192
-rw-r--r--test/openssl/test_digest.rb63
-rw-r--r--test/openssl/test_engine.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.rb43
-rw-r--r--test/openssl/test_ossl.rb2
-rw-r--r--test/openssl/test_pair.rb19
-rw-r--r--test/openssl/test_pkcs12.rb297
-rw-r--r--test/openssl/test_pkcs7.rb18
-rw-r--r--test/openssl/test_pkey.rb177
-rw-r--r--test/openssl/test_pkey_dh.rb105
-rw-r--r--test/openssl/test_pkey_dsa.rb107
-rw-r--r--test/openssl/test_pkey_ec.rb208
-rw-r--r--test/openssl/test_pkey_rsa.rb317
-rw-r--r--test/openssl/test_ssl.rb780
-rw-r--r--test/openssl/test_ssl_session.rb11
-rw-r--r--test/openssl/test_ts.rb67
-rw-r--r--test/openssl/test_x509cert.rb50
-rw-r--r--test/openssl/test_x509crl.rb20
-rw-r--r--test/openssl/test_x509name.rb4
-rw-r--r--test/openssl/test_x509req.rb36
-rw-r--r--test/openssl/test_x509store.rb412
-rw-r--r--test/openssl/ut_eof.rb4
-rw-r--r--test/openssl/utils.rb52
-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.rb198
-rw-r--r--test/pathname/test_pathname.rb157
-rw-r--r--test/pathname/test_ractor.rb22
-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.rb61
-rw-r--r--test/psych/test_hash.rb80
-rw-r--r--test/psych/test_marshalable.rb12
-rw-r--r--test/psych/test_merge_keys.rb34
-rw-r--r--test/psych/test_nil.rb4
-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.rb181
-rw-r--r--test/psych/test_ractor.rb50
-rw-r--r--test/psych/test_safe_load.rb93
-rw-r--r--test/psych/test_scalar_scanner.rb75
-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.rb40
-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/ifelse.y14
-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/cadenza190
-rw-r--r--test/racc/regress/cast1552
-rw-r--r--test/racc/regress/csspool396
-rw-r--r--test/racc/regress/edtf446
-rw-r--r--test/racc/regress/huia675
-rw-r--r--test/racc/regress/journey2
-rw-r--r--test/racc/regress/liquor218
-rw-r--r--test/racc/regress/machete48
-rw-r--r--test/racc/regress/mediacloth454
-rw-r--r--test/racc/regress/mof192
-rw-r--r--test/racc/regress/namae70
-rw-r--r--test/racc/regress/nasl1292
-rw-r--r--test/racc/regress/nokogiri-css124
-rw-r--r--test/racc/regress/opal7650
-rw-r--r--test/racc/regress/php_serialization36
-rw-r--r--test/racc/regress/riml2238
-rw-r--r--test/racc/regress/ruby187408
-rw-r--r--test/racc/regress/ruby227892
-rw-r--r--test/racc/regress/tp_plus430
-rw-r--r--test/racc/regress/twowaysql42
-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.rb19
-rw-r--r--test/racc/test_scan_y.rb2
-rw-r--r--test/rdoc/helper.rb6
-rw-r--r--test/rdoc/support/test_case.rb33
-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.rb88
-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.rb30
-rw-r--r--test/rdoc/test_rdoc_markup_to_markdown.rb4
-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.rb169
-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.rb106
-rw-r--r--test/rdoc/test_rdoc_require.rb3
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb99
-rw-r--r--test/rdoc/test_rdoc_ri_paths.rb10
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb83
-rw-r--r--test/rdoc/test_rdoc_servlet.rb12
-rw-r--r--test/rdoc/test_rdoc_store.rb22
-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.rb315
-rw-r--r--test/readline/test_readline_history.rb7
-rw-r--r--test/reline/helper.rb49
-rw-r--r--test/reline/test_config.rb203
-rw-r--r--test/reline/test_history.rb31
-rw-r--r--test/reline/test_key_actor_emacs.rb491
-rw-r--r--test/reline/test_key_actor_vi.rb301
-rw-r--r--test/reline/test_key_stroke.rb49
-rw-r--r--test/reline/test_kill_ring.rb12
-rw-r--r--test/reline/test_macro.rb4
-rw-r--r--test/reline/test_reline.rb212
-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.rb25
-rw-r--r--test/reline/test_within_pipe.rb31
-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.rb1345
-rw-r--r--test/resolv/test_addr.rb26
-rw-r--r--test/resolv/test_dns.rb156
-rw-r--r--test/rinda/test_rinda.rb102
-rw-r--r--test/ripper/dummyparser.rb6
-rw-r--r--test/ripper/test_lexer.rb176
-rw-r--r--test/ripper/test_parser_events.rb190
-rw-r--r--test/ripper/test_ripper.rb31
-rw-r--r--test/ripper/test_scanner_events.rb48
-rw-r--r--test/ripper/test_sexp.rb64
-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.rb65
-rw-r--r--test/ruby/test_argf.rb132
-rw-r--r--test/ruby/test_arithmetic_sequence.rb18
-rw-r--r--test/ruby/test_arity.rb44
-rw-r--r--test/ruby/test_array.rb516
-rw-r--r--test/ruby/test_assignment.rb176
-rw-r--r--test/ruby/test_ast.rb747
-rw-r--r--test/ruby/test_autoload.rb152
-rw-r--r--test/ruby/test_backtrace.rb85
-rw-r--r--test/ruby/test_bignum.rb110
-rw-r--r--test/ruby/test_call.rb16
-rw-r--r--test/ruby/test_case.rb12
-rw-r--r--test/ruby/test_class.rb142
-rw-r--r--test/ruby/test_clone.rb53
-rw-r--r--test/ruby/test_complex.rb116
-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.rb161
-rw-r--r--test/ruby/test_dir.rb193
-rw-r--r--test/ruby/test_dir_m17n.rb53
-rw-r--r--test/ruby/test_dup.rb110
-rw-r--r--test/ruby/test_econv.rb6
-rw-r--r--test/ruby/test_encoding.rb29
-rw-r--r--test/ruby/test_enum.rb186
-rw-r--r--test/ruby/test_enumerator.rb155
-rw-r--r--test/ruby/test_env.rb963
-rw-r--r--test/ruby/test_eval.rb70
-rw-r--r--test/ruby/test_exception.rb350
-rw-r--r--test/ruby/test_fiber.rb179
-rw-r--r--test/ruby/test_file.rb54
-rw-r--r--test/ruby/test_file_exhaustive.rb171
-rw-r--r--test/ruby/test_fixnum.rb1
-rw-r--r--test/ruby/test_float.rb47
-rw-r--r--test/ruby/test_frozen.rb30
-rw-r--r--test/ruby/test_gc.rb241
-rw-r--r--test/ruby/test_gc_compact.rb415
-rw-r--r--test/ruby/test_hash.rb540
-rw-r--r--test/ruby/test_inlinecache.rb48
-rw-r--r--test/ruby/test_insns_leaf.rb46
-rw-r--r--test/ruby/test_integer.rb95
-rw-r--r--test/ruby/test_io.rb397
-rw-r--r--test/ruby/test_io_buffer.rb562
-rw-r--r--test/ruby/test_io_m17n.rb22
-rw-r--r--test/ruby/test_io_timeout.rb58
-rw-r--r--test/ruby/test_iseq.rb265
-rw-r--r--test/ruby/test_iterator.rb3
-rw-r--r--test/ruby/test_jit.rb1080
-rw-r--r--test/ruby/test_keyword.rb349
-rw-r--r--test/ruby/test_lambda.rb109
-rw-r--r--test/ruby/test_lazy_enumerator.rb28
-rw-r--r--test/ruby/test_literal.rb63
-rw-r--r--test/ruby/test_m17n.rb68
-rw-r--r--test/ruby/test_m17n_comb.rb15
-rw-r--r--test/ruby/test_marshal.rb185
-rw-r--r--test/ruby/test_math.rb54
-rw-r--r--test/ruby/test_memory_view.rb341
-rw-r--r--test/ruby/test_method.rb379
-rw-r--r--test/ruby/test_method_cache.rb76
-rw-r--r--test/ruby/test_mjit.rb1327
-rw-r--r--test/ruby/test_mjit_debug.rb17
-rw-r--r--test/ruby/test_module.rb955
-rw-r--r--test/ruby/test_name_error.rb26
-rw-r--r--test/ruby/test_nomethod_error.rb38
-rw-r--r--test/ruby/test_notimp.rb90
-rw-r--r--test/ruby/test_numeric.rb88
-rw-r--r--test/ruby/test_object.rb57
-rw-r--r--test/ruby/test_objectspace.rb58
-rw-r--r--test/ruby/test_optimization.rb110
-rw-r--r--test/ruby/test_pack.rb94
-rw-r--r--test/ruby/test_parse.rb283
-rw-r--r--test/ruby/test_pattern_matching.rb451
-rw-r--r--test/ruby/test_proc.rb339
-rw-r--r--test/ruby/test_process.rb398
-rw-r--r--test/ruby/test_rand.rb361
-rw-r--r--test/ruby/test_random_formatter.rb123
-rw-r--r--test/ruby/test_range.rb128
-rw-r--r--test/ruby/test_rational.rb36
-rw-r--r--test/ruby/test_refinement.rb459
-rw-r--r--test/ruby/test_regexp.rb614
-rw-r--r--test/ruby/test_require.rb197
-rw-r--r--test/ruby/test_require_lib.rb5
-rw-r--r--test/ruby/test_rubyoptions.rb172
-rw-r--r--test/ruby/test_rubyvm.rb57
-rw-r--r--test/ruby/test_rubyvm_mjit.rb38
-rw-r--r--test/ruby/test_settracefunc.rb730
-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_stack.rb82
-rw-r--r--test/ruby/test_string.rb1003
-rw-r--r--test/ruby/test_struct.rb96
-rw-r--r--test/ruby/test_super.rb123
-rw-r--r--test/ruby/test_symbol.rb29
-rw-r--r--test/ruby/test_syntax.rb479
-rw-r--r--test/ruby/test_thread.rb175
-rw-r--r--test/ruby/test_thread_cv.rb63
-rw-r--r--test/ruby/test_thread_queue.rb161
-rw-r--r--test/ruby/test_time.rb236
-rw-r--r--test/ruby/test_time_tz.rb61
-rw-r--r--test/ruby/test_transcode.rb55
-rw-r--r--test/ruby/test_undef.rb16
-rw-r--r--test/ruby/test_variable.rb102
-rw-r--r--test/ruby/test_vm_dump.rb6
-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.rb3
-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.rb3
-rw-r--r--test/rubygems/rubygems_plugin.rb7
-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.gemspec14
-rw-r--r--test/rubygems/test_bundled_ca.rb92
-rw-r--r--test/rubygems/test_config.rb13
-rw-r--r--test/rubygems/test_deprecate.rb86
-rw-r--r--test/rubygems/test_exit.rb17
-rw-r--r--test/rubygems/test_gem.rb1392
-rw-r--r--test/rubygems/test_gem_available_set.rb51
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb87
-rw-r--r--test/rubygems/test_gem_command.rb128
-rw-r--r--test/rubygems/test_gem_command_manager.rb164
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb358
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb306
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb21
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb148
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb116
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb79
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb99
-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.rb21
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb51
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb43
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb619
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb13
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb25
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb9
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb36
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb31
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb333
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb254
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb335
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb179
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb7
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb57
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb463
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb216
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb13
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb172
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb137
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb11
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb191
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb67
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb402
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb27
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb245
-rw-r--r--test/rubygems/test_gem_config_file.rb205
-rw-r--r--test/rubygems/test_gem_dependency.rb175
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb701
-rw-r--r--test/rubygems/test_gem_dependency_list.rb117
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb13
-rw-r--r--test/rubygems/test_gem_doctor.rb103
-rw-r--r--test/rubygems/test_gem_ext_builder.rb227
-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.rb72
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb63
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb148
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb82
-rw-r--r--test/rubygems/test_gem_gem_runner.rb39
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb281
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb11
-rw-r--r--test/rubygems/test_gem_indexer.rb182
-rw-r--r--test/rubygems/test_gem_install_update_options.rb53
-rw-r--r--test/rubygems/test_gem_installer.rb1348
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb25
-rw-r--r--test/rubygems/test_gem_name_tuple.rb11
-rw-r--r--test/rubygems/test_gem_package.rb646
-rw-r--r--test/rubygems/test_gem_package_old.rb39
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb122
-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.rb202
-rw-r--r--test/rubygems/test_gem_package_task.rb84
-rw-r--r--test/rubygems/test_gem_path_support.rb37
-rw-r--r--test/rubygems/test_gem_platform.rb590
-rw-r--r--test/rubygems/test_gem_rdoc.rb41
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb684
-rw-r--r--test/rubygems/test_gem_request.rb210
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb65
-rw-r--r--test/rubygems/test_gem_request_set.rb250
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb459
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb189
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb141
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb275
-rw-r--r--test/rubygems/test_gem_requirement.rb188
-rw-r--r--test/rubygems/test_gem_resolver.rb300
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb15
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb158
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb97
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb66
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb5
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb27
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb33
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb47
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb46
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb31
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb35
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb13
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb149
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb17
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb33
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb37
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb5
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb21
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb21
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb23
-rw-r--r--test/rubygems/test_gem_security.rb185
-rw-r--r--test/rubygems/test_gem_security_policy.rb209
-rw-r--r--test/rubygems/test_gem_security_signer.rb105
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb31
-rw-r--r--test/rubygems/test_gem_server.rb612
-rw-r--r--test/rubygems/test_gem_silent_ui.rb89
-rw-r--r--test/rubygems/test_gem_source.rb106
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb25
-rw-r--r--test/rubygems/test_gem_source_git.rb151
-rw-r--r--test/rubygems/test_gem_source_installed.rb35
-rw-r--r--test/rubygems/test_gem_source_list.rb12
-rw-r--r--test/rubygems/test_gem_source_local.rb33
-rw-r--r--test/rubygems/test_gem_source_lock.rb65
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb39
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb50
-rw-r--r--test/rubygems/test_gem_source_vendor.rb29
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb142
-rw-r--r--test/rubygems/test_gem_specification.rb2049
-rw-r--r--test/rubygems/test_gem_stream_ui.rb77
-rw-r--r--test/rubygems/test_gem_stub_specification.rb98
-rw-r--r--test/rubygems/test_gem_text.rb13
-rw-r--r--test/rubygems/test_gem_uninstaller.rb326
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb9
-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.rb31
-rw-r--r--test/rubygems/test_gem_util.rb73
-rw-r--r--test/rubygems/test_gem_validator.rb22
-rw-r--r--test/rubygems/test_gem_version.rb63
-rw-r--r--test/rubygems/test_gem_version_option.rb35
-rw-r--r--test/rubygems/test_kernel.rb122
-rw-r--r--test/rubygems/test_project_sanity.rb40
-rw-r--r--test/rubygems/test_remote_fetch_error.rb17
-rw-r--r--test/rubygems/test_require.rb502
-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/sdbm/test_sdbm.rb544
-rw-r--r--test/socket/test_addrinfo.rb18
-rw-r--r--test/socket/test_basicsocket.rb6
-rw-r--r--test/socket/test_nonblock.rb12
-rw-r--r--test/socket/test_socket.rb23
-rw-r--r--test/socket/test_sockopt.rb2
-rw-r--r--test/socket/test_tcp.rb45
-rw-r--r--test/socket/test_udp.rb2
-rw-r--r--test/socket/test_unix.rb167
-rw-r--r--test/stringio/test_ractor.rb23
-rw-r--r--test/stringio/test_stringio.rb158
-rw-r--r--test/strscan/test_ractor.rb28
-rw-r--r--test/strscan/test_stringscanner.rb80
-rw-r--r--test/test_delegate.rb34
-rw-r--r--test/test_extlibs.rb4
-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_mutex_m.rb32
-rw-r--r--test/test_open3.rb24
-rw-r--r--test/test_pp.rb35
-rw-r--r--test/test_prime.rb280
-rw-r--r--test/test_pstore.rb36
-rw-r--r--test/test_pty.rb30
-rw-r--r--test/test_securerandom.rb121
-rw-r--r--test/test_set.rb186
-rw-r--r--test/test_sorted_set.rb45
-rw-r--r--test/test_syslog.rb7
-rw-r--r--test/test_time.rb18
-rw-r--r--test/test_timeout.rb65
-rw-r--r--test/test_tmpdir.rb70
-rw-r--r--test/test_tracer.rb234
-rw-r--r--test/test_trick.rb214
-rw-r--r--test/test_win32api.rb27
-rw-r--r--test/uri/test_common.rb119
-rw-r--r--test/uri/test_generic.rb87
-rw-r--r--test/uri/test_http.rb31
-rw-r--r--test/uri/test_ldap.rb10
-rw-r--r--test/uri/test_parser.rb43
-rw-r--r--test/uri/test_ws.rb71
-rw-r--r--test/uri/test_wss.rb71
-rw-r--r--test/webrick/test_cgi.rb170
-rw-r--r--test/webrick/test_filehandler.rb354
-rw-r--r--test/webrick/test_httpproxy.rb466
-rw-r--r--test/webrick/test_httprequest.rb476
-rw-r--r--test/webrick/test_httpresponse.rb282
-rw-r--r--test/webrick/test_httpserver.rb543
-rw-r--r--test/webrick/test_server.rb163
-rw-r--r--test/webrick/utils.rb82
-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.rb235
-rw-r--r--thread.c2881
-rw-r--r--thread_none.c284
-rw-r--r--thread_none.h20
-rw-r--r--thread_pthread.c1166
-rw-r--r--thread_pthread.h96
-rw-r--r--thread_sync.c921
-rw-r--r--thread_sync.rb68
-rw-r--r--thread_win32.c502
-rw-r--r--thread_win32.h45
-rw-r--r--time.c3062
-rw-r--r--timev.h11
-rw-r--r--timev.rb404
-rwxr-xr-xtool/actions-commit-info.sh17
-rw-r--r--tool/annocheck/Dockerfile4
-rw-r--r--tool/annocheck/Dockerfile-copy7
-rwxr-xr-xtool/bisect.sh17
-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.rb12
-rw-r--r--tool/bundler/test_gems.rb.lock45
-rwxr-xr-xtool/checksum.rb4
-rw-r--r--tool/ci_functions.sh29
-rwxr-xr-xtool/disable_ipv6.sh9
-rw-r--r--tool/downloader.rb121
-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.rb192
-rw-r--r--tool/fake.rb13
-rwxr-xr-xtool/fetch-bundled_gems.rb19
-rwxr-xr-xtool/file2lastrev.rb91
-rwxr-xr-xtool/format-release39
-rw-r--r--tool/gem-unpack.rb18
-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
-rwxr-xr-xtool/leaked-globals31
-rw-r--r--tool/lib/-test-/integer.rb4
-rw-r--r--tool/lib/bundled_gem.rb68
-rw-r--r--tool/lib/colorize.rb16
-rw-r--r--tool/lib/core_assertions.rb821
-rw-r--r--tool/lib/envutil.rb72
-rw-r--r--tool/lib/gc_checker.rb36
-rw-r--r--tool/lib/gc_compact_checker.rb10
-rw-r--r--tool/lib/leakchecker.rb127
-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.rb1438
-rw-r--r--tool/lib/output.rb57
-rw-r--r--tool/lib/profile_test_all.rb2
-rw-r--r--tool/lib/test/unit.rb827
-rw-r--r--tool/lib/test/unit/assertions.rb679
-rw-r--r--tool/lib/test/unit/core_assertions.rb591
-rw-r--r--tool/lib/test/unit/parallel.rb82
-rw-r--r--tool/lib/test/unit/testcase.rb280
-rw-r--r--tool/lib/vcs.rb356
-rw-r--r--tool/lib/vpath.rb7
-rw-r--r--tool/lib/webrick.rb232
-rw-r--r--tool/lib/webrick/.document (renamed from lib/webrick/.document)0
-rw-r--r--tool/lib/webrick/accesslog.rb (renamed from lib/webrick/accesslog.rb)0
-rw-r--r--tool/lib/webrick/cgi.rb (renamed from lib/webrick/cgi.rb)0
-rw-r--r--tool/lib/webrick/compat.rb (renamed from lib/webrick/compat.rb)0
-rw-r--r--tool/lib/webrick/config.rb (renamed from lib/webrick/config.rb)0
-rw-r--r--tool/lib/webrick/cookie.rb (renamed from lib/webrick/cookie.rb)0
-rw-r--r--tool/lib/webrick/htmlutils.rb (renamed from lib/webrick/htmlutils.rb)0
-rw-r--r--tool/lib/webrick/httpauth.rb (renamed from lib/webrick/httpauth.rb)0
-rw-r--r--tool/lib/webrick/httpauth/authenticator.rb117
-rw-r--r--tool/lib/webrick/httpauth/basicauth.rb (renamed from lib/webrick/httpauth/basicauth.rb)0
-rw-r--r--tool/lib/webrick/httpauth/digestauth.rb (renamed from lib/webrick/httpauth/digestauth.rb)0
-rw-r--r--tool/lib/webrick/httpauth/htdigest.rb (renamed from lib/webrick/httpauth/htdigest.rb)0
-rw-r--r--tool/lib/webrick/httpauth/htgroup.rb (renamed from lib/webrick/httpauth/htgroup.rb)0
-rw-r--r--tool/lib/webrick/httpauth/htpasswd.rb (renamed from lib/webrick/httpauth/htpasswd.rb)0
-rw-r--r--tool/lib/webrick/httpauth/userdb.rb (renamed from lib/webrick/httpauth/userdb.rb)0
-rw-r--r--tool/lib/webrick/httpproxy.rb354
-rw-r--r--tool/lib/webrick/httprequest.rb636
-rw-r--r--tool/lib/webrick/httpresponse.rb (renamed from lib/webrick/httpresponse.rb)0
-rw-r--r--tool/lib/webrick/https.rb (renamed from lib/webrick/https.rb)0
-rw-r--r--tool/lib/webrick/httpserver.rb293
-rw-r--r--tool/lib/webrick/httpservlet.rb (renamed from lib/webrick/httpservlet.rb)0
-rw-r--r--tool/lib/webrick/httpservlet/abstract.rb (renamed from lib/webrick/httpservlet/abstract.rb)0
-rw-r--r--tool/lib/webrick/httpservlet/cgi_runner.rb (renamed from lib/webrick/httpservlet/cgi_runner.rb)0
-rw-r--r--tool/lib/webrick/httpservlet/cgihandler.rb (renamed from lib/webrick/httpservlet/cgihandler.rb)0
-rw-r--r--tool/lib/webrick/httpservlet/erbhandler.rb (renamed from lib/webrick/httpservlet/erbhandler.rb)0
-rw-r--r--tool/lib/webrick/httpservlet/filehandler.rb552
-rw-r--r--tool/lib/webrick/httpservlet/prochandler.rb (renamed from lib/webrick/httpservlet/prochandler.rb)0
-rw-r--r--tool/lib/webrick/httpstatus.rb (renamed from lib/webrick/httpstatus.rb)0
-rw-r--r--tool/lib/webrick/httputils.rb512
-rw-r--r--tool/lib/webrick/httpversion.rb (renamed from lib/webrick/httpversion.rb)0
-rw-r--r--tool/lib/webrick/log.rb (renamed from lib/webrick/log.rb)0
-rw-r--r--tool/lib/webrick/server.rb381
-rw-r--r--tool/lib/webrick/ssl.rb215
-rw-r--r--tool/lib/webrick/utils.rb265
-rw-r--r--tool/lib/webrick/version.rb18
-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.m46
-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.m417
-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.m439
-rw-r--r--tool/m4/ruby_wasm_tools.m424
-rw-r--r--tool/m4/ruby_werror_flag.m42
-rwxr-xr-xtool/make-snapshot68
-rw-r--r--tool/make_hgraph.rb7
-rwxr-xr-xtool/merger.rb192
-rwxr-xr-xtool/mjit/bindgen.rb435
-rw-r--r--tool/mjit_tabs.rb67
-rw-r--r--tool/mk_builtin_binary.rb44
-rw-r--r--tool/mk_builtin_loader.rb347
-rw-r--r--tool/mk_call_iseq_optimized.rb73
-rwxr-xr-xtool/mkconfig.rb45
-rwxr-xr-xtool/mkrunnable.rb28
-rwxr-xr-xtool/outdate-bundled-gems.rb135
-rwxr-xr-xtool/pure_parser.rb20
-rwxr-xr-xtool/rbinstall.rb503
-rw-r--r--tool/rbs_skip_tests11
-rwxr-xr-xtool/rbuninstall.rb18
-rwxr-xr-xtool/redmine-backporter.rb169
-rwxr-xr-xtool/releng/gen-mail.rb55
-rwxr-xr-xtool/releng/gen-release-note.rb36
-rwxr-xr-xtool/releng/update-www-meta.rb213
-rw-r--r--tool/ruby_vm/controllers/application_controller.rb5
-rw-r--r--tool/ruby_vm/helpers/c_escape.rb6
-rw-r--r--tool/ruby_vm/helpers/dumper.rb10
-rw-r--r--tool/ruby_vm/helpers/scanner.rb3
-rw-r--r--tool/ruby_vm/loaders/insns_def.rb8
-rwxr-xr-xtool/ruby_vm/models/bare_instructions.rb4
-rw-r--r--tool/ruby_vm/models/typemap.rb2
-rw-r--r--tool/ruby_vm/scripts/insns2vm.rb12
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb6
-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.erb62
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb92
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb115
-rw-r--r--tool/ruby_vm/views/_mjit_compile_ivar.erb54
-rw-r--r--tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb36
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb112
-rw-r--r--tool/ruby_vm/views/_trace_instruction.erb9
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb40
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb93
-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.rb25
-rw-r--r--tool/search-cgvars.rb55
-rwxr-xr-xtool/strip-rdoc.rb30
-rwxr-xr-x[-rw-r--r--]tool/sync_default_gems.rb1135
-rwxr-xr-xtool/test-annocheck.sh33
-rw-r--r--tool/test-bundled-gems.rb82
-rw-r--r--tool/test-coverage.rb2
-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.rb1790
-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.rb6
-rw-r--r--tool/test/testunit/test_minitest_unit.rb1488
-rw-r--r--tool/test/testunit/test_parallel.rb33
-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/.htaccess (renamed from test/webrick/.htaccess)0
-rw-r--r--tool/test/webrick/test_cgi.rb170
-rw-r--r--tool/test/webrick/test_config.rb (renamed from test/webrick/test_config.rb)0
-rw-r--r--tool/test/webrick/test_cookie.rb (renamed from test/webrick/test_cookie.rb)0
-rw-r--r--tool/test/webrick/test_do_not_reverse_lookup.rb (renamed from test/webrick/test_do_not_reverse_lookup.rb)0
-rw-r--r--tool/test/webrick/test_filehandler.rb403
-rw-r--r--tool/test/webrick/test_htgroup.rb (renamed from test/webrick/test_htgroup.rb)0
-rw-r--r--tool/test/webrick/test_htmlutils.rb (renamed from test/webrick/test_htmlutils.rb)0
-rw-r--r--tool/test/webrick/test_httpauth.rb (renamed from test/webrick/test_httpauth.rb)0
-rw-r--r--tool/test/webrick/test_httpproxy.rb467
-rw-r--r--tool/test/webrick/test_httprequest.rb488
-rw-r--r--tool/test/webrick/test_httpresponse.rb282
-rw-r--r--tool/test/webrick/test_https.rb (renamed from test/webrick/test_https.rb)0
-rw-r--r--tool/test/webrick/test_httpserver.rb543
-rw-r--r--tool/test/webrick/test_httpstatus.rb (renamed from test/webrick/test_httpstatus.rb)0
-rw-r--r--tool/test/webrick/test_httputils.rb (renamed from test/webrick/test_httputils.rb)0
-rw-r--r--tool/test/webrick/test_httpversion.rb (renamed from test/webrick/test_httpversion.rb)0
-rw-r--r--tool/test/webrick/test_server.rb191
-rw-r--r--tool/test/webrick/test_ssl_server.rb (renamed from test/webrick/test_ssl_server.rb)0
-rw-r--r--tool/test/webrick/test_utils.rb (renamed from test/webrick/test_utils.rb)0
-rw-r--r--tool/test/webrick/utils.rb84
-rw-r--r--tool/test/webrick/webrick.cgi (renamed from test/webrick/webrick.cgi)0
-rw-r--r--tool/test/webrick/webrick.rhtml (renamed from test/webrick/webrick.rhtml)0
-rw-r--r--tool/test/webrick/webrick_long_filename.cgi (renamed from test/webrick/webrick_long_filename.cgi)0
-rw-r--r--tool/transcode-tblgen.rb24
-rw-r--r--tool/transform_mjit_header.rb65
-rwxr-xr-xtool/travis_disable_ipv6.sh11
-rwxr-xr-xtool/travis_wait.sh18
-rw-r--r--tool/update-NEWS-refs.rb37
-rwxr-xr-xtool/update-bundled_gems.rb23
-rwxr-xr-xtool/update-deps24
-rwxr-xr-xtool/wasm-clangw9
-rwxr-xr-xtool/ytab.sed1
-rw-r--r--trace_point.rb142
-rw-r--r--transcode.c805
-rw-r--r--transcode_data.h37
-rw-r--r--transient_heap.c169
-rw-r--r--transient_heap.h9
-rw-r--r--util.c198
-rw-r--r--variable.c3087
-rw-r--r--variable.h22
-rw-r--r--version.c67
-rw-r--r--version.h72
-rw-r--r--vm.c2544
-rw-r--r--vm_args.c714
-rw-r--r--vm_backtrace.c1172
-rw-r--r--vm_callinfo.h269
-rw-r--r--vm_core.h866
-rw-r--r--vm_debug.h98
-rw-r--r--vm_dump.c1098
-rw-r--r--vm_eval.c1392
-rw-r--r--vm_exec.c50
-rw-r--r--vm_exec.h33
-rw-r--r--vm_insnhelper.c5018
-rw-r--r--vm_insnhelper.h62
-rw-r--r--vm_method.c1714
-rw-r--r--vm_opts.h11
-rw-r--r--vm_sync.c301
-rw-r--r--vm_sync.h137
-rw-r--r--vm_trace.c714
-rw-r--r--vsnprintf.c25
-rw-r--r--warning.rb14
-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.sub302
-rwxr-xr-xwin32/configure.bat51
-rw-r--r--win32/dir.h8
-rw-r--r--win32/file.c621
-rw-r--r--win32/file.h38
-rwxr-xr-xwin32/ifchange.bat31
-rwxr-xr-xwin32/mkexports.rb18
-rwxr-xr-xwin32/resource.rb4
-rw-r--r--win32/ruby.manifest8
-rw-r--r--win32/setup.mak114
-rw-r--r--win32/win32.c6151
-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
6071 files changed, 977203 insertions, 304188 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 a5018a6cdc..3a6b0c238c 100644
--- a/.document
+++ b/.document
@@ -10,13 +10,26 @@
# prelude
prelude.rb
rbconfig.rb
+
array.rb
ast.rb
+dir.rb
gc.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
+yjit.rb
# the lib/ directory (which has its own .document file)
lib
@@ -32,7 +45,6 @@ README.ja.md
COPYING
COPYING.ja
-CONTRIBUTING.md
LEGAL
diff --git a/.gdbinit b/.gdbinit
index f73c036299..34d044caf6 100644
--- a/.gdbinit
+++ b/.gdbinit
@@ -136,7 +136,7 @@ define rp
printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len
if ($flags & RUBY_FL_USER2)
printf "(shared) shared="
- output/x ((struct RArray*)($arg0))->as.heap.aux.shared
+ output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root
printf " "
else
printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa
@@ -156,12 +156,12 @@ define rp
else
if ($flags & RUBY_T_MASK) == RUBY_T_HASH
printf "%sT_HASH%s: ", $color_type, $color_end,
- if (((struct RHash *)($arg0))->basic->flags & RHASH_ST_TABLE_FLAG)
+ if (((struct RHash *)($arg0))->basic.flags & RHASH_ST_TABLE_FLAG)
printf "st len=%ld ", ((struct RHash *)($arg0))->as.st->num_entries
else
printf "li len=%ld bound=%ld ", \
- ((((struct RHash *)($arg0))->basic->flags & RHASH_AR_TABLE_SIZE_MASK) >> RHASH_AR_TABLE_SIZE_SHIFT), \
- ((((struct RHash *)($arg0))->basic->flags & RHASH_AR_TABLE_BOUND_MASK) >> RHASH_AR_TABLE_BOUND_SHIFT)
+ ((((struct RHash *)($arg0))->basic.flags & RHASH_AR_TABLE_SIZE_MASK) >> RHASH_AR_TABLE_SIZE_SHIFT), \
+ ((((struct RHash *)($arg0))->basic.flags & RHASH_AR_TABLE_BOUND_MASK) >> RHASH_AR_TABLE_BOUND_SHIFT)
end
print (struct RHash *)($arg0)
else
@@ -265,6 +265,10 @@ define rp
printf "%sT_ZOMBIE%s: ", $color_type, $color_end
print (struct RData *)($arg0)
else
+ if ($flags & RUBY_T_MASK) == RUBY_T_MOVED
+ printf "%sT_MOVED%s: ", $color_type, $color_end
+ print *(struct RMoved *)$arg0
+ else
printf "%sunknown%s: ", $color_type, $color_end
print (struct RBasic *)($arg0)
end
@@ -300,6 +304,7 @@ define rp
end
end
end
+ end
end
document rp
Print a Ruby's VALUE.
@@ -539,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.
@@ -974,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)
@@ -1097,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
@@ -1319,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
new file mode 100644
index 0000000000..91f82b842b
--- /dev/null
+++ b/.github/codeql/codeql-config.yml
@@ -0,0 +1,3 @@
+name: "CodeQL config for the Ruby language"
+
+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
new file mode 100644
index 0000000000..ebaafe3bf0
--- /dev/null
+++ b/.github/workflows/baseruby.yml
@@ -0,0 +1,80 @@
+name: BASERUBY Check
+
+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-22.04
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+ strategy:
+ matrix:
+ ruby:
+ - ruby-2.2
+# - ruby-2.3
+# - ruby-2.4
+# - ruby-2.5
+# - ruby-2.6
+# - ruby-2.7
+ - ruby-3.0
+ - ruby-3.1
+
+ steps:
+ - 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 "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 common-srcs
+ - run: make incs
+ - run: make all
+ - run: make test
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}",
+ "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/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
new file mode 100644
index 0000000000..79b2916feb
--- /dev/null
+++ b/.github/workflows/check_dependencies.yml
@@ -0,0 +1,78 @@
+name: Check Dependencies
+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-22.04]
+ fail-fast: true
+ runs-on: ${{ matrix.os }}
+ 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 bison autoconf ruby
+ if: ${{ contains(matrix.os, 'ubuntu') }}
+ - name: Install libraries
+ run: |
+ 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
+ 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: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ matrix.os }} / Dependencies need to 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/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000000..8dba76fbe2
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,75 @@
+name: "Code scanning - action"
+
+on:
+ # push:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
+ # pull_request:
+ # paths-ignore:
+ # - 'doc/**'
+ # - '**/man'
+ # - '**.md'
+ # - '**.rdoc'
+ # - '**/.document'
+ schedule:
+ - 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 bison autoconf ruby
+
+ - name: Checkout repository
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - 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@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
+ with:
+ 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@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml
new file mode 100644
index 0000000000..caf12cc0f4
--- /dev/null
+++ b/.github/workflows/compilers.yml
@@ -0,0 +1,281 @@
+name: Compilations
+
+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'
+
+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-15
+ append_cc: ''
+
+ # -O1 is faster than -O3 in our tests... Majority of time are consumed trying
+ # 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'
+
+ # -g0 disables backtraces when SEGV. Do not set that.
+ debugflags: '-ggdb3'
+
+ default_configure: >-
+ --enable-debug-env
+ --disable-install-doc
+ --with-ext=-test-/cxxanyargs,+
+ append_configure: >-
+ --without-valgrind
+ --without-jemalloc
+ --without-gmp
+
+ UPDATE_UNICODE: >-
+ UNICODE_FILES=.
+ UNICODE_PROPERTY_FILES=.
+ UNICODE_AUXILIARY_FILES=.
+ UNICODE_EMOJI_FILES=.
+ CONFIGURE_TTY: never
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ RUBY_DEBUG: ci rgengc
+ RUBY_TESTOPTS: >-
+ -q
+ --color=always
+ --tty=no
+
+permissions:
+ contents: read
+
+jobs:
+ compile:
+ strategy:
+ fail-fast: false
+ matrix:
+ env:
+ - {}
+ entry:
+ - { 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:
+ 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 "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - 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
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ 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: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / ${{ matrix.entry.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/macos.yml b/.github/workflows/macos.yml
index 7203db371d..d8dc58b119 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -1,80 +1,113 @@
name: macOS
on:
push:
- branches:
- - '*'
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
pull_request:
- branches:
- - '*'
+ 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", "test-bundled-gems" ]
+ test_task: ["check"] # "test-bundler-parallel", "test-bundled-gems"
+ os:
+ - macos-13
+ - macos-14
+ - macos-15
fail-fast: false
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ runs-on: ${{ matrix.os }}
+ if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- - name: Disable Firewall
+ - run: mkdir build
+ working-directory:
+ - name: git config
run: |
- sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
- sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
- # Not using official actions/checkout because it's unstable and sometimes doesn't work for a fork.
- - name: Checkout ruby
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${GITHUB_REF#refs/heads/} https://github.com/${{ github.repository }} src
- git -C src reset --hard "$GITHUB_SHA"
- if: github.event_name == 'push'
- - name: Checkout a pull request
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${{ github.event.pull_request.head.ref }} https://github.com/${{ github.event.pull_request.head.repo.full_name }} src
- git -C src reset --hard ${{ github.event.pull_request.head.sha }}
- if: github.event_name == 'pull_request'
- - run: ./src/tool/actions-commit-info.sh
- id: commit_info
+ 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: Install libraries
run: |
- export WAITS='5 60'
- cd src
- 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 '::set-env name=JOBS::'-j$((1 + $(sysctl -n hw.activecpu)))
- - name: 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 incs
+ - run: make prepare-gems
+ if: ${{ matrix.test_task == 'test-bundled-gems' }}
+ - run: make
+ - run: make leaked-globals
+ if: ${{ matrix.test_task == 'check' }}
+ - name: make ${{ matrix.test_task }}
run: |
- cd src
- autoconf
- - name: Configure
- run: |
- mkdir build
- cd build
- ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline)
- - name: Make
- run: make -C build $JOBS
- - name: Extract gems
- run: make -C build update-gems extract-gems
- if: matrix.test_task == 'check'
- - name: Tests
- run: make -C build $JOBS -s ${{ matrix.test_task }}
+ 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"
- # Remove minitest from TEST_BUNDLED_GEMS_ALLOW_FAILURES if https://github.com/seattlerb/minitest/pull/798 is resolved
- # rss needs to add workaround for the non rexml environment
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: "minitest,xmlrpc,rss,rexml"
- - name: Leaked Globals
- run: make -C build -s leaked-globals
- - 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: |
{
- "attachments": [{
- "text": "${{ github.workflow }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ steps.commit_info.outputs.COMMIT_DATE }} #${{ steps.commit_info.outputs.COMMIT_NUMBER_OF_DAY }}> " +
- "(<https://github.com/${{ github.repository }}/commit/${{ github.sha }}|" + "${{ github.sha }}".substring(0, 10) + ">) " +
- "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }} failed",
- "color": "danger"
- }]
+ "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.SLACK_WEBHOOK_URL }}
- if: failure() && github.event_name == 'push'
+ 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/mingw.yml b/.github/workflows/mingw.yml
index 1596adef49..0df917d3d8 100644
--- a/.github/workflows/mingw.yml
+++ b/.github/workflows/mingw.yml
@@ -1,156 +1,179 @@
name: MinGW
on:
push:
- branches:
- - '*'
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
pull_request:
- branches:
- - '*'
+ 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:
-# Action ENV TEMP and TMP are short 8.3 paths, but the long path differs.
-# Code uses TMPDIR, which is Ruby's 'first' check
-#
-# Console encoding causes issues, see test-all & test-spec steps
+# 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
- # Not using official actions/checkout@v2 because it's unstable.
- - name: Checkout ruby
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${GITHUB_REF#refs/heads/} https://github.com/${{ github.repository }} src
- git -C src reset --hard "$GITHUB_SHA"
- if: github.event_name == 'push'
- shell: bash
- - name: Checkout a pull request
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${{ github.event.pull_request.head.ref }} https://github.com/${{ github.event.pull_request.head.repo.full_name }} src
- git -C src reset --hard ${{ github.event.pull_request.head.sha }}
- if: github.event_name == 'pull_request'
- - run: ./src/tool/actions-commit-info.sh
- shell: bash
- id: commit_info
+ 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/actions-ruby@master
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
- ruby-version: 2.6.x
- base: update
- mingw: 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 build
- mkdir install
- mkdir temp
- cd src
- sh -c "autoreconf -fi"
+ # 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: autogen
+ run: |
+ ./autogen.sh
+ working-directory: src
- name: configure
+ run: >
+ ../src/configure --disable-install-doc --prefix=/.
+ --build=$CHOST --host=$CHOST --target=$CHOST
+
+ - name: update
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")
- cd build
- $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 $_}
-
- - name: download unicode, gems, etc
+ make incs
+
+ - name: download gems
run: |
- $jobs = [int]$env:NUMBER_OF_PROCESSORS + 1
- cd build
- make -j $jobs update-unicode
- make -j $jobs update-gems
+ make update-gems
- name: make all
- timeout-minutes: 20
+ timeout-minutes: 30
run: |
- $jobs = [int]$env:NUMBER_OF_PROCESSORS + 1
- make -C build -j $jobs V=1
+ 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 -C build DESTDIR=.. install-nodoc
+ make DESTDIR=../install install-nodoc
- name: test
timeout-minutes: 5
run: |
- $env:TMPDIR = "$pwd/temp"
- make -C build test
+ make test
+ if: ${{matrix.test_task == 'check' || matrix.test_task == 'test'}}
- name: test-all
- timeout-minutes: 25
+ timeout-minutes: 45
run: |
- $env:TMPDIR = "$pwd/temp"
# 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]$env:NUMBER_OF_PROCESSORS
- make -C build 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
run: |
- $env:TMPDIR = "$pwd/temp"
- $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
- cd src/spec/ruby
- ruby ../mspec/bin/mspec -j
-
- - uses: k0kubun/action-slack@v2.0.0
+ 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: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
- "attachments": [{
- "text": "${{ github.workflow }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ steps.commit_info.outputs.COMMIT_DATE }} #${{ steps.commit_info.outputs.COMMIT_NUMBER_OF_DAY }}> " +
- "(<https://github.com/${{ github.repository }}/commit/${{ github.sha }}|" + "${{ github.sha }}".substring(0, 10) + ">) " +
- "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }} failed",
- "color": "danger"
- }]
+ "ci": "GitHub Actions",
+ "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_name }}"
}
env:
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- if: failure() && github.event_name == 'push'
+ 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
+ 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 d87f4fbba3..6f7181489a 100644
--- a/.github/workflows/mjit.yml
+++ b/.github/workflows/mjit.yml
@@ -1,76 +1,113 @@
name: MJIT
on:
push:
- branches:
- - '*'
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
pull_request:
- branches:
- - '*'
+ 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.mjit_opts }} --mjit-debug=-ggdb3'
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
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 libgdbm-dev bison autoconf ruby
- # Not using official actions/checkout because it's unstable and sometimes doesn't work for a fork.
- - name: Checkout 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 clone --single-branch --shallow-since=yesterday --branch=${GITHUB_REF#refs/heads/} https://github.com/${{ github.repository }} src
- git -C src reset --hard "$GITHUB_SHA"
- if: github.event_name == 'push'
- - name: Checkout a pull request
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${{ github.event.pull_request.head.ref }} https://github.com/${{ github.event.pull_request.head.repo.full_name }} src
- git -C src reset --hard ${{ github.event.pull_request.head.sha }}
- if: github.event_name == 'pull_request'
- - run: ./src/tool/actions-commit-info.sh
- id: commit_info
+ 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 go-w $HOME
+ 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 '::set-env name=JOBS::'-j$((1 + $(nproc --all)))
- - name: Autoconf
- run: cd src && exec autoconf
- - name: configure
+ echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ 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: |
+ 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: |
- mkdir build
- cd build
- ../src/configure -C --disable-install-doc
- - name: make all
- run: make -C build $JOBS
- - name: make install
- run: sudo make -C build $JOBS install
- - name: make test
- run: "make -C build $JOBS -s test TESTOPTS='-q --tty=no' RUN_OPTS='--disable-gems --jit-warnings ${{ matrix.jit_opts }}'"
- - name: make test-all
- run: "make -C build $JOBS -s test-all TESTOPTS='-q --tty=no' RUN_OPTS='--disable-gems --jit-warnings ${{ matrix.jit_opts }}'"
- - name: make test-spec
- run: "make -C build $JOBS -s test-spec RUN_OPTS='--disable-gems --jit-warnings ${{ matrix.jit_opts }}'"
- - name: Leaked Globals
- run: make -C build -s leaked-globals
- - uses: k0kubun/action-slack@v2.0.0
+ unset GNUMAKEFLAGS
+ make -s test-spec RUN_OPTS="$RUN_OPTS"
+ timeout-minutes: 60
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
- "attachments": [{
- "text": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.jit_opts }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ steps.commit_info.outputs.COMMIT_DATE }} #${{ steps.commit_info.outputs.COMMIT_NUMBER_OF_DAY }}> " +
- "(<https://github.com/${{ github.repository }}/commit/${{ github.sha }}|" + "${{ github.sha }}".substring(0, 10) + ">) " +
- "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }} failed",
- "color": "danger"
- }]
+ "ci": "GitHub Actions",
+ "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_name }}"
}
env:
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- if: failure() && github.event_name == 'push'
+ 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/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
new file mode 100644
index 0000000000..4521195a2b
--- /dev/null
+++ b/.github/workflows/spec_guards.yml
@@ -0,0 +1,71 @@
+name: Rubyspec Version Guards Check
+
+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-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-3.1
+ - ruby-3.2
+
+ steps:
+ - 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
+ env:
+ CHECK_LEAKS: true
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
+ with:
+ payload: |
+ {
+ "ci": "GitHub Actions",
+ "env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}",
+ "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() }}
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index bb174fd650..4fbca1170e 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -1,116 +1,146 @@
name: Ubuntu
on:
push:
- branches:
- - '*'
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
pull_request:
- branches:
- - '*'
+ 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", "test-bundled-gems", "test-all TESTS=--repeat-count=2" ]
- os: [ubuntu-latest, ubuntu-16.04]
- exclude:
- - test_task: test-bundler
- os: ubuntu-16.04
+ # 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
- test_task: test-bundled-gems
- os: ubuntu-16.04
- - test_task: "test-all TESTS=--repeat-count=2"
- os: ubuntu-16.04
fail-fast: false
- runs-on: ${{ matrix.os }}
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ env:
+ GITPULLOPTIONS: --no-tags origin ${{github.ref}}
+ RUBY_DEBUG: ci
+ 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: env | sort
- - name: Dump GitHub context
- env:
- GITHUB_CONTEXT: ${{ toJson(github) }}
- run: echo "$GITHUB_CONTEXT"
- - name: Dump job context
- env:
- JOB_CONTEXT: ${{ toJson(job) }}
- run: echo "$JOB_CONTEXT"
- - name: Dump steps context
- env:
- STEPS_CONTEXT: ${{ toJson(steps) }}
- run: echo "$STEPS_CONTEXT"
- - name: Dump runner context
- env:
- RUNNER_CONTEXT: ${{ toJson(runner) }}
- run: echo "$RUNNER_CONTEXT"
- - name: Dump strategy context
- env:
- STRATEGY_CONTEXT: ${{ toJson(strategy) }}
- run: echo "$STRATEGY_CONTEXT"
- - name: Dump matrix context
- env:
- MATRIX_CONTEXT: ${{ toJson(matrix) }}
- run: echo "$MATRIX_CONTEXT"
-
+ - 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
- # Not using official actions/checkout because it's unstable and sometimes doesn't work for a fork.
- - name: Checkout ruby
- run: |
- git clone --single-branch --shallow-since=yesterday --branch=${GITHUB_REF#refs/heads/} https://github.com/${{ github.repository }} src
- git -C src reset --hard "$GITHUB_SHA"
- if: github.event_name == 'push'
- - name: Checkout a pull request
+ 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 clone --single-branch --shallow-since=yesterday --branch=${{ github.event.pull_request.head.ref }} https://github.com/${{ github.event.pull_request.head.repo.full_name }} src
- git -C src reset --hard ${{ github.event.pull_request.head.sha }}
- if: github.event_name == 'pull_request'
- - run: ./src/tool/actions-commit-info.sh
- id: commit_info
+ 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 go-w $HOME
+ chmod -v go-w $HOME $HOME/.config
sudo chmod -R go-w /usr/share
- - name: Set ENV
- run: |
- echo '::set-env name=JOBS::'-j$((1 + $(nproc --all)))
- - name: Autoconf
- run: cd src && exec autoconf
- - name: configure
- run: |
- mkdir build
- cd build
- ../src/configure -C --disable-install-doc
- - name: Make
- run: make -C build $JOBS
- - name: Extract gems
- run: make -C build update-gems extract-gems
- if: matrix.test_task == 'check'
+ sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || :
+ - run: ./autogen.sh
+ working-directory: src
+ - name: Run configure
+ 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: |
- cd build
- ./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: Tests
- run: make -C build $JOBS -s ${{ matrix.test_task }}
+ $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"
- # Remove minitest from TEST_BUNDLED_GEMS_ALLOW_FAILURES if https://github.com/seattlerb/minitest/pull/798 is resolved
- # rss needs to add workaround for the non rexml environment
- TEST_BUNDLED_GEMS_ALLOW_FAILURES: "minitest,xmlrpc,rss"
- - name: Leaked Globals
- run: make -C build -s leaked-globals
- - 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: |
+ $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: |
{
- "attachments": [{
- "text": "${{ matrix.os }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ steps.commit_info.outputs.COMMIT_DATE }} #${{ steps.commit_info.outputs.COMMIT_NUMBER_OF_DAY }}> " +
- "(<https://github.com/${{ github.repository }}/commit/${{ github.sha }}|" + "${{ github.sha }}".substring(0, 10) + ">) " +
- "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }} failed",
- "color": "danger"
- }]
+ "ci": "GitHub Actions",
+ "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_name }}"
}
env:
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- if: failure() && github.event_name == 'push'
+ 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/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 3e466fd441..c2bd4881c2 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -1,91 +1,149 @@
name: Windows
on:
push:
- branches:
- - '*'
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
pull_request:
- branches:
- - '*'
+ 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 }}
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ 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}}
+ PATCH: C:\msys64\usr\bin\patch.exe
+ OS_VER: windows-${{ matrix.vs }}
steps:
- - uses: actions/cache@v1
+ - run: md build
+ working-directory:
+ - 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 }}
+ 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:\vcpkg\installed
+ key: ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-${{ github.sha }}
restore-keys: |
- ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-
- ${{ runner.os }}-vcpkg-download-
+ ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-
+ ${{ runner.os }}-vcpkg-installed-windows-
- name: Install libraries with vcpkg
run: |
- vcpkg --triplet x64-windows install readline zlib
- - uses: actions/cache@v1
- with:
- path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
- key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-chocolatey-${{ matrix.os }}-
- ${{ runner.os }}-chocolatey-
- - name: Install libraries with chocolatey
+ 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: |
- choco install --no-progress openssl winflexbison3
- # Not using official actions/checkout because it's unstable and sometimes doesn't work for a fork.
- - name: Checkout ruby
+ 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: 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: |
- git clone --single-branch --shallow-since=yesterday --branch=${GITHUB_REF#refs/heads/} https://github.com/${{ github.repository }} src
- git -C src reset --hard ${{ github.sha }}
- if: github.event_name == 'push'
- shell: bash
- - name: Checkout a pull request
+ 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: |
- git clone --single-branch --shallow-since=yesterday --branch=${{ github.event.pull_request.head.ref }} https://github.com/${{ github.event.pull_request.head.repo.full_name }} src
- git -C src reset --hard ${{ github.event.pull_request.head.sha }}
- if: github.event_name == 'pull_request'
- - run: ./src/tool/actions-commit-info.sh
- shell: bash
- id: commit_info
+ 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: |
- md build
- cd build
- call "C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- ../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"
- shell: cmd
- - name: nmake
- run: |
- call "C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- set YACC=win_bison
- cd build
- echo on
- nmake up
- nmake extract-gems
- nmake
- shell: cmd
- - name: nmake test
- run: |
- call "C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- cd build
- nmake ${{ matrix.test_task }}
- shell: cmd
- - uses: k0kubun/action-slack@v2.0.0
+ 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: |
{
- "attachments": [{
- "text": "${{ matrix.os }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ steps.commit_info.outputs.COMMIT_DATE }} #${{ steps.commit_info.outputs.COMMIT_NUMBER_OF_DAY }}> " +
- "(<https://github.com/${{ github.repository }}/commit/${{ github.sha }}|" + "${{ github.sha }}".substring(0, 10) + ">) " +
- "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }} failed",
- "color": "danger"
- }]
+ "ci": "GitHub Actions",
+ "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_name }}"
}
env:
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- if: failure() && github.event_name == 'push'
+ 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
+ shell: cmd
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 916c7aaf9e..99d32a1825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,9 +10,11 @@
*.dylib
*.elc
*.i
+*.ii
*.inc
*.log
*.o
+*.o.tmp
*.obj
*.old
*.orig
@@ -24,10 +26,10 @@
*.sav
*.sl
*.so
+*.so.*
*.swp
*.yarb
*~
-.*-*
.*.list
.*.time
.DS_Store
@@ -38,6 +40,7 @@
.ppack
.svn
.time
+.ruby-version
Makefile
cygruby*.def
extconf.h
@@ -57,6 +60,8 @@ lcov*.info
/*.pc
/*.rc
/*_prelude.c
+/.downloaded-cache
+/.top-enc.mk
/build*/
/COPYING.LIB
/ChangeLog
@@ -124,8 +129,10 @@ lcov*.info
/ruby-runner
/ruby-runner.h
/ruby-man.rd.gz
+/rubyspec_temp
/run.gdb
/sizes.c
+/static-ruby
/test.rb
/test-coverage.dat
/tmp
@@ -140,6 +147,8 @@ lcov*.info
/bin/*.exe
/bin/*.dll
+/bin/goruby
+/bin/ruby
# /benchmark/
/benchmark/bm_require.data
@@ -179,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
@@ -191,6 +203,7 @@ lcov*.info
# /ext/ripper/
/ext/ripper/eventids1.c
+/ext/ripper/.eventids2-check
/ext/ripper/eventids2table.c
/ext/ripper/ripper.*
/ext/ripper/ids1
@@ -210,6 +223,9 @@ lcov*.info
/lib/ruby/[1-9]*.*
/lib/ruby/vendor_ruby
+# /misc/
+/misc/**/__pycache__
+
# /spec/bundler
/.rspec_status
@@ -221,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 6d1d1ebd04..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,567 +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:
-
- - &cron-only
- if: (type = cron) AND (branch = master) AND (fork = false)
-
- - &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 \
- libgmp-dev \
- libjemalloc-dev \
- libncurses5-dev \
- libncursesw5-dev \
- libreadline6-dev \
- libssl-dev \
- libyaml-dev \
- openssl \
- valgrind \
- 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 \
- libgmp-dev \
- libjemalloc-dev \
- libncurses5-dev \
- libncursesw5-dev \
- libreadline6-dev \
- libssl-dev \
- libyaml-dev \
- openssl \
- valgrind \
- 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
- env:
- - BEFORE_INSTALL="tool/travis_disable_ipv6.sh"
-
- - &jemalloc
- name: --with-jemalloc
- <<: *gcc-8
- <<: *cron-only
- env:
- - CONFIG_FLAG='--with-gmp --with-jemalloc --with-valgrind'
-
- - &assertions
- name: RUBY_DEBUG=1
- <<: *gcc-8
- #<<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cppflags='-DRUBY_DEBUG -DVM_CHECK_MODE=1 -DTRANSIENT_HEAP_CHECK_MODE -DRGENGC_CHECK_MODE -DENC_DEBUG'
-
- - &VM_CHECK_MODE
- name: VM_CHECK_MODE=3
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cppflags=-DVM_CHECK_MODE=0x0003
-
- - &SUPPORT_JOKE
- name: SUPPORT_JOKE
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - BEFORE_INSTALL="sed vm_opts.h -e 's/OPT_SUPPORT_JOKE *0/OPT_SUPPORT_JOKE 1/' -i"
-
- - &CPDEBUG
- name: CPDEBUG
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - cppflags=-DCPDEBUG
-
- - &WITH_COROUTINE_UCONTEXT
- name: COROUTINE=ucontext
- <<: *gcc-8
- <<: *cron-only
- env:
- - CONFIG_FLAG='--with-coroutine=ucontext'
-
- - &WITH_COROUTINE_COPY
- name: COROUTINE=copy
- <<: *gcc-8
- <<: *cron-only
- env:
- - CONFIG_FLAG='--with-coroutine=copy'
-
- - &TOKEN_THREADED_CODE
- name: TOKEN_THREADED_CODE
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cppflags=-DOPT_THREADED_CODE=1
-
- - &CALL_THREADED_CODE
- name: CALL_THREADED_CODE
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cppflags=-DOPT_THREADED_CODE=2
-
- - &NO_THREADED_CODE
- name: NO_THREADED_CODE
- <<: *gcc-8
- <<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cppflags=-DOPT_THREADED_CODE=3
-
- - &ASAN
- name: -fsanitize=address
- <<: *clang-8
- #<<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - ASAN_OPTIONS=detect_leaks=0
- - cflags='-U_FORTIFY_SOURCE -march=native -fsanitize=address -fno-omit-frame-pointer -fPIC'
- - debugflags=-ggdb3
- - optflags=-O1
- - LD=clang-8
- - LDFLAGS='-fsanitize=address -fPIC'
- - CONFIG_FLAG='--with-out-ext=openssl --without-gmp --without-jemalloc --without-valgrind'
-
- - &MSAN
- name: -fsanitize=memory
- <<: *clang-8
- #<<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cflags='-U_FORTIFY_SOURCE -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -fPIC'
- - optflags=-O1
- - LD=clang-8
- - LDFLAGS='-fsanitize=memory -fPIC'
- - CONFIG_FLAG='--with-out-ext=openssl --without-gmp --without-jemalloc --without-valgrind'
-
- - &UBSAN
- name: -fsanitize=undefined
- <<: *clang-8
- #<<: *cron-only
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - cflags='-U_FORTIFY_SOURCE -fsanitize=undefined,integer,nullability -fno-sanitize=implicit-integer-sign-change,unsigned-integer-overflow'
- - cppflags=-DUNALIGNED_WORD_ACCESS=0
- - debugflags=-ggdb3
- - optflags='-O1 -march=native'
- - LD=clang-8
- - LDFLAGS='-fsanitize=undefined,integer,nullability -fno-sanitize=implicit-integer-sign-change,unsigned-integer-overflow'
-
- - &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
-
- - &pedanticism
- name: -std=c99 -pedantic
- compiler: clang
- <<: *make-test-only
- env:
- - GEMS_FOR_TEST=
- - GCC_FLAGS='-std=c99 -Werror=pedantic -pedantic-errors'
- - CONFIG_FLAG=
- - JOBS=
- - >-
- warnflags='
- -Wall
- -Wextra
- -Werror=deprecated-declarations
- -Werror=division-by-zero
- -Werror=extra-tokens
- -Werror=implicit-function-declaration
- -Werror=implicit-int
- -Werror=pointer-arith
- -Werror=shorten-64-to-32
- -Werror=write-strings
- -Wmissing-noreturn
- -Wno-constant-logical-operand
- -Wno-missing-field-initializers
- -Wno-overlength-strings
- -Wno-parentheses-equality
- -Wno-self-assign
- -Wno-tautological-compare
- -Wno-unused-local-typedef
- -Wno-unused-parameter
- -Wunused-variable'
- - LDFLAGS=-Wno-unused-command-line-argument
-
- - &rubyspec24
- name: Check ruby/spec version guards on Ruby 2.4
- language: ruby
- rvm: 2.4.9
- before_install:
- install:
- before_script: chmod -R u+w spec/ruby
- # -j randomly hangs.
- script: ruby -C spec/ruby ../mspec/bin/mspec .
- after_failure:
- - echo "ruby/spec failed on Ruby 2.4. This is likely because of a missing ruby_version_is guard, please add it. See spec/README.md."
-
- - &rubyspec27
- name: Check ruby/spec version guards on Ruby 2.7
- language: ruby
- rvm: 2.7.0
- before_install:
- install:
- before_script: chmod -R u+w spec/ruby
- # -j randomly hangs.
- script: ruby -C spec/ruby ../mspec/bin/mspec .
- after_failure:
- - echo "ruby/spec failed on Ruby 2.7. This is likely because of a missing ruby_version_is guard, please add it. See spec/README.md."
-
- - &baseruby
- name: "BASERUBY: Ruby 2.2"
- <<: *gcc-8
- <<: *make-test-only
- language: ruby
- rvm: 2.2
-
- - &dependency
- name: Check dependencies in makefiles
- language: ruby
- before_install:
- install:
- before_script:
- - |-
- ruby -e 'new = []
- Dir.glob("ext/**/extconf.rb") {|ex|
- unless File.exist?(dep = File.dirname(ex)+"/depend")
- puts "Adding "+dep
- File.copy_stream("template/depend.tmpl", dep)
- new << dep
- end
- }
- exec("git", "add", *new) unless new.empty?'
- - git diff --cached
- - "> 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
- - $SETARCH ./configure -C --disable-install-doc --prefix=$RUBY_PREFIX --disable-rubygems 'optflags=-O0' 'debugflags=-save-temps=obj -g'
- - ruby tool/update-deps --fix
- script:
- - git diff --no-ext-diff --ignore-submodules --exit-code
- after_failure:
- - echo "Dependencies need to update"
- env:
- - CONFIG_FLAG=
-
-matrix:
- include:
- # Build every commit:
- - <<: *x86_64-linux
- - <<: *arm64-linux
- - <<: *i686-linux
- - <<: *arm32-linux
- - <<: *s390x-linux
- - <<: *pedanticism
- - <<: *assertions
- - <<: *baseruby
- - <<: *rubyspec24
- - <<: *rubyspec27
- - <<: *dependency
- # Build every commit (Allowed Failures):
- - <<: *ASAN
- - <<: *MSAN
- - <<: *UBSAN
- # Cron only:
- - <<: *jemalloc
- - <<: *VM_CHECK_MODE
- - <<: *SUPPORT_JOKE
- - <<: *CPDEBUG
- - <<: *WITH_COROUTINE_UCONTEXT
- - <<: *WITH_COROUTINE_COPY
- - <<: *TOKEN_THREADED_CODE
- - <<: *CALL_THREADED_CODE
- - <<: *NO_THREADED_CODE
- allow_failures:
- - name: -fsanitize=address
- - name: -fsanitize=memory
- - name: -fsanitize=undefined
- fast_finish: true
-
-before_script:
- - date # Debugging "Permission defined" failure on darwin like https://travis-ci.org/ruby/ruby/jobs/508683759
- - dpkg --print-architecture
- - dpkg --print-foreign-architectures
- - setarch --list
- - echo JOBS=${JOBS} SETARCH=${SETARCH}
- - $SETARCH uname -a
- - $SETARCH uname -r
- - ip a
- - cat /etc/hosts
- - rm -fr .ext autom4te.cache
- - echo $TERM
- - |-
- [ -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
- - date; make touch-unicode-files
- - date; make -s $JOBS $UPDATE_UNICODE up
- - date; 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
- - ccache --show-stats
- - |-
- 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
- - |-
- date; : # Debugging "Permission defined" failure on darwin like https://travis-ci.org/ruby/ruby/jobs/508683759
- if ! make install; then
- if [ "$(uname)" = Darwin ]; then
- # Debugging "Permission defined" failure on darwin like https://travis-ci.org/ruby/ruby/jobs/508683759
- set -x
- date
- ./miniruby -e 'ARGV.map{|path|[path,File.stat(path)]}.sort_by{|path,st|st.mtime}.each{|path,st|p mtime:st.mtime.to_f, ctime:st.ctime.to_f, path:path}' .ext/.timestamp/.RUBYCOMMONDIR*time .ext/common/bigdecimal/*.rb ../ext/bigdecimal/lib/bigdecimal/*.rb . .. .ext .ext/common .ext/common/bigdecimal ext/bigdecimal ../ext ../ext/bigdecimal ../ext/bigdecimal/lib ../ext/bigdecimal/lib/bigdecimal
- make COPY='cp -f' install
- else
- exit 1
- fi
- fi
- - ccache --show-stats
- - |-
- [ -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
-
-# 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}"
-
- slack:
- rooms:
- - secure: ah7UEHBvncXT7bM5mvYIQAO+tIyV/wl7nXLb7wQD16dO2v8Gragy0mWjB79Q09hrrMGmp6H9bCDpdGS80boIA5EHaHoG4QaP0i9bsSt8U2AMWgZtfyIgQKJ4H2kXkGlrjO+AXTgnIkP7LNjdgAVUUTGQPb26T3QmoN2Splt+fIQ= # ruby:<token>#alerts
- on_pull_requests: false
- 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 565c4c9cde..0423d57ac9 100644
--- a/LEGAL
+++ b/LEGAL
@@ -7,92 +7,118 @@ All the files in this distribution are covered under either the Ruby's
license (see the file COPYING) or public-domain except some files
mentioned below.
-ccan/build_assert/build_assert.h::
-ccan/check_type/check_type.h::
-ccan/container_of/container_of.h::
-ccan/str/str.h::
+[addr2line.c]
- These files are licensed under the CC0.
+ A part of this file is from FreeBSD.
>>>
- https://creativecommons.org/choose/zero/
+ Copyright (c) 1986, 1988, 1991, 1993::
+ The Regents of the University of California. All rights reserved.
-ccan/list/list.h::
+ (c) UNIX System Laboratories, Inc.
- This file is licensed under the MIT License.
+ All or some portions of this file are derived from material licensed
+ to the University of California by American Telephone and Telegraph
+ Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ the permission of UNIX System Laboratories, Inc.
- >>>
- 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:
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
- 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.
-
-include/ruby/onigmo.h::
-include/ruby/oniguruma.h::
-regcomp.c::
-regenc.c::
-regenc.h::
-regerror.c::
-regexec.c::
-regint.h::
-regparse.c::
-regparse.h::
-enc/ascii.c::
-enc/big5.c::
-enc/cp949.c::
-enc/emacs_mule.c::
-enc/encdb.c::
-enc/euc_jp.c::
-enc/euc_kr.c::
-enc/euc_tw.c::
-enc/gb18030.c::
-enc/gb2312.c::
-enc/gbk.c::
-enc/iso_8859_1.c::
-enc/iso_8859_10.c::
-enc/iso_8859_11.c::
-enc/iso_8859_13.c::
-enc/iso_8859_14.c::
-enc/iso_8859_15.c::
-enc/iso_8859_16.c::
-enc/iso_8859_2.c::
-enc/iso_8859_3.c::
-enc/iso_8859_4.c::
-enc/iso_8859_5.c::
-enc/iso_8859_6.c::
-enc/iso_8859_7.c::
-enc/iso_8859_8.c::
-enc/iso_8859_9.c::
-enc/koi8_r.c::
-enc/koi8_u.c::
-enc/shift_jis.c::
-enc/unicode.c::
-enc/us_ascii.c::
-enc/utf_16be.c::
-enc/utf_16le.c::
-enc/utf_32be.c::
-enc/utf_32le.c::
-enc/utf_8.c::
-enc/windows_1251.c::
+ @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+
+
+[ccan/build_assert/build_assert.h]
+[ccan/check_type/check_type.h]
+[ccan/container_of/container_of.h]
+[ccan/str/str.h]
+
+ These files are licensed under the {CC0}[https://creativecommons.org/choose/zero/].
+
+[ccan/list/list.h]
+
+ This file is licensed under the {MIT License}[rdoc-label:label-MIT+License].
+
+[coroutine]
+
+ Unless otherwise specified, these files are licensed under the
+ {MIT License}[rdoc-label:label-MIT+License].
+
+[include/ruby/onigmo.h]
+[include/ruby/oniguruma.h]
+[regcomp.c]
+[regenc.c]
+[regenc.h]
+[regerror.c]
+[regexec.c]
+[regint.h]
+[regparse.c]
+[regparse.h]
+[enc/ascii.c]
+[enc/big5.c]
+[enc/cp949.c]
+[enc/emacs_mule.c]
+[enc/encdb.c]
+[enc/euc_jp.c]
+[enc/euc_kr.c]
+[enc/euc_tw.c]
+[enc/gb18030.c]
+[enc/gb2312.c]
+[enc/gbk.c]
+[enc/iso_8859_1.c]
+[enc/iso_8859_10.c]
+[enc/iso_8859_11.c]
+[enc/iso_8859_13.c]
+[enc/iso_8859_14.c]
+[enc/iso_8859_15.c]
+[enc/iso_8859_16.c]
+[enc/iso_8859_2.c]
+[enc/iso_8859_3.c]
+[enc/iso_8859_4.c]
+[enc/iso_8859_5.c]
+[enc/iso_8859_6.c]
+[enc/iso_8859_7.c]
+[enc/iso_8859_8.c]
+[enc/iso_8859_9.c]
+[enc/koi8_r.c]
+[enc/koi8_u.c]
+[enc/shift_jis.c]
+[enc/unicode.c]
+[enc/us_ascii.c]
+[enc/utf_16be.c]
+[enc/utf_16le.c]
+[enc/utf_32be.c]
+[enc/utf_32le.c]
+[enc/utf_8.c]
+[enc/windows_1251.c]
+[enc/windows_31j.c]
Onigmo (Oniguruma-mod) LICENSE
>>>
- Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
- Copyright (c) 2011-2014 K.Takata <kentkt AT csc DOT jp>
+ Copyright (c) 2002-2009:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ Copyright (c) 2011-2014:: K.Takata <kentkt AT csc DOT jp>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -119,7 +145,7 @@ enc/windows_1251.c::
Oniguruma LICENSE
>>>
- Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ Copyright (c) 2002-2009:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -150,10 +176,69 @@ enc/windows_1251.c::
When this software is partly used or it is distributed with Ruby,
this of Ruby follows the license of Ruby.
-enc/trans/GB/GB12345%UCS.src::
-enc/trans/GB/UCS%GB12345.src::
-enc/trans/GB/GB2312%UCS.src::
-enc/trans/GB/UCS%GB2312.src::
+[enc/windows_1250.c]
+[enc/windows_1252.c]
+
+ >>>
+ Copyright (c) 2006-2007:: Byte <byte AT mail DOT kna DOT ru>
+ K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+[enc/cesu_8.c]
+[enc/windows_1253.c]
+[enc/windows_1254.c]
+[enc/windows_1257.c]
+
+ >>>
+ Copyright (c) 2002-2007:: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+[enc/trans/GB/GB12345%UCS.src]
+[enc/trans/GB/UCS%GB12345.src]
+[enc/trans/GB/GB2312%UCS.src]
+[enc/trans/GB/UCS%GB2312.src]
These files have this explanatory texts.
@@ -165,12 +250,12 @@ enc/trans/GB/UCS%GB2312.src::
files for any particular purpose, and has ceased to publish the files many
years ago.
-enc/trans/JIS/JISX0201-KANA%UCS.src::
-enc/trans/JIS/JISX0208\@1990%UCS.src::
-enc/trans/JIS/JISX0212%UCS.src::
-enc/trans/JIS/UCS%JISX0201-KANA.src::
-enc/trans/JIS/UCS%JISX0208@1990.src::
-enc/trans/JIS/UCS%JISX0212.src::
+[enc/trans/JIS/JISX0201-KANA%UCS.src]
+[enc/trans/JIS/JISX0208\@1990%UCS.src]
+[enc/trans/JIS/JISX0212%UCS.src]
+[enc/trans/JIS/UCS%JISX0201-KANA.src]
+[enc/trans/JIS/UCS%JISX0208@1990.src]
+[enc/trans/JIS/UCS%JISX0212.src]
These files are copyrighted as the following.
@@ -179,49 +264,64 @@ enc/trans/JIS/UCS%JISX0212.src::
For terms of use, see http://www.unicode.org/terms_of_use.html
-enc/trans/JIS/JISX0213-1%UCS@BMP.src::
-enc/trans/JIS/JISX0213-1%UCS@SIP.src::
-enc/trans/JIS/JISX0213-2%UCS@BMP.src::
-enc/trans/JIS/JISX0213-2%UCS@SIP.src::
+[enc/trans/JIS/JISX0213-1%UCS@BMP.src]
+[enc/trans/JIS/JISX0213-1%UCS@SIP.src]
+[enc/trans/JIS/JISX0213-2%UCS@BMP.src]
+[enc/trans/JIS/JISX0213-2%UCS@SIP.src]
These files are copyrighted as the following.
>>>
- Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved.
- Copyright (C) 2001 I'O, All Rights Reserved.
- Copyright (C) 2006 Project X0213, All Rights Reserved.
+ Copyright (C) 2001:: earthian@tama.or.jp, All Rights Reserved.
+ Copyright (C) 2001:: I'O, All Rights Reserved.
+ Copyright (C) 2006:: Project X0213, All Rights Reserved.
You can use, modify, distribute this table freely.
-enc/trans/JIS/UCS@BMP%JISX0213-1.src::
-enc/trans/JIS/UCS@BMP%JISX0213-2.src::
-enc/trans/JIS/UCS@SIP%JISX0213-1.src::
-enc/trans/JIS/UCS@SIP%JISX0213-2.src::
+[enc/trans/JIS/UCS@BMP%JISX0213-1.src]
+[enc/trans/JIS/UCS@BMP%JISX0213-2.src]
+[enc/trans/JIS/UCS@SIP%JISX0213-1.src]
+[enc/trans/JIS/UCS@SIP%JISX0213-2.src]
These files are copyrighted as the following.
>>>
- Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved.
- Copyright (C) 2001 I'O, All Rights Reserved.
+ Copyright (C) 2001:: earthian@tama.or.jp, All Rights Reserved.
+ Copyright (C) 2001:: I'O, All Rights Reserved.
You can use, modify, distribute this table freely.
-configure::
+[enc/trans/ucm/glibc-BIG5-2.3.3.ucm]
+[enc/trans/ucm/glibc-BIG5HKSCS-2.3.3.ucm]
+
+ >>>
+ Copyright (C) 2001-2005:: International Business Machines
+ Corporation and others. All Rights Reserved.
+
+[enc/trans/ucm/windows-950-2000.ucm]
+[enc/trans/ucm/windows-950_hkscs-2001.ucm]
+
+ >>>
+ Copyright (C) 2001-2002:: International Business Machines
+ Corporation and others. All Rights Reserved.
+
+
+[configure]
This file is free software.
>>>
- Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+ Copyright (C) 1992-1996, 1998-2012:: Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
-tool/config.guess::
-tool/config.sub::
+[tool/config.guess]
+[tool/config.sub]
As long as you distribute these files with the file configure, they
are covered under the Ruby's license.
>>>
- Copyright 1992-2018 Free Software Foundation, Inc.
+ Copyright 1992-2018:: Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@@ -243,14 +343,43 @@ tool/config.sub::
program. This Exception is an additional permission under section 7
of the GNU General Public License, version 3 ("GPLv3").
-parse.c::
+[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.
- This file is licensed under the GPL, but is incorporated into Ruby and
+[parse.c]
+[parse.h]
+
+ These files are licensed under the GPL, but are incorporated into Ruby and
redistributed under the terms of the Ruby license, as permitted by the
exception to the GPL below.
>>>
- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018:: Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -278,12 +407,12 @@ parse.c::
This special exception was added by the Free Software Foundation in
version 2.2 of Bison.
-missing/dtoa.c::
+[missing/dtoa.c]
This file is under these licenses.
>>>
- Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ Copyright (c) 1991, 2000, 2001:: by Lucent Technologies.
Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice
@@ -297,8 +426,8 @@ missing/dtoa.c::
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
>>>
- Copyright (c) 2004-2008 David Schultz <das@FreeBSD.ORG>
- All rights reserved.
+ Copyright (c) 2004-2008:: David Schultz <das@FreeBSD.ORG>
+ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -321,32 +450,34 @@ missing/dtoa.c::
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-win32/win32.{c,h}::
+[win32/win32.c]
+[include/ruby/win32.h]
You can apply the Artistic License to these files. (or GPL,
alternatively)
>>>
- Copyright (c) 1993, Intergraph Corporation
+ Copyright (c) 1993:: Intergraph Corporation
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the perl README file.
-missing/mt19937.c::
+[missing/mt19937.c]
This file is under the new-style BSD license.
>>>
- A C-program for MT19937, with initialization improved 2002/2/10.
- Coded by Takuji Nishimura and Makoto Matsumoto.
+ A C-program for MT19937, with initialization improved 2002/2/10.::
+ 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.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
+ Copyright (C) 1997 - 2002:: Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -382,13 +513,13 @@ missing/mt19937.c::
The Wayback Machine url: http://web.archive.org/web/19990429082237/http://www.math.keio.ac.jp/matumoto/emt.html
-missing/procstat_vm.c::
+[missing/procstat_vm.c]
This file is under the new-style BSD license.
>>>
- Copyright (c) 2007 Robert N. M. Watson
- All rights reserved.
+ Copyright (c) 2007:: Robert N. M. Watson
+ All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -413,151 +544,65 @@ missing/procstat_vm.c::
$FreeBSD: head/usr.bin/procstat/procstat_vm.c 261780 2014-02-11 21:57:37Z jhb $
-vsnprintf.c::
+[vsnprintf.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
>>>
- Copyright (c) 1990, 1993
+ Copyright (c) 1990, 1993::
The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Chris Torek.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
- IMPORTANT NOTE:
- --------------
- From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
- paragraph 3 above is now null and void.
-
-st.c::
-strftime.c::
-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::
-missing/strchr.c::
-missing/strerror.c::
-missing/strstr.c::
-missing/tgamma.c::
-ext/date/date_strftime.c::
-ext/digest/sha1/sha1.c::
-ext/digest/sha1/sha1.h::
-ext/sdbm/_sdbm.c::
-ext/sdbm/sdbm.h::
+[st.c]
+[strftime.c]
+[include/ruby/st.h]
+[missing/acosh.c]
+[missing/alloca.c]
+[missing/erf.c]
+[missing/hypot.c]
+[missing/lgamma_r.c]
+[missing/memcmp.c]
+[missing/memmove.c]
+[missing/strchr.c]
+[missing/strerror.c]
+[missing/strstr.c]
+[missing/tgamma.c]
+[ext/date/date_strftime.c]
+[ext/digest/sha1/sha1.c]
+[ext/digest/sha1/sha1.h]
These files are all under public domain.
-missing/crypt.c::
+[missing/crypt.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
>>>
- Copyright (c) 1989, 1993
+ Copyright (c) 1989, 1993::
The Regents of the University of California. All rights reserved.
This code is derived from software contributed to Berkeley by
Tom Truscott.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-missing/setproctitle.c::
+[missing/setproctitle.c]
- This file is under the old-style BSD license. Note that the
- paragraph 3 below is now null and void.
+ This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license].
>>>
- Copyright 2003 Damien Miller
- Copyright (c) 1983, 1995-1997 Eric P. Allman
- Copyright (c) 1988, 1993
+ Copyright 2003:: Damien Miller
+ Copyright (c) 1983, 1995-1997:: Eric P. Allman
+ Copyright (c) 1988, 1993::
The Regents of the University of California. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-
-missing/strlcat.c::
-missing/strlcpy.c::
+[missing/strlcat.c]
+[missing/strlcpy.c]
These files are under an ISC-style license.
>>>
- Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ Copyright (c) 1998, 2015:: Todd C. Miller <Todd.Miller@courtesan.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -571,26 +616,26 @@ missing/strlcpy.c::
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-missing/langinfo.c::
+[missing/langinfo.c]
This file is from http://www.cl.cam.ac.uk/~mgk25/ucs/langinfo.c.
Ruby uses a modified version. The file contains the following
author/copyright notice:
>>>
- Markus.Kuhn@cl.cam.ac.uk -- 2002-03-11
+ Markus.Kuhn@cl.cam.ac.uk -- 2002-03-11::
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted. The author
disclaims all warranties with regard to this software.
-ext/digest/md5/md5.c::
-ext/digest/md5/md5.h::
+[ext/digest/md5/md5.c]
+[ext/digest/md5/md5.h]
These files are under the following license. Ruby uses modified
versions of them.
>>>
- Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved.
+ Copyright (C) 1999, 2000:: Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -611,8 +656,8 @@ ext/digest/md5/md5.h::
L. Peter Deutsch
ghost@aladdin.com
-ext/digest/rmd160/rmd160.c::
-ext/digest/rmd160/rmd160.h::
+[ext/digest/rmd160/rmd160.c]
+[ext/digest/rmd160/rmd160.h]
These files have the following copyright information, and by the
author we are allowed to use it under the new-style BSD license.
@@ -622,16 +667,16 @@ ext/digest/rmd160/rmd160.h::
(Arranged for libc by Todd C. Miller)
DATE:: 1 March 1996
- Copyright (c) Katholieke Universiteit Leuven
+ Copyright (c):: Katholieke Universiteit Leuven
1996, All Rights Reserved
-ext/digest/sha2/sha2.c::
-ext/digest/sha2/sha2.h::
+[ext/digest/sha2/sha2.c]
+[ext/digest/sha2/sha2.h]
These files are under the new-style BSD license.
>>>
- Copyright 2000 Aaron D. Gifford. All rights reserved.
+ Copyright 2000:: Aaron D. Gifford. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -657,12 +702,12 @@ ext/digest/sha2/sha2.h::
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-ext/json/generator/generator.c::
+[ext/json/generator/generator.c]
The file contains the following copyright notice.
>>>
- Copyright 2001-2004 Unicode, Inc.
+ Copyright 2001-2004:: Unicode, Inc.
Disclaimer::
@@ -682,15 +727,15 @@ ext/json/generator/generator.c::
for internal or external distribution as long as this notice
remains attached.
-ext/nkf/nkf-utf8/config.h::
-ext/nkf/nkf-utf8/nkf.c::
-ext/nkf/nkf-utf8/utf8tbl.c::
+[ext/nkf/nkf-utf8/config.h]
+[ext/nkf/nkf-utf8/nkf.c]
+[ext/nkf/nkf-utf8/utf8tbl.c]
These files are under the following license. So to speak, it is
copyrighted semi-public-domain software.
>>>
- Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
+ Copyright (C) 1987:: Fujitsu LTD. (Itaru ICHIKAWA)
Everyone is permitted to do anything on this program
including copying, modifying, improving,
@@ -700,14 +745,14 @@ ext/nkf/nkf-utf8/utf8tbl.c::
You don't have to ask before copying, redistribution or publishing.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
-ext/psych::
-test/psych::
+[ext/psych]
+[test/psych]
The files under these directories are under the following license, except for
ext/psych/yaml.
>>>
- Copyright 2009 Aaron Patterson, et al.
+ Copyright 2009:: Aaron Patterson, et al.
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
@@ -727,12 +772,12 @@ test/psych::
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-ext/psych/yaml::
+[ext/psych/yaml]
The files under this directory are under the following license.
>>>
- Copyright (c) 2006 Kirill Simonov
+ Copyright (c) 2006:: Kirill Simonov
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
@@ -752,14 +797,28 @@ ext/psych/yaml::
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-ext/socket/addrinfo.h::
-ext/socket/getaddrinfo.c::
-ext/socket/getnameinfo.c::
+[ext/pty/pty.c]
+
+ >>>
+ C) Copyright 1998:: by Akinori Ito.
+
+ This software may be redistributed freely for this purpose, in full
+ or in part, provided that this entire copyright notice is included
+ on any copies of this software and applications and derivations thereof.
+
+ This software is provided on an "as is" basis, without warranty of any
+ kind, either expressed or implied, as to any matter including, but not
+ limited to warranty of fitness of purpose, or merchantability, or
+ results obtained from use of this software.
+
+[ext/socket/addrinfo.h]
+[ext/socket/getaddrinfo.c]
+[ext/socket/getnameinfo.c]
These files are under the new-style BSD license.
>>>
- Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ Copyright (C) 1995, 1996, 1997, 1998, and 1999:: WIDE Project.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -786,16 +845,16 @@ ext/socket/getnameinfo.c::
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-ext/win32ole/win32ole.c::
+[ext/win32ole/win32ole.c]
You can apply the Artistic License to this file. (or GPL,
alternatively)
>>>
- (c) 1995 Microsoft Corporation. All rights reserved.
+ (c) 1995:: Microsoft Corporation. All rights reserved.
Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
- Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
+ Other modifications Copyright (c) 1997, 1998:: by Gurusamy Sarathy
<gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
You may distribute under the terms of either the GNU General Public
@@ -804,20 +863,17 @@ ext/win32ole/win32ole.c::
The Wayback Machine url: http://web.archive.org/web/19970607104352/http://www.activeware.com:80/
-lib/rdoc/generator/template/darkfish/css/fonts.css::
+[lib/rdoc/generator/template/darkfish/css/fonts.css]
- This file is licensed under the SIL Open Font License.
+ This file is licensed under the {SIL Open Font License}[http://scripts.sil.org/OFL].
- >>>
- http://scripts.sil.org/OFL
-
-spec/mspec::
-spec/ruby::
+[spec/mspec]
+[spec/ruby]
The files under these directories are under the following license.
>>>
- Copyright (c) 2008 Engine Yard, Inc. All rights reserved.
+ Copyright (c) 2008:: Engine Yard, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -840,17 +896,17 @@ spec/ruby::
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
-lib/rubygems.rb::
-lib/rubygems::
-test/rubygems::
+[lib/rubygems.rb]
+[lib/rubygems]
+[test/rubygems]
RubyGems is under the following license.
>>>
RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
Weirich and others. You can redistribute it and/or modify it under
- either the terms of the MIT license (see the file MIT.txt), or the
- conditions below:
+ either the terms of the {MIT license}[rdoc-label:label-MIT+License], or the conditions
+ below:
1. You may make and give away verbatim copies of the source form of the
software without restriction, provided that you duplicate all of the
@@ -901,20 +957,117 @@ test/rubygems::
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
-lib/bundler::
-lib/bundler.rb::
-lib/bundler.gemspec::
-spec/bundler::
-man/bundle-*,gemfile.*::
+[lib/bundler]
+[lib/bundler.rb]
+[spec/bundler]
Bundler is under the following license.
>>>
- Portions copyright (c) 2010 Andre Arko
- Portions copyright (c) 2009 Engine Yard
+ Portions copyright (c) 2010:: Andre Arko
+ Portions copyright (c) 2009:: Engine Yard
+
+ {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::
+ {MIT License}[rdoc-label:label-MIT+License]
+[lib/did_you_mean]
+[lib/did_you_mean.rb]
+[test/did_you_mean]
+
+ did_you_mean is under the following license.
+
+ >>>
+ Copyright (c) 2014-2016 Yuki Nishijima
+
+ {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]
+[benchmark/so_concatenate.rb]
+[benchmark/so_count_words.yml]
+[benchmark/so_exception.rb]
+[benchmark/so_fannkuch.rb]
+[benchmark/so_fasta.rb]
+[benchmark/so_k_nucleotide.yml]
+[benchmark/so_lists.rb]
+[benchmark/so_mandelbrot.rb]
+[benchmark/so_matrix.rb]
+[benchmark/so_meteor_contest.rb]
+[benchmark/so_nbody.rb]
+[benchmark/so_nested_loop.rb]
+[benchmark/so_nsieve.rb]
+[benchmark/so_nsieve_bits.rb]
+[benchmark/so_object.rb]
+[benchmark/so_partial_sums.rb]
+[benchmark/so_pidigits.rb]
+[benchmark/so_random.rb]
+[benchmark/so_reverse_complement.yml]
+[benchmark/so_sieve.rb]
+[benchmark/so_spectralnorm.rb]
+
+ These files are very old copy of then-called "The Great Computer Language
+ Shootout". LEGAL SITUATION OF THESE FILES ARE UNCLEAR because the original
+ site has been lost. Upstream diverged to delete several benchmarks listed
+ above.
+
+== MIT License
+>>>
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
@@ -933,3 +1086,34 @@ man/bundle-*,gemfile.*::
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.
+
+== Old-style BSD license
+>>>
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ IMPORTANT NOTE::
+
+ From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
+ paragraph 3 above is now null and void.
diff --git a/NEWS.md b/NEWS.md
index 203fa08f78..f6c3c6fc97 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,84 +1,820 @@
-# NEWS for Ruby 2.8.0 (tentative; to be 3.0.0)
+# NEWS for Ruby 3.2.0
-This document is a list of user visible feature changes
-since the **2.7.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
-* $SAFE is now a normal global variable with no special behavior.
- [[Feature #16131]]
+* 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
+
+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)
+ ```
-* yield in singleton class definitions in methods is now a SyntaxError.
- [[Feature #15575]]
+ * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`.
+ [[Feature #19036]]
-## Command line options
+* Class
-## Core classes updates (outstanding ones only)
+ * 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]]
-* Dir
+ ```ruby
+ class Foo; end
- * Modified method
+ 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
+ ```
- * Dir.glob and Dir.[] now sort the results by default, and
- accept `sort:` keyword option. [[Feature #8709]]
+* 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
- * Modified method
+ * Hash#shift now always returns nil if the hash is
+ empty, instead of returning the default value or
+ calling the default proc. [[Bug #16908]]
- * Hash#transform_keys now accepts a hash that maps keys to new
- keys. [[Feature #16274]]
+* Integer
-* Symbol
+ * Integer#ceildiv has been added. [[Feature #18809]]
- * Modified method
+* Kernel
- * Symbol#to_proc now returns a lambda Proc.
- [[Feature #16260]]
+ * Kernel#binding raises RuntimeError if called from a non-Ruby frame
+ (such as a method defined in C). [[Bug #18487]]
-## Stdlib updates (outstanding ones only)
+* MatchData
-* Net::HTTP
+ * MatchData#byteoffset has been added. [[Feature #13110]]
+ * MatchData#deconstruct has been added. [[Feature #18821]]
+ * MatchData#deconstruct_keys has been added. [[Feature #18821]]
- * New method
+* Module
- * Add Net::HTTP#verify_hostname= and Net::HTTP#verify_hostname
- to skip hostname verification. [[Feature #16555]]
+ * 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]]
-## Compatibility issues (excluding feature bug fixes)
+* Proc
-* Regexp literals are frozen [[Feature #8948]] [[Feature #16377]]
+ * Proc#dup returns an instance of subclass. [[Bug #17545]]
+ * Proc#parameters now accepts lambda keyword. [[Feature #15357]]
- ```ruby
- /foo/.frozen? #=> true
+* 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
+
+* 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
+
+* `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
```
-* Bundled gems
+ [[Feature #18571]]
- * net-telnet and xmlrpc have been removed from the bundled gems.
- If you are interested in maintaining them, please comment on
- your plan to https://github.com/ruby/xmlrpc
- or https://github.com/ruby/net-telnet.
+* Check cookie name/path/domain characters in `CGI::Cookie`. [[CVE-2021-33621]]
-## Stdlib compatibility issues (excluding feature bug fixes)
+* `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
-## Miscellaneous changes
+* 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
+
+* 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.
+
+### MJIT
+* 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.
-[Feature #8709]: https://bugs.ruby-lang.org/issues/8709
-[Feature #8948]: https://bugs.ruby-lang.org/issues/8948
-[Feature #15575]: https://bugs.ruby-lang.org/issues/15575
-[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
-[Feature #16260]: https://bugs.ruby-lang.org/issues/16260
-[Feature #16274]: https://bugs.ruby-lang.org/issues/16274
-[Feature #16377]: https://bugs.ruby-lang.org/issues/16377
-[Feature #16555]: https://bugs.ruby-lang.org/issues/16555
+[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 bee6433c62..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](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
-[![Actions Status](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
-[![Actions Status](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
-[![Actions Status](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
-[![Actions Status](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
+[![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 378f48f8d7..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](https://github.com/ruby/ruby/workflows/macOS/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"macOS")
-[![Actions Status](https://github.com/ruby/ruby/workflows/MinGW/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW")
-[![Actions Status](https://github.com/ruby/ruby/workflows/MJIT/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT")
-[![Actions Status](https://github.com/ruby/ruby/workflows/Ubuntu/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu")
-[![Actions Status](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
+[![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, Haiku, etc.) cf.
- https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#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,103 +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.
-
- 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`.
+in the mail body (not subject) to the address [ruby-talk-request@ruby-lang.org].
- 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. Optionally, run `make update-gems` and `make extract-gems`.
-
- If you want to install bundled gems, run `make update-gems` and
- `make extract-gems` before running `make install`.
-
-9. 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 ed7d14ef63..e69de29bb2 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,47 +0,0 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
-
-# Copyright (C) 1996-2018 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_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 c6704858a9..e5f25293e2 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -13,7 +13,7 @@
#pragma clang diagnostic ignored "-Wgcc-compat"
#endif
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include "ruby/defines.h"
#include "ruby/missing.h"
#include "addr2line.h"
@@ -25,7 +25,7 @@
#include <libproc.h>
#endif
-#include "internal/stdbool.h"
+#include "ruby/internal/stdbool.h"
#if defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)
@@ -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;
@@ -526,13 +562,25 @@ append_obj(obj_info_t **objp)
}
#ifdef USE_ELF
+/* Ideally we should check 4 paths to follow gnu_debuglink:
+ *
+ * - /usr/lib/debug/.build-id/ab/cdef1234.debug
+ * - /usr/bin/ruby.debug
+ * - /usr/bin/.debug/ruby.debug
+ * - /usr/lib/debug/usr/bin/ruby.debug.
+ *
+ * but we handle only two cases for now as the two formats are
+ * used by some linux distributions.
+ *
+ * See GDB's info for detail.
+ * https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
+ */
+
+// check the path pattern of "/usr/lib/debug/usr/bin/ruby.debug"
static void
follow_debuglink(const char *debuglink, int num_traces, void **traces,
obj_info_t **objp, line_info_t *lines, int offset)
{
- /* Ideally we should check 4 paths to follow gnu_debuglink,
- but we handle only one case for now as this format is used
- by some linux distributions. See GDB's info for detail. */
static const char global_debug_dir[] = "/usr/lib/debug";
const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
char *p;
@@ -559,6 +607,37 @@ follow_debuglink(const char *debuglink, int num_traces, void **traces,
o2->path = o1->path;
fill_lines(num_traces, traces, 0, objp, lines, offset);
}
+
+// check the path pattern of "/usr/lib/debug/.build-id/ab/cdef1234.debug"
+static void
+follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_traces, void **traces,
+ obj_info_t **objp, line_info_t *lines, int offset)
+{
+ static const char global_debug_dir[] = "/usr/lib/debug/.build-id/";
+ const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
+ char *p;
+ obj_info_t *o1 = *objp, *o2;
+ size_t i;
+
+ if (PATH_MAX < global_debug_dir_len + 1 + build_id_size * 2 + 6) return;
+
+ memcpy(binary_filename, global_debug_dir, global_debug_dir_len);
+ p = binary_filename + global_debug_dir_len;
+ for (i = 0; i < build_id_size; i++) {
+ static const char tbl[] = "0123456789abcdef";
+ unsigned char n = build_id[i];
+ *p++ = tbl[n / 16];
+ *p++ = tbl[n % 16];
+ if (i == 0) *p++ = '/';
+ }
+ strcpy(p, ".debug");
+
+ append_obj(objp);
+ o2 = *objp;
+ o2->base_addr = o1->base_addr;
+ o2->path = o1->path;
+ fill_lines(num_traces, traces, 0, objp, lines, offset);
+}
#endif
enum
@@ -764,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 {
@@ -800,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;
@@ -811,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)
@@ -833,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);
@@ -873,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);
@@ -914,13 +1016,34 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
reader->p = obj->debug_info.ptr;
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;
@@ -930,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);
}
}
@@ -946,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;
@@ -957,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;
@@ -971,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;
@@ -979,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;
@@ -987,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;
@@ -1003,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);
@@ -1067,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:
@@ -1115,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));
@@ -1134,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));
@@ -1153,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;
@@ -1188,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];
}
@@ -1199,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);
@@ -1212,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;
}
@@ -1231,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]);
@@ -1252,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;
}
@@ -1312,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;
@@ -1322,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) {
@@ -1358,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);
@@ -1369,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;
}
}
}
@@ -1427,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;
}
@@ -1459,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 */
@@ -1505,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 = {};
@@ -1531,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;
@@ -1539,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;
@@ -1547,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; */
}
}
@@ -1556,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));
@@ -1577,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;
@@ -1601,6 +1995,7 @@ uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
fail:
free(*ptr);
+ *ptr = NULL;
#endif
return 0;
}
@@ -1615,6 +2010,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
ElfW(Ehdr) *ehdr;
ElfW(Shdr) *shdr, *shstr_shdr;
ElfW(Shdr) *gnu_debuglink_shdr = NULL;
+ ElfW(Shdr) *note_gnu_build_id = NULL;
int fd;
off_t filesize;
char *file;
@@ -1687,6 +2083,11 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
/* if (!strcmp(section_name, ".dynsym")) */
dynsym_shdr = shdr + i;
break;
+ case SHT_NOTE:
+ if (!strcmp(section_name, ".note.gnu.build-id")) {
+ note_gnu_build_id = shdr + i;
+ }
+ break;
case SHT_PROGBITS:
if (!strcmp(section_name, ".gnu_debuglink")) {
gnu_debuglink_shdr = shdr + i;
@@ -1697,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++) {
@@ -1802,6 +2207,13 @@ use_symtab:
num_traces, traces,
objp, lines, offset);
}
+ if (note_gnu_build_id && check_debuglink) {
+ ElfW(Nhdr) *nhdr = (ElfW(Nhdr)*) (file + note_gnu_build_id->sh_offset);
+ const char *build_id = (char *)(nhdr + 1) + nhdr->n_namesz;
+ follow_debuglink_build_id(build_id, nhdr->n_descsz,
+ num_traces, traces,
+ objp, lines, offset);
+ }
goto finish;
}
@@ -1946,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) {
@@ -1983,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];
@@ -2035,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)
@@ -2044,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)
{
@@ -2098,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);
@@ -2137,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;
@@ -2167,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;
}
}
@@ -2178,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/addr2line.h b/addr2line.h
index 4f6cf179ef..f09b665800 100644
--- a/addr2line.h
+++ b/addr2line.h
@@ -1,3 +1,5 @@
+#ifndef RUBY_ADDR2LINE_H
+#define RUBY_ADDR2LINE_H
/**********************************************************************
addr2line.h -
@@ -8,9 +10,6 @@
**********************************************************************/
-#ifndef RUBY_ADDR2LINE_H
-#define RUBY_ADDR2LINE_H
-
#if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H))
void
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 17efe005a0..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,94 +0,0 @@
----
-version: '{build}'
-shallow_clone: true
-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% up incs
- - del Makefile
- - mkdir \usr\local\bin
- - mkdir \usr\local\include
- - mkdir \usr\local\lib
- - curl -fsSL -o zlib%zlib_version:.=%.zip --retry 10 https://zlib.net/zlib%zlib_version:.=%.zip
- - 7z x -o%APPVEYOR_BUILD_FOLDER%\ext\zlib zlib%zlib_version:.=%.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:
- # Using "Webhook" with templated body to skip notification on Pull Request
- - provider: Webhook
- method: POST
- url:
- secure: iMINHMS0nZabaDsxN9omRDsekxzVvAAzEq5ev7lN6vb+gUETT+rbDKLGxBxBpEpxlnPlLdzroIJ+DTKlwfJA8VkGawTn9EXNsucH0OkSf2M= # AppVeyor CI
- body: >-
- {{^isPullRequest}}
- {
- "attachments": [
- {
- "text": "Build <{{buildUrl}}|#{{buildVersion}}> (<{{commitUrl}}|{{commitId}}>) of {{repositoryName}}@{{branch}} by {{commitAuthor}} {{status}}",
- "color": "{{#passed}}good{{/passed}}{{#failed}}danger{{/failed}}"
- }
- ],
- "channel": "#alerts"
- }
- {{/isPullRequest}}
- on_build_success: false
- on_build_failure: true
- on_build_status_changed: false
diff --git a/array.c b/array.c
index d5650cfeed..b76e9a64a3 100644
--- a/array.c
+++ b/array.c
@@ -32,12 +32,44 @@
#include "builtin.h"
#if !ARRAY_DEBUG
+# undef NDEBUG
# define NDEBUG
#endif
#include "ruby_assert.h"
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
@@ -45,28 +77,13 @@ VALUE rb_cArray;
#define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
#define SMALL_ARRAY_LEN 16
+RBIMPL_ATTR_MAYBE_UNUSED()
static int
should_be_T_ARRAY(VALUE ary)
{
return RB_TYPE_P(ary, T_ARRAY);
}
-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)), \
@@ -76,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)); \
@@ -92,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)); \
@@ -104,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)
@@ -136,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)); \
@@ -145,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); \
@@ -180,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__)
@@ -189,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
@@ -216,9 +290,11 @@ ary_verify_(VALUE ary, const char *file, int line)
#endif
}
+#if USE_TRANSIENT_HEAP
if (RARRAY_TRANSIENT_P(ary)) {
assert(rb_transient_heap_managed_ptr_p(RARRAY_CONST_PTR_TRANSIENT(ary)));
}
+#endif
rb_transient_heap_verify();
@@ -255,7 +331,7 @@ void
rb_mem_clear(VALUE *mem, long size)
{
while (size--) {
- *mem++ = Qnil;
+ *mem++ = Qnil;
}
}
@@ -263,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);
});
}
@@ -271,7 +347,7 @@ static inline void
memfill(register VALUE *mem, register long size, register VALUE val)
{
while (size--) {
- *mem++ = val;
+ *mem++ = val;
}
}
@@ -279,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);
});
}
@@ -349,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);
@@ -374,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
@@ -381,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));
@@ -430,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)
{
@@ -437,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);
@@ -448,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)) {
@@ -488,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);
@@ -502,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;
@@ -557,34 +657,33 @@ rb_ary_modify_check(VALUE ary)
}
void
-rb_ary_modify(VALUE ary)
+rb_ary_cancel_sharing(VALUE ary)
{
- rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
- long shared_len, len = RARRAY_LEN(ary);
+ long shared_len, len = RARRAY_LEN(ary);
VALUE shared_root = ARY_SHARED_ROOT(ary);
ary_verify(shared_root);
- if (len <= RARRAY_EMBED_LEN_MAX) {
- const VALUE *ptr = ARY_HEAP_PTR(ary);
+ if (len <= ary_embed_capa(ary)) {
+ const VALUE *ptr = ARY_HEAP_PTR(ary);
FL_UNSET_SHARED(ary);
FL_SET_EMBED(ary);
- MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
+ MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
rb_ary_decrement_share(shared_root);
ARY_SET_EMBED_LEN(ary, len);
}
else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) {
long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root);
- FL_UNSET_SHARED(ary);
+ FL_UNSET_SHARED(ary);
ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root));
- ARY_SET_CAPA(ary, shared_len);
+ ARY_SET_CAPA(ary, shared_len);
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr, ptr+shift, VALUE, len);
- });
+ MEMMOVE(ptr, ptr+shift, VALUE, len);
+ });
FL_SET_EMBED(shared_root);
rb_ary_decrement_share(shared_root);
- }
+ }
else {
VALUE *ptr = ary_heap_alloc(ary, len);
MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
@@ -593,11 +692,18 @@ rb_ary_modify(VALUE ary)
ARY_SET_PTR(ary, ptr);
}
- rb_gc_writebarrier_remember(ary);
+ rb_gc_writebarrier_remember(ary);
}
ary_verify(ary);
}
+void
+rb_ary_modify(VALUE ary)
+{
+ rb_ary_modify_check(ary);
+ rb_ary_cancel_sharing(ary);
+}
+
static VALUE
ary_ensure_room_for_push(VALUE ary, long add_len)
{
@@ -606,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);
@@ -648,12 +754,16 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
/*
* call-seq:
- * ary.freeze -> ary
+ * array.freeze -> self
*
- * Calls Object#freeze on +ary+ to prevent any further
- * modification. A RuntimeError will be raised if a modification
- * attempt is made.
+ * Freezes +self+; returns +self+:
*
+ * a = []
+ * a.frozen? # => false
+ * a.freeze
+ * a.frozen? # => true
+ *
+ * An attempt to modify a frozen \Array raises FrozenError.
*/
VALUE
@@ -673,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);
@@ -693,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
@@ -705,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);
}
@@ -734,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
@@ -748,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);
@@ -763,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;
@@ -776,8 +906,79 @@ rb_ary_new_from_values(long n, const VALUE *elts)
return rb_ary_tmp_new_from_values(rb_cArray, n, elts);
}
+static VALUE
+ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa)
+{
+ 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);
+ */
+ return (VALUE)ary;
+}
+
+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)");
+ }
+ if (capa > ARY_MAX_SIZE) {
+ rb_raise(rb_eArgError, "array size too big");
+ }
+
+ RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
+
+ 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));
+
+ ptr = ary_heap_alloc(ary, capa);
+ ARY_SET_PTR(ary, ptr);
+ ARY_SET_HEAP_LEN(ary, 0);
+ }
+
+ return ary;
+}
+
+VALUE
+rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts)
+{
+ VALUE ary;
+
+ ary = ec_ary_new(ec, rb_cArray, n);
+ if (n > 0 && elts) {
+ 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);
@@ -785,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;
}
@@ -828,63 +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));
-
rb_ary_transient_heap_evacuate(ary, TRUE);
- ptr = ARY_HEAP_PTR(ary);
-
- FL_UNSET_EMBED(shared);
- ARY_SET_LEN((VALUE)shared, capa);
- ARY_SET_PTR((VALUE)shared, ptr);
- ary_mem_clear((VALUE)shared, len, capa - len);
- FL_SET_SHARED_ROOT(shared);
- ARY_SET_SHARED_ROOT_REFCNT((VALUE)shared, 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, (VALUE)shared);
- OBJ_FREEZE(shared);
+ ARY_SET_SHARED(ary, shared);
- ary_verify((VALUE)shared);
+ ary_verify(shared);
ary_verify(ary);
- return (VALUE)shared;
+ return shared;
}
}
@@ -893,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;
@@ -929,23 +1137,24 @@ 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(obj) -> array or nil
+ * Array.try_convert(object) -> object, new_array, or nil
*
- * Tries to convert +obj+ into an array, using the +to_ary+ method. Returns
- * the converted array or +nil+ if +obj+ cannot be converted.
- * This method can be used to check if an argument is an array.
+ * If +object+ is an \Array object, returns +object+.
*
- * Array.try_convert([1]) #=> [1]
- * Array.try_convert("1") #=> nil
+ * Otherwise if +object+ responds to <tt>:to_ary</tt>,
+ * calls <tt>object.to_ary</tt> and returns the result.
*
- * if tmp = Array.try_convert(arg)
- * # the argument is an array
- * elsif tmp = String.try_convert(arg)
- * # the argument is a string
- * end
+ * Returns +nil+ if +object+ does not respond to <tt>:to_ary</tt>
*
+ * Raises an exception unless <tt>object.to_ary</tt> returns an \Array object.
*/
static VALUE
@@ -954,60 +1163,76 @@ 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(size=0, default=nil)
- * Array.new(array)
- * Array.new(size) {|index| block }
- *
- * Returns a new array.
- *
- * In the first form, if no arguments are sent, the new array will be empty.
- * When a +size+ and an optional +default+ are sent, an array is created with
- * +size+ copies of +default+. Take notice that all elements will reference the
- * same object +default+.
- *
- * The second form creates a copy of the array passed as a parameter (the
- * array is generated by calling to_ary on the parameter).
- *
- * first_array = ["Matz", "Guido"]
+ * Array.new -> new_empty_array
+ * Array.new(array) -> new_array
+ * Array.new(size) -> new_array
+ * Array.new(size, default_value) -> new_array
+ * Array.new(size) {|index| ... } -> new_array
*
- * second_array = Array.new(first_array) #=> ["Matz", "Guido"]
+ * Returns a new \Array.
*
- * first_array.equal? second_array #=> false
+ * With no block and no arguments, returns a new empty \Array object.
*
- * In the last form, an array of the given size is created. Each element in
- * this array is created by passing the element's index to the given block
- * and storing the return value.
+ * With no block and a single \Array argument +array+,
+ * returns a new \Array formed from +array+:
*
- * Array.new(3) {|index| index ** 2}
- * # => [0, 1, 4]
+ * a = Array.new([:foo, 'bar', 2])
+ * a.class # => Array
+ * a # => [:foo, "bar", 2]
*
- * == Common gotchas
+ * With no block and a single \Integer argument +size+,
+ * returns a new \Array of the given size
+ * whose elements are all +nil+:
*
- * When sending the second parameter, the same object will be used as the
- * value for all the array elements:
+ * a = Array.new(3)
+ * a # => [nil, nil, nil]
*
- * a = Array.new(2, Hash.new)
- * # => [{}, {}]
+ * With no block and arguments +size+ and +default_value+,
+ * returns an \Array of the given size;
+ * each element is that same +default_value+:
*
- * a[0]['cat'] = 'feline'
- * a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
+ * a = Array.new(3, 'x')
+ * a # => ['x', 'x', 'x']
*
- * a[1]['cat'] = 'Felix'
- * a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
+ * With a block and argument +size+,
+ * 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:
*
- * Since all the Array elements store the same hash, changes to one of them
- * will affect them all.
+ * a = Array.new(3) {|index| "Element #{index}" }
+ * a # => ["Element 0", "Element 1", "Element 2"]
*
- * If multiple copies are what you want, you should use the block
- * version which uses the result of that block each time an element
- * of the array needs to be initialized:
- *
- * a = Array.new(2) {Hash.new}
- * a[0]['cat'] = 'feline'
- * a # => [{"cat"=>"feline"}, {}]
+ * Raises ArgumentError if +size+ is negative.
*
+ * With a block and no argument,
+ * or a single argument +0+,
+ * ignores the block and returns a new empty \Array.
*/
static VALUE
@@ -1018,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;
}
@@ -1093,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);
}
@@ -1124,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);
@@ -1149,9 +1374,59 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
}
static VALUE
+ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
+{
+ assert(offset >= 0);
+ assert(len >= 0);
+ assert(offset+len <= RARRAY_LEN(ary));
+ assert(step != 0);
+
+ const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary);
+ const long orig_len = 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 = roomof(len, ustep);
+
+ long i;
+ long j = offset + ((step > 0) ? 0 : (orig_len - 1));
+
+ VALUE result = ary_new(klass, len);
+ 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]);
+ j += step;
+ }
+ ARY_SET_EMBED_LEN(result, len);
+ }
+ else {
+ RARRAY_PTR_USE_TRANSIENT(result, ptr, {
+ for (i = 0; i < len; ++i) {
+ RB_OBJ_WRITE(result, ptr+i, values[j]);
+ j += step;
+ }
+ });
+ ARY_SET_LEN(result, len);
+ }
+
+ return result;
+}
+
+static VALUE
ary_make_shared_copy(VALUE ary)
{
- return ary_make_partial(ary, rb_obj_class(ary), 0, RARRAY_LEN(ary));
+ return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
}
enum ary_take_pos_flags
@@ -1176,30 +1451,31 @@ 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);
}
/*
* call-seq:
- * ary << obj -> ary
+ * array << object -> self
+ *
+ * Appends +object+ to +self+; returns +self+:
*
- * Append---Pushes the given object on to the end of this array. This
- * expression returns the array itself, so several appends
- * may be chained together.
+ * a = [:foo, 'bar', 2]
+ * a << :baz # => [:foo, "bar", 2, :baz]
*
- * a = [ 1, 2 ]
- * a << "c" << "d" << [ 3, 4 ]
- * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
- * a
- * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
+ * 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]]
*
*/
@@ -1209,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);
@@ -1228,19 +1504,24 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len)
/*
* call-seq:
- * ary.push(obj, ...) -> ary
- * ary.append(obj, ...) -> ary
- *
- * Append --- Pushes the given object(s) on to the end of this array. This
- * expression returns the array itself, so several appends
- * may be chained together. See also Array#pop for the opposite
- * effect.
- *
- * a = [ "a", "b", "c" ]
- * a.push("d", "e", "f")
- * #=> ["a", "b", "c", "d", "e", "f"]
- * [1, 2, 3].push(4).push(5)
- * #=> [1, 2, 3, 4, 5]
+ * array.push(*objects) -> self
+ *
+ * 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.
+ *
+ * Related: #pop, #shift, #unshift.
*/
static VALUE
@@ -1257,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);
@@ -1270,20 +1551,33 @@ rb_ary_pop(VALUE ary)
/*
* call-seq:
- * ary.pop -> obj or nil
- * ary.pop(n) -> new_ary
+ * array.pop -> object or nil
+ * array.pop(n) -> new_array
+ *
+ * Removes and returns trailing elements.
+ *
+ * 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"]
*
- * Removes the last element from +self+ and returns it, or
- * +nil+ if the array is empty.
+ * Returns +nil+ if the array is empty.
*
- * If a number +n+ is given, returns an array of the last +n+ elements
- * (or less) just like <code>array.slice!(-n, n)</code> does. See also
- * Array#push for the opposite effect.
+ * When a non-negative \Integer argument +n+ is given and is in range,
*
- * a = [ "a", "b", "c", "d" ]
- * a.pop #=> "d"
- * a.pop(2) #=> ["b", "c"]
- * a #=> ["a"]
+ * 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]
+ *
+ * Related: #push, #shift, #unshift.
*/
static VALUE
@@ -1292,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);
@@ -1308,55 +1602,49 @@ 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;
}
/*
* call-seq:
- * ary.shift -> obj or nil
- * ary.shift(n) -> new_ary
+ * array.shift -> object or nil
+ * array.shift(n) -> new_array
+ *
+ * Removes and returns leading elements.
+ *
+ * When no argument is given, removes and returns the first element:
*
- * Removes the first element of +self+ and returns it (shifting all
- * other elements down by one). Returns +nil+ if the array
- * is empty.
+ * a = [:foo, 'bar', 2]
+ * a.shift # => :foo
+ * a # => ['bar', 2]
*
- * If a number +n+ is given, returns an array of the first +n+ elements
- * (or less) just like <code>array.slice!(0, n)</code> does. With +ary+
- * containing only the remainder elements, not including what was shifted to
- * +new_ary+. See also Array#unshift for the opposite effect.
+ * Returns +nil+ if +self+ is empty.
*
- * args = [ "-m", "-q", "filename" ]
- * args.shift #=> "-m"
- * args #=> ["-q", "filename"]
+ * When positive \Integer argument +n+ is given, removes the first +n+ elements;
+ * returns those elements in a new \Array:
*
- * args = [ "-m", "-q", "filename" ]
- * args.shift(2) #=> ["-m", "-q"]
- * args #=> ["filename"]
+ * 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]
+ *
+ * If +n+ is zero, returns a new empty \Array; +self+ is unmodified.
+ *
+ * Related: #push, #pop, #unshift.
*/
static VALUE
@@ -1366,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);
@@ -1380,109 +1668,133 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
MJIT_FUNC_EXPORTED VALUE
rb_ary_behead(VALUE ary, long n)
{
- if (n<=0) return ary;
+ if (n <= 0) {
+ return ary;
+ }
rb_ary_modify_check(ary);
- if (ARY_SHARED_P(ary)) {
- if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
- setup_occupied_shared:
- ary_mem_clear(ary, 0, n);
- }
- ARY_INCREASE_PTR(ary, n);
- }
- else {
- if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
+
+ 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 */
- }
- else {
- ary_make_shared(ary);
- goto setup_occupied_shared;
- }
+ 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);
+ }
+ else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
+ ary_mem_clear(ary, 0, n);
}
- ARY_INCREASE_LEN(ary, -n);
+ ARY_INCREASE_PTR(ary, n);
+ ARY_INCREASE_LEN(ary, -n);
ary_verify(ary);
+
return ary;
}
static VALUE
-ary_ensure_room_for_unshift(VALUE ary, int argc)
+make_room_for_unshift(VALUE ary, const VALUE *head, VALUE *sharedp, int argc, long capa, long len)
+{
+ if (head - sharedp < argc) {
+ long room = capa - len - argc;
+
+ room -= room >> 4;
+ MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
+ head = sharedp + argc + room;
+ }
+ ARY_SET_PTR(ary, head - argc);
+ assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary)));
+
+ ary_verify(ary);
+ return ARY_SHARED_ROOT(ary);
+}
+
+static VALUE
+ary_modify_for_unshift(VALUE ary, int argc)
{
long len = RARRAY_LEN(ary);
long new_len = len + argc;
long capa;
const VALUE *head, *sharedp;
- if (len > ARY_MAX_SIZE - argc) {
- rb_raise(rb_eIndexError, "index %ld too big", new_len);
- }
-
- if (ARY_SHARED_P(ary)) {
- VALUE shared_root = ARY_SHARED_ROOT(ary);
- capa = RARRAY_LEN(shared_root);
- if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && capa > new_len) {
- rb_ary_modify_check(ary);
- head = RARRAY_CONST_PTR_TRANSIENT(ary);
- sharedp = RARRAY_CONST_PTR_TRANSIENT(shared_root);
- goto makeroom_if_need;
- }
- }
-
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);
- goto makeroom;
- makeroom_if_need:
- if (head - sharedp < argc) {
- long room;
- makeroom:
- room = capa - new_len;
- room -= room >> 4;
- MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
- head = sharedp + argc + room;
- }
- ARY_SET_PTR(ary, head - argc);
- assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary)));
-
- ary_verify(ary);
- return ARY_SHARED_ROOT(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;
+ }
+}
+
+static VALUE
+ary_ensure_room_for_unshift(VALUE ary, int argc)
+{
+ long len = RARRAY_LEN(ary);
+ long new_len = len + argc;
+
+ if (len > ARY_MAX_SIZE - argc) {
+ rb_raise(rb_eIndexError, "index %ld too big", new_len);
+ }
+ else if (! ARY_SHARED_P(ary)) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else {
+ VALUE shared_root = ARY_SHARED_ROOT(ary);
+ long capa = RARRAY_LEN(shared_root);
+
+ if (! ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else if (new_len > capa) {
+ return ary_modify_for_unshift(ary, argc);
+ }
+ else {
+ const VALUE * head = RARRAY_CONST_PTR_TRANSIENT(ary);
+ void *sharedp = (void *)RARRAY_CONST_PTR_TRANSIENT(shared_root);
+
+ rb_ary_modify_check(ary);
+ return make_room_for_unshift(ary, head, sharedp, argc, capa, len);
+ }
}
}
/*
* call-seq:
- * ary.unshift(obj, ...) -> ary
- * ary.prepend(obj, ...) -> ary
+ * array.unshift(*objects) -> self
+ *
+ * Prepends the given +objects+ to +self+:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
*
- * Prepends objects to the front of +self+, moving other elements upwards.
- * See also Array#shift for the opposite effect.
+ * Array#prepend is an alias for Array#unshift.
*
- * a = [ "b", "c", "d" ]
- * a.unshift("a") #=> ["a", "b", "c", "d"]
- * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
+ * Related: #push, #pop, #shift.
*/
static VALUE
@@ -1492,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);
@@ -1515,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);
}
@@ -1527,7 +1839,7 @@ rb_ary_entry(VALUE ary, long offset)
}
VALUE
-rb_ary_subseq(VALUE ary, long beg, long len)
+rb_ary_subseq_step(VALUE ary, long beg, long len, long step)
{
VALUE klass;
long alen = RARRAY_LEN(ary);
@@ -1536,50 +1848,129 @@ rb_ary_subseq(VALUE ary, long beg, long len)
if (beg < 0 || len < 0) return Qnil;
if (alen < len || alen < beg + len) {
- len = alen - beg;
+ len = alen - beg;
}
- klass = rb_obj_class(ary);
+ klass = rb_cArray;
if (len == 0) return ary_new(klass, 0);
+ if (step == 0)
+ rb_raise(rb_eArgError, "slice step cannot be zero");
+ if (step == 1)
+ return ary_make_partial(ary, klass, beg, len);
+ else
+ return ary_make_partial_step(ary, klass, beg, len, step);
+}
- return ary_make_partial(ary, klass, beg, len);
+VALUE
+rb_ary_subseq(VALUE ary, long beg, long len)
+{
+ return rb_ary_subseq_step(ary, beg, len, 1);
}
static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
/*
* call-seq:
- * ary[index] -> obj or nil
- * ary[start, length] -> new_ary or nil
- * ary[range] -> new_ary or nil
- * ary.slice(index) -> obj or nil
- * ary.slice(start, length) -> new_ary or nil
- * ary.slice(range) -> new_ary or nil
- *
- * Element Reference --- Returns the element at +index+, or returns a
- * subarray starting at the +start+ index and continuing for +length+
- * elements, or returns a subarray specified by +range+ of indices.
- *
- * Negative indices count backward from the end of the array (-1 is the last
- * element). For +start+ and +range+ cases the starting index is just before
- * an element. Additionally, an empty array is returned when the starting
- * index for an element range is at the end of the array.
- *
- * Returns +nil+ if the index (or starting index) are out of range.
- *
- * a = [ "a", "b", "c", "d", "e" ]
- * a[2] + a[0] + a[1] #=> "cab"
- * a[6] #=> nil
- * a[1, 2] #=> [ "b", "c" ]
- * a[1..3] #=> [ "b", "c", "d" ]
- * a[4..7] #=> [ "e" ]
- * a[6..10] #=> nil
- * a[-3, 3] #=> [ "c", "d", "e" ]
- * # special cases
- * a[5] #=> nil
- * a[6, 1] #=> nil
- * a[5, 1] #=> []
- * a[5..10] #=> []
+ * array[index] -> object or nil
+ * array[start, length] -> object or nil
+ * array[range] -> object or nil
+ * array[aseq] -> object or nil
+ * array.slice(index) -> object or nil
+ * array.slice(start, length) -> object or nil
+ * array.slice(range) -> object or nil
+ * array.slice(aseq) -> object or nil
+ *
+ * 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"
+ *
+ * If +index+ is out of range, returns +nil+.
+ *
+ * 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]
+ * a[2, 2] # => [2]
+ *
+ * If <tt>start == self.size</tt> and <tt>length >= 0</tt>,
+ * returns a new empty \Array.
+ *
+ * If +length+ is negative, returns +nil+.
+ *
+ * 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]
+ *
+ * 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
+ * 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)
+ * a[(7..).step(2)]
+ * # RangeError (((7..).step(2)) out of range)
+ *
+ * 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]
+ *
+ * Array#slice is an alias for Array#[].
*/
VALUE
@@ -1587,18 +1978,18 @@ 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]);
}
-VALUE
+static VALUE
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);
}
@@ -1606,35 +1997,34 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
MJIT_FUNC_EXPORTED VALUE
rb_ary_aref1(VALUE ary, VALUE arg)
{
- long beg, len;
+ long beg, len, step;
/* 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 */
- switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0)) {
+ /* check if idx is Range or ArithmeticSequence */
+ switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &len, &step, RARRAY_LEN(ary), 0)) {
case Qfalse:
- break;
+ break;
case Qnil:
- return Qnil;
+ return Qnil;
default:
- return rb_ary_subseq(ary, beg, len);
+ return rb_ary_subseq_step(ary, beg, len, step);
}
+
return rb_ary_entry(ary, NUM2LONG(arg));
}
/*
* call-seq:
- * ary.at(index) -> obj or nil
+ * array.at(index) -> object
*
- * Returns the element at +index+. A negative index counts from the end of
- * +self+. Returns +nil+ if the index is out of range. See also
- * Array#[].
+ * Returns the element at \Integer offset +index+; does not modify +self+.
+ * a = [:foo, 'bar', 2]
+ * a.at(0) # => :foo
+ * a.at(2) # => 2
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.at(0) #=> "a"
- * a.at(-1) #=> "e"
*/
VALUE
@@ -1645,81 +2035,131 @@ rb_ary_at(VALUE ary, VALUE pos)
/*
* call-seq:
- * ary.first -> obj or nil
- * ary.first(n) -> new_ary
+ * array.first -> object or nil
+ * array.first(n) -> new_array
+ *
+ * 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]
+ *
+ * If +self+ is empty, returns +nil+.
+ *
+ * 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"]
*
- * Returns the first element, or the first +n+ elements, of the array.
- * If the array is empty, the first form returns +nil+, and the
- * second form returns an empty array. See also Array#last for
- * the opposite effect.
+ * If <tt>n >= array.size</tt>, returns all elements:
*
- * a = [ "q", "r", "s", "t" ]
- * a.first #=> "q"
- * a.first(2) #=> ["q", "r"]
+ * 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) # []
+ *
+ * Related: #last.
*/
-
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);
}
}
/*
* call-seq:
- * ary.last -> obj or nil
- * ary.last(n) -> new_ary
+ * array.last -> object or nil
+ * array.last(n) -> new_array
+ *
+ * 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 \Integer argument +n+ is given,
+ * returns the last +n+ elements in a new \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last(2) # => ["bar", 2]
*
- * Returns the last element(s) of +self+. If the array is empty,
- * the first form returns +nil+.
+ * If <tt>n >= array.size</tt>, returns all elements:
*
- * See also Array#first for the opposite effect.
+ * a = [:foo, 'bar', 2]
+ * a.last(50) # => [:foo, "bar", 2]
*
- * a = [ "w", "x", "y", "z" ]
- * a.last #=> "z"
- * a.last(2) #=> ["y", "z"]
+ * If <tt>n == 0</tt>, returns an new empty \Array:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.last(0) # []
+ *
+ * Related: #first.
*/
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);
}
}
/*
* call-seq:
- * ary.fetch(index) -> obj
- * ary.fetch(index, default) -> obj
- * ary.fetch(index) {|index| block} -> obj
- *
- * Tries to return the element at position +index+, but throws an IndexError
- * exception if the referenced +index+ lies outside of the array bounds. This
- * error can be prevented by supplying a second argument, which will act as a
- * +default+ value.
- *
- * Alternatively, if a block is given it will only be executed when an
- * invalid +index+ is referenced.
- *
- * Negative values of +index+ count from the end of the array.
- *
- * a = [ 11, 22, 33, 44 ]
- * a.fetch(1) #=> 22
- * a.fetch(-1) #=> 44
- * a.fetch(4, 'cat') #=> "cat"
- * a.fetch(100) {|i| puts "#{i} is out of bounds"}
- * #=> "100 is out of bounds"
+ * array.fetch(index) -> element
+ * array.fetch(index, default_value) -> element
+ * array.fetch(index) {|index| ... } -> element
+ *
+ * Returns the element at offset +index+.
+ *
+ * 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"
+ *
+ * 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"
+ *
+ * With argument +index+ and a block,
+ * returns the element at offset +index+ if index is in range
+ * (and the block is not called); otherwise calls the block with index and returns its return value:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
+ * a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"
+ *
*/
static VALUE
@@ -1732,50 +2172,60 @@ 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);
}
/*
* call-seq:
- * ary.find_index(obj) -> int or nil
- * ary.find_index {|item| block} -> int or nil
- * ary.find_index -> Enumerator
- * ary.index(obj) -> int or nil
- * ary.index {|item| block} -> int or nil
- * ary.index -> Enumerator
+ * array.index(object) -> integer or nil
+ * array.index {|element| ... } -> integer or nil
+ * array.index -> new_enumerator
+ *
+ * Returns the index of a specified element.
+ *
+ * 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
+ *
+ * Returns +nil+ if no such element found.
+ *
+ * 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:
*
- * Returns the _index_ of the first object in +ary+ such that the object is
- * <code>==</code> to +obj+.
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.index {|element| element == 'bar' } # => 1
*
- * If a block is given instead of an argument, returns the _index_ of the
- * first object for which the block returns +true+. Returns +nil+ if no
- * match is found.
+ * Returns +nil+ if the block never returns a truthy value.
*
- * See also Array#rindex.
+ * When neither an argument nor a block is given, returns a new Enumerator:
*
- * An Enumerator is returned if neither a block nor argument is given.
+ * a = [:foo, 'bar', 2]
+ * e = a.index
+ * e # => #<Enumerator: [:foo, "bar", 2]:index>
+ * e.each {|element| element == 'bar' } # => 1
*
- * a = [ "a", "b", "c" ]
- * a.index("b") #=> 1
- * a.index("z") #=> nil
- * a.index {|x| x == "b"} #=> 1
+ * Array#find_index is an alias for Array#index.
*
- * Array#index is an alias for Array#find_index.
+ * Related: #rindex.
*/
static VALUE
@@ -1785,49 +2235,58 @@ 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;
}
/*
* call-seq:
- * ary.rindex(obj) -> int or nil
- * ary.rindex {|item| block} -> int or nil
- * ary.rindex -> Enumerator
+ * array.rindex(object) -> integer or nil
+ * array.rindex {|element| ... } -> integer or nil
+ * array.rindex -> new_enumerator
+ *
+ * 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
+ *
+ * Returns +nil+ if no such object found.
*
- * Returns the _index_ of the last object in +self+ <code>==</code> to +obj+.
+ * 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:
*
- * If a block is given instead of an argument, returns the _index_ of the
- * first object for which the block returns +true+, starting from the last
- * object.
+ * a = [:foo, 'bar', 2, 'bar']
+ * a.rindex {|element| element == 'bar' } # => 3
*
- * Returns +nil+ if no match is found.
+ * Returns +nil+ if the block never returns a truthy value.
*
- * See also Array#index.
+ * When neither an argument nor a block is given, returns a new \Enumerator:
*
- * If neither block nor argument is given, an Enumerator is returned instead.
+ * a = [:foo, 'bar', 2, 'bar']
+ * e = a.rindex
+ * e # => #<Enumerator: [:foo, "bar", 2, "bar"]:rindex>
+ * e.each {|element| element == 'bar' } # => 3
*
- * a = [ "a", "b", "b", "b", "c" ]
- * a.rindex("b") #=> 3
- * a.rindex("z") #=> nil
- * a.rindex {|x| x == "b"} #=> 3
+ * Related: #index.
*/
static VALUE
@@ -1837,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;
}
@@ -1881,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);
@@ -1938,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));
- }
+ }
}
}
@@ -1949,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)
{
@@ -1974,118 +2425,231 @@ 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;
}
+static VALUE
+ary_aset_by_rb_ary_store(VALUE ary, long key, VALUE val)
+{
+ rb_ary_store(ary, key, val);
+ return val;
+}
+
+static VALUE
+ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
+{
+ VALUE rpl = rb_ary_to_ary(val);
+ rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl));
+ RB_GC_GUARD(rpl);
+ return val;
+}
+
/*
* call-seq:
- * ary[index] = obj -> obj
- * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil
- * ary[range] = obj or other_ary or nil -> obj or other_ary or nil
- *
- * Element Assignment --- Sets the element at +index+, or replaces a subarray
- * from the +start+ index for +length+ elements, or replaces a subarray
- * specified by the +range+ of indices.
- *
- * If indices are greater than the current capacity of the array, the array
- * grows automatically. Elements are inserted into the array at +start+ if
- * +length+ is zero.
- *
- * Negative indices will count backward from the end of the array. For
- * +start+ and +range+ cases the starting index is just before an element.
- *
- * An IndexError is raised if a negative index points past the beginning of
- * the array.
- *
- * See also Array#push, and Array#unshift.
- *
- * a = Array.new
- * a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
- * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
- * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
- * a[0, 2] = "?" #=> ["?", 2, nil, "4"]
- * a[0..2] = "A" #=> ["A", "4"]
- * a[-1] = "Z" #=> ["A", "Z"]
- * a[1..-1] = nil #=> ["A", nil]
- * a[1..-1] = [] #=> ["A"]
- * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"]
- * a[3, 0] = "B" #=> [1, 2, "A", "B"]
+ * array[index] = object -> object
+ * array[start, length] = object -> object
+ * array[range] = object -> object
+ *
+ * Assigns elements in +self+; returns the given +object+.
+ *
+ * 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"]
+ *
+ * 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"]
+ *
+ * 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"]
+ *
+ * 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"]
+ * a = [:foo, 'bar', 2]
+ * a[1..-2] = 'foo' # => "foo"
+ * a # => [:foo, "foo", 2]
+ * a = [:foo, 'bar', 2]
+ * a[1..-3] = 'foo' # => "foo"
+ * a # => [:foo, "foo", "bar", 2]
+ * a = [:foo, 'bar', 2]
+ *
+ * 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
rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
long offset, beg, len;
- VALUE rpl;
+ rb_check_arity(argc, 2, 3);
+ rb_ary_modify_check(ary);
if (argc == 3) {
- rb_ary_modify_check(ary);
- beg = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
- goto range;
+ beg = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
+ return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
}
- rb_check_arity(argc, 2, 2);
- rb_ary_modify_check(ary);
if (FIXNUM_P(argv[0])) {
- offset = FIX2LONG(argv[0]);
- goto fixnum;
+ 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 */
- range:
- rpl = rb_ary_to_ary(argv[argc-1]);
- rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl));
- RB_GC_GUARD(rpl);
- return argv[argc-1];
+ /* check if idx is Range */
+ return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
}
offset = NUM2LONG(argv[0]);
-fixnum:
- rb_ary_store(ary, offset, argv[1]);
- return argv[1];
+ return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
/*
* call-seq:
- * ary.insert(index, obj...) -> ary
+ * array.insert(index, *objects) -> self
+ *
+ * Inserts given +objects+ before or after the element at \Integer index +offset+;
+ * returns +self+.
+ *
+ * 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]
*
- * Inserts the given values before the element with the given +index+.
+ * Does nothing if no objects given:
*
- * Negative indices count backwards from the end of the array, where +-1+ is
- * the last element. If a negative index is used, the given values will be
- * inserted after that element, so using an index of +-1+ will insert the
- * values at the end of the array.
+ * a = [:foo, 'bar', 2]
+ * a.insert(1)
+ * a.insert(50)
+ * a.insert(-50)
+ * a # => [:foo, "bar", 2]
+ *
+ * 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]
*
- * a = %w{ a b c d }
- * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
- * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
*/
static VALUE
@@ -2098,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;
@@ -2123,20 +2687,47 @@ ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.each {|item| block} -> ary
- * ary.each -> Enumerator
+ * array.each {|element| ... } -> self
+ * array.each -> Enumerator
+ *
+ * Iterates over array elements.
+ *
+ * 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') }
*
- * Calls the given block once for each element in +self+, passing that element
- * as a parameter. Returns the array itself.
+ * Output:
*
- * If no block is given, an Enumerator is returned.
+ * foo
+ * bar
*
- * a = [ "a", "b", "c" ]
- * a.each {|x| print x, " -- " }
+ * When no block given, returns a new \Enumerator:
+ * a = [:foo, 'bar', 2]
*
- * produces:
+ * e = a.each
+ * e # => #<Enumerator: [:foo, "bar", 2]:each>
+ * a1 = e.each {|element| puts "#{element.class} #{element}" }
*
- * a -- b -- c --
+ * Output:
+ *
+ * Symbol foo
+ * String bar
+ * Integer 2
+ *
+ * Related: #each_index, #reverse_each.
*/
VALUE
@@ -2146,27 +2737,54 @@ 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;
}
/*
* call-seq:
- * ary.each_index {|index| block} -> ary
- * ary.each_index -> Enumerator
+ * array.each_index {|index| ... } -> self
+ * array.each_index -> Enumerator
+ *
+ * Iterates over array indexes.
+ *
+ * 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:
*
- * Same as Array#each, but passes the +index+ of the element instead of the
- * element itself.
+ * 0
+ * 1
*
- * An Enumerator is returned if no block is given.
+ * When no block given, returns a new \Enumerator:
*
- * a = [ "a", "b", "c" ]
- * a.each_index {|x| print x, " -- " }
+ * a = [:foo, 'bar', 2]
+ * e = a.each_index
+ * e # => #<Enumerator: [:foo, "bar", 2]:each_index>
+ * a1 = e.each {|index| puts "#{index} #{a[index]}"}
*
- * produces:
+ * Output:
*
- * 0 -- 1 -- 2 --
+ * 0 foo
+ * 1 bar
+ * 2 2
+ *
+ * Related: #each, #reverse_each.
*/
static VALUE
@@ -2176,24 +2794,54 @@ 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;
}
/*
* call-seq:
- * ary.reverse_each {|item| block} -> ary
- * ary.reverse_each -> Enumerator
+ * array.reverse_each {|element| ... } -> self
+ * array.reverse_each -> Enumerator
+ *
+ * Iterates backwards over array elements.
+ *
+ * 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
*
- * Same as Array#each, but traverses +self+ in reverse order.
+ * When no block given, returns a new \Enumerator:
*
- * a = [ "a", "b", "c" ]
- * a.reverse_each {|x| print x, " " }
+ * a = [:foo, 'bar', 2]
+ * e = a.reverse_each
+ * e # => #<Enumerator: [:foo, "bar", 2]:reverse_each>
+ * a1 = e.each {|element| puts "#{element.class} #{element}" }
*
- * produces:
+ * Output:
*
- * c b a
+ * Integer 2
+ * String bar
+ * Symbol foo
+ *
+ * Related: #each, #each_index.
*/
static VALUE
@@ -2204,24 +2852,21 @@ 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;
}
/*
* call-seq:
- * ary.length -> int
- *
- * Returns the number of elements in +self+. May be zero.
+ * array.length -> an_integer
*
- * [ 1, 2, 3, 4, 5 ].length #=> 5
- * [].length #=> 0
+ * Returns the count of elements in +self+.
*/
static VALUE
@@ -2233,19 +2878,16 @@ rb_ary_length(VALUE ary)
/*
* call-seq:
- * ary.empty? -> true or false
+ * array.empty? -> true or false
*
- * Returns +true+ if +self+ contains no elements.
- *
- * [].empty? #=> true
+ * Returns +true+ if the count of elements in +self+ is zero,
+ * +false+ otherwise.
*/
static VALUE
rb_ary_empty_p(VALUE ary)
{
- if (RARRAY_LEN(ary) == 0)
- return Qtrue;
- return Qfalse;
+ return RBOOL(RARRAY_LEN(ary) == 0);
}
VALUE
@@ -2281,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;
}
@@ -2297,65 +2939,68 @@ 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;
}
static void
+ary_join_1_str(VALUE dst, VALUE src, int *first)
+{
+ rb_str_buf_append(dst, src);
+ if (*first) {
+ rb_enc_copy(dst, src);
+ *first = FALSE;
+ }
+}
+
+static void
+ary_join_1_ary(VALUE obj, VALUE ary, VALUE sep, VALUE result, VALUE val, int *first)
+{
+ if (val == ary) {
+ rb_raise(rb_eArgError, "recursive array join");
+ }
+ else {
+ VALUE args[4];
+
+ *first = FALSE;
+ args[0] = val;
+ args[1] = sep;
+ args[2] = result;
+ args[3] = (VALUE)first;
+ rb_exec_recursive(recursive_join, obj, (VALUE)args);
+ }
+}
+
+static void
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);
-
- val = RARRAY_AREF(ary, i);
- if (RB_TYPE_P(val, T_STRING)) {
- str_join:
- rb_str_buf_append(result, val);
- if (*first) {
- rb_enc_copy(result, val);
- *first = FALSE;
- }
- }
- else if (RB_TYPE_P(val, T_ARRAY)) {
- obj = val;
- ary_join:
- if (val == ary) {
- rb_raise(rb_eArgError, "recursive array join");
- }
- else {
- VALUE args[4];
-
- *first = FALSE;
- args[0] = val;
- args[1] = sep;
- args[2] = result;
- args[3] = (VALUE)first;
- rb_exec_recursive(recursive_join, obj, (VALUE)args);
- }
- }
- else {
- tmp = rb_check_string_type(val);
- if (!NIL_P(tmp)) {
- val = tmp;
- goto str_join;
- }
- tmp = rb_check_array_type(val);
- if (!NIL_P(tmp)) {
- obj = val;
- val = tmp;
- goto ary_join;
- }
- val = rb_obj_as_string(val);
- goto str_join;
- }
+ if (i > 0 && !NIL_P(sep))
+ rb_str_buf_append(result, sep);
+
+ 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)) {
+ 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);
+ }
+ else if (!NIL_P(tmp = rb_check_array_type(val))) {
+ ary_join_1_ary(val, ary, sep, result, tmp, first);
+ }
+ else {
+ ary_join_1_str(result, rb_obj_as_string(val), first);
+ }
}
}
@@ -2368,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);
@@ -2400,22 +3045,32 @@ rb_ary_join(VALUE ary, VALUE sep)
/*
* call-seq:
- * ary.join(separator=$,) -> str
+ * array.join ->new_string
+ * array.join(separator = $,) -> new_string
+ *
+ * Returns the new \String formed by joining the array elements after conversion.
+ * 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>:
*
- * Returns a string created by converting each element of the array to
- * a string, separated by the given +separator+.
- * If the +separator+ is +nil+, it uses current <code>$,</code>.
- * If both the +separator+ and <code>$,</code> are +nil+,
- * it uses an empty string.
+ * a = [:foo, 'bar', 2]
+ * $, # => nil
+ * a.join # => "foobar2"
*
- * [ "a", "b", "c" ].join #=> "abc"
- * [ "a", "b", "c" ].join("-") #=> "a-b-c"
+ * With \string argument +separator+, joins using that separator:
*
- * For nested arrays, join is applied recursively:
+ * a = [:foo, 'bar', 2]
+ * a.join("\n") # => "foo\nbar\n2"
+ *
+ * Joins recursively for nested Arrays:
+ *
+ * a = [:foo, [:bar, [:baz, :bat]]]
+ * a.join # => "foobarbazbat"
*
- * [ "a", [1, 2, [:x, :y]], "b" ].join("-") #=> "a-1-2-x-y-b"
*/
-
static VALUE
rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
{
@@ -2424,7 +3079,7 @@ rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
sep = rb_output_fs;
if (!NIL_P(sep)) {
- rb_warn("$, is set to non-nil value");
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
}
}
@@ -2440,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;
@@ -2451,13 +3106,15 @@ inspect_ary(VALUE ary, VALUE dummy, int recur)
/*
* call-seq:
- * ary.inspect -> string
- * ary.to_s -> string
+ * array.inspect -> new_string
*
- * Creates a string representation of +self+, by calling #inspect
- * on each element.
+ * Returns the new \String formed by calling method <tt>#inspect</tt>
+ * on each array element:
*
- * [ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
+ * a = [:foo, 'bar', 2]
+ * a.inspect # => "[:foo, \"bar\", 2]"
+ *
+ * Array#to_s is an alias for Array#inspect.
*/
static VALUE
@@ -2475,40 +3132,59 @@ rb_ary_to_s(VALUE ary)
/*
* call-seq:
- * ary.to_a -> ary
+ * to_a -> self or new_array
*
- * Returns +self+.
+ * 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
+ * a.kind_of?(Array) # => true
+ * a1 = a.to_a
+ * a1 # => ["foo", "bar", "two"]
+ * a1.class # => Array # Not MyArray
*
- * If called on a subclass of Array, converts the receiver to an Array object.
*/
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;
}
/*
* call-seq:
- * ary.to_h -> hash
- * ary.to_h {|item| block } -> hash
+ * array.to_h -> new_hash
+ * array.to_h {|item| ... } -> new_hash
+ *
+ * Returns a new \Hash formed from +self+.
*
- * Returns the result of interpreting <i>ary</i> as an array of
- * <tt>[key, value]</tt> pairs.
+ * 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:
*
- * [[:foo, :bar], [1, 2]].to_h
- * # => {:foo => :bar, 1 => 2}
+ * 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}}
*
- * If a block is given, the results of the block on each element of
- * the array will be used as pairs.
+ * 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"}
*
- * ["foo", "bar"].to_h {|s| [s.ord, s]}
- * # => {102=>"foo", 98=>"bar"}
*/
static VALUE
@@ -2519,25 +3195,25 @@ 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;
}
/*
* call-seq:
- * ary.to_ary -> ary
+ * array.to_ary -> self
*
* Returns +self+.
*/
@@ -2552,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;
}
}
@@ -2569,20 +3245,20 @@ 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;
}
/*
* call-seq:
- * ary.reverse! -> ary
+ * array.reverse! -> self
*
- * Reverses +self+ in place.
+ * Reverses +self+ in place:
+ *
+ * a = ['foo', 'bar', 'two']
+ * a.reverse! # => ["two", "bar", "foo"]
*
- * a = [ "a", "b", "c" ]
- * a.reverse! #=> ["c", "b", "a"]
- * a #=> ["c", "b", "a"]
*/
static VALUE
@@ -2593,12 +3269,14 @@ rb_ary_reverse_bang(VALUE ary)
/*
* call-seq:
- * ary.reverse -> new_ary
+ * array.reverse -> new_array
+ *
+ * Returns a new \Array with the elements of +self+ in reverse order:
*
- * Returns a new array containing +self+'s elements in reverse order.
+ * a = ['foo', 'bar', 'two']
+ * a1 = a.reverse
+ * a1 # => ["two", "bar", "foo"]
*
- * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
- * [ 1 ].reverse #=> [1]
*/
static VALUE
@@ -2610,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;
@@ -2629,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);
@@ -2658,19 +3338,48 @@ rb_ary_rotate(VALUE ary, long cnt)
/*
* call-seq:
- * ary.rotate!(count=1) -> ary
+ * array.rotate! -> self
+ * array.rotate!(count) -> self
*
- * Rotates +self+ in place so that the element at +count+ comes first, and
- * returns +self+.
+ * 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:
*
- * If +count+ is negative then it rotates in the opposite direction, starting
- * from the end of the array where +-1+ is the last element.
+ * a = [:foo, 'bar', 2]
+ * a.rotate!(-5)
+ * a # => ["bar", 2, :foo]
*
- * a = [ "a", "b", "c", "d" ]
- * a.rotate! #=> ["b", "c", "d", "a"]
- * a #=> ["b", "c", "d", "a"]
- * a.rotate!(2) #=> ["d", "a", "b", "c"]
- * a.rotate!(-3) #=> ["a", "b", "c", "d"]
*/
static VALUE
@@ -2683,19 +3392,51 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.rotate(count=1) -> new_ary
+ * array.rotate -> new_array
+ * array.rotate(count) -> new_array
*
- * Returns a new array by rotating +self+ so that the element at +count+ is
- * the first element of the new array.
+ * Returns a new \Array formed from +self+ with elements
+ * rotated from one end to the other.
*
- * If +count+ is negative then it rotates in the opposite direction, starting
- * from the end of +self+ where +-1+ is the last element.
+ * 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]
*
- * a = [ "a", "b", "c", "d" ]
- * a.rotate #=> ["b", "c", "d", "a"]
- * a #=> ["a", "b", "c", "d"]
- * a.rotate(2) #=> ["c", "d", "a", "b"]
- * a.rotate(-3) #=> ["b", "c", "d", "a"]
*/
static VALUE
@@ -2709,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;
@@ -2721,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)
{
@@ -2746,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;
}
@@ -2758,47 +3508,64 @@ 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, Fixnum)) {
- 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;
}
/*
* call-seq:
- * ary.sort! -> ary
- * ary.sort! {|a, b| block} -> ary
+ * array.sort! -> self
+ * array.sort! {|a, b| ... } -> self
*
- * Sorts +self+ in place.
+ * Returns +self+ with its elements sorted in place.
*
- * Comparisons for the sort will be done using the <code><=></code> operator
- * or using an optional code block.
+ * With no block, compares elements using operator <tt><=></tt>
+ * (see Comparable):
*
- * The block must implement a comparison between +a+ and +b+ and return
- * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
- * are equivalent, or an integer greater than 0 when +a+ follows +b+.
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a.sort!
+ * a # => ["a", "b", "c", "d", "e"]
*
- * The result is not guaranteed to be stable. When the comparison of two
- * elements returns +0+, the order of the elements is unpredictable.
+ * With a block, calls the block with each element pair;
+ * for each element pair +a+ and +b+, the block should return an integer:
*
- * ary = [ "d", "a", "e", "c", "b" ]
- * ary.sort! #=> ["a", "b", "c", "d", "e"]
- * ary.sort! {|a, b| b <=> a} #=> ["e", "d", "c", "b", "a"]
+ * - 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 }
+ * a # => ["a", "b", "c", "d", "e"]
+ * a.sort! {|a, b| b <=> a }
+ * a # => ["e", "d", "c", "b", "a"]
+ *
+ * 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"]
*
- * See also Enumerable#sort_by.
*/
VALUE
@@ -2807,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 {
@@ -2863,31 +3629,44 @@ rb_ary_sort_bang(VALUE ary)
/*
* call-seq:
- * ary.sort -> new_ary
- * ary.sort {|a, b| block} -> new_ary
+ * array.sort -> new_array
+ * array.sort {|a, b| ... } -> new_array
+ *
+ * Returns a new \Array whose elements are those from +self+, sorted.
+ *
+ * With no block, compares elements using operator <tt><=></tt>
+ * (see Comparable):
*
- * Returns a new array created by sorting +self+.
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort
+ * a1 # => ["a", "b", "c", "d", "e"]
*
- * Comparisons for the sort will be done using the <code><=></code> operator
- * or using an optional code block.
+ * With a block, calls the block with each element pair;
+ * for each element pair +a+ and +b+, the block should return an integer:
*
- * The block must implement a comparison between +a+ and +b+ and return
- * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
- * are equivalent, or an integer greater than 0 when +a+ follows +b+.
+ * - Negative when +b+ is to follow +a+.
+ * - Zero when +a+ and +b+ are equivalent.
+ * - Positive when +a+ is to follow +b+.
*
- * The result is not guaranteed to be stable. When the comparison of two
- * elements returns +0+, the order of the elements is unpredictable.
+ * Example:
*
- * ary = [ "d", "a", "e", "c", "b" ]
- * ary.sort #=> ["a", "b", "c", "d", "e"]
- * ary.sort {|a, b| b <=> a} #=> ["e", "d", "c", "b", "a"]
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort {|a, b| a <=> b }
+ * a1 # => ["a", "b", "c", "d", "e"]
+ * a2 = a.sort {|a, b| b <=> a }
+ * a2 # => ["e", "d", "c", "b", "a"]
*
- * To produce the reverse order, the following can also be used
- * (and may be faster):
+ * When the block returns zero, the order for +a+ and +b+ is indeterminate,
+ * and may be unstable:
*
- * ary.sort.reverse! #=> ["e", "d", "c", "b", "a"]
+ * a = 'abcde'.split('').shuffle
+ * a # => ["e", "b", "d", "a", "c"]
+ * a1 = a.sort {|a, b| 0 }
+ * a1 # => ["c", "e", "b", "d", "a"]
*
- * See also Enumerable#sort_by.
+ * Related: Enumerable#sort_by.
*/
VALUE
@@ -2902,55 +3681,12 @@ static VALUE rb_ary_bsearch_index(VALUE ary);
/*
* call-seq:
- * ary.bsearch {|x| block } -> elem
- *
- * By using binary search, finds a value from this array which meets
- * the given condition in O(log n) where n is the size of the array.
- *
- * You can use this method in two modes: a find-minimum mode and
- * a find-any mode. In either case, the elements of the array must be
- * monotone (or sorted) with respect to the block.
- *
- * In find-minimum mode (this is a good choice for typical use cases),
- * the block must always return true or false, and there must be an index i
- * (0 <= i <= ary.size) so that:
- *
- * - the block returns false for any element whose index is less than
- * i, and
- * - the block returns true for any element whose index is greater
- * than or equal to i.
- *
- * This method returns the i-th element. If i is equal to ary.size,
- * it returns nil.
- *
- * ary = [0, 4, 7, 10, 12]
- * ary.bsearch {|x| x >= 4 } #=> 4
- * ary.bsearch {|x| x >= 6 } #=> 7
- * ary.bsearch {|x| x >= -1 } #=> 0
- * ary.bsearch {|x| x >= 100 } #=> nil
- *
- * In find-any mode (this behaves like libc's bsearch(3)), the block
- * must always return a number, and there must be two indices i and j
- * (0 <= i <= j <= ary.size) so that:
- *
- * - the block returns a positive number for ary[k] if 0 <= k < i,
- * - the block returns zero for ary[k] if i <= k < j, and
- * - the block returns a negative number for ary[k] if
- * j <= k < ary.size.
- *
- * Under this condition, this method returns any element whose index
- * is within i...j. If i is equal to j (i.e., there is no element
- * that satisfies the block), this method returns nil.
- *
- * ary = [0, 4, 7, 10, 12]
- * # try to find v such that 4 <= v < 8
- * ary.bsearch {|x| 1 - x / 4 } #=> 4 or 7
- * # try to find v such that 8 <= v < 10
- * ary.bsearch {|x| 4 - x / 2 } #=> nil
- *
- * You must not mix the two modes at a time; the block must always
- * return either true/false, or always return a number. It is
- * undefined which value is actually picked up at each iteration.
+ * array.bsearch {|element| ... } -> object
+ * array.bsearch -> new_enumerator
+ *
+ * Returns an element from +self+ selected by a binary search.
+ *
+ * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
*/
static VALUE
@@ -2959,22 +3695,18 @@ 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;
}
/*
* call-seq:
- * ary.bsearch_index {|x| block } -> int or nil
+ * array.bsearch_index {|element| ... } -> integer or nil
+ * array.bsearch_index -> new_enumerator
*
- * By using binary search, finds an index of a value from this array which
- * meets the given condition in O(log n) where n is the size of the array.
- *
- * It supports two modes, depending on the nature of the block. They are
- * exactly the same as in the case of the #bsearch method, with the only difference
- * being that this method returns the index of the element instead of the
- * element itself. For more details consult the documentation for #bsearch.
+ * Searches +self+ as described at method #bsearch,
+ * but returns the _index_ of the found element instead of the element itself.
*/
static VALUE
@@ -2986,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);
@@ -3033,18 +3765,28 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
/*
* call-seq:
- * ary.sort_by! {|obj| block} -> ary
- * ary.sort_by! -> Enumerator
+ * array.sort_by! {|element| ... } -> self
+ * array.sort_by! -> new_enumerator
+ *
+ * Sorts the elements of +self+ in place,
+ * using an ordering determined by the block; returns self.
+ *
+ * Calls the block with each successive element;
+ * sorts elements based on the values returned from the block.
+ *
+ * For duplicates returned by the block, the ordering is indeterminate, and may be unstable.
+ *
+ * This example sorts strings based on their sizes:
*
- * Sorts +self+ in place using a set of keys generated by mapping the
- * values in +self+ through the given block.
+ * a = ['aaaa', 'bbb', 'cc', 'd']
+ * a.sort_by! {|element| element.size }
+ * a # => ["d", "cc", "bbb", "aaaa"]
*
- * The result is not guaranteed to be stable. When two keys are equal,
- * the order of the corresponding elements is unpredictable.
+ * Returns a new \Enumerator if no block given:
*
- * If no block is given, an Enumerator is returned instead.
+ * a = ['aaaa', 'bbb', 'cc', 'd']
+ * a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
*
- * See also Enumerable#sort_by.
*/
static VALUE
@@ -3062,23 +3804,22 @@ rb_ary_sort_by_bang(VALUE ary)
/*
* call-seq:
- * ary.collect {|item| block} -> new_ary
- * ary.map {|item| block} -> new_ary
- * ary.collect -> Enumerator
- * ary.map -> Enumerator
+ * array.map {|element| ... } -> new_array
+ * array.map -> new_enumerator
*
- * Invokes the given block once for each element of +self+.
+ * Calls the block, if given, with each element of +self+;
+ * returns a new \Array whose elements are the return values from the block:
*
- * Creates a new array containing the values returned by the block.
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map {|element| element.class }
+ * a1 # => [Symbol, String, Integer]
*
- * See also Enumerable#collect.
+ * Returns a new \Enumerator if no block given:
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map
+ * a1 # => #<Enumerator: [:foo, "bar", 2]:map>
*
- * If no block is given, an Enumerator is returned instead.
- *
- * a = [ "a", "b", "c", "d" ]
- * a.collect {|x| x + "!"} #=> ["a!", "b!", "c!", "d!"]
- * a.map.with_index {|x, i| x * i} #=> ["", "b", "cc", "ddd"]
- * a #=> ["a", "b", "c", "d"]
+ * Array#collect is an alias for Array#map.
*/
static VALUE
@@ -3098,23 +3839,22 @@ rb_ary_collect(VALUE ary)
/*
* call-seq:
- * ary.collect! {|item| block } -> ary
- * ary.map! {|item| block } -> ary
- * ary.collect! -> Enumerator
- * ary.map! -> Enumerator
+ * array.map! {|element| ... } -> self
+ * array.map! -> new_enumerator
+ *
+ * Calls the block, if given, with each element;
+ * replaces the element with the block's return value:
*
- * Invokes the given block once for each element of +self+, replacing the
- * element with the value returned by the block.
+ * a = [:foo, 'bar', 2]
+ * a.map! { |element| element.class } # => [Symbol, String, Integer]
*
- * See also Enumerable#collect.
+ * Returns a new \Enumerator if no block given:
*
- * If no block is given, an Enumerator is returned instead.
+ * a = [:foo, 'bar', 2]
+ * a1 = a.map!
+ * a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
*
- * a = [ "a", "b", "c", "d" ]
- * a.map! {|x| x + "!" }
- * a #=> [ "a!", "b!", "c!", "d!" ]
- * a.collect!.with_index {|x, i| x[0...i] }
- * a #=> ["", "b", "c!", "d!"]
+ * Array#collect! is an alias for Array#map!.
*/
static VALUE
@@ -3125,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;
}
@@ -3137,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;
}
@@ -3161,45 +3901,70 @@ 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));
}
/*
* call-seq:
- * ary.values_at(selector, ...) -> new_ary
+ * array.values_at(*indexes) -> new_array
+ *
+ * Returns a new \Array whose elements are the elements
+ * 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]
*
- * Returns an array containing the elements in +self+ corresponding to the
- * given +selector+(s).
+ * Assigns +nil+ for an +index+ that is too large:
*
- * The selectors may be either integer indices or ranges.
+ * a = [:foo, 'bar', 2]
+ * a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil]
*
- * See also Array#select.
+ * 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]
*
- * a = %w{ a b c d e f }
- * a.values_at(1, 3, 5) # => ["b", "d", "f"]
- * a.values_at(1, 3, 5, 7) # => ["b", "d", "f", nil]
- * a.values_at(-1, -2, -2, -7) # => ["f", "e", "e", nil]
- * a.values_at(4..6, 3...6) # => ["e", "f", nil, "d", "e", "f"]
*/
static VALUE
@@ -3208,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;
@@ -3217,22 +3982,21 @@ rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.select {|item| block} -> new_ary
- * ary.select -> Enumerator
- * ary.filter {|item| block} -> new_ary
- * ary.filter -> Enumerator
- *
- * Returns a new array containing all elements of +ary+
- * for which the given +block+ returns a true value.
+ * array.select {|element| ... } -> new_array
+ * array.select -> new_enumerator
*
- * If no block is given, an Enumerator is returned instead.
+ * 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:
*
- * [1,2,3,4,5].select {|num| num.even? } #=> [2, 4]
+ * a = [:foo, 'bar', 2, :bam]
+ * a1 = a.select {|element| element.to_s.start_with?('b') }
+ * a1 # => ["bar", :bam]
*
- * a = %w[ a b c d e f ]
- * a.select {|v| v =~ /[aeiou]/ } #=> ["a", "e"]
+ * Returns a new \Enumerator if no block given:
*
- * See also Enumerable#select.
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
*
* Array#filter is an alias for Array#select.
*/
@@ -3246,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;
}
@@ -3266,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;
}
@@ -3285,35 +4049,38 @@ 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;
}
/*
* call-seq:
- * ary.select! {|item| block } -> ary or nil
- * ary.select! -> Enumerator
- * ary.filter! {|item| block } -> ary or nil
- * ary.filter! -> Enumerator
+ * array.select! {|element| ... } -> self or nil
+ * array.select! -> new_enumerator
+ *
+ * Calls the block, if given with each element of +self+;
+ * removes from +self+ those elements for which the block returns +false+ or +nil+.
*
- * Invokes the given block passing in successive elements from +self+,
- * deleting elements for which the block returns a +false+ value.
+ * Returns +self+ if any elements were removed:
*
- * The array may not be changed instantly every time the block is called.
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
- * If changes were made, it will return +self+, otherwise it returns +nil+.
+ * Returns +nil+ if no elements were removed.
*
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
*
- * See also Array#keep_if.
+ * a = [:foo, 'bar', 2, :bam]
+ * a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
*
* Array#filter! is an alias for Array#select!.
*/
@@ -3333,19 +4100,20 @@ rb_ary_select_bang(VALUE ary)
/*
* call-seq:
- * ary.keep_if {|item| block} -> ary
- * ary.keep_if -> Enumerator
+ * array.keep_if {|element| ... } -> self
+ * array.keep_if -> new_enumeration
+ *
+ * Retains those elements for which the block returns a truthy value;
+ * deletes all other elements; returns +self+:
*
- * Deletes every element of +self+ for which the given block evaluates to
- * +false+, and returns +self+.
+ * a = [:foo, 'bar', 2, :bam]
+ * a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
*
- * If no block is given, an Enumerator is returned instead.
+ * Returns a new \Enumerator if no block given:
*
- * a = %w[ a b c d e f ]
- * a.keep_if {|v| v =~ /[aeiou]/ } #=> ["a", "e"]
- * a #=> ["a", "e"]
+ * a = [:foo, 'bar', 2, :bam]
+ * a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
*
- * See also Array#select!.
*/
static VALUE
@@ -3361,32 +4129,48 @@ 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);
+ }
}
}
/*
* call-seq:
- * ary.delete(obj) -> item or nil
- * ary.delete(obj) {block} -> item or result of block
+ * array.delete(obj) -> deleted_object
+ * array.delete(obj) {|nosuch| ... } -> deleted_object or block_return
+ *
+ * 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"
+ * a # => [:foo, 2]
+ *
+ * Returns +nil+ if no elements removed.
+ *
+ * When a block is given,
+ * removes from +self+ each element +ele+ such that <tt>ele == obj</tt>.
+ *
+ * If any such elements are found, ignores the block
+ * and returns the last deleted element:
*
- * Deletes all items from +self+ that are equal to +obj+.
+ * s1 = 'bar'; s2 = 'bar'
+ * a = [:foo, s1, 2, s2]
+ * deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' }
+ * a # => [:foo, 2]
*
- * Returns the last deleted item, or +nil+ if no matching item is found.
+ * If no such elements are found, returns the block's return value:
*
- * If the optional code block is given, the result of the block is returned if
- * the item is not found. (To remove +nil+ elements and get an informative
- * return value, use Array#compact!)
+ * a = [:foo, 'bar', 2]
+ * a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found"
*
- * a = [ "a", "b", "b", "b", "c" ]
- * a.delete("b") #=> "b"
- * a #=> ["a", "c"]
- * a.delete("z") #=> nil
- * a.delete("z") {"not found"} #=> "not found"
*/
VALUE
@@ -3396,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);
@@ -3426,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);
@@ -3451,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);
@@ -3467,17 +4251,25 @@ rb_ary_delete_at(VALUE ary, long pos)
/*
* call-seq:
- * ary.delete_at(index) -> obj or nil
+ * array.delete_at(index) -> deleted_object or nil
+ *
+ * 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]
*
- * Deletes the element at the specified +index+, returning that element, or
- * +nil+ if the +index+ is out of range.
+ * If index is too large, returns +nil+.
*
- * See also Array#slice!
+ * When +index+ is negative, counts backward from the end of the array:
*
- * a = ["ant", "bat", "cat", "dog"]
- * a.delete_at(2) #=> "cat"
- * a #=> ["ant", "bat", "dog"]
- * a.delete_at(99) #=> nil
+ * a = [:foo, 'bar', 2]
+ * a.delete_at(-2) # => "bar"
+ * a # => [:foo, 2]
+ *
+ * If +index+ is too small (far from zero), returns nil.
*/
static VALUE
@@ -3486,70 +4278,133 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos)
return rb_ary_delete_at(ary, NUM2LONG(pos));
}
+static VALUE
+ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
+{
+ const long orig_len = RARRAY_LEN(ary);
+
+ if (len < 0) {
+ return Qnil;
+ }
+ else if (pos < -orig_len) {
+ return Qnil;
+ }
+ else if (pos < 0) {
+ pos += orig_len;
+ }
+ else if (orig_len < pos) {
+ return Qnil;
+ }
+ if (orig_len < pos + len) {
+ len = orig_len - pos;
+ }
+ if (len == 0) {
+ return rb_ary_new2(0);
+ }
+ else {
+ VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
+ rb_ary_splice(ary, pos, len, 0, 0);
+ return arg2;
+ }
+}
+
/*
* call-seq:
- * ary.slice!(index) -> obj or nil
- * ary.slice!(start, length) -> new_ary or nil
- * ary.slice!(range) -> new_ary or nil
- *
- * Deletes the element(s) given by an +index+ (optionally up to +length+
- * elements) or by a +range+.
- *
- * Returns the deleted object (or objects), or +nil+ if the +index+ is out of
- * range.
- *
- * a = [ "a", "b", "c" ]
- * a.slice!(1) #=> "b"
- * a #=> ["a", "c"]
- * a.slice!(-1) #=> "c"
- * a #=> ["a"]
- * a.slice!(100) #=> nil
- * a #=> ["a"]
+ * array.slice!(n) -> object or nil
+ * array.slice!(start, length) -> new_array or nil
+ * array.slice!(range) -> new_array or nil
+ *
+ * Removes and returns elements from +self+.
+ *
+ * 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"]
+ *
+ * If +n+ is out of range, returns +nil+.
+ *
+ * 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:
+ *
+ * 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]
+ *
+ * If <tt>start == a.size</tt> and +length+ is non-negative,
+ * returns a new empty \Array.
+ *
+ * If +length+ is negative, returns +nil+.
+ *
+ * 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 # => [:foo]
+ *
+ * If <tt>range.start == a.size</tt>, returns a new empty \Array.
+ *
+ * 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
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
{
- VALUE arg1, arg2;
- long pos, len, orig_len;
+ VALUE arg1;
+ long pos, len;
rb_ary_modify_check(ary);
- if (argc == 2) {
- pos = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
- delete_pos_len:
- if (len < 0) return Qnil;
- orig_len = RARRAY_LEN(ary);
- if (pos < 0) {
- pos += orig_len;
- if (pos < 0) return Qnil;
- }
- else if (orig_len < pos) return Qnil;
- if (orig_len < pos + len) {
- len = orig_len - pos;
- }
- if (len == 0) return rb_ary_new2(0);
- arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
- RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
- rb_ary_splice(ary, pos, len, 0, 0);
- return arg2;
- }
-
rb_check_arity(argc, 1, 2);
arg1 = argv[0];
+ if (argc == 2) {
+ 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 */
- goto delete_pos_len;
- case Qnil:
- /* invalid range */
- return Qnil;
- default:
- /* not a range */
- break;
- }
+ 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;
+ }
}
return rb_ary_delete_at(ary, NUM2LONG(arg1));
@@ -3561,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;
}
@@ -3578,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;
}
@@ -3600,17 +4455,23 @@ ary_reject_bang(VALUE ary)
/*
* call-seq:
- * ary.reject! {|item| block} -> ary or nil
- * ary.reject! -> Enumerator
+ * array.reject! {|element| ... } -> self or nil
+ * array.reject! -> new_enumerator
+ *
+ * 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]
*
- * Deletes every element of +self+ for which the block evaluates to +true+,
- * if no changes were made returns +nil+.
+ * Returns +nil+ if no elements removed.
*
- * The array may not be changed instantly every time the block is called.
+ * Returns a new \Enumerator if no block given:
*
- * See also Enumerable#reject and Array#delete_if.
+ * a = [:foo, 'bar', 2]
+ * a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
*
- * If no block is given, an Enumerator is returned instead.
*/
static VALUE
@@ -3623,15 +4484,21 @@ rb_ary_reject_bang(VALUE ary)
/*
* call-seq:
- * ary.reject {|item| block } -> new_ary
- * ary.reject -> Enumerator
+ * array.reject {|element| ... } -> new_array
+ * array.reject -> new_enumerator
*
- * Returns a new array containing the items in +self+ for which the given
- * block is not +true+. The ordering of non-rejected elements is maintained.
+ * Returns a new \Array whose elements are all those from +self+
+ * for which the block returns +false+ or +nil+:
*
- * See also Array#delete_if
+ * 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>
*
- * If no block is given, an Enumerator is returned instead.
*/
static VALUE
@@ -3647,21 +4514,21 @@ rb_ary_reject(VALUE ary)
/*
* call-seq:
- * ary.delete_if {|item| block} -> ary
- * ary.delete_if -> Enumerator
+ * array.delete_if {|element| ... } -> self
+ * array.delete_if -> Enumerator
*
- * Deletes every element of +self+ for which block evaluates to +true+.
+ * Removes each element in +self+ for which the block returns a truthy value;
+ * returns +self+:
*
- * The array is changed instantly every time the block is called, not after
- * the iteration is over.
+ * a = [:foo, 'bar', 2, 'bat']
+ * a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
*
- * See also Array#reject!
+ * Returns a new \Enumerator if no block given:
*
- * If no block is given, an Enumerator is returned instead.
+ * a = [:foo, 'bar', 2]
+ * a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
*
- * scores = [ 97, 42, 75 ]
- * scores.delete_if {|score| score < 80 } #=> [97]
- */
+3 */
static VALUE
rb_ary_delete_if(VALUE ary)
@@ -3676,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;
}
@@ -3689,38 +4555,71 @@ 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;
}
/*
* call-seq:
- * ary.zip(arg, ...) -> new_ary
- * ary.zip(arg, ...) {|arr| block} -> nil
+ * array.zip(*other_arrays) -> new_array
+ * array.zip(*other_arrays) {|other_array| ... } -> nil
+ *
+ * When no block given, returns a new \Array +new_array+ of size <tt>self.size</tt>
+ * whose elements are Arrays.
+ *
+ * Each nested array <tt>new_array[n]</tt> is of size <tt>other_arrays.size+1</tt>,
+ * and contains:
*
- * Converts any arguments to arrays, then merges elements of +self+ with
- * corresponding elements from each argument.
+ * - The _nth_ element of +self+.
+ * - The _nth_ element of each of the +other_arrays+.
*
- * This generates a sequence of <code>ary.size</code> _n_-element arrays,
- * where _n_ is one more than the count of arguments.
+ * If all +other_arrays+ and +self+ are the same size:
*
- * If the size of any argument is less than the size of the initial array,
- * +nil+ values are supplied.
+ * a = [:a0, :a1, :a2, :a3]
+ * b = [:b0, :b1, :b2, :b3]
+ * c = [:c0, :c1, :c2, :c3]
+ * d = a.zip(b, c)
+ * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
*
- * If a block is given, it is invoked for each output +array+, otherwise an
- * array of arrays is returned.
+ * 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]
+ * d = a.zip(b, c)
+ * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
+ *
+ * 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+:
+ *
+ * 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]
*
- * a = [ 4, 5, 6 ]
- * b = [ 7, 8, 9 ]
- * [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
- * [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
- * a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
*/
static VALUE
@@ -3731,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;
@@ -3783,15 +4682,14 @@ rb_ary_zip(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.transpose -> new_ary
+ * array.transpose -> new_array
*
- * Assumes that +self+ is an array of arrays and transposes the rows and
- * columns.
+ * Transposes the rows and columns in an \Array of Arrays;
+ * the nested Arrays must all be the same size:
*
- * a = [[1,2], [3,4], [5,6]]
- * a.transpose #=> [[1, 3, 5], [2, 4, 6]]
+ * a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
+ * a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
*
- * If the length of the subarrays don't match, an IndexError is raised.
*/
static VALUE
@@ -3803,36 +4701,34 @@ 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;
}
/*
* call-seq:
- * ary.replace(other_ary) -> ary
- * ary.initialize_copy(other_ary) -> ary
+ * array.replace(other_array) -> self
+ *
+ * Replaces the content of +self+ with the content of +other_array+; returns +self+:
*
- * Replaces the contents of +self+ with the contents of +other_ary+,
- * truncating or expanding if necessary.
+ * a = [:foo, 'bar', 2]
+ * a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
- * a #=> ["x", "y", "z"]
*/
VALUE
@@ -3842,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));
@@ -3878,12 +4778,13 @@ rb_ary_replace(VALUE copy, VALUE orig)
/*
* call-seq:
- * ary.clear -> ary
+ * array.clear -> self
*
- * Removes all elements from +self+.
+ * Removes all elements from +self+:
+ *
+ * a = [:foo, 'bar', 2]
+ * a.clear # => []
*
- * a = [ "a", "b", "c", "d", "e" ]
- * a.clear #=> [ ]
*/
VALUE
@@ -3891,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);
@@ -3909,32 +4810,198 @@ rb_ary_clear(VALUE ary)
/*
* call-seq:
- * ary.fill(obj) -> ary
- * ary.fill(obj, start [, length]) -> ary
- * ary.fill(obj, range) -> ary
- * ary.fill {|index| block} -> ary
- * ary.fill(start [, length]) {|index| block} -> ary
- * ary.fill(range) {|index| block} -> ary
+ * array.fill(obj) -> self
+ * array.fill(obj, start) -> self
+ * array.fill(obj, start, length) -> self
+ * array.fill(obj, range) -> self
+ * array.fill {|index| ... } -> self
+ * array.fill(start) {|index| ... } -> self
+ * array.fill(start, length) {|index| ... } -> self
+ * array.fill(range) {|index| ... } -> self
+ *
+ * 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]
+ *
+ * With arguments +obj+ and \Integer +start+, and no block given,
+ * replaces elements based on the given start.
+ *
+ * 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']
+ * a.fill(:X, -50) # => [:X, :X, :X, :X]
+ *
+ * With arguments +obj+, \Integer +start+, and \Integer +length+, and no block given,
+ * 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"]
+ *
+ * With arguments +obj+ and \Range +range+, and no block given,
+ * replaces elements based on the given range.
+ *
+ * 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"]
*
- * The first three forms set the selected elements of +self+ (which
- * may be the entire array) to +obj+.
+ * If <tt>range.last</tt> is negative, counts from the end:
*
- * A +start+ of +nil+ is equivalent to zero.
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"]
*
- * A +length+ of +nil+ is equivalent to the length of the array.
+ * If <tt>range.last</tt> and <tt>range.last</tt> are both negative,
+ * both count from the end of the array:
*
- * The last three forms fill the array with the value of the given block,
- * which is passed the absolute index of each element to be filled.
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X]
+ * a = ['a', 'b', 'c', 'd']
+ * a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"]
*
- * Negative values of +start+ count from the end of the array, where +-1+ is
- * the last element.
+ * 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.
+ *
+ * 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']
+ * a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
+ *
+ * With arguments +start+ and +length+, and a block given,
+ * calls the block for each index specified by start length;
+ * 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"]
+ *
+ * With arguments +obj+ and +range+, and a block given,
+ * calls the block with each index in the given range;
+ * replaces the corresponding element with the block's return value.
+ *
+ * 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']
+ * a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"]
+ *
+ * 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"]
*
- * a = [ "a", "b", "c", "d" ]
- * a.fill("x") #=> ["x", "x", "x", "x"]
- * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
- * a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
- * a.fill {|i| i*i} #=> [0, 1, 4, 9]
- * a.fill(-2) {|i| i*i*i} #=> [0, 1, 8, 27]
*/
static VALUE
@@ -3944,84 +5011,74 @@ 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;
}
/*
* call-seq:
- * ary + other_ary -> new_ary
+ * array + other_array -> new_array
*
- * Concatenation --- Returns a new array built by concatenating the
- * two arrays together to produce a third array.
+ * Returns a new \Array containing all elements of +array+
+ * followed by all elements of +other_array+:
*
- * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
- * a = [ "a", "b", "c" ]
- * c = a + [ "d", "e", "f" ]
- * c #=> [ "a", "b", "c", "d", "e", "f" ]
- * a #=> [ "a", "b", "c" ]
+ * a = [0, 1] + [2, 3]
+ * a # => [0, 1, 2, 3]
*
- * Note that
- * x += y
- * is the same as
- * x = x + y
- * This means that it produces a new array. As a consequence,
- * repeated use of <code>+=</code> on arrays can be quite inefficient.
- *
- * See also Array#concat.
+ * Related: #concat.
*/
VALUE
@@ -4049,27 +5106,18 @@ 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;
}
/*
* call-seq:
- * ary.concat(other_ary1, other_ary2, ...) -> ary
- *
- * Appends the elements of <code>other_ary</code>s to +self+.
+ * array.concat(*other_arrays) -> self
*
- * [ "a", "b" ].concat( ["c", "d"]) #=> [ "a", "b", "c", "d" ]
- * [ "a" ].concat( ["b"], ["c", "d"]) #=> [ "a", "b", "c", "d" ]
- * [ "a" ].concat #=> [ "a" ]
+ * Adds to +array+ all elements from each \Array in +other_arrays+; returns +self+:
*
- * a = [ 1, 2, 3 ]
- * a.concat( [ 4, 5 ])
- * a #=> [ 1, 2, 3, 4, 5 ]
- *
- * a = [ 1, 2 ]
- * a.concat(a, a) #=> [1, 2, 1, 2, 1, 2]
- *
- * See also Array#+.
+ * a = [0, 1]
+ * a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]
*/
static VALUE
@@ -4078,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);
@@ -4101,18 +5149,19 @@ rb_ary_concat(VALUE x, VALUE y)
/*
* call-seq:
- * ary * int -> new_ary
- * ary * str -> new_string
+ * array * n -> new_array
+ * array * string_separator -> new_string
*
- * Repetition --- With a String argument, equivalent to
- * <code>ary.join(str)</code>.
+ * When non-negative argument \Integer +n+ is given,
+ * returns a new \Array built by concatenating the +n+ copies of +self+:
*
- * Otherwise, returns a new array built by concatenating the +int+ 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>:
*
- * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]
- * [ 1, 2, 3 ] * "," #=> "1,2,3"
+ * [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
*
*/
@@ -4125,30 +5174,30 @@ 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_obj_class(ary), 0);
- goto out;
+ ary2 = ary_new(rb_cArray, 0);
+ 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);
- ary2 = ary_new(rb_obj_class(ary), len);
+ ary2 = ary_new(rb_cArray, len);
ARY_SET_LEN(ary2, len);
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;
}
@@ -4162,22 +5211,17 @@ rb_ary_times(VALUE ary, VALUE times)
/*
* call-seq:
- * ary.assoc(obj) -> element_ary or nil
+ * array.assoc(obj) -> found_array or nil
*
- * Searches through an array whose elements are also arrays comparing +obj+
- * with the first element of each contained array using <code>obj.==</code>.
+ * Returns the first element in +self+ that is an \Array
+ * whose first element <tt>==</tt> +obj+:
*
- * Returns the first contained array that matches (that is, the first
- * associated array), or +nil+ if no match is found.
+ * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
+ * a.assoc(4) # => [4, 5, 6]
*
- * See also Array#rassoc
+ * Returns +nil+ if no such element is found.
*
- * s1 = [ "colors", "red", "blue", "green" ]
- * s2 = [ "letters", "a", "b", "c" ]
- * s3 = "foo"
- * a = [ s1, s2, s3 ]
- * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
- * a.assoc("foo") #=> nil
+ * Related: #rassoc.
*/
VALUE
@@ -4187,30 +5231,27 @@ 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;
}
/*
* call-seq:
- * ary.rassoc(obj) -> element_ary or nil
+ * array.rassoc(obj) -> found_array or nil
*
- * Searches through the array whose elements are also arrays.
+ * Returns the first element in +self+ that is an \Array
+ * whose second element <tt>==</tt> +obj+:
*
- * Compares +obj+ with the second element of each contained array using
- * <code>obj.==</code>.
+ * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
+ * a.rassoc(4) # => [2, 4]
*
- * Returns the first contained array that matches +obj+.
+ * Returns +nil+ if no such element is found.
*
- * See also Array#assoc.
- *
- * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
- * a.rassoc("two") #=> [2, "two"]
- * a.rassoc("four") #=> nil
+ * Related: #assoc.
*/
VALUE
@@ -4220,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;
}
@@ -4243,38 +5284,42 @@ 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;
}
/*
* call-seq:
- * ary == other_ary -> bool
+ * array == other_array -> true or false
*
- * Equality --- Two arrays are equal if they contain the same number of
- * elements and if each element is equal to (according to Object#==) the
- * corresponding element in +other_ary+.
+ * 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>:
*
- * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
- * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
- * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
+ * a0 = [:foo, 'bar', 2]
+ * a1 = [:foo, 'bar', 2.0]
+ * a1 == a0 # => true
+ * [] == [] # => true
*
+ * Otherwise, returns +false+.
+ *
+ * This method is different from method Array#eql?,
+ * which compares elements using <tt>Object#eql?</tt>.
*/
static VALUE
@@ -4282,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;
@@ -4299,18 +5344,27 @@ 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;
}
/*
* call-seq:
- * ary.eql?(other) -> true or false
+ * array.eql? other_array -> true or false
+ *
+ * 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+.
*
- * Returns +true+ if +self+ and +other+ are the same object,
- * or are both arrays with the same content (according to Object#eql?).
+ * This method is different from method Array#==,
+ * which compares using method <tt>Object#==</tt>.
*/
static VALUE
@@ -4325,14 +5379,15 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary.hash -> integer
+ * array.hash -> integer
*
- * Compute a hash-code for this array.
+ * Returns the integer hash value for +self+.
*
- * Two arrays with the same content will have the same hash code (and will
- * compare using #eql?).
+ * 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
*
- * See also Object#hash.
*/
static VALUE
@@ -4345,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);
@@ -4354,14 +5409,13 @@ rb_ary_hash(VALUE ary)
/*
* call-seq:
- * ary.include?(object) -> true or false
+ * array.include?(obj) -> true or false
*
- * Returns +true+ if the given +object+ is present in +self+ (that is, if any
- * element <code>==</code> +object+), otherwise returns +false+.
+ * Returns +true+ if for some index +i+ in +self+, <tt>obj == self[i]</tt>;
+ * otherwise +false+:
*
- * a = [ "a", "b", "c" ]
- * a.include?("b") #=> true
- * a.include?("z") #=> false
+ * [0, 1, 2].include?(2) # => true
+ * [0, 1, 2].include?(3) # => false
*/
VALUE
@@ -4371,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;
}
@@ -4386,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;
}
@@ -4402,45 +5456,46 @@ 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;
}
/*
* call-seq:
- * ary <=> other_ary -> -1, 0, +1 or nil
+ * array <=> other_array -> -1, 0, or 1
+ *
+ * Returns -1, 0, or 1 as +self+ is less than, equal to, or greater than +other_array+.
+ * 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:
*
- * Comparison --- Returns an integer (+-1+, +0+, or <code>+1</code>) if this
- * array is less than, equal to, or greater than +other_ary+.
+ * [0, 1, 2] <=> [0, 1, 1] # => 1
*
- * Each object in each array is compared (using the <=> operator).
+ * When all results are zero:
*
- * Arrays are compared in an "element-wise" manner; the first element of +ary+
- * is compared with the first one of +other_ary+ using the <=> operator, then
- * each of the second elements, etc...
- * As soon as the result of any such comparison is non zero (i.e. the two
- * corresponding elements are not equal), that result is returned for the
- * whole array comparison.
+ * - Returns -1 if +array+ is smaller than +other_array+:
*
- * If all the elements are equal, then the result is based on a comparison of
- * the array lengths. Thus, two arrays are "equal" according to Array#<=> if,
- * and only if, they have the same length and the value of each element is
- * equal to the value of the corresponding element in the other array.
+ * [0, 1, 2] <=> [0, 1, 2, 3] # => -1
*
- * +nil+ is returned if the +other_ary+ is not an array or if the comparison
- * of two elements returned +nil+.
+ * - Returns 1 if +array+ is larger than +other_array+:
*
- * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
- * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
- * [ 1, 2 ] <=> [ 1, :two ] #=> nil
+ * [0, 1, 2] <=> [0, 1] # => 1
+ *
+ * - Returns 0 if +array+ and +other_array+ are the same size:
+ *
+ * [0, 1, 2] <=> [0, 1, 2] # => 0
*
*/
@@ -4454,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);
@@ -4467,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;
}
@@ -4496,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;
}
@@ -4515,35 +5570,28 @@ 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);
}
}
/*
* call-seq:
- * ary - other_ary -> new_ary
- *
- * Array Difference
- *
- * Returns a new array that is a copy of the original array, removing all
- * occurrences of any item that also appear in +other_ary+. The order is
- * preserved from the original array.
- *
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * array - other_array -> new_array
*
- * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
+ * Returns a new \Array containing only those elements from +array+
+ * that are not found in \Array +other_array+;
+ * items are compared using <tt>eql?</tt>;
+ * the order from +array+ is preserved:
*
- * Note that while 1 and 2 were only present once in the array argument, and
- * were present twice in the receiver array, all occurrences of each Integer are
- * removed in the returned array.
+ * [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]
*
- * If you need set-like behavior, see the library class Set.
- *
- * See also Array#difference.
+ * Related: Array#difference.
*/
-static VALUE
+VALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
VALUE ary3;
@@ -4551,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;
@@ -4573,31 +5622,19 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary.difference(other_ary1, other_ary2, ...) -> new_ary
- *
- * Array Difference
+ * array.difference(*other_arrays) -> new_array
*
- * Returns a new array that is a copy of the original array, removing all
- * occurrences of any item that also appear in +other_ary+. The order is
- * preserved from the original array.
+ * 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:
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * [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]
*
- * [ 1, 1, 2, 2, 3, 3, 4, 5 ].difference([ 1, 2, 4 ]) #=> [ 3, 3, 5 ]
+ * Returns a copy of +self+ if no arguments given.
*
- * Note that while 1 and 2 were only present once in the array argument, and
- * were present twice in the receiver array, all occurrences of each Integer are
- * removed in the returned array.
- *
- * Multiple array arguments can be supplied and all occurrences of any element
- * in those supplied arrays that match the receiver will be removed from the
- * returned array.
- *
- * [ 1, 'c', :s, 'yep' ].difference([ 1 ], [ 'a', 'c' ]) #=> [ :s, "yep" ]
- *
- * If you need set-like behavior, see the library class Set.
- *
- * See also Array#-.
+ * Related: Array#-.
*/
static VALUE
@@ -4639,17 +5676,19 @@ rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary & other_ary -> new_ary
+ * array & other_array -> new_array
+ *
+ * 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>:
*
- * Set Intersection --- Returns a new array containing unique elements common to the
- * two arrays. The order is preserved from the original array.
+ * [0, 1, 2, 3] & [1, 2] # => [1, 2]
+ * [0, 1, 0, 1] & [0, 1] # => [0, 1]
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * Preserves order from +array+:
*
- * [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
- * [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
+ * [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
*
- * See also Array#uniq.
+ * Related: Array#intersection.
*/
@@ -4665,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);
@@ -4690,19 +5729,22 @@ rb_ary_and(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary.intersection(other_ary1, other_ary2, ...) -> new_ary
+ * array.intersection(*other_arrays) -> new_array
+ *
+ * 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]
*
- * Set Intersection --- Returns a new array containing unique elements common
- * to +self+ and <code>other_ary</code>s. Order is preserved from the original
- * array.
+ * Preserves order from +self+:
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
*
- * [ 1, 1, 3, 5 ].intersection([ 3, 2, 1 ]) # => [ 1, 3 ]
- * [ "a", "b", "z" ].intersection([ "a", "b", "c" ], [ "b" ]) # => [ "b" ]
- * [ "a" ].intersection #=> [ "a" ]
+ * Returns a copy of +self+ if no arguments given.
*
- * See also Array#&.
+ * Related: Array#&.
*/
static VALUE
@@ -4751,17 +5793,17 @@ rb_ary_union_hash(VALUE hash, VALUE ary2)
/*
* call-seq:
- * ary | other_ary -> new_ary
+ * array | other_array -> new_array
*
- * Set Union --- Returns a new array by joining +ary+ with +other_ary+,
- * excluding any duplicates and preserving the order from the given arrays.
+ * Returns the union of +array+ and \Array +other_array+;
+ * duplicates are removed; order is preserved;
+ * items are compared using <tt>eql?</tt>:
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * [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]
*
- * [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
- * [ "c", "d", "a" ] | [ "a", "b", "c" ] #=> [ "c", "d", "a", "b" ]
- *
- * See also Array#union.
+ * Related: Array#union.
*/
static VALUE
@@ -4771,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);
@@ -4787,18 +5829,18 @@ rb_ary_or(VALUE ary1, VALUE ary2)
/*
* call-seq:
- * ary.union(other_ary1, other_ary2, ...) -> new_ary
+ * array.union(*other_arrays) -> new_array
*
- * Set Union --- Returns a new array by joining <code>other_ary</code>s with +self+,
- * excluding any duplicates and preserving the order from the given arrays.
+ * 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>:
*
- * It compares elements using their #hash and #eql? methods for efficiency.
+ * [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]
*
- * [ "a", "b", "c" ].union( [ "c", "d", "a" ] ) #=> [ "a", "b", "c", "d" ]
- * [ "a" ].union( ["e", "b"], ["a", "c", "b"] ) #=> [ "a", "e", "b", "c" ]
- * [ "a" ].union #=> [ "a" ]
+ * Returns a copy of +self+ if no arguments given.
*
- * See also Array#|.
+ * Related: Array#|.
*/
static VALUE
@@ -4833,30 +5875,191 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.max -> obj
- * ary.max {|a, b| block} -> obj
- * ary.max(n) -> array
- * ary.max(n) {|a, b| block} -> array
+ * 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)
+{
+ RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
+
+ VALUE v;
+ for (; i < RARRAY_LEN(ary); ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_fixnum(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(FIXNUM_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (FIXNUM_P(v)) {
+ if ((long)vmax < (long)v) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_float(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(RB_FLOAT_TYPE_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (RB_FLOAT_TYPE_P(v)) {
+ if (rb_float_cmp(vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+static VALUE
+ary_max_opt_string(VALUE ary, long i, VALUE vmax)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(STRING_P(vmax));
+
+ VALUE v;
+ for (; i < n; ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (STRING_P(v)) {
+ if (rb_str_cmp(vmax, v) < 0) {
+ vmax = v;
+ }
+ }
+ else {
+ return ary_max_generic(ary, i, vmax);
+ }
+ }
+
+ return vmax;
+}
+
+/*
+ * call-seq:
+ * array.max -> element
+ * array.max {|a, b| ... } -> element
+ * array.max(n) -> new_array
+ * 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+.
+ *
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * with an \Integer.
+ *
+ * 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]
+ *
+ * When a block is given, the block must return an \Integer.
*
- * Returns the object in _ary_ with the maximum value. The
- * first form assumes all objects implement Comparable;
- * the second uses the block to return <em>a <=> b</em>.
+ * 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:
*
- * ary = %w(albatross dog horse)
- * ary.max #=> "horse"
- * ary.max {|a, b| a.length <=> b.length} #=> "albatross"
+ * ['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000"
*
- * If the +n+ argument is given, maximum +n+ elements are returned
- * as an array.
+ * 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"]
*
- * ary = %w[albatross dog horse]
- * ary.max(2) #=> ["horse", "dog"]
- * ary.max(2) {|a, b| a.length <=> b.length } #=> ["albatross", "horse"]
*/
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;
@@ -4864,52 +6067,167 @@ rb_ary_max(int argc, VALUE *argv, VALUE ary)
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 1, 1);
+ 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 {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
- result = v;
- }
- }
- }
- if (result == Qundef) return Qnil;
+ else if (n > 0) {
+ result = RARRAY_AREF(ary, 0);
+ if (n > 1) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
+ return ary_max_opt_fixnum(ary, 1, result);
+ }
+ 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(FLOAT)) {
+ return ary_max_opt_float(ary, 1, result);
+ }
+ else {
+ return ary_max_generic(ary, 1, result);
+ }
+ }
+ }
+ if (UNDEF_P(result)) return Qnil;
return result;
}
+static VALUE
+ary_min_generic(VALUE ary, long i, VALUE vmin)
+{
+ RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
+
+ VALUE v;
+ for (; i < RARRAY_LEN(ary); ++i) {
+ v = RARRAY_AREF(ary, i);
+
+ if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
+ vmin = v;
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_fixnum(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(FIXNUM_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (FIXNUM_P(a)) {
+ if ((long)vmin > (long)a) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_float(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(RB_FLOAT_TYPE_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (RB_FLOAT_TYPE_P(a)) {
+ if (rb_float_cmp(vmin, a) > 0) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
+static VALUE
+ary_min_opt_string(VALUE ary, long i, VALUE vmin)
+{
+ const long n = RARRAY_LEN(ary);
+ RUBY_ASSERT(i > 0 && i < n);
+ RUBY_ASSERT(STRING_P(vmin));
+
+ VALUE a;
+ for (; i < n; ++i) {
+ a = RARRAY_AREF(ary, i);
+
+ if (STRING_P(a)) {
+ if (rb_str_cmp(vmin, a) > 0) {
+ vmin = a;
+ }
+ }
+ else {
+ return ary_min_generic(ary, i, vmin);
+ }
+ }
+
+ return vmin;
+}
+
/*
* call-seq:
- * ary.min -> obj
- * ary.min {| a,b | block } -> obj
- * ary.min(n) -> array
- * ary.min(n) {| a,b | block } -> array
+ * array.min -> element
+ * array.min { |a, b| ... } -> element
+ * array.min(n) -> new_array
+ * 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+.
+ *
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * with an \Integer.
+ *
+ * With no argument and no block, returns the element in +self+
+ * having the minimum value per method <tt><=></tt>:
*
- * Returns the object in _ary_ with the minimum value. The
- * first form assumes all objects implement Comparable;
- * the second uses the block to return <em>a <=> b</em>.
+ * [0, 1, 2].min # => 0
*
- * ary = %w(albatross dog horse)
- * ary.min #=> "albatross"
- * ary.min {|a, b| a.length <=> b.length} #=> "dog"
+ * With \Integer argument +n+ and no block, returns a new \Array with at most +n+ elements,
+ * in ascending order per method <tt><=></tt>:
*
- * If the +n+ argument is given, minimum +n+ elements are returned
- * as an array.
+ * [0, 1, 2, 3].min(3) # => [0, 1, 2]
+ * [0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
+ *
+ * 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 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', '00', '000'].min(2) {|a, b| a.size <=> b.size } # => ["0", "00"]
*
- * ary = %w[albatross dog horse]
- * ary.min(2) #=> ["albatross", "dog"]
- * ary.min(2) {|a, b| a.length <=> b.length } #=> ["dog", "horse"]
*/
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;
@@ -4917,36 +6235,58 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary)
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 0, 1);
+ 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 {
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- v = RARRAY_AREF(ary, i);
- if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
- result = v;
- }
- }
- }
- if (result == Qundef) return Qnil;
+ else if (n > 0) {
+ result = RARRAY_AREF(ary, 0);
+ if (n > 1) {
+ if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
+ return ary_min_opt_fixnum(ary, 1, result);
+ }
+ 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(FLOAT)) {
+ return ary_min_opt_float(ary, 1, result);
+ }
+ else {
+ return ary_min_generic(ary, 1, result);
+ }
+ }
+ }
+ if (UNDEF_P(result)) return Qnil;
return result;
}
/*
* call-seq:
- * ary.minmax -> [obj, obj]
- * ary.minmax {| a,b | block } -> [obj, obj]
+ * array.minmax -> [min_val, max_val]
+ * array.minmax {|a, b| ... } -> [min_val, max_val]
*
- * Returns a two element array which contains the minimum and the
- * maximum value in the array.
+ * Returns a new 2-element \Array containing the minimum and maximum values
+ * from +self+, either per method <tt><=></tt> or per a given block:.
+ *
+ * When no block is given, each element in +self+ must respond to method <tt><=></tt>
+ * 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"]
*
- * Can be given an optional block to override the default comparison
- * method <code>a <=> b</code>.
*/
static VALUE
rb_ary_minmax(VALUE ary)
@@ -4966,31 +6306,33 @@ push_value(st_data_t key, st_data_t val, st_data_t ary)
/*
* call-seq:
- * ary.uniq! -> ary or nil
- * ary.uniq! {|item| ...} -> ary or nil
+ * array.uniq! -> self or nil
+ * array.uniq! {|element| ... } -> self or nil
*
- * Removes duplicate elements from +self+.
+ * Removes duplicate elements from +self+, the first occurrence always being retained;
+ * returns +self+ if any elements removed, +nil+ otherwise.
*
- * If a block is given, it will use the return value of the block for
- * comparison.
+ * With no block given, identifies and removes elements using method <tt>eql?</tt>
+ * to compare.
*
- * It compares values using their #hash and #eql? methods for efficiency.
+ * Returns +self+ if any elements removed:
*
- * +self+ is traversed in order, and the first occurrence is kept.
+ * a = [0, 0, 1, 1, 2, 2]
+ * a.uniq! # => [0, 1, 2]
*
- * Returns +nil+ if no changes are made (that is, no duplicates are found).
+ * Returns +nil+ if no elements removed.
*
- * a = [ "a", "a", "b", "b", "c" ]
- * a.uniq! # => ["a", "b", "c"]
+ * With a block given, calls the block for each element;
+ * identifies (using method <tt>eql?</tt>) and removes
+ * elements for which the block returns duplicate values.
*
- * b = [ "a", "b", "c" ]
- * b.uniq! # => nil
+ * Returns +self+ if any elements removed:
*
- * c = [["student","sam"], ["student","george"], ["teacher","matz"]]
- * c.uniq! {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]
+ * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
+ * a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa']
*
+ * Returns +nil+ if no elements removed.
*/
-
static VALUE
rb_ary_uniq_bang(VALUE ary)
{
@@ -5001,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);
@@ -5024,22 +6366,24 @@ rb_ary_uniq_bang(VALUE ary)
/*
* call-seq:
- * ary.uniq -> new_ary
- * ary.uniq {|item| ...} -> new_ary
- *
- * Returns a new array by removing duplicate values in +self+.
+ * array.uniq -> new_array
+ * array.uniq {|element| ... } -> new_array
*
- * If a block is given, it will use the return value of the block for comparison.
+ * Returns a new \Array containing those elements from +self+ that are not duplicates,
+ * the first occurrence always being retained.
*
- * It compares values using their #hash and #eql? methods for efficiency.
+ * With no block given, identifies and omits duplicates using method <tt>eql?</tt>
+ * to compare:
*
- * +self+ is traversed in order, and the first occurrence is kept.
+ * a = [0, 0, 1, 1, 2, 2]
+ * a.uniq # => [0, 1, 2]
*
- * a = [ "a", "a", "b", "b", "c" ]
- * a.uniq # => ["a", "b", "c"]
+ * 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:
*
- * b = [["student","sam"], ["student","george"], ["teacher","matz"]]
- * b.uniq {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]
+ * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
+ * a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
*
*/
@@ -5053,14 +6397,13 @@ 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);
}
- RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
if (hash) {
ary_recycle_hash(hash);
}
@@ -5070,14 +6413,11 @@ rb_ary_uniq(VALUE ary)
/*
* call-seq:
- * ary.compact! -> ary or nil
+ * array.compact! -> self or nil
*
- * Removes +nil+ elements from the array.
+ * Removes all +nil+ elements from +self+.
*
- * Returns +nil+ if no changes were made, otherwise returns the array.
- *
- * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
- * [ "a", "b", "c" ].compact! #=> nil
+ * Returns +self+ if any elements removed, otherwise +nil+.
*/
static VALUE
@@ -5091,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);
@@ -5105,12 +6445,12 @@ rb_ary_compact_bang(VALUE ary)
/*
* call-seq:
- * ary.compact -> new_ary
+ * array.compact -> new_array
*
- * Returns a copy of +self+ with all +nil+ elements removed.
+ * Returns a new \Array containing all non-+nil+ elements from +self+:
*
- * [ "a", nil, "b", nil, "c", nil ].compact
- * #=> [ "a", "b", "c" ]
+ * a = [nil, 0, nil, 1, nil, 2, nil]
+ * a.compact # => [0, 1, 2]
*/
static VALUE
@@ -5123,23 +6463,29 @@ rb_ary_compact(VALUE ary)
/*
* call-seq:
- * ary.count -> int
- * ary.count(obj) -> int
- * ary.count {|item| block} -> int
+ * array.count -> an_integer
+ * array.count(obj) -> an_integer
+ * array.count {|element| ... } -> an_integer
*
- * Returns the number of elements.
+ * Returns a count of specified elements.
*
- * If an argument is given, counts the number of elements which equal +obj+
- * using <code>==</code>.
+ * With no argument and no block, returns the count of all elements:
*
- * If a block is given, counts the number of elements for which the block
- * returns a true value.
+ * [0, 1, 2].count # => 3
+ * [].count # => 0
*
- * ary = [1, 2, 4, 2]
- * ary.count #=> 4
- * ary.count(2) #=> 2
- * ary.count {|x| x%2 == 0} #=> 3
+ * 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>==</tt> to +obj+.
*/
static VALUE
@@ -5148,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);
@@ -5176,8 +6522,8 @@ static VALUE
flatten(VALUE ary, int level)
{
long i;
- VALUE stack, result, tmp, elt, vmemo;
- st_table *memo;
+ VALUE stack, result, tmp = 0, elt, vmemo;
+ st_table *memo = 0;
st_data_t id;
for (i = 0; i < RARRAY_LEN(ary); i++) {
@@ -5189,8 +6535,6 @@ flatten(VALUE ary, int level)
}
if (i == RARRAY_LEN(ary)) {
return ary;
- } else if (tmp == ary) {
- rb_raise(rb_eArgError, "tried to flatten recursive array");
}
result = ary_new(0, RARRAY_LEN(ary));
@@ -5201,79 +6545,100 @@ flatten(VALUE ary, int level)
rb_ary_push(stack, ary);
rb_ary_push(stack, LONG2NUM(i + 1));
- 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);
+ 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);
+ }
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) {
- RB_GC_GUARD(vmemo);
- st_clear(memo);
- rb_raise(rb_eRuntimeError, "flatten reentered");
- }
- if (NIL_P(tmp)) {
- rb_ary_push(result, elt);
- }
- else {
- id = (st_data_t)tmp;
- if (st_is_member(memo, id)) {
+ 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_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;
- }
- id = (st_data_t)ary;
- st_delete(memo, &id, 0);
- tmp = rb_ary_pop(stack);
- i = NUM2LONG(tmp);
- ary = rb_ary_pop(stack);
- }
-
- st_clear(memo);
-
- RBASIC_SET_CLASS(result, rb_obj_class(ary));
+ }
+ 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);
+ }
+
+ RBASIC_SET_CLASS(result, rb_cArray);
return result;
}
/*
* call-seq:
- * ary.flatten! -> ary or nil
- * ary.flatten!(level) -> ary or nil
+ * array.flatten! -> self or nil
+ * array.flatten!(level) -> self or nil
*
- * Flattens +self+ in place.
+ * Replaces each nested \Array in +self+ with the elements from that \Array;
+ * returns +self+ if any changes, +nil+ otherwise.
*
- * Returns +nil+ if no modifications were made (i.e., the array contains no
- * subarrays.)
+ * With non-negative \Integer argument +level+, flattens recursively through +level+ levels:
*
- * The optional +level+ argument determines the level of recursion to flatten.
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(2) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(3) # => [0, 1, 2, 3, 4, 5]
+ * [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
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(-1) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten!(-2) # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten!(-1) # => nil
*
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten! #=> [1, 2, 3, 4, 5]
- * a.flatten! #=> nil
- * a #=> [1, 2, 3, 4, 5]
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten!(1) #=> [1, 2, 3, [4, 5]]
*/
static VALUE
@@ -5289,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);
@@ -5300,24 +6665,35 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.flatten -> new_ary
- * ary.flatten(level) -> new_ary
- *
- * Returns a new array that is a one-dimensional flattening of +self+
- * (recursively).
- *
- * That is, for every element that is an array, extract its elements into
- * the new array.
+ * array.flatten -> new_array
+ * array.flatten(level) -> new_array
+ *
+ * Returns a new \Array that is a recursive flattening of +self+:
+ * - Each non-Array element is unchanged.
+ * - 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 ]
+ * a.flatten(1) # => [0, 1, [2, 3], 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(2) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * 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]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(-1) # => [0, 1, 2, 3, 4, 5]
+ * a = [ 0, [ 1, [2, 3], 4 ], 5 ]
+ * a.flatten(-2) # => [0, 1, 2, 3, 4, 5]
+ * [0, 1, 2].flatten(-1) # => [0, 1, 2]
*
- * The optional +level+ argument determines the level of recursion to
- * flatten.
- *
- * s = [ 1, 2, 3 ] #=> [1, 2, 3]
- * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
- * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
- * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- * a = [ 1, 2, [3, [4, 5] ] ]
- * a.flatten(1) #=> [1, 2, 3, [4, 5]]
*/
static VALUE
@@ -5349,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;
}
@@ -5372,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];
@@ -5381,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_values(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);
@@ -5502,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);
@@ -5519,24 +6901,37 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.cycle(n=nil) {|obj| block} -> nil
- * ary.cycle(n=nil) -> Enumerator
+ * array.cycle {|element| ... } -> nil
+ * array.cycle(count) {|element| ... } -> nil
+ * array.cycle -> new_enumerator
+ * array.cycle(count) -> new_enumerator
*
- * Calls the given block for each element +n+ times or forever if +nil+ is
- * given.
+ * 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+:
*
- * Does nothing if a non-positive number is given or the array is empty.
+ * output = []
+ * [0, 1].cycle(2) {|element| output.push(element) } # => nil
+ * output # => [0, 1, 0, 1]
*
- * Returns +nil+ if the loop has finished without getting interrupted.
+ * If +count+ is zero or negative, does not call the block:
*
- * If no block is given, an Enumerator is returned instead.
+ * [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil
+ * [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil
*
- * a = ["a", "b", "c"]
- * a.cycle {|x| puts x} # print, a, b, c, a, b, c,.. forever.
- * a.cycle(2) {|x| puts x} # print, a, b, c, a, b, c.
+ * 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 }
+ *
+ * When no block is given, returns a new \Enumerator:
+ *
+ * [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)
{
@@ -5561,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.
@@ -5599,52 +6991,52 @@ 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;
+ }
}
}
/*
* Returns the product of from, from-1, ..., from - how_many + 1.
- * http://en.wikipedia.org/wiki/Pochhammer_symbol
+ * https://en.wikipedia.org/wiki/Pochhammer_symbol
*/
static VALUE
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;
}
@@ -5655,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;
}
@@ -5682,30 +7074,82 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.permutation {|p| block} -> ary
- * ary.permutation -> Enumerator
- * ary.permutation(n) {|p| block} -> ary
- * ary.permutation(n) -> Enumerator
+ * array.permutation {|element| ... } -> self
+ * array.permutation(n) {|element| ... } -> self
+ * array.permutation -> new_enumerator
+ * array.permutation(n) -> new_enumerator
+ *
+ * When invoked with a block, yield all permutations of elements of +self+; returns +self+.
+ * The order of permutations is indeterminate.
*
- * When invoked with a block, yield all permutations of length +n+ of the
- * elements of the array, then return the array itself.
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * are given, calls the block with all +n+-tuple permutations of +self+.
*
- * If +n+ is not specified, yield all permutations of all elements.
+ * Example:
*
- * The implementation makes no guarantees about the order in which the
- * permutations are yielded.
+ * a = [0, 1, 2]
+ * a.permutation(2) {|permutation| p permutation }
*
- * If no block is given, an Enumerator is returned instead.
+ * Output:
*
- * Examples:
+ * [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]
+ * [1, 2, 0]
+ * [2, 0, 1]
+ * [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]
+ * [1, 2, 0]
+ * [2, 0, 1]
+ * [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)>
*
- * a = [1, 2, 3]
- * a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
- * a.permutation(1).to_a #=> [[1],[2],[3]]
- * a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
- * a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
- * a.permutation(0).to_a #=> [[]] # one permutation of length 0
- * a.permutation(4).to_a #=> [] # no permutations of length 4
*/
static VALUE
@@ -5720,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;
}
@@ -5754,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);
}
}
@@ -5778,26 +7222,55 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
/*
* call-seq:
- * ary.combination(n) {|c| block} -> ary
- * ary.combination(n) -> Enumerator
+ * array.combination(n) {|element| ... } -> self
+ * array.combination(n) -> new_enumerator
+ *
+ * Calls the block, if given, with combinations of elements of +self+;
+ * returns +self+. The order of combinations is indeterminate.
*
- * When invoked with a block, yields all combinations of length +n+ of elements
- * from the array and then returns the array itself.
+ * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>)
+ * are given, calls the block with all +n+-tuple combinations of +self+.
*
- * The implementation makes no guarantees about the order in which the
- * combinations are yielded.
+ * Example:
*
- * If no block is given, an Enumerator is returned instead.
+ * a = [0, 1, 2]
+ * a.combination(2) {|combination| p combination }
*
- * Examples:
+ * Output:
*
- * a = [1, 2, 3, 4]
- * a.combination(1).to_a #=> [[1],[2],[3],[4]]
- * a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
- * a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
- * a.combination(4).to_a #=> [[1,2,3,4]]
- * a.combination(0).to_a #=> [[]] # one combination of length 0
- * a.combination(5).to_a #=> [] # no combinations of length 5
+ * [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)>
*
*/
@@ -5810,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;
}
@@ -5852,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);
}
}
@@ -5875,37 +7348,79 @@ 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);
}
/*
* call-seq:
- * ary.repeated_permutation(n) {|p| block} -> ary
- * ary.repeated_permutation(n) -> Enumerator
+ * array.repeated_permutation(n) {|permutation| ... } -> self
+ * array.repeated_permutation(n) -> new_enumerator
+ *
+ * Calls the block with each repeated permutation of length +n+ of the elements of +self+;
+ * each permutation is an \Array;
+ * returns +self+. The order of the permutations is indeterminate.
+ *
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
+ * +n+-tuple repeated permutation of the elements of +self+.
+ * The number of permutations is <tt>self.size**n</tt>.
+ *
+ * +n+ = 1:
+ *
+ * a = [0, 1, 2]
+ * a.repeated_permutation(1) {|permutation| p permutation }
*
- * When invoked with a block, yield all repeated permutations of length +n+ of
- * the elements of the array, then return the array itself.
+ * Output:
*
- * The implementation makes no guarantees about the order in which the repeated
- * permutations are yielded.
+ * [0]
+ * [1]
+ * [2]
*
- * If no block is given, an Enumerator is returned instead.
+ * +n+ = 2:
*
- * Examples:
+ * a.repeated_permutation(2) {|permutation| p permutation }
+ *
+ * Output:
+ *
+ * [0, 0]
+ * [0, 1]
+ * [0, 2]
+ * [1, 0]
+ * [1, 1]
+ * [1, 2]
+ * [2, 0]
+ * [2, 1]
+ * [2, 2]
+ *
+ * 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 # => [[]]
+ * e = a.repeated_permutation(1)
+ * e.size # => 3
+ * e.to_a # => [[0], [1], [2]]
+ * 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]]
*
- * a = [1, 2]
- * a.repeated_permutation(1).to_a #=> [[1], [2]]
- * a.repeated_permutation(2).to_a #=> [[1,1],[1,2],[2,1],[2,2]]
- * a.repeated_permutation(3).to_a #=> [[1,1,1],[1,1,2],[1,2,1],[1,2,2],
- * # [2,1,1],[2,1,2],[2,2,1],[2,2,2]]
- * a.repeated_permutation(0).to_a #=> [[]] # one permutation of length 0
*/
-
static VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
{
@@ -5916,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;
}
@@ -5946,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);
}
}
@@ -5968,35 +7483,71 @@ 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);
}
/*
* call-seq:
- * ary.repeated_combination(n) {|c| block} -> ary
- * ary.repeated_combination(n) -> Enumerator
+ * array.repeated_combination(n) {|combination| ... } -> self
+ * array.repeated_combination(n) -> new_enumerator
+ *
+ * Calls the block with each repeated combination of length +n+ of the elements of +self+;
+ * each combination is an \Array;
+ * returns +self+. The order of the combinations is indeterminate.
+ *
+ * When a block and a positive \Integer argument +n+ are given, calls the block with each
+ * +n+-tuple repeated combination of the elements of +self+.
+ * 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]
*
- * When invoked with a block, yields all repeated combinations of length +n+ of
- * elements from the array and then returns the array itself.
+ * +n+ = 2:
*
- * The implementation makes no guarantees about the order in which the repeated
- * combinations are yielded.
+ * a.repeated_combination(2) {|combination| p combination }
*
- * If no block is given, an Enumerator is returned instead.
+ * Output:
*
- * Examples:
+ * [0, 0]
+ * [0, 1]
+ * [0, 2]
+ * [1, 1]
+ * [1, 2]
+ * [2, 2]
*
- * a = [1, 2, 3]
- * a.repeated_combination(1).to_a #=> [[1], [2], [3]]
- * a.repeated_combination(2).to_a #=> [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]
- * a.repeated_combination(3).to_a #=> [[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3],
- * # [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]]
- * a.repeated_combination(4).to_a #=> [[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,2,3],
- * # [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3],
- * # [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]]
- * a.repeated_combination(0).to_a #=> [[]] # one combination of length 0
+ * 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 # => [[]]
+ * e = a.repeated_combination(1)
+ * e.size # => 3
+ * e.to_a # => [[0], [1], [2]]
+ * e = a.repeated_combination(2)
+ * e.size # => 6
+ * e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
*
*/
@@ -6009,58 +7560,97 @@ 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;
}
/*
* call-seq:
- * ary.product(other_ary, ...) -> new_ary
- * ary.product(other_ary, ...) {|p| block} -> ary
+ * array.product(*other_arrays) -> new_array
+ * 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+:
+ *
+ * - 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]
+ * p = a.product(a1)
+ * p.size # => 6 # a.size * a1.size
+ * p # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]
+ * p = a.product(a1, a2)
+ * p.size # => 12 # a.size * a1.size * a2.size
+ * p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
+ *
+ * If any argument is an empty \Array, returns an empty \Array.
+ *
+ * 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]
+ * [1, 4]
+ * [2, 3]
+ * [2, 4]
+ *
+ * If any argument is an empty \Array, does not call the block:
*
- * Returns an array of all combinations of elements from all arrays.
+ * a.product(a1, a2, []) {|combination| fail 'Cannot happen' }
*
- * The length of the returned array is the product of the length of +self+ and
- * the argument arrays.
+ * If no argument is given, yields each element of +self+ as a 1-element \Array:
*
- * If given a block, #product will yield all combinations and return +self+
- * instead.
+ * a.product {|combination| p combination }
+ *
+ * Output:
+ *
+ * [0]
+ * [1]
+ * [2]
*
- * [1,2,3].product([4,5]) #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
- * [1,2].product([1,2]) #=> [[1,1],[1,2],[2,1],[2,2]]
- * [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
- * # [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
- * [1,2].product() #=> [[1],[2]]
- * [1,2].product([]) #=> []
*/
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 */
@@ -6081,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;
@@ -6146,16 +7736,19 @@ done:
/*
* call-seq:
- * ary.take(n) -> new_ary
+ * array.take(n) -> new_array
*
- * Returns first +n+ elements from the array.
+ * Returns a new \Array containing the first +n+ element of +self+,
+ * where +n+ is a non-negative \Integer;
+ * does not modify +self+.
*
- * If a negative number is given, raises an ArgumentError.
+ * Examples:
*
- * See also Array#drop
- *
- * a = [1, 2, 3, 4, 5, 0]
- * a.take(3) #=> [1, 2, 3]
+ * 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]
*
*/
@@ -6164,25 +7757,31 @@ 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);
}
/*
* call-seq:
- * ary.take_while {|obj| block} -> new_ary
- * ary.take_while -> Enumerator
+ * array.take_while {|element| ... } -> new_array
+ * array.take_while -> new_enumerator
+ *
+ * Returns a new \Array containing zero or more leading elements of +self+;
+ * does not modify +self+.
*
- * Passes elements to the block until the block returns +nil+ or +false+, then
- * stops iterating and returns an array of all prior elements.
+ * 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:
*
- * If no block is given, an Enumerator is returned instead.
+ * 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]
*
- * See also Array#drop_while
+ * With no block given, returns a new \Enumerator:
*
- * a = [1, 2, 3, 4, 5, 0]
- * a.take_while {|i| i < 3} #=> [1, 2]
+ * [0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
*
*/
@@ -6193,24 +7792,25 @@ 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));
}
/*
* call-seq:
- * ary.drop(n) -> new_ary
+ * array.drop(n) -> new_array
*
- * Drops first +n+ elements from +ary+ and returns the rest of the elements in
- * an array.
+ * Returns a new \Array containing all but the first +n+ element of +self+,
+ * where +n+ is a non-negative \Integer;
+ * does not modify +self+.
*
- * If a negative number is given, raises an ArgumentError.
+ * Examples:
*
- * See also Array#take
- *
- * a = [1, 2, 3, 4, 5, 0]
- * a.drop(3) #=> [4, 5, 0]
+ * 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]
*
*/
@@ -6220,29 +7820,32 @@ 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;
}
/*
* call-seq:
- * ary.drop_while {|obj| block} -> new_ary
- * ary.drop_while -> Enumerator
+ * array.drop_while {|element| ... } -> new_array
+ * array.drop_while -> new_enumerator
+
+ * Returns a new \Array containing zero or more trailing elements of +self+;
+ * does not modify +self+.
*
- * Drops elements up to, but not including, the first element for which the
- * block returns +nil+ or +false+ and returns an array containing the
- * remaining elements.
+ * 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:
*
- * If no block is given, an Enumerator is returned instead.
+ * a = [0, 1, 2, 3, 4, 5]
+ * a.drop_while {|element| element < 3 } # => [3, 4, 5]
*
- * See also Array#take_while
+ * With no block given, returns a new \Enumerator:
*
- * a = [1, 2, 3, 4, 5, 0]
- * a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
+ * [0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
*
*/
@@ -6253,17 +7856,42 @@ 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));
}
/*
* call-seq:
- * ary.any? [{|obj| block} ] -> true or false
- * ary.any?(pattern) -> true or false
+ * array.any? -> true or false
+ * array.any? {|element| ... } -> true or false
+ * array.any?(obj) -> true or false
+ *
+ * Returns +true+ if any element of +self+ meets a given criterion.
+ *
+ * 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
*
- * See also Enumerable#any?
+ * 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
+ * [0, 1, 2].any?(1) # => true
+ * [0, 1, 2].any?(3) # => false
+ *
+ * Related: Enumerable#any?
*/
static VALUE
@@ -6277,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) {
@@ -6287,19 +7915,43 @@ 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;
}
/*
* call-seq:
- * ary.all? [{|obj| block} ] -> true or false
- * ary.all?(pattern) -> true or false
+ * array.all? -> true or false
+ * array.all? {|element| ... } -> true or false
+ * array.all?(obj) -> true or false
+ *
+ * Returns +true+ if all elements of +self+ meet a given criterion.
+ *
+ * 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:
*
- * See also Enumerable#all?
+ * ['food', 'fool', 'foot'].all?(/foo/) # => true
+ * ['food', 'drink'].all?(/bar/) # => false
+ * [].all?(/foo/) # => true
+ * [0, 0, 0].all?(0) # => true
+ * [0, 1, 2].all?(1) # => false
+ *
+ * Related: Enumerable#all?
*/
static VALUE
@@ -6332,10 +7984,34 @@ rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.none? [{|obj| block} ] -> true or false
- * ary.none?(pattern) -> true or false
+ * array.none? -> true or false
+ * array.none? {|element| ... } -> true or false
+ * array.none?(obj) -> true or false
+ *
+ * Returns +true+ if no element of +self+ meet a given criterion.
+ *
+ * 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:
*
- * See also Enumerable#none?
+ * [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
+ * [0, 1, 2].none?(3) # => true
+ * [0, 1, 2].none?(1) # => false
+ *
+ * Related: Enumerable#none?
*/
static VALUE
@@ -6368,10 +8044,38 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
/*
* call-seq:
- * ary.one? [{|obj| block} ] -> true or false
- * ary.one?(pattern) -> true or false
+ * array.one? -> true or false
+ * array.one? {|element| ... } -> true or false
+ * array.one?(obj) -> true or false
+ *
+ * Returns +true+ if exactly one element of +self+ meets a given criterion.
+ *
+ * With no block given and no argument, returns +true+ if +self+ has exactly one truthy element,
+ * +false+ otherwise:
*
- * See also Enumerable#one?
+ * [nil, 0].one? # => true
+ * [0, 0].one? # => false
+ * [nil, nil].one? # => false
+ * [].one? # => false
+ *
+ * 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
+ * ['food', 'drink'].one?(/bar/) # => false
+ * ['food', 'drink'].one?(/foo/) # => true
+ * [].one?(/foo/) # => false
+ *
+ * Related: Enumerable#one?
*/
static VALUE
@@ -6413,19 +8117,22 @@ rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
}
/*
- * call-seq:
- * ary.dig(idx, ...) -> object
+ * call-seq:
+ * array.dig(index, *identifiers) -> object
+ *
+ * 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:dig_methods.rdoc].
*
- * Extracts the nested value specified by the sequence of <i>idx</i>
- * objects by calling +dig+ at each step, returning +nil+ if any
- * intermediate step is +nil+.
+ * Examples:
*
- * a = [[1, [2, 3]]]
+ * 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
*
- * a.dig(0, 1, 1) #=> 3
- * a.dig(1, 2, 3) #=> nil
- * a.dig(0, 0, 0) #=> TypeError: Integer does not have #dig method
- * [42, {foo: :bar}].dig(1, :foo) #=> :bar
*/
static VALUE
@@ -6443,14 +8150,8 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
{
if (n != 0)
v = rb_fix_plus(LONG2FIX(n), v);
- if (r != Qundef) {
- /* r can be an Integer when mathn is loaded */
- if (FIXNUM_P(r))
- v = rb_fix_plus(r, v);
- else if (RB_TYPE_P(r, T_BIGNUM))
- v = rb_big_plus(r, v);
- else
- v = rb_rational_plus(r, v);
+ if (!UNDEF_P(r)) {
+ v = rb_rational_plus(r, v);
}
else if (!n && z) {
v = rb_fix_plus(LONG2FIX(0), v);
@@ -6460,43 +8161,41 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z)
/*
* call-seq:
- * ary.sum(init=0) -> number
- * ary.sum(init=0) {|e| expr } -> number
+ * array.sum(init = 0) -> object
+ * array.sum(init = 0) {|element| ... } -> object
*
- * Returns the sum of elements.
- * For example, [e1, e2, e3].sum returns init + e1 + e2 + e3.
+ * When no block is given, returns the object equivalent to:
*
- * If a block is given, the block is applied to each element
- * before addition.
+ * sum = init
+ * array.each {|element| sum += element }
+ * sum
*
- * If <i>ary</i> is empty, it returns <i>init</i>.
+ * For example, <tt>[e1, e2, e3].sum</tt> returns <tt>init + e1 + e2 + e3</tt>.
*
- * [].sum #=> 0
- * [].sum(0.0) #=> 0.0
- * [1, 2, 3].sum #=> 6
- * [3, 5.5].sum #=> 8.5
- * [2.5, 3.0].sum(0.0) {|e| e * e } #=> 15.25
- * [Object.new].sum #=> TypeError
+ * Examples:
*
- * The (arithmetic) mean value of an array can be obtained as follows.
+ * a = [0, 1, 2, 3]
+ * a.sum # => 6
+ * a.sum(100) # => 106
*
- * mean = ary.sum(0.0) / ary.length
+ * The elements need not be numeric, but must be <tt>+</tt>-compatible
+ * with each other and with +init+:
*
- * This method can be used for non-numeric objects by
- * explicit <i>init</i> argument.
+ * a = ['abc', 'def', 'ghi']
+ * a.sum('jkl') # => "jklabcdefghi"
*
- * ["a", "b", "c"].sum("") #=> "abc"
- * [[1], [[2]], [3]].sum([]) #=> [1, [2], 3]
+ * 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:
*
- * However, Array#join and Array#flatten is faster than Array#sum for
- * array of strings and array of arrays.
+ * a = ['zero', 1, :two]
+ * s = a.sum('Coerced and concatenated: ') {|element| element.to_s }
+ * s # => "Coerced and concatenated: zero1two"
*
- * ["a", "b", "c"].join #=> "abc"
- * [[1], [[2]], [3]].flatten(1) #=> [1, [2], 3]
+ * Notes:
*
- *
- * Array#sum method may not respect method redefinition of "+" methods
- * such as Integer#+.
+ * - 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#+.
*
*/
@@ -6527,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);
@@ -6547,7 +8246,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
if (RB_FLOAT_TYPE_P(e)) {
/*
* Kahan-Babuska balancing compensated summation algorithm
- * See http://link.springer.com/article/10.1007/s00607-005-0139-x
+ * See https://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double f, c;
double x, t;
@@ -6564,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);
@@ -6617,55 +8316,128 @@ rb_ary_deconstruct(VALUE ary)
}
/*
- * Arrays are ordered, integer-indexed collections of any object.
+ * 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 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 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].
*
- * Array indexing starts at 0, as in C or Java. A negative index is assumed
- * to be relative to the end of the array---that is, an index of -1 indicates
- * the last element of the array, -2 is the next to last element in the
- * array, and so on.
*
* == 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:
*
- * ary = [1, "two", 3.0] #=> [1, "two", 3.0]
+ * - An {array literal}[rdoc-ref:literals.rdoc@Array+Literals]:
*
- * 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).
+ * [1, 'one', :one, [2, 'two', :two]]
*
- * ary = Array.new #=> []
- * Array.new(3) #=> [nil, nil, nil]
- * Array.new(3, true) #=> [true, true, true]
+ * - A {%w or %W: string-array Literal}[rdoc-ref:literals.rdoc@25w+and+-25W-3A+String-Array+Literals]:
*
- * 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.
+ * %w[foo bar baz] # => ["foo", "bar", "baz"]
+ * %w[1 % *] # => ["1", "%", "*"]
*
- * 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:
+ * - A {%i pr %I: symbol-array Literal}[rdoc-ref:literals.rdoc@25i+and+-25I-3A+Symbol-Array+Literals]:
*
- * Array.new(4) {Hash.new} #=> [{}, {}, {}, {}]
- * Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
+ * %i[foo bar baz] # => [:foo, :bar, :baz]
+ * %i[1 % *] # => [:"1", :%, :*]
*
- * This is also a quick way to build up multi-dimensional arrays:
+ * - \Method Kernel#Array:
*
- * empty_table = Array.new(3) {Array.new(3)}
- * #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
+ * 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"]]
*
- * 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.
+ * - \Method Array.new:
*
- * Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
+ * Array.new # => []
+ * Array.new(3) # => [nil, nil, nil]
+ * Array.new(4) {Hash.new} # => [{}, {}, {}, {}]
+ * Array.new(3, true) # => [true, true, true]
+ *
+ * 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+.
+ *
+ * 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.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.
@@ -6713,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.
@@ -6751,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:
*
@@ -6793,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.
@@ -6821,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
@@ -6852,18 +8625,198 @@ rb_ary_deconstruct(VALUE ary)
* 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
Init_Array(void)
{
-#undef rb_intern
-#define rb_intern(str) rb_intern_const(str)
-
rb_cArray = rb_define_class("Array", rb_cObject);
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);
@@ -6889,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");
@@ -6901,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 a49ab9823e..b9fa9844e6 100644
--- a/array.rb
+++ b/array.rb
@@ -1,62 +1,69 @@
class Array
# call-seq:
- # ary.shuffle! -> ary
- # ary.shuffle!(random: rng) -> ary
+ # array.shuffle!(random: Random) -> array
#
- # Shuffles elements in +self+ in place.
- #
- # a = [ 1, 2, 3 ] #=> [1, 2, 3]
- # a.shuffle! #=> [2, 3, 1]
- # a #=> [2, 3, 1]
- #
- # The optional +rng+ argument will be used as the random number generator.
+ # Shuffles the elements of +self+ in place.
+ # a = [1, 2, 3] #=> [1, 2, 3]
+ # a.shuffle! #=> [2, 3, 1]
+ # a #=> [2, 3, 1]
#
+ # The optional +random+ argument will be used as the random number generator:
# a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
def shuffle!(random: Random)
- __builtin_rb_ary_shuffle_bang(random)
+ Primitive.rb_ary_shuffle_bang(random)
end
# call-seq:
- # ary.shuffle -> new_ary
- # ary.shuffle(random: rng) -> new_ary
+ # array.shuffle(random: Random) -> new_ary
#
# Returns a new array with elements of +self+ shuffled.
+ # a = [1, 2, 3] #=> [1, 2, 3]
+ # a.shuffle #=> [2, 3, 1]
+ # a #=> [1, 2, 3]
#
- # a = [ 1, 2, 3 ] #=> [1, 2, 3]
- # a.shuffle #=> [2, 3, 1]
- # a #=> [1, 2, 3]
- #
- # The optional +rng+ argument will be used as the random number generator.
- #
+ # The optional +random+ argument will be used as the random number generator:
# a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
def shuffle(random: Random)
- __builtin_rb_ary_shuffle(random)
+ Primitive.rb_ary_shuffle(random)
end
# call-seq:
- # ary.sample -> obj
- # ary.sample(random: rng) -> obj
- # ary.sample(n) -> new_ary
- # ary.sample(n, random: rng) -> new_ary
- #
- # Choose a random element or +n+ random elements from the array.
- #
- # The elements are chosen by using random and unique indices into the array
- # in order to ensure that an element doesn't repeat itself unless the array
- # already contained duplicate elements.
+ # array.sample(random: Random) -> object
+ # array.sample(n, random: Random) -> new_ary
#
- # If the array is empty the first form returns +nil+ and the second form
- # returns an empty array.
+ # Returns random elements from +self+.
#
- # a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
- # a.sample #=> 7
- # a.sample(4) #=> [6, 4, 2, 5]
+ # When no arguments are given, returns a random element from +self+:
+ # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ # a.sample # => 3
+ # a.sample # => 8
+ # If +self+ is empty, returns +nil+.
#
- # The optional +rng+ argument will be used as the random number generator.
+ # When argument +n+ is given, returns a new \Array containing +n+ random
+ # elements from +self+:
+ # a.sample(3) # => [8, 9, 2]
+ # a.sample(6) # => [9, 6, 10, 3, 1, 4]
+ # Returns no more than <tt>a.size</tt> elements
+ # (because no new duplicates are introduced):
+ # a.sample(a.size * 2) # => [6, 4, 1, 8, 5, 9, 10, 2, 3, 7]
+ # 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:
+ # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 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)
- __builtin_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 18a97239ff..adb7287ed3 100644
--- a/ast.c
+++ b/ast.c
@@ -17,7 +17,7 @@ static VALUE rb_cNode;
struct ASTNodeData {
rb_ast_t *ast;
- NODE *node;
+ const NODE *node;
};
static void
@@ -44,7 +44,7 @@ static const rb_data_type_t rb_node_type = {
static VALUE rb_ast_node_alloc(VALUE klass);
static void
-setup_node(VALUE obj, rb_ast_t *ast, NODE *node)
+setup_node(VALUE obj, rb_ast_t *ast, const NODE *node)
{
struct ASTNodeData *data;
@@ -54,7 +54,7 @@ setup_node(VALUE obj, rb_ast_t *ast, NODE *node)
}
static VALUE
-ast_new_internal(rb_ast_t *ast, NODE *node)
+ast_new_internal(rb_ast_t *ast, const NODE *node)
{
VALUE obj;
@@ -64,9 +64,8 @@ ast_new_internal(rb_ast_t *ast, 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,16 +143,20 @@ 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);
}
-static VALUE node_children(rb_ast_t*, NODE*);
+static VALUE node_children(rb_ast_t*, const NODE*);
static VALUE
node_find(VALUE self, const int node_id)
@@ -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;
+
+ if (NIL_P(lines) && rb_iseq_from_eval_p(iseq) && !e_option) {
+ rb_raise(rb_eArgError, "cannot get AST for method defined in eval");
+ }
- 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) || !NIL_P(lines = script_lines(path))) {
+ node = rb_ast_parse_array(lines, keep_script_lines, error_tolerant, keep_tokens);
}
- else if (RSTRING_LEN(path) == 2 && memcmp(RSTRING_PTR(path), "-e", 2) == 0) {
- node = rb_ast_parse_str(rb_e_script);
+ 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
@@ -268,13 +322,13 @@ rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
}
static VALUE
-dump_block(rb_ast_t *ast, NODE *node)
+dump_block(rb_ast_t *ast, const NODE *node)
{
VALUE ary = rb_ary_new();
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));
@@ -284,12 +338,12 @@ dump_block(rb_ast_t *ast, NODE *node)
}
static VALUE
-dump_array(rb_ast_t *ast, NODE *node)
+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));
}
@@ -307,7 +361,21 @@ var_name(ID id)
}
static VALUE
-node_children(rb_ast_t *ast, NODE *node)
+no_name_rest(void)
+{
+ ID rest;
+ CONST_ID(rest, "NODE_SPECIAL_NO_NAME_REST");
+ return ID2SYM(rest);
+}
+
+static VALUE
+rest_arg(rb_ast_t *ast, const NODE *rest_arg)
+{
+ return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast, rest_arg) : no_name_rest();
+}
+
+static VALUE
+node_children(rb_ast_t *ast, const NODE *node)
{
char name[DECIMAL_SIZE_OF_BITS(sizeof(long) * CHAR_BIT) + 2]; /* including '$' */
@@ -330,22 +398,17 @@ node_children(rb_ast_t *ast, NODE *node)
case NODE_IN:
return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
case NODE_WHILE:
- goto loop;
case NODE_UNTIL:
- loop:
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);
case NODE_FOR_MASGN:
return rb_ary_new_from_node_args(ast, 1, node->nd_var);
case NODE_BREAK:
- goto jump;
case NODE_NEXT:
- goto jump;
case NODE_RETURN:
- jump:
return rb_ary_new_from_node_args(ast, 1, node->nd_stts);
case NODE_REDO:
return rb_ary_new_from_node_args(ast, 0);
@@ -360,15 +423,13 @@ node_children(rb_ast_t *ast, NODE *node)
case NODE_ENSURE:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr);
case NODE_AND:
- goto andor;
case NODE_OR:
- andor:
{
VALUE ary = rb_ary_new();
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;
}
@@ -382,24 +443,17 @@ node_children(rb_ast_t *ast, NODE *node)
else {
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value),
NEW_CHILD(ast, node->nd_head),
- ID2SYM(rb_intern("NODE_SPECIAL_NO_NAME_REST")));
+ no_name_rest());
}
case NODE_LASGN:
- goto asgn;
case NODE_DASGN:
- goto asgn;
- case NODE_DASGN_CURR:
- goto asgn;
case NODE_IASGN:
- goto asgn;
case NODE_CVASGN:
- asgn:
+ case NODE_GASGN:
if (NODE_REQUIRED_KEYWORD_P(node)) {
return rb_ary_new_from_args(2, var_name(node->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
}
return rb_ary_new_from_args(2, var_name(node->nd_vid), NEW_CHILD(ast, node->nd_value));
- case NODE_GASGN:
- goto asgn;
case NODE_CDECL:
if (node->nd_vid) {
return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value));
@@ -411,9 +465,10 @@ node_children(rb_ast_t *ast, NODE *node)
NEW_CHILD(ast, node->nd_args->nd_head),
NEW_CHILD(ast, node->nd_args->nd_body));
case NODE_OP_ASGN2:
- return rb_ary_new_from_args(4, NEW_CHILD(ast, node->nd_recv),
- node->nd_next->nd_aid ? Qtrue : Qfalse,
+ return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv),
+ RBOOL(node->nd_next->nd_aid),
ID2SYM(node->nd_next->nd_vid),
+ ID2SYM(node->nd_next->nd_mid),
NEW_CHILD(ast, node->nd_value));
case NODE_OP_ASGN_AND:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP),
@@ -441,9 +496,7 @@ node_children(rb_ast_t *ast, NODE *node)
case NODE_ZSUPER:
return rb_ary_new_from_node_args(ast, 0);
case NODE_LIST:
- goto ary;
case NODE_VALUES:
- ary:
return dump_array(ast, node);
case NODE_ZLIST:
return rb_ary_new_from_node_args(ast, 0);
@@ -467,8 +520,6 @@ node_children(rb_ast_t *ast, NODE *node)
name[1] = (char)node->nd_nth;
name[2] = '\0';
return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
- case NODE_MATCH:
- goto lit;
case NODE_MATCH2:
if (node->nd_args) {
return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args);
@@ -476,26 +527,26 @@ node_children(rb_ast_t *ast, NODE *node)
return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
case NODE_MATCH3:
return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
+ case NODE_MATCH:
case NODE_LIT:
- goto lit;
case NODE_STR:
- goto lit;
case NODE_XSTR:
- lit:
return rb_ary_new_from_args(1, node->nd_lit);
case NODE_ONCE:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_DSTR:
- goto dlit;
case NODE_DXSTR:
- goto dlit;
case NODE_DREGX:
- goto dlit;
case NODE_DSYM:
- dlit:
- return rb_ary_new_from_args(3, node->nd_lit,
- NEW_CHILD(ast, node->nd_next->nd_head),
- NEW_CHILD(ast, node->nd_next->nd_next));
+ {
+ NODE *n = node->nd_next;
+ VALUE head = Qnil, next = Qnil;
+ if (n) {
+ head = NEW_CHILD(ast, n->nd_head);
+ next = NEW_CHILD(ast, n->nd_next);
+ }
+ return rb_ary_new_from_args(3, node->nd_lit, head, next);
+ }
case NODE_EVSTR:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
case NODE_ARGSCAT:
@@ -527,13 +578,9 @@ node_children(rb_ast_t *ast, NODE *node)
case NODE_COLON3:
return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
case NODE_DOT2:
- goto dot;
case NODE_DOT3:
- goto dot;
case NODE_FLIP2:
- goto dot;
case NODE_FLIP3:
- dot:
return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end);
case NODE_SELF:
return rb_ary_new_from_node_args(ast, 0);
@@ -561,7 +608,7 @@ node_children(rb_ast_t *ast, NODE *node)
if (NODE_NAMED_REST_P(node->nd_1st)) {
return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
}
- return rb_ary_new_from_args(2, ID2SYM(rb_intern("NODE_SPECIAL_NO_NAME_REST")),
+ return rb_ary_new_from_args(2, no_name_rest(),
NEW_CHILD(ast, node->nd_2nd));
case NODE_ARGS:
{
@@ -573,32 +620,44 @@ node_children(rb_ast_t *ast, NODE *node)
var_name(ainfo->first_post_arg),
INT2NUM(ainfo->post_args_num),
NEW_CHILD(ast, ainfo->post_init),
- var_name(ainfo->rest_arg),
+ (ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA
+ ? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA"))
+ : var_name(ainfo->rest_arg)),
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_args)),
(ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_rest_arg)),
var_name(ainfo->block_arg));
}
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));
}
case NODE_ARYPTN:
{
struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
- VALUE rest = NODE_NAMED_REST_P(apinfo->rest_arg) ? NEW_CHILD(ast, apinfo->rest_arg) :
- ID2SYM(rb_intern("NODE_SPECIAL_NO_NAME_REST"));
+ VALUE rest = rest_arg(ast, apinfo->rest_arg);
return rb_ary_new_from_args(4,
NEW_CHILD(ast, node->nd_pconst),
NEW_CHILD(ast, apinfo->pre_args),
rest,
NEW_CHILD(ast, apinfo->post_args));
}
+ case NODE_FNDPTN:
+ {
+ struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
+ VALUE pre_rest = rest_arg(ast, fpinfo->pre_rest_arg);
+ VALUE post_rest = rest_arg(ast, fpinfo->post_rest_arg);
+ return rb_ary_new_from_args(4,
+ NEW_CHILD(ast, node->nd_pconst),
+ pre_rest,
+ NEW_CHILD(ast, fpinfo->args),
+ post_rest);
+ }
case NODE_HSHPTN:
{
VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
@@ -609,6 +668,8 @@ node_children(rb_ast_t *ast, 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;
@@ -663,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;
@@ -682,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 c507c50af8..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 class 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 class 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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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
- __builtin_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 25a4298234..95875b52a6 100755
--- a/basictest/test.rb
+++ b/basictest/test.rb
@@ -1425,9 +1425,6 @@ marity_test(:test_ok)
marity_test(:marity_test)
marity_test(:p)
-lambda(&method(:test_ok)).call(true)
-lambda(&block_get{|a,n| test_ok(a,n)}).call(true, 2)
-
class ITER_TEST1
def a
block_given?
@@ -1963,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')
@@ -2013,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
@@ -2140,7 +2140,7 @@ $_ = foobar
test_ok($_ == foobar)
class Gods
- @@rule = "Uranus" # private to Gods
+ @@rule = "Uranus"
def ruler0
@@rule
end
@@ -2163,7 +2163,7 @@ module Olympians
end
class Titans < Gods
- @@rule = "Cronus" # do not affect @@rule in Gods
+ @@rule = "Cronus" # modifies @@rule in Gods
include Olympians
def ruler4
@@rule
@@ -2178,7 +2178,14 @@ test_ok(Titans.ruler2 == "Cronus")
atlas = Titans.new
test_ok(atlas.ruler0 == "Cronus")
test_ok(atlas.ruler3 == "Zeus")
-test_ok(atlas.ruler4 == "Cronus")
+begin
+ atlas.ruler4
+rescue RuntimeError => e
+ test_ok(e.message.include?("class variable @@rule of Olympians is overtaken by Gods"))
+else
+ test_ok(false)
+end
+test_ok(atlas.ruler3 == "Zeus")
test_check "trace"
$x = 1234
diff --git a/benchmark/README.md b/benchmark/README.md
index 24a2669143..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)
```
@@ -53,20 +55,20 @@ make benchmark
# Or compare with specific ruby binary
make benchmark COMPARE_RUBY="/path/to/ruby --jit"
-# Run vm1 benchmarks
-make benchmark ITEM=vm1
+# Run vm benchmarks
+make benchmark ITEM=vm
# Run some limited benchmarks in ITEM-matched files
-make benchmark ITEM=vm1 OPTS=--filter=block
+make benchmark ITEM=vm OPTS=--filter=block
# You can specify the benchmark by an exact filename instead of using the default argument:
# ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb')
-make benchmark ARGS=../benchmark/erb_render.yml
+make benchmark ARGS=benchmark/erb_render.yml
# You can specify any option via $OPTS
make benchmark OPTS="--help"
# With `make benchmark`, some special runner plugins are available:
# -r peak, -r size, -r total, -r utime, -r stime, -r cutime, -r cstime
-make benchmark ITEM=vm2_bigarray OPTS="-r peak"
+make benchmark ITEM=vm_bigarray OPTS="-r peak"
```
diff --git a/benchmark/array_max_float.yml b/benchmark/array_max_float.yml
new file mode 100644
index 0000000000..ace1ae2e14
--- /dev/null
+++ b/benchmark/array_max_float.yml
@@ -0,0 +1,30 @@
+prelude: |
+ ary2 = 2.times.map(&:to_f).shuffle
+ ary10 = 10.times.map(&:to_f).shuffle
+ ary100 = 100.times.map(&:to_f).shuffle
+ ary500 = 500.times.map(&:to_f).shuffle
+ ary1000 = 1000.times.map(&:to_f).shuffle
+ ary2000 = 2500.times.map(&:to_f).shuffle
+ ary3000 = 2500.times.map(&:to_f).shuffle
+ ary5000 = 5000.times.map(&:to_f).shuffle
+ ary10000 = 10000.times.map(&:to_f).shuffle
+ ary20000 = 20000.times.map(&:to_f).shuffle
+ ary50000 = 50000.times.map(&:to_f).shuffle
+ ary100000 = 100000.times.map(&:to_f).shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+
+loop_count: 10000
+
diff --git a/benchmark/array_max_int.yml b/benchmark/array_max_int.yml
new file mode 100644
index 0000000000..acd83684d0
--- /dev/null
+++ b/benchmark/array_max_int.yml
@@ -0,0 +1,31 @@
+prelude: |
+ ary2 = 2.times.to_a.shuffle
+ ary10 = 10.times.to_a.shuffle
+ ary100 = 100.times.to_a.shuffle
+ ary500 = 500.times.to_a.shuffle
+ ary1000 = 1000.times.to_a.shuffle
+ ary2000 = 2500.times.to_a.shuffle
+ ary3000 = 2500.times.to_a.shuffle
+ ary5000 = 5000.times.to_a.shuffle
+ ary10000 = 10000.times.to_a.shuffle
+ ary20000 = 20000.times.to_a.shuffle
+ ary50000 = 50000.times.to_a.shuffle
+ ary100000 = 100000.times.to_a.shuffle
+ ary1000000 = 1000000.times.to_a.shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+ ary1000000.max: ary1000000.max
+
+loop_count: 10000
diff --git a/benchmark/array_max_str.yml b/benchmark/array_max_str.yml
new file mode 100644
index 0000000000..2aeed010f2
--- /dev/null
+++ b/benchmark/array_max_str.yml
@@ -0,0 +1,30 @@
+prelude: |
+ ary2 = 2.times.map(&:to_s).shuffle
+ ary10 = 10.times.map(&:to_s).shuffle
+ ary100 = 100.times.map(&:to_s).shuffle
+ ary500 = 500.times.map(&:to_s).shuffle
+ ary1000 = 1000.times.map(&:to_s).shuffle
+ ary2000 = 2500.times.map(&:to_s).shuffle
+ ary3000 = 2500.times.map(&:to_s).shuffle
+ ary5000 = 5000.times.map(&:to_s).shuffle
+ ary10000 = 10000.times.map(&:to_s).shuffle
+ ary20000 = 20000.times.map(&:to_s).shuffle
+ ary50000 = 50000.times.map(&:to_s).shuffle
+ ary100000 = 100000.times.map(&:to_s).shuffle
+
+benchmark:
+ ary2.max: ary2.max
+ ary10.max: ary10.max
+ ary100.max: ary100.max
+ ary500.max: ary500.max
+ ary1000.max: ary1000.max
+ ary2000.max: ary2000.max
+ ary3000.max: ary3000.max
+ ary5000.max: ary5000.max
+ ary10000.max: ary10000.max
+ ary20000.max: ary20000.max
+ ary50000.max: ary50000.max
+ ary100000.max: ary100000.max
+
+loop_count: 10000
+
diff --git a/benchmark/array_min.yml b/benchmark/array_min.yml
new file mode 100644
index 0000000000..53e5072b14
--- /dev/null
+++ b/benchmark/array_min.yml
@@ -0,0 +1,31 @@
+prelude: |
+ ary2 = 2.times.to_a.shuffle
+ ary10 = 10.times.to_a.shuffle
+ ary100 = 100.times.to_a.shuffle
+ ary500 = 500.times.to_a.shuffle
+ ary1000 = 1000.times.to_a.shuffle
+ ary2000 = 2500.times.to_a.shuffle
+ ary3000 = 2500.times.to_a.shuffle
+ ary5000 = 5000.times.to_a.shuffle
+ ary10000 = 10000.times.to_a.shuffle
+ ary20000 = 20000.times.to_a.shuffle
+ ary50000 = 50000.times.to_a.shuffle
+ ary100000 = 100000.times.to_a.shuffle
+ ary1000000 = 1000000.times.to_a.shuffle
+
+benchmark:
+ ary2.min: ary2.min
+ ary10.min: ary10.min
+ ary100.min: ary100.min
+ ary500.min: ary500.min
+ ary1000.min: ary1000.min
+ ary2000.min: ary2000.min
+ ary3000.min: ary3000.min
+ ary5000.min: ary5000.min
+ ary10000.min: ary10000.min
+ ary20000.min: ary20000.min
+ ary50000.min: ary50000.min
+ ary100000.min: ary100000.min
+ ary1000000.min: ary1000000.min
+
+loop_count: 10000
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_lazy_flat_map.yml b/benchmark/enum_lazy_flat_map.yml
new file mode 100644
index 0000000000..0ee390a441
--- /dev/null
+++ b/benchmark/enum_lazy_flat_map.yml
@@ -0,0 +1,16 @@
+prelude: |
+ num = (1..).lazy.take(100)
+ ary2 = [[1,2]].cycle.lazy.take(10)
+ ary10 = [[*1..10]].cycle.lazy.take(10)
+ ary20 = [[*1..20]].cycle.lazy.take(10)
+ ary50 = [[*1..50]].cycle.lazy.take(10)
+ ary100 = [[*1..100]].cycle.lazy.take(10)
+
+benchmark:
+ num3: num.flat_map {|x| x}.take(3).to_a
+ num10: num.flat_map {|x| x}.take(3).to_a
+ ary2: ary2.flat_map {|x| x}.take(3).to_a
+ ary10: ary10.flat_map {|x| x}.take(3).to_a
+ ary20: ary20.flat_map {|x| x}.take(3).to_a
+ ary50: ary50.flat_map {|x| x}.take(3).to_a
+ ary100: ary100.flat_map {|x| x}.take(3).to_a
diff --git a/benchmark/enum_lazy_zip.yml b/benchmark/enum_lazy_zip.yml
new file mode 100644
index 0000000000..4566ff0261
--- /dev/null
+++ b/benchmark/enum_lazy_zip.yml
@@ -0,0 +1,22 @@
+prelude: |
+ a = (1..3).lazy
+ b = a.map {|x| x}
+
+benchmark:
+ first_ary: a.zip(["a", "b", "c"]).first
+ first_nonary: a.zip("a".."c").first
+ first_noarg: a.zip.first
+
+ take3_ary: a.zip(["a", "b", "c"]).take(3).force
+ take3_nonary: a.zip("a".."c").take(3).force
+ take3_noarg: a.zip.take(3).force
+
+ chain-first_ary: b.zip(["a", "b", "c"]).first
+ chain-first_nonary: b.zip("a".."c").first
+ chain-first_noarg: b.zip.first
+
+ chain-take3_ary: b.zip(["a", "b", "c"]).take(3).force
+ chain-take3_nonary: b.zip("a".."c").take(3).force
+ chain-take3_noarg: b.zip.take(3).force
+
+ block: a.zip("a".."c") {|x, y| [x, y]}
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/kernel_clone.yml b/benchmark/kernel_clone.yml
new file mode 100644
index 0000000000..069b23abcd
--- /dev/null
+++ b/benchmark/kernel_clone.yml
@@ -0,0 +1,6 @@
+prelude: "object = Object.new"
+benchmark:
+ clone: "object.clone"
+ clone_true: "object.clone(freeze: true)"
+ clone_false: "object.clone(freeze: false)"
+loop_count: 10000
diff --git a/benchmark/kernel_float.yml b/benchmark/kernel_float.yml
new file mode 100644
index 0000000000..215f6750fc
--- /dev/null
+++ b/benchmark/kernel_float.yml
@@ -0,0 +1,5 @@
+benchmark:
+ float: "Float(42)"
+ float_true: "Float(42, exception: true)"
+ float_false: "Float(42, exception: false)"
+loop_count: 10000
diff --git a/benchmark/kernel_tap.yml b/benchmark/kernel_tap.yml
new file mode 100644
index 0000000000..4dcbb31b4d
--- /dev/null
+++ b/benchmark/kernel_tap.yml
@@ -0,0 +1,6 @@
+prelude: |
+ obj = Object.new
+ x = nil
+benchmark:
+ kernel_tap: obj.tap { |o| x = o }
+loop_count: 20000000
diff --git a/benchmark/kernel_then.yml b/benchmark/kernel_then.yml
new file mode 100644
index 0000000000..85f7341e33
--- /dev/null
+++ b/benchmark/kernel_then.yml
@@ -0,0 +1,6 @@
+benchmark:
+ kernel_then: 1.then { |i| i + 1 }
+ kernel_then_enum: 1.then
+ kernel_yield_self: 1.yield_self { |i| i + 1 }
+ kernel_yield_self_enum: 1.yield_self
+loop_count: 20000000
diff --git a/benchmark/keyword_arguments.yml b/benchmark/keyword_arguments.yml
new file mode 100644
index 0000000000..fce6bce0b8
--- /dev/null
+++ b/benchmark/keyword_arguments.yml
@@ -0,0 +1,13 @@
+prelude: |
+ h = {a: 1}
+ def kw(a: 1) a end
+ def kws(**kw) kw end
+benchmark:
+ kw_to_kw: "kw(a: 1)"
+ kw_splat_to_kw: "kw(**h)"
+ kw_to_kw_splat: "kws(a: 1)"
+ kw_splat_to_kw_splat: "kws(**h)"
+ kw_and_splat_to_kw: "kw(a: 1, **h)"
+ kw_splats_to_kw: "kw(**h, **h)"
+ kw_and_splat_to_kw_splat: "kws(a: 1, **h)"
+ kw_splats_to_kw_splat: "kws(**h, **h)"
diff --git a/benchmark/lib/benchmark_driver/runner/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb
new file mode 100644
index 0000000000..3a58a620de
--- /dev/null
+++ b/benchmark/lib/benchmark_driver/runner/mjit.rb
@@ -0,0 +1,34 @@
+require 'benchmark_driver/struct'
+require 'benchmark_driver/metric'
+require 'erb'
+
+# A runner to measure after-JIT performance easily
+class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips
+ # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job"
+ Job = Class.new(BenchmarkDriver::DefaultJob)
+
+ # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse`
+ JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{
+ def parse(**)
+ jobs = super
+ jobs.map do |job|
+ job = job.dup
+ job.prelude = "#{job.prelude}\n#{<<~EOS}"
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ __bmdv_ruby_i = 0
+ while __bmdv_ruby_i < 10000 # MJIT call threshold
+ #{job.script}
+ __bmdv_ruby_i += 1
+ end
+ RubyVM::MJIT.pause # compile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile
+ #{job.script}
+ RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile 2
+ end
+ EOS
+ job
+ end
+ end
+ })
+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 9f7c8c8af3..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 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 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 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 5be408e30c..0000000000
--- a/benchmark/mjit_exec_jt2jt.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# Usage:
-# RUBYOPT=-Ibenchmark/lib benchmark-driver -e 'ruby --jit' benchmark/mjit_exec_vm2jt.yml
-type: mjit_exec # benchmark/lib/benchmark_driver/runner/mjit_exec.rb
-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 9947dbb7dd..0000000000
--- a/benchmark/mjit_exec_vm2jt.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# Usage:
-# RUBYOPT=-Ibenchmark/lib benchmark-driver -e 'ruby --jit' benchmark/mjit_exec_vm2jt.yml
-type: mjit_exec # benchmark/lib/benchmark_driver/runner/mjit_exec.rb
-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 4b84427b10..0000000000
--- a/benchmark/mjit_exec_vm2vm.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# Usage:
-# RUBYOPT=-Ibenchmark/lib benchmark-driver -e 'ruby --jit' benchmark/mjit_exec_vm2vm.yml
-type: mjit_exec # benchmark/lib/benchmark_driver/runner/mjit_exec.rb
-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_exivar.yml b/benchmark/mjit_exivar.yml
new file mode 100644
index 0000000000..2584fa6410
--- /dev/null
+++ b/benchmark/mjit_exivar.yml
@@ -0,0 +1,18 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ class Bench < Hash
+ def initialize
+ @exivar = nil
+ end
+
+ def exivar
+ @exivar
+ end
+ end
+
+ bench = Bench.new
+
+benchmark:
+ mjit_exivar: bench.exivar
+
+loop_count: 200000000
diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml
new file mode 100644
index 0000000000..a6b5c9ee16
--- /dev/null
+++ b/benchmark/mjit_integer.yml
@@ -0,0 +1,32 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_abs(int) int.abs end
+ def mjit_bit_length(int) int.bit_length end
+ def mjit_comp(int) ~int end
+ def mjit_even?(int) int.even? end
+ def mjit_integer?(int) int.integer? end
+ 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
+ def mjit_zero?(int) int.zero? end
+
+benchmark:
+ - mjit_abs(-1)
+ - mjit_bit_length(100)
+ - mjit_comp(1)
+ - mjit_even?(2)
+ - mjit_integer?(0)
+ - mjit_magnitude(-1)
+ - mjit_odd?(1)
+ - mjit_ord(1)
+ - mjit_size(1)
+ - mjit_to_i(1)
+ - mjit_to_int(1)
+ - mjit_uminus(1)
+ - mjit_zero?(0)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_kernel.yml b/benchmark/mjit_kernel.yml
new file mode 100644
index 0000000000..7720e65c2c
--- /dev/null
+++ b/benchmark/mjit_kernel.yml
@@ -0,0 +1,20 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_class(obj)
+ obj.class
+ end
+
+ def mjit_frozen?(obj)
+ obj.frozen?
+ end
+
+ str = ""
+ fstr = "".freeze
+
+benchmark:
+ - mjit_class(self)
+ - mjit_class(1)
+ - mjit_frozen?(str)
+ - mjit_frozen?(fstr)
+
+loop_count: 40000000
diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml
new file mode 100644
index 0000000000..9ac68b164b
--- /dev/null
+++ b/benchmark/mjit_leave.yml
@@ -0,0 +1,8 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def leave
+ nil
+ end
+benchmark:
+ mjit_leave: leave
+loop_count: 200000000
diff --git a/benchmark/mjit_opt_cc_insns.yml b/benchmark/mjit_opt_cc_insns.yml
new file mode 100644
index 0000000000..fed6d34bd5
--- /dev/null
+++ b/benchmark/mjit_opt_cc_insns.yml
@@ -0,0 +1,27 @@
+# opt_* insns using vm_method_cfunc_is with send-compatible operands:
+# * opt_nil_p
+# * opt_not
+# * opt_eq
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_nil?(obj)
+ obj.nil?
+ end
+
+ def mjit_not(obj)
+ !obj
+ end
+
+ def mjit_eq(a, b)
+ a == b
+ end
+
+benchmark:
+ - script: mjit_nil?(1)
+ loop_count: 40000000
+ - script: mjit_not(1)
+ loop_count: 40000000
+ - script: mjit_eq(1, nil)
+ loop_count: 8000000
+ - script: mjit_eq(nil, 1)
+ loop_count: 8000000
diff --git a/benchmark/mjit_struct_aref.yml b/benchmark/mjit_struct_aref.yml
new file mode 100644
index 0000000000..bfba1323f2
--- /dev/null
+++ b/benchmark/mjit_struct_aref.yml
@@ -0,0 +1,10 @@
+type: lib/benchmark_driver/runner/mjit
+prelude: |
+ def mjit_struct_aref(struct)
+ struct.aa
+ end
+ struct = Struct.new(:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :aa).new
+
+benchmark: mjit_struct_aref(struct)
+
+loop_count: 40000000
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/num_zero_p.yml b/benchmark/num_zero_p.yml
new file mode 100644
index 0000000000..2195963433
--- /dev/null
+++ b/benchmark/num_zero_p.yml
@@ -0,0 +1,8 @@
+benchmark:
+ - 0.zero?
+ - 1.zero?
+ - 0r.zero?
+ - 1r.zero?
+ - 0i.zero?
+ - 1i.zero?
+loop_count: 50000000
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/object_allocate.yml b/benchmark/object_allocate.yml
new file mode 100644
index 0000000000..93ff463e41
--- /dev/null
+++ b/benchmark/object_allocate.yml
@@ -0,0 +1,21 @@
+prelude: |
+ class Eight
+ 8.times { include(Module.new) }
+ end
+ class ThirtyTwo
+ 32.times { include(Module.new) }
+ end
+ class SixtyFour
+ 64.times { include(Module.new) }
+ end
+ class OneTwentyEight
+ 128.times { include(Module.new) }
+ end
+ # Disable GC to see raw throughput:
+ GC.disable
+benchmark:
+ allocate_8_deep: Eight.new
+ allocate_32_deep: ThirtyTwo.new
+ allocate_64_deep: SixtyFour.new
+ allocate_128_deep: OneTwentyEight.new
+loop_count: 100000
diff --git a/benchmark/objspace_dump_all.yml b/benchmark/objspace_dump_all.yml
new file mode 100644
index 0000000000..ebab562d2e
--- /dev/null
+++ b/benchmark/objspace_dump_all.yml
@@ -0,0 +1,13 @@
+prelude: |
+ require 'objspace'
+ require 'tempfile'
+ $objs = 1_000.times.map { Object.new }
+ $strings = 1_000.times.map { |i| "string #{i}" }
+ $file = Tempfile.new('heap')
+ $dev_null = File.open(File::NULL, 'w+')
+
+benchmark:
+ dump_all_string: "ObjectSpace.dump_all(output: :string)"
+ dump_all_file: "ObjectSpace.dump_all(output: $file)"
+ dump_all_dev_null: "ObjectSpace.dump_all(output: $dev_null)"
+loop_count: 1
diff --git a/benchmark/pm_array.yml b/benchmark/pm_array.yml
new file mode 100644
index 0000000000..babb65a289
--- /dev/null
+++ b/benchmark/pm_array.yml
@@ -0,0 +1,19 @@
+prelude: |
+ def call(*val)
+ case val
+ in [String => body]
+ [200, {}, [body]]
+ in [Integer => status]
+ [status, {}, [""]]
+ in [Integer, String] => response
+ [response[0], {}, [response[1]]]
+ in [Integer, Hash, String] => response
+ [response[0], response[1], [response[2]]]
+ end
+ end
+
+benchmark:
+ first_match: call("ok")
+ second_match: call(401)
+ third_match: call(200, "ok")
+ fourth_match: call(201, {}, "created")
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_casecmp.yml b/benchmark/string_casecmp.yml
new file mode 100644
index 0000000000..2354040a04
--- /dev/null
+++ b/benchmark/string_casecmp.yml
@@ -0,0 +1,26 @@
+prelude: |
+ lstr1 = [*"a".."z",*"0".."9"].join("")
+ lstr10 = lstr1 * 10
+ lstr100 = lstr10 * 10
+ lstr1000 = lstr100 * 10
+ lnonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ lnonascii10 = lnonascii1 * 10
+ lnonascii100 = lnonascii10 * 10
+ lnonascii1000 = lnonascii100 * 10
+ ustr1 = [*"A".."Z",*"0".."9"].join("")
+ ustr10 = ustr1 * 10
+ ustr100 = ustr10 * 10
+ ustr1000 = ustr100 * 10
+ unonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ unonascii10 = unonascii1 * 10
+ unonascii100 = unonascii10 * 10
+ unonascii1000 = unonascii100 * 10
+benchmark:
+ casecmp-1: lstr1.casecmp(ustr1)
+ casecmp-10: lstr10.casecmp(ustr10)
+ casecmp-100: lstr100.casecmp(ustr100)
+ casecmp-1000: lstr1000.casecmp(ustr1000)
+ casecmp-nonascii1: lnonascii1.casecmp(unonascii1)
+ casecmp-nonascii10: lnonascii10.casecmp(unonascii10)
+ casecmp-nonascii100: lnonascii100.casecmp(unonascii100)
+ casecmp-nonascii1000: lnonascii1000.casecmp(unonascii1000)
diff --git a/benchmark/string_casecmp_p.yml b/benchmark/string_casecmp_p.yml
new file mode 100644
index 0000000000..a790ce7d55
--- /dev/null
+++ b/benchmark/string_casecmp_p.yml
@@ -0,0 +1,26 @@
+prelude: |
+ lstr1 = [*"a".."z",*"0".."9"].join("")
+ lstr10 = lstr1 * 10
+ lstr100 = lstr10 * 10
+ lstr1000 = lstr100 * 10
+ lnonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ lnonascii10 = lnonascii1 * 10
+ lnonascii100 = lnonascii10 * 10
+ lnonascii1000 = lnonascii100 * 10
+ ustr1 = [*"A".."Z",*"0".."9"].join("")
+ ustr10 = ustr1 * 10
+ ustr100 = ustr10 * 10
+ ustr1000 = ustr100 * 10
+ unonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ unonascii10 = unonascii1 * 10
+ unonascii100 = unonascii10 * 10
+ unonascii1000 = unonascii100 * 10
+benchmark:
+ casecmp_p-1: lstr1.casecmp?(ustr1)
+ casecmp_p-10: lstr10.casecmp?(ustr10)
+ casecmp_p-100: lstr100.casecmp?(ustr100)
+ casecmp_p-1000: lstr1000.casecmp?(ustr1000)
+ casecmp_p-nonascii1: lnonascii1.casecmp?(unonascii1)
+ casecmp_p-nonascii10: lnonascii10.casecmp?(unonascii10)
+ casecmp_p-nonascii100: lnonascii100.casecmp?(unonascii100)
+ casecmp_p-nonascii1000: lnonascii1000.casecmp?(unonascii1000)
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/string_downcase.yml b/benchmark/string_downcase.yml
index a31c3ac712..1fea6afbec 100644
--- a/benchmark/string_downcase.yml
+++ b/benchmark/string_downcase.yml
@@ -3,8 +3,16 @@ prelude: |
str10 = str1 * 10
str100 = str10 * 10
str1000 = str100 * 10
+ nonascii1 = [*"\u{c0}".."\u{df}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
benchmark:
downcase-1: str1.upcase
downcase-10: str10.upcase
downcase-100: str100.upcase
downcase-1000: str1000.upcase
+ downcase-nonascii1: nonascii1.downcase
+ downcase-nonascii10: nonascii10.downcase
+ downcase-nonascii100: nonascii100.downcase
+ downcase-nonascii1000: nonascii1000.downcase
diff --git a/benchmark/string_split.yml b/benchmark/string_split.yml
index 84ffe8f6a7..cc2c7d7855 100644
--- a/benchmark/string_split.yml
+++ b/benchmark/string_split.yml
@@ -1,7 +1,22 @@
prelude: |
- str0 = [*0..9].join("")
+ str1 = [*0..5].join(" ") + " "
+ str10 = str1 * 10
+ str100 = str10 * 10
+ str1000 = str100 * 10
benchmark:
- to_chars-1: str0.split('')
- to_chars-10: (str0 * 10).split('')
- to_chars-100: (str0 * 100).split('')
- to_chars-1000: (str0 * 1000).split('')
+ to_chars-1: str1.split('')
+ to_chars-10: str10.split('')
+ to_chars-100: str100.split('')
+ to_chars-1000: str1000.split('')
+ to_words-1: str1.split(' ')
+ to_words-10: str10.split(' ')
+ to_words-100: str100.split(' ')
+ to_words-1000: str1000.split(' ')
+ re_chars-1: str1.split(//)
+ re_chars-10: str10.split(//)
+ re_chars-100: str100.split(//)
+ re_chars-1000: str1000.split(//)
+ re_space-1: str1.split(/ /)
+ re_space-10: str10.split(/ /)
+ re_space-100: str100.split(/ /)
+ re_space-1000: str1000.split(/ /)
diff --git a/benchmark/string_swapcase.yml b/benchmark/string_swapcase.yml
index afaae3f696..eeb5928907 100644
--- a/benchmark/string_swapcase.yml
+++ b/benchmark/string_swapcase.yml
@@ -3,8 +3,16 @@ prelude: |
str10 = str1 * 10
str100 = str10 * 10
str1000 = str100 * 10
+ nonascii1 = [*"\u{c0}".."\u{cf}",*"\u{f0}".."\u{ff}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
benchmark:
swapcase-1: str1.swapcase
swapcase-10: str10.swapcase
swapcase-100: str100.swapcase
swapcase-1000: str1000.swapcase
+ swapcase-nonascii1: nonascii1.swapcase
+ swapcase-nonascii10: nonascii10.swapcase
+ swapcase-nonascii100: nonascii100.swapcase
+ swapcase-nonascii1000: nonascii1000.swapcase
diff --git a/benchmark/string_upcase.yml b/benchmark/string_upcase.yml
index 456d213c74..dab84bbde2 100644
--- a/benchmark/string_upcase.yml
+++ b/benchmark/string_upcase.yml
@@ -3,8 +3,16 @@ prelude: |
str10 = str1 * 10
str100 = str10 * 10
str1000 = str100 * 10
+ nonascii1 = [*"\u{e0}".."\u{ff}"].join("")
+ nonascii10 = nonascii1 * 10
+ nonascii100 = nonascii10 * 10
+ nonascii1000 = nonascii100 * 10
benchmark:
upcase-1: str1.upcase
upcase-10: str10.upcase
upcase-100: str100.upcase
upcase-1000: str1000.upcase
+ upcase-nonascii1: nonascii1.upcase
+ upcase-nonascii10: nonascii10.upcase
+ upcase-nonascii100: nonascii100.upcase
+ upcase-nonascii1000: nonascii1000.upcase
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/vm1_attr_ivar.yml b/benchmark/vm1_attr_ivar.yml
deleted file mode 100644
index f714dd9bd9..0000000000
--- a/benchmark/vm1_attr_ivar.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-prelude: |
- class C
- attr_reader :a, :b
- def initialize
- @a = nil
- @b = nil
- end
- end
- obj = C.new
-benchmark:
- vm1_attr_ivar: |
- j = obj.a
- k = obj.b
-loop_count: 30000000
diff --git a/benchmark/vm1_attr_ivar_set.yml b/benchmark/vm1_attr_ivar_set.yml
deleted file mode 100644
index f383e59ef4..0000000000
--- a/benchmark/vm1_attr_ivar_set.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-prelude: |
- class C
- attr_accessor :a, :b
- def initialize
- @a = nil
- @b = nil
- end
- end
- obj = C.new
-benchmark:
- vm1_attr_ivar_set: |
- obj.a = 1
- obj.b = 2
-loop_count: 30000000
diff --git a/benchmark/vm1_block.yml b/benchmark/vm1_block.yml
deleted file mode 100644
index ac7c940f93..0000000000
--- a/benchmark/vm1_block.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-prelude: |
- def m
- yield
- end
-benchmark:
- vm1_block: |
- m{
- }
-loop_count: 30000000
diff --git a/benchmark/vm1_blockparam.yml b/benchmark/vm1_blockparam.yml
deleted file mode 100644
index 947b8c53d5..0000000000
--- a/benchmark/vm1_blockparam.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- def m &b
- end
-benchmark:
- vm1_blockparam: |
- m{}
-loop_count: 30000000
diff --git a/benchmark/vm1_blockparam_call.yml b/benchmark/vm1_blockparam_call.yml
deleted file mode 100644
index e2817a3ce2..0000000000
--- a/benchmark/vm1_blockparam_call.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- def m &b
- b.call
- end
-benchmark:
- vm1_blockparam_call: |
- m{}
-loop_count: 30000000
diff --git a/benchmark/vm1_blockparam_pass.yml b/benchmark/vm1_blockparam_pass.yml
deleted file mode 100644
index ca1bef3369..0000000000
--- a/benchmark/vm1_blockparam_pass.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-prelude: |
- def bp_yield
- yield
- end
-
- def bp_pass &b
- bp_yield &b
- end
-benchmark:
- vm1_blockparam_pass: |
- bp_pass{}
-loop_count: 30000000
diff --git a/benchmark/vm1_blockparam_yield.yml b/benchmark/vm1_blockparam_yield.yml
deleted file mode 100644
index 56ae617798..0000000000
--- a/benchmark/vm1_blockparam_yield.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- def bp_yield &b
- yield
- end
-benchmark:
- vm1_blockparam_yield: |
- bp_yield{}
-loop_count: 30000000
diff --git a/benchmark/vm1_const.yml b/benchmark/vm1_const.yml
deleted file mode 100644
index b98db1545c..0000000000
--- a/benchmark/vm1_const.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- Const = 1
-benchmark:
- vm1_const: |
- j = Const
- k = Const
-loop_count: 30000000
diff --git a/benchmark/vm1_ensure.yml b/benchmark/vm1_ensure.yml
deleted file mode 100644
index afbbe38bec..0000000000
--- a/benchmark/vm1_ensure.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-# Not utilizing loop_count since using it for this is too unstable for now
-benchmark:
- vm1_ensure: |
- i = 0
- while i<30_000_000
- i += 1
- begin
- begin
- ensure
- end
- ensure
- end
- end
-loop_count: 1
diff --git a/benchmark/vm1_float_simple.yml b/benchmark/vm1_float_simple.yml
deleted file mode 100644
index 4e9ad1852b..0000000000
--- a/benchmark/vm1_float_simple.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- f = 0.0
-benchmark:
- vm1_float_simple: |
- f += 0.1; f -= 0.1
- f += 0.1; f -= 0.1
- f += 0.1; f -= 0.1
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_short_lived.yml b/benchmark/vm1_gc_short_lived.yml
deleted file mode 100644
index 8fdcb7371d..0000000000
--- a/benchmark/vm1_gc_short_lived.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-benchmark:
- vm1_gc_short_lived: |
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_short_with_complex_long.yml b/benchmark/vm1_gc_short_with_complex_long.yml
deleted file mode 100644
index c22ea74a60..0000000000
--- a/benchmark/vm1_gc_short_with_complex_long.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-prelude: |
- def nested_hash h, n
- if n == 0
- ''
- else
- 10.times{
- h[Object.new] = nested_hash(h, n-1)
- }
- end
- end
-
- long_lived = Hash.new
- nested_hash long_lived, 6
-
- GC.start
- GC.start
-benchmark:
- vm1_gc_short_with_complex_long: |
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_short_with_long.yml b/benchmark/vm1_gc_short_with_long.yml
deleted file mode 100644
index c731aae548..0000000000
--- a/benchmark/vm1_gc_short_with_long.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-prelude: |
- long_lived = Array.new(1_000_000){|i| "#{i}"}
- GC.start
- GC.start
-benchmark:
- vm1_gc_short_with_long: |
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_short_with_symbol.yml b/benchmark/vm1_gc_short_with_symbol.yml
deleted file mode 100644
index 7fc1abedd8..0000000000
--- a/benchmark/vm1_gc_short_with_symbol.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-prelude: |
- 50_000.times{|i| sym = "sym#{i}".to_sym}
- GC.start
- GC.start
-benchmark:
- vm1_gc_short_with_symbol: |
- a = '' # short-lived String
- b = ''
- c = ''
- d = ''
- e = ''
- f = ''
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_wb_ary.yml b/benchmark/vm1_gc_wb_ary.yml
deleted file mode 100644
index 50fb4b6f84..0000000000
--- a/benchmark/vm1_gc_wb_ary.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-prelude: |
- short_lived_ary = []
-
- if RUBY_VERSION >= "2.2.0"
- GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
- end
-
- short_lived = ''
-benchmark:
- vm1_gc_wb_ary: |
- short_lived_ary[0] = short_lived # write barrier
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_wb_ary_promoted.yml b/benchmark/vm1_gc_wb_ary_promoted.yml
deleted file mode 100644
index cf9b5de005..0000000000
--- a/benchmark/vm1_gc_wb_ary_promoted.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-prelude: |
- long_lived = []
-
- if RUBY_VERSION > "2.2.0"
- 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
- elsif
- GC.start
- end
-
- short_lived = ''
-
-benchmark:
- vm1_gc_wb_ary_promoted: |
- long_lived[0] = short_lived # write barrier
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_wb_obj.yml b/benchmark/vm1_gc_wb_obj.yml
deleted file mode 100644
index 9dc08e7e1a..0000000000
--- a/benchmark/vm1_gc_wb_obj.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-prelude: |
- class C
- attr_accessor :foo
- end
- short_lived_obj = C.new
-
- if RUBY_VERSION >= "2.2.0"
- GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
- end
-
- short_lived = ''
-benchmark:
- vm1_gc_wb_obj: |
- short_lived_obj.foo = short_lived # write barrier
-loop_count: 30000000
diff --git a/benchmark/vm1_gc_wb_obj_promoted.yml b/benchmark/vm1_gc_wb_obj_promoted.yml
deleted file mode 100644
index 26859d2a52..0000000000
--- a/benchmark/vm1_gc_wb_obj_promoted.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-prelude: |
- class C
- attr_accessor :foo
- end
- long_lived = C.new
-
- if RUBY_VERSION >= "2.2.0"
- 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
- elsif
- GC.start
- end
-
- short_lived = ''
-benchmark:
- vm1_gc_wb_obj_promoted: |
- long_lived.foo = short_lived # write barrier
-loop_count: 30000000
diff --git a/benchmark/vm1_ivar.yml b/benchmark/vm1_ivar.yml
deleted file mode 100644
index 7aa6fac729..0000000000
--- a/benchmark/vm1_ivar.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-prelude: "@a = 1\n"
-benchmark:
- vm1_ivar: |
- j = @a
- k = @a
-loop_count: 30000000
diff --git a/benchmark/vm1_ivar_set.yml b/benchmark/vm1_ivar_set.yml
deleted file mode 100644
index 6f19412d16..0000000000
--- a/benchmark/vm1_ivar_set.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-benchmark:
- vm1_ivar_set: |
- @a = 1
- @b = 2
-loop_count: 30000000
diff --git a/benchmark/vm1_length.yml b/benchmark/vm1_length.yml
deleted file mode 100644
index a18e2ca2e6..0000000000
--- a/benchmark/vm1_length.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- a = 'abc'
- b = [1, 2, 3]
-benchmark:
- vm1_length: |
- a.length
- b.length
-loop_count: 30000000
diff --git a/benchmark/vm1_lvar_init.yml b/benchmark/vm1_lvar_init.yml
deleted file mode 100644
index 10e2becef9..0000000000
--- a/benchmark/vm1_lvar_init.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-# while loop cost is not removed because `i` is used in the script
-benchmark:
- vm1_lvar_init: |
- def m v
- unless v
- # unreachable code
- v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 =
- v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 =
- v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 =
- v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 =
- v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1
- end
- end
-
- i = 0
-
- while i<30_000_000
- i += 1
- m i
- end
-loop_count: 1
diff --git a/benchmark/vm1_lvar_set.yml b/benchmark/vm1_lvar_set.yml
deleted file mode 100644
index df8f6b6ea4..0000000000
--- a/benchmark/vm1_lvar_set.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm1_lvar_set: |
- a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1
-loop_count: 30000000
diff --git a/benchmark/vm1_neq.yml b/benchmark/vm1_neq.yml
deleted file mode 100644
index 65a8128dda..0000000000
--- a/benchmark/vm1_neq.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- obj1 = Object.new
- obj2 = Object.new
-benchmark:
- vm1_neq: |
- obj1 != obj2
-loop_count: 30000000
diff --git a/benchmark/vm1_not.yml b/benchmark/vm1_not.yml
deleted file mode 100644
index 0fb7b282a9..0000000000
--- a/benchmark/vm1_not.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-prelude: |
- obj = Object.new
-benchmark:
- vm1_not: |
- !obj
-loop_count: 30000000
diff --git a/benchmark/vm1_rescue.yml b/benchmark/vm1_rescue.yml
deleted file mode 100644
index a175b823af..0000000000
--- a/benchmark/vm1_rescue.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-benchmark:
- vm1_rescue: |
- begin
- rescue
- end
-loop_count: 30000000
diff --git a/benchmark/vm1_simplereturn.yml b/benchmark/vm1_simplereturn.yml
deleted file mode 100644
index 3564aac7e2..0000000000
--- a/benchmark/vm1_simplereturn.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- def m
- return 1
- end
-benchmark:
- vm1_simplereturn: m
-loop_count: 30000000
diff --git a/benchmark/vm1_swap.yml b/benchmark/vm1_swap.yml
deleted file mode 100644
index fed87ccd62..0000000000
--- a/benchmark/vm1_swap.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- a = 1
- b = 2
-benchmark:
- vm1_swap: |
- a, b = b, a
-loop_count: 30000000
diff --git a/benchmark/vm1_yield.yml b/benchmark/vm1_yield.yml
deleted file mode 100644
index ae1f9316f9..0000000000
--- a/benchmark/vm1_yield.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# while loop cost is not removed due to benchmark_driver.gem's limitation
-benchmark:
- vm1_yield: |
- def m
- i = 0
- while i<30_000_000
- i += 1
- yield
- end
- end
-
- m{}
-loop_count: 1
diff --git a/benchmark/vm2_array.yml b/benchmark/vm2_array.yml
deleted file mode 100644
index 7373098d5e..0000000000
--- a/benchmark/vm2_array.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_array: |
- a = [1,2,3,4,5,6,7,8,9,10]
-loop_count: 6000000
diff --git a/benchmark/vm2_bigarray.yml b/benchmark/vm2_bigarray.yml
deleted file mode 100644
index 2ad6da3905..0000000000
--- a/benchmark/vm2_bigarray.yml
+++ /dev/null
@@ -1,105 +0,0 @@
-benchmark:
- vm2_bigarray: |
- a = [
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- 1,2,3,4,5,6,7,8,9,10,
- ]
-loop_count: 6000000
diff --git a/benchmark/vm2_bighash.yml b/benchmark/vm2_bighash.yml
deleted file mode 100644
index e9154e4ba9..0000000000
--- a/benchmark/vm2_bighash.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_bighash: |
- a = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10, 11=>11, 12=>12, 13=>13, 14=>14, 15=>15, 16=>16, 17=>17, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,}
-loop_count: 60000
diff --git a/benchmark/vm2_case.yml b/benchmark/vm2_case.yml
deleted file mode 100644
index 7716783c09..0000000000
--- a/benchmark/vm2_case.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-benchmark:
- vm2_case: |
- case :foo
- when :bar
- raise
- when :baz
- raise
- when :boo
- raise
- when :foo
- # noop
- end
-loop_count: 6000000
diff --git a/benchmark/vm2_case_lit.yml b/benchmark/vm2_case_lit.yml
deleted file mode 100644
index c49b8dfe5e..0000000000
--- a/benchmark/vm2_case_lit.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_case_lit: |
- i = 0
- @ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ]
- def foo(i)
- @ret[i % @ret.size]
- end
-
- while i<6_000_000
- case foo(i)
- when "foo" then :foo
- when true then true
- when false then false
- when :sym then :sym
- when 6 then :fix
- when nil then nil
- when 0.1 then :float
- when 0xffffffffffffffff then :big
- end
- i += 1
- end
-loop_count: 1
diff --git a/benchmark/vm2_defined_method.yml b/benchmark/vm2_defined_method.yml
deleted file mode 100644
index e1b0d55674..0000000000
--- a/benchmark/vm2_defined_method.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- class Object
- define_method(:m){}
- end
-benchmark:
- vm2_defined_method: |
- m; m; m; m; m; m; m; m;
-loop_count: 6000000
diff --git a/benchmark/vm2_dstr.yml b/benchmark/vm2_dstr.yml
deleted file mode 100644
index f8bd6e0133..0000000000
--- a/benchmark/vm2_dstr.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-prelude: |
- x = y = 'z'
-benchmark:
- vm2_dstr: |
- str = "foo#{x}bar#{y}baz"
-loop_count: 6000000
diff --git a/benchmark/vm2_eval.yml b/benchmark/vm2_eval.yml
deleted file mode 100644
index d506a9c079..0000000000
--- a/benchmark/vm2_eval.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_eval: |
- eval("1")
-loop_count: 6000000
diff --git a/benchmark/vm2_fiber_allocate.yml b/benchmark/vm2_fiber_allocate.yml
deleted file mode 100644
index f29705f694..0000000000
--- a/benchmark/vm2_fiber_allocate.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- # Disable GC to see raw throughput:
- GC.disable
-benchmark:
- vm2_fiber_allocate: |
- fiber = Fiber.new{Fiber.yield}
- fiber.resume
-loop_count: 100000
diff --git a/benchmark/vm2_fiber_count.yml b/benchmark/vm2_fiber_count.yml
deleted file mode 100644
index 3ecf6bdcb2..0000000000
--- a/benchmark/vm2_fiber_count.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-# On Linux, you will need to increase the maximum number of memory maps:
-# sudo sysctl -w vm.max_map_count=200000
-prelude: |
- fibers = []
-benchmark:
- vm2_fiber_count: |
- fiber = Fiber.new{Fiber.yield}
- fibers << fiber
- fiber.resume
-loop_count: 100000
diff --git a/benchmark/vm2_fiber_reuse.yml b/benchmark/vm2_fiber_reuse.yml
deleted file mode 100644
index 0170650638..0000000000
--- a/benchmark/vm2_fiber_reuse.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-prelude: |
- GC.disable
- fibers = []
-benchmark:
- vm2_fiber_reuse: |
- 1024.times do
- fiber = Fiber.new{Fiber.yield}
- fibers << fiber
- fiber.resume
- end
-
- fibers.clear
- GC.start
-loop_count: 200
diff --git a/benchmark/vm2_fiber_reuse_gc.yml b/benchmark/vm2_fiber_reuse_gc.yml
deleted file mode 100644
index 8fb91a84eb..0000000000
--- a/benchmark/vm2_fiber_reuse_gc.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# https://bugs.ruby-lang.org/issues/16009
-prelude: |
- fibers = []
-benchmark:
- vm2_fiber_reuse_gc: |
- 2000.times do
- fiber = Fiber.new{Fiber.yield}
- fibers << fiber
- fiber.resume
- end
- fibers.clear
-loop_count: 100
diff --git a/benchmark/vm2_fiber_switch.yml b/benchmark/vm2_fiber_switch.yml
deleted file mode 100644
index fbf7283c29..0000000000
--- a/benchmark/vm2_fiber_switch.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-prelude: |
- # based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke
- fib = Fiber.new do
- loop { Fiber.yield }
- end
-benchmark:
- vm2_fiber_switch: |
- fib.resume
-loop_count: 20000000
diff --git a/benchmark/vm2_freezestring.yml b/benchmark/vm2_freezestring.yml
deleted file mode 100644
index b78af91a20..0000000000
--- a/benchmark/vm2_freezestring.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-prelude: |
- class String
- def freeze
- -self
- end
- end
-benchmark:
- vm2_freezestring: |
- "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze
-loop_count: 6000000
diff --git a/benchmark/vm2_method.yml b/benchmark/vm2_method.yml
deleted file mode 100644
index cc7b9b28ff..0000000000
--- a/benchmark/vm2_method.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- def m
- nil
- end
-benchmark:
- vm2_method: |
- m; m; m; m; m; m; m; m;
-loop_count: 6000000
diff --git a/benchmark/vm2_method_missing.yml b/benchmark/vm2_method_missing.yml
deleted file mode 100644
index cbfb794b25..0000000000
--- a/benchmark/vm2_method_missing.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-prelude: |
- class C
- def method_missing mid
- end
- end
-
- obj = C.new
-benchmark:
- vm2_method_missing: |
- obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m;
-loop_count: 6000000
diff --git a/benchmark/vm2_method_with_block.yml b/benchmark/vm2_method_with_block.yml
deleted file mode 100644
index 6e522adccc..0000000000
--- a/benchmark/vm2_method_with_block.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- def m
- nil
- end
-benchmark:
- vm2_method_with_block: |
- m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{};
-loop_count: 6000000
diff --git a/benchmark/vm2_module_ann_const_set.yml b/benchmark/vm2_module_ann_const_set.yml
deleted file mode 100644
index b0becd9d3d..0000000000
--- a/benchmark/vm2_module_ann_const_set.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_module_ann_const_set: |
- Module.new.const_set(:X, Module.new)
-loop_count: 6000000
diff --git a/benchmark/vm2_module_const_set.yml b/benchmark/vm2_module_const_set.yml
deleted file mode 100644
index 05a640069c..0000000000
--- a/benchmark/vm2_module_const_set.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- module M
- end
- $VERBOSE = nil
-benchmark:
- vm2_module_const_set: |
- M.const_set(:X, Module.new)
-loop_count: 6000000
diff --git a/benchmark/vm2_mutex.yml b/benchmark/vm2_mutex.yml
deleted file mode 100644
index c40a90444a..0000000000
--- a/benchmark/vm2_mutex.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- require 'thread'
-
- m = Thread::Mutex.new
-benchmark:
- vm2_mutex: |
- m.synchronize{}
-loop_count: 6000000
diff --git a/benchmark/vm2_newlambda.yml b/benchmark/vm2_newlambda.yml
deleted file mode 100644
index 93133f9f30..0000000000
--- a/benchmark/vm2_newlambda.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_newlambda: |
- lambda {}
-loop_count: 6000000
diff --git a/benchmark/vm2_poly_method.yml b/benchmark/vm2_poly_method.yml
deleted file mode 100644
index 0104bdfb66..0000000000
--- a/benchmark/vm2_poly_method.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_poly_method: |
- class C1
- def m
- 1
- end
- end
- class C2
- def m
- 2
- end
- end
-
- o1 = C1.new
- o2 = C2.new
-
- i = 0
- while i<6_000_000
- o = (i % 2 == 0) ? o1 : o2
- o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
- end
-loop_count: 1
diff --git a/benchmark/vm2_poly_method_ov.yml b/benchmark/vm2_poly_method_ov.yml
deleted file mode 100644
index 3748073ba2..0000000000
--- a/benchmark/vm2_poly_method_ov.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_poly_method_ov: |
- class C1
- def m
- 1
- end
- end
- class C2
- def m
- 2
- end
- end
-
- o1 = C1.new
- o2 = C2.new
-
- i = 0
- while i<6_000_000
- o = (i % 2 == 0) ? o1 : o2
- # o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
- end
-loop_count: 1
diff --git a/benchmark/vm2_poly_same_method.yml b/benchmark/vm2_poly_same_method.yml
deleted file mode 100644
index 867c433cf8..0000000000
--- a/benchmark/vm2_poly_same_method.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-prelude: |
- module AR; end
- class AR::Base
- def create_or_update
- nil
- end
- def save
- create_or_update
- end
- end
- class Foo < AR::Base; end
- class Bar < AR::Base; end
- o1 = Foo.new
- o2 = Bar.new
-benchmark:
- vm2_poly_same_method: |
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
- o1.save; o2.save;
-loop_count: 6000000
diff --git a/benchmark/vm2_poly_singleton.yml b/benchmark/vm2_poly_singleton.yml
deleted file mode 100644
index e58d7bfb37..0000000000
--- a/benchmark/vm2_poly_singleton.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_poly_singleton: |
- class C1
- def m; 1; end
- end
-
- o1 = C1.new
- o2 = C1.new
- o2.singleton_class
-
- i = 0
- while i<6_000_000 # benchmark loop 2
- o = (i % 2 == 0) ? o1 : o2
- o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
- i += 1
- end
-loop_count: 1
diff --git a/benchmark/vm2_proc.yml b/benchmark/vm2_proc.yml
deleted file mode 100644
index 5c36e936d9..0000000000
--- a/benchmark/vm2_proc.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-prelude: |
- def m &b
- b
- end
-
- pr = m{
- a = 1
- }
-benchmark:
- vm2_proc: |
- pr.call
-loop_count: 6000000
diff --git a/benchmark/vm2_raise1.yml b/benchmark/vm2_raise1.yml
deleted file mode 100644
index f6eb308968..0000000000
--- a/benchmark/vm2_raise1.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-prelude: |
- def rec n
- if n > 0
- rec n-1
- else
- raise
- end
- end
-benchmark:
- vm2_raise1: |
- begin
- rec 1
- rescue
- # ignore
- end
-loop_count: 6000000
diff --git a/benchmark/vm2_raise2.yml b/benchmark/vm2_raise2.yml
deleted file mode 100644
index 7d51b1b314..0000000000
--- a/benchmark/vm2_raise2.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-prelude: |
- def rec n
- if n > 0
- rec n-1
- else
- raise
- end
- end
-benchmark:
- vm2_raise2: |
- begin
- rec 10
- rescue
- # ignore
- end
-loop_count: 6000000
diff --git a/benchmark/vm2_regexp.yml b/benchmark/vm2_regexp.yml
deleted file mode 100644
index e53341f43b..0000000000
--- a/benchmark/vm2_regexp.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-prelude: |
- str = 'xxxhogexxx'
-benchmark:
- vm2_regexp: |
- /hoge/ =~ str
- vm2_regexp_invert: |
- str =~ /hoge/
-loop_count: 6000000
diff --git a/benchmark/vm2_send.yml b/benchmark/vm2_send.yml
deleted file mode 100644
index 44a12a27d9..0000000000
--- a/benchmark/vm2_send.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-prelude: |
- class C
- def m
- end
- end
-
- o = C.new
-benchmark:
- vm2_send: |
- o.__send__ :m
-loop_count: 6000000
diff --git a/benchmark/vm2_string_literal.yml b/benchmark/vm2_string_literal.yml
deleted file mode 100644
index 54b0aec1fe..0000000000
--- a/benchmark/vm2_string_literal.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-benchmark:
- vm2_string_literal: |
- x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_big_aref_hi.yml b/benchmark/vm2_struct_big_aref_hi.yml
deleted file mode 100644
index eed1846d28..0000000000
--- a/benchmark/vm2_struct_big_aref_hi.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
-benchmark:
- vm2_struct_big_aref_hi: |
- x.z # x[25]
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_big_aref_lo.yml b/benchmark/vm2_struct_big_aref_lo.yml
deleted file mode 100644
index 0915435b76..0000000000
--- a/benchmark/vm2_struct_big_aref_lo.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
-benchmark:
- vm2_struct_big_aref_lo: |
- x.k # x[10]
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_big_aset.yml b/benchmark/vm2_struct_big_aset.yml
deleted file mode 100644
index 6af50103d3..0000000000
--- a/benchmark/vm2_struct_big_aset.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_struct_big_aset: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
- i = 0
- while i<6_000_000
- i += 1
- x.k = i # x[10] = i
- end
-loop_count: 1
diff --git a/benchmark/vm2_struct_big_href_hi.yml b/benchmark/vm2_struct_big_href_hi.yml
deleted file mode 100644
index 60aa7fddf3..0000000000
--- a/benchmark/vm2_struct_big_href_hi.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
-benchmark:
- vm2_struct_big_href_hi: |
- x[:z]
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_big_href_lo.yml b/benchmark/vm2_struct_big_href_lo.yml
deleted file mode 100644
index c55c0bd16c..0000000000
--- a/benchmark/vm2_struct_big_href_lo.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
-benchmark:
- vm2_struct_big_href_lo: |
- x[:k]
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_big_hset.yml b/benchmark/vm2_struct_big_hset.yml
deleted file mode 100644
index d199c5bd47..0000000000
--- a/benchmark/vm2_struct_big_hset.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_struct_big_hset: |
- s = Struct.new(*('a'..'z').map { |x| x.to_sym })
- x = s.new
- i = 0
- while i<6_000_000
- i += 1
- x[:k] = i
- end
-loop_count: 1
diff --git a/benchmark/vm2_struct_small_aref.yml b/benchmark/vm2_struct_small_aref.yml
deleted file mode 100644
index 83381bed3a..0000000000
--- a/benchmark/vm2_struct_small_aref.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(:a, :b, :c)
- x = s.new
-benchmark:
- vm2_struct_small_aref: |
- x.a
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_small_aset.yml b/benchmark/vm2_struct_small_aset.yml
deleted file mode 100644
index 3e84a61dd0..0000000000
--- a/benchmark/vm2_struct_small_aset.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-# loop_count is not utilized since `i` is involved in the script
-benchmark:
- vm2_struct_small_aset: |
- s = Struct.new(:a, :b, :c)
- x = s.new
- i = 0
- while i<6_000_000
- i += 1
- x.a = i
- end
-loop_count: 1
diff --git a/benchmark/vm2_struct_small_href.yml b/benchmark/vm2_struct_small_href.yml
deleted file mode 100644
index b744f070d1..0000000000
--- a/benchmark/vm2_struct_small_href.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(:a, :b, :c)
- x = s.new
-benchmark:
- vm2_struct_small_href: |
- x[:a]
-loop_count: 6000000
diff --git a/benchmark/vm2_struct_small_hset.yml b/benchmark/vm2_struct_small_hset.yml
deleted file mode 100644
index d43845d6e0..0000000000
--- a/benchmark/vm2_struct_small_hset.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- s = Struct.new(:a, :b, :c)
- x = s.new
-benchmark:
- vm2_struct_small_hset: |
- x[:a] = 1
-loop_count: 6000000
diff --git a/benchmark/vm2_super.yml b/benchmark/vm2_super.yml
deleted file mode 100644
index 674743762a..0000000000
--- a/benchmark/vm2_super.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-prelude: |
- class C
- def m
- 1
- end
- end
-
- class CC < C
- def m
- super()
- end
- end
-
- obj = CC.new
-benchmark:
- vm2_super: obj.m
-loop_count: 6000000
diff --git a/benchmark/vm2_unif1.yml b/benchmark/vm2_unif1.yml
deleted file mode 100644
index caef13279f..0000000000
--- a/benchmark/vm2_unif1.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-prelude: |
- def m a, b
- end
-benchmark:
- vm2_unif1: |
- m 100, 200
-loop_count: 6000000
diff --git a/benchmark/vm2_zsuper.yml b/benchmark/vm2_zsuper.yml
deleted file mode 100644
index f760cfd48e..0000000000
--- a/benchmark/vm2_zsuper.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-prelude: |
- class C
- def m a
- 1
- end
- end
-
- class CC < C
- def m a
- super
- end
- end
-
- obj = CC.new
-benchmark:
- vm2_zsuper: |
- obj.m 10
-loop_count: 6000000
diff --git a/benchmark/vm_array.yml b/benchmark/vm_array.yml
new file mode 100644
index 0000000000..2a177237ef
--- /dev/null
+++ b/benchmark/vm_array.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_array: |
+ a = [1,2,3,4,5,6,7,8,9,10]
+loop_count: 6000000
diff --git a/benchmark/vm_attr_ivar.yml b/benchmark/vm_attr_ivar.yml
new file mode 100644
index 0000000000..75b803478e
--- /dev/null
+++ b/benchmark/vm_attr_ivar.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ attr_reader :a, :b
+ def initialize
+ @a = nil
+ @b = nil
+ end
+ end
+ obj = C.new
+benchmark:
+ vm_attr_ivar: |
+ j = obj.a
+ k = obj.b
+loop_count: 30000000
diff --git a/benchmark/vm_attr_ivar_set.yml b/benchmark/vm_attr_ivar_set.yml
new file mode 100644
index 0000000000..a0d379b18a
--- /dev/null
+++ b/benchmark/vm_attr_ivar_set.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ attr_accessor :a, :b
+ def initialize
+ @a = nil
+ @b = nil
+ end
+ end
+ obj = C.new
+benchmark:
+ vm_attr_ivar_set: |
+ obj.a = 1
+ obj.b = 2
+loop_count: 30000000
diff --git a/benchmark/vm3_backtrace.rb b/benchmark/vm_backtrace.rb
index 0fbf73e1ca..0fbf73e1ca 100644
--- a/benchmark/vm3_backtrace.rb
+++ b/benchmark/vm_backtrace.rb
diff --git a/benchmark/vm_bigarray.yml b/benchmark/vm_bigarray.yml
new file mode 100644
index 0000000000..8b2d3f3443
--- /dev/null
+++ b/benchmark/vm_bigarray.yml
@@ -0,0 +1,105 @@
+benchmark:
+ vm_bigarray: |
+ a = [
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ 1,2,3,4,5,6,7,8,9,10,
+ ]
+loop_count: 6000000
diff --git a/benchmark/vm_bighash.yml b/benchmark/vm_bighash.yml
new file mode 100644
index 0000000000..4dacfde793
--- /dev/null
+++ b/benchmark/vm_bighash.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_bighash: |
+ a = {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10, 11=>11, 12=>12, 13=>13, 14=>14, 15=>15, 16=>16, 17=>17, 18=>18, 19=>19, 20=>20, 21=>21, 22=>22, 23=>23, 24=>24, 25=>25, 26=>26, 27=>27, 28=>28, 29=>29, 30=>30, 31=>31, 32=>32, 33=>33, 34=>34, 35=>35, 36=>36, 37=>37, 38=>38, 39=>39, 40=>40, 41=>41, 42=>42, 43=>43, 44=>44, 45=>45, 46=>46, 47=>47, 48=>48, 49=>49, 50=>50, 51=>51, 52=>52, 53=>53, 54=>54, 55=>55, 56=>56, 57=>57, 58=>58, 59=>59, 60=>60, 61=>61, 62=>62, 63=>63, 64=>64, 65=>65, 66=>66, 67=>67, 68=>68, 69=>69, 70=>70, 71=>71, 72=>72, 73=>73, 74=>74, 75=>75, 76=>76, 77=>77, 78=>78, 79=>79, 80=>80, 81=>81, 82=>82, 83=>83, 84=>84, 85=>85, 86=>86, 87=>87, 88=>88, 89=>89, 90=>90, 91=>91, 92=>92, 93=>93, 94=>94, 95=>95, 96=>96, 97=>97, 98=>98, 99=>99, 100=>100, 101=>101, 102=>102, 103=>103, 104=>104, 105=>105, 106=>106, 107=>107, 108=>108, 109=>109, 110=>110, 111=>111, 112=>112, 113=>113, 114=>114, 115=>115, 116=>116, 117=>117, 118=>118, 119=>119, 120=>120, 121=>121, 122=>122, 123=>123, 124=>124, 125=>125, 126=>126, 127=>127, 128=>128, 129=>129, 130=>130, 131=>131, 132=>132, 133=>133, 134=>134, 135=>135, 136=>136, 137=>137, 138=>138, 139=>139, 140=>140, 141=>141, 142=>142, 143=>143, 144=>144, 145=>145, 146=>146, 147=>147, 148=>148, 149=>149, 150=>150, 151=>151, 152=>152, 153=>153, 154=>154, 155=>155, 156=>156, 157=>157, 158=>158, 159=>159, 160=>160, 161=>161, 162=>162, 163=>163, 164=>164, 165=>165, 166=>166, 167=>167, 168=>168, 169=>169, 170=>170, 171=>171, 172=>172, 173=>173, 174=>174, 175=>175, 176=>176, 177=>177, 178=>178, 179=>179, 180=>180, 181=>181, 182=>182, 183=>183, 184=>184, 185=>185, 186=>186, 187=>187, 188=>188, 189=>189, 190=>190, 191=>191, 192=>192, 193=>193, 194=>194, 195=>195, 196=>196, 197=>197, 198=>198, 199=>199, 200=>200, 201=>201, 202=>202, 203=>203, 204=>204, 205=>205, 206=>206, 207=>207, 208=>208, 209=>209, 210=>210, 211=>211, 212=>212, 213=>213, 214=>214, 215=>215, 216=>216, 217=>217, 218=>218, 219=>219, 220=>220, 221=>221, 222=>222, 223=>223, 224=>224, 225=>225, 226=>226, 227=>227, 228=>228, 229=>229, 230=>230, 231=>231, 232=>232, 233=>233, 234=>234, 235=>235, 236=>236, 237=>237, 238=>238, 239=>239, 240=>240, 241=>241, 242=>242, 243=>243, 244=>244, 245=>245, 246=>246, 247=>247, 248=>248, 249=>249, 250=>250, 251=>251, 252=>252, 253=>253, 254=>254, 255=>255, 256=>256, 257=>257, 258=>258, 259=>259, 260=>260, 261=>261, 262=>262, 263=>263, 264=>264, 265=>265, 266=>266, 267=>267, 268=>268, 269=>269, 270=>270, 271=>271, 272=>272, 273=>273, 274=>274, 275=>275, 276=>276, 277=>277, 278=>278, 279=>279, 280=>280, 281=>281, 282=>282, 283=>283, 284=>284, 285=>285, 286=>286, 287=>287, 288=>288, 289=>289, 290=>290, 291=>291, 292=>292, 293=>293, 294=>294, 295=>295, 296=>296, 297=>297, 298=>298, 299=>299, 300=>300, 301=>301, 302=>302, 303=>303, 304=>304, 305=>305, 306=>306, 307=>307, 308=>308, 309=>309, 310=>310, 311=>311, 312=>312, 313=>313, 314=>314, 315=>315, 316=>316, 317=>317, 318=>318, 319=>319, 320=>320, 321=>321, 322=>322, 323=>323, 324=>324, 325=>325, 326=>326, 327=>327, 328=>328, 329=>329, 330=>330, 331=>331, 332=>332, 333=>333, 334=>334, 335=>335, 336=>336, 337=>337, 338=>338, 339=>339, 340=>340, 341=>341, 342=>342, 343=>343, 344=>344, 345=>345, 346=>346, 347=>347, 348=>348, 349=>349, 350=>350, 351=>351, 352=>352, 353=>353, 354=>354, 355=>355, 356=>356, 357=>357, 358=>358, 359=>359, 360=>360, 361=>361, 362=>362, 363=>363, 364=>364, 365=>365, 366=>366, 367=>367, 368=>368, 369=>369, 370=>370, 371=>371, 372=>372, 373=>373, 374=>374, 375=>375, 376=>376, 377=>377, 378=>378, 379=>379, 380=>380, 381=>381, 382=>382, 383=>383, 384=>384, 385=>385, 386=>386, 387=>387, 388=>388, 389=>389, 390=>390, 391=>391, 392=>392, 393=>393, 394=>394, 395=>395, 396=>396, 397=>397, 398=>398, 399=>399, 400=>400, 401=>401, 402=>402, 403=>403, 404=>404, 405=>405, 406=>406, 407=>407, 408=>408, 409=>409, 410=>410, 411=>411, 412=>412, 413=>413, 414=>414, 415=>415, 416=>416, 417=>417, 418=>418, 419=>419, 420=>420, 421=>421, 422=>422, 423=>423, 424=>424, 425=>425, 426=>426, 427=>427, 428=>428, 429=>429, 430=>430, 431=>431, 432=>432, 433=>433, 434=>434, 435=>435, 436=>436, 437=>437, 438=>438, 439=>439, 440=>440, 441=>441, 442=>442, 443=>443, 444=>444, 445=>445, 446=>446, 447=>447, 448=>448, 449=>449, 450=>450, 451=>451, 452=>452, 453=>453, 454=>454, 455=>455, 456=>456, 457=>457, 458=>458, 459=>459, 460=>460, 461=>461, 462=>462, 463=>463, 464=>464, 465=>465, 466=>466, 467=>467, 468=>468, 469=>469, 470=>470, 471=>471, 472=>472, 473=>473, 474=>474, 475=>475, 476=>476, 477=>477, 478=>478, 479=>479, 480=>480, 481=>481, 482=>482, 483=>483, 484=>484, 485=>485, 486=>486, 487=>487, 488=>488, 489=>489, 490=>490, 491=>491, 492=>492, 493=>493, 494=>494, 495=>495, 496=>496, 497=>497, 498=>498, 499=>499, 500=>500,}
+loop_count: 60000
diff --git a/benchmark/vm_block.yml b/benchmark/vm_block.yml
new file mode 100644
index 0000000000..68b3e40bf5
--- /dev/null
+++ b/benchmark/vm_block.yml
@@ -0,0 +1,9 @@
+prelude: |
+ def m
+ yield
+ end
+benchmark:
+ vm_block: |
+ m{
+ }
+loop_count: 30000000
diff --git a/benchmark/vm_block_handler.yml b/benchmark/vm_block_handler.yml
new file mode 100644
index 0000000000..461d7953ad
--- /dev/null
+++ b/benchmark/vm_block_handler.yml
@@ -0,0 +1,27 @@
+# :FIXME: is there a way to benchmark block_handler_type_ifunc?
+
+prelude: |
+ p = proc{_1}
+ o = Object.new
+ def o.each
+ i = 0
+ while i < 3_000_000 do
+ yield i
+ i += 1
+ end
+ end
+
+benchmark:
+ - name: block_handler_type_iseq
+ script: |
+ o.each{_1}
+
+ - name: block_handler_type_symbol
+ script: |
+ o.each(&:itself)
+
+ - name: block_handler_type_proc
+ script: |
+ o.each(&p)
+
+loop_count: 1
diff --git a/benchmark/vm_blockparam.yml b/benchmark/vm_blockparam.yml
new file mode 100644
index 0000000000..5e5a0170a2
--- /dev/null
+++ b/benchmark/vm_blockparam.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m &b
+ end
+benchmark:
+ vm_blockparam: |
+ m{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_call.yml b/benchmark/vm_blockparam_call.yml
new file mode 100644
index 0000000000..a7d8d366ea
--- /dev/null
+++ b/benchmark/vm_blockparam_call.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m &b
+ b.call
+ end
+benchmark:
+ vm_blockparam_call: |
+ m{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_pass.yml b/benchmark/vm_blockparam_pass.yml
new file mode 100644
index 0000000000..841f5e7a63
--- /dev/null
+++ b/benchmark/vm_blockparam_pass.yml
@@ -0,0 +1,12 @@
+prelude: |
+ def bp_yield
+ yield
+ end
+
+ def bp_pass &b
+ bp_yield &b
+ end
+benchmark:
+ vm_blockparam_pass: |
+ bp_pass{}
+loop_count: 30000000
diff --git a/benchmark/vm_blockparam_yield.yml b/benchmark/vm_blockparam_yield.yml
new file mode 100644
index 0000000000..8ea9b46ed2
--- /dev/null
+++ b/benchmark/vm_blockparam_yield.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def bp_yield &b
+ yield
+ end
+benchmark:
+ vm_blockparam_yield: |
+ bp_yield{}
+loop_count: 30000000
diff --git a/benchmark/vm_case.yml b/benchmark/vm_case.yml
new file mode 100644
index 0000000000..b26a491a15
--- /dev/null
+++ b/benchmark/vm_case.yml
@@ -0,0 +1,13 @@
+benchmark:
+ vm_case: |
+ case :foo
+ when :bar
+ raise
+ when :baz
+ raise
+ when :boo
+ raise
+ when :foo
+ # noop
+ end
+loop_count: 6000000
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_case_lit.yml b/benchmark/vm_case_lit.yml
new file mode 100644
index 0000000000..9f91801544
--- /dev/null
+++ b/benchmark/vm_case_lit.yml
@@ -0,0 +1,23 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_case_lit: |
+ i = 0
+ @ret = [ "foo", true, false, :sym, 6, nil, 0.1, 0xffffffffffffffff ]
+ def foo(i)
+ @ret[i % @ret.size]
+ end
+
+ while i<6_000_000
+ case foo(i)
+ when "foo" then :foo
+ when true then true
+ when false then false
+ when :sym then :sym
+ when 6 then :fix
+ when nil then nil
+ when 0.1 then :float
+ when 0xffffffffffffffff then :big
+ end
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm3_clearmethodcache.rb b/benchmark/vm_clearmethodcache.rb
index 9661323cd2..9661323cd2 100644
--- a/benchmark/vm3_clearmethodcache.rb
+++ b/benchmark/vm_clearmethodcache.rb
diff --git a/benchmark/vm_const.yml b/benchmark/vm_const.yml
new file mode 100644
index 0000000000..8939ca0cd3
--- /dev/null
+++ b/benchmark/vm_const.yml
@@ -0,0 +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_defined_method.yml b/benchmark/vm_defined_method.yml
new file mode 100644
index 0000000000..347e0cfd33
--- /dev/null
+++ b/benchmark/vm_defined_method.yml
@@ -0,0 +1,8 @@
+prelude: |
+ class Object
+ define_method(:m){}
+ end
+benchmark:
+ vm_defined_method: |
+ m; m; m; m; m; m; m; m;
+loop_count: 6000000
diff --git a/benchmark/vm_dstr.yml b/benchmark/vm_dstr.yml
new file mode 100644
index 0000000000..30c7a3193c
--- /dev/null
+++ b/benchmark/vm_dstr.yml
@@ -0,0 +1,6 @@
+prelude: |
+ x = y = 'z'
+benchmark:
+ vm_dstr: |
+ str = "foo#{x}bar#{y}baz"
+loop_count: 6000000
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_ensure.yml b/benchmark/vm_ensure.yml
new file mode 100644
index 0000000000..4ea62f30de
--- /dev/null
+++ b/benchmark/vm_ensure.yml
@@ -0,0 +1,14 @@
+# Not utilizing loop_count since using it for this is too unstable for now
+benchmark:
+ vm_ensure: |
+ i = 0
+ while i<30_000_000
+ i += 1
+ begin
+ begin
+ ensure
+ end
+ ensure
+ end
+ end
+loop_count: 1
diff --git a/benchmark/vm_eval.yml b/benchmark/vm_eval.yml
new file mode 100644
index 0000000000..7ba1a8d1de
--- /dev/null
+++ b/benchmark/vm_eval.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_eval: |
+ eval("1")
+loop_count: 6000000
diff --git a/benchmark/vm_fiber_allocate.yml b/benchmark/vm_fiber_allocate.yml
new file mode 100644
index 0000000000..b5a54e1ddf
--- /dev/null
+++ b/benchmark/vm_fiber_allocate.yml
@@ -0,0 +1,8 @@
+prelude: |
+ # Disable GC to see raw throughput:
+ GC.disable
+benchmark:
+ vm_fiber_allocate: |
+ fiber = Fiber.new{Fiber.yield}
+ fiber.resume
+loop_count: 100000
diff --git a/benchmark/vm_fiber_count.yml b/benchmark/vm_fiber_count.yml
new file mode 100644
index 0000000000..b83d3152d4
--- /dev/null
+++ b/benchmark/vm_fiber_count.yml
@@ -0,0 +1,10 @@
+# On Linux, you will need to increase the maximum number of memory maps:
+# sudo sysctl -w vm.max_map_count=200000
+prelude: |
+ fibers = []
+benchmark:
+ vm_fiber_count: |
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+loop_count: 100000
diff --git a/benchmark/vm_fiber_reuse.yml b/benchmark/vm_fiber_reuse.yml
new file mode 100644
index 0000000000..4ca41085b1
--- /dev/null
+++ b/benchmark/vm_fiber_reuse.yml
@@ -0,0 +1,14 @@
+prelude: |
+ GC.disable
+ fibers = []
+benchmark:
+ vm_fiber_reuse: |
+ 1024.times do
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+ end
+
+ fibers.clear
+ GC.start
+loop_count: 200
diff --git a/benchmark/vm_fiber_reuse_gc.yml b/benchmark/vm_fiber_reuse_gc.yml
new file mode 100644
index 0000000000..892622f121
--- /dev/null
+++ b/benchmark/vm_fiber_reuse_gc.yml
@@ -0,0 +1,12 @@
+# https://bugs.ruby-lang.org/issues/16009
+prelude: |
+ fibers = []
+benchmark:
+ vm_fiber_reuse_gc: |
+ 2000.times do
+ fiber = Fiber.new{Fiber.yield}
+ fibers << fiber
+ fiber.resume
+ end
+ fibers.clear
+loop_count: 100
diff --git a/benchmark/vm_fiber_switch.yml b/benchmark/vm_fiber_switch.yml
new file mode 100644
index 0000000000..3de36b66eb
--- /dev/null
+++ b/benchmark/vm_fiber_switch.yml
@@ -0,0 +1,9 @@
+prelude: |
+ # based on benchmark for [ruby-core:65518] [Feature #10341] by Knut Franke
+ fib = Fiber.new do
+ loop { Fiber.yield }
+ end
+benchmark:
+ vm_fiber_switch: |
+ fib.resume
+loop_count: 20000000
diff --git a/benchmark/vm_float_simple.yml b/benchmark/vm_float_simple.yml
new file mode 100644
index 0000000000..92f5fd52ab
--- /dev/null
+++ b/benchmark/vm_float_simple.yml
@@ -0,0 +1,8 @@
+prelude: |
+ f = 0.0
+benchmark:
+ vm_float_simple: |
+ f += 0.1; f -= 0.1
+ f += 0.1; f -= 0.1
+ f += 0.1; f -= 0.1
+loop_count: 30000000
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_freezestring.yml b/benchmark/vm_freezestring.yml
new file mode 100644
index 0000000000..facc9aa043
--- /dev/null
+++ b/benchmark/vm_freezestring.yml
@@ -0,0 +1,10 @@
+prelude: |
+ class String
+ def freeze
+ -self
+ end
+ end
+benchmark:
+ vm_freezestring: |
+ "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze
+loop_count: 6000000
diff --git a/benchmark/vm3_gc.rb b/benchmark/vm_gc.rb
index e668026915..e668026915 100644
--- a/benchmark/vm3_gc.rb
+++ b/benchmark/vm_gc.rb
diff --git a/benchmark/vm3_gc_old_full.rb b/benchmark/vm_gc_old_full.rb
index cfdfc8c5a5..cfdfc8c5a5 100644
--- a/benchmark/vm3_gc_old_full.rb
+++ b/benchmark/vm_gc_old_full.rb
diff --git a/benchmark/vm3_gc_old_immediate.rb b/benchmark/vm_gc_old_immediate.rb
index ad22feb655..ad22feb655 100644
--- a/benchmark/vm3_gc_old_immediate.rb
+++ b/benchmark/vm_gc_old_immediate.rb
diff --git a/benchmark/vm3_gc_old_lazy.rb b/benchmark/vm_gc_old_lazy.rb
index b74d44baf1..b74d44baf1 100644
--- a/benchmark/vm3_gc_old_lazy.rb
+++ b/benchmark/vm_gc_old_lazy.rb
diff --git a/benchmark/vm_gc_short_lived.yml b/benchmark/vm_gc_short_lived.yml
new file mode 100644
index 0000000000..29c803fee3
--- /dev/null
+++ b/benchmark/vm_gc_short_lived.yml
@@ -0,0 +1,9 @@
+benchmark:
+ vm_gc_short_lived: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_complex_long.yml b/benchmark/vm_gc_short_with_complex_long.yml
new file mode 100644
index 0000000000..4b6c3ed7b9
--- /dev/null
+++ b/benchmark/vm_gc_short_with_complex_long.yml
@@ -0,0 +1,25 @@
+prelude: |
+ def nested_hash h, n
+ if n == 0
+ ''
+ else
+ 10.times{
+ h[Object.new] = nested_hash(h, n-1)
+ }
+ end
+ end
+
+ long_lived = Hash.new
+ nested_hash long_lived, 6
+
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_complex_long: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_long.yml b/benchmark/vm_gc_short_with_long.yml
new file mode 100644
index 0000000000..03ba0f95a9
--- /dev/null
+++ b/benchmark/vm_gc_short_with_long.yml
@@ -0,0 +1,13 @@
+prelude: |
+ long_lived = Array.new(1_000_000){|i| "#{i}"}
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_long: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_short_with_symbol.yml b/benchmark/vm_gc_short_with_symbol.yml
new file mode 100644
index 0000000000..129b8bf4ed
--- /dev/null
+++ b/benchmark/vm_gc_short_with_symbol.yml
@@ -0,0 +1,13 @@
+prelude: |
+ 50_000.times{|i| sym = "sym#{i}".to_sym}
+ GC.start
+ GC.start
+benchmark:
+ vm_gc_short_with_symbol: |
+ a = '' # short-lived String
+ b = ''
+ c = ''
+ d = ''
+ e = ''
+ f = ''
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_ary.yml b/benchmark/vm_gc_wb_ary.yml
new file mode 100644
index 0000000000..e3293e72d0
--- /dev/null
+++ b/benchmark/vm_gc_wb_ary.yml
@@ -0,0 +1,12 @@
+prelude: |
+ short_lived_ary = []
+
+ if RUBY_VERSION >= "2.2.0"
+ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_ary: |
+ short_lived_ary[0] = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_ary_promoted.yml b/benchmark/vm_gc_wb_ary_promoted.yml
new file mode 100644
index 0000000000..003995945b
--- /dev/null
+++ b/benchmark/vm_gc_wb_ary_promoted.yml
@@ -0,0 +1,15 @@
+prelude: |
+ long_lived = []
+
+ if RUBY_VERSION > "2.2.0"
+ 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
+ elsif
+ GC.start
+ end
+
+ short_lived = ''
+
+benchmark:
+ vm_gc_wb_ary_promoted: |
+ long_lived[0] = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_obj.yml b/benchmark/vm_gc_wb_obj.yml
new file mode 100644
index 0000000000..a2a2ce2d18
--- /dev/null
+++ b/benchmark/vm_gc_wb_obj.yml
@@ -0,0 +1,15 @@
+prelude: |
+ class C
+ attr_accessor :foo
+ end
+ short_lived_obj = C.new
+
+ if RUBY_VERSION >= "2.2.0"
+ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true)
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_obj: |
+ short_lived_obj.foo = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_gc_wb_obj_promoted.yml b/benchmark/vm_gc_wb_obj_promoted.yml
new file mode 100644
index 0000000000..00a454ba72
--- /dev/null
+++ b/benchmark/vm_gc_wb_obj_promoted.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class C
+ attr_accessor :foo
+ end
+ long_lived = C.new
+
+ if RUBY_VERSION >= "2.2.0"
+ 3.times{ GC.start(full_mark: false, immediate_mark: true, immediate_sweep: true) }
+ elsif
+ GC.start
+ end
+
+ short_lived = ''
+benchmark:
+ vm_gc_wb_obj_promoted: |
+ long_lived.foo = short_lived # write barrier
+loop_count: 30000000
diff --git a/benchmark/vm_iclass_super.yml b/benchmark/vm_iclass_super.yml
new file mode 100644
index 0000000000..21bb7db247
--- /dev/null
+++ b/benchmark/vm_iclass_super.yml
@@ -0,0 +1,20 @@
+prelude: |
+ class C
+ def m
+ 1
+ end
+
+ ("A".."M").each do |module_name|
+ eval <<-EOM
+ module #{module_name}
+ def m; super; end
+ end
+ prepend #{module_name}
+ EOM
+ end
+ end
+
+ obj = C.new
+benchmark:
+ vm_iclass_super: obj.m
+loop_count: 6000000
diff --git a/benchmark/vm_ivar.yml b/benchmark/vm_ivar.yml
new file mode 100644
index 0000000000..119531d5ef
--- /dev/null
+++ b/benchmark/vm_ivar.yml
@@ -0,0 +1,6 @@
+prelude: "@a = 1\n"
+benchmark:
+ vm_ivar: |
+ j = @a
+ k = @a
+loop_count: 30000000
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_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.yml b/benchmark/vm_ivar_set.yml
new file mode 100644
index 0000000000..8bbb60043b
--- /dev/null
+++ b/benchmark/vm_ivar_set.yml
@@ -0,0 +1,5 @@
+benchmark:
+ vm_ivar_set: |
+ @a = 1
+ @b = 2
+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
new file mode 100644
index 0000000000..bc8bf5bf6b
--- /dev/null
+++ b/benchmark/vm_ivar_set_subclass.yml
@@ -0,0 +1,20 @@
+prelude: |
+ class A
+ def set_ivars
+ @a = nil
+ @b = nil
+ @c = nil
+ @d = nil
+ @e = nil
+ end
+ end
+ class B < A; end
+ class C < A; end
+
+ b = B.new
+ c = C.new
+benchmark:
+ vm_ivar_init_subclass: |
+ b.set_ivars
+ c.set_ivars
+loop_count: 3000000
diff --git a/benchmark/vm_length.yml b/benchmark/vm_length.yml
new file mode 100644
index 0000000000..5fd94e7d86
--- /dev/null
+++ b/benchmark/vm_length.yml
@@ -0,0 +1,8 @@
+prelude: |
+ a = 'abc'
+ b = [1, 2, 3]
+benchmark:
+ vm_length: |
+ a.length
+ b.length
+loop_count: 30000000
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_lvar_init.yml b/benchmark/vm_lvar_init.yml
new file mode 100644
index 0000000000..70a9b1c0ca
--- /dev/null
+++ b/benchmark/vm_lvar_init.yml
@@ -0,0 +1,21 @@
+# while loop cost is not removed because `i` is used in the script
+benchmark:
+ vm_lvar_init: |
+ def m v
+ unless v
+ # unreachable code
+ v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = v10 =
+ v11 = v12 = v13 = v14 = v15 = v16 = v17 = v18 = v19 = v20 =
+ v21 = v22 = v23 = v24 = v25 = v26 = v27 = v28 = v29 = v30 =
+ v31 = v32 = v33 = v34 = v35 = v36 = v37 = v38 = v39 = v40 =
+ v41 = v42 = v43 = v44 = v45 = v46 = v47 = v48 = v49 = v50 = 1
+ end
+ end
+
+ i = 0
+
+ while i<30_000_000
+ i += 1
+ m i
+ end
+loop_count: 1
diff --git a/benchmark/vm_lvar_set.yml b/benchmark/vm_lvar_set.yml
new file mode 100644
index 0000000000..f29f763d81
--- /dev/null
+++ b/benchmark/vm_lvar_set.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_lvar_set: |
+ a = b = c = d = e = f = g = h = j = k = l = m = n = o = p = q = r = 1
+loop_count: 30000000
diff --git a/benchmark/vm_method.yml b/benchmark/vm_method.yml
new file mode 100644
index 0000000000..d45e4ec572
--- /dev/null
+++ b/benchmark/vm_method.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m
+ nil
+ end
+benchmark:
+ vm_method: |
+ m; m; m; m; m; m; m; m;
+loop_count: 6000000
diff --git a/benchmark/vm_method_missing.yml b/benchmark/vm_method_missing.yml
new file mode 100644
index 0000000000..3da456c0bb
--- /dev/null
+++ b/benchmark/vm_method_missing.yml
@@ -0,0 +1,11 @@
+prelude: |
+ class C
+ def method_missing mid
+ end
+ end
+
+ obj = C.new
+benchmark:
+ vm_method_missing: |
+ obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m; obj.m;
+loop_count: 6000000
diff --git a/benchmark/vm_method_with_block.yml b/benchmark/vm_method_with_block.yml
new file mode 100644
index 0000000000..281a481394
--- /dev/null
+++ b/benchmark/vm_method_with_block.yml
@@ -0,0 +1,8 @@
+prelude: |
+ def m
+ nil
+ end
+benchmark:
+ vm_method_with_block: |
+ m{}; m{}; m{}; m{}; m{}; m{}; m{}; m{};
+loop_count: 6000000
diff --git a/benchmark/vm_module_ann_const_set.yml b/benchmark/vm_module_ann_const_set.yml
new file mode 100644
index 0000000000..243229ba4a
--- /dev/null
+++ b/benchmark/vm_module_ann_const_set.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_module_ann_const_set: |
+ Module.new.const_set(:X, Module.new)
+loop_count: 6000000
diff --git a/benchmark/vm_module_const_set.yml b/benchmark/vm_module_const_set.yml
new file mode 100644
index 0000000000..e5a24181a9
--- /dev/null
+++ b/benchmark/vm_module_const_set.yml
@@ -0,0 +1,8 @@
+prelude: |
+ module M
+ end
+ $VERBOSE = nil
+benchmark:
+ vm_module_const_set: |
+ M.const_set(:X, Module.new)
+loop_count: 6000000
diff --git a/benchmark/vm_mutex.yml b/benchmark/vm_mutex.yml
new file mode 100644
index 0000000000..abcf1e28ce
--- /dev/null
+++ b/benchmark/vm_mutex.yml
@@ -0,0 +1,8 @@
+prelude: |
+ require 'thread'
+
+ m = Thread::Mutex.new
+benchmark:
+ vm_mutex: |
+ m.synchronize{}
+loop_count: 6000000
diff --git a/benchmark/vm_neq.yml b/benchmark/vm_neq.yml
new file mode 100644
index 0000000000..fb04d15ae8
--- /dev/null
+++ b/benchmark/vm_neq.yml
@@ -0,0 +1,7 @@
+prelude: |
+ obj1 = Object.new
+ obj2 = Object.new
+benchmark:
+ vm_neq: |
+ obj1 != obj2
+loop_count: 30000000
diff --git a/benchmark/vm_newlambda.yml b/benchmark/vm_newlambda.yml
new file mode 100644
index 0000000000..0b9787d91a
--- /dev/null
+++ b/benchmark/vm_newlambda.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_newlambda: |
+ lambda {}
+loop_count: 6000000
diff --git a/benchmark/vm_not.yml b/benchmark/vm_not.yml
new file mode 100644
index 0000000000..c68dde3c50
--- /dev/null
+++ b/benchmark/vm_not.yml
@@ -0,0 +1,6 @@
+prelude: |
+ obj = Object.new
+benchmark:
+ vm_not: |
+ !obj
+loop_count: 30000000
diff --git a/benchmark/vm_poly_method.yml b/benchmark/vm_poly_method.yml
new file mode 100644
index 0000000000..dd2f4e71de
--- /dev/null
+++ b/benchmark/vm_poly_method.yml
@@ -0,0 +1,24 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_method: |
+ class C1
+ def m
+ 1
+ end
+ end
+ class C2
+ def m
+ 2
+ end
+ end
+
+ o1 = C1.new
+ o2 = C2.new
+
+ i = 0
+ while i<6_000_000
+ o = (i % 2 == 0) ? o1 : o2
+ o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_poly_method_ov.yml b/benchmark/vm_poly_method_ov.yml
new file mode 100644
index 0000000000..bca1b62729
--- /dev/null
+++ b/benchmark/vm_poly_method_ov.yml
@@ -0,0 +1,24 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_method_ov: |
+ class C1
+ def m
+ 1
+ end
+ end
+ class C2
+ def m
+ 2
+ end
+ end
+
+ o1 = C1.new
+ o2 = C2.new
+
+ i = 0
+ while i<6_000_000
+ o = (i % 2 == 0) ? o1 : o2
+ # o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_poly_same_method.yml b/benchmark/vm_poly_same_method.yml
new file mode 100644
index 0000000000..6c5404ac84
--- /dev/null
+++ b/benchmark/vm_poly_same_method.yml
@@ -0,0 +1,25 @@
+prelude: |
+ module AR; end
+ class AR::Base
+ def create_or_update
+ nil
+ end
+ def save
+ create_or_update
+ end
+ end
+ class Foo < AR::Base; end
+ class Bar < AR::Base; end
+ o1 = Foo.new
+ o2 = Bar.new
+benchmark:
+ vm_poly_same_method: |
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+ o1.save; o2.save;
+loop_count: 6000000
diff --git a/benchmark/vm_poly_singleton.yml b/benchmark/vm_poly_singleton.yml
new file mode 100644
index 0000000000..c7923160fb
--- /dev/null
+++ b/benchmark/vm_poly_singleton.yml
@@ -0,0 +1,18 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_poly_singleton: |
+ class C1
+ def m; 1; end
+ end
+
+ o1 = C1.new
+ o2 = C1.new
+ o2.singleton_class
+
+ i = 0
+ while i<6_000_000 # benchmark loop 2
+ o = (i % 2 == 0) ? o1 : o2
+ o.m; o.m; o.m; o.m; o.m; o.m; o.m; o.m
+ i += 1
+ end
+loop_count: 1
diff --git a/benchmark/vm_proc.yml b/benchmark/vm_proc.yml
new file mode 100644
index 0000000000..2f8de6c272
--- /dev/null
+++ b/benchmark/vm_proc.yml
@@ -0,0 +1,12 @@
+prelude: |
+ def m &b
+ b
+ end
+
+ pr = m{
+ a = 1
+ }
+benchmark:
+ vm_proc: |
+ pr.call
+loop_count: 6000000
diff --git a/benchmark/vm_raise1.yml b/benchmark/vm_raise1.yml
new file mode 100644
index 0000000000..247d9f70ee
--- /dev/null
+++ b/benchmark/vm_raise1.yml
@@ -0,0 +1,16 @@
+prelude: |
+ def rec n
+ if n > 0
+ rec n-1
+ else
+ raise
+ end
+ end
+benchmark:
+ vm_raise1: |
+ begin
+ rec 1
+ rescue
+ # ignore
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_raise2.yml b/benchmark/vm_raise2.yml
new file mode 100644
index 0000000000..f0fa047b3c
--- /dev/null
+++ b/benchmark/vm_raise2.yml
@@ -0,0 +1,16 @@
+prelude: |
+ def rec n
+ if n > 0
+ rec n-1
+ else
+ raise
+ end
+ end
+benchmark:
+ vm_raise2: |
+ begin
+ rec 10
+ rescue
+ # ignore
+ end
+loop_count: 6000000
diff --git a/benchmark/vm_regexp.yml b/benchmark/vm_regexp.yml
new file mode 100644
index 0000000000..2aa3d94dbd
--- /dev/null
+++ b/benchmark/vm_regexp.yml
@@ -0,0 +1,8 @@
+prelude: |
+ str = 'xxxhogexxx'
+benchmark:
+ vm_regexp: |
+ /hoge/ =~ str
+ vm_regexp_invert: |
+ str =~ /hoge/
+loop_count: 6000000
diff --git a/benchmark/vm_rescue.yml b/benchmark/vm_rescue.yml
new file mode 100644
index 0000000000..b4a0af521f
--- /dev/null
+++ b/benchmark/vm_rescue.yml
@@ -0,0 +1,6 @@
+benchmark:
+ vm_rescue: |
+ begin
+ rescue
+ end
+loop_count: 30000000
diff --git a/benchmark/vm_send.yml b/benchmark/vm_send.yml
new file mode 100644
index 0000000000..f31bc7ac89
--- /dev/null
+++ b/benchmark/vm_send.yml
@@ -0,0 +1,14 @@
+prelude: |
+ class C
+ def m
+ end
+ end
+
+ o = C.new
+ m = :m
+benchmark:
+ vm_send: |
+ o.__send__ :m
+ vm_send_var: |
+ o.__send__ m
+loop_count: 6000000
diff --git a/benchmark/vm_send_cfunc.yml b/benchmark/vm_send_cfunc.yml
new file mode 100644
index 0000000000..b114ac317d
--- /dev/null
+++ b/benchmark/vm_send_cfunc.yml
@@ -0,0 +1,3 @@
+benchmark:
+ vm_send_cfunc: self.class
+loop_count: 100000000
diff --git a/benchmark/vm_simplereturn.yml b/benchmark/vm_simplereturn.yml
new file mode 100644
index 0000000000..c9829cff0b
--- /dev/null
+++ b/benchmark/vm_simplereturn.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m
+ return 1
+ end
+benchmark:
+ vm_simplereturn: m
+loop_count: 30000000
diff --git a/benchmark/vm_string_literal.yml b/benchmark/vm_string_literal.yml
new file mode 100644
index 0000000000..64439c7980
--- /dev/null
+++ b/benchmark/vm_string_literal.yml
@@ -0,0 +1,4 @@
+benchmark:
+ vm_string_literal: |
+ x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aref_hi.yml b/benchmark/vm_struct_big_aref_hi.yml
new file mode 100644
index 0000000000..4cf78970cb
--- /dev/null
+++ b/benchmark/vm_struct_big_aref_hi.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_aref_hi: |
+ x.z # x[25]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aref_lo.yml b/benchmark/vm_struct_big_aref_lo.yml
new file mode 100644
index 0000000000..c91af27fa5
--- /dev/null
+++ b/benchmark/vm_struct_big_aref_lo.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_aref_lo: |
+ x.k # x[10]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_aset.yml b/benchmark/vm_struct_big_aset.yml
new file mode 100644
index 0000000000..69550d14ea
--- /dev/null
+++ b/benchmark/vm_struct_big_aset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_big_aset: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x.k = i # x[10] = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_big_href_hi.yml b/benchmark/vm_struct_big_href_hi.yml
new file mode 100644
index 0000000000..09b764dd13
--- /dev/null
+++ b/benchmark/vm_struct_big_href_hi.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_href_hi: |
+ x[:z]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_href_lo.yml b/benchmark/vm_struct_big_href_lo.yml
new file mode 100644
index 0000000000..d2f00b220f
--- /dev/null
+++ b/benchmark/vm_struct_big_href_lo.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+benchmark:
+ vm_struct_big_href_lo: |
+ x[:k]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_big_hset.yml b/benchmark/vm_struct_big_hset.yml
new file mode 100644
index 0000000000..fc45cbee9c
--- /dev/null
+++ b/benchmark/vm_struct_big_hset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_big_hset: |
+ s = Struct.new(*('a'..'z').map { |x| x.to_sym })
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x[:k] = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_small_aref.yml b/benchmark/vm_struct_small_aref.yml
new file mode 100644
index 0000000000..5a83251d1e
--- /dev/null
+++ b/benchmark/vm_struct_small_aref.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_aref: |
+ x.a
+loop_count: 6000000
diff --git a/benchmark/vm_struct_small_aset.yml b/benchmark/vm_struct_small_aset.yml
new file mode 100644
index 0000000000..74f435f126
--- /dev/null
+++ b/benchmark/vm_struct_small_aset.yml
@@ -0,0 +1,11 @@
+# loop_count is not utilized since `i` is involved in the script
+benchmark:
+ vm_struct_small_aset: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+ i = 0
+ while i<6_000_000
+ i += 1
+ x.a = i
+ end
+loop_count: 1
diff --git a/benchmark/vm_struct_small_href.yml b/benchmark/vm_struct_small_href.yml
new file mode 100644
index 0000000000..6b7d7f39e7
--- /dev/null
+++ b/benchmark/vm_struct_small_href.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_href: |
+ x[:a]
+loop_count: 6000000
diff --git a/benchmark/vm_struct_small_hset.yml b/benchmark/vm_struct_small_hset.yml
new file mode 100644
index 0000000000..5d43b150de
--- /dev/null
+++ b/benchmark/vm_struct_small_hset.yml
@@ -0,0 +1,7 @@
+prelude: |
+ s = Struct.new(:a, :b, :c)
+ x = s.new
+benchmark:
+ vm_struct_small_hset: |
+ x[:a] = 1
+loop_count: 6000000
diff --git a/benchmark/vm_super.yml b/benchmark/vm_super.yml
new file mode 100644
index 0000000000..0d1e965c6e
--- /dev/null
+++ b/benchmark/vm_super.yml
@@ -0,0 +1,17 @@
+prelude: |
+ class C
+ def m
+ 1
+ end
+ end
+
+ class CC < C
+ def m
+ super()
+ end
+ end
+
+ obj = CC.new
+benchmark:
+ vm_super: obj.m
+loop_count: 6000000
diff --git a/benchmark/vm_swap.yml b/benchmark/vm_swap.yml
new file mode 100644
index 0000000000..e824a65e0a
--- /dev/null
+++ b/benchmark/vm_swap.yml
@@ -0,0 +1,7 @@
+prelude: |
+ a = 1
+ b = 2
+benchmark:
+ vm_swap: |
+ a, b = b, a
+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/benchmark/vm_unif1.yml b/benchmark/vm_unif1.yml
new file mode 100644
index 0000000000..04187bb0e2
--- /dev/null
+++ b/benchmark/vm_unif1.yml
@@ -0,0 +1,7 @@
+prelude: |
+ def m a, b
+ end
+benchmark:
+ vm_unif1: |
+ m 100, 200
+loop_count: 6000000
diff --git a/benchmark/vm_yield.yml b/benchmark/vm_yield.yml
new file mode 100644
index 0000000000..230be3d84f
--- /dev/null
+++ b/benchmark/vm_yield.yml
@@ -0,0 +1,13 @@
+# while loop cost is not removed due to benchmark_driver.gem's limitation
+benchmark:
+ vm_yield: |
+ def m
+ i = 0
+ while i<30_000_000
+ i += 1
+ yield
+ end
+ end
+
+ m{}
+loop_count: 1
diff --git a/benchmark/vm_zsuper.yml b/benchmark/vm_zsuper.yml
new file mode 100644
index 0000000000..bfb5837578
--- /dev/null
+++ b/benchmark/vm_zsuper.yml
@@ -0,0 +1,18 @@
+prelude: |
+ class C
+ def m a
+ 1
+ end
+ end
+
+ class CC < C
+ def m a
+ super
+ end
+ end
+
+ obj = CC.new
+benchmark:
+ vm_zsuper: |
+ obj.m 10
+loop_count: 6000000
diff --git a/bignum.c b/bignum.c
index e9bb5780b5..cb2c3b6f07 100644
--- a/bignum.c
+++ b/bignum.c
@@ -9,7 +9,7 @@
**********************************************************************/
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include <ctype.h>
#include <float.h>
@@ -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,18 +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)
-
-#ifndef RUBY_INTEGER_UNIFICATION
-VALUE rb_cBignum;
-#endif
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
#ifndef SIZEOF_BDIGIT_DBL
@@ -78,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)))
@@ -105,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) : \
@@ -151,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
@@ -162,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
@@ -423,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);
}
@@ -441,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);
}
}
@@ -453,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;
}
@@ -470,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;
@@ -982,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;
}
@@ -992,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;
@@ -1060,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
}
@@ -1354,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++) {
@@ -1375,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;
@@ -1383,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;
}
@@ -1413,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;
@@ -1441,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;
}
@@ -1583,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)
@@ -1601,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 */
@@ -1649,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);
@@ -1663,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,
@@ -1678,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);
@@ -2009,7 +2029,7 @@ bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGI
}
/*
- * ref. http://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication
+ * ref. https://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication
*
* x(b) = x0 * b^0 + x1 * b^1 + x2 * b^2
* y(b) = y0 * b^0 + y1 * b^1 + y2 * b^2
@@ -2082,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);
@@ -2289,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)
{
@@ -2362,9 +2382,9 @@ bary_sparse_p(const BDIGIT *ds, size_t n)
{
long c = 0;
- if ( ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
- if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
- if (c <= 1 && ds[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
+ if ( ds[2 * n / 5]) c++;
+ if (c <= 1 && ds[ n / 2]) c++;
+ if (c <= 1 && ds[3 * n / 5]) c++;
return (c <= 1) ? 1 : 0;
}
@@ -2427,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);
@@ -2472,12 +2492,7 @@ bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn,
{
/* normal multiplication when x is small */
if (xn < KARATSUBA_MUL_DIGITS) {
- normal:
- if (xds == yds && xn == yn)
- bary_sq_fast(zds, zn, xds, xn);
- else
- bary_short_mul(zds, zn, xds, xn, yds, yn);
- return;
+ goto normal;
}
/* normal multiplication when x or y is a sparse bignum */
@@ -2495,6 +2510,15 @@ bary_mul_karatsuba_branch(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn,
/* multiplication by karatsuba method */
bary_mul_karatsuba(zds, zn, xds, xn, yds, yn, wds, wn);
+ return;
+
+ normal:
+ if (xds == yds && xn == yn) {
+ bary_sq_fast(zds, zn, xds, xn);
+ }
+ else {
+ bary_short_mul(zds, zn, xds, xn, yds, yn);
+ }
}
static void
@@ -2550,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);
@@ -2574,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;
}
@@ -2662,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);
}
}
@@ -2770,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)
{
@@ -2854,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;
@@ -2909,29 +2933,8 @@ bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, s
}
-#define BIGNUM_DEBUG 0
-#if BIGNUM_DEBUG
-#define ON_DEBUG(x) do { x; } while (0)
-static void
-dump_bignum(VALUE x)
-{
- long i;
- printf("%c0x0", BIGNUM_SIGN(x) ? '+' : '-');
- for (i = BIGNUM_LEN(x); i--; ) {
- printf("_%0*"PRIxBDIGIT, SIZEOF_BDIGIT*2, BDIGITS(x)[i]);
- }
- printf(", len=%"PRIuSIZE, BIGNUM_LEN(x));
- puts("");
-}
-
-static VALUE
-rb_big_dump(VALUE x)
-{
- dump_bignum(x);
- return x;
-}
-#else
-#define ON_DEBUG(x)
+#ifndef BIGNUM_DEBUG
+# define BIGNUM_DEBUG (0+RUBY_DEBUG)
#endif
static int
@@ -2950,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);
@@ -2959,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;
@@ -2971,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
@@ -2980,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);
+ }
+ }
}
}
@@ -3021,18 +3024,19 @@ static VALUE
bignew_1(VALUE klass, size_t len, int sign)
{
NEWOBJ_OF(big, struct RBignum, klass, T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0));
- BIGNUM_SET_SIGN((VALUE)big, sign);
+ VALUE bigv = (VALUE)big;
+ BIGNUM_SET_SIGN(bigv, sign);
if (len <= BIGNUM_EMBED_LEN_MAX) {
- FL_SET_RAW(big, BIGNUM_EMBED_FLAG);
- BIGNUM_SET_LEN((VALUE)big, len);
- (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)RBIGNUM(big)->as.ary, sizeof(RBIGNUM(big)->as.ary));
+ FL_SET_RAW(bigv, BIGNUM_EMBED_FLAG);
+ BIGNUM_SET_LEN(bigv, len);
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)big->as.ary, sizeof(big->as.ary));
}
else {
- RBIGNUM(big)->as.heap.digits = ALLOC_N(BDIGIT, len);
- RBIGNUM(big)->as.heap.len = len;
+ big->as.heap.digits = ALLOC_N(BDIGIT, len);
+ big->as.heap.len = len;
}
- OBJ_FREEZE(big);
- return (VALUE)big;
+ OBJ_FREEZE(bigv);
+ return bigv;
}
VALUE
@@ -3091,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;
@@ -3115,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;
}
@@ -3168,7 +3172,7 @@ static VALUE
bignorm(VALUE x)
{
if (RB_BIGNUM_TYPE_P(x)) {
- x = bigfixize(x);
+ x = bigfixize(x);
}
return x;
}
@@ -3190,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
@@ -3210,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;
}
@@ -3376,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;
}
@@ -3409,7 +3413,7 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
size_t numbytes;
int nlz_bits_in_msbyte;
size_t numwords;
- size_t nlz_bits;
+ size_t nlz_bits = 0;
if (word_numbits == 0)
return (size_t)-1;
@@ -3424,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
}
@@ -3695,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 {
@@ -3707,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);
}
@@ -3761,42 +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 == '_') goto bad;
+ if (badcheck && *str == '_') return FALSE;
while ((c = *str++) != 0) {
- if (c == '_') {
- if (nondigit) {
- if (badcheck) goto bad;
- 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) goto bad;
+ 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;
+ }
+ if (badcheck && nondigit) return FALSE;
if (badcheck && len) {
- str--;
- while (*str && ISSPACE(*str)) {
- str++;
- if (len > 0 && !--len) break;
- }
- if (len && *str) {
- bad:
- 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;
@@ -3971,7 +3975,7 @@ str2big_karatsuba(
return z;
}
-#ifdef USE_GMP
+#if USE_GMP
static VALUE
str2big_gmp(
int sign,
@@ -4038,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;
}
@@ -4063,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;
@@ -4080,85 +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) {
- bad:
- if (endp) *endp = (char *)str;
- if (ndigits) *ndigits = num_digits;
- return z;
+ 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);
@@ -4166,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);
@@ -4257,13 +4257,18 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
}
return bignorm(z);
+
+ bad:
+ if (endp) *endp = (char *)str;
+ if (ndigits) *ndigits = num_digits;
+ return z;
}
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
@@ -4312,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,
@@ -4351,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);
@@ -4393,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);
@@ -4414,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)
{
@@ -4436,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);
@@ -4470,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
@@ -4490,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;
}
@@ -4505,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);
}
@@ -4527,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);
@@ -4545,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;
}
@@ -4581,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);
@@ -4676,12 +4684,6 @@ static size_t base36_numdigits_cache[35][MAX_BASE36_POWER_TABLE_ENTRIES];
static void
power_cache_init(void)
{
- int i, j;
- for (i = 0; i < 35; ++i) {
- for (j = 0; j < MAX_BASE36_POWER_TABLE_ENTRIES; ++j) {
- base36_power_cache[i][j] = Qnil;
- }
- }
}
static inline VALUE
@@ -4704,8 +4706,8 @@ power_cache_get_power(int base, int power_level, size_t *numdigits_ret)
if (MAX_BASE36_POWER_TABLE_ENTRIES <= power_level)
rb_bug("too big power number requested: maxpow_in_bdigit_dbl(%d)**(2**%d)", base, power_level);
- if (NIL_P(base36_power_cache[base - 2][power_level])) {
- VALUE power;
+ VALUE power = base36_power_cache[base - 2][power_level];
+ if (!power) {
size_t numdigits;
if (power_level == 0) {
int numdigits0;
@@ -4721,11 +4723,11 @@ 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];
- return base36_power_cache[base - 2][power_level];
+ return power;
}
struct big2str_struct {
@@ -4772,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;
@@ -4789,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;
@@ -4819,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;
}
@@ -4857,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;
@@ -4961,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'");
@@ -5002,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;
@@ -5011,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);
}
@@ -5030,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)
{
@@ -5077,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);
@@ -5086,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'");
@@ -5101,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);
}
@@ -5137,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
@@ -5190,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
@@ -5246,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;
@@ -5282,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;
@@ -5311,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;
@@ -5335,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;
}
@@ -5409,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)
@@ -5417,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);
@@ -5440,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);
}
@@ -5478,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;
}
@@ -5536,7 +5534,7 @@ rb_big_le(VALUE x, VALUE y)
*
* Returns <code>true</code> only if <i>obj</i> has the same value
* as <i>big</i>. Contrast this with Integer#eql?, which requires
- * <i>obj</i> to be a Integer.
+ * <i>obj</i> to be an Integer.
*
* 68719476736 == 68719476736.0 #=> true
*/
@@ -5545,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)) {
}
@@ -5553,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
@@ -5567,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
@@ -5662,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);
@@ -5677,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;
@@ -5695,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++) {
@@ -5711,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++) {
@@ -5725,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);
@@ -5768,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;
@@ -5787,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;
@@ -5822,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);
@@ -5847,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, '+');
}
}
@@ -5876,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, '-');
}
}
@@ -5954,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));
@@ -5989,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);
@@ -6068,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;
}
}
@@ -6083,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);
@@ -6126,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);
@@ -6142,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);
@@ -6158,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);
@@ -6172,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;
}
@@ -6198,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);
@@ -6234,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));
@@ -6271,53 +6267,53 @@ 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, INT2NUM(-yy));
+ x = rb_big_pow(x, LONG2NUM(-yy));
if (RB_INTEGER_TYPE_P(x))
return rb_rational_raw(INT2FIX(1), x);
else
return DBL2NUM(1.0 / NUM2DBL(x));
}
- else {
- VALUE z = 0;
- SIGNED_VALUE mask;
+ else {
+ VALUE z = 0;
+ SIGNED_VALUE mask;
const size_t xbits = rb_absint_numwords(x, 1, NULL);
- const size_t BIGLEN_LIMIT = 32*1024*1024;
+ const size_t BIGLEN_LIMIT = 32*1024*1024;
- if (xbits == (size_t)-1 ||
+ if (xbits == (size_t)-1 ||
(xbits > BIGLEN_LIMIT) ||
(xbits * yy > BIGLEN_LIMIT)) {
- rb_warn("in a**b, b may be too big");
- d = (double)yy;
- }
- else {
- for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
- if (z) z = bigsq(z);
- if (yy & mask) {
- z = z ? bigtrunc(bigmul0(z, x)) : x;
- }
- }
- return bignorm(z);
- }
- }
+ rb_warn("in a**b, b may be too big");
+ d = (double)yy;
+ }
+ else {
+ for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
+ if (z) z = bigsq(z);
+ if (yy & mask) {
+ z = z ? bigtrunc(bigmul0(z, x)) : x;
+ }
+ }
+ return bignorm(z);
+ }
+ }
}
else {
- return rb_num_coerce_bin(x, y, idPow);
+ return rb_num_coerce_bin(x, y, idPow);
}
return DBL2NUM(pow(rb_big2dbl(x), d));
}
@@ -6337,8 +6333,8 @@ bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
xds = BDIGITS(x);
#if SIZEOF_BDIGIT >= SIZEOF_LONG
if (!hibitsy) {
- y &= xds[0];
- return LONG2NUM(y);
+ y &= xds[0];
+ return LONG2NUM(y);
}
#endif
@@ -6367,10 +6363,10 @@ bigand_int(VALUE x, long xn, BDIGIT hibitsx, long y)
}
#endif
for (;i < xn; i++) {
- zds[i] = xds[i] & hibitsy;
+ zds[i] = xds[i] & hibitsy;
}
for (;i < zn; i++) {
- zds[i] = hibitsx & hibitsy;
+ zds[i] = hibitsx & hibitsy;
}
twocomp2abs_bang(z, hibitsx && hibitsy);
RB_GC_GUARD(x);
@@ -6390,12 +6386,12 @@ rb_big_and(VALUE x, VALUE y)
long tmpn;
if (!RB_INTEGER_TYPE_P(y)) {
- return rb_num_coerce_bit(x, y, '&');
+ return rb_num_coerce_bit(x, y, '&');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
- return bigand_int(x, xn, hibitsx, FIX2LONG(y));
+ return bigand_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
@@ -6417,10 +6413,10 @@ rb_big_and(VALUE x, VALUE y)
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
- zds[i] = ds1[i] & ds2[i];
+ zds[i] = ds1[i] & ds2[i];
}
for (; i<n2; i++) {
- zds[i] = hibits1 & ds2[i];
+ zds[i] = hibits1 & ds2[i];
}
twocomp2abs_bang(z, hibits1 && hibits2);
RB_GC_GUARD(x);
@@ -6509,12 +6505,12 @@ rb_big_or(VALUE x, VALUE y)
long tmpn;
if (!RB_INTEGER_TYPE_P(y)) {
- return rb_num_coerce_bit(x, y, '|');
+ return rb_num_coerce_bit(x, y, '|');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
- return bigor_int(x, xn, hibitsx, FIX2LONG(y));
+ return bigor_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
@@ -6536,10 +6532,10 @@ rb_big_or(VALUE x, VALUE y)
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
- zds[i] = ds1[i] | ds2[i];
+ zds[i] = ds1[i] | ds2[i];
}
for (; i<n2; i++) {
- zds[i] = hibits1 | ds2[i];
+ zds[i] = hibits1 | ds2[i];
}
twocomp2abs_bang(z, hibits1 || hibits2);
RB_GC_GUARD(x);
@@ -6603,12 +6599,12 @@ rb_big_xor(VALUE x, VALUE y)
long tmpn;
if (!RB_INTEGER_TYPE_P(y)) {
- return rb_num_coerce_bit(x, y, '^');
+ return rb_num_coerce_bit(x, y, '^');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
- return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
+ return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
@@ -6627,10 +6623,10 @@ rb_big_xor(VALUE x, VALUE y)
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
- zds[i] = ds1[i] ^ ds2[i];
+ zds[i] = ds1[i] ^ ds2[i];
}
for (; i<n2; i++) {
- zds[i] = hibitsx ^ ds2[i];
+ zds[i] = hibitsx ^ ds2[i];
}
twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
RB_GC_GUARD(x);
@@ -6646,25 +6642,25 @@ rb_big_lshift(VALUE x, VALUE y)
int shift_numbits;
for (;;) {
- if (FIXNUM_P(y)) {
- long l = FIX2LONG(y);
+ if (FIXNUM_P(y)) {
+ long l = FIX2LONG(y);
unsigned long shift;
- if (0 <= l) {
- lshift_p = 1;
+ if (0 <= l) {
+ lshift_p = 1;
shift = l;
}
else {
- lshift_p = 0;
- shift = 1+(unsigned long)(-(l+1));
- }
+ lshift_p = 0;
+ shift = 1+(unsigned long)(-(l+1));
+ }
shift_numbits = (int)(shift & (BITSPERDIG-1));
shift_numdigits = shift >> bit_length(BITSPERDIG-1);
return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
- }
- else if (RB_BIGNUM_TYPE_P(y)) {
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(big_shift2(x, 1, y));
- }
- y = rb_to_int(y);
+ }
+ y = rb_to_int(y);
}
}
@@ -6676,8 +6672,8 @@ rb_big_rshift(VALUE x, VALUE y)
int shift_numbits;
for (;;) {
- if (FIXNUM_P(y)) {
- long l = FIX2LONG(y);
+ if (FIXNUM_P(y)) {
+ long l = FIX2LONG(y);
unsigned long shift;
if (0 <= l) {
lshift_p = 0;
@@ -6685,16 +6681,16 @@ rb_big_rshift(VALUE x, VALUE y)
}
else {
lshift_p = 1;
- shift = 1+(unsigned long)(-(l+1));
- }
+ shift = 1+(unsigned long)(-(l+1));
+ }
shift_numbits = (int)(shift & (BITSPERDIG-1));
shift_numdigits = shift >> bit_length(BITSPERDIG-1);
return bignorm(big_shift3(x, lshift_p, shift_numdigits, shift_numbits));
- }
- else if (RB_BIGNUM_TYPE_P(y)) {
+ }
+ else if (RB_BIGNUM_TYPE_P(y)) {
return bignorm(big_shift2(x, 0, y));
- }
- y = rb_to_int(y);
+ }
+ y = rb_to_int(y);
}
}
@@ -6708,29 +6704,29 @@ rb_big_aref(VALUE x, VALUE y)
BDIGIT bit;
if (RB_BIGNUM_TYPE_P(y)) {
- if (BIGNUM_NEGATIVE_P(y))
- return INT2FIX(0);
- bigtrunc(y);
- if (BIGSIZE(y) > sizeof(size_t)) {
- out_of_range:
- return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
- }
+ if (BIGNUM_NEGATIVE_P(y))
+ return INT2FIX(0);
+ bigtrunc(y);
+ if (BIGSIZE(y) > sizeof(size_t)) {
+ return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
+ }
#if SIZEOF_SIZE_T <= SIZEOF_LONG
- shift = big2ulong(y, "long");
+ shift = big2ulong(y, "long");
#else
- shift = big2ull(y, "long long");
+ shift = big2ull(y, "long long");
#endif
}
else {
- l = NUM2LONG(y);
- if (l < 0) return INT2FIX(0);
- shift = (size_t)l;
+ l = NUM2LONG(y);
+ if (l < 0) return INT2FIX(0);
+ shift = (size_t)l;
}
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
bit = (BDIGIT)1 << s2;
- if (s1 >= BIGNUM_LEN(x)) goto out_of_range;
+ if (s1 >= BIGNUM_LEN(x))
+ return BIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
xds = BDIGITS(x);
if (BIGNUM_POSITIVE_P(x))
@@ -6754,14 +6750,15 @@ rb_big_hash(VALUE x)
/*
* call-seq:
- * big.coerce(numeric) -> array
+ * int.coerce(numeric) -> array
*
- * Returns an array with both a +numeric+ and a +big+ represented as Bignum
- * objects.
+ * Returns an array with both a +numeric+ and a +int+ represented as
+ * Integer objects or Float objects.
*
- * This is achieved by converting +numeric+ to a Bignum.
+ * This is achieved by converting +numeric+ to an Integer or a Float.
*
- * A TypeError is raised if the +numeric+ is not a Fixnum or Bignum type.
+ * A TypeError is raised if the +numeric+ is not an Integer or a Float
+ * type.
*
* (0x3FFFFFFFFFFFFFFF+1).coerce(42) #=> [42, 4611686018427387904]
*/
@@ -6783,8 +6780,8 @@ VALUE
rb_big_abs(VALUE x)
{
if (BIGNUM_NEGATIVE_P(x)) {
- x = rb_big_clone(x);
- BIGNUM_SET_POSITIVE_SIGN(x);
+ x = rb_big_clone(x);
+ BIGNUM_SET_POSITIVE_SIGN(x);
}
return x;
}
@@ -6851,17 +6848,14 @@ rb_big_bit_length(VALUE big)
VALUE
rb_big_odd_p(VALUE num)
{
- if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
- return Qtrue;
- }
- return Qfalse;
+ return RBOOL(BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1);
}
VALUE
rb_big_even_p(VALUE num)
{
if (BIGNUM_LEN(num) != 0 && BDIGITS(num)[0] & 1) {
- return Qfalse;
+ return Qfalse;
}
return Qtrue;
}
@@ -6892,21 +6886,21 @@ estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len)
double f;
if (rshift > 0) {
- lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
- d >>= rshift;
+ lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift);
+ d >>= rshift;
}
else if (rshift < 0) {
- d <<= -rshift;
- d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
+ d <<= -rshift;
+ d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift);
}
f = sqrt(BDIGIT_DBL_TO_DOUBLE(d));
d = (BDIGIT_DBL)ceil(f);
if (BDIGIT_DBL_TO_DOUBLE(d) == f) {
- if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
- ++d;
+ if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig)))
+ ++d;
}
else {
- lowbits = 1;
+ lowbits = 1;
}
rshift /= 2;
rshift += (2-(len&1))*BITSPERDIG/2;
@@ -6938,37 +6932,35 @@ rb_big_isqrt(VALUE n)
BDIGIT *xds;
if (len <= 2) {
- BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len));
+ BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len));
#if SIZEOF_BDIGIT > SIZEOF_LONG
- return ULL2NUM(sq);
+ return ULL2NUM(sq);
#else
- return ULONG2NUM(sq);
+ return ULONG2NUM(sq);
#endif
}
else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) {
- size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
- VALUE t = bignew_1(0, tn, 1);
- BDIGIT *tds = BDIGITS(t);
- tn = BIGNUM_LEN(t);
-
- /* t = n/x */
- while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn),
- bary_cmp(tds, tn, xds, xn) < 0) {
- int carry;
- BARY_TRUNC(tds, tn);
- /* x = (x+t)/2 */
- carry = bary_add(xds, xn, xds, xn, tds, tn);
- bary_small_rshift(xds, xds, xn, 1, carry);
- tn = BIGNUM_LEN(t);
- }
- rb_big_realloc(t, 0);
- rb_gc_force_recycle(t);
+ size_t tn = xn + BIGDIVREM_EXTRA_WORDS;
+ VALUE t = bignew_1(0, tn, 1);
+ BDIGIT *tds = BDIGITS(t);
+ tn = BIGNUM_LEN(t);
+
+ /* t = n/x */
+ while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn),
+ bary_cmp(tds, tn, xds, xn) < 0) {
+ int carry;
+ BARY_TRUNC(tds, tn);
+ /* x = (x+t)/2 */
+ carry = bary_add(xds, xn, xds, xn, tds, tn);
+ bary_small_rshift(xds, xds, xn, 1, carry);
+ tn = BIGNUM_LEN(t);
+ }
}
RBASIC_SET_CLASS_RAW(x, rb_cInteger);
return x;
}
-#ifdef USE_GMP
+#if USE_GMP
static void
bary_powm_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn, const BDIGIT *mds, size_t mn)
{
@@ -6994,7 +6986,7 @@ bary_powm_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT
static VALUE
int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
{
-#ifdef USE_GMP
+#if USE_GMP
VALUE z;
size_t xn, yn, mn, zn;
@@ -7160,6 +7152,7 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
long const half_val = (long)HALF_LONG_MSB;
long const mm = FIX2LONG(m);
if (!mm) rb_num_zerodiv();
+ if (mm == 1) return INT2FIX(0);
if (mm <= half_val) {
return int_pow_tmp1(rb_int_modulo(a, m), b, mm, nega_flg);
}
@@ -7169,6 +7162,7 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
}
else {
if (rb_bigzero_p(m)) rb_num_zerodiv();
+ if (bignorm(m) == INT2FIX(1)) return INT2FIX(0);
return int_pow_tmp3(rb_int_modulo(a, m), b, m, nega_flg);
}
}
@@ -7196,16 +7190,9 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
void
Init_Bignum(void)
{
-#ifndef RUBY_INTEGER_UNIFICATION
- rb_cBignum = rb_cInteger;
-#endif
- /* An obsolete class, use Integer */
- rb_define_const(rb_cObject, "Bignum", rb_cInteger);
- rb_deprecate_constant(rb_cObject, "Bignum");
-
rb_define_method(rb_cInteger, "coerce", rb_int_coerce, 1);
-#ifdef USE_GMP
+#if USE_GMP
/* The version of loaded GMP. */
rb_define_const(rb_cInteger, "GMP_VERSION", rb_sprintf("GMP %s", gmp_version));
#endif
diff --git a/bin/bundle b/bin/bundle
deleted file mode 100755
index 1a0b06b005..0000000000
--- a/bin/bundle
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'bundler' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-str = ARGV.first
-if str
- str = str.b[/\A_(.*)_\z/, 1]
- if str and Gem::Version.correct?(str)
- version = str
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('bundler', 'bundle', version)
-else
-gem "bundler", version
-load Gem.bin_path("bundler", "bundle", version)
-end
diff --git a/bin/bundler b/bin/bundler
deleted file mode 100755
index e15eb39ed7..0000000000
--- a/bin/bundler
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'bundler' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-str = ARGV.first
-if str
- str = str.b[/\A_(.*)_\z/, 1]
- if str and Gem::Version.correct?(str)
- version = str
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('bundler', 'bundler', version)
-else
-gem "bundler", version
-load Gem.bin_path("bundler", "bundler", version)
-end
diff --git a/bin/erb b/bin/erb
deleted file mode 100755
index 2435224fe1..0000000000
--- a/bin/erb
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env ruby
-# Tiny eRuby --- ERB2
-# Copyright (c) 1999-2000,2002 Masatoshi SEKI
-# You can redistribute it and/or modify it under the same terms as Ruby.
-
-require 'erb'
-
-class ERB
- module Main
- def ARGV.switch
- return nil if self.empty?
- arg = self.shift
- return nil if arg == '--'
- case arg
- when /\A-(.)(.*)/
- if $1 == '-'
- arg, @maybe_arg = arg.split(/=/, 2)
- return arg
- end
- raise 'unknown switch "-"' if $2[0] == ?- and $1 != 'T'
- if $2.size > 0
- self.unshift "-#{$2}"
- @maybe_arg = $2
- else
- @maybe_arg = nil
- end
- "-#{$1}"
- when /\A(\w+)=/
- arg
- else
- self.unshift arg
- nil
- end
- end
-
- def ARGV.req_arg
- (@maybe_arg || self.shift || raise('missing argument')).tap {
- @maybe_arg = nil
- }
- end
-
- def trim_mode_opt(trim_mode, disable_percent)
- return trim_mode if disable_percent
- case trim_mode
- when 0
- return '%'
- when 1
- return '%>'
- when 2
- return '%<>'
- when '-'
- return '%-'
- end
- end
- module_function :trim_mode_opt
-
- def run(factory=ERB)
- trim_mode = 0
- disable_percent = false
- variables = {}
- begin
- while switch = ARGV.switch
- case switch
- when '-x' # ruby source
- output = true
- when '-n' # line number
- number = true
- when '-v' # verbose
- $VERBOSE = true
- when '--version' # version
- STDERR.puts factory.version
- exit
- when '-d', '--debug' # debug
- $DEBUG = true
- when '-r' # require
- require ARGV.req_arg
- when '-S' # security level
- warn 'warning: -S option of erb command is deprecated. Please do not use this.'
- arg = ARGV.req_arg
- raise "invalid safe_level #{arg.dump}" unless arg =~ /\A[0-1]\z/
- safe_level = arg.to_i
- when '-T' # trim mode
- arg = ARGV.req_arg
- if arg == '-'
- trim_mode = arg
- next
- end
- raise "invalid trim mode #{arg.dump}" unless arg =~ /\A[0-2]\z/
- trim_mode = arg.to_i
- when '-E', '--encoding'
- arg = ARGV.req_arg
- set_encoding(*arg.split(/:/, 2))
- when '-U'
- set_encoding(Encoding::UTF_8, Encoding::UTF_8)
- when '-P'
- disable_percent = true
- when '--help'
- raise "print this help"
- when /\A-/
- raise "unknown switch #{switch.dump}"
- else
- var, val = *switch.split('=', 2)
- (variables ||= {})[var] = val
- end
- end
- rescue # usage
- STDERR.puts $!.to_s
- STDERR.puts File.basename($0) +
- " [switches] [var=value...] [inputfile]"
- STDERR.puts <<EOU
- -x print ruby script
- -n print ruby script with line number
- -v enable verbose mode
- -d set $DEBUG to true
- -r library load a library
- -E ex[:in] set default external/internal encodings
- -U set default encoding to UTF-8
- -T trim_mode specify trim_mode (0..2, -)
- -P disable ruby code evaluation for lines beginning with %
- var=value set variable
-EOU
- exit 1
- end
-
- $<.set_encoding(Encoding::UTF_8, nil)
- src = $<.read
- filename = $FILENAME
- exit 2 unless src
- trim = trim_mode_opt(trim_mode, disable_percent)
- if safe_level.nil?
- erb = factory.new(src, trim_mode: trim)
- else
- # [deprecated] This will be removed at Ruby 2.7.
- erb = factory.new(src, safe_level, trim_mode: trim)
- end
- erb.filename = filename
- if output
- if number
- erb.src.each_line.with_index do |line, l|
- puts "%3d %s"%[l+1, line]
- end
- else
- puts erb.src
- end
- else
- bind = TOPLEVEL_BINDING
- if variables
- enc = erb.encoding
- for var, val in variables do
- val = val.encode(enc) if val
- bind.local_variable_set(var, val)
- end
- end
- erb.run(bind)
- end
- end
- module_function :run
-
- def set_encoding(extern, intern = nil)
- verbose, $VERBOSE = $VERBOSE, nil
- Encoding.default_external = extern unless extern.nil? || extern == ""
- Encoding.default_internal = intern unless intern.nil? || intern == ""
- [$stdin, $stdout, $stderr].each do |io|
- io.set_encoding(extern, intern)
- end
- ensure
- $VERBOSE = verbose
- end
- module_function :set_encoding
- class << self; private :set_encoding; end
- end
-end
-
-if __FILE__ == $0
- ERB::Main.run
-end
diff --git a/bin/gem b/bin/gem
index a4ec754abb..1c16ea7ddd 100755
--- a/bin/gem
+++ b/bin/gem
@@ -5,21 +5,6 @@
# See LICENSE.txt for permissions.
#++
-require 'rubygems'
-require 'rubygems/gem_runner'
-require 'rubygems/exceptions'
-
-required_version = Gem::Requirement.new ">= 1.8.7"
-
-unless required_version.satisfied_by? Gem.ruby_version then
- abort "Expected Ruby Version #{required_version}, is #{Gem.ruby_version}"
-end
-
-args = ARGV.clone
-
-begin
- Gem::GemRunner.new.run args
-rescue Gem::SystemExitException => e
- exit e.exit_code
-end
+require "rubygems/gem_runner"
+Gem::GemRunner.new.run ARGV.clone
diff --git a/bin/irb b/bin/irb
deleted file mode 100755
index ae6d358c9d..0000000000
--- a/bin/irb
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'irb' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-str = ARGV.first
-if str
- str = str.b[/\A_(.*)_\z/, 1]
- if str and Gem::Version.correct?(str)
- version = str
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('irb', 'irb', version)
-else
-gem "irb", version
-load Gem.bin_path("irb", "irb", version)
-end
diff --git a/bin/racc b/bin/racc
deleted file mode 100755
index 3ddac532b4..0000000000
--- a/bin/racc
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'racc' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-if ARGV.first
- str = ARGV.first
- str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
- if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
- version = $1
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('racc', 'racc', version)
-else
-gem "racc", version
-load Gem.bin_path("racc", "racc", version)
-end
diff --git a/bin/rdoc b/bin/rdoc
deleted file mode 100755
index 8fa948cddb..0000000000
--- a/bin/rdoc
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'rdoc' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-str = ARGV.first
-if str
- str = str.b[/\A_(.*)_\z/, 1]
- if str and Gem::Version.correct?(str)
- version = str
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('rdoc', 'rdoc', version)
-else
-gem "rdoc", version
-load Gem.bin_path("rdoc", "rdoc", version)
-end
diff --git a/bin/ri b/bin/ri
deleted file mode 100755
index 0cc2f73bb6..0000000000
--- a/bin/ri
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This file was generated by RubyGems.
-#
-# The application 'rdoc' is installed as part of a gem, and
-# this file is here to facilitate running it.
-#
-
-require 'rubygems'
-
-version = ">= 0.a"
-
-str = ARGV.first
-if str
- str = str.b[/\A_(.*)_\z/, 1]
- if str and Gem::Version.correct?(str)
- version = str
- ARGV.shift
- end
-end
-
-if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('rdoc', 'ri', version)
-else
-gem "rdoc", version
-load Gem.bin_path("rdoc", "ri", version)
-end
diff --git a/bootstraptest/pending.rb b/bootstraptest/pending.rb
index 0959bfa2b0..2c4b85a419 100644
--- a/bootstraptest/pending.rb
+++ b/bootstraptest/pending.rb
@@ -1,19 +1,3 @@
-assert_equal 'A', %q{
- class A
- @@a = 'A'
- def a=(x)
- @@a = x
- end
- def a
- @@a
- end
- end
-
- B = A.dup
- B.new.a = 'B'
- A.new.a
-}, '[ruby-core:17019]'
-
assert_equal 'ok', %q{
def m
lambda{
@@ -31,13 +15,6 @@ assert_equal 'ok', %q{
end
}
-assert_normal_exit %q{
- r = Range.allocate
- def r.<=>(o) true end
- r.instance_eval { initialize r, r }
- r.inspect
-}
-
# This randomly fails on mswin.
assert_equal %q{[]}, %q{
Thread.new{sleep}.backtrace
diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb
index 56b4b12230..f9b3e919b8 100755
--- a/bootstraptest/runner.rb
+++ b/bootstraptest/runner.rb
@@ -8,6 +8,8 @@
# Never use Ruby extensions in this file.
# Maintain Ruby 1.8 compatibility for now
+$start_time = Time.now
+
begin
require 'fileutils'
require 'tmpdir'
@@ -58,24 +60,114 @@ if !Dir.respond_to?(:mktmpdir)
end
end
+# Configuration
+bt = Struct.new(:ruby,
+ :verbose,
+ :color,
+ :tty,
+ :quiet,
+ :wn,
+ :progress,
+ :progress_bs,
+ :passed,
+ :failed,
+ :reset,
+ :columns,
+ :window_width,
+ :width,
+ :indent,
+ :platform,
+ )
+BT = Class.new(bt) do
+ def indent=(n)
+ super
+ if (self.columns ||= 0) < n
+ $stderr.print(' ' * (n - self.columns))
+ end
+ self.columns = indent
+ end
+
+ def putc(c)
+ unless self.quiet
+ if self.window_width == nil
+ unless w = ENV["COLUMNS"] and (w = w.to_i) > 0
+ w = 80
+ end
+ w -= 1
+ self.window_width = w
+ end
+ if self.window_width and self.columns >= self.window_width
+ $stderr.print "\n", " " * (self.indent ||= 0)
+ self.columns = indent
+ end
+ $stderr.print c
+ $stderr.flush
+ self.columns += 1
+ end
+ end
+
+ def wn=(wn)
+ unless wn == 1
+ if /(?:\A|\s)--jobserver-(?:auth|fds)=(?:(\d+),(\d+)|fifo:((?:\\.|\S)+))/ =~ ENV.delete("MAKEFLAGS")
+ begin
+ if fifo = $3
+ fifo.gsub!(/\\(?=.)/, '')
+ r = File.open(fifo, IO::RDONLY|IO::NONBLOCK|IO::BINARY)
+ w = File.open(fifo, IO::WRONLY|IO::NONBLOCK|IO::BINARY)
+ else
+ r = IO.for_fd($1.to_i(10), "rb", autoclose: false)
+ w = IO.for_fd($2.to_i(10), "wb", autoclose: false)
+ end
+ rescue => e
+ r.close if r
+ else
+ r.close_on_exec = true
+ w.close_on_exec = true
+ tokens = r.read_nonblock(wn > 0 ? wn : 1024, exception: false)
+ r.close
+ if String === tokens
+ tokens.freeze
+ auth = w
+ w = nil
+ at_exit {auth << tokens; auth.close}
+ wn = tokens.size + 1
+ else
+ w.close
+ wn = 1
+ end
+ end
+ end
+ if wn <= 0
+ require 'etc'
+ wn = [Etc.nprocessors / 2, 1].max
+ end
+ end
+ super wn
+ end
+end.new
+
+BT_STATE = Struct.new(:count, :error).new
+
def main
- @ruby = File.expand_path('miniruby')
- @verbose = false
+ BT.ruby = File.expand_path('miniruby')
+ BT.verbose = false
$VERBOSE = false
$stress = false
- @color = nil
- @tty = nil
- @quiet = false
+ BT.color = nil
+ BT.tty = nil
+ BT.quiet = false
+ # BT.wn = 1
dir = nil
quiet = false
tests = nil
ARGV.delete_if {|arg|
case arg
when /\A--ruby=(.*)/
- @ruby = $1
- @ruby.gsub!(/^([^ ]*)/){File.expand_path($1)}
- @ruby.gsub!(/(\s+-I\s*)((?!(?:\.\/)*-(?:\s|\z))\S+)/){$1+File.expand_path($2)}
- @ruby.gsub!(/(\s+-r\s*)(\.\.?\/\S+)/){$1+File.expand_path($2)}
+ ruby = $1
+ ruby.gsub!(/^([^ ]*)/){File.expand_path($1)}
+ ruby.gsub!(/(\s+-I\s*)((?!(?:\.\/)*-(?:\s|\z))\S+)/){$1+File.expand_path($2)}
+ ruby.gsub!(/(\s+-r\s*)(\.\.?\/\S+)/){$1+File.expand_path($2)}
+ BT.ruby = ruby
true
when /\A--sets=(.*)/
tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb").sort
@@ -88,18 +180,23 @@ def main
$stress = true
when /\A--color(?:=(?:always|(auto)|(never)|(.*)))?\z/
warn "unknown --color argument: #$3" if $3
- @color = $1 ? nil : !$2
+ BT.color = color = $1 ? nil : !$2
true
when /\A--tty(=(?:yes|(no)|(.*)))?\z/
warn "unknown --tty argument: #$3" if $3
- @tty = !$1 || !$2
+ BT.tty = !$1 || !$2
true
when /\A(-q|--q(uiet))\z/
quiet = true
- @quiet = true
+ BT.quiet = true
+ true
+ when /\A-j(\d+)?/
+ BT.wn = $1.to_i
true
when /\A(-v|--v(erbose))\z/
- @verbose = true
+ BT.verbose = true
+ BT.quiet = false
+ true
when /\A(-h|--h(elp)?)\z/
puts(<<-End)
Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...]
@@ -121,22 +218,23 @@ End
end
}
if tests and not ARGV.empty?
- $stderr.puts "--tests and arguments are exclusive"
- exit false
+ abort "--sets and arguments are exclusive"
end
tests ||= ARGV
tests = Dir.glob("#{File.dirname($0)}/test_*.rb").sort if tests.empty?
pathes = tests.map {|path| File.expand_path(path) }
- @progress = %w[- \\ | /]
- @progress_bs = "\b" * @progress[0].size
- @tty = $stderr.tty? if @tty.nil?
- case @color
+ BT.progress = %w[- \\ | /]
+ BT.progress_bs = "\b" * BT.progress[0].size
+ BT.tty = $stderr.tty? if BT.tty.nil?
+ BT.wn ||= /-j(\d+)?/ =~ (ENV["MAKEFLAGS"] || ENV["MFLAGS"]) ? $1.to_i : 1
+
+ case BT.color
when nil
- @color = @tty && /dumb/ !~ ENV["TERM"]
+ BT.color = BT.tty && /dumb/ !~ ENV["TERM"]
end
- @tty &&= !@verbose
- if @color
+ BT.tty &&= !BT.verbose
+ if BT.color
# dircolors-like style
colors = (colors = ENV['TEST_COLORS']) ? Hash[colors.scan(/(\w+)=([^:\n]*)/)] : {}
begin
@@ -145,14 +243,16 @@ End
end
rescue
end
- @passed = "\e[;#{colors["pass"] || "32"}m"
- @failed = "\e[;#{colors["fail"] || "31"}m"
- @reset = "\e[m"
+ BT.passed = "\e[;#{colors["pass"] || "32"}m"
+ BT.failed = "\e[;#{colors["fail"] || "31"}m"
+ BT.reset = "\e[m"
else
- @passed = @failed = @reset = ""
+ BT.passed = BT.failed = BT.reset = ""
end
+ target_version = `#{BT.ruby} -v`.chomp
+ BT.platform = target_version[/\[(.*)\]\z/, 1]
unless quiet
- puts Time.now
+ puts $start_time
if defined?(RUBY_DESCRIPTION)
puts "Driver is #{RUBY_DESCRIPTION}"
elsif defined?(RUBY_PATCHLEVEL)
@@ -160,265 +260,469 @@ End
else
puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
end
- puts "Target is #{`#{@ruby} -v`.chomp}"
+ puts "Target is #{target_version}"
puts
$stdout.flush
end
- in_temporary_working_directory(dir) {
+ in_temporary_working_directory(dir) do
exec_test pathes
- }
+ end
end
def erase(e = true)
- if e and @columns > 0 and @tty and !@verbose
+ if e and BT.columns > 0 and BT.tty and !BT.verbose
"\e[1K\r"
else
""
end
end
-def exec_test(pathes)
- @count = 0
- @error = 0
- @errbuf = []
- @location = nil
- @columns = 0
- @width = pathes.map {|path| File.basename(path).size}.max + 2
+def load_test pathes
pathes.each do |path|
- @basename = File.basename(path)
- $stderr.printf("%s%-*s ", erase(@quiet), @width, @basename)
- $stderr.flush
- @columns = @width + 1
- $stderr.puts if @verbose
- count = @count
- error = @error
load File.expand_path(path)
- if @tty
- if @error == error
- msg = "PASS #{@count-count}"
- @columns += msg.size - 1
- $stderr.print "#{@progress_bs}#{@passed}#{msg}#{@reset}"
+ end
+end
+
+def concurrent_exec_test
+ aq = Queue.new
+ rq = Queue.new
+
+ ts = BT.wn.times.map do
+ Thread.new do
+ while as = aq.pop
+ as.call
+ rq << as
+ end
+ ensure
+ rq << nil
+ end
+ end
+
+ Assertion.all.to_a.shuffle.each do |path, assertions|
+ assertions.each do |as|
+ aq << as
+ end
+ end
+
+ BT.indent = 1
+ aq.close
+ i = 1
+ term_wn = 0
+ begin
+ while BT.wn != term_wn
+ if r = rq.pop
+ case
+ when BT.quiet
+ when BT.tty
+ $stderr.print "#{BT.progress_bs}#{BT.progress[(i+=1) % BT.progress.size]}"
+ else
+ BT.putc '.'
+ end
else
- msg = "FAIL #{@error-error}/#{@count-count}"
- $stderr.print "#{@progress_bs}#{@failed}#{msg}#{@reset}"
- @columns = 0
+ term_wn += 1
+ end
+ end
+ ensure
+ ts.each(&:kill)
+ ts.each(&:join)
+ end
+end
+
+def exec_test(pathes)
+ # setup
+ load_test pathes
+ BT_STATE.count = 0
+ BT_STATE.error = 0
+ BT.columns = 0
+ BT.width = pathes.map {|path| File.basename(path).size}.max + 2
+
+ # execute tests
+ if BT.wn > 1
+ concurrent_exec_test
+ else
+ prev_basename = nil
+ Assertion.all.each do |basename, assertions|
+ if !BT.quiet && basename != prev_basename
+ prev_basename = basename
+ $stderr.printf("%s%-*s ", erase(BT.quiet), BT.width, basename)
+ $stderr.flush
+ end
+ BT.columns = BT.width + 1
+ $stderr.puts if BT.verbose
+ count = BT_STATE.count
+ error = BT_STATE.error
+
+ assertions.each do |assertion|
+ BT_STATE.count += 1
+ assertion.call
+ end
+
+ if BT.tty
+ if BT_STATE.error == error
+ msg = "PASS #{BT_STATE.count-count}"
+ BT.columns += msg.size - 1
+ $stderr.print "#{BT.progress_bs}#{BT.passed}#{msg}#{BT.reset}" unless BT.quiet
+ else
+ msg = "FAIL #{BT_STATE.error-error}/#{BT_STATE.count-count}"
+ $stderr.print "#{BT.progress_bs}#{BT.failed}#{msg}#{BT.reset}"
+ BT.columns = 0
+ end
end
+ $stderr.puts if !BT.quiet and (BT.tty or BT_STATE.error == error)
end
- $stderr.puts unless @quiet and @tty and @error == error
end
- $stderr.print(erase) if @quiet
- @errbuf.each do |msg|
+
+ # show results
+ unless BT.quiet
+ $stderr.puts(erase)
+
+ sec = Time.now - $start_time
+ $stderr.puts "Finished in #{'%.2f' % sec} sec\n\n" if Assertion.count > 0
+ end
+
+ Assertion.errbuf.each do |msg|
$stderr.puts msg
end
- if @error == 0
- if @count == 0
- $stderr.puts "No tests, no problem"
+
+ out = BT.quiet ? $stdout : $stderr
+
+ if BT_STATE.error == 0
+ if Assertion.count == 0
+ out.puts "No tests, no problem" unless BT.quiet
else
- $stderr.puts "#{@passed}PASS#{@reset} all #{@count} tests"
+ out.puts "#{BT.passed}PASS#{BT.reset} all #{Assertion.count} tests"
end
- exit true
+ true
else
- $stderr.puts "#{@failed}FAIL#{@reset} #{@error}/#{@count} tests failed"
- exit false
+ $stderr.puts "#{BT.failed}FAIL#{BT.reset} #{BT_STATE.error}/#{BT_STATE.count} tests failed"
+ false
end
end
-def show_progress(message = '')
- if @verbose
- $stderr.print "\##{@count} #{@location} "
- elsif @tty
- $stderr.print "#{@progress_bs}#{@progress[@count % @progress.size]}"
- end
- t = Time.now if @verbose
- faildesc, errout = with_stderr {yield}
- t = Time.now - t if @verbose
- if !faildesc
- if @tty
- $stderr.print "#{@progress_bs}#{@progress[@count % @progress.size]}"
- elsif @verbose
- $stderr.printf(". %.3f\n", t)
+def target_platform
+ BT.platform or RUBY_PLATFORM
+end
+
+class Assertion < Struct.new(:src, :path, :lineno, :proc)
+ @count = 0
+ @all = Hash.new{|h, k| h[k] = []}
+ @errbuf = []
+
+ class << self
+ attr_reader :count, :errbuf
+
+ def all
+ @all
+ end
+
+ def add as
+ @all[as.path] << as
+ as.id = (@count += 1)
+ end
+ end
+
+ attr_accessor :id
+ attr_reader :err, :category
+
+ def initialize(*args)
+ super
+ self.class.add self
+ @category = self.path.match(/test_(.+)\.rb/)[1]
+ end
+
+ def call
+ self.proc.call self
+ end
+
+ def assert_check(message = '', opt = '', **argh)
+ show_progress(message) {
+ result = get_result_string(opt, **argh)
+ yield(result)
+ }
+ end
+
+ def with_stderr
+ out = err = nil
+ r, w = IO.pipe
+ @err = w
+ err_reader = Thread.new{ r.read }
+
+ begin
+ out = yield
+ ensure
+ w.close
+ err = err_reader.value
+ r.close rescue nil
+ end
+
+ return out, err
+ end
+
+ def show_error(msg, additional_message)
+ msg = "#{BT.failed}\##{self.id} #{self.path}:#{self.lineno}#{BT.reset}: #{msg} #{additional_message}"
+ if BT.tty
+ $stderr.puts "#{erase}#{msg}"
else
- $stderr.print '.'
+ Assertion.errbuf << msg
end
- else
- $stderr.print "#{@failed}F"
- $stderr.printf(" %.3f", t) if @verbose
- $stderr.print @reset
- $stderr.puts if @verbose
- error faildesc, message
- unless errout.empty?
- $stderr.print "#{@failed}stderr output is not empty#{@reset}\n", adjust_indent(errout)
+ BT_STATE.error += 1
+ end
+
+
+ def show_progress(message = '')
+ if BT.quiet || BT.wn > 1
+ # do nothing
+ elsif BT.verbose
+ $stderr.print "\##{@id} #{self.path}:#{self.lineno} "
+ elsif BT.tty
+ $stderr.print "#{BT.progress_bs}#{BT.progress[BT_STATE.count % BT.progress.size]}"
+ end
+
+ t = Time.now if BT.verbose
+ faildesc, errout = with_stderr {yield}
+ t = Time.now - t if BT.verbose
+
+ if !faildesc
+ # success
+ if BT.quiet || BT.wn > 1
+ # do nothing
+ elsif BT.tty
+ $stderr.print "#{BT.progress_bs}#{BT.progress[BT_STATE.count % BT.progress.size]}"
+ elsif BT.verbose
+ $stderr.printf(". %.3f\n", t)
+ else
+ BT.putc '.'
+ end
+ else
+ $stderr.print "#{BT.failed}F"
+ $stderr.printf(" %.3f", t) if BT.verbose
+ $stderr.print BT.reset
+ $stderr.puts if BT.verbose
+ show_error faildesc, message
+ unless errout.empty?
+ $stderr.print "#{BT.failed}stderr output is not empty#{BT.reset}\n", adjust_indent(errout)
+ end
+
+ if BT.tty and !BT.verbose and BT.wn == 1
+ $stderr.printf("%-*s%s", BT.width, path, BT.progress[BT_STATE.count % BT.progress.size])
+ end
end
- if @tty and !@verbose
- $stderr.printf("%-*s%s", @width, @basename, @progress[@count % @progress.size])
+ rescue Interrupt
+ $stderr.puts "\##{@id} #{path}:#{lineno}"
+ raise
+ rescue Exception => err
+ $stderr.print 'E'
+ $stderr.puts if BT.verbose
+ show_error err.message, message
+ ensure
+ begin
+ check_coredump
+ rescue CoreDumpError => err
+ $stderr.print 'E'
+ $stderr.puts if BT.verbose
+ show_error err.message, message
+ cleanup_coredump
end
end
-rescue Interrupt
- $stderr.puts "\##{@count} #{@location}"
- raise
-rescue Exception => err
- $stderr.print 'E'
- $stderr.puts if @verbose
- error err.message, message
-end
-def show_limit(testsrc, opt = '', **argh)
- result = get_result_string(testsrc, opt, **argh)
- if @tty and @verbose
- $stderr.puts ".{#@reset}\n#{erase}#{result}"
- else
- @errbuf.push result
+ def get_result_string(opt = '', **argh)
+ if BT.ruby
+ filename = make_srcfile(**argh)
+ begin
+ kw = self.err ? {err: self.err} : {}
+ out = IO.popen("#{BT.ruby} -W0 #{opt} #{filename}", **kw)
+ pid = out.pid
+ out.read.tap{ Process.waitpid(pid); out.close }
+ ensure
+ raise Interrupt if $? and $?.signaled? && $?.termsig == Signal.list["INT"]
+
+ begin
+ Process.kill :KILL, pid
+ rescue Errno::ESRCH
+ # OK
+ end
+ end
+ else
+ eval(src).to_s
+ end
+ end
+
+ def make_srcfile(frozen_string_literal: nil)
+ filename = "bootstraptest.#{self.path}_#{self.lineno}_#{self.id}.rb"
+ File.open(filename, 'w') {|f|
+ f.puts "#frozen_string_literal:true" if frozen_string_literal
+ f.puts "GC.stress = true" if $stress
+ f.puts "print(begin; #{self.src}; end)"
+ }
+ filename
end
end
-def assert_check(testsrc, message = '', opt = '', **argh)
- show_progress(message) {
- result = get_result_string(testsrc, opt, **argh)
- check_coredump
- yield(result)
- }
+def add_assertion src, pr
+ loc = caller_locations(2, 1).first
+ lineno = loc.lineno
+ path = File.basename(loc.path)
+
+ Assertion.new(src, path, lineno, pr)
end
def assert_equal(expected, testsrc, message = '', opt = '', **argh)
- newtest
- assert_check(testsrc, message, opt, **argh) {|result|
- if expected == result
- nil
- else
- desc = "#{result.inspect} (expected #{expected.inspect})"
- pretty(testsrc, desc, result)
- end
- }
+ add_assertion testsrc, -> as do
+ as.assert_check(message, opt, **argh) {|result|
+ if expected == result
+ nil
+ else
+ desc = "#{result.inspect} (expected #{expected.inspect})"
+ pretty(testsrc, desc, result)
+ end
+ }
+ end
end
def assert_match(expected_pattern, testsrc, message = '')
- newtest
- assert_check(testsrc, message) {|result|
- if expected_pattern =~ result
- nil
- else
- desc = "#{expected_pattern.inspect} expected to be =~\n#{result.inspect}"
- pretty(testsrc, desc, result)
- end
- }
+ add_assertion testsrc, -> as do
+ as.assert_check(message) {|result|
+ if expected_pattern =~ result
+ nil
+ else
+ desc = "#{expected_pattern.inspect} expected to be =~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+ end
end
def assert_not_match(unexpected_pattern, testsrc, message = '')
- newtest
- assert_check(testsrc, message) {|result|
- if unexpected_pattern !~ result
- nil
- else
- desc = "#{unexpected_pattern.inspect} expected to be !~\n#{result.inspect}"
- pretty(testsrc, desc, result)
- end
- }
+ add_assertion testsrc, -> as do
+ as.assert_check(message) {|result|
+ if unexpected_pattern !~ result
+ nil
+ else
+ desc = "#{unexpected_pattern.inspect} expected to be !~\n#{result.inspect}"
+ pretty(testsrc, desc, result)
+ end
+ }
+ end
end
def assert_valid_syntax(testsrc, message = '')
- newtest
- assert_check(testsrc, message, '-c') {|result|
- result if /Syntax OK/ !~ result
- }
+ add_assertion testsrc, -> as do
+ as.assert_check(message, '-c') {|result|
+ result if /Syntax OK/ !~ result
+ }
+ end
end
def assert_normal_exit(testsrc, *rest, timeout: nil, **opt)
- newtest
- message, ignore_signals = rest
- message ||= ''
- show_progress(message) {
- faildesc = nil
- filename = make_srcfile(testsrc)
- old_stderr = $stderr.dup
- timeout_signaled = false
- begin
- $stderr.reopen("assert_normal_exit.log", "w")
- io = IO.popen("#{@ruby} -W0 #{filename}")
- pid = io.pid
- th = Thread.new {
- io.read
- io.close
- $?
- }
- if !th.join(timeout)
- Process.kill :KILL, pid
- timeout_signaled = true
- end
- status = th.value
- ensure
- $stderr.reopen(old_stderr)
- old_stderr.close
- end
- if status && status.signaled?
- signo = status.termsig
- signame = Signal.list.invert[signo]
- unless ignore_signals and ignore_signals.include?(signame)
- sigdesc = "signal #{signo}"
- if signame
- sigdesc = "SIG#{signame} (#{sigdesc})"
- end
- if timeout_signaled
- sigdesc << " (timeout)"
+ add_assertion testsrc, -> as do
+ message, ignore_signals = rest
+ message ||= ''
+ as.show_progress(message) {
+ faildesc = nil
+ filename = as.make_srcfile
+ timeout_signaled = false
+ logfile = "assert_normal_exit.#{as.path}.#{as.lineno}.log"
+
+ begin
+ err = open(logfile, "w")
+ io = IO.popen("#{BT.ruby} -W0 #{filename}", err: err)
+ pid = io.pid
+ th = Thread.new {
+ io.read
+ io.close
+ $?
+ }
+ if !th.join(timeout)
+ Process.kill :KILL, pid
+ timeout_signaled = true
end
- faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
- stderr_log = File.read("assert_normal_exit.log")
- if !stderr_log.empty?
- faildesc << "\n" if /\n\z/ !~ faildesc
- stderr_log << "\n" if /\n\z/ !~ stderr_log
- stderr_log.gsub!(/^.*\n/) { '| ' + $& }
- faildesc << stderr_log
+ status = th.value
+ ensure
+ err.close
+ end
+ if status && status.signaled?
+ signo = status.termsig
+ signame = Signal.list.invert[signo]
+ unless ignore_signals and ignore_signals.include?(signame)
+ sigdesc = "signal #{signo}"
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if timeout_signaled
+ sigdesc << " (timeout)"
+ end
+ faildesc = pretty(testsrc, "killed by #{sigdesc}", nil)
+ stderr_log = File.read(logfile)
+ if !stderr_log.empty?
+ faildesc << "\n" if /\n\z/ !~ faildesc
+ stderr_log << "\n" if /\n\z/ !~ stderr_log
+ stderr_log.gsub!(/^.*\n/) { '| ' + $& }
+ faildesc << stderr_log
+ end
end
end
- end
- faildesc
- }
+ faildesc
+ }
+ end
end
def assert_finish(timeout_seconds, testsrc, message = '')
- if RubyVM.const_defined? :MJIT
- timeout_seconds *= 3 if RubyVM::MJIT.enabled? # for --jit-wait
- end
- newtest
- show_progress(message) {
- faildesc = nil
- filename = make_srcfile(testsrc)
- io = IO.popen("#{@ruby} -W0 #{filename}")
- pid = io.pid
- waited = false
- tlimit = Time.now + timeout_seconds
- diff = timeout_seconds
- while diff > 0
- if Process.waitpid pid, Process::WNOHANG
- waited = true
- break
- end
- if io.respond_to?(:read_nonblock)
- if IO.select([io], nil, nil, diff)
- begin
- io.read_nonblock(1024)
- rescue Errno::EAGAIN, IO::WaitReadable, EOFError
- break
- end while true
+ add_assertion testsrc, -> as do
+ if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
+ timeout_seconds *= 3
+ end
+
+ as.show_progress(message) {
+ faildesc = nil
+ filename = as.make_srcfile
+ io = IO.popen("#{BT.ruby} -W0 #{filename}", err: as.err)
+ pid = io.pid
+ waited = false
+ tlimit = Time.now + timeout_seconds
+ diff = timeout_seconds
+ while diff > 0
+ if Process.waitpid pid, Process::WNOHANG
+ waited = true
+ break
end
- else
- sleep 0.1
+ if io.respond_to?(:read_nonblock)
+ if IO.select([io], nil, nil, diff)
+ begin
+ io.read_nonblock(1024)
+ rescue Errno::EAGAIN, IO::WaitReadable, EOFError
+ break
+ end while true
+ end
+ else
+ sleep 0.1
+ end
+ diff = tlimit - Time.now
end
- diff = tlimit - Time.now
- end
- if !waited
- Process.kill(:KILL, pid)
- Process.waitpid pid
- faildesc = pretty(testsrc, "not finished in #{timeout_seconds} seconds", nil)
- end
- io.close
- faildesc
- }
+ if !waited
+ Process.kill(:KILL, pid)
+ Process.waitpid pid
+ faildesc = pretty(testsrc, "not finished in #{timeout_seconds} seconds", nil)
+ end
+ io.close
+ faildesc
+ }
+ end
end
def flunk(message = '')
- newtest
- show_progress('') { message }
+ add_assertion '', -> as do
+ as.show_progress('') { message }
+ end
+end
+
+def show_limit(testsrc, opt = '', **argh)
+ return if BT.quiet
+
+ add_assertion testsrc, -> as do
+ result = as.get_result_string(opt, **argh)
+ Assertion.errbuf << result
+ end
end
def pretty(src, desc, result)
@@ -436,67 +740,6 @@ def untabify(str)
str.gsub(/^\t+/) {' ' * (8 * $&.size) }
end
-def make_srcfile(src, frozen_string_literal: nil)
- filename = 'bootstraptest.tmp.rb'
- File.open(filename, 'w') {|f|
- f.puts "#frozen_string_literal:true" if frozen_string_literal
- f.puts "GC.stress = true" if $stress
- f.puts "print(begin; #{src}; end)"
- }
- filename
-end
-
-def get_result_string(src, opt = '', **argh)
- if @ruby
- filename = make_srcfile(src, **argh)
- begin
- `#{@ruby} -W0 #{opt} #{filename}`
- ensure
- raise Interrupt if $? and $?.signaled? && $?.termsig == Signal.list["INT"]
- raise CoreDumpError, "core dumped" if $? and $?.coredump?
- end
- else
- eval(src).to_s
- end
-end
-
-def with_stderr
- out = err = nil
- begin
- r, w = IO.pipe
- stderr = $stderr.dup
- $stderr.reopen(w)
- w.close
- reader = Thread.start {r.read}
- begin
- out = yield
- ensure
- $stderr.reopen(stderr)
- err = reader.value
- end
- ensure
- w.close rescue nil
- r.close rescue nil
- end
- return out, err
-end
-
-def newtest
- @location = File.basename(caller(2).first)
- @count += 1
- cleanup_coredump
-end
-
-def error(msg, additional_message)
- msg = "#{@failed}\##{@count} #{@location}#{@reset}: #{msg} #{additional_message}"
- if @tty
- $stderr.puts "#{erase}#{msg}"
- else
- @errbuf.push msg
- end
- @error += 1
-end
-
def in_temporary_working_directory(dir)
if dir
Dir.mkdir dir
@@ -513,18 +756,32 @@ def in_temporary_working_directory(dir)
end
def cleanup_coredump
- FileUtils.rm_f 'core'
+ if File.file?('core')
+ require 'time'
+ Dir.glob('/tmp/bootstraptest-core.*').each do |f|
+ if Time.now - File.mtime(f) > 7 * 24 * 60 * 60 # 7 days
+ warn "Deleting an old core file: #{f}"
+ FileUtils.rm(f)
+ end
+ end
+ core_path = "/tmp/bootstraptest-core.#{Time.now.utc.iso8601}"
+ warn "A core file is found. Saving it at: #{core_path.dump}"
+ FileUtils.mv('core', core_path)
+ cmd = ['gdb', BT.ruby, '-c', core_path, '-ex', 'bt', '-batch']
+ p cmd # debugging why it's not working
+ system(*cmd)
+ end
FileUtils.rm_f Dir.glob('core.*')
- FileUtils.rm_f @ruby+'.stackdump' if @ruby
+ FileUtils.rm_f BT.ruby+'.stackdump' if BT.ruby
end
class CoreDumpError < StandardError; end
def check_coredump
if File.file?('core') or not Dir.glob('core.*').empty? or
- (@ruby and File.exist?(@ruby+'.stackdump'))
+ (BT.ruby and File.exist?(BT.ruby+'.stackdump'))
raise CoreDumpError, "core dumped"
end
end
-main
+exit main
diff --git a/bootstraptest/test_attr.rb b/bootstraptest/test_attr.rb
index 721a847145..3cb9d3eb39 100644
--- a/bootstraptest/test_attr.rb
+++ b/bootstraptest/test_attr.rb
@@ -34,3 +34,19 @@ assert_equal %{ok}, %{
print "ok"
end
}, '[ruby-core:15120]'
+
+assert_equal %{ok}, %{
+ class Big
+ attr_reader :foo
+ def initialize
+ @foo = "ok"
+ end
+ end
+
+ obj = Big.new
+ 100.times do |i|
+ obj.instance_variable_set(:"@ivar_\#{i}", i)
+ end
+
+ Big.new.foo
+}
diff --git a/bootstraptest/test_autoload.rb b/bootstraptest/test_autoload.rb
index a9f8e6dacd..9e0850bc52 100644
--- a/bootstraptest/test_autoload.rb
+++ b/bootstraptest/test_autoload.rb
@@ -1,7 +1,7 @@
assert_equal 'ok', %q{
- File.unlink('zzz.rb') if File.file?('zzz.rb')
+ File.unlink('zzz1.rb') if File.file?('zzz1.rb')
instance_eval do
- autoload :ZZZ, './zzz.rb'
+ autoload :ZZZ, './zzz1.rb'
begin
ZZZ
rescue LoadError
@@ -11,9 +11,9 @@ assert_equal 'ok', %q{
}, '[ruby-dev:43816]'
assert_equal 'ok', %q{
- open('zzz.rb', 'w') {|f| f.puts '' }
+ open('zzz2.rb', 'w') {|f| f.puts '' }
instance_eval do
- autoload :ZZZ, './zzz.rb'
+ autoload :ZZZ, './zzz2.rb'
begin
ZZZ
rescue NameError
@@ -23,29 +23,29 @@ assert_equal 'ok', %q{
}, '[ruby-dev:43816]'
assert_equal 'ok', %q{
- open('zzz.rb', 'w') {|f| f.puts 'class ZZZ; def self.ok;:ok;end;end'}
+ open('zzz3.rb', 'w') {|f| f.puts 'class ZZZ; def self.ok;:ok;end;end'}
instance_eval do
- autoload :ZZZ, './zzz.rb'
+ autoload :ZZZ, './zzz3.rb'
ZZZ.ok
end
}, '[ruby-dev:43816]'
assert_equal 'ok', %q{
- open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
- autoload :ZZZ, "./zzz.rb"
+ open("zzz4.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz4.rb"
ZZZ.ok
}
assert_equal 'ok', %q{
- open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
- autoload :ZZZ, "./zzz.rb"
- require "./zzz.rb"
+ open("zzz5.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz5.rb"
+ require "./zzz5.rb"
ZZZ.ok
}
assert_equal 'okok', %q{
- open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
- autoload :ZZZ, "./zzz.rb"
+ open("zzz6.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+ autoload :ZZZ, "./zzz6.rb"
t1 = Thread.new {ZZZ.ok}
t2 = Thread.new {ZZZ.ok}
[t1.value, t2.value].join
@@ -60,9 +60,9 @@ assert_finish 5, %q{
}, '[ruby-core:21696]'
assert_equal 'A::C', %q{
- open("zzz.rb", "w") {}
+ open("zzz7.rb", "w") {}
class A
- autoload :C, "./zzz"
+ autoload :C, "./zzz7"
class C
end
C
diff --git a/bootstraptest/test_constant_cache.rb b/bootstraptest/test_constant_cache.rb
new file mode 100644
index 0000000000..1fa83256ed
--- /dev/null
+++ b/bootstraptest/test_constant_cache.rb
@@ -0,0 +1,187 @@
+# Constant lookup is cached.
+assert_equal '1', %q{
+ CONST = 1
+
+ def const
+ CONST
+ end
+
+ const
+ const
+}
+
+# Invalidate when a constant is set.
+assert_equal '2', %q{
+ CONST = 1
+
+ def const
+ CONST
+ end
+
+ const
+
+ CONST = 2
+
+ const
+}
+
+# Invalidate when a constant of the same name is set.
+assert_equal '1', %q{
+ CONST = 1
+
+ def const
+ CONST
+ end
+
+ const
+
+ class Container
+ CONST = 2
+ end
+
+ const
+}
+
+# Invalidate when a constant is removed.
+assert_equal 'missing', %q{
+ class Container
+ CONST = 1
+
+ def const
+ CONST
+ end
+
+ def self.const_missing(name)
+ 'missing'
+ end
+
+ new.const
+ remove_const :CONST
+ end
+
+ Container.new.const
+}
+
+# Invalidate when a constant's visibility changes.
+assert_equal 'missing', %q{
+ class Container
+ CONST = 1
+
+ def self.const_missing(name)
+ 'missing'
+ end
+ end
+
+ def const
+ Container::CONST
+ end
+
+ const
+
+ Container.private_constant :CONST
+
+ const
+}
+
+# Invalidate when a constant's visibility changes even if the call to the
+# visibility change method fails.
+assert_equal 'missing', %q{
+ class Container
+ CONST1 = 1
+
+ def self.const_missing(name)
+ 'missing'
+ end
+ end
+
+ def const1
+ Container::CONST1
+ end
+
+ const1
+
+ begin
+ Container.private_constant :CONST1, :CONST2
+ rescue NameError
+ end
+
+ const1
+}
+
+# Invalidate when a module is included.
+assert_equal 'INCLUDE', %q{
+ module Include
+ CONST = :INCLUDE
+ end
+
+ class Parent
+ CONST = :PARENT
+ end
+
+ class Child < Parent
+ def const
+ CONST
+ end
+
+ new.const
+
+ include Include
+ end
+
+ Child.new.const
+}
+
+# Invalidate when const_missing is hit.
+assert_equal '2', %q{
+ module Container
+ Foo = 1
+ Bar = 2
+
+ class << self
+ attr_accessor :count
+
+ def const_missing(name)
+ @count += 1
+ @count == 1 ? Foo : Bar
+ end
+ end
+
+ @count = 0
+ end
+
+ def const
+ Container::Baz
+ end
+
+ const
+ const
+}
+
+# Invalidate when the iseq gets cleaned up.
+assert_equal '2', %q{
+ CONSTANT = 1
+
+ iseq = RubyVM::InstructionSequence.compile(<<~RUBY)
+ CONSTANT
+ RUBY
+
+ iseq.eval
+ iseq = nil
+
+ GC.start
+ CONSTANT = 2
+}
+
+# Invalidate when the iseq gets cleaned up even if it was never in the cache.
+assert_equal '2', %q{
+ CONSTANT = 1
+
+ iseq = RubyVM::InstructionSequence.compile(<<~RUBY)
+ CONSTANT
+ RUBY
+
+ iseq = nil
+
+ GC.start
+ CONSTANT = 2
+}
diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb
index fa04323b7f..a9f389c673 100644
--- a/bootstraptest/test_eval.rb
+++ b/bootstraptest/test_eval.rb
@@ -116,6 +116,33 @@ assert_equal %q{1}, %q{
Const
}
}
+assert_equal %q{1}, %q{
+ class TrueClass
+ Const = 1
+ end
+ true.instance_eval %{
+ Const
+ }
+}
+assert_equal %q{[:Const]}, %q{
+ mod = Module.new
+ mod.instance_eval %{
+ Const = 1
+ }
+ raise if defined?(Module::Const)
+ mod.singleton_class.constants
+}
+assert_equal %q{can't define singleton}, %q{
+ begin
+ 123.instance_eval %{
+ Const = 1
+ }
+ "bad"
+ rescue TypeError => e
+ raise "bad" if defined?(Integer::Const)
+ e.message
+ end
+}
assert_equal %q{top}, %q{
Const = :top
class C
@@ -191,7 +218,7 @@ assert_equal %q{[10, main]}, %q{
%w[break next redo].each do |keyword|
assert_match %r"Can't escape from eval with #{keyword}\b", %{
- STDERR.reopen(STDOUT)
+ $stderr = STDOUT
begin
eval "0 rescue #{keyword}"
rescue SyntaxError => e
@@ -201,7 +228,7 @@ assert_equal %q{[10, main]}, %q{
end
assert_normal_exit %q{
- STDERR.reopen(STDOUT)
+ $stderr = STDOUT
class Foo
def self.add_method
class_eval("def some-bad-name; puts 'hello' unless @some_variable.some_function(''); end")
@@ -250,7 +277,9 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
begin
- 12.instance_eval { @@a }
+ class A
+ 12.instance_eval { @@a }
+ end
rescue NameError
:ok
end
@@ -258,7 +287,9 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
begin
- 12.instance_exec { @@a }
+ class A
+ 12.instance_exec { @@a }
+ end
rescue NameError
:ok
end
diff --git a/bootstraptest/test_fiber.rb b/bootstraptest/test_fiber.rb
index 35e1bf6851..2614dd13bf 100644
--- a/bootstraptest/test_fiber.rb
+++ b/bootstraptest/test_fiber.rb
@@ -19,12 +19,12 @@ assert_equal %q{ok}, %q{
}
assert_equal %q{ok}, %q{
- 10_000.times.collect{Fiber.new{}}
+ 100.times.collect{Fiber.new{}}
:ok
}
assert_equal %q{ok}, %q{
- fibers = 100.times.collect{Fiber.new{Fiber.yield}}
+ fibers = 1000.times.collect{Fiber.new{Fiber.yield}}
fibers.each(&:resume)
fibers.each(&:resume)
:ok
diff --git a/bootstraptest/test_flow.rb b/bootstraptest/test_flow.rb
index 9da6d45cbd..35f19db588 100644
--- a/bootstraptest/test_flow.rb
+++ b/bootstraptest/test_flow.rb
@@ -534,11 +534,11 @@ assert_equal %Q{ENSURE\n}, %q{
['[ruby-core:39125]', %q{
class Bug5234
include Enumerable
- def each
+ def each(&block)
begin
yield :foo
ensure
- proc
+ proc(&block)
end
end
end
@@ -547,11 +547,11 @@ assert_equal %Q{ENSURE\n}, %q{
['[ruby-dev:45656]', %q{
class Bug6460
include Enumerable
- def each
+ def each(&block)
begin
yield :foo
ensure
- 1.times { Proc.new }
+ 1.times { Proc.new(&block) }
end
end
end
diff --git a/bootstraptest/test_insns.rb b/bootstraptest/test_insns.rb
index 1269d7d013..91fba9b011 100644
--- a/bootstraptest/test_insns.rb
+++ b/bootstraptest/test_insns.rb
@@ -64,8 +64,8 @@ tests = [
[ 'setinstancevariable', %q{ @x = true }, ],
[ 'getinstancevariable', %q{ @x = true; @x }, ],
- [ 'setclassvariable', %q{ @@x = true }, ],
- [ 'getclassvariable', %q{ @@x = true; @@x }, ],
+ [ 'setclassvariable', %q{ class A; @@x = true; end }, ],
+ [ 'getclassvariable', %q{ class A; @@x = true; @@x end }, ],
[ 'setconstant', %q{ X = true }, ],
[ 'setconstant', %q{ Object::X = true }, ],
@@ -86,11 +86,8 @@ tests = [
[ 'putobject', %q{ /(?<x>x)/ =~ "x"; x == "x" }, ],
[ 'putspecialobject', %q{ {//=>true}[//] }, ],
- [ 'putiseq', %q{ -> { true }.() }, ],
[ 'putstring', %q{ "true" }, ],
[ 'tostring / concatstrings', %q{ "#{true}" }, ],
- [ 'freezestring', %q{ "#{true}" }, fsl, ],
- [ 'freezestring', %q{ "#{true}" }, '-d', fsl, ],
[ 'toregexp', %q{ /#{true}/ =~ "true" && $~ }, ],
[ 'intern', %q{ :"#{true}" }, ],
@@ -123,6 +120,7 @@ tests = [
[ 'dup', %q{ x = y = true; x }, ],
[ 'dupn', %q{ Object::X ||= true }, ],
[ 'reverse', %q{ q, (w, e), r = 1, [2, 3], 4; e == 3 }, ],
+ [ 'swap', %q{ !!defined?([[]]) }, ],
[ 'swap', <<-'},', ], # {
x = [[false, true]]
for i, j in x # here
@@ -387,14 +385,13 @@ tests = [
[ 'opt_empty_p', %q{ ''.empty? }, ],
[ 'opt_empty_p', %q{ [].empty? }, ],
[ 'opt_empty_p', %q{ {}.empty? }, ],
- [ 'opt_empty_p', %q{ Queue.new.empty? }, ],
+ [ 'opt_empty_p', %q{ Thread::Queue.new.empty? }, ],
[ 'opt_succ', %q{ 1.succ == 2 }, ],
if defined? $FIXNUM_MAX then
[ 'opt_succ',%Q{ #{ $FIXNUM_MAX }.succ == #{ $FIXNUM_MAX + 1 } }, ]
end,
[ 'opt_succ', %q{ '1'.succ == '2' }, ],
- [ 'opt_succ', %q{ x = Time.at(0); x.succ == Time.at(1) }, ],
[ 'opt_not', %q{ ! false }, ],
[ 'opt_neq', <<-'},', ], # {
@@ -412,8 +409,6 @@ tests = [
class String; def =~ other; true; end; end
'true' =~ /true/
},
-
- [ 'opt_call_c_function', 'Struct.new(:x).new.x = true', ],
]
# normal path
@@ -438,3 +433,8 @@ tests.compact.each {|(insn, expr, *a)|
assert_equal 'true', progn, 'trace_' + insn, *a
end
}
+
+assert_normal_exit("#{<<-"begin;"}\n#{<<-'end;'}")
+begin;
+ RubyVM::InstructionSequence.compile("", debug_level: 5)
+end;
diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb
index 89c00d0b88..666e5a011b 100644
--- a/bootstraptest/test_io.rb
+++ b/bootstraptest/test_io.rb
@@ -1,3 +1,4 @@
+/freebsd/ =~ RUBY_PLATFORM or
assert_finish 5, %q{
r, w = IO.pipe
t1 = Thread.new { r.sysread(1) }
@@ -30,7 +31,8 @@ assert_finish 10, %q{
end
}, '[ruby-dev:32566]'
-assert_finish 1, %q{
+/freebsd/ =~ RUBY_PLATFORM or
+assert_finish 5, %q{
r, w = IO.pipe
Thread.new {
w << "ab"
@@ -83,6 +85,7 @@ assert_normal_exit %q{
ARGF.set_encoding "foo"
}
+/freebsd/ =~ RUBY_PLATFORM or
10.times do
assert_normal_exit %q{
at_exit { p :foo }
diff --git a/bootstraptest/test_jump.rb b/bootstraptest/test_jump.rb
index 18a2737ea3..d07c47a56d 100644
--- a/bootstraptest/test_jump.rb
+++ b/bootstraptest/test_jump.rb
@@ -147,7 +147,7 @@ assert_equal %q{131}, %q{
}
}
assert_match %r{Invalid retry}, %q{
-STDERR.reopen(STDOUT)
+$stderr = STDOUT
begin
eval %q{
1.times{
@@ -297,7 +297,7 @@ assert_equal "true", %q{
}, '[ruby-core:21379]'
assert_match %r{Invalid yield}, %q{
-STDERR.reopen(STDOUT)
+$stderr = STDOUT
begin
eval %q{
class Object
diff --git a/bootstraptest/test_literal.rb b/bootstraptest/test_literal.rb
index 9b3c10d519..a0d4ee08c6 100644
--- a/bootstraptest/test_literal.rb
+++ b/bootstraptest/test_literal.rb
@@ -65,8 +65,11 @@ assert_equal ':a3c', ':"a#{1+2}c".inspect'
assert_equal 'Symbol', ':"a#{1+2}c".class'
# xstring
-assert_equal "foo\n", %q(`echo foo`)
-assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
+# WASI doesn't support spawning a new process for now.
+if /wasi/ !~ target_platform
+ assert_equal "foo\n", %q(`echo foo`)
+ assert_equal "foo\n", %q(s = "foo"; `echo #{s}`)
+end
# regexp
assert_equal '', '//.source'
diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb
index 3462aa9434..04c9eb2d11 100644
--- a/bootstraptest/test_method.rb
+++ b/bootstraptest/test_method.rb
@@ -22,7 +22,7 @@ assert_match /\Awrong number of arguments \(.*\b0\b.* 1\)\z/, %q{
}
# default argument
-assert_equal '1', 'def m(x=1) x end; m()'
+assert_equal '1', 'def m(x=1) x end; m();'
assert_equal '1', 'def m(x=7) x end; m(1)'
assert_equal '1', 'def m(a,x=1) x end; m(7)'
assert_equal '1', 'def m(a,x=7) x end; m(7,1)'
diff --git a/bootstraptest/test_proc.rb b/bootstraptest/test_proc.rb
index 6d2c557c3c..637603243d 100644
--- a/bootstraptest/test_proc.rb
+++ b/bootstraptest/test_proc.rb
@@ -367,8 +367,8 @@ assert_equal 'ok', %q{
assert_equal 'ok', %q{
class Foo
- def call_it
- p = Proc.new
+ def call_it(&block)
+ p = Proc.new(&block)
p.call
end
end
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
new file mode 100644
index 0000000000..67e66b03ee
--- /dev/null
+++ b/bootstraptest/test_ractor.rb
@@ -0,0 +1,1628 @@
+# Ractor.current returns a current ractor
+assert_equal 'Ractor', %q{
+ Ractor.current.class
+}
+
+# Ractor.new returns new Ractor
+assert_equal 'Ractor', %q{
+ Ractor.new{}.class
+}
+
+# Ractor.allocate is not supported
+assert_equal "[:ok, :ok]", %q{
+ rs = []
+ begin
+ Ractor.allocate
+ rescue => e
+ rs << :ok if e.message == 'allocator undefined for Ractor'
+ end
+
+ begin
+ Ractor.new{}.dup
+ rescue
+ rs << :ok if e.message == 'allocator undefined for Ractor'
+ end
+
+ rs
+}
+
+# A Ractor can have a name
+assert_equal 'test-name', %q{
+ r = Ractor.new name: 'test-name' do
+ end
+ r.name
+}
+
+# If Ractor doesn't have a name, Ractor#name returns nil.
+assert_equal 'nil', %q{
+ r = Ractor.new do
+ end
+ r.name.inspect
+}
+
+# Raises exceptions if initialize with an invalid name
+assert_equal 'ok', %q{
+ begin
+ r = Ractor.new(name: [{}]) {}
+ rescue TypeError => e
+ 'ok'
+ end
+}
+
+# Ractor.new must call with a block
+assert_equal "must be called with a block", %q{
+ begin
+ Ractor.new
+ rescue ArgumentError => e
+ e.message
+ end
+}
+
+# Ractor#inspect
+# Return only id and status for main ractor
+assert_equal "#<Ractor:#1 running>", %q{
+ Ractor.current.inspect
+}
+
+# Return id, loc, and status for no-name ractor
+assert_match /^#<Ractor:#([^ ]*?) .+:[0-9]+ terminated>$/, %q{
+ r = Ractor.new { '' }
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+ r.inspect
+}
+
+# Return id, name, loc, and status for named ractor
+assert_match /^#<Ractor:#([^ ]*?) Test Ractor .+:[0-9]+ terminated>$/, %q{
+ r = Ractor.new(name: 'Test Ractor') { '' }
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+ r.inspect
+}
+
+# A return value of a Ractor block will be a message from the Ractor.
+assert_equal 'ok', %q{
+ # join
+ r = Ractor.new do
+ 'ok'
+ end
+ r.take
+}
+
+# Passed arguments to Ractor.new will be a block parameter
+# The values are passed with Ractor-communication pass.
+assert_equal 'ok', %q{
+ # ping-pong with arg
+ r = Ractor.new 'ok' do |msg|
+ msg
+ end
+ r.take
+}
+
+# Pass multiple arguments to Ractor.new
+assert_equal 'ok', %q{
+ # ping-pong with two args
+ r = Ractor.new 'ping', 'pong' do |msg, msg2|
+ [msg, msg2]
+ end
+ 'ok' if r.take == ['ping', 'pong']
+}
+
+# Ractor#send passes an object with copy to a Ractor
+# and Ractor.receive in the Ractor block can receive the passed value.
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ msg = Ractor.receive
+ end
+ r.send 'ok'
+ r.take
+}
+
+# Ractor#receive_if can filter the message
+assert_equal '[2, 3, 1]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+ a = []
+ a << Ractor.receive_if{|msg| msg == 2}
+ a << Ractor.receive_if{|msg| msg == 3}
+ a << Ractor.receive
+}
+
+# Ractor#receive_if with break
+assert_equal '[2, [1, :break], 3]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+
+ a = []
+ a << Ractor.receive_if{|msg| msg == 2}
+ a << Ractor.receive_if{|msg| break [msg, :break]}
+ a << Ractor.receive
+}
+
+# Ractor#receive_if can't be called recursively
+assert_equal '[[:e1, 1], [:e2, 2]]', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ end
+
+ a = []
+
+ Ractor.receive_if do |msg|
+ begin
+ Ractor.receive
+ rescue Ractor::Error
+ a << [:e1, msg]
+ end
+ true # delete 1 from queue
+ end
+
+ Ractor.receive_if do |msg|
+ begin
+ Ractor.receive_if{}
+ rescue Ractor::Error
+ a << [:e2, msg]
+ end
+ true # delete 2 from queue
+ end
+
+ a #
+}
+
+# dtoa race condition
+assert_equal '[:ok, :ok, :ok]', %q{
+ n = 3
+ n.times.map{
+ Ractor.new{
+ 10_000.times{ rand.to_s }
+ :ok
+ }
+ }.map(&:take)
+}
+
+# Ractor.make_shareable issue for locals in proc [Bug #18023]
+assert_equal '[:a, :b, :c, :d, :e]', %q{
+ v1, v2, v3, v4, v5 = :a, :b, :c, :d, :e
+ closure = Ractor.current.instance_eval{ Proc.new { [v1, v2, v3, v4, v5] } }
+
+ Ractor.make_shareable(closure).call
+}
+
+# Ractor.make_shareable issue for locals in proc [Bug #18023]
+assert_equal '[:a, :b, :c, :d, :e, :f, :g]', %q{
+ a = :a
+ closure = Ractor.current.instance_eval do
+ -> {
+ b, c, d = :b, :c, :d
+ -> {
+ e, f, g = :e, :f, :g
+ -> { [a, b, c, d, e, f, g] }
+ }.call
+ }.call
+ end
+
+ Ractor.make_shareable(closure).call
+}
+
+# Now autoload in non-main Ractor is not supported
+assert_equal 'ok', %q{
+ autoload :Foo, 'foo.rb'
+ r = Ractor.new do
+ p Foo
+ rescue Ractor::UnsafeError
+ :ok
+ end
+ r.take
+}
+
+###
+###
+# Ractor still has several memory corruption so skip huge number of tests
+if ENV['GITHUB_WORKFLOW'] &&
+ ENV['GITHUB_WORKFLOW'] == 'Compilations'
+ # ignore the follow
+else
+
+# Ractor.select(*ractors) receives a values from a ractors.
+# It is similar to select(2) and Go's select syntax.
+# The return value is [ch, received_value]
+assert_equal 'ok', %q{
+ # select 1
+ r1 = Ractor.new{'r1'}
+ r, obj = Ractor.select(r1)
+ 'ok' if r == r1 and obj == 'r1'
+}
+
+# Ractor.select from two ractors.
+assert_equal '["r1", "r2"]', %q{
+ # select 2
+ r1 = Ractor.new{'r1'}
+ r2 = Ractor.new{'r2'}
+ rs = [r1, r2]
+ as = []
+ r, obj = Ractor.select(*rs)
+ rs.delete(r)
+ as << obj
+ r, obj = Ractor.select(*rs)
+ as << obj
+ as.sort #=> ["r1", "r2"]
+}
+
+# Ractor.select from multiple ractors.
+assert_equal 30.times.map { 'ok' }.to_s, %q{
+ def test n
+ rs = (1..n).map do |i|
+ Ractor.new(i) do |i|
+ "r#{i}"
+ end
+ end
+ as = []
+ all_rs = rs.dup
+
+ n.times{
+ r, obj = Ractor.select(*rs)
+ as << [r, obj]
+ rs.delete(r)
+ }
+
+ if as.map{|r, o| r.object_id}.sort == all_rs.map{|r| r.object_id}.sort &&
+ as.map{|r, o| o}.sort == (1..n).map{|i| "r#{i}"}.sort
+ 'ok'
+ else
+ 'ng'
+ end
+ end
+
+ 30.times.map{|i|
+ test i
+ }
+} unless ENV['RUN_OPTS'] =~ /--mjit-call-threshold=5/ || # This always fails with --mjit-wait --mjit-call-threshold=5
+ (ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') || # https://bugs.ruby-lang.org/issues/17878
+ true # too flaky everywhere http://ci.rvm.jp/results/trunk@ruby-sp1/4321096
+
+# Exception for empty select
+assert_match /specify at least one ractor/, %q{
+ begin
+ Ractor.select
+ rescue ArgumentError => e
+ e.message
+ end
+}
+
+# Outgoing port of a ractor will be closed when the Ractor is terminated.
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ 'finish'
+ end
+
+ r.take
+ sleep 0.1 until r.inspect =~ /terminated/
+
+ begin
+ o = r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ "ng: #{o}"
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a terminated ractor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ end
+
+ r.take # closed
+ sleep 0.1 until r.inspect =~ /terminated/
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a closed actor
+assert_equal 'ok', %q{
+ r = Ractor.new { Ractor.receive }
+ r.close_incoming
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to take from closed actor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ Ractor.receive
+ end
+
+ r.close_outgoing
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Can mix with Thread#interrupt and Ractor#take [Bug #17366]
+assert_equal 'err', %q{
+ Ractor.new{
+ t = Thread.current
+ begin
+ Thread.new{ t.raise "err" }.join
+ rescue => e
+ e.message
+ end
+ }.take
+}
+
+# Killed Ractor's thread yields nil
+assert_equal 'nil', %q{
+ Ractor.new{
+ t = Thread.current
+ Thread.new{ t.kill }.join
+ }.take.inspect #=> nil
+}
+
+# Ractor.yield raises Ractor::ClosedError when outgoing port is closed.
+assert_equal 'ok', %q{
+ r = Ractor.new Ractor.current do |main|
+ Ractor.receive
+ main << true
+ Ractor.yield 1
+ end
+
+ r.close_outgoing
+ r << true
+ Ractor.receive
+
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# Raise Ractor::ClosedError when try to send into a ractor with closed incoming port
+assert_equal 'ok', %q{
+ r = Ractor.new { Ractor.receive }
+ r.close_incoming
+
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# A ractor with closed incoming port still can send messages out
+assert_equal '[1, 2]', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ 2
+ end
+ r.close_incoming
+
+ [r.take, r.take]
+}
+
+# Raise Ractor::ClosedError when try to take from a ractor with closed outgoing port
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.yield 1
+ Ractor.receive
+ end
+
+ sleep 0.01 # wait for Ractor.yield in r
+ r.close_outgoing
+ begin
+ r.take
+ rescue Ractor::ClosedError
+ 'ok'
+ else
+ 'ng'
+ end
+}
+
+# A ractor with closed outgoing port still can receive messages from incoming port
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ Ractor.receive
+ end
+
+ r.close_outgoing
+ begin
+ r.send(1)
+ rescue Ractor::ClosedError
+ 'ng'
+ else
+ 'ok'
+ end
+}
+
+# Ractor.main returns main ractor
+assert_equal 'true', %q{
+ Ractor.new{
+ Ractor.main
+ }.take == Ractor.current
+}
+
+# a ractor with closed outgoing port should terminate
+assert_equal 'ok', %q{
+ Ractor.new do
+ close_outgoing
+ end
+
+ true until Ractor.count == 1
+ :ok
+}
+
+# multiple Ractors can receive (wait) from one Ractor
+assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ rs = RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ msg = pipe.take
+ msg # ping-pong
+ end
+ }
+ RN.times{|i|
+ pipe << i
+ }
+ RN.times.map{
+ r, n = Ractor.select(*rs)
+ rs.delete r
+ n
+ }.sort
+} unless /mswin/ =~ RUBY_PLATFORM # randomly hangs on mswin https://github.com/ruby/ruby/actions/runs/3753871445/jobs/6377551069#step:20:131
+
+# Ractor.select also support multiple take, receive and yield
+assert_equal '[true, true, true]', %q{
+ RN = 10
+ CR = Ractor.current
+
+ rs = (1..RN).map{
+ Ractor.new do
+ CR.send 'send' + CR.take #=> 'sendyield'
+ 'take'
+ end
+ }
+ received = []
+ take = []
+ yielded = []
+ until rs.empty?
+ r, v = Ractor.select(CR, *rs, yield_value: 'yield')
+ case r
+ when :receive
+ received << v
+ when :yield
+ yielded << v
+ else
+ take << v
+ rs.delete r
+ end
+ end
+ [received.all?('sendyield'), yielded.all?(nil), take.all?('take')]
+}
+
+# multiple Ractors can send to one Ractor
+assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
+ pipe = Ractor.new do
+ loop do
+ Ractor.yield Ractor.receive
+ end
+ end
+
+ RN = 10
+ RN.times.map{|i|
+ Ractor.new pipe, i do |pipe, i|
+ pipe << i
+ end
+ }
+ RN.times.map{
+ pipe.take
+ }.sort
+}
+
+# an exception in a Ractor will be re-raised at Ractor#receive
+assert_equal '[RuntimeError, "ok", true]', %q{
+ r = Ractor.new do
+ raise 'ok' # exception will be transferred receiver
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ [e.cause.class, #=> RuntimeError
+ e.cause.message, #=> 'ok'
+ e.ractor == r] #=> true
+ end
+}
+
+# threads in a ractor will killed
+assert_equal '{:ok=>3}', %q{
+ Ractor.new Ractor.current do |main|
+ q = Thread::Queue.new
+ Thread.new do
+ q << true
+ loop{}
+ ensure
+ main << :ok
+ end
+
+ Thread.new do
+ q << true
+ while true
+ end
+ ensure
+ main << :ok
+ end
+
+ Thread.new do
+ q << true
+ sleep 1
+ ensure
+ main << :ok
+ end
+
+ # wait for the start of all threads
+ 3.times{q.pop}
+ end
+
+ 3.times.map{Ractor.receive}.tally
+}
+
+# unshareable object are copied
+assert_equal 'false', %q{
+ obj = 'str'.dup
+ r = Ractor.new obj do |msg|
+ msg.object_id
+ end
+
+ obj.object_id == r.take
+}
+
+# To copy the object, now Marshal#dump is used
+assert_equal "allocator undefined for Thread", %q{
+ obj = Thread.new{}
+ begin
+ r = Ractor.new obj do |msg|
+ msg
+ end
+ rescue TypeError => e
+ e.message #=> no _dump_data is defined for class Thread
+ else
+ 'ng'
+ end
+}
+
+# send shareable and unshareable objects
+assert_equal "ok", %q{
+ echo_ractor = Ractor.new do
+ loop do
+ v = Ractor.receive
+ Ractor.yield v
+ end
+ end
+
+ class C; end
+ module M; end
+ S = Struct.new(:a, :b, :c, :d)
+
+ shareable_objects = [
+ true,
+ false,
+ nil,
+ 1,
+ 1.1, # Float
+ 1+2r, # Rational
+ 3+4i, # Complex
+ 2**128, # Bignum
+ :sym, # Symbol
+ 'xyzzy'.to_sym, # dynamic symbol
+ 'frozen'.freeze, # frozen String
+ /regexp/, # regexp literal
+ /reg{true}exp/.freeze, # frozen dregexp
+ [1, 2].freeze, # frozen Array which only refers to shareable
+ {a: 1}.freeze, # frozen Hash which only refers to shareable
+ [{a: 1}.freeze, 'str'.freeze].freeze, # nested frozen container
+ S.new(1, 2).freeze, # frozen Struct
+ S.new(1, 2, 3, 4).freeze, # frozen Struct
+ (1..2), # Range on Struct
+ (1..), # Range on Struct
+ (..1), # Range on Struct
+ C, # class
+ M, # module
+ Ractor.current, # Ractor
+ ]
+
+ unshareable_objects = [
+ 'mutable str'.dup,
+ [:array],
+ {hash: true},
+ S.new(1, 2),
+ S.new(1, 2, 3, 4),
+ S.new("a", 2).freeze, # frozen, but refers to an unshareable object
+ ]
+
+ results = []
+
+ shareable_objects.map{|o|
+ echo_ractor << o
+ o2 = echo_ractor.take
+ results << "#{o} is copied" unless o.object_id == o2.object_id
+ }
+
+ unshareable_objects.map{|o|
+ echo_ractor << o
+ o2 = echo_ractor.take
+ results << "#{o.inspect} is not copied" if o.object_id == o2.object_id
+ }
+
+ if results.empty?
+ :ok
+ else
+ results.inspect
+ end
+}
+
+# frozen Objects are shareable
+assert_equal [false, true, false].inspect, %q{
+ class C
+ def initialize freeze
+ @a = 1
+ @b = :sym
+ @c = 'frozen_str'
+ @c.freeze if freeze
+ @d = true
+ end
+ end
+
+ def check obj1
+ obj2 = Ractor.new obj1 do |obj|
+ obj
+ end.take
+
+ obj1.object_id == obj2.object_id
+ end
+
+ results = []
+ results << check(C.new(true)) # false
+ results << check(C.new(true).freeze) # true
+ results << check(C.new(false).freeze) # false
+}
+
+# move example2: String
+# touching moved object causes an error
+assert_equal 'hello world', %q{
+ # move
+ r = Ractor.new do
+ obj = Ractor.receive
+ obj << ' world'
+ end
+
+ str = 'hello'
+ r.send str, move: true
+ modified = r.take
+
+ begin
+ str << ' exception' # raise Ractor::MovedError
+ rescue Ractor::MovedError
+ modified #=> 'hello world'
+ else
+ raise 'unreachable'
+ end
+}
+
+# move example2: Array
+assert_equal '[0, 1]', %q{
+ r = Ractor.new do
+ ary = Ractor.receive
+ ary << 1
+ end
+
+ a1 = [0]
+ r.send a1, move: true
+ a2 = r.take
+ begin
+ a1 << 2 # raise Ractor::MovedError
+ rescue Ractor::MovedError
+ a2.inspect
+ end
+}
+
+# move with yield
+assert_equal 'hello', %q{
+ r = Ractor.new do
+ Thread.current.report_on_exception = false
+ obj = 'hello'
+ Ractor.yield obj, move: true
+ obj << 'world'
+ end
+
+ str = r.take
+ begin
+ r.take
+ rescue Ractor::RemoteError
+ str #=> "hello"
+ end
+}
+
+# yield/move should not make moved object when the yield is not succeeded
+assert_equal '"str"', %q{
+ R = Ractor.new{}
+ M = Ractor.current
+ r = Ractor.new do
+ s = 'str'
+ selected_r, v = Ractor.select R, yield_value: s, move: true
+ raise if selected_r != R # taken from R
+ M.send s.inspect # s should not be a moved object
+ end
+
+ Ractor.receive
+}
+
+# yield/move can fail
+assert_equal "allocator undefined for Thread", %q{
+ r = Ractor.new do
+ obj = Thread.new{}
+ Ractor.yield obj
+ rescue => e
+ e.message
+ end
+ r.take
+}
+
+# Access to global-variables are prohibited
+assert_equal 'can not access global variables $gv from non-main Ractors', %q{
+ $gv = 1
+ r = Ractor.new do
+ $gv
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Access to global-variables are prohibited
+assert_equal 'can not access global variables $gv from non-main Ractors', %q{
+ r = Ractor.new do
+ $gv = 1
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# $stdin,out,err is Ractor local, but shared fds
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ [$stdin, $stdout, $stderr].map{|io|
+ [io.object_id, io.fileno]
+ }
+ end
+
+ [$stdin, $stdout, $stderr].zip(r.take){|io, (oid, fno)|
+ raise "should not be different object" if io.object_id == oid
+ raise "fd should be same" unless io.fileno == fno
+ }
+ 'ok'
+}
+
+# $stdin,out,err belong to Ractor
+assert_equal 'ok', %q{
+ r = Ractor.new do
+ $stdin.itself
+ $stdout.itself
+ $stderr.itself
+ 'ok'
+ end
+
+ r.take
+}
+
+# $DEBUG, $VERBOSE are Ractor local
+assert_equal 'true', %q{
+ $DEBUG = true
+ $VERBOSE = true
+
+ def ractor_local_globals
+ /a(b)(c)d/ =~ 'abcd' # for $~
+ `echo foo` unless /solaris/ =~ RUBY_PLATFORM
+
+ {
+ # ractor-local (derived from created ractor): debug
+ '$DEBUG' => $DEBUG,
+ '$-d' => $-d,
+
+ # ractor-local (derived from created ractor): verbose
+ '$VERBOSE' => $VERBOSE,
+ '$-w' => $-w,
+ '$-W' => $-W,
+ '$-v' => $-v,
+
+ # process-local (readonly): other commandline parameters
+ '$-p' => $-p,
+ '$-l' => $-l,
+ '$-a' => $-a,
+
+ # process-local (readonly): getpid
+ '$$' => $$,
+
+ # thread local: process result
+ '$?' => $?,
+
+ # scope local: match
+ '$~' => $~.inspect,
+ '$&' => $&,
+ '$`' => $`,
+ '$\'' => $',
+ '$+' => $+,
+ '$1' => $1,
+
+ # scope local: last line
+ '$_' => $_,
+
+ # scope local: last backtrace
+ '$@' => $@,
+ '$!' => $!,
+
+ # ractor local: stdin, out, err
+ '$stdin' => $stdin.inspect,
+ '$stdout' => $stdout.inspect,
+ '$stderr' => $stderr.inspect,
+ }
+ end
+
+ h = Ractor.new do
+ ractor_local_globals
+ end.take
+ ractor_local_globals == h #=> true
+}
+
+# selfs are different objects
+assert_equal 'false', %q{
+ r = Ractor.new do
+ self.object_id
+ end
+ r.take == self.object_id #=> false
+}
+
+# self is a Ractor instance
+assert_equal 'true', %q{
+ r = Ractor.new do
+ self.object_id
+ end
+ r.object_id == r.take #=> true
+}
+
+# given block Proc will be isolated, so can not access outer variables.
+assert_equal 'ArgumentError', %q{
+ begin
+ a = true
+ r = Ractor.new do
+ a
+ end
+ rescue => e
+ e.class
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal "can not get unshareable values from instance variables of classes/modules from non-main Ractors", %q{
+ class C
+ @iv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @iv
+ end
+ end
+
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ shared = Ractor.new{}
+ shared.instance_variable_set(:@iv, 'str')
+
+ r = Ractor.new shared do |shared|
+ p shared.instance_variable_get(:@iv)
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor, by @iv (get)
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ class Ractor
+ def setup
+ @foo = ''
+ end
+
+ def foo
+ @foo
+ end
+ end
+
+ shared = Ractor.new{}
+ shared.setup
+
+ r = Ractor.new shared do |shared|
+ p shared.foo
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# ivar in shareable-objects are not allowed to access from non-main Ractor, by @iv (set)
+assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{
+ class Ractor
+ def setup
+ @foo = ''
+ end
+ end
+
+ shared = Ractor.new{}
+
+ r = Ractor.new shared do |shared|
+ p shared.setup
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# But a shareable object is frozen, it is allowed to access ivars from non-main Ractor
+assert_equal '11', %q{
+ [Object.new, [], ].map{|obj|
+ obj.instance_variable_set('@a', 1)
+ Ractor.make_shareable obj = obj.freeze
+
+ Ractor.new obj do |obj|
+ obj.instance_variable_get('@a')
+ end.take.to_s
+ }.join
+}
+
+# and instance variables of classes/modules are accessible if they refer shareable objects
+assert_equal '333', %q{
+ class C
+ @int = 1
+ @str = '-1000'.dup
+ @fstr = '100'.freeze
+
+ def self.int = @int
+ def self.str = @str
+ def self.fstr = @fstr
+ end
+
+ module M
+ @int = 2
+ @str = '-2000'.dup
+ @fstr = '200'.freeze
+
+ def self.int = @int
+ def self.str = @str
+ def self.fstr = @fstr
+ end
+
+ a = Ractor.new{ C.int }.take
+ b = Ractor.new do
+ C.str.to_i
+ rescue Ractor::IsolationError
+ 10
+ end.take
+ c = Ractor.new do
+ C.fstr.to_i
+ end.take
+
+ d = Ractor.new{ M.int }.take
+ e = Ractor.new do
+ M.str.to_i
+ rescue Ractor::IsolationError
+ 20
+ end.take
+ f = Ractor.new do
+ M.fstr.to_i
+ end.take
+
+
+ # 1 + 10 + 100 + 2 + 20 + 200
+ a + b + c + d + e + f
+}
+
+# cvar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access class variables from non-main Ractors', %q{
+ class C
+ @@cv = 'str'
+ end
+
+ r = Ractor.new do
+ class C
+ p @@cv
+ end
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# also cached cvar in shareable-objects are not allowed to access from non-main Ractor
+assert_equal 'can not access class variables from non-main Ractors', %q{
+ class C
+ @@cv = 'str'
+ def self.cv
+ @@cv
+ end
+ end
+
+ C.cv # cache
+
+ r = Ractor.new do
+ C.cv
+ end
+
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Getting non-shareable objects via constants by other Ractors is not allowed
+assert_equal 'can not access non-shareable objects in constant C::CONST by non-main Ractor.', %q{
+ class C
+ CONST = 'str'
+ end
+ r = Ractor.new do
+ C::CONST
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Constant cache should care about non-sharable constants
+assert_equal "can not access non-shareable objects in constant Object::STR by non-main Ractor.", %q{
+ STR = "hello"
+ def str; STR; end
+ s = str() # fill const cache
+ begin
+ Ractor.new{ str() }.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# Setting non-shareable objects into constants by other Ractors is not allowed
+assert_equal 'can not set constants with non-shareable objects by non-main Ractors', %q{
+ class C
+ end
+ r = Ractor.new do
+ C::CONST = 'str'
+ end
+ begin
+ r.take
+ rescue Ractor::RemoteError => e
+ e.cause.message
+ end
+}
+
+# define_method is not allowed
+assert_equal "defined with an un-shareable Proc in a different Ractor", %q{
+ str = "foo"
+ define_method(:buggy){|i| str << "#{i}"}
+ begin
+ Ractor.new{buggy(10)}.take
+ rescue => e
+ e.cause.message
+ end
+}
+
+# Immutable Array and Hash are shareable, so it can be shared with constants
+assert_equal '[1000, 3]', %q{
+ A = Array.new(1000).freeze # [nil, ...]
+ H = {a: 1, b: 2, c: 3}.freeze
+
+ Ractor.new{ [A.size, H.size] }.take
+}
+
+# Ractor.count
+assert_equal '[1, 4, 3, 2, 1]', %q{
+ counts = []
+ counts << Ractor.count
+ ractors = (1..3).map { Ractor.new { Ractor.receive } }
+ counts << Ractor.count
+
+ ractors[0].send('End 0').take
+ sleep 0.1 until ractors[0].inspect =~ /terminated/
+ counts << Ractor.count
+
+ ractors[1].send('End 1').take
+ sleep 0.1 until ractors[1].inspect =~ /terminated/
+ counts << Ractor.count
+
+ ractors[2].send('End 2').take
+ sleep 0.1 until ractors[2].inspect =~ /terminated/
+ counts << Ractor.count
+
+ counts.inspect
+}
+
+# ObjectSpace.each_object can not handle unshareable objects with Ractors
+assert_equal '0', %q{
+ Ractor.new{
+ n = 0
+ ObjectSpace.each_object{|o| n += 1 unless Ractor.shareable?(o)}
+ n
+ }.take
+}
+
+# ObjectSpace._id2ref can not handle unshareable objects with Ractors
+assert_equal 'ok', %q{
+ s = 'hello'
+
+ Ractor.new s.object_id do |id ;s|
+ begin
+ s = ObjectSpace._id2ref(id)
+ rescue => e
+ :ok
+ end
+ end.take
+}
+
+# Ractor.make_shareable(obj)
+assert_equal 'true', %q{
+ class C
+ def initialize
+ @a = 'foo'
+ @b = 'bar'
+ end
+
+ def freeze
+ @c = [:freeze_called]
+ super
+ end
+
+ attr_reader :a, :b, :c
+ end
+ S = Struct.new(:s1, :s2)
+ str = "hello"
+ str.instance_variable_set("@iv", "hello")
+ /a/ =~ 'a'
+ m = $~
+ class N < Numeric
+ def /(other)
+ 1
+ end
+ end
+ ary = []; ary << ary
+
+ a = [[1, ['2', '3']],
+ {Object.new => "hello"},
+ C.new,
+ S.new("x", "y"),
+ ("a".."b"),
+ str,
+ ary, # cycle
+ /regexp/,
+ /#{'r'.upcase}/,
+ m,
+ Complex(N.new,0),
+ Rational(N.new,0),
+ true,
+ false,
+ nil,
+ 1, 1.2, 1+3r, 1+4i, # Numeric
+ ]
+ Ractor.make_shareable(a)
+
+ # check all frozen
+ a.each{|o|
+ raise o.inspect unless o.frozen?
+
+ case o
+ when C
+ raise o.a.inspect unless o.a.frozen?
+ raise o.b.inspect unless o.b.frozen?
+ raise o.c.inspect unless o.c.frozen? && o.c == [:freeze_called]
+ when Rational
+ raise o.numerator.inspect unless o.numerator.frozen?
+ when Complex
+ raise o.real.inspect unless o.real.frozen?
+ when Array
+ if o[0] == 1
+ raise o[1][1].inspect unless o[1][1].frozen?
+ end
+ when Hash
+ o.each{|k, v|
+ raise k.inspect unless k.frozen?
+ raise v.inspect unless v.frozen?
+ }
+ end
+ }
+
+ Ractor.shareable?(a)
+}
+
+# Ractor.make_shareable(obj) doesn't freeze shareable objects
+assert_equal 'true', %q{
+ r = Ractor.new{}
+ Ractor.make_shareable(a = [r])
+ [a.frozen?, a[0].frozen?] == [true, false]
+}
+
+# Ractor.make_shareable(a_proc) makes a proc shareable.
+assert_equal 'true', %q{
+ a = [1, [2, 3], {a: "4"}]
+
+ pr = Ractor.current.instance_eval do
+ Proc.new do
+ a
+ end
+ end
+
+ Ractor.make_shareable(a) # referred value should be shareable
+ Ractor.make_shareable(pr)
+ Ractor.shareable?(pr)
+}
+
+# Ractor.shareable?(recursive_objects)
+assert_equal '[false, false]', %q{
+ y = []
+ x = [y, {}].freeze
+ y << x
+ y.freeze
+ [Ractor.shareable?(x), Ractor.shareable?(y)]
+}
+
+# Ractor.make_shareable(recursive_objects)
+assert_equal '[:ok, false, false]', %q{
+ o = Object.new
+ def o.freeze; raise; end
+ y = []
+ x = [y, o].freeze
+ y << x
+ y.freeze
+ [(Ractor.make_shareable(x) rescue :ok), Ractor.shareable?(x), Ractor.shareable?(y)]
+}
+
+# Ractor.make_shareable with Class/Module
+assert_equal '[C, M]', %q{
+ class C; end
+ module M; end
+
+ Ractor.make_shareable(ary = [C, M])
+}
+
+# define_method() can invoke different Ractor's proc if the proc is shareable.
+assert_equal '1', %q{
+ class C
+ a = 1
+ define_method "foo", Ractor.make_shareable(Proc.new{ a })
+ a = 2
+ end
+
+ Ractor.new{ C.new.foo }.take
+}
+
+# Ractor.make_shareable(a_proc) makes a proc shareable.
+assert_equal 'can not make a Proc shareable because it accesses outer variables (a).', %q{
+ a = b = nil
+ pr = Ractor.current.instance_eval do
+ Proc.new do
+ c = b # assign to a is okay because c is block local variable
+ # reading b is okay
+ a = b # assign to a is not allowed #=> Ractor::Error
+ end
+ end
+
+ begin
+ Ractor.make_shareable(pr)
+ rescue => e
+ e.message
+ end
+}
+
+# Ractor.make_shareable(obj, copy: true) makes copied shareable object.
+assert_equal '[false, false, true, true]', %q{
+ r = []
+ o1 = [1, 2, ["3"]]
+
+ o2 = Ractor.make_shareable(o1, copy: true)
+ r << Ractor.shareable?(o1) # false
+ r << (o1.object_id == o2.object_id) # false
+
+ o3 = Ractor.make_shareable(o1)
+ r << Ractor.shareable?(o1) # true
+ r << (o1.object_id == o3.object_id) # false
+ r
+}
+
+# TracePoint with normal Proc should be Ractor local
+assert_equal '[4, 8]', %q{
+ rs = []
+ TracePoint.new(:line){|tp| rs << tp.lineno if tp.path == __FILE__}.enable do
+ Ractor.new{ # line 4
+ a = 1
+ b = 2
+ }.take
+ c = 3 # line 8
+ end
+ rs
+}
+
+# Ractor deep copies frozen objects (ary)
+assert_equal '[true, false]', %q{
+ Ractor.new([[]].freeze) { |ary|
+ [ary.frozen?, ary.first.frozen? ]
+ }.take
+}
+
+# Ractor deep copies frozen objects (str)
+assert_equal '[true, false]', %q{
+ s = String.new.instance_eval { @x = []; freeze}
+ Ractor.new(s) { |s|
+ [s.frozen?, s.instance_variable_get(:@x).frozen?]
+ }.take
+}
+
+# Can not trap with not isolated Proc on non-main ractor
+assert_equal '[:ok, :ok]', %q{
+ a = []
+ Ractor.new{
+ trap(:INT){p :ok}
+ }.take
+ a << :ok
+
+ begin
+ Ractor.new{
+ s = 'str'
+ trap(:INT){p s}
+ }.take
+ rescue => Ractor::RemoteError
+ a << :ok
+ end
+}
+
+# Ractor-local storage
+assert_equal '[nil, "b", "a"]', %q{
+ ans = []
+ Ractor.current[:key] = 'a'
+ r = Ractor.new{
+ Ractor.yield self[:key]
+ self[:key] = 'b'
+ self[:key]
+ }
+ ans << r.take
+ ans << r.take
+ ans << Ractor.current[:key]
+}
+
+###
+### Synchronization tests
+###
+
+N = 100_000
+
+# fstring pool
+assert_equal "#{N}#{N}", %Q{
+ N = #{N}
+ 2.times.map{
+ Ractor.new{
+ N.times{|i| -(i.to_s)}
+ }
+ }.map{|r| r.take}.join
+}
+
+# enc_table
+assert_equal "100", %Q{
+ Ractor.new do
+ loop do
+ Encoding.find("test-enc-#{rand(5_000)}").inspect
+ rescue ArgumentError => e
+ end
+ end
+
+ src = Encoding.find("UTF-8")
+ 100.times{|i|
+ src.replicate("test-enc-\#{i}")
+ }
+}
+
+# Generic ivtbl
+n = N/2
+assert_equal "#{n}#{n}", %Q{
+ 2.times.map{
+ Ractor.new do
+ #{n}.times do
+ obj = ''
+ obj.instance_variable_set("@a", 1)
+ obj.instance_variable_set("@b", 1)
+ obj.instance_variable_set("@c", 1)
+ obj.instance_variable_defined?("@a")
+ end
+ end
+ }.map{|r| r.take}.join
+}
+
+# NameError
+assert_equal "ok", %q{
+ begin
+ bar
+ rescue => err
+ end
+ begin
+ Ractor.new{} << err
+ rescue TypeError
+ 'ok'
+ end
+}
+
+assert_equal "ok", %q{
+ GC.disable
+ Ractor.new {}
+ raise "not ok" unless GC.disable
+
+ foo = []
+ 10.times { foo << 1 }
+
+ GC.start
+
+ 'ok'
+}
+
+# Can yield back values while GC is sweeping [Bug #18117]
+assert_equal "ok", %q{
+ workers = (0...8).map do
+ Ractor.new do
+ loop do
+ 10_000.times.map { Object.new }
+ Ractor.yield Time.now
+ end
+ end
+ end
+
+ 1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
+ "ok"
+}
+
+assert_equal "ok", %q{
+ def foo(*); ->{ super }; end
+ begin
+ Ractor.make_shareable(foo)
+ rescue Ractor::IsolationError
+ "ok"
+ end
+}
+
+assert_equal "ok", %q{
+ def foo(**); ->{ super }; end
+ begin
+ Ractor.make_shareable(foo)
+ rescue Ractor::IsolationError
+ "ok"
+ end
+}
+
+assert_equal "ok", %q{
+ def foo(...); ->{ super }; end
+ begin
+ Ractor.make_shareable(foo)
+ rescue Ractor::IsolationError
+ "ok"
+ end
+}
+
+assert_equal "ok", %q{
+ def foo((x), (y)); ->{ super }; end
+ begin
+ Ractor.make_shareable(foo([], []))
+ rescue Ractor::IsolationError
+ "ok"
+ end
+}
+
+assert_equal "ok", %q{
+ module M
+ def foo
+ @foo
+ end
+ end
+
+ class A
+ include M
+
+ def initialize
+ 100.times { |i| instance_variable_set(:"@var_#{i}", "bad: #{i}") }
+ @foo = 2
+ end
+ end
+
+ class B
+ include M
+
+ def initialize
+ @foo = 1
+ end
+ end
+
+ Ractor.new do
+ b = B.new
+ 100_000.times do
+ raise unless b.foo == 1
+ end
+ end
+
+ a = A.new
+ 100_000.times do
+ raise unless a.foo == 2
+ end
+
+ "ok"
+}
+
+assert_match /\Atest_ractor\.rb:1:\s+warning:\s+Ractor is experimental/, %q{
+ Warning[:experimental] = $VERBOSE = true
+ STDERR.reopen(STDOUT)
+ eval("Ractor.new{}.take", nil, "test_ractor.rb", 1)
+}
+
+end # if !ENV['GITHUB_WORKFLOW']
diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb
index a111990a1f..948e2d7809 100644
--- a/bootstraptest/test_syntax.rb
+++ b/bootstraptest/test_syntax.rb
@@ -268,8 +268,10 @@ assert_equal %q{}, %q{
defined?(@@a)
}
assert_equal %q{class variable}, %q{
- @@a = 1
- defined?(@@a)
+ class A
+ @@a = 1
+ defined?(@@a)
+ end
}
assert_equal %q{}, %q{
defined?($a)
@@ -626,7 +628,7 @@ assert_equal '2', %q{
}
assert_match /invalid multibyte char/, %q{
- STDERR.reopen(STDOUT)
+ $stderr = STDOUT
eval("\"\xf0".force_encoding("utf-8"))
}, '[ruby-dev:32429]'
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
index f00e2f7efc..5361828403 100644
--- a/bootstraptest/test_thread.rb
+++ b/bootstraptest/test_thread.rb
@@ -8,7 +8,8 @@ show_limit %q{
puts "Thread count: #{threads.count} (#{error})"
break
end while true
-}
+} if false # disable to pass CI
+
assert_equal %q{ok}, %q{
Thread.new{
}.join
@@ -242,7 +243,7 @@ assert_equal 'true', %{
}
assert_equal 'ok', %{
- open("zzz.rb", "w") do |f|
+ open("zzz_t1.rb", "w") do |f|
f.puts <<-END
begin
Thread.new { fork { GC.start } }.join
@@ -253,7 +254,7 @@ assert_equal 'ok', %{
end
END
end
- require "./zzz.rb"
+ require "./zzz_t1.rb"
$result
}
@@ -407,7 +408,7 @@ assert_equal 'ok', %q{
}
assert_equal 'ok', %{
- open("zzz.rb", "w") do |f|
+ open("zzz_t2.rb", "w") do |f|
f.puts <<-'end;' # do
begin
m = Thread::Mutex.new
@@ -431,7 +432,7 @@ assert_equal 'ok', %{
end
end;
end
- require "./zzz.rb"
+ require "./zzz_t2.rb"
$result
}
@@ -483,3 +484,17 @@ assert_equal 'foo', %q{
GC.start
f.call.source
}
+assert_normal_exit %q{
+ class C
+ def inspect
+ sleep 0.5
+ 'C!!'
+ end
+ end
+ Thread.new{
+ loop{
+ p C.new
+ }
+ }
+ sleep 0.1
+}, timeout: 5
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
new file mode 100644
index 0000000000..5c655b8f25
--- /dev/null
+++ b/bootstraptest/test_yjit.rb
@@ -0,0 +1,3530 @@
+# Regression test for yielding with autosplat to block with
+# optional parameters. https://github.com/Shopify/yjit/issues/313
+assert_equal '[:a, :b, :a, :b]', %q{
+ def yielder(arg) = yield(arg) + yield(arg)
+
+ yielder([:a, :b]) do |c = :c, d = :d|
+ [c, d]
+ end
+}
+
+# Regression test for GC mishap while doing shape transition
+assert_equal '[:ok]', %q{
+ # [Bug #19601]
+ class RegressionTest
+ def initialize
+ @a = @b = @fourth_ivar_does_shape_transition = nil
+ end
+
+ def extender
+ @first_extended_ivar = [:ok]
+ end
+ end
+
+ GC.stress = true
+
+ # Used to crash due to GC run in rb_ensure_iv_list_size()
+ # not marking the newly allocated [:ok].
+ RegressionTest.new.extender.itself
+}
+
+assert_equal 'true', %q{
+ # regression test for tracking type of locals for too long
+ def local_setting_cmp(five)
+ victim = 5
+ five.define_singleton_method(:respond_to?) do |_, _|
+ victim = nil
+ end
+
+ # +1 makes YJIT track that victim is a number and
+ # defined? calls respond_to? from above indirectly
+ unless (victim + 1) && defined?(five.something)
+ # Would return wrong result if we still think `five` is a number
+ victim.nil?
+ end
+ end
+
+ local_setting_cmp(Object.new)
+ local_setting_cmp(Object.new)
+}
+
+assert_equal '18374962167983112447', %q{
+ # regression test for incorrectly discarding 32 bits of a pointer when it
+ # comes to default values.
+ def large_literal_default(n: 0xff00_fabcafe0_00ff)
+ n
+ end
+
+ def call_graph_root
+ large_literal_default
+ end
+
+ call_graph_root
+ call_graph_root
+}
+
+assert_normal_exit %q{
+ # regression test for a leak caught by an assert on --yjit-call-threshold=2
+ Foo = 1
+
+ eval("def foo = [#{(['Foo,']*256).join}]")
+
+ foo
+ foo
+
+ Object.send(:remove_const, :Foo)
+}
+
+assert_normal_exit %q{
+ # Test to ensure send on overriden c functions
+ # doesn't corrupt the stack
+ class Bar
+ def bar(x)
+ x
+ end
+ end
+
+ class Foo
+ def bar
+ Bar.new
+ end
+ end
+
+ foo = Foo.new
+ # before this change, this line would error
+ # because "s" would still be on the stack
+ # String.to_s is the overridden method here
+ p foo.bar.bar("s".__send__(:to_s))
+}
+
+
+assert_equal '[nil, nil, nil, nil, nil, nil]', %q{
+ [NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass|
+ klass.class_eval("def foo = @foo")
+ end
+
+ [nil, true, false, 0xFABCAFE, 0.42, :cake].map do |instance|
+ instance.foo
+ instance.foo
+ end
+}
+
+assert_equal '0', %q{
+ # This is a regression test for incomplete invalidation from
+ # opt_setinlinecache. This test might be brittle, so
+ # feel free to remove it in the future if it's too annoying.
+ # This test assumes --yjit-call-threshold=2.
+ module M
+ Foo = 1
+ def foo
+ Foo
+ end
+
+ def pin_self_type_then_foo
+ _ = @foo
+ foo
+ end
+
+ def only_ints
+ 1 + self
+ foo
+ end
+ end
+
+ class Integer
+ include M
+ end
+
+ class Sub
+ include M
+ end
+
+ foo_method = M.instance_method(:foo)
+
+ dbg = ->(message) do
+ return # comment this out to get printouts
+
+ $stderr.puts RubyVM::YJIT.disasm(foo_method)
+ $stderr.puts message
+ end
+
+ 2.times { 42.only_ints }
+
+ dbg["There should be two versions of getinlineache"]
+
+ module M
+ remove_const(:Foo)
+ end
+
+ dbg["There should be no getinlinecaches"]
+
+ 2.times do
+ 42.only_ints
+ rescue NameError => err
+ _ = "caught name error #{err}"
+ end
+
+ dbg["There should be one version of getinlineache"]
+
+ 2.times do
+ Sub.new.pin_self_type_then_foo
+ rescue NameError
+ _ = 'second specialization'
+ end
+
+ dbg["There should be two versions of getinlineache"]
+
+ module M
+ Foo = 1
+ end
+
+ dbg["There should still be two versions of getinlineache"]
+
+ 42.only_ints
+
+ dbg["There should be no getinlinecaches"]
+
+ # Find name of the first VM instruction in M#foo.
+ insns = RubyVM::InstructionSequence.of(foo_method).to_a
+ if defined?(RubyVM::YJIT.blocks_for) && (insns.last.find { Array === _1 }&.first == :opt_getinlinecache)
+ RubyVM::YJIT.blocks_for(RubyVM::InstructionSequence.of(foo_method))
+ .filter { _1.iseq_start_index == 0 }.count
+ else
+ 0 # skip the test
+ end
+}
+
+# Check that frozen objects are respected
+assert_equal 'great', %q{
+ class Foo
+ attr_accessor :bar
+ def initialize
+ @bar = 1
+ freeze
+ end
+ end
+
+ foo = Foo.new
+
+ 5.times do
+ begin
+ foo.bar = 2
+ rescue FrozenError
+ end
+ end
+
+ foo.bar == 1 ? "great" : "NG"
+}
+
+# Check that global variable set works
+assert_equal 'string', %q{
+ def foo
+ $foo = "string"
+ end
+
+ foo
+}
+
+# Check that exceptions work when setting global variables
+assert_equal 'rescued', %q{
+ def set_var
+ $var = 100
+ rescue
+ :rescued
+ end
+
+ set_var
+ trace_var(:$var) { raise }
+ set_var
+}
+
+# Check that global variables work
+assert_equal 'string', %q{
+ $foo = "string"
+
+ def foo
+ $foo
+ end
+
+ foo
+}
+
+# Check that exceptions work when getting global variable
+assert_equal 'rescued', %q{
+ Warning[:deprecated] = true
+
+ module Warning
+ def warn(message)
+ raise
+ end
+ end
+
+ def get_var
+ $=
+ rescue
+ :rescued
+ end
+
+ $VERBOSE = true
+ get_var
+ get_var
+}
+
+# Check that global tracepoints work
+assert_equal 'true', %q{
+ def foo
+ 1
+ end
+
+ foo
+ foo
+ foo
+
+ called = false
+
+ tp = TracePoint.new(:return) { |event|
+ if event.method_id == :foo
+ called = true
+ end
+ }
+ tp.enable
+ foo
+ tp.disable
+ called
+}
+
+# Check that local tracepoints work
+assert_equal 'true', %q{
+ def foo
+ 1
+ end
+
+ foo
+ foo
+ foo
+
+ called = false
+
+ tp = TracePoint.new(:return) { |_| called = true }
+ tp.enable(target: method(:foo))
+ foo
+ tp.disable
+ called
+}
+
+# Make sure that optional param methods return the correct value
+assert_equal '1', %q{
+ def m(ary = [])
+ yield(ary)
+ end
+
+ # Warm the JIT with a 0 param call
+ 2.times { m { } }
+ m(1) { |v| v }
+}
+
+# Test for topn
+assert_equal 'array', %q{
+ def threequals(a)
+ case a
+ when Array
+ "array"
+ when Hash
+ "hash"
+ else
+ "unknown"
+ end
+ end
+
+ threequals([])
+ threequals([])
+ threequals([])
+}
+
+# Test for opt_mod
+assert_equal '2', %q{
+ def mod(a, b)
+ a % b
+ end
+
+ mod(7, 5)
+ mod(7, 5)
+}
+
+# Test for opt_mult
+assert_equal '12', %q{
+ def mult(a, b)
+ a * b
+ end
+
+ mult(6, 2)
+ mult(6, 2)
+}
+
+# Test for opt_div
+assert_equal '3', %q{
+ def div(a, b)
+ a / b
+ end
+
+ div(6, 2)
+ div(6, 2)
+}
+
+# BOP redefined methods work when JIT compiled
+assert_equal 'false', %q{
+ def less_than x
+ x < 10
+ end
+
+ class Integer
+ def < x
+ false
+ end
+ end
+
+ less_than 2
+ less_than 2
+ less_than 2
+}
+
+# BOP redefinition works on Integer#<
+assert_equal 'false', %q{
+ def less_than x
+ x < 10
+ end
+
+ less_than 2
+ less_than 2
+
+ class Integer
+ def < x
+ false
+ end
+ end
+
+ less_than 2
+}
+
+# Putobject, less-than operator, fixnums
+assert_equal '2', %q{
+ def check_index(index)
+ if 0x40000000 < index
+ raise "wat? #{index}"
+ end
+ index
+ end
+ check_index 2
+ check_index 2
+}
+
+# foo leaves a temp on the stack before the call
+assert_equal '6', %q{
+ def bar
+ return 5
+ end
+
+ def foo
+ return 1 + bar
+ end
+
+ foo()
+ retval = foo()
+}
+
+# Method with one arguments
+# foo leaves a temp on the stack before the call
+assert_equal '7', %q{
+ def bar(a)
+ return a + 1
+ end
+
+ def foo
+ return 1 + bar(5)
+ end
+
+ foo()
+ retval = foo()
+}
+
+# Method with two arguments
+# foo leaves a temp on the stack before the call
+assert_equal '0', %q{
+ def bar(a, b)
+ return a - b
+ end
+
+ def foo
+ return 1 + bar(1, 2)
+ end
+
+ foo()
+ retval = foo()
+}
+
+# Passing argument types to callees
+assert_equal '8.5', %q{
+ def foo(x, y)
+ x + y
+ end
+
+ def bar
+ foo(7, 1.5)
+ end
+
+ bar
+ bar
+}
+
+# Recursive Ruby-to-Ruby calls
+assert_equal '21', %q{
+ def fib(n)
+ if n < 2
+ return n
+ end
+
+ return fib(n-1) + fib(n-2)
+ end
+
+ r = fib(8)
+}
+
+# Ruby-to-Ruby call and C call
+assert_normal_exit %q{
+ def bar
+ puts('hi!')
+ end
+
+ def foo
+ bar
+ end
+
+ foo()
+ foo()
+}
+
+# Method aliasing
+assert_equal '42', %q{
+ class Foo
+ def method_a
+ 42
+ end
+
+ alias method_b method_a
+
+ def method_a
+ :somethingelse
+ end
+ end
+
+ @obj = Foo.new
+
+ def test
+ @obj.method_b
+ end
+
+ test
+ test
+}
+
+# Method aliasing with method from parent class
+assert_equal '777', %q{
+ class A
+ def method_a
+ 777
+ end
+ end
+
+ class B < A
+ alias method_b method_a
+ end
+
+ @obj = B.new
+
+ def test
+ @obj.method_b
+ end
+
+ test
+ test
+}
+
+# The hash method is a C function and uses the self argument
+assert_equal 'true', %q{
+ def lehashself
+ hash
+ end
+
+ a = lehashself
+ b = lehashself
+ a == b
+}
+
+# Method redefinition (code invalidation) test
+assert_equal '1', %q{
+ def ret1
+ return 1
+ end
+
+ klass = Class.new do
+ def alias_then_hash(klass, method_to_redefine)
+ # Redefine the method to be ret1
+ klass.alias_method(method_to_redefine, :ret1)
+ hash
+ end
+ end
+
+ instance = klass.new
+
+ i = 0
+ while i < 12
+ if i < 11
+ # Redefine the bar method
+ instance.alias_then_hash(klass, :bar)
+ else
+ # Redefine the hash method to be ret1
+ retval = instance.alias_then_hash(klass, :hash)
+ end
+ i += 1
+ end
+
+ retval
+}
+
+# Code invalidation and opt_getinlinecache
+assert_normal_exit %q{
+ class Foo; end
+
+ # Uses the class constant Foo
+ def use_constant(arg)
+ [Foo.new, arg]
+ end
+
+ def propagate_type
+ i = Array.new
+ i.itself # make it remember that i is on-heap
+ use_constant(i)
+ end
+
+ propagate_type
+ propagate_type
+ use_constant(Foo.new)
+ class Jo; end # bump global constant state
+ use_constant(3)
+}
+
+# Method redefinition (code invalidation) and GC
+assert_equal '7', %q{
+ def bar()
+ return 5
+ end
+
+ def foo()
+ bar()
+ end
+
+ foo()
+ foo()
+
+ def bar()
+ return 7
+ end
+
+ 4.times { GC.start }
+
+ foo()
+ foo()
+}
+
+# Method redefinition with two block versions
+assert_equal '7', %q{
+ def bar()
+ return 5
+ end
+
+ def foo(n)
+ return ((n < 5)? 5:false), bar()
+ end
+
+ foo(4)
+ foo(4)
+ foo(10)
+ foo(10)
+
+ def bar()
+ return 7
+ end
+
+ 4.times { GC.start }
+
+ foo(4)
+ foo(4)[1]
+}
+
+# Method redefinition while the method is on the stack
+assert_equal '[777, 1]', %q{
+ def foo
+ redef()
+ 777
+ end
+
+ def redef
+ # Redefine the global foo
+ eval("def foo; 1; end", TOPLEVEL_BINDING)
+
+ # Collect dead code
+ GC.stress = true
+ GC.start
+
+ # But we will return to the original foo,
+ # which remains alive because it's on the stack
+ end
+
+ # Must produce [777, 1]
+ [foo, foo]
+}
+
+# Test for GC safety. Don't invalidate dead iseqs.
+assert_normal_exit %q{
+ Class.new do
+ def foo
+ itself
+ end
+
+ new.foo
+ new.foo
+ new.foo
+ new.foo
+ end
+
+ 4.times { GC.start }
+ def itself
+ self
+ end
+}
+
+# test setinstancevariable on extended objects
+assert_equal '1', %q{
+ class Extended
+ attr_reader :one
+
+ def write_many
+ @a = 1
+ @b = 2
+ @c = 3
+ @d = 4
+ @one = 1
+ end
+ end
+
+ foo = Extended.new
+ foo.write_many
+ foo.write_many
+ foo.write_many
+}
+
+# test setinstancevariable on embedded objects
+assert_equal '1', %q{
+ class Embedded
+ attr_reader :one
+
+ def write_one
+ @one = 1
+ end
+ end
+
+ foo = Embedded.new
+ foo.write_one
+ foo.write_one
+ foo.write_one
+}
+
+# test setinstancevariable after extension
+assert_equal '[10, 11, 12, 13, 1]', %q{
+ class WillExtend
+ attr_reader :one
+
+ def make_extended
+ @foo1 = 10
+ @foo2 = 11
+ @foo3 = 12
+ @foo4 = 13
+ end
+
+ def write_one
+ @one = 1
+ end
+
+ def read_all
+ [@foo1, @foo2, @foo3, @foo4, @one]
+ end
+ end
+
+ foo = WillExtend.new
+ foo.write_one
+ foo.write_one
+ foo.make_extended
+ foo.write_one
+ foo.read_all
+}
+
+# test setinstancevariable on frozen object
+assert_equal 'object was not modified', %q{
+ class WillFreeze
+ def write
+ @ivar = 1
+ end
+ end
+
+ wf = WillFreeze.new
+ wf.write
+ wf.write
+ wf.freeze
+
+ begin
+ wf.write
+ rescue FrozenError
+ "object was not modified"
+ end
+}
+
+# Test getinstancevariable and inline caches
+assert_equal '6', %q{
+ class Foo
+ def initialize
+ @x1 = 1
+ @x2 = 1
+ @x2 = 1
+ @x3 = 1
+ @x4 = 3
+ end
+
+ def bar
+ x = 1
+ @x4 + @x4
+ end
+ end
+
+ f = Foo.new
+ f.bar
+ f.bar
+}
+
+# Test that getinstancevariable codegen checks for extended table size
+assert_equal "nil\n", %q{
+ class A
+ def read
+ @ins1000
+ end
+ end
+
+ ins = A.new
+ other = A.new
+ 10.times { other.instance_variable_set(:"@otr#{_1}", 'value') }
+ 1001.times { ins.instance_variable_set(:"@ins#{_1}", 'value') }
+
+ ins.read
+ ins.read
+ ins.read
+
+ p other.read
+}
+
+# Test that opt_aref checks the class of the receiver
+assert_equal 'special', %q{
+ def foo(array)
+ array[30]
+ end
+
+ foo([])
+ foo([])
+
+ special = []
+ def special.[](idx)
+ 'special'
+ end
+
+ foo(special)
+}
+
+# Test that object references in generated code get marked and moved
+assert_equal "good", %q{
+ def bar
+ "good"
+ end
+
+ def foo
+ bar
+ end
+
+ foo
+ foo
+
+ begin
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+ rescue NotImplementedError
+ # in case compaction isn't supported
+ end
+
+ foo
+}
+
+# Test polymorphic getinstancevariable. T_OBJECT -> T_STRING
+assert_equal 'ok', %q{
+ @hello = @h1 = @h2 = @h3 = @h4 = 'ok'
+ str = ""
+ str.instance_variable_set(:@hello, 'ok')
+
+ public def get
+ @hello
+ end
+
+ get
+ get
+ str.get
+ str.get
+}
+
+# Test polymorphic getinstancevariable, two different classes
+assert_equal 'ok', %q{
+ class Embedded
+ def initialize
+ @ivar = 0
+ end
+
+ def get
+ @ivar
+ end
+ end
+
+ class Extended < Embedded
+ def initialize
+ @v1 = @v2 = @v3 = @v4 = @ivar = 'ok'
+ end
+ end
+
+ embed = Embedded.new
+ extend = Extended.new
+
+ embed.get
+ embed.get
+ extend.get
+ extend.get
+}
+
+# Test megamorphic getinstancevariable
+assert_equal 'ok', %q{
+ parent = Class.new do
+ def initialize
+ @hello = @h1 = @h2 = @h3 = @h4 = 'ok'
+ end
+
+ def get
+ @hello
+ end
+ end
+
+ subclasses = 300.times.map { Class.new(parent) }
+ subclasses.each { _1.new.get }
+ parent.new.get
+}
+
+# Test polymorphic opt_aref. array -> hash
+assert_equal '[42, :key]', %q{
+ def index(obj, idx)
+ obj[idx]
+ end
+
+ index([], 0) # get over compilation threshold
+
+ [
+ index([42], 0),
+ index({0=>:key}, 0),
+ ]
+}
+
+# Test polymorphic opt_aref. hash -> array -> custom class
+assert_equal '[nil, nil, :custom]', %q{
+ def index(obj, idx)
+ obj[idx]
+ end
+
+ custom = Object.new
+ def custom.[](_idx)
+ :custom
+ end
+
+ index({}, 0) # get over compilation threshold
+
+ [
+ index({}, 0),
+ index([], 0),
+ index(custom, 0)
+ ]
+}
+
+# Test polymorphic opt_aref. array -> custom class
+assert_equal '[42, :custom]', %q{
+ def index(obj, idx)
+ obj[idx]
+ end
+
+ custom = Object.new
+ def custom.[](_idx)
+ :custom
+ end
+
+ index([], 0) # get over compilation threshold
+
+ [
+ index([42], 0),
+ index(custom, 0)
+ ]
+}
+
+# Test custom hash method with opt_aref
+assert_equal '[nil, :ok]', %q{
+ def index(obj, idx)
+ obj[idx]
+ end
+
+ custom = Object.new
+ def custom.hash
+ 42
+ end
+
+ h = {custom => :ok}
+
+ [
+ index(h, 0),
+ index(h, custom)
+ ]
+}
+
+# Test default value block for Hash with opt_aref
+assert_equal '[42, :default]', %q{
+ def index(obj, idx)
+ obj[idx]
+ end
+
+ h = Hash.new { :default }
+ h[0] = 42
+
+ [
+ index(h, 0),
+ index(h, 1)
+ ]
+}
+
+# A regression test for making sure cfp->sp is proper when
+# hitting stubs. See :stub-sp-flush:
+assert_equal 'ok', %q{
+ class D
+ def foo
+ Object.new
+ end
+ end
+
+ GC.stress = true
+ 10.times do
+ D.new.foo
+ # ^
+ # This hits a stub with sp_offset > 0
+ end
+
+ :ok
+}
+
+# Test polymorphic callsite, cfunc -> iseq
+assert_equal '[Cfunc, Iseq]', %q{
+ public def call_itself
+ itself # the polymorphic callsite
+ end
+
+ class Cfunc; end
+
+ class Iseq
+ def itself
+ self
+ end
+ end
+
+ call_itself # cross threshold
+
+ [Cfunc.call_itself, Iseq.call_itself]
+}
+
+# Test polymorphic callsite, iseq -> cfunc
+assert_equal '[Iseq, Cfunc]', %q{
+ public def call_itself
+ itself # the polymorphic callsite
+ end
+
+ class Cfunc; end
+
+ class Iseq
+ def itself
+ self
+ end
+ end
+
+ call_itself # cross threshold
+
+ [Iseq.call_itself, Cfunc.call_itself]
+}
+
+# attr_reader method
+assert_equal '[100, 299]', %q{
+ class A
+ attr_reader :foo
+
+ def initialize
+ @foo = 100
+ end
+
+ # Make it extended
+ def fill!
+ @bar = @jojo = @as = @sdfsdf = @foo = 299
+ end
+ end
+
+ def bar(ins)
+ ins.foo
+ end
+
+ ins = A.new
+ oth = A.new
+ oth.fill!
+
+ bar(ins)
+ bar(oth)
+
+ [bar(ins), bar(oth)]
+}
+
+# get ivar on object, then on hash
+assert_equal '[42, 100]', %q{
+ class Hash
+ attr_accessor :foo
+ end
+
+ class A
+ attr_reader :foo
+
+ def initialize
+ @foo = 42
+ end
+ end
+
+ def use(val)
+ val.foo
+ end
+
+
+ h = {}
+ h.foo = 100
+ obj = A.new
+
+ use(obj)
+ [use(obj), use(h)]
+}
+
+# get ivar on String
+assert_equal '[nil, nil, 42, 42]', %q{
+ # @foo to exercise the getinstancevariable instruction
+ public def get_foo
+ @foo
+ end
+
+ get_foo
+ get_foo # compile it for the top level object
+
+ class String
+ attr_reader :foo
+ end
+
+ def run
+ str = String.new
+
+ getter = str.foo
+ insn = str.get_foo
+
+ str.instance_variable_set(:@foo, 42)
+
+ [getter, insn, str.foo, str.get_foo]
+ end
+
+ run
+ run
+}
+
+# splatting an empty array on a getter
+assert_equal '42', %q{
+ @foo = 42
+ module Kernel
+ attr_reader :foo
+ end
+
+ def run
+ foo(*[])
+ end
+
+ run
+ run
+}
+
+# splatting an empty array on a specialized method
+assert_equal 'ok', %q{
+ def run
+ "ok".to_s(*[])
+ end
+
+ run
+ run
+}
+
+# splatting an single element array on a specialized method
+assert_equal '[1]', %q{
+ def run
+ [].<<(*[1])
+ end
+
+ run
+ run
+}
+
+# specialized method with wrong args
+assert_equal 'ok', %q{
+ def run(x)
+ "bad".to_s(123) if x
+ rescue
+ :ok
+ end
+
+ run(false)
+ run(true)
+}
+
+# getinstancevariable on Symbol
+assert_equal '[nil, nil]', %q{
+ # @foo to exercise the getinstancevariable instruction
+ public def get_foo
+ @foo
+ end
+
+ dyn_sym = ("a" + "b").to_sym
+ sym = :static
+
+ # compile get_foo
+ dyn_sym.get_foo
+ dyn_sym.get_foo
+
+ [dyn_sym.get_foo, sym.get_foo]
+}
+
+# attr_reader on Symbol
+assert_equal '[nil, nil]', %q{
+ class Symbol
+ attr_reader :foo
+ end
+
+ public def get_foo
+ foo
+ end
+
+ dyn_sym = ("a" + "b").to_sym
+ sym = :static
+
+ # compile get_foo
+ dyn_sym.get_foo
+ dyn_sym.get_foo
+
+ [dyn_sym.get_foo, sym.get_foo]
+}
+
+# passing too few arguments to method with optional parameters
+assert_equal 'raised', %q{
+ def opt(a, b = 0)
+ end
+
+ def use
+ opt
+ end
+
+ use rescue nil
+ begin
+ use
+ :ng
+ rescue ArgumentError
+ :raised
+ end
+}
+
+# passing too many arguments to method with optional parameters
+assert_equal 'raised', %q{
+ def opt(a, b = 0)
+ end
+
+ def use
+ opt(1, 2, 3, 4)
+ end
+
+ use rescue nil
+ begin
+ use
+ :ng
+ rescue ArgumentError
+ :raised
+ end
+}
+
+# test calling Ruby method with a block
+assert_equal '[1, 2, 42]', %q{
+ def thing(a, b)
+ [a, b, yield]
+ end
+
+ def use
+ thing(1,2) { 42 }
+ end
+
+ use
+ use
+}
+
+# test calling C method with a block
+assert_equal '[42, 42]', %q{
+ def use(array, initial)
+ array.reduce(initial) { |a, b| a + b }
+ end
+
+ use([], 0)
+ [use([2, 2], 38), use([14, 14, 14], 0)]
+}
+
+# test calling block param
+assert_equal '[1, 2, 42]', %q{
+ def foo(&block)
+ block.call
+ end
+
+ [foo {1}, foo {2}, foo {42}]
+}
+
+# test calling without block param
+assert_equal '[1, false, 2, false]', %q{
+ def bar
+ block_given? && yield
+ end
+
+ def foo(&block)
+ bar(&block)
+ end
+
+ [foo { 1 }, foo, foo { 2 }, foo]
+}
+
+# test calling block param failing
+assert_equal '42', %q{
+ def foo(&block)
+ block.call
+ end
+
+ foo {} # warmup
+
+ begin
+ foo
+ rescue NoMethodError => e
+ 42 if nil == e.receiver
+ end
+}
+
+# test calling method taking block param
+assert_equal '[Proc, 1, 2, 3, Proc]', %q{
+ def three(a, b, c, &block)
+ [a, b, c, block.class]
+ end
+
+ def zero(&block)
+ block.class
+ end
+
+ def use_three
+ three(1, 2, 3) {}
+ end
+
+ def use_zero
+ zero {}
+ end
+
+ use_three
+ use_zero
+
+ [use_zero] + use_three
+}
+
+# test building empty array
+assert_equal '[]', %q{
+ def build_arr
+ []
+ end
+
+ build_arr
+ build_arr
+}
+
+# test building array of one element
+assert_equal '[5]', %q{
+ def build_arr(val)
+ [val]
+ end
+
+ build_arr(5)
+ build_arr(5)
+}
+
+# test building array of several element
+assert_equal '[5, 5, 5, 5, 5]', %q{
+ def build_arr(val)
+ [val, val, val, val, val]
+ end
+
+ build_arr(5)
+ build_arr(5)
+}
+
+# test building empty hash
+assert_equal '{}', %q{
+ def build_hash
+ {}
+ end
+
+ build_hash
+ build_hash
+}
+
+# test building hash with values
+assert_equal '{:foo=>:bar}', %q{
+ def build_hash(val)
+ { foo: val }
+ end
+
+ build_hash(:bar)
+ build_hash(:bar)
+}
+
+# test string interpolation with known types
+assert_equal 'foobar', %q{
+ def make_str
+ foo = -"foo"
+ bar = -"bar"
+ "#{foo}#{bar}"
+ end
+
+ make_str
+ make_str
+}
+
+# test string interpolation with unknown types
+assert_equal 'foobar', %q{
+ def make_str(foo, bar)
+ "#{foo}#{bar}"
+ end
+
+ make_str("foo", "bar")
+ make_str("foo", "bar")
+}
+
+# test string interpolation with known non-strings
+assert_equal 'foo123', %q{
+ def make_str
+ foo = -"foo"
+ bar = 123
+ "#{foo}#{bar}"
+ end
+
+ make_str
+ make_str
+}
+
+# test string interpolation with unknown non-strings
+assert_equal 'foo123', %q{
+ def make_str(foo, bar)
+ "#{foo}#{bar}"
+ end
+
+ make_str("foo", 123)
+ make_str("foo", 123)
+}
+
+# test that invalidation of String#to_s doesn't crash
+assert_equal 'meh', %q{
+ def inval_method
+ "".to_s
+ end
+
+ inval_method
+
+ class String
+ def to_s
+ "meh"
+ end
+ end
+
+ inval_method
+}
+
+# test that overriding to_s on a String subclass works consistently
+assert_equal 'meh', %q{
+ class MyString < String
+ def to_s
+ "meh"
+ end
+ end
+
+ def test_to_s(obj)
+ obj.to_s
+ end
+
+ OBJ = MyString.new
+
+ # Should return '' both times
+ test_to_s("")
+ test_to_s("")
+
+ # Can return '' if YJIT optimises String#to_s too aggressively
+ test_to_s(OBJ)
+ test_to_s(OBJ)
+}
+
+# test string interpolation with overridden to_s
+assert_equal 'foo', %q{
+ class String
+ def to_s
+ "bad"
+ end
+ end
+
+ def make_str(foo)
+ "#{foo}"
+ end
+
+ make_str("foo")
+ make_str("foo")
+}
+
+# Test that String unary plus returns the same object ID for an unfrozen string.
+assert_equal 'true', %q{
+ def jittable_method
+ str = "bar"
+
+ old_obj_id = str.object_id
+ uplus_str = +str
+
+ uplus_str.object_id == old_obj_id
+ end
+ jittable_method
+}
+
+# Test that String unary plus returns a different unfrozen string when given a frozen string
+assert_equal 'false', %q{
+ # Logic needs to be inside an ISEQ, such as a method, for YJIT to compile it
+ def jittable_method
+ frozen_str = "foo".freeze
+
+ old_obj_id = frozen_str.object_id
+ uplus_str = +frozen_str
+
+ uplus_str.object_id == old_obj_id || uplus_str.frozen?
+ end
+
+ jittable_method
+}
+
+# String-subclass objects should behave as expected inside string-interpolation via concatstrings
+assert_equal 'monkeys / monkeys, yo!', %q{
+ class MyString < String
+ # This is a terrible idea in production code, but we'd like YJIT to match CRuby
+ def to_s
+ super + ", yo!"
+ end
+ end
+
+ def jittable_method
+ m = MyString.new('monkeys')
+ "#{m} / #{m.to_s}"
+ end
+
+ jittable_method
+}
+
+# String-subclass objects should behave as expected for string equality
+assert_equal 'false', %q{
+ class MyString < String
+ # This is a terrible idea in production code, but we'd like YJIT to match CRuby
+ def ==(b)
+ "#{self}_" == b
+ end
+ end
+
+ def jittable_method
+ ma = MyString.new("a")
+
+ # Check equality with string-subclass receiver
+ ma == "a" || ma != "a_" ||
+ # Check equality with string receiver
+ "a_" == ma || "a" != ma ||
+ # Check equality between string subclasses
+ ma != MyString.new("a_") ||
+ # Make sure "string always equals itself" check isn't used with overridden equality
+ ma == ma
+ end
+ jittable_method
+}
+
+# Test to_s duplicates a string subclass object but not a string
+assert_equal 'false', %q{
+ class MyString < String; end
+
+ def jittable_method
+ a = "a"
+ ma = MyString.new("a")
+
+ a.object_id != a.to_s.object_id ||
+ ma.object_id == ma.to_s.object_id
+ end
+ jittable_method
+}
+
+# Test freeze on string subclass
+assert_equal 'true', %q{
+ class MyString < String; end
+
+ def jittable_method
+ fma = MyString.new("a").freeze
+
+ # Freezing a string subclass should not duplicate it
+ fma.object_id == fma.freeze.object_id
+ end
+ jittable_method
+}
+
+# Test unary minus on string subclass
+assert_equal 'true', %q{
+ class MyString < String; end
+
+ def jittable_method
+ ma = MyString.new("a")
+ fma = MyString.new("a").freeze
+
+ # Unary minus on frozen string subclass should not duplicate it
+ fma.object_id == (-fma).object_id &&
+ # Unary minus on unfrozen string subclass should duplicate it
+ ma.object_id != (-ma).object_id
+ end
+ jittable_method
+}
+
+# Test unary plus on string subclass
+assert_equal 'true', %q{
+ class MyString < String; end
+
+ def jittable_method
+ fma = MyString.new("a").freeze
+
+ # Unary plus on frozen string subclass should not duplicate it
+ fma.object_id != (+fma).object_id
+ end
+ jittable_method
+}
+
+# Test << operator on string subclass
+assert_equal 'abab', %q{
+ class MyString < String; end
+
+ def jittable_method
+ a = -"a"
+ mb = MyString.new("b")
+
+ buf = String.new
+ mbuf = MyString.new
+
+ buf << a << mb
+ mbuf << a << mb
+
+ buf + mbuf
+ end
+ jittable_method
+}
+
+# test invokebuiltin as used in struct assignment
+assert_equal '123', %q{
+ def foo(obj)
+ obj.foo = 123
+ end
+
+ struct = Struct.new(:foo)
+ obj = struct.new
+ foo(obj)
+ foo(obj)
+}
+
+# test invokebuiltin_delegate as used inside Dir.open
+assert_equal '.', %q{
+ def foo(path)
+ Dir.open(path).path
+ end
+
+ foo(".")
+ foo(".")
+}
+
+# test invokebuiltin_delegate_leave in method called from jit
+assert_normal_exit %q{
+ def foo(obj)
+ obj.clone
+ end
+
+ foo(Object.new)
+ foo(Object.new)
+}
+
+# test invokebuiltin_delegate_leave in method called from cfunc
+assert_normal_exit %q{
+ def foo(obj)
+ [obj].map(&:clone)
+ end
+
+ foo(Object.new)
+ foo(Object.new)
+}
+
+# defining TrueClass#!
+assert_equal '[false, false, :ok]', %q{
+ def foo(obj)
+ !obj
+ end
+
+ x = foo(true)
+ y = foo(true)
+
+ class TrueClass
+ def !
+ :ok
+ end
+ end
+
+ z = foo(true)
+
+ [x, y, z]
+}
+
+# defining FalseClass#!
+assert_equal '[true, true, :ok]', %q{
+ def foo(obj)
+ !obj
+ end
+
+ x = foo(false)
+ y = foo(false)
+
+ class FalseClass
+ def !
+ :ok
+ end
+ end
+
+ z = foo(false)
+
+ [x, y, z]
+}
+
+# defining NilClass#!
+assert_equal '[true, true, :ok]', %q{
+ def foo(obj)
+ !obj
+ end
+
+ x = foo(nil)
+ y = foo(nil)
+
+ class NilClass
+ def !
+ :ok
+ end
+ end
+
+ z = foo(nil)
+
+ [x, y, z]
+}
+
+# polymorphic opt_not
+assert_equal '[true, true, false, false, false, false, false]', %q{
+ def foo(obj)
+ !obj
+ end
+
+ foo(0)
+ [foo(nil), foo(false), foo(true), foo([]), foo(0), foo(4.2), foo(:sym)]
+}
+
+# getlocal with 2 levels
+assert_equal '7', %q{
+ def foo(foo, bar)
+ while foo > 0
+ while bar > 0
+ return foo + bar
+ end
+ end
+ end
+
+ foo(5,2)
+ foo(5,2)
+}
+
+# test pattern matching
+assert_equal '[:ok, :ok]', %q{
+ class C
+ def destructure_keys
+ {}
+ end
+ end
+
+ pattern_match = ->(i) do
+ case i
+ in a: 0
+ :ng
+ else
+ :ok
+ end
+ end
+
+ [{}, C.new].map(&pattern_match)
+}
+
+# Call to object with singleton
+assert_equal '123', %q{
+ obj = Object.new
+ def obj.foo
+ 123
+ end
+
+ def foo(obj)
+ obj.foo()
+ end
+
+ foo(obj)
+ foo(obj)
+}
+
+# Call method on an object that has a non-material
+# singleton class.
+# TODO: assert that it takes no side exits? This
+# test case revealed that we were taking exits unnecessarily.
+assert_normal_exit %q{
+ def foo(obj)
+ obj.itself
+ end
+
+ o = Object.new.singleton_class
+ foo(o)
+ foo(o)
+}
+
+# Call to singleton class
+assert_equal '123', %q{
+ class Foo
+ def self.foo
+ 123
+ end
+ end
+
+ def foo(obj)
+ obj.foo()
+ end
+
+ foo(Foo)
+ foo(Foo)
+}
+
+# invokesuper edge case
+assert_equal '[:A, [:A, :B]]', %q{
+ class B
+ def foo = :B
+ end
+
+ class A < B
+ def foo = [:A, super()]
+ end
+
+ A.new.foo
+ A.new.foo # compile A#foo
+
+ class C < A
+ define_method(:bar, A.instance_method(:foo))
+ end
+
+ C.new.bar
+}
+
+# Same invokesuper bytecode, multiple destinations
+assert_equal '[:Forward, :SecondTerminus]', %q{
+ module Terminus
+ def foo = :Terminus
+ end
+
+ module SecondTerminus
+ def foo = :SecondTerminus
+ end
+
+
+ module Forward
+ def foo = [:Forward, super]
+ end
+
+ class B
+ include SecondTerminus
+ end
+
+ class A < B
+ include Terminus
+ include Forward
+ end
+
+ A.new.foo
+ A.new.foo # compile
+
+ class B
+ include Forward
+ alias bar foo
+ end
+
+ # A.ancestors.take(5) == [A, Forward, Terminus, B, Forward, SecondTerminus]
+
+ A.new.bar
+}
+
+# invokesuper calling into itself
+assert_equal '[:B, [:B, :m]]', %q{
+ module M
+ def foo = :m
+ end
+
+ class B
+ include M
+ def foo = [:B, super]
+ end
+
+ ins = B.new
+ ins.singleton_class # materialize the singleton class
+ ins.foo
+ ins.foo # compile
+
+ ins.singleton_class.define_method(:bar, B.instance_method(:foo))
+ ins.bar
+}
+
+# invokesuper changed ancestor
+assert_equal '[:A, [:M, :B]]', %q{
+ class B
+ def foo
+ :B
+ end
+ end
+
+ class A < B
+ def foo
+ [:A, super]
+ end
+ end
+
+ module M
+ def foo
+ [:M, super]
+ end
+ end
+
+ ins = A.new
+ ins.foo
+ ins.foo
+ A.include(M)
+ ins.foo
+}
+
+# invokesuper changed ancestor via prepend
+assert_equal '[:A, [:M, :B]]', %q{
+ class B
+ def foo
+ :B
+ end
+ end
+
+ class A < B
+ def foo
+ [:A, super]
+ end
+ end
+
+ module M
+ def foo
+ [:M, super]
+ end
+ end
+
+ ins = A.new
+ ins.foo
+ ins.foo
+ B.prepend(M)
+ ins.foo
+}
+
+# invokesuper replaced method
+assert_equal '[:A, :Btwo]', %q{
+ class B
+ def foo
+ :B
+ end
+ end
+
+ class A < B
+ def foo
+ [:A, super]
+ end
+ end
+
+ ins = A.new
+ ins.foo
+ ins.foo
+ class B
+ def foo
+ :Btwo
+ end
+ end
+ ins.foo
+}
+
+# Call to fixnum
+assert_equal '[true, false]', %q{
+ def is_odd(obj)
+ obj.odd?
+ end
+
+ is_odd(1)
+ is_odd(1)
+
+ [is_odd(123), is_odd(456)]
+}
+
+# Call to bignum
+assert_equal '[true, false]', %q{
+ def is_odd(obj)
+ obj.odd?
+ end
+
+ bignum = 99999999999999999999
+ is_odd(bignum)
+ is_odd(bignum)
+
+ [is_odd(bignum), is_odd(bignum+1)]
+}
+
+# Call to fixnum and bignum
+assert_equal '[true, false, true, false]', %q{
+ def is_odd(obj)
+ obj.odd?
+ end
+
+ bignum = 99999999999999999999
+ is_odd(bignum)
+ is_odd(bignum)
+ is_odd(123)
+ is_odd(123)
+
+ [is_odd(123), is_odd(456), is_odd(bignum), is_odd(bignum+1)]
+}
+
+# Call to static and dynamic symbol
+assert_equal 'bar', %q{
+ def to_string(obj)
+ obj.to_s
+ end
+
+ to_string(:foo)
+ to_string(:foo)
+ to_string((-"bar").to_sym)
+ to_string((-"bar").to_sym)
+}
+
+# Call to flonum and heap float
+assert_equal '[nil, nil, nil, 1]', %q{
+ def is_inf(obj)
+ obj.infinite?
+ end
+
+ is_inf(0.0)
+ is_inf(0.0)
+ is_inf(1e256)
+ is_inf(1e256)
+
+ [
+ is_inf(0.0),
+ is_inf(1.0),
+ is_inf(1e256),
+ is_inf(1.0/0.0)
+ ]
+}
+
+assert_equal '[1, 2, 3, 4, 5]', %q{
+ def splatarray
+ [*(1..5)]
+ end
+
+ splatarray
+ splatarray
+}
+
+assert_equal '[1, 1, 2, 1, 2, 3]', %q{
+ def expandarray
+ arr = [1, 2, 3]
+
+ a, = arr
+ b, c, = arr
+ d, e, f = arr
+
+ [a, b, c, d, e, f]
+ end
+
+ expandarray
+ expandarray
+}
+
+assert_equal '[1, 1]', %q{
+ def expandarray_useless_splat
+ arr = (1..10).to_a
+
+ a, * = arr
+ b, (*) = arr
+
+ [a, b]
+ end
+
+ expandarray_useless_splat
+ expandarray_useless_splat
+}
+
+assert_equal '[:not_heap, nil, nil]', %q{
+ def expandarray_not_heap
+ a, b, c = :not_heap
+ [a, b, c]
+ end
+
+ expandarray_not_heap
+ expandarray_not_heap
+}
+
+assert_equal '[:not_array, nil, nil]', %q{
+ def expandarray_not_array(obj)
+ a, b, c = obj
+ [a, b, c]
+ end
+
+ obj = Object.new
+ def obj.to_ary
+ [:not_array]
+ end
+
+ expandarray_not_array(obj)
+ expandarray_not_array(obj)
+}
+
+assert_equal '[1, 2, nil]', %q{
+ def expandarray_rhs_too_small
+ a, b, c = [1, 2]
+ [a, b, c]
+ end
+
+ expandarray_rhs_too_small
+ expandarray_rhs_too_small
+}
+
+assert_equal '[1, [2]]', %q{
+ def expandarray_splat
+ a, *b = [1, 2]
+ [a, b]
+ end
+
+ expandarray_splat
+ expandarray_splat
+}
+
+assert_equal '2', %q{
+ def expandarray_postarg
+ *, a = [1, 2]
+ a
+ end
+
+ expandarray_postarg
+ expandarray_postarg
+}
+
+assert_equal '10', %q{
+ obj = Object.new
+ val = nil
+ obj.define_singleton_method(:to_ary) { val = 10; [] }
+
+ def expandarray_always_call_to_ary(object)
+ * = object
+ end
+
+ expandarray_always_call_to_ary(obj)
+ expandarray_always_call_to_ary(obj)
+
+ val
+}
+
+# regression test of local type change
+assert_equal '1.1', %q{
+def bar(baz, quux)
+ if baz.integer?
+ baz, quux = quux, nil
+ end
+ baz.to_s
+end
+
+bar(123, 1.1)
+bar(123, 1.1)
+}
+
+# test enabling a line TracePoint in a C method call
+assert_equal '[[:line, true]]', %q{
+ events = []
+ events.instance_variable_set(
+ :@tp,
+ TracePoint.new(:line) { |tp| events << [tp.event, tp.lineno] if tp.path == __FILE__ }
+ )
+ def events.to_str
+ @tp.enable; ''
+ end
+
+ # Stay in generated code while enabling tracing
+ def events.compiled(obj)
+ String(obj)
+ @tp.disable; __LINE__
+ end
+
+ line = events.compiled(events)
+ events[0][-1] = (events[0][-1] == line)
+
+ events
+}
+
+# test enabling a c_return TracePoint in a C method call
+assert_equal '[[:c_return, :String, :string_alias, "events_to_str"]]', %q{
+ events = []
+ events.instance_variable_set(:@tp, TracePoint.new(:c_return) { |tp| events << [tp.event, tp.method_id, tp.callee_id, tp.return_value] })
+ def events.to_str
+ @tp.enable; 'events_to_str'
+ end
+
+ # Stay in generated code while enabling tracing
+ alias string_alias String
+ def events.compiled(obj)
+ string_alias(obj)
+ @tp.disable
+ end
+
+ events.compiled(events)
+
+ events
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
+
+# test enabling a TracePoint that targets a particular line in a C method call
+assert_equal '[true]', %q{
+ events = []
+ events.instance_variable_set(:@tp, TracePoint.new(:line) { |tp| events << tp.lineno })
+ def events.to_str
+ @tp.enable(target: method(:compiled))
+ ''
+ end
+
+ # Stay in generated code while enabling tracing
+ def events.compiled(obj)
+ String(obj)
+ __LINE__
+ end
+
+ line = events.compiled(events)
+ events[0] = (events[0] == line)
+
+ events
+}
+
+# test enabling tracing in the middle of splatarray
+assert_equal '[true]', %q{
+ events = []
+ obj = Object.new
+ obj.instance_variable_set(:@tp, TracePoint.new(:line) { |tp| events << tp.lineno })
+ def obj.to_a
+ @tp.enable(target: method(:compiled))
+ []
+ end
+
+ # Enable tracing in the middle of the splatarray instruction
+ def obj.compiled(obj)
+ * = *obj
+ __LINE__
+ end
+
+ obj.compiled([])
+ line = obj.compiled(obj)
+ events[0] = (events[0] == line)
+
+ events
+}
+
+# test enabling tracing in the middle of opt_aref. Different since the codegen
+# for it ends in a jump.
+assert_equal '[true]', %q{
+ def lookup(hash, tp)
+ hash[42]
+ tp.disable; __LINE__
+ end
+
+ lines = []
+ tp = TracePoint.new(:line) { lines << _1.lineno if _1.path == __FILE__ }
+
+ lookup(:foo, tp)
+ lookup({}, tp)
+
+ enable_tracing_on_missing = Hash.new { tp.enable }
+
+ expected_line = lookup(enable_tracing_on_missing, tp)
+
+ lines[0] = true if lines[0] == expected_line
+
+ lines
+}
+
+# test enabling c_call tracing before compiling
+assert_equal '[[:c_call, :itself]]', %q{
+ def shouldnt_compile
+ itself
+ end
+
+ events = []
+ tp = TracePoint.new(:c_call) { |tp| events << [tp.event, tp.method_id] }
+
+ # assume first call compiles
+ tp.enable { shouldnt_compile }
+
+ events
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
+
+# test enabling c_return tracing before compiling
+assert_equal '[[:c_return, :itself, main]]', %q{
+ def shouldnt_compile
+ itself
+ end
+
+ events = []
+ tp = TracePoint.new(:c_return) { |tp| events << [tp.event, tp.method_id, tp.return_value] }
+
+ # assume first call compiles
+ tp.enable { shouldnt_compile }
+
+ events
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
+
+# test c_call invalidation
+assert_equal '[[:c_call, :itself]]', %q{
+ # enable the event once to make sure invalidation
+ # happens the second time we enable it
+ TracePoint.new(:c_call) {}.enable{}
+
+ def compiled
+ itself
+ end
+
+ # assume first call compiles
+ compiled
+
+ events = []
+ tp = TracePoint.new(:c_call) { |tp| events << [tp.event, tp.method_id] }
+ tp.enable { compiled }
+
+ events
+}
+
+# test enabling tracing for a suspended fiber
+assert_equal '[[:return, 42]]', %q{
+ def traced_method
+ Fiber.yield
+ 42
+ end
+
+ events = []
+ tp = TracePoint.new(:return) { events << [_1.event, _1.return_value] }
+ # assume first call compiles
+ fiber = Fiber.new { traced_method }
+ fiber.resume
+ tp.enable(target: method(:traced_method))
+ fiber.resume
+
+ events
+}
+
+# test compiling on non-tracing ractor then running on a tracing one
+assert_equal '[:itself]', %q{
+ def traced_method
+ itself
+ end
+
+ tracing_ractor = Ractor.new do
+ # 1: start tracing
+ events = []
+ tp = TracePoint.new(:c_call) { events << _1.method_id }
+ tp.enable
+ Ractor.yield(nil)
+
+ # 3: run compiled method on tracing ractor
+ Ractor.yield(nil)
+ traced_method
+
+ events
+ ensure
+ tp&.disable
+ end
+
+ tracing_ractor.take
+
+ # 2: compile on non tracing ractor
+ traced_method
+
+ tracing_ractor.take
+ tracing_ractor.take
+}
+
+# Try to hit a lazy branch stub while another ractor enables tracing
+assert_equal '42', %q{
+ def compiled(arg)
+ if arg
+ arg + 1
+ else
+ itself
+ itself
+ end
+ end
+
+ ractor = Ractor.new do
+ compiled(false)
+ Ractor.yield(nil)
+ compiled(41)
+ end
+
+ tp = TracePoint.new(:line) { itself }
+ ractor.take
+ tp.enable
+
+ ractor.take
+}
+
+# Test equality with changing types
+assert_equal '[true, false, false, false]', %q{
+ def eq(a, b)
+ a == b
+ end
+
+ [
+ eq("foo", "foo"),
+ eq("foo", "bar"),
+ eq(:foo, "bar"),
+ eq("foo", :bar)
+ ]
+}
+
+# Redefined String eq
+assert_equal 'true', %q{
+ class String
+ def ==(other)
+ true
+ end
+ end
+
+ def eq(a, b)
+ a == b
+ end
+
+ eq("foo", "bar")
+ eq("foo", "bar")
+}
+
+# Redefined Integer eq
+assert_equal 'true', %q{
+ class Integer
+ def ==(other)
+ true
+ end
+ end
+
+ def eq(a, b)
+ a == b
+ end
+
+ eq(1, 2)
+ eq(1, 2)
+}
+
+# aset on array with invalid key
+assert_normal_exit %q{
+ def foo(arr)
+ arr[:foo] = 123
+ end
+
+ foo([1]) rescue nil
+ foo([1]) rescue nil
+}
+
+# test ractor exception on when setting ivar
+assert_equal '42', %q{
+ class A
+ def self.foo
+ _foo = 1
+ _bar = 2
+ begin
+ @bar = _foo + _bar
+ rescue Ractor::IsolationError
+ 42
+ end
+ end
+ end
+
+ A.foo
+ A.foo
+
+ Ractor.new { A.foo }.take
+}
+
+assert_equal '["plain", "special", "sub", "plain"]', %q{
+ def foo(arg)
+ arg.to_s
+ end
+
+ class Sub < String
+ end
+
+ special = String.new("special")
+ special.singleton_class
+
+ [
+ foo("plain"),
+ foo(special),
+ foo(Sub.new("sub")),
+ foo("plain")
+ ]
+}
+
+assert_equal '["sub", "sub"]', %q{
+ def foo(arg)
+ arg.to_s
+ end
+
+ class Sub < String
+ def to_s
+ super
+ end
+ end
+
+ sub = Sub.new("sub")
+
+ [foo(sub), foo(sub)]
+}
+
+assert_equal '[1]', %q{
+ def kwargs(value:)
+ value
+ end
+
+ 5.times.map { kwargs(value: 1) }.uniq
+}
+
+assert_equal '[:ok]', %q{
+ def kwargs(value:)
+ value
+ end
+
+ 5.times.map { kwargs() rescue :ok }.uniq
+}
+
+assert_equal '[:ok]', %q{
+ def kwargs(a:, b: nil)
+ value
+ end
+
+ 5.times.map { kwargs(b: 123) rescue :ok }.uniq
+}
+
+assert_equal '[[1, 2]]', %q{
+ def kwargs(left:, right:)
+ [left, right]
+ end
+
+ 5.times.flat_map do
+ [
+ kwargs(left: 1, right: 2),
+ kwargs(right: 2, left: 1)
+ ]
+ end.uniq
+}
+
+assert_equal '[[1, 2]]', %q{
+ def kwargs(lead, kwarg:)
+ [lead, kwarg]
+ end
+
+ 5.times.map { kwargs(1, kwarg: 2) }.uniq
+}
+
+# optional and keyword args
+assert_equal '[[1, 2, 3]]', %q{
+ def opt_and_kwargs(a, b=2, c: nil)
+ [a,b,c]
+ end
+
+ 5.times.map { opt_and_kwargs(1, c: 3) }.uniq
+}
+
+assert_equal '[[1, 2, 3]]', %q{
+ def opt_and_kwargs(a, b=nil, c: nil)
+ [a,b,c]
+ end
+
+ 5.times.map { opt_and_kwargs(1, 2, c: 3) }.uniq
+}
+
+# Bug #18453
+assert_equal '[[1, nil, 2]]', %q{
+ def opt_and_kwargs(a = {}, b: nil, c: nil)
+ [a, b, c]
+ end
+
+ 5.times.map { opt_and_kwargs(1, c: 2) }.uniq
+}
+
+assert_equal '[[{}, nil, 1]]', %q{
+ def opt_and_kwargs(a = {}, b: nil, c: nil)
+ [a, b, c]
+ end
+
+ 5.times.map { opt_and_kwargs(c: 1) }.uniq
+}
+
+# leading and keyword arguments are swapped into the right order
+assert_equal '[[1, 2, 3, 4, 5, 6]]', %q{
+ def kwargs(five, six, a:, b:, c:, d:)
+ [a, b, c, d, five, six]
+ end
+
+ 5.times.flat_map do
+ [
+ kwargs(5, 6, a: 1, b: 2, c: 3, d: 4),
+ kwargs(5, 6, a: 1, b: 2, d: 4, c: 3),
+ kwargs(5, 6, a: 1, c: 3, b: 2, d: 4),
+ kwargs(5, 6, a: 1, c: 3, d: 4, b: 2),
+ kwargs(5, 6, a: 1, d: 4, b: 2, c: 3),
+ kwargs(5, 6, a: 1, d: 4, c: 3, b: 2),
+ kwargs(5, 6, b: 2, a: 1, c: 3, d: 4),
+ kwargs(5, 6, b: 2, a: 1, d: 4, c: 3),
+ kwargs(5, 6, b: 2, c: 3, a: 1, d: 4),
+ kwargs(5, 6, b: 2, c: 3, d: 4, a: 1),
+ kwargs(5, 6, b: 2, d: 4, a: 1, c: 3),
+ kwargs(5, 6, b: 2, d: 4, c: 3, a: 1),
+ kwargs(5, 6, c: 3, a: 1, b: 2, d: 4),
+ kwargs(5, 6, c: 3, a: 1, d: 4, b: 2),
+ kwargs(5, 6, c: 3, b: 2, a: 1, d: 4),
+ kwargs(5, 6, c: 3, b: 2, d: 4, a: 1),
+ kwargs(5, 6, c: 3, d: 4, a: 1, b: 2),
+ kwargs(5, 6, c: 3, d: 4, b: 2, a: 1),
+ kwargs(5, 6, d: 4, a: 1, b: 2, c: 3),
+ kwargs(5, 6, d: 4, a: 1, c: 3, b: 2),
+ kwargs(5, 6, d: 4, b: 2, a: 1, c: 3),
+ kwargs(5, 6, d: 4, b: 2, c: 3, a: 1),
+ kwargs(5, 6, d: 4, c: 3, a: 1, b: 2),
+ kwargs(5, 6, d: 4, c: 3, b: 2, a: 1)
+ ]
+ end.uniq
+}
+
+# implicit hashes get skipped and don't break compilation
+assert_equal '[[:key]]', %q{
+ def implicit(hash)
+ hash.keys
+ end
+
+ 5.times.map { implicit(key: :value) }.uniq
+}
+
+# default values on keywords don't mess up argument order
+assert_equal '[2]', %q{
+ def default_value
+ 1
+ end
+
+ def default_expression(value: default_value)
+ value
+ end
+
+ 5.times.map { default_expression(value: 2) }.uniq
+}
+
+# constant default values on keywords
+assert_equal '[3]', %q{
+ def default_expression(value: 3)
+ value
+ end
+
+ 5.times.map { default_expression }.uniq
+}
+
+# non-constant default values on keywords
+assert_equal '[3]', %q{
+ def default_value
+ 3
+ end
+
+ def default_expression(value: default_value)
+ value
+ end
+
+ 5.times.map { default_expression }.uniq
+}
+
+# reordered optional kwargs
+assert_equal '[[100, 1]]', %q{
+ def foo(capacity: 100, max: nil)
+ [capacity, max]
+ end
+
+ 5.times.map { foo(max: 1) }.uniq
+}
+
+# invalid lead param
+assert_equal 'ok', %q{
+ def bar(baz: 2)
+ baz
+ end
+
+ def foo
+ bar(1, baz: 123)
+ end
+
+ begin
+ foo
+ foo
+ rescue ArgumentError => e
+ print "ok"
+ end
+}
+
+# reordered required kwargs
+assert_equal '[[1, 2, 3, 4]]', %q{
+ def foo(default1: 1, required1:, default2: 3, required2:)
+ [default1, required1, default2, required2]
+ end
+
+ 5.times.map { foo(required1: 2, required2: 4) }.uniq
+}
+
+# reordered default expression kwargs
+assert_equal '[[:one, :two, 3]]', %q{
+ def foo(arg1: (1+0), arg2: (2+0), arg3: (3+0))
+ [arg1, arg2, arg3]
+ end
+
+ 5.times.map { foo(arg2: :two, arg1: :one) }.uniq
+}
+
+# complex kwargs
+assert_equal '[[1, 2, 3, 4]]', %q{
+ def foo(required:, specified: 999, simple_default: 3, complex_default: "4".to_i)
+ [required, specified, simple_default, complex_default]
+ end
+
+ 5.times.map { foo(specified: 2, required: 1) }.uniq
+}
+
+# cfunc kwargs
+assert_equal '{:foo=>123}', %q{
+ def foo(bar)
+ bar.store(:value, foo: 123)
+ bar[:value]
+ end
+
+ foo({})
+ foo({})
+}
+
+# cfunc kwargs
+assert_equal '{:foo=>123}', %q{
+ def foo(bar)
+ bar.replace(foo: 123)
+ end
+
+ foo({})
+ foo({})
+}
+
+# cfunc kwargs
+assert_equal '{:foo=>123, :bar=>456}', %q{
+ def foo(bar)
+ bar.replace(foo: 123, bar: 456)
+ end
+
+ foo({})
+ foo({})
+}
+
+# variadic cfunc kwargs
+assert_equal '{:foo=>123}', %q{
+ def foo(bar)
+ bar.merge(foo: 123)
+ end
+
+ foo({})
+ foo({})
+}
+
+# optimized cfunc kwargs
+assert_equal 'false', %q{
+ def foo
+ :foo.eql?(foo: :foo)
+ end
+
+ foo
+ foo
+}
+
+# attr_reader on frozen object
+assert_equal 'false', %q{
+ class Foo
+ attr_reader :exception
+
+ def failed?
+ !exception.nil?
+ end
+ end
+
+ foo = Foo.new.freeze
+ foo.failed?
+ foo.failed?
+}
+
+# regression test for doing kwarg shuffle before checking for interrupts
+assert_equal 'ok', %q{
+ def new_media_drop(attributes:, product_drop:, context:, sources:)
+ nil.nomethod rescue nil # force YJIT to bail to side exit
+
+ [attributes, product_drop, context, sources]
+ end
+
+ def load_medias(product_drop: nil, raw_medias:, context:)
+ raw_medias.map do |raw_media|
+ case new_media_drop(context: context, attributes: raw_media, product_drop: product_drop, sources: [])
+ in [Hash, ProductDrop, Context, Array]
+ else
+ raise "bad shuffle"
+ end
+ end
+ end
+
+ class Context; end
+
+ class ProductDrop
+ attr_reader :title
+ def initialize(title)
+ @title = title
+ end
+ end
+
+ # Make a thread so we have thread switching interrupts
+ th = Thread.new do
+ while true; end
+ end
+ 1_000.times do |i|
+ load_medias(product_drop: ProductDrop.new("foo"), raw_medias: [{}, {}], context: Context.new)
+ end
+ th.kill.join
+
+ :ok
+}
+
+# regression test for tracing attr_accessor methods.
+assert_equal "true", %q{
+ c = Class.new do
+ attr_accessor :x
+ alias y x
+ alias y= x=
+ end
+ obj = c.new
+
+ ar_meth = obj.method(:x)
+ aw_meth = obj.method(:x=)
+ aar_meth = obj.method(:y)
+ aaw_meth = obj.method(:y=)
+ events = []
+ trace = TracePoint.new(:c_call, :c_return){|tp|
+ next if tp.path != __FILE__
+ next if tp.method_id == :call
+ case tp.event
+ when :c_call
+ events << [tp.event, tp.method_id, tp.callee_id]
+ when :c_return
+ events << [tp.event, tp.method_id, tp.callee_id, tp.return_value]
+ end
+ }
+ test_proc = proc do
+ obj.x = 1
+ obj.x
+ obj.y = 2
+ obj.y
+ aw_meth.call(1)
+ ar_meth.call
+ aaw_meth.call(2)
+ aar_meth.call
+ end
+ test_proc.call # populate call caches
+ trace.enable(&test_proc)
+ expected = [
+ [:c_call, :x=, :x=],
+ [:c_return, :x=, :x=, 1],
+ [:c_call, :x, :x],
+ [:c_return, :x, :x, 1],
+ [:c_call, :x=, :y=],
+ [:c_return, :x=, :y=, 2],
+ [:c_call, :x, :y],
+ [:c_return, :x, :y, 2],
+ ] * 2
+
+ expected == events
+}
+
+# duphash
+assert_equal '{:foo=>123}', %q{
+ def foo
+ {foo: 123}
+ end
+
+ foo
+ foo
+}
+
+# newhash
+assert_equal '{:foo=>2}', %q{
+ def foo
+ {foo: 1+1}
+ end
+
+ foo
+ foo
+}
+
+# block invalidation edge case
+assert_equal 'undef', %q{
+ class A
+ def foo(arg)
+ arg.times { A.remove_method(:bar) }
+ self
+ end
+
+ def bar
+ 4
+ end
+
+ def use(arg)
+ # two consecutive sends. When bar is removed, the return address
+ # for calling it is already on foo's control frame
+ foo(arg).bar
+ rescue NoMethodError
+ :undef
+ end
+ end
+
+ A.new.use 0
+ A.new.use 0
+ A.new.use 1
+}
+
+# block invalidation edge case
+assert_equal 'ok', %q{
+ class A
+ Good = :ng
+ def foo(arg)
+ arg.times { A.const_set(:Good, :ok) }
+ self
+ end
+
+ def id(arg)
+ arg
+ end
+
+ def use(arg)
+ # send followed by an opt_getinlinecache.
+ # The return address remains on the control frame
+ # when opt_getinlinecache is invalidated.
+ foo(arg).id(Good)
+ end
+ end
+
+ A.new.use 0
+ A.new.use 0
+ A.new.use 1
+}
+
+assert_equal 'ok', %q{
+ # test hitting a branch stub when out of memory
+ def nimai(jita)
+ if jita
+ :ng
+ else
+ :ok
+ end
+ end
+
+ nimai(true)
+ nimai(true)
+
+ RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT)
+
+ nimai(false)
+}
+
+assert_equal 'new', %q{
+ # test block invalidation while out of memory
+ def foo
+ :old
+ end
+
+ def test
+ foo
+ end
+
+ def bar
+ :bar
+ end
+
+
+ test
+ test
+
+ RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT)
+
+ # Old simulat_omm! leaves one byte of space and this fills it up
+ bar
+ bar
+
+ def foo
+ :new
+ end
+
+ test
+}
+
+assert_equal 'ok', %q{
+ # Try to compile new method while OOM
+ def foo
+ :ok
+ end
+
+ RubyVM::YJIT.simulate_oom! if defined?(RubyVM::YJIT)
+
+ foo
+ foo
+}
+
+# struct aref embedded
+assert_equal '2', %q{
+ def foo(s)
+ s.foo
+ end
+
+ S = Struct.new(:foo)
+ foo(S.new(1))
+ foo(S.new(2))
+}
+
+# struct aref non-embedded
+assert_equal '4', %q{
+ def foo(s)
+ s.d
+ end
+
+ S = Struct.new(:a, :b, :c, :d, :e)
+ foo(S.new(1,2,3,4,5))
+ foo(S.new(1,2,3,4,5))
+}
+
+# struct aset embedded
+assert_equal '123', %q{
+ def foo(s)
+ s.foo = 123
+ end
+
+ s = Struct.new(:foo).new
+ foo(s)
+ s = Struct.new(:foo).new
+ foo(s)
+ s.foo
+}
+
+# struct aset non-embedded
+assert_equal '[1, 2, 3, 4, 5]', %q{
+ def foo(s)
+ s.a = 1
+ s.b = 2
+ s.c = 3
+ s.d = 4
+ s.e = 5
+ end
+
+ S = Struct.new(:a, :b, :c, :d, :e)
+ s = S.new
+ foo(s)
+ s = S.new
+ foo(s)
+ [s.a, s.b, s.c, s.d, s.e]
+}
+
+# struct aref too many args
+assert_equal 'ok', %q{
+ def foo(s)
+ s.foo(:bad)
+ end
+
+ s = Struct.new(:foo).new
+ foo(s) rescue :ok
+ foo(s) rescue :ok
+}
+
+# struct aset too many args
+assert_equal 'ok', %q{
+ def foo(s)
+ s.set_foo(123, :bad)
+ end
+
+ s = Struct.new(:foo) do
+ alias :set_foo :foo=
+ end
+ foo(s) rescue :ok
+ foo(s) rescue :ok
+}
+
+# File.join is a cfunc accepting variable arguments as a Ruby array (argc = -2)
+assert_equal 'foo/bar', %q{
+ def foo
+ File.join("foo", "bar")
+ end
+
+ foo
+ foo
+}
+
+# File.join is a cfunc accepting variable arguments as a Ruby array (argc = -2)
+assert_equal '', %q{
+ def foo
+ File.join()
+ end
+
+ foo
+ foo
+}
+
+# Make sure we're correctly reading RStruct's as.ary union for embedded RStructs
+assert_equal '3,12', %q{
+ pt_struct = Struct.new(:x, :y)
+ p = pt_struct.new(3, 12)
+ def pt_inspect(pt)
+ "#{pt.x},#{pt.y}"
+ end
+
+ # Make sure pt_inspect is JITted
+ 10.times { pt_inspect(p) }
+
+ # Make sure it's returning '3,12' instead of e.g. '3,false'
+ pt_inspect(p)
+}
+
+# Regression test for deadlock between branch_stub_hit and ractor_receive_if
+assert_equal '10', %q{
+ r = Ractor.new Ractor.current do |main|
+ main << 1
+ main << 2
+ main << 3
+ main << 4
+ main << 5
+ main << 6
+ main << 7
+ main << 8
+ main << 9
+ main << 10
+ end
+
+ a = []
+ a << Ractor.receive_if{|msg| msg == 10}
+ a << Ractor.receive_if{|msg| msg == 9}
+ a << Ractor.receive_if{|msg| msg == 8}
+ a << Ractor.receive_if{|msg| msg == 7}
+ a << Ractor.receive_if{|msg| msg == 6}
+ a << Ractor.receive_if{|msg| msg == 5}
+ a << Ractor.receive_if{|msg| msg == 4}
+ a << Ractor.receive_if{|msg| msg == 3}
+ a << Ractor.receive_if{|msg| msg == 2}
+ a << Ractor.receive_if{|msg| msg == 1}
+
+ a.length
+}
+
+# checktype
+assert_equal 'false', %q{
+ def function()
+ [1, 2] in [Integer, String]
+ end
+ function()
+}
+
+# opt_send_without_block (VM_METHOD_TYPE_ATTRSET)
+assert_equal 'foo', %q{
+ class Foo
+ attr_writer :foo
+
+ def foo()
+ self.foo = "foo"
+ end
+ end
+ foo = Foo.new
+ foo.foo
+}
+
+# anytostring, intern
+assert_equal 'true', %q{
+ def foo()
+ :"#{true}"
+ end
+ foo()
+}
+
+# toregexp, objtostring
+assert_equal '/true/', %q{
+ def foo()
+ /#{true}/
+ end
+ foo().inspect
+}
+
+# concatstrings, objtostring
+assert_equal '9001', %q{
+ def foo()
+ "#{9001}"
+ end
+ foo()
+}
+
+# opt_send_without_block (VM_METHOD_TYPE_CFUNC)
+assert_equal 'nil', %q{
+ def foo
+ nil.inspect # argc: 0
+ end
+ foo
+}
+assert_equal '4', %q{
+ def foo
+ 2.pow(2) # argc: 1
+ end
+ foo
+}
+assert_equal 'aba', %q{
+ def foo
+ "abc".tr("c", "a") # argc: 2
+ end
+ foo
+}
+assert_equal 'true', %q{
+ def foo
+ respond_to?(:inspect) # argc: -1
+ end
+ foo
+}
+assert_equal '["a", "b"]', %q{
+ def foo
+ "a\nb".lines(chomp: true) # kwargs
+ end
+ foo
+}
+
+# invokebuiltin
+assert_equal '123', %q{
+ def foo(obj)
+ obj.foo = 123
+ end
+
+ struct = Struct.new(:foo)
+ obj = struct.new
+ foo(obj)
+}
+
+# invokebuiltin_delegate
+assert_equal '.', %q{
+ def foo(path)
+ Dir.open(path).path
+ end
+ foo(".")
+}
+
+# opt_invokebuiltin_delegate_leave
+assert_equal '[0]', %q{"\x00".unpack("c")}
+
+# opt_send_without_block (VM_METHOD_TYPE_ISEQ)
+assert_equal '1', %q{
+ def foo = 1
+ def bar = foo
+ bar
+}
+assert_equal '[1, 2, 3]', %q{
+ def foo(a, b) = [1, a, b]
+ def bar = foo(2, 3)
+ bar
+}
+assert_equal '[1, 2, 3, 4, 5, 6]', %q{
+ def foo(a, b, c:, d:, e: 0, f: 6) = [a, b, c, d, e, f]
+ def bar = foo(1, 2, c: 3, d: 4, e: 5)
+ bar
+}
+assert_equal '[1, 2, 3, 4]', %q{
+ def foo(a, b = 2) = [a, b]
+ def bar = foo(1) + foo(3, 4)
+ bar
+}
+
+assert_equal '1', %q{
+ def foo(a) = a
+ def bar = foo(1) { 2 }
+ bar
+}
+assert_equal '[1, 2]', %q{
+ def foo(a, &block) = [a, block.call]
+ def bar = foo(1) { 2 }
+ bar
+}
+
+# opt_send_without_block (VM_METHOD_TYPE_IVAR)
+assert_equal 'foo', %q{
+ class Foo
+ attr_reader :foo
+
+ def initialize
+ @foo = "foo"
+ end
+ end
+ Foo.new.foo
+}
+
+# opt_send_without_block (VM_METHOD_TYPE_OPTIMIZED)
+assert_equal 'foo', %q{
+ Foo = Struct.new(:bar)
+ Foo.new("bar").bar = "foo"
+}
+assert_equal 'foo', %q{
+ Foo = Struct.new(:bar)
+ Foo.new("foo").bar
+}
+
+# getblockparamproxy
+assert_equal 'foo', %q{
+ def foo(&block)
+ block.call
+ end
+ foo { "foo" }
+}
+
+# getblockparam
+assert_equal 'foo', %q{
+ def foo(&block)
+ block
+ end
+ foo { "foo" }.call
+}
+
+assert_equal '[1, 2]', %q{
+ def foo
+ x = [2]
+ [1, *x]
+ end
+
+ foo
+ foo
+}
+
+# respond_to? with changing symbol
+assert_equal 'false', %q{
+ def foo(name)
+ :sym.respond_to?(name)
+ end
+ foo(:to_s)
+ foo(:to_s)
+ foo(:not_exist)
+}
+
+# respond_to? with method being defined
+assert_equal 'true', %q{
+ def foo
+ :sym.respond_to?(:not_yet_defined)
+ end
+ foo
+ foo
+ module Kernel
+ def not_yet_defined = true
+ end
+ foo
+}
+
+# respond_to? with undef method
+assert_equal 'false', %q{
+ module Kernel
+ def to_be_removed = true
+ end
+ def foo
+ :sym.respond_to?(:to_be_removed)
+ end
+ foo
+ foo
+ class Object
+ undef_method :to_be_removed
+ end
+ foo
+}
+
+# respond_to? with respond_to_missing?
+assert_equal 'true', %q{
+ class Foo
+ end
+ def foo(x)
+ x.respond_to?(:bar)
+ end
+ foo(Foo.new)
+ foo(Foo.new)
+ class Foo
+ def respond_to_missing?(*) = true
+ end
+ foo(Foo.new)
+}
+
+# bmethod
+assert_equal '[1, 2, 3]', %q{
+ one = 1
+ define_method(:foo) do
+ one
+ end
+
+ 3.times.map { |i| foo + i }
+}
+
+# return inside bmethod
+assert_equal 'ok', %q{
+ define_method(:foo) do
+ 1.tap { return :ok }
+ end
+
+ foo
+}
+
+# bmethod optional and keywords
+assert_equal '[[1, nil, 2]]', %q{
+ define_method(:opt_and_kwargs) do |a = {}, b: nil, c: nil|
+ [a, b, c]
+ end
+
+ 5.times.map { opt_and_kwargs(1, c: 2) }.uniq
+}
+
+# bmethod with forwarded block
+assert_equal '2', %q{
+ define_method(:foo) do |&block|
+ block.call
+ end
+
+ def bar(&block)
+ foo(&block)
+ end
+
+ bar { 1 }
+ bar { 2 }
+}
+
+# bmethod with forwarded block and arguments
+assert_equal '5', %q{
+ define_method(:foo) do |n, &block|
+ n + block.call
+ end
+
+ def bar(n, &block)
+ foo(n, &block)
+ end
+
+ bar(0) { 1 }
+ bar(3) { 2 }
+}
+
+# bmethod with forwarded unwanted block
+assert_equal '1', %q{
+ one = 1
+ define_method(:foo) do
+ one
+ end
+
+ def bar(&block)
+ foo(&block)
+ end
+
+ bar { }
+ bar { }
+}
+
+# test for return stub lifetime issue
+assert_equal '1', %q{
+ def foo(n)
+ if n == 2
+ return 1.times { Object.define_method(:foo) {} }
+ end
+
+ foo(n + 1)
+ end
+
+ foo(1)
+}
+
+# case-when with redefined ===
+assert_equal 'ok', %q{
+ class Symbol
+ def ===(a)
+ true
+ end
+ end
+
+ def cw(arg)
+ case arg
+ when :b
+ :ok
+ when 4
+ :ng
+ end
+ end
+
+ cw(4)
+}
+
+assert_normal_exit %{
+ class Bug20997
+ def foo(&) = self.class.name(&)
+
+ new.foo
+ end
+}
diff --git a/bootstraptest/test_yjit_30k_ifelse.rb b/bootstraptest/test_yjit_30k_ifelse.rb
new file mode 100644
index 0000000000..c3afa95e4d
--- /dev/null
+++ b/bootstraptest/test_yjit_30k_ifelse.rb
@@ -0,0 +1,241023 @@
+# This is a torture test for the JIT.
+# There are 30K tiny methods with if-else statements in a 30-deep call hierarchy.
+assert_equal '100000', %q{
+
+def fun_l0_n0(x)
+ if (x < 1)
+ fun_l1_n310(x)
+ else
+ fun_l1_n485(x)
+ end
+end
+
+def fun_l0_n1(x)
+ if (x < 1)
+ fun_l1_n930(x)
+ else
+ fun_l1_n418(x)
+ end
+end
+
+def fun_l0_n2(x)
+ if (x < 1)
+ fun_l1_n549(x)
+ else
+ fun_l1_n44(x)
+ end
+end
+
+def fun_l0_n3(x)
+ if (x < 1)
+ fun_l1_n394(x)
+ else
+ fun_l1_n447(x)
+ end
+end
+
+def fun_l0_n4(x)
+ if (x < 1)
+ fun_l1_n683(x)
+ else
+ fun_l1_n547(x)
+ end
+end
+
+def fun_l0_n5(x)
+ if (x < 1)
+ fun_l1_n320(x)
+ else
+ fun_l1_n896(x)
+ end
+end
+
+def fun_l0_n6(x)
+ if (x < 1)
+ fun_l1_n649(x)
+ else
+ fun_l1_n243(x)
+ end
+end
+
+def fun_l0_n7(x)
+ if (x < 1)
+ fun_l1_n100(x)
+ else
+ fun_l1_n243(x)
+ end
+end
+
+def fun_l0_n8(x)
+ if (x < 1)
+ fun_l1_n839(x)
+ else
+ fun_l1_n720(x)
+ end
+end
+
+def fun_l0_n9(x)
+ if (x < 1)
+ fun_l1_n177(x)
+ else
+ fun_l1_n555(x)
+ end
+end
+
+def fun_l0_n10(x)
+ if (x < 1)
+ fun_l1_n814(x)
+ else
+ fun_l1_n900(x)
+ end
+end
+
+def fun_l0_n11(x)
+ if (x < 1)
+ fun_l1_n585(x)
+ else
+ fun_l1_n901(x)
+ end
+end
+
+def fun_l0_n12(x)
+ if (x < 1)
+ fun_l1_n952(x)
+ else
+ fun_l1_n270(x)
+ end
+end
+
+def fun_l0_n13(x)
+ if (x < 1)
+ fun_l1_n172(x)
+ else
+ fun_l1_n209(x)
+ end
+end
+
+def fun_l0_n14(x)
+ if (x < 1)
+ fun_l1_n514(x)
+ else
+ fun_l1_n414(x)
+ end
+end
+
+def fun_l0_n15(x)
+ if (x < 1)
+ fun_l1_n190(x)
+ else
+ fun_l1_n100(x)
+ end
+end
+
+def fun_l0_n16(x)
+ if (x < 1)
+ fun_l1_n696(x)
+ else
+ fun_l1_n997(x)
+ end
+end
+
+def fun_l0_n17(x)
+ if (x < 1)
+ fun_l1_n568(x)
+ else
+ fun_l1_n820(x)
+ end
+end
+
+def fun_l0_n18(x)
+ if (x < 1)
+ fun_l1_n837(x)
+ else
+ fun_l1_n588(x)
+ end
+end
+
+def fun_l0_n19(x)
+ if (x < 1)
+ fun_l1_n206(x)
+ else
+ fun_l1_n126(x)
+ end
+end
+
+def fun_l0_n20(x)
+ if (x < 1)
+ fun_l1_n317(x)
+ else
+ fun_l1_n722(x)
+ end
+end
+
+def fun_l0_n21(x)
+ if (x < 1)
+ fun_l1_n614(x)
+ else
+ fun_l1_n372(x)
+ end
+end
+
+def fun_l0_n22(x)
+ if (x < 1)
+ fun_l1_n530(x)
+ else
+ fun_l1_n862(x)
+ end
+end
+
+def fun_l0_n23(x)
+ if (x < 1)
+ fun_l1_n889(x)
+ else
+ fun_l1_n271(x)
+ end
+end
+
+def fun_l0_n24(x)
+ if (x < 1)
+ fun_l1_n996(x)
+ else
+ fun_l1_n717(x)
+ end
+end
+
+def fun_l0_n25(x)
+ if (x < 1)
+ fun_l1_n726(x)
+ else
+ fun_l1_n939(x)
+ end
+end
+
+def fun_l0_n26(x)
+ if (x < 1)
+ fun_l1_n316(x)
+ else
+ fun_l1_n293(x)
+ end
+end
+
+def fun_l0_n27(x)
+ if (x < 1)
+ fun_l1_n90(x)
+ else
+ fun_l1_n596(x)
+ end
+end
+
+def fun_l0_n28(x)
+ if (x < 1)
+ fun_l1_n743(x)
+ else
+ fun_l1_n782(x)
+ end
+end
+
+def fun_l0_n29(x)
+ if (x < 1)
+ fun_l1_n896(x)
+ else
+ fun_l1_n247(x)
+ end
+end
+
+def fun_l0_n30(x)
+ if (x < 1)
+ fun_l1_n2(x)
+ else
+ fun_l1_n377(x)
+ end
+end
+
+def fun_l0_n31(x)
+ if (x < 1)
+ fun_l1_n380(x)
+ else
+ fun_l1_n655(x)
+ end
+end
+
+def fun_l0_n32(x)
+ if (x < 1)
+ fun_l1_n572(x)
+ else
+ fun_l1_n778(x)
+ end
+end
+
+def fun_l0_n33(x)
+ if (x < 1)
+ fun_l1_n485(x)
+ else
+ fun_l1_n282(x)
+ end
+end
+
+def fun_l0_n34(x)
+ if (x < 1)
+ fun_l1_n703(x)
+ else
+ fun_l1_n179(x)
+ end
+end
+
+def fun_l0_n35(x)
+ if (x < 1)
+ fun_l1_n281(x)
+ else
+ fun_l1_n572(x)
+ end
+end
+
+def fun_l0_n36(x)
+ if (x < 1)
+ fun_l1_n48(x)
+ else
+ fun_l1_n286(x)
+ end
+end
+
+def fun_l0_n37(x)
+ if (x < 1)
+ fun_l1_n539(x)
+ else
+ fun_l1_n86(x)
+ end
+end
+
+def fun_l0_n38(x)
+ if (x < 1)
+ fun_l1_n918(x)
+ else
+ fun_l1_n778(x)
+ end
+end
+
+def fun_l0_n39(x)
+ if (x < 1)
+ fun_l1_n832(x)
+ else
+ fun_l1_n94(x)
+ end
+end
+
+def fun_l0_n40(x)
+ if (x < 1)
+ fun_l1_n213(x)
+ else
+ fun_l1_n580(x)
+ end
+end
+
+def fun_l0_n41(x)
+ if (x < 1)
+ fun_l1_n413(x)
+ else
+ fun_l1_n793(x)
+ end
+end
+
+def fun_l0_n42(x)
+ if (x < 1)
+ fun_l1_n451(x)
+ else
+ fun_l1_n779(x)
+ end
+end
+
+def fun_l0_n43(x)
+ if (x < 1)
+ fun_l1_n118(x)
+ else
+ fun_l1_n778(x)
+ end
+end
+
+def fun_l0_n44(x)
+ if (x < 1)
+ fun_l1_n162(x)
+ else
+ fun_l1_n901(x)
+ end
+end
+
+def fun_l0_n45(x)
+ if (x < 1)
+ fun_l1_n157(x)
+ else
+ fun_l1_n280(x)
+ end
+end
+
+def fun_l0_n46(x)
+ if (x < 1)
+ fun_l1_n748(x)
+ else
+ fun_l1_n881(x)
+ end
+end
+
+def fun_l0_n47(x)
+ if (x < 1)
+ fun_l1_n529(x)
+ else
+ fun_l1_n732(x)
+ end
+end
+
+def fun_l0_n48(x)
+ if (x < 1)
+ fun_l1_n417(x)
+ else
+ fun_l1_n483(x)
+ end
+end
+
+def fun_l0_n49(x)
+ if (x < 1)
+ fun_l1_n743(x)
+ else
+ fun_l1_n525(x)
+ end
+end
+
+def fun_l0_n50(x)
+ if (x < 1)
+ fun_l1_n14(x)
+ else
+ fun_l1_n309(x)
+ end
+end
+
+def fun_l0_n51(x)
+ if (x < 1)
+ fun_l1_n436(x)
+ else
+ fun_l1_n304(x)
+ end
+end
+
+def fun_l0_n52(x)
+ if (x < 1)
+ fun_l1_n623(x)
+ else
+ fun_l1_n590(x)
+ end
+end
+
+def fun_l0_n53(x)
+ if (x < 1)
+ fun_l1_n696(x)
+ else
+ fun_l1_n53(x)
+ end
+end
+
+def fun_l0_n54(x)
+ if (x < 1)
+ fun_l1_n807(x)
+ else
+ fun_l1_n523(x)
+ end
+end
+
+def fun_l0_n55(x)
+ if (x < 1)
+ fun_l1_n607(x)
+ else
+ fun_l1_n609(x)
+ end
+end
+
+def fun_l0_n56(x)
+ if (x < 1)
+ fun_l1_n721(x)
+ else
+ fun_l1_n994(x)
+ end
+end
+
+def fun_l0_n57(x)
+ if (x < 1)
+ fun_l1_n472(x)
+ else
+ fun_l1_n818(x)
+ end
+end
+
+def fun_l0_n58(x)
+ if (x < 1)
+ fun_l1_n30(x)
+ else
+ fun_l1_n954(x)
+ end
+end
+
+def fun_l0_n59(x)
+ if (x < 1)
+ fun_l1_n223(x)
+ else
+ fun_l1_n148(x)
+ end
+end
+
+def fun_l0_n60(x)
+ if (x < 1)
+ fun_l1_n761(x)
+ else
+ fun_l1_n40(x)
+ end
+end
+
+def fun_l0_n61(x)
+ if (x < 1)
+ fun_l1_n57(x)
+ else
+ fun_l1_n858(x)
+ end
+end
+
+def fun_l0_n62(x)
+ if (x < 1)
+ fun_l1_n114(x)
+ else
+ fun_l1_n767(x)
+ end
+end
+
+def fun_l0_n63(x)
+ if (x < 1)
+ fun_l1_n287(x)
+ else
+ fun_l1_n752(x)
+ end
+end
+
+def fun_l0_n64(x)
+ if (x < 1)
+ fun_l1_n16(x)
+ else
+ fun_l1_n229(x)
+ end
+end
+
+def fun_l0_n65(x)
+ if (x < 1)
+ fun_l1_n230(x)
+ else
+ fun_l1_n954(x)
+ end
+end
+
+def fun_l0_n66(x)
+ if (x < 1)
+ fun_l1_n98(x)
+ else
+ fun_l1_n320(x)
+ end
+end
+
+def fun_l0_n67(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n985(x)
+ end
+end
+
+def fun_l0_n68(x)
+ if (x < 1)
+ fun_l1_n32(x)
+ else
+ fun_l1_n648(x)
+ end
+end
+
+def fun_l0_n69(x)
+ if (x < 1)
+ fun_l1_n453(x)
+ else
+ fun_l1_n466(x)
+ end
+end
+
+def fun_l0_n70(x)
+ if (x < 1)
+ fun_l1_n787(x)
+ else
+ fun_l1_n802(x)
+ end
+end
+
+def fun_l0_n71(x)
+ if (x < 1)
+ fun_l1_n656(x)
+ else
+ fun_l1_n347(x)
+ end
+end
+
+def fun_l0_n72(x)
+ if (x < 1)
+ fun_l1_n358(x)
+ else
+ fun_l1_n336(x)
+ end
+end
+
+def fun_l0_n73(x)
+ if (x < 1)
+ fun_l1_n291(x)
+ else
+ fun_l1_n536(x)
+ end
+end
+
+def fun_l0_n74(x)
+ if (x < 1)
+ fun_l1_n795(x)
+ else
+ fun_l1_n606(x)
+ end
+end
+
+def fun_l0_n75(x)
+ if (x < 1)
+ fun_l1_n21(x)
+ else
+ fun_l1_n720(x)
+ end
+end
+
+def fun_l0_n76(x)
+ if (x < 1)
+ fun_l1_n513(x)
+ else
+ fun_l1_n300(x)
+ end
+end
+
+def fun_l0_n77(x)
+ if (x < 1)
+ fun_l1_n358(x)
+ else
+ fun_l1_n332(x)
+ end
+end
+
+def fun_l0_n78(x)
+ if (x < 1)
+ fun_l1_n712(x)
+ else
+ fun_l1_n906(x)
+ end
+end
+
+def fun_l0_n79(x)
+ if (x < 1)
+ fun_l1_n555(x)
+ else
+ fun_l1_n850(x)
+ end
+end
+
+def fun_l0_n80(x)
+ if (x < 1)
+ fun_l1_n320(x)
+ else
+ fun_l1_n892(x)
+ end
+end
+
+def fun_l0_n81(x)
+ if (x < 1)
+ fun_l1_n191(x)
+ else
+ fun_l1_n187(x)
+ end
+end
+
+def fun_l0_n82(x)
+ if (x < 1)
+ fun_l1_n457(x)
+ else
+ fun_l1_n718(x)
+ end
+end
+
+def fun_l0_n83(x)
+ if (x < 1)
+ fun_l1_n314(x)
+ else
+ fun_l1_n697(x)
+ end
+end
+
+def fun_l0_n84(x)
+ if (x < 1)
+ fun_l1_n459(x)
+ else
+ fun_l1_n500(x)
+ end
+end
+
+def fun_l0_n85(x)
+ if (x < 1)
+ fun_l1_n912(x)
+ else
+ fun_l1_n992(x)
+ end
+end
+
+def fun_l0_n86(x)
+ if (x < 1)
+ fun_l1_n523(x)
+ else
+ fun_l1_n201(x)
+ end
+end
+
+def fun_l0_n87(x)
+ if (x < 1)
+ fun_l1_n30(x)
+ else
+ fun_l1_n829(x)
+ end
+end
+
+def fun_l0_n88(x)
+ if (x < 1)
+ fun_l1_n223(x)
+ else
+ fun_l1_n799(x)
+ end
+end
+
+def fun_l0_n89(x)
+ if (x < 1)
+ fun_l1_n289(x)
+ else
+ fun_l1_n289(x)
+ end
+end
+
+def fun_l0_n90(x)
+ if (x < 1)
+ fun_l1_n961(x)
+ else
+ fun_l1_n694(x)
+ end
+end
+
+def fun_l0_n91(x)
+ if (x < 1)
+ fun_l1_n423(x)
+ else
+ fun_l1_n848(x)
+ end
+end
+
+def fun_l0_n92(x)
+ if (x < 1)
+ fun_l1_n612(x)
+ else
+ fun_l1_n358(x)
+ end
+end
+
+def fun_l0_n93(x)
+ if (x < 1)
+ fun_l1_n148(x)
+ else
+ fun_l1_n312(x)
+ end
+end
+
+def fun_l0_n94(x)
+ if (x < 1)
+ fun_l1_n771(x)
+ else
+ fun_l1_n205(x)
+ end
+end
+
+def fun_l0_n95(x)
+ if (x < 1)
+ fun_l1_n573(x)
+ else
+ fun_l1_n692(x)
+ end
+end
+
+def fun_l0_n96(x)
+ if (x < 1)
+ fun_l1_n66(x)
+ else
+ fun_l1_n936(x)
+ end
+end
+
+def fun_l0_n97(x)
+ if (x < 1)
+ fun_l1_n429(x)
+ else
+ fun_l1_n949(x)
+ end
+end
+
+def fun_l0_n98(x)
+ if (x < 1)
+ fun_l1_n737(x)
+ else
+ fun_l1_n338(x)
+ end
+end
+
+def fun_l0_n99(x)
+ if (x < 1)
+ fun_l1_n335(x)
+ else
+ fun_l1_n739(x)
+ end
+end
+
+def fun_l0_n100(x)
+ if (x < 1)
+ fun_l1_n989(x)
+ else
+ fun_l1_n735(x)
+ end
+end
+
+def fun_l0_n101(x)
+ if (x < 1)
+ fun_l1_n559(x)
+ else
+ fun_l1_n478(x)
+ end
+end
+
+def fun_l0_n102(x)
+ if (x < 1)
+ fun_l1_n261(x)
+ else
+ fun_l1_n162(x)
+ end
+end
+
+def fun_l0_n103(x)
+ if (x < 1)
+ fun_l1_n400(x)
+ else
+ fun_l1_n156(x)
+ end
+end
+
+def fun_l0_n104(x)
+ if (x < 1)
+ fun_l1_n747(x)
+ else
+ fun_l1_n361(x)
+ end
+end
+
+def fun_l0_n105(x)
+ if (x < 1)
+ fun_l1_n717(x)
+ else
+ fun_l1_n522(x)
+ end
+end
+
+def fun_l0_n106(x)
+ if (x < 1)
+ fun_l1_n513(x)
+ else
+ fun_l1_n150(x)
+ end
+end
+
+def fun_l0_n107(x)
+ if (x < 1)
+ fun_l1_n710(x)
+ else
+ fun_l1_n602(x)
+ end
+end
+
+def fun_l0_n108(x)
+ if (x < 1)
+ fun_l1_n866(x)
+ else
+ fun_l1_n111(x)
+ end
+end
+
+def fun_l0_n109(x)
+ if (x < 1)
+ fun_l1_n725(x)
+ else
+ fun_l1_n448(x)
+ end
+end
+
+def fun_l0_n110(x)
+ if (x < 1)
+ fun_l1_n703(x)
+ else
+ fun_l1_n127(x)
+ end
+end
+
+def fun_l0_n111(x)
+ if (x < 1)
+ fun_l1_n420(x)
+ else
+ fun_l1_n666(x)
+ end
+end
+
+def fun_l0_n112(x)
+ if (x < 1)
+ fun_l1_n647(x)
+ else
+ fun_l1_n567(x)
+ end
+end
+
+def fun_l0_n113(x)
+ if (x < 1)
+ fun_l1_n543(x)
+ else
+ fun_l1_n992(x)
+ end
+end
+
+def fun_l0_n114(x)
+ if (x < 1)
+ fun_l1_n12(x)
+ else
+ fun_l1_n470(x)
+ end
+end
+
+def fun_l0_n115(x)
+ if (x < 1)
+ fun_l1_n25(x)
+ else
+ fun_l1_n917(x)
+ end
+end
+
+def fun_l0_n116(x)
+ if (x < 1)
+ fun_l1_n201(x)
+ else
+ fun_l1_n110(x)
+ end
+end
+
+def fun_l0_n117(x)
+ if (x < 1)
+ fun_l1_n222(x)
+ else
+ fun_l1_n747(x)
+ end
+end
+
+def fun_l0_n118(x)
+ if (x < 1)
+ fun_l1_n990(x)
+ else
+ fun_l1_n794(x)
+ end
+end
+
+def fun_l0_n119(x)
+ if (x < 1)
+ fun_l1_n712(x)
+ else
+ fun_l1_n5(x)
+ end
+end
+
+def fun_l0_n120(x)
+ if (x < 1)
+ fun_l1_n28(x)
+ else
+ fun_l1_n89(x)
+ end
+end
+
+def fun_l0_n121(x)
+ if (x < 1)
+ fun_l1_n341(x)
+ else
+ fun_l1_n983(x)
+ end
+end
+
+def fun_l0_n122(x)
+ if (x < 1)
+ fun_l1_n123(x)
+ else
+ fun_l1_n452(x)
+ end
+end
+
+def fun_l0_n123(x)
+ if (x < 1)
+ fun_l1_n514(x)
+ else
+ fun_l1_n949(x)
+ end
+end
+
+def fun_l0_n124(x)
+ if (x < 1)
+ fun_l1_n280(x)
+ else
+ fun_l1_n281(x)
+ end
+end
+
+def fun_l0_n125(x)
+ if (x < 1)
+ fun_l1_n512(x)
+ else
+ fun_l1_n772(x)
+ end
+end
+
+def fun_l0_n126(x)
+ if (x < 1)
+ fun_l1_n911(x)
+ else
+ fun_l1_n693(x)
+ end
+end
+
+def fun_l0_n127(x)
+ if (x < 1)
+ fun_l1_n633(x)
+ else
+ fun_l1_n574(x)
+ end
+end
+
+def fun_l0_n128(x)
+ if (x < 1)
+ fun_l1_n318(x)
+ else
+ fun_l1_n266(x)
+ end
+end
+
+def fun_l0_n129(x)
+ if (x < 1)
+ fun_l1_n677(x)
+ else
+ fun_l1_n10(x)
+ end
+end
+
+def fun_l0_n130(x)
+ if (x < 1)
+ fun_l1_n994(x)
+ else
+ fun_l1_n48(x)
+ end
+end
+
+def fun_l0_n131(x)
+ if (x < 1)
+ fun_l1_n335(x)
+ else
+ fun_l1_n473(x)
+ end
+end
+
+def fun_l0_n132(x)
+ if (x < 1)
+ fun_l1_n641(x)
+ else
+ fun_l1_n48(x)
+ end
+end
+
+def fun_l0_n133(x)
+ if (x < 1)
+ fun_l1_n914(x)
+ else
+ fun_l1_n818(x)
+ end
+end
+
+def fun_l0_n134(x)
+ if (x < 1)
+ fun_l1_n479(x)
+ else
+ fun_l1_n761(x)
+ end
+end
+
+def fun_l0_n135(x)
+ if (x < 1)
+ fun_l1_n186(x)
+ else
+ fun_l1_n692(x)
+ end
+end
+
+def fun_l0_n136(x)
+ if (x < 1)
+ fun_l1_n325(x)
+ else
+ fun_l1_n279(x)
+ end
+end
+
+def fun_l0_n137(x)
+ if (x < 1)
+ fun_l1_n493(x)
+ else
+ fun_l1_n293(x)
+ end
+end
+
+def fun_l0_n138(x)
+ if (x < 1)
+ fun_l1_n788(x)
+ else
+ fun_l1_n364(x)
+ end
+end
+
+def fun_l0_n139(x)
+ if (x < 1)
+ fun_l1_n565(x)
+ else
+ fun_l1_n63(x)
+ end
+end
+
+def fun_l0_n140(x)
+ if (x < 1)
+ fun_l1_n128(x)
+ else
+ fun_l1_n299(x)
+ end
+end
+
+def fun_l0_n141(x)
+ if (x < 1)
+ fun_l1_n782(x)
+ else
+ fun_l1_n195(x)
+ end
+end
+
+def fun_l0_n142(x)
+ if (x < 1)
+ fun_l1_n696(x)
+ else
+ fun_l1_n117(x)
+ end
+end
+
+def fun_l0_n143(x)
+ if (x < 1)
+ fun_l1_n263(x)
+ else
+ fun_l1_n683(x)
+ end
+end
+
+def fun_l0_n144(x)
+ if (x < 1)
+ fun_l1_n633(x)
+ else
+ fun_l1_n92(x)
+ end
+end
+
+def fun_l0_n145(x)
+ if (x < 1)
+ fun_l1_n626(x)
+ else
+ fun_l1_n201(x)
+ end
+end
+
+def fun_l0_n146(x)
+ if (x < 1)
+ fun_l1_n296(x)
+ else
+ fun_l1_n425(x)
+ end
+end
+
+def fun_l0_n147(x)
+ if (x < 1)
+ fun_l1_n395(x)
+ else
+ fun_l1_n750(x)
+ end
+end
+
+def fun_l0_n148(x)
+ if (x < 1)
+ fun_l1_n164(x)
+ else
+ fun_l1_n580(x)
+ end
+end
+
+def fun_l0_n149(x)
+ if (x < 1)
+ fun_l1_n904(x)
+ else
+ fun_l1_n264(x)
+ end
+end
+
+def fun_l0_n150(x)
+ if (x < 1)
+ fun_l1_n383(x)
+ else
+ fun_l1_n558(x)
+ end
+end
+
+def fun_l0_n151(x)
+ if (x < 1)
+ fun_l1_n522(x)
+ else
+ fun_l1_n735(x)
+ end
+end
+
+def fun_l0_n152(x)
+ if (x < 1)
+ fun_l1_n496(x)
+ else
+ fun_l1_n562(x)
+ end
+end
+
+def fun_l0_n153(x)
+ if (x < 1)
+ fun_l1_n374(x)
+ else
+ fun_l1_n561(x)
+ end
+end
+
+def fun_l0_n154(x)
+ if (x < 1)
+ fun_l1_n314(x)
+ else
+ fun_l1_n368(x)
+ end
+end
+
+def fun_l0_n155(x)
+ if (x < 1)
+ fun_l1_n456(x)
+ else
+ fun_l1_n189(x)
+ end
+end
+
+def fun_l0_n156(x)
+ if (x < 1)
+ fun_l1_n46(x)
+ else
+ fun_l1_n620(x)
+ end
+end
+
+def fun_l0_n157(x)
+ if (x < 1)
+ fun_l1_n259(x)
+ else
+ fun_l1_n742(x)
+ end
+end
+
+def fun_l0_n158(x)
+ if (x < 1)
+ fun_l1_n881(x)
+ else
+ fun_l1_n786(x)
+ end
+end
+
+def fun_l0_n159(x)
+ if (x < 1)
+ fun_l1_n607(x)
+ else
+ fun_l1_n177(x)
+ end
+end
+
+def fun_l0_n160(x)
+ if (x < 1)
+ fun_l1_n824(x)
+ else
+ fun_l1_n415(x)
+ end
+end
+
+def fun_l0_n161(x)
+ if (x < 1)
+ fun_l1_n443(x)
+ else
+ fun_l1_n787(x)
+ end
+end
+
+def fun_l0_n162(x)
+ if (x < 1)
+ fun_l1_n124(x)
+ else
+ fun_l1_n529(x)
+ end
+end
+
+def fun_l0_n163(x)
+ if (x < 1)
+ fun_l1_n696(x)
+ else
+ fun_l1_n96(x)
+ end
+end
+
+def fun_l0_n164(x)
+ if (x < 1)
+ fun_l1_n775(x)
+ else
+ fun_l1_n549(x)
+ end
+end
+
+def fun_l0_n165(x)
+ if (x < 1)
+ fun_l1_n860(x)
+ else
+ fun_l1_n212(x)
+ end
+end
+
+def fun_l0_n166(x)
+ if (x < 1)
+ fun_l1_n378(x)
+ else
+ fun_l1_n904(x)
+ end
+end
+
+def fun_l0_n167(x)
+ if (x < 1)
+ fun_l1_n15(x)
+ else
+ fun_l1_n640(x)
+ end
+end
+
+def fun_l0_n168(x)
+ if (x < 1)
+ fun_l1_n771(x)
+ else
+ fun_l1_n861(x)
+ end
+end
+
+def fun_l0_n169(x)
+ if (x < 1)
+ fun_l1_n468(x)
+ else
+ fun_l1_n586(x)
+ end
+end
+
+def fun_l0_n170(x)
+ if (x < 1)
+ fun_l1_n477(x)
+ else
+ fun_l1_n674(x)
+ end
+end
+
+def fun_l0_n171(x)
+ if (x < 1)
+ fun_l1_n509(x)
+ else
+ fun_l1_n64(x)
+ end
+end
+
+def fun_l0_n172(x)
+ if (x < 1)
+ fun_l1_n612(x)
+ else
+ fun_l1_n828(x)
+ end
+end
+
+def fun_l0_n173(x)
+ if (x < 1)
+ fun_l1_n440(x)
+ else
+ fun_l1_n204(x)
+ end
+end
+
+def fun_l0_n174(x)
+ if (x < 1)
+ fun_l1_n259(x)
+ else
+ fun_l1_n947(x)
+ end
+end
+
+def fun_l0_n175(x)
+ if (x < 1)
+ fun_l1_n402(x)
+ else
+ fun_l1_n588(x)
+ end
+end
+
+def fun_l0_n176(x)
+ if (x < 1)
+ fun_l1_n245(x)
+ else
+ fun_l1_n540(x)
+ end
+end
+
+def fun_l0_n177(x)
+ if (x < 1)
+ fun_l1_n869(x)
+ else
+ fun_l1_n249(x)
+ end
+end
+
+def fun_l0_n178(x)
+ if (x < 1)
+ fun_l1_n830(x)
+ else
+ fun_l1_n210(x)
+ end
+end
+
+def fun_l0_n179(x)
+ if (x < 1)
+ fun_l1_n692(x)
+ else
+ fun_l1_n222(x)
+ end
+end
+
+def fun_l0_n180(x)
+ if (x < 1)
+ fun_l1_n220(x)
+ else
+ fun_l1_n281(x)
+ end
+end
+
+def fun_l0_n181(x)
+ if (x < 1)
+ fun_l1_n523(x)
+ else
+ fun_l1_n618(x)
+ end
+end
+
+def fun_l0_n182(x)
+ if (x < 1)
+ fun_l1_n44(x)
+ else
+ fun_l1_n422(x)
+ end
+end
+
+def fun_l0_n183(x)
+ if (x < 1)
+ fun_l1_n944(x)
+ else
+ fun_l1_n230(x)
+ end
+end
+
+def fun_l0_n184(x)
+ if (x < 1)
+ fun_l1_n678(x)
+ else
+ fun_l1_n121(x)
+ end
+end
+
+def fun_l0_n185(x)
+ if (x < 1)
+ fun_l1_n73(x)
+ else
+ fun_l1_n398(x)
+ end
+end
+
+def fun_l0_n186(x)
+ if (x < 1)
+ fun_l1_n121(x)
+ else
+ fun_l1_n689(x)
+ end
+end
+
+def fun_l0_n187(x)
+ if (x < 1)
+ fun_l1_n946(x)
+ else
+ fun_l1_n613(x)
+ end
+end
+
+def fun_l0_n188(x)
+ if (x < 1)
+ fun_l1_n987(x)
+ else
+ fun_l1_n785(x)
+ end
+end
+
+def fun_l0_n189(x)
+ if (x < 1)
+ fun_l1_n181(x)
+ else
+ fun_l1_n644(x)
+ end
+end
+
+def fun_l0_n190(x)
+ if (x < 1)
+ fun_l1_n623(x)
+ else
+ fun_l1_n679(x)
+ end
+end
+
+def fun_l0_n191(x)
+ if (x < 1)
+ fun_l1_n784(x)
+ else
+ fun_l1_n274(x)
+ end
+end
+
+def fun_l0_n192(x)
+ if (x < 1)
+ fun_l1_n71(x)
+ else
+ fun_l1_n773(x)
+ end
+end
+
+def fun_l0_n193(x)
+ if (x < 1)
+ fun_l1_n516(x)
+ else
+ fun_l1_n496(x)
+ end
+end
+
+def fun_l0_n194(x)
+ if (x < 1)
+ fun_l1_n608(x)
+ else
+ fun_l1_n460(x)
+ end
+end
+
+def fun_l0_n195(x)
+ if (x < 1)
+ fun_l1_n25(x)
+ else
+ fun_l1_n437(x)
+ end
+end
+
+def fun_l0_n196(x)
+ if (x < 1)
+ fun_l1_n410(x)
+ else
+ fun_l1_n674(x)
+ end
+end
+
+def fun_l0_n197(x)
+ if (x < 1)
+ fun_l1_n949(x)
+ else
+ fun_l1_n708(x)
+ end
+end
+
+def fun_l0_n198(x)
+ if (x < 1)
+ fun_l1_n714(x)
+ else
+ fun_l1_n119(x)
+ end
+end
+
+def fun_l0_n199(x)
+ if (x < 1)
+ fun_l1_n41(x)
+ else
+ fun_l1_n865(x)
+ end
+end
+
+def fun_l0_n200(x)
+ if (x < 1)
+ fun_l1_n383(x)
+ else
+ fun_l1_n90(x)
+ end
+end
+
+def fun_l0_n201(x)
+ if (x < 1)
+ fun_l1_n581(x)
+ else
+ fun_l1_n273(x)
+ end
+end
+
+def fun_l0_n202(x)
+ if (x < 1)
+ fun_l1_n350(x)
+ else
+ fun_l1_n425(x)
+ end
+end
+
+def fun_l0_n203(x)
+ if (x < 1)
+ fun_l1_n259(x)
+ else
+ fun_l1_n922(x)
+ end
+end
+
+def fun_l0_n204(x)
+ if (x < 1)
+ fun_l1_n448(x)
+ else
+ fun_l1_n741(x)
+ end
+end
+
+def fun_l0_n205(x)
+ if (x < 1)
+ fun_l1_n86(x)
+ else
+ fun_l1_n618(x)
+ end
+end
+
+def fun_l0_n206(x)
+ if (x < 1)
+ fun_l1_n412(x)
+ else
+ fun_l1_n646(x)
+ end
+end
+
+def fun_l0_n207(x)
+ if (x < 1)
+ fun_l1_n196(x)
+ else
+ fun_l1_n496(x)
+ end
+end
+
+def fun_l0_n208(x)
+ if (x < 1)
+ fun_l1_n777(x)
+ else
+ fun_l1_n150(x)
+ end
+end
+
+def fun_l0_n209(x)
+ if (x < 1)
+ fun_l1_n20(x)
+ else
+ fun_l1_n718(x)
+ end
+end
+
+def fun_l0_n210(x)
+ if (x < 1)
+ fun_l1_n934(x)
+ else
+ fun_l1_n416(x)
+ end
+end
+
+def fun_l0_n211(x)
+ if (x < 1)
+ fun_l1_n803(x)
+ else
+ fun_l1_n636(x)
+ end
+end
+
+def fun_l0_n212(x)
+ if (x < 1)
+ fun_l1_n93(x)
+ else
+ fun_l1_n791(x)
+ end
+end
+
+def fun_l0_n213(x)
+ if (x < 1)
+ fun_l1_n76(x)
+ else
+ fun_l1_n172(x)
+ end
+end
+
+def fun_l0_n214(x)
+ if (x < 1)
+ fun_l1_n103(x)
+ else
+ fun_l1_n381(x)
+ end
+end
+
+def fun_l0_n215(x)
+ if (x < 1)
+ fun_l1_n433(x)
+ else
+ fun_l1_n349(x)
+ end
+end
+
+def fun_l0_n216(x)
+ if (x < 1)
+ fun_l1_n154(x)
+ else
+ fun_l1_n740(x)
+ end
+end
+
+def fun_l0_n217(x)
+ if (x < 1)
+ fun_l1_n927(x)
+ else
+ fun_l1_n886(x)
+ end
+end
+
+def fun_l0_n218(x)
+ if (x < 1)
+ fun_l1_n804(x)
+ else
+ fun_l1_n6(x)
+ end
+end
+
+def fun_l0_n219(x)
+ if (x < 1)
+ fun_l1_n921(x)
+ else
+ fun_l1_n121(x)
+ end
+end
+
+def fun_l0_n220(x)
+ if (x < 1)
+ fun_l1_n732(x)
+ else
+ fun_l1_n224(x)
+ end
+end
+
+def fun_l0_n221(x)
+ if (x < 1)
+ fun_l1_n818(x)
+ else
+ fun_l1_n105(x)
+ end
+end
+
+def fun_l0_n222(x)
+ if (x < 1)
+ fun_l1_n162(x)
+ else
+ fun_l1_n700(x)
+ end
+end
+
+def fun_l0_n223(x)
+ if (x < 1)
+ fun_l1_n57(x)
+ else
+ fun_l1_n734(x)
+ end
+end
+
+def fun_l0_n224(x)
+ if (x < 1)
+ fun_l1_n283(x)
+ else
+ fun_l1_n87(x)
+ end
+end
+
+def fun_l0_n225(x)
+ if (x < 1)
+ fun_l1_n623(x)
+ else
+ fun_l1_n363(x)
+ end
+end
+
+def fun_l0_n226(x)
+ if (x < 1)
+ fun_l1_n962(x)
+ else
+ fun_l1_n660(x)
+ end
+end
+
+def fun_l0_n227(x)
+ if (x < 1)
+ fun_l1_n255(x)
+ else
+ fun_l1_n536(x)
+ end
+end
+
+def fun_l0_n228(x)
+ if (x < 1)
+ fun_l1_n377(x)
+ else
+ fun_l1_n249(x)
+ end
+end
+
+def fun_l0_n229(x)
+ if (x < 1)
+ fun_l1_n527(x)
+ else
+ fun_l1_n691(x)
+ end
+end
+
+def fun_l0_n230(x)
+ if (x < 1)
+ fun_l1_n781(x)
+ else
+ fun_l1_n494(x)
+ end
+end
+
+def fun_l0_n231(x)
+ if (x < 1)
+ fun_l1_n889(x)
+ else
+ fun_l1_n967(x)
+ end
+end
+
+def fun_l0_n232(x)
+ if (x < 1)
+ fun_l1_n509(x)
+ else
+ fun_l1_n910(x)
+ end
+end
+
+def fun_l0_n233(x)
+ if (x < 1)
+ fun_l1_n354(x)
+ else
+ fun_l1_n5(x)
+ end
+end
+
+def fun_l0_n234(x)
+ if (x < 1)
+ fun_l1_n423(x)
+ else
+ fun_l1_n788(x)
+ end
+end
+
+def fun_l0_n235(x)
+ if (x < 1)
+ fun_l1_n632(x)
+ else
+ fun_l1_n705(x)
+ end
+end
+
+def fun_l0_n236(x)
+ if (x < 1)
+ fun_l1_n955(x)
+ else
+ fun_l1_n908(x)
+ end
+end
+
+def fun_l0_n237(x)
+ if (x < 1)
+ fun_l1_n329(x)
+ else
+ fun_l1_n2(x)
+ end
+end
+
+def fun_l0_n238(x)
+ if (x < 1)
+ fun_l1_n767(x)
+ else
+ fun_l1_n766(x)
+ end
+end
+
+def fun_l0_n239(x)
+ if (x < 1)
+ fun_l1_n304(x)
+ else
+ fun_l1_n507(x)
+ end
+end
+
+def fun_l0_n240(x)
+ if (x < 1)
+ fun_l1_n845(x)
+ else
+ fun_l1_n777(x)
+ end
+end
+
+def fun_l0_n241(x)
+ if (x < 1)
+ fun_l1_n69(x)
+ else
+ fun_l1_n260(x)
+ end
+end
+
+def fun_l0_n242(x)
+ if (x < 1)
+ fun_l1_n194(x)
+ else
+ fun_l1_n412(x)
+ end
+end
+
+def fun_l0_n243(x)
+ if (x < 1)
+ fun_l1_n974(x)
+ else
+ fun_l1_n922(x)
+ end
+end
+
+def fun_l0_n244(x)
+ if (x < 1)
+ fun_l1_n532(x)
+ else
+ fun_l1_n530(x)
+ end
+end
+
+def fun_l0_n245(x)
+ if (x < 1)
+ fun_l1_n554(x)
+ else
+ fun_l1_n656(x)
+ end
+end
+
+def fun_l0_n246(x)
+ if (x < 1)
+ fun_l1_n253(x)
+ else
+ fun_l1_n235(x)
+ end
+end
+
+def fun_l0_n247(x)
+ if (x < 1)
+ fun_l1_n754(x)
+ else
+ fun_l1_n775(x)
+ end
+end
+
+def fun_l0_n248(x)
+ if (x < 1)
+ fun_l1_n89(x)
+ else
+ fun_l1_n129(x)
+ end
+end
+
+def fun_l0_n249(x)
+ if (x < 1)
+ fun_l1_n284(x)
+ else
+ fun_l1_n642(x)
+ end
+end
+
+def fun_l0_n250(x)
+ if (x < 1)
+ fun_l1_n67(x)
+ else
+ fun_l1_n867(x)
+ end
+end
+
+def fun_l0_n251(x)
+ if (x < 1)
+ fun_l1_n926(x)
+ else
+ fun_l1_n442(x)
+ end
+end
+
+def fun_l0_n252(x)
+ if (x < 1)
+ fun_l1_n196(x)
+ else
+ fun_l1_n583(x)
+ end
+end
+
+def fun_l0_n253(x)
+ if (x < 1)
+ fun_l1_n966(x)
+ else
+ fun_l1_n810(x)
+ end
+end
+
+def fun_l0_n254(x)
+ if (x < 1)
+ fun_l1_n984(x)
+ else
+ fun_l1_n752(x)
+ end
+end
+
+def fun_l0_n255(x)
+ if (x < 1)
+ fun_l1_n941(x)
+ else
+ fun_l1_n744(x)
+ end
+end
+
+def fun_l0_n256(x)
+ if (x < 1)
+ fun_l1_n785(x)
+ else
+ fun_l1_n610(x)
+ end
+end
+
+def fun_l0_n257(x)
+ if (x < 1)
+ fun_l1_n622(x)
+ else
+ fun_l1_n730(x)
+ end
+end
+
+def fun_l0_n258(x)
+ if (x < 1)
+ fun_l1_n453(x)
+ else
+ fun_l1_n641(x)
+ end
+end
+
+def fun_l0_n259(x)
+ if (x < 1)
+ fun_l1_n407(x)
+ else
+ fun_l1_n818(x)
+ end
+end
+
+def fun_l0_n260(x)
+ if (x < 1)
+ fun_l1_n252(x)
+ else
+ fun_l1_n205(x)
+ end
+end
+
+def fun_l0_n261(x)
+ if (x < 1)
+ fun_l1_n940(x)
+ else
+ fun_l1_n678(x)
+ end
+end
+
+def fun_l0_n262(x)
+ if (x < 1)
+ fun_l1_n350(x)
+ else
+ fun_l1_n496(x)
+ end
+end
+
+def fun_l0_n263(x)
+ if (x < 1)
+ fun_l1_n688(x)
+ else
+ fun_l1_n193(x)
+ end
+end
+
+def fun_l0_n264(x)
+ if (x < 1)
+ fun_l1_n366(x)
+ else
+ fun_l1_n790(x)
+ end
+end
+
+def fun_l0_n265(x)
+ if (x < 1)
+ fun_l1_n592(x)
+ else
+ fun_l1_n93(x)
+ end
+end
+
+def fun_l0_n266(x)
+ if (x < 1)
+ fun_l1_n189(x)
+ else
+ fun_l1_n467(x)
+ end
+end
+
+def fun_l0_n267(x)
+ if (x < 1)
+ fun_l1_n813(x)
+ else
+ fun_l1_n7(x)
+ end
+end
+
+def fun_l0_n268(x)
+ if (x < 1)
+ fun_l1_n516(x)
+ else
+ fun_l1_n271(x)
+ end
+end
+
+def fun_l0_n269(x)
+ if (x < 1)
+ fun_l1_n0(x)
+ else
+ fun_l1_n121(x)
+ end
+end
+
+def fun_l0_n270(x)
+ if (x < 1)
+ fun_l1_n634(x)
+ else
+ fun_l1_n726(x)
+ end
+end
+
+def fun_l0_n271(x)
+ if (x < 1)
+ fun_l1_n192(x)
+ else
+ fun_l1_n468(x)
+ end
+end
+
+def fun_l0_n272(x)
+ if (x < 1)
+ fun_l1_n278(x)
+ else
+ fun_l1_n355(x)
+ end
+end
+
+def fun_l0_n273(x)
+ if (x < 1)
+ fun_l1_n354(x)
+ else
+ fun_l1_n87(x)
+ end
+end
+
+def fun_l0_n274(x)
+ if (x < 1)
+ fun_l1_n643(x)
+ else
+ fun_l1_n806(x)
+ end
+end
+
+def fun_l0_n275(x)
+ if (x < 1)
+ fun_l1_n389(x)
+ else
+ fun_l1_n559(x)
+ end
+end
+
+def fun_l0_n276(x)
+ if (x < 1)
+ fun_l1_n283(x)
+ else
+ fun_l1_n539(x)
+ end
+end
+
+def fun_l0_n277(x)
+ if (x < 1)
+ fun_l1_n0(x)
+ else
+ fun_l1_n351(x)
+ end
+end
+
+def fun_l0_n278(x)
+ if (x < 1)
+ fun_l1_n813(x)
+ else
+ fun_l1_n513(x)
+ end
+end
+
+def fun_l0_n279(x)
+ if (x < 1)
+ fun_l1_n501(x)
+ else
+ fun_l1_n967(x)
+ end
+end
+
+def fun_l0_n280(x)
+ if (x < 1)
+ fun_l1_n727(x)
+ else
+ fun_l1_n232(x)
+ end
+end
+
+def fun_l0_n281(x)
+ if (x < 1)
+ fun_l1_n946(x)
+ else
+ fun_l1_n693(x)
+ end
+end
+
+def fun_l0_n282(x)
+ if (x < 1)
+ fun_l1_n260(x)
+ else
+ fun_l1_n525(x)
+ end
+end
+
+def fun_l0_n283(x)
+ if (x < 1)
+ fun_l1_n957(x)
+ else
+ fun_l1_n817(x)
+ end
+end
+
+def fun_l0_n284(x)
+ if (x < 1)
+ fun_l1_n91(x)
+ else
+ fun_l1_n735(x)
+ end
+end
+
+def fun_l0_n285(x)
+ if (x < 1)
+ fun_l1_n71(x)
+ else
+ fun_l1_n24(x)
+ end
+end
+
+def fun_l0_n286(x)
+ if (x < 1)
+ fun_l1_n594(x)
+ else
+ fun_l1_n747(x)
+ end
+end
+
+def fun_l0_n287(x)
+ if (x < 1)
+ fun_l1_n869(x)
+ else
+ fun_l1_n414(x)
+ end
+end
+
+def fun_l0_n288(x)
+ if (x < 1)
+ fun_l1_n182(x)
+ else
+ fun_l1_n835(x)
+ end
+end
+
+def fun_l0_n289(x)
+ if (x < 1)
+ fun_l1_n188(x)
+ else
+ fun_l1_n949(x)
+ end
+end
+
+def fun_l0_n290(x)
+ if (x < 1)
+ fun_l1_n35(x)
+ else
+ fun_l1_n259(x)
+ end
+end
+
+def fun_l0_n291(x)
+ if (x < 1)
+ fun_l1_n593(x)
+ else
+ fun_l1_n810(x)
+ end
+end
+
+def fun_l0_n292(x)
+ if (x < 1)
+ fun_l1_n680(x)
+ else
+ fun_l1_n564(x)
+ end
+end
+
+def fun_l0_n293(x)
+ if (x < 1)
+ fun_l1_n57(x)
+ else
+ fun_l1_n91(x)
+ end
+end
+
+def fun_l0_n294(x)
+ if (x < 1)
+ fun_l1_n945(x)
+ else
+ fun_l1_n807(x)
+ end
+end
+
+def fun_l0_n295(x)
+ if (x < 1)
+ fun_l1_n442(x)
+ else
+ fun_l1_n123(x)
+ end
+end
+
+def fun_l0_n296(x)
+ if (x < 1)
+ fun_l1_n536(x)
+ else
+ fun_l1_n987(x)
+ end
+end
+
+def fun_l0_n297(x)
+ if (x < 1)
+ fun_l1_n519(x)
+ else
+ fun_l1_n657(x)
+ end
+end
+
+def fun_l0_n298(x)
+ if (x < 1)
+ fun_l1_n204(x)
+ else
+ fun_l1_n437(x)
+ end
+end
+
+def fun_l0_n299(x)
+ if (x < 1)
+ fun_l1_n289(x)
+ else
+ fun_l1_n385(x)
+ end
+end
+
+def fun_l0_n300(x)
+ if (x < 1)
+ fun_l1_n629(x)
+ else
+ fun_l1_n803(x)
+ end
+end
+
+def fun_l0_n301(x)
+ if (x < 1)
+ fun_l1_n576(x)
+ else
+ fun_l1_n921(x)
+ end
+end
+
+def fun_l0_n302(x)
+ if (x < 1)
+ fun_l1_n466(x)
+ else
+ fun_l1_n475(x)
+ end
+end
+
+def fun_l0_n303(x)
+ if (x < 1)
+ fun_l1_n658(x)
+ else
+ fun_l1_n333(x)
+ end
+end
+
+def fun_l0_n304(x)
+ if (x < 1)
+ fun_l1_n728(x)
+ else
+ fun_l1_n749(x)
+ end
+end
+
+def fun_l0_n305(x)
+ if (x < 1)
+ fun_l1_n68(x)
+ else
+ fun_l1_n552(x)
+ end
+end
+
+def fun_l0_n306(x)
+ if (x < 1)
+ fun_l1_n633(x)
+ else
+ fun_l1_n958(x)
+ end
+end
+
+def fun_l0_n307(x)
+ if (x < 1)
+ fun_l1_n79(x)
+ else
+ fun_l1_n386(x)
+ end
+end
+
+def fun_l0_n308(x)
+ if (x < 1)
+ fun_l1_n831(x)
+ else
+ fun_l1_n176(x)
+ end
+end
+
+def fun_l0_n309(x)
+ if (x < 1)
+ fun_l1_n770(x)
+ else
+ fun_l1_n334(x)
+ end
+end
+
+def fun_l0_n310(x)
+ if (x < 1)
+ fun_l1_n21(x)
+ else
+ fun_l1_n643(x)
+ end
+end
+
+def fun_l0_n311(x)
+ if (x < 1)
+ fun_l1_n673(x)
+ else
+ fun_l1_n298(x)
+ end
+end
+
+def fun_l0_n312(x)
+ if (x < 1)
+ fun_l1_n753(x)
+ else
+ fun_l1_n817(x)
+ end
+end
+
+def fun_l0_n313(x)
+ if (x < 1)
+ fun_l1_n299(x)
+ else
+ fun_l1_n350(x)
+ end
+end
+
+def fun_l0_n314(x)
+ if (x < 1)
+ fun_l1_n190(x)
+ else
+ fun_l1_n519(x)
+ end
+end
+
+def fun_l0_n315(x)
+ if (x < 1)
+ fun_l1_n934(x)
+ else
+ fun_l1_n416(x)
+ end
+end
+
+def fun_l0_n316(x)
+ if (x < 1)
+ fun_l1_n695(x)
+ else
+ fun_l1_n377(x)
+ end
+end
+
+def fun_l0_n317(x)
+ if (x < 1)
+ fun_l1_n194(x)
+ else
+ fun_l1_n747(x)
+ end
+end
+
+def fun_l0_n318(x)
+ if (x < 1)
+ fun_l1_n145(x)
+ else
+ fun_l1_n761(x)
+ end
+end
+
+def fun_l0_n319(x)
+ if (x < 1)
+ fun_l1_n223(x)
+ else
+ fun_l1_n237(x)
+ end
+end
+
+def fun_l0_n320(x)
+ if (x < 1)
+ fun_l1_n907(x)
+ else
+ fun_l1_n653(x)
+ end
+end
+
+def fun_l0_n321(x)
+ if (x < 1)
+ fun_l1_n216(x)
+ else
+ fun_l1_n67(x)
+ end
+end
+
+def fun_l0_n322(x)
+ if (x < 1)
+ fun_l1_n658(x)
+ else
+ fun_l1_n948(x)
+ end
+end
+
+def fun_l0_n323(x)
+ if (x < 1)
+ fun_l1_n358(x)
+ else
+ fun_l1_n926(x)
+ end
+end
+
+def fun_l0_n324(x)
+ if (x < 1)
+ fun_l1_n533(x)
+ else
+ fun_l1_n252(x)
+ end
+end
+
+def fun_l0_n325(x)
+ if (x < 1)
+ fun_l1_n284(x)
+ else
+ fun_l1_n670(x)
+ end
+end
+
+def fun_l0_n326(x)
+ if (x < 1)
+ fun_l1_n327(x)
+ else
+ fun_l1_n298(x)
+ end
+end
+
+def fun_l0_n327(x)
+ if (x < 1)
+ fun_l1_n837(x)
+ else
+ fun_l1_n890(x)
+ end
+end
+
+def fun_l0_n328(x)
+ if (x < 1)
+ fun_l1_n941(x)
+ else
+ fun_l1_n794(x)
+ end
+end
+
+def fun_l0_n329(x)
+ if (x < 1)
+ fun_l1_n859(x)
+ else
+ fun_l1_n970(x)
+ end
+end
+
+def fun_l0_n330(x)
+ if (x < 1)
+ fun_l1_n282(x)
+ else
+ fun_l1_n569(x)
+ end
+end
+
+def fun_l0_n331(x)
+ if (x < 1)
+ fun_l1_n33(x)
+ else
+ fun_l1_n525(x)
+ end
+end
+
+def fun_l0_n332(x)
+ if (x < 1)
+ fun_l1_n847(x)
+ else
+ fun_l1_n540(x)
+ end
+end
+
+def fun_l0_n333(x)
+ if (x < 1)
+ fun_l1_n485(x)
+ else
+ fun_l1_n756(x)
+ end
+end
+
+def fun_l0_n334(x)
+ if (x < 1)
+ fun_l1_n396(x)
+ else
+ fun_l1_n781(x)
+ end
+end
+
+def fun_l0_n335(x)
+ if (x < 1)
+ fun_l1_n225(x)
+ else
+ fun_l1_n417(x)
+ end
+end
+
+def fun_l0_n336(x)
+ if (x < 1)
+ fun_l1_n906(x)
+ else
+ fun_l1_n301(x)
+ end
+end
+
+def fun_l0_n337(x)
+ if (x < 1)
+ fun_l1_n863(x)
+ else
+ fun_l1_n409(x)
+ end
+end
+
+def fun_l0_n338(x)
+ if (x < 1)
+ fun_l1_n103(x)
+ else
+ fun_l1_n460(x)
+ end
+end
+
+def fun_l0_n339(x)
+ if (x < 1)
+ fun_l1_n787(x)
+ else
+ fun_l1_n434(x)
+ end
+end
+
+def fun_l0_n340(x)
+ if (x < 1)
+ fun_l1_n308(x)
+ else
+ fun_l1_n875(x)
+ end
+end
+
+def fun_l0_n341(x)
+ if (x < 1)
+ fun_l1_n146(x)
+ else
+ fun_l1_n566(x)
+ end
+end
+
+def fun_l0_n342(x)
+ if (x < 1)
+ fun_l1_n837(x)
+ else
+ fun_l1_n770(x)
+ end
+end
+
+def fun_l0_n343(x)
+ if (x < 1)
+ fun_l1_n668(x)
+ else
+ fun_l1_n60(x)
+ end
+end
+
+def fun_l0_n344(x)
+ if (x < 1)
+ fun_l1_n305(x)
+ else
+ fun_l1_n388(x)
+ end
+end
+
+def fun_l0_n345(x)
+ if (x < 1)
+ fun_l1_n796(x)
+ else
+ fun_l1_n920(x)
+ end
+end
+
+def fun_l0_n346(x)
+ if (x < 1)
+ fun_l1_n257(x)
+ else
+ fun_l1_n229(x)
+ end
+end
+
+def fun_l0_n347(x)
+ if (x < 1)
+ fun_l1_n740(x)
+ else
+ fun_l1_n372(x)
+ end
+end
+
+def fun_l0_n348(x)
+ if (x < 1)
+ fun_l1_n698(x)
+ else
+ fun_l1_n63(x)
+ end
+end
+
+def fun_l0_n349(x)
+ if (x < 1)
+ fun_l1_n4(x)
+ else
+ fun_l1_n119(x)
+ end
+end
+
+def fun_l0_n350(x)
+ if (x < 1)
+ fun_l1_n186(x)
+ else
+ fun_l1_n352(x)
+ end
+end
+
+def fun_l0_n351(x)
+ if (x < 1)
+ fun_l1_n619(x)
+ else
+ fun_l1_n583(x)
+ end
+end
+
+def fun_l0_n352(x)
+ if (x < 1)
+ fun_l1_n2(x)
+ else
+ fun_l1_n275(x)
+ end
+end
+
+def fun_l0_n353(x)
+ if (x < 1)
+ fun_l1_n843(x)
+ else
+ fun_l1_n986(x)
+ end
+end
+
+def fun_l0_n354(x)
+ if (x < 1)
+ fun_l1_n865(x)
+ else
+ fun_l1_n64(x)
+ end
+end
+
+def fun_l0_n355(x)
+ if (x < 1)
+ fun_l1_n732(x)
+ else
+ fun_l1_n332(x)
+ end
+end
+
+def fun_l0_n356(x)
+ if (x < 1)
+ fun_l1_n642(x)
+ else
+ fun_l1_n559(x)
+ end
+end
+
+def fun_l0_n357(x)
+ if (x < 1)
+ fun_l1_n385(x)
+ else
+ fun_l1_n532(x)
+ end
+end
+
+def fun_l0_n358(x)
+ if (x < 1)
+ fun_l1_n672(x)
+ else
+ fun_l1_n721(x)
+ end
+end
+
+def fun_l0_n359(x)
+ if (x < 1)
+ fun_l1_n663(x)
+ else
+ fun_l1_n590(x)
+ end
+end
+
+def fun_l0_n360(x)
+ if (x < 1)
+ fun_l1_n240(x)
+ else
+ fun_l1_n743(x)
+ end
+end
+
+def fun_l0_n361(x)
+ if (x < 1)
+ fun_l1_n301(x)
+ else
+ fun_l1_n943(x)
+ end
+end
+
+def fun_l0_n362(x)
+ if (x < 1)
+ fun_l1_n108(x)
+ else
+ fun_l1_n975(x)
+ end
+end
+
+def fun_l0_n363(x)
+ if (x < 1)
+ fun_l1_n554(x)
+ else
+ fun_l1_n135(x)
+ end
+end
+
+def fun_l0_n364(x)
+ if (x < 1)
+ fun_l1_n360(x)
+ else
+ fun_l1_n821(x)
+ end
+end
+
+def fun_l0_n365(x)
+ if (x < 1)
+ fun_l1_n992(x)
+ else
+ fun_l1_n158(x)
+ end
+end
+
+def fun_l0_n366(x)
+ if (x < 1)
+ fun_l1_n439(x)
+ else
+ fun_l1_n506(x)
+ end
+end
+
+def fun_l0_n367(x)
+ if (x < 1)
+ fun_l1_n229(x)
+ else
+ fun_l1_n714(x)
+ end
+end
+
+def fun_l0_n368(x)
+ if (x < 1)
+ fun_l1_n459(x)
+ else
+ fun_l1_n874(x)
+ end
+end
+
+def fun_l0_n369(x)
+ if (x < 1)
+ fun_l1_n799(x)
+ else
+ fun_l1_n406(x)
+ end
+end
+
+def fun_l0_n370(x)
+ if (x < 1)
+ fun_l1_n791(x)
+ else
+ fun_l1_n669(x)
+ end
+end
+
+def fun_l0_n371(x)
+ if (x < 1)
+ fun_l1_n99(x)
+ else
+ fun_l1_n344(x)
+ end
+end
+
+def fun_l0_n372(x)
+ if (x < 1)
+ fun_l1_n585(x)
+ else
+ fun_l1_n388(x)
+ end
+end
+
+def fun_l0_n373(x)
+ if (x < 1)
+ fun_l1_n35(x)
+ else
+ fun_l1_n369(x)
+ end
+end
+
+def fun_l0_n374(x)
+ if (x < 1)
+ fun_l1_n41(x)
+ else
+ fun_l1_n378(x)
+ end
+end
+
+def fun_l0_n375(x)
+ if (x < 1)
+ fun_l1_n372(x)
+ else
+ fun_l1_n406(x)
+ end
+end
+
+def fun_l0_n376(x)
+ if (x < 1)
+ fun_l1_n247(x)
+ else
+ fun_l1_n563(x)
+ end
+end
+
+def fun_l0_n377(x)
+ if (x < 1)
+ fun_l1_n998(x)
+ else
+ fun_l1_n302(x)
+ end
+end
+
+def fun_l0_n378(x)
+ if (x < 1)
+ fun_l1_n955(x)
+ else
+ fun_l1_n333(x)
+ end
+end
+
+def fun_l0_n379(x)
+ if (x < 1)
+ fun_l1_n554(x)
+ else
+ fun_l1_n863(x)
+ end
+end
+
+def fun_l0_n380(x)
+ if (x < 1)
+ fun_l1_n248(x)
+ else
+ fun_l1_n297(x)
+ end
+end
+
+def fun_l0_n381(x)
+ if (x < 1)
+ fun_l1_n85(x)
+ else
+ fun_l1_n726(x)
+ end
+end
+
+def fun_l0_n382(x)
+ if (x < 1)
+ fun_l1_n75(x)
+ else
+ fun_l1_n990(x)
+ end
+end
+
+def fun_l0_n383(x)
+ if (x < 1)
+ fun_l1_n353(x)
+ else
+ fun_l1_n218(x)
+ end
+end
+
+def fun_l0_n384(x)
+ if (x < 1)
+ fun_l1_n103(x)
+ else
+ fun_l1_n192(x)
+ end
+end
+
+def fun_l0_n385(x)
+ if (x < 1)
+ fun_l1_n659(x)
+ else
+ fun_l1_n996(x)
+ end
+end
+
+def fun_l0_n386(x)
+ if (x < 1)
+ fun_l1_n528(x)
+ else
+ fun_l1_n654(x)
+ end
+end
+
+def fun_l0_n387(x)
+ if (x < 1)
+ fun_l1_n857(x)
+ else
+ fun_l1_n638(x)
+ end
+end
+
+def fun_l0_n388(x)
+ if (x < 1)
+ fun_l1_n311(x)
+ else
+ fun_l1_n877(x)
+ end
+end
+
+def fun_l0_n389(x)
+ if (x < 1)
+ fun_l1_n406(x)
+ else
+ fun_l1_n191(x)
+ end
+end
+
+def fun_l0_n390(x)
+ if (x < 1)
+ fun_l1_n464(x)
+ else
+ fun_l1_n684(x)
+ end
+end
+
+def fun_l0_n391(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n635(x)
+ end
+end
+
+def fun_l0_n392(x)
+ if (x < 1)
+ fun_l1_n863(x)
+ else
+ fun_l1_n486(x)
+ end
+end
+
+def fun_l0_n393(x)
+ if (x < 1)
+ fun_l1_n587(x)
+ else
+ fun_l1_n387(x)
+ end
+end
+
+def fun_l0_n394(x)
+ if (x < 1)
+ fun_l1_n553(x)
+ else
+ fun_l1_n789(x)
+ end
+end
+
+def fun_l0_n395(x)
+ if (x < 1)
+ fun_l1_n420(x)
+ else
+ fun_l1_n148(x)
+ end
+end
+
+def fun_l0_n396(x)
+ if (x < 1)
+ fun_l1_n802(x)
+ else
+ fun_l1_n845(x)
+ end
+end
+
+def fun_l0_n397(x)
+ if (x < 1)
+ fun_l1_n749(x)
+ else
+ fun_l1_n742(x)
+ end
+end
+
+def fun_l0_n398(x)
+ if (x < 1)
+ fun_l1_n929(x)
+ else
+ fun_l1_n458(x)
+ end
+end
+
+def fun_l0_n399(x)
+ if (x < 1)
+ fun_l1_n908(x)
+ else
+ fun_l1_n188(x)
+ end
+end
+
+def fun_l0_n400(x)
+ if (x < 1)
+ fun_l1_n932(x)
+ else
+ fun_l1_n854(x)
+ end
+end
+
+def fun_l0_n401(x)
+ if (x < 1)
+ fun_l1_n29(x)
+ else
+ fun_l1_n666(x)
+ end
+end
+
+def fun_l0_n402(x)
+ if (x < 1)
+ fun_l1_n877(x)
+ else
+ fun_l1_n518(x)
+ end
+end
+
+def fun_l0_n403(x)
+ if (x < 1)
+ fun_l1_n639(x)
+ else
+ fun_l1_n618(x)
+ end
+end
+
+def fun_l0_n404(x)
+ if (x < 1)
+ fun_l1_n177(x)
+ else
+ fun_l1_n487(x)
+ end
+end
+
+def fun_l0_n405(x)
+ if (x < 1)
+ fun_l1_n536(x)
+ else
+ fun_l1_n860(x)
+ end
+end
+
+def fun_l0_n406(x)
+ if (x < 1)
+ fun_l1_n626(x)
+ else
+ fun_l1_n894(x)
+ end
+end
+
+def fun_l0_n407(x)
+ if (x < 1)
+ fun_l1_n533(x)
+ else
+ fun_l1_n367(x)
+ end
+end
+
+def fun_l0_n408(x)
+ if (x < 1)
+ fun_l1_n146(x)
+ else
+ fun_l1_n546(x)
+ end
+end
+
+def fun_l0_n409(x)
+ if (x < 1)
+ fun_l1_n872(x)
+ else
+ fun_l1_n387(x)
+ end
+end
+
+def fun_l0_n410(x)
+ if (x < 1)
+ fun_l1_n726(x)
+ else
+ fun_l1_n973(x)
+ end
+end
+
+def fun_l0_n411(x)
+ if (x < 1)
+ fun_l1_n168(x)
+ else
+ fun_l1_n783(x)
+ end
+end
+
+def fun_l0_n412(x)
+ if (x < 1)
+ fun_l1_n895(x)
+ else
+ fun_l1_n901(x)
+ end
+end
+
+def fun_l0_n413(x)
+ if (x < 1)
+ fun_l1_n235(x)
+ else
+ fun_l1_n593(x)
+ end
+end
+
+def fun_l0_n414(x)
+ if (x < 1)
+ fun_l1_n328(x)
+ else
+ fun_l1_n693(x)
+ end
+end
+
+def fun_l0_n415(x)
+ if (x < 1)
+ fun_l1_n882(x)
+ else
+ fun_l1_n290(x)
+ end
+end
+
+def fun_l0_n416(x)
+ if (x < 1)
+ fun_l1_n433(x)
+ else
+ fun_l1_n220(x)
+ end
+end
+
+def fun_l0_n417(x)
+ if (x < 1)
+ fun_l1_n966(x)
+ else
+ fun_l1_n74(x)
+ end
+end
+
+def fun_l0_n418(x)
+ if (x < 1)
+ fun_l1_n750(x)
+ else
+ fun_l1_n547(x)
+ end
+end
+
+def fun_l0_n419(x)
+ if (x < 1)
+ fun_l1_n94(x)
+ else
+ fun_l1_n794(x)
+ end
+end
+
+def fun_l0_n420(x)
+ if (x < 1)
+ fun_l1_n68(x)
+ else
+ fun_l1_n970(x)
+ end
+end
+
+def fun_l0_n421(x)
+ if (x < 1)
+ fun_l1_n663(x)
+ else
+ fun_l1_n388(x)
+ end
+end
+
+def fun_l0_n422(x)
+ if (x < 1)
+ fun_l1_n686(x)
+ else
+ fun_l1_n67(x)
+ end
+end
+
+def fun_l0_n423(x)
+ if (x < 1)
+ fun_l1_n210(x)
+ else
+ fun_l1_n64(x)
+ end
+end
+
+def fun_l0_n424(x)
+ if (x < 1)
+ fun_l1_n375(x)
+ else
+ fun_l1_n205(x)
+ end
+end
+
+def fun_l0_n425(x)
+ if (x < 1)
+ fun_l1_n832(x)
+ else
+ fun_l1_n325(x)
+ end
+end
+
+def fun_l0_n426(x)
+ if (x < 1)
+ fun_l1_n819(x)
+ else
+ fun_l1_n601(x)
+ end
+end
+
+def fun_l0_n427(x)
+ if (x < 1)
+ fun_l1_n588(x)
+ else
+ fun_l1_n875(x)
+ end
+end
+
+def fun_l0_n428(x)
+ if (x < 1)
+ fun_l1_n682(x)
+ else
+ fun_l1_n523(x)
+ end
+end
+
+def fun_l0_n429(x)
+ if (x < 1)
+ fun_l1_n972(x)
+ else
+ fun_l1_n891(x)
+ end
+end
+
+def fun_l0_n430(x)
+ if (x < 1)
+ fun_l1_n90(x)
+ else
+ fun_l1_n655(x)
+ end
+end
+
+def fun_l0_n431(x)
+ if (x < 1)
+ fun_l1_n393(x)
+ else
+ fun_l1_n454(x)
+ end
+end
+
+def fun_l0_n432(x)
+ if (x < 1)
+ fun_l1_n435(x)
+ else
+ fun_l1_n860(x)
+ end
+end
+
+def fun_l0_n433(x)
+ if (x < 1)
+ fun_l1_n516(x)
+ else
+ fun_l1_n246(x)
+ end
+end
+
+def fun_l0_n434(x)
+ if (x < 1)
+ fun_l1_n216(x)
+ else
+ fun_l1_n78(x)
+ end
+end
+
+def fun_l0_n435(x)
+ if (x < 1)
+ fun_l1_n357(x)
+ else
+ fun_l1_n61(x)
+ end
+end
+
+def fun_l0_n436(x)
+ if (x < 1)
+ fun_l1_n289(x)
+ else
+ fun_l1_n507(x)
+ end
+end
+
+def fun_l0_n437(x)
+ if (x < 1)
+ fun_l1_n182(x)
+ else
+ fun_l1_n289(x)
+ end
+end
+
+def fun_l0_n438(x)
+ if (x < 1)
+ fun_l1_n69(x)
+ else
+ fun_l1_n549(x)
+ end
+end
+
+def fun_l0_n439(x)
+ if (x < 1)
+ fun_l1_n275(x)
+ else
+ fun_l1_n723(x)
+ end
+end
+
+def fun_l0_n440(x)
+ if (x < 1)
+ fun_l1_n469(x)
+ else
+ fun_l1_n243(x)
+ end
+end
+
+def fun_l0_n441(x)
+ if (x < 1)
+ fun_l1_n595(x)
+ else
+ fun_l1_n624(x)
+ end
+end
+
+def fun_l0_n442(x)
+ if (x < 1)
+ fun_l1_n655(x)
+ else
+ fun_l1_n896(x)
+ end
+end
+
+def fun_l0_n443(x)
+ if (x < 1)
+ fun_l1_n926(x)
+ else
+ fun_l1_n503(x)
+ end
+end
+
+def fun_l0_n444(x)
+ if (x < 1)
+ fun_l1_n875(x)
+ else
+ fun_l1_n110(x)
+ end
+end
+
+def fun_l0_n445(x)
+ if (x < 1)
+ fun_l1_n832(x)
+ else
+ fun_l1_n154(x)
+ end
+end
+
+def fun_l0_n446(x)
+ if (x < 1)
+ fun_l1_n538(x)
+ else
+ fun_l1_n75(x)
+ end
+end
+
+def fun_l0_n447(x)
+ if (x < 1)
+ fun_l1_n183(x)
+ else
+ fun_l1_n718(x)
+ end
+end
+
+def fun_l0_n448(x)
+ if (x < 1)
+ fun_l1_n680(x)
+ else
+ fun_l1_n93(x)
+ end
+end
+
+def fun_l0_n449(x)
+ if (x < 1)
+ fun_l1_n147(x)
+ else
+ fun_l1_n924(x)
+ end
+end
+
+def fun_l0_n450(x)
+ if (x < 1)
+ fun_l1_n702(x)
+ else
+ fun_l1_n830(x)
+ end
+end
+
+def fun_l0_n451(x)
+ if (x < 1)
+ fun_l1_n750(x)
+ else
+ fun_l1_n447(x)
+ end
+end
+
+def fun_l0_n452(x)
+ if (x < 1)
+ fun_l1_n520(x)
+ else
+ fun_l1_n69(x)
+ end
+end
+
+def fun_l0_n453(x)
+ if (x < 1)
+ fun_l1_n132(x)
+ else
+ fun_l1_n877(x)
+ end
+end
+
+def fun_l0_n454(x)
+ if (x < 1)
+ fun_l1_n247(x)
+ else
+ fun_l1_n69(x)
+ end
+end
+
+def fun_l0_n455(x)
+ if (x < 1)
+ fun_l1_n180(x)
+ else
+ fun_l1_n645(x)
+ end
+end
+
+def fun_l0_n456(x)
+ if (x < 1)
+ fun_l1_n658(x)
+ else
+ fun_l1_n487(x)
+ end
+end
+
+def fun_l0_n457(x)
+ if (x < 1)
+ fun_l1_n276(x)
+ else
+ fun_l1_n528(x)
+ end
+end
+
+def fun_l0_n458(x)
+ if (x < 1)
+ fun_l1_n30(x)
+ else
+ fun_l1_n456(x)
+ end
+end
+
+def fun_l0_n459(x)
+ if (x < 1)
+ fun_l1_n986(x)
+ else
+ fun_l1_n552(x)
+ end
+end
+
+def fun_l0_n460(x)
+ if (x < 1)
+ fun_l1_n874(x)
+ else
+ fun_l1_n396(x)
+ end
+end
+
+def fun_l0_n461(x)
+ if (x < 1)
+ fun_l1_n524(x)
+ else
+ fun_l1_n335(x)
+ end
+end
+
+def fun_l0_n462(x)
+ if (x < 1)
+ fun_l1_n471(x)
+ else
+ fun_l1_n578(x)
+ end
+end
+
+def fun_l0_n463(x)
+ if (x < 1)
+ fun_l1_n173(x)
+ else
+ fun_l1_n456(x)
+ end
+end
+
+def fun_l0_n464(x)
+ if (x < 1)
+ fun_l1_n872(x)
+ else
+ fun_l1_n745(x)
+ end
+end
+
+def fun_l0_n465(x)
+ if (x < 1)
+ fun_l1_n387(x)
+ else
+ fun_l1_n776(x)
+ end
+end
+
+def fun_l0_n466(x)
+ if (x < 1)
+ fun_l1_n119(x)
+ else
+ fun_l1_n428(x)
+ end
+end
+
+def fun_l0_n467(x)
+ if (x < 1)
+ fun_l1_n416(x)
+ else
+ fun_l1_n738(x)
+ end
+end
+
+def fun_l0_n468(x)
+ if (x < 1)
+ fun_l1_n762(x)
+ else
+ fun_l1_n694(x)
+ end
+end
+
+def fun_l0_n469(x)
+ if (x < 1)
+ fun_l1_n27(x)
+ else
+ fun_l1_n562(x)
+ end
+end
+
+def fun_l0_n470(x)
+ if (x < 1)
+ fun_l1_n12(x)
+ else
+ fun_l1_n812(x)
+ end
+end
+
+def fun_l0_n471(x)
+ if (x < 1)
+ fun_l1_n865(x)
+ else
+ fun_l1_n94(x)
+ end
+end
+
+def fun_l0_n472(x)
+ if (x < 1)
+ fun_l1_n346(x)
+ else
+ fun_l1_n39(x)
+ end
+end
+
+def fun_l0_n473(x)
+ if (x < 1)
+ fun_l1_n309(x)
+ else
+ fun_l1_n158(x)
+ end
+end
+
+def fun_l0_n474(x)
+ if (x < 1)
+ fun_l1_n828(x)
+ else
+ fun_l1_n229(x)
+ end
+end
+
+def fun_l0_n475(x)
+ if (x < 1)
+ fun_l1_n554(x)
+ else
+ fun_l1_n121(x)
+ end
+end
+
+def fun_l0_n476(x)
+ if (x < 1)
+ fun_l1_n818(x)
+ else
+ fun_l1_n390(x)
+ end
+end
+
+def fun_l0_n477(x)
+ if (x < 1)
+ fun_l1_n88(x)
+ else
+ fun_l1_n73(x)
+ end
+end
+
+def fun_l0_n478(x)
+ if (x < 1)
+ fun_l1_n709(x)
+ else
+ fun_l1_n680(x)
+ end
+end
+
+def fun_l0_n479(x)
+ if (x < 1)
+ fun_l1_n271(x)
+ else
+ fun_l1_n439(x)
+ end
+end
+
+def fun_l0_n480(x)
+ if (x < 1)
+ fun_l1_n493(x)
+ else
+ fun_l1_n562(x)
+ end
+end
+
+def fun_l0_n481(x)
+ if (x < 1)
+ fun_l1_n642(x)
+ else
+ fun_l1_n221(x)
+ end
+end
+
+def fun_l0_n482(x)
+ if (x < 1)
+ fun_l1_n838(x)
+ else
+ fun_l1_n345(x)
+ end
+end
+
+def fun_l0_n483(x)
+ if (x < 1)
+ fun_l1_n411(x)
+ else
+ fun_l1_n266(x)
+ end
+end
+
+def fun_l0_n484(x)
+ if (x < 1)
+ fun_l1_n916(x)
+ else
+ fun_l1_n791(x)
+ end
+end
+
+def fun_l0_n485(x)
+ if (x < 1)
+ fun_l1_n392(x)
+ else
+ fun_l1_n68(x)
+ end
+end
+
+def fun_l0_n486(x)
+ if (x < 1)
+ fun_l1_n834(x)
+ else
+ fun_l1_n783(x)
+ end
+end
+
+def fun_l0_n487(x)
+ if (x < 1)
+ fun_l1_n398(x)
+ else
+ fun_l1_n627(x)
+ end
+end
+
+def fun_l0_n488(x)
+ if (x < 1)
+ fun_l1_n904(x)
+ else
+ fun_l1_n167(x)
+ end
+end
+
+def fun_l0_n489(x)
+ if (x < 1)
+ fun_l1_n54(x)
+ else
+ fun_l1_n28(x)
+ end
+end
+
+def fun_l0_n490(x)
+ if (x < 1)
+ fun_l1_n24(x)
+ else
+ fun_l1_n9(x)
+ end
+end
+
+def fun_l0_n491(x)
+ if (x < 1)
+ fun_l1_n497(x)
+ else
+ fun_l1_n297(x)
+ end
+end
+
+def fun_l0_n492(x)
+ if (x < 1)
+ fun_l1_n951(x)
+ else
+ fun_l1_n534(x)
+ end
+end
+
+def fun_l0_n493(x)
+ if (x < 1)
+ fun_l1_n213(x)
+ else
+ fun_l1_n808(x)
+ end
+end
+
+def fun_l0_n494(x)
+ if (x < 1)
+ fun_l1_n904(x)
+ else
+ fun_l1_n94(x)
+ end
+end
+
+def fun_l0_n495(x)
+ if (x < 1)
+ fun_l1_n799(x)
+ else
+ fun_l1_n817(x)
+ end
+end
+
+def fun_l0_n496(x)
+ if (x < 1)
+ fun_l1_n45(x)
+ else
+ fun_l1_n860(x)
+ end
+end
+
+def fun_l0_n497(x)
+ if (x < 1)
+ fun_l1_n482(x)
+ else
+ fun_l1_n783(x)
+ end
+end
+
+def fun_l0_n498(x)
+ if (x < 1)
+ fun_l1_n78(x)
+ else
+ fun_l1_n785(x)
+ end
+end
+
+def fun_l0_n499(x)
+ if (x < 1)
+ fun_l1_n174(x)
+ else
+ fun_l1_n87(x)
+ end
+end
+
+def fun_l0_n500(x)
+ if (x < 1)
+ fun_l1_n608(x)
+ else
+ fun_l1_n7(x)
+ end
+end
+
+def fun_l0_n501(x)
+ if (x < 1)
+ fun_l1_n157(x)
+ else
+ fun_l1_n718(x)
+ end
+end
+
+def fun_l0_n502(x)
+ if (x < 1)
+ fun_l1_n823(x)
+ else
+ fun_l1_n549(x)
+ end
+end
+
+def fun_l0_n503(x)
+ if (x < 1)
+ fun_l1_n13(x)
+ else
+ fun_l1_n502(x)
+ end
+end
+
+def fun_l0_n504(x)
+ if (x < 1)
+ fun_l1_n119(x)
+ else
+ fun_l1_n191(x)
+ end
+end
+
+def fun_l0_n505(x)
+ if (x < 1)
+ fun_l1_n503(x)
+ else
+ fun_l1_n974(x)
+ end
+end
+
+def fun_l0_n506(x)
+ if (x < 1)
+ fun_l1_n893(x)
+ else
+ fun_l1_n582(x)
+ end
+end
+
+def fun_l0_n507(x)
+ if (x < 1)
+ fun_l1_n403(x)
+ else
+ fun_l1_n228(x)
+ end
+end
+
+def fun_l0_n508(x)
+ if (x < 1)
+ fun_l1_n640(x)
+ else
+ fun_l1_n362(x)
+ end
+end
+
+def fun_l0_n509(x)
+ if (x < 1)
+ fun_l1_n629(x)
+ else
+ fun_l1_n824(x)
+ end
+end
+
+def fun_l0_n510(x)
+ if (x < 1)
+ fun_l1_n84(x)
+ else
+ fun_l1_n330(x)
+ end
+end
+
+def fun_l0_n511(x)
+ if (x < 1)
+ fun_l1_n91(x)
+ else
+ fun_l1_n523(x)
+ end
+end
+
+def fun_l0_n512(x)
+ if (x < 1)
+ fun_l1_n696(x)
+ else
+ fun_l1_n126(x)
+ end
+end
+
+def fun_l0_n513(x)
+ if (x < 1)
+ fun_l1_n905(x)
+ else
+ fun_l1_n496(x)
+ end
+end
+
+def fun_l0_n514(x)
+ if (x < 1)
+ fun_l1_n766(x)
+ else
+ fun_l1_n523(x)
+ end
+end
+
+def fun_l0_n515(x)
+ if (x < 1)
+ fun_l1_n798(x)
+ else
+ fun_l1_n698(x)
+ end
+end
+
+def fun_l0_n516(x)
+ if (x < 1)
+ fun_l1_n124(x)
+ else
+ fun_l1_n356(x)
+ end
+end
+
+def fun_l0_n517(x)
+ if (x < 1)
+ fun_l1_n289(x)
+ else
+ fun_l1_n782(x)
+ end
+end
+
+def fun_l0_n518(x)
+ if (x < 1)
+ fun_l1_n483(x)
+ else
+ fun_l1_n586(x)
+ end
+end
+
+def fun_l0_n519(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n37(x)
+ end
+end
+
+def fun_l0_n520(x)
+ if (x < 1)
+ fun_l1_n48(x)
+ else
+ fun_l1_n216(x)
+ end
+end
+
+def fun_l0_n521(x)
+ if (x < 1)
+ fun_l1_n805(x)
+ else
+ fun_l1_n846(x)
+ end
+end
+
+def fun_l0_n522(x)
+ if (x < 1)
+ fun_l1_n422(x)
+ else
+ fun_l1_n190(x)
+ end
+end
+
+def fun_l0_n523(x)
+ if (x < 1)
+ fun_l1_n168(x)
+ else
+ fun_l1_n272(x)
+ end
+end
+
+def fun_l0_n524(x)
+ if (x < 1)
+ fun_l1_n766(x)
+ else
+ fun_l1_n125(x)
+ end
+end
+
+def fun_l0_n525(x)
+ if (x < 1)
+ fun_l1_n56(x)
+ else
+ fun_l1_n224(x)
+ end
+end
+
+def fun_l0_n526(x)
+ if (x < 1)
+ fun_l1_n540(x)
+ else
+ fun_l1_n303(x)
+ end
+end
+
+def fun_l0_n527(x)
+ if (x < 1)
+ fun_l1_n846(x)
+ else
+ fun_l1_n955(x)
+ end
+end
+
+def fun_l0_n528(x)
+ if (x < 1)
+ fun_l1_n571(x)
+ else
+ fun_l1_n640(x)
+ end
+end
+
+def fun_l0_n529(x)
+ if (x < 1)
+ fun_l1_n650(x)
+ else
+ fun_l1_n107(x)
+ end
+end
+
+def fun_l0_n530(x)
+ if (x < 1)
+ fun_l1_n240(x)
+ else
+ fun_l1_n139(x)
+ end
+end
+
+def fun_l0_n531(x)
+ if (x < 1)
+ fun_l1_n975(x)
+ else
+ fun_l1_n970(x)
+ end
+end
+
+def fun_l0_n532(x)
+ if (x < 1)
+ fun_l1_n753(x)
+ else
+ fun_l1_n147(x)
+ end
+end
+
+def fun_l0_n533(x)
+ if (x < 1)
+ fun_l1_n269(x)
+ else
+ fun_l1_n292(x)
+ end
+end
+
+def fun_l0_n534(x)
+ if (x < 1)
+ fun_l1_n791(x)
+ else
+ fun_l1_n69(x)
+ end
+end
+
+def fun_l0_n535(x)
+ if (x < 1)
+ fun_l1_n469(x)
+ else
+ fun_l1_n58(x)
+ end
+end
+
+def fun_l0_n536(x)
+ if (x < 1)
+ fun_l1_n526(x)
+ else
+ fun_l1_n265(x)
+ end
+end
+
+def fun_l0_n537(x)
+ if (x < 1)
+ fun_l1_n681(x)
+ else
+ fun_l1_n646(x)
+ end
+end
+
+def fun_l0_n538(x)
+ if (x < 1)
+ fun_l1_n377(x)
+ else
+ fun_l1_n969(x)
+ end
+end
+
+def fun_l0_n539(x)
+ if (x < 1)
+ fun_l1_n935(x)
+ else
+ fun_l1_n556(x)
+ end
+end
+
+def fun_l0_n540(x)
+ if (x < 1)
+ fun_l1_n498(x)
+ else
+ fun_l1_n439(x)
+ end
+end
+
+def fun_l0_n541(x)
+ if (x < 1)
+ fun_l1_n451(x)
+ else
+ fun_l1_n35(x)
+ end
+end
+
+def fun_l0_n542(x)
+ if (x < 1)
+ fun_l1_n32(x)
+ else
+ fun_l1_n795(x)
+ end
+end
+
+def fun_l0_n543(x)
+ if (x < 1)
+ fun_l1_n732(x)
+ else
+ fun_l1_n530(x)
+ end
+end
+
+def fun_l0_n544(x)
+ if (x < 1)
+ fun_l1_n176(x)
+ else
+ fun_l1_n735(x)
+ end
+end
+
+def fun_l0_n545(x)
+ if (x < 1)
+ fun_l1_n34(x)
+ else
+ fun_l1_n989(x)
+ end
+end
+
+def fun_l0_n546(x)
+ if (x < 1)
+ fun_l1_n534(x)
+ else
+ fun_l1_n705(x)
+ end
+end
+
+def fun_l0_n547(x)
+ if (x < 1)
+ fun_l1_n997(x)
+ else
+ fun_l1_n883(x)
+ end
+end
+
+def fun_l0_n548(x)
+ if (x < 1)
+ fun_l1_n379(x)
+ else
+ fun_l1_n33(x)
+ end
+end
+
+def fun_l0_n549(x)
+ if (x < 1)
+ fun_l1_n454(x)
+ else
+ fun_l1_n516(x)
+ end
+end
+
+def fun_l0_n550(x)
+ if (x < 1)
+ fun_l1_n678(x)
+ else
+ fun_l1_n652(x)
+ end
+end
+
+def fun_l0_n551(x)
+ if (x < 1)
+ fun_l1_n13(x)
+ else
+ fun_l1_n864(x)
+ end
+end
+
+def fun_l0_n552(x)
+ if (x < 1)
+ fun_l1_n178(x)
+ else
+ fun_l1_n996(x)
+ end
+end
+
+def fun_l0_n553(x)
+ if (x < 1)
+ fun_l1_n865(x)
+ else
+ fun_l1_n703(x)
+ end
+end
+
+def fun_l0_n554(x)
+ if (x < 1)
+ fun_l1_n306(x)
+ else
+ fun_l1_n24(x)
+ end
+end
+
+def fun_l0_n555(x)
+ if (x < 1)
+ fun_l1_n110(x)
+ else
+ fun_l1_n123(x)
+ end
+end
+
+def fun_l0_n556(x)
+ if (x < 1)
+ fun_l1_n367(x)
+ else
+ fun_l1_n117(x)
+ end
+end
+
+def fun_l0_n557(x)
+ if (x < 1)
+ fun_l1_n967(x)
+ else
+ fun_l1_n662(x)
+ end
+end
+
+def fun_l0_n558(x)
+ if (x < 1)
+ fun_l1_n68(x)
+ else
+ fun_l1_n47(x)
+ end
+end
+
+def fun_l0_n559(x)
+ if (x < 1)
+ fun_l1_n154(x)
+ else
+ fun_l1_n344(x)
+ end
+end
+
+def fun_l0_n560(x)
+ if (x < 1)
+ fun_l1_n835(x)
+ else
+ fun_l1_n577(x)
+ end
+end
+
+def fun_l0_n561(x)
+ if (x < 1)
+ fun_l1_n393(x)
+ else
+ fun_l1_n419(x)
+ end
+end
+
+def fun_l0_n562(x)
+ if (x < 1)
+ fun_l1_n632(x)
+ else
+ fun_l1_n630(x)
+ end
+end
+
+def fun_l0_n563(x)
+ if (x < 1)
+ fun_l1_n9(x)
+ else
+ fun_l1_n109(x)
+ end
+end
+
+def fun_l0_n564(x)
+ if (x < 1)
+ fun_l1_n65(x)
+ else
+ fun_l1_n123(x)
+ end
+end
+
+def fun_l0_n565(x)
+ if (x < 1)
+ fun_l1_n156(x)
+ else
+ fun_l1_n921(x)
+ end
+end
+
+def fun_l0_n566(x)
+ if (x < 1)
+ fun_l1_n88(x)
+ else
+ fun_l1_n743(x)
+ end
+end
+
+def fun_l0_n567(x)
+ if (x < 1)
+ fun_l1_n92(x)
+ else
+ fun_l1_n27(x)
+ end
+end
+
+def fun_l0_n568(x)
+ if (x < 1)
+ fun_l1_n462(x)
+ else
+ fun_l1_n988(x)
+ end
+end
+
+def fun_l0_n569(x)
+ if (x < 1)
+ fun_l1_n241(x)
+ else
+ fun_l1_n199(x)
+ end
+end
+
+def fun_l0_n570(x)
+ if (x < 1)
+ fun_l1_n429(x)
+ else
+ fun_l1_n530(x)
+ end
+end
+
+def fun_l0_n571(x)
+ if (x < 1)
+ fun_l1_n412(x)
+ else
+ fun_l1_n530(x)
+ end
+end
+
+def fun_l0_n572(x)
+ if (x < 1)
+ fun_l1_n100(x)
+ else
+ fun_l1_n270(x)
+ end
+end
+
+def fun_l0_n573(x)
+ if (x < 1)
+ fun_l1_n326(x)
+ else
+ fun_l1_n191(x)
+ end
+end
+
+def fun_l0_n574(x)
+ if (x < 1)
+ fun_l1_n151(x)
+ else
+ fun_l1_n354(x)
+ end
+end
+
+def fun_l0_n575(x)
+ if (x < 1)
+ fun_l1_n322(x)
+ else
+ fun_l1_n534(x)
+ end
+end
+
+def fun_l0_n576(x)
+ if (x < 1)
+ fun_l1_n995(x)
+ else
+ fun_l1_n658(x)
+ end
+end
+
+def fun_l0_n577(x)
+ if (x < 1)
+ fun_l1_n193(x)
+ else
+ fun_l1_n444(x)
+ end
+end
+
+def fun_l0_n578(x)
+ if (x < 1)
+ fun_l1_n527(x)
+ else
+ fun_l1_n517(x)
+ end
+end
+
+def fun_l0_n579(x)
+ if (x < 1)
+ fun_l1_n885(x)
+ else
+ fun_l1_n218(x)
+ end
+end
+
+def fun_l0_n580(x)
+ if (x < 1)
+ fun_l1_n789(x)
+ else
+ fun_l1_n711(x)
+ end
+end
+
+def fun_l0_n581(x)
+ if (x < 1)
+ fun_l1_n848(x)
+ else
+ fun_l1_n321(x)
+ end
+end
+
+def fun_l0_n582(x)
+ if (x < 1)
+ fun_l1_n389(x)
+ else
+ fun_l1_n360(x)
+ end
+end
+
+def fun_l0_n583(x)
+ if (x < 1)
+ fun_l1_n319(x)
+ else
+ fun_l1_n972(x)
+ end
+end
+
+def fun_l0_n584(x)
+ if (x < 1)
+ fun_l1_n421(x)
+ else
+ fun_l1_n659(x)
+ end
+end
+
+def fun_l0_n585(x)
+ if (x < 1)
+ fun_l1_n462(x)
+ else
+ fun_l1_n302(x)
+ end
+end
+
+def fun_l0_n586(x)
+ if (x < 1)
+ fun_l1_n122(x)
+ else
+ fun_l1_n50(x)
+ end
+end
+
+def fun_l0_n587(x)
+ if (x < 1)
+ fun_l1_n795(x)
+ else
+ fun_l1_n622(x)
+ end
+end
+
+def fun_l0_n588(x)
+ if (x < 1)
+ fun_l1_n719(x)
+ else
+ fun_l1_n390(x)
+ end
+end
+
+def fun_l0_n589(x)
+ if (x < 1)
+ fun_l1_n916(x)
+ else
+ fun_l1_n925(x)
+ end
+end
+
+def fun_l0_n590(x)
+ if (x < 1)
+ fun_l1_n541(x)
+ else
+ fun_l1_n139(x)
+ end
+end
+
+def fun_l0_n591(x)
+ if (x < 1)
+ fun_l1_n610(x)
+ else
+ fun_l1_n509(x)
+ end
+end
+
+def fun_l0_n592(x)
+ if (x < 1)
+ fun_l1_n217(x)
+ else
+ fun_l1_n452(x)
+ end
+end
+
+def fun_l0_n593(x)
+ if (x < 1)
+ fun_l1_n456(x)
+ else
+ fun_l1_n888(x)
+ end
+end
+
+def fun_l0_n594(x)
+ if (x < 1)
+ fun_l1_n987(x)
+ else
+ fun_l1_n462(x)
+ end
+end
+
+def fun_l0_n595(x)
+ if (x < 1)
+ fun_l1_n571(x)
+ else
+ fun_l1_n429(x)
+ end
+end
+
+def fun_l0_n596(x)
+ if (x < 1)
+ fun_l1_n751(x)
+ else
+ fun_l1_n773(x)
+ end
+end
+
+def fun_l0_n597(x)
+ if (x < 1)
+ fun_l1_n181(x)
+ else
+ fun_l1_n340(x)
+ end
+end
+
+def fun_l0_n598(x)
+ if (x < 1)
+ fun_l1_n6(x)
+ else
+ fun_l1_n39(x)
+ end
+end
+
+def fun_l0_n599(x)
+ if (x < 1)
+ fun_l1_n814(x)
+ else
+ fun_l1_n320(x)
+ end
+end
+
+def fun_l0_n600(x)
+ if (x < 1)
+ fun_l1_n931(x)
+ else
+ fun_l1_n535(x)
+ end
+end
+
+def fun_l0_n601(x)
+ if (x < 1)
+ fun_l1_n99(x)
+ else
+ fun_l1_n154(x)
+ end
+end
+
+def fun_l0_n602(x)
+ if (x < 1)
+ fun_l1_n981(x)
+ else
+ fun_l1_n817(x)
+ end
+end
+
+def fun_l0_n603(x)
+ if (x < 1)
+ fun_l1_n975(x)
+ else
+ fun_l1_n364(x)
+ end
+end
+
+def fun_l0_n604(x)
+ if (x < 1)
+ fun_l1_n112(x)
+ else
+ fun_l1_n226(x)
+ end
+end
+
+def fun_l0_n605(x)
+ if (x < 1)
+ fun_l1_n995(x)
+ else
+ fun_l1_n95(x)
+ end
+end
+
+def fun_l0_n606(x)
+ if (x < 1)
+ fun_l1_n930(x)
+ else
+ fun_l1_n77(x)
+ end
+end
+
+def fun_l0_n607(x)
+ if (x < 1)
+ fun_l1_n899(x)
+ else
+ fun_l1_n957(x)
+ end
+end
+
+def fun_l0_n608(x)
+ if (x < 1)
+ fun_l1_n844(x)
+ else
+ fun_l1_n119(x)
+ end
+end
+
+def fun_l0_n609(x)
+ if (x < 1)
+ fun_l1_n861(x)
+ else
+ fun_l1_n74(x)
+ end
+end
+
+def fun_l0_n610(x)
+ if (x < 1)
+ fun_l1_n521(x)
+ else
+ fun_l1_n46(x)
+ end
+end
+
+def fun_l0_n611(x)
+ if (x < 1)
+ fun_l1_n258(x)
+ else
+ fun_l1_n208(x)
+ end
+end
+
+def fun_l0_n612(x)
+ if (x < 1)
+ fun_l1_n620(x)
+ else
+ fun_l1_n427(x)
+ end
+end
+
+def fun_l0_n613(x)
+ if (x < 1)
+ fun_l1_n583(x)
+ else
+ fun_l1_n400(x)
+ end
+end
+
+def fun_l0_n614(x)
+ if (x < 1)
+ fun_l1_n933(x)
+ else
+ fun_l1_n810(x)
+ end
+end
+
+def fun_l0_n615(x)
+ if (x < 1)
+ fun_l1_n154(x)
+ else
+ fun_l1_n879(x)
+ end
+end
+
+def fun_l0_n616(x)
+ if (x < 1)
+ fun_l1_n715(x)
+ else
+ fun_l1_n862(x)
+ end
+end
+
+def fun_l0_n617(x)
+ if (x < 1)
+ fun_l1_n178(x)
+ else
+ fun_l1_n285(x)
+ end
+end
+
+def fun_l0_n618(x)
+ if (x < 1)
+ fun_l1_n458(x)
+ else
+ fun_l1_n217(x)
+ end
+end
+
+def fun_l0_n619(x)
+ if (x < 1)
+ fun_l1_n655(x)
+ else
+ fun_l1_n405(x)
+ end
+end
+
+def fun_l0_n620(x)
+ if (x < 1)
+ fun_l1_n470(x)
+ else
+ fun_l1_n306(x)
+ end
+end
+
+def fun_l0_n621(x)
+ if (x < 1)
+ fun_l1_n755(x)
+ else
+ fun_l1_n425(x)
+ end
+end
+
+def fun_l0_n622(x)
+ if (x < 1)
+ fun_l1_n426(x)
+ else
+ fun_l1_n737(x)
+ end
+end
+
+def fun_l0_n623(x)
+ if (x < 1)
+ fun_l1_n79(x)
+ else
+ fun_l1_n55(x)
+ end
+end
+
+def fun_l0_n624(x)
+ if (x < 1)
+ fun_l1_n437(x)
+ else
+ fun_l1_n79(x)
+ end
+end
+
+def fun_l0_n625(x)
+ if (x < 1)
+ fun_l1_n691(x)
+ else
+ fun_l1_n198(x)
+ end
+end
+
+def fun_l0_n626(x)
+ if (x < 1)
+ fun_l1_n703(x)
+ else
+ fun_l1_n585(x)
+ end
+end
+
+def fun_l0_n627(x)
+ if (x < 1)
+ fun_l1_n966(x)
+ else
+ fun_l1_n425(x)
+ end
+end
+
+def fun_l0_n628(x)
+ if (x < 1)
+ fun_l1_n516(x)
+ else
+ fun_l1_n744(x)
+ end
+end
+
+def fun_l0_n629(x)
+ if (x < 1)
+ fun_l1_n40(x)
+ else
+ fun_l1_n942(x)
+ end
+end
+
+def fun_l0_n630(x)
+ if (x < 1)
+ fun_l1_n528(x)
+ else
+ fun_l1_n440(x)
+ end
+end
+
+def fun_l0_n631(x)
+ if (x < 1)
+ fun_l1_n139(x)
+ else
+ fun_l1_n403(x)
+ end
+end
+
+def fun_l0_n632(x)
+ if (x < 1)
+ fun_l1_n421(x)
+ else
+ fun_l1_n510(x)
+ end
+end
+
+def fun_l0_n633(x)
+ if (x < 1)
+ fun_l1_n718(x)
+ else
+ fun_l1_n388(x)
+ end
+end
+
+def fun_l0_n634(x)
+ if (x < 1)
+ fun_l1_n67(x)
+ else
+ fun_l1_n342(x)
+ end
+end
+
+def fun_l0_n635(x)
+ if (x < 1)
+ fun_l1_n943(x)
+ else
+ fun_l1_n941(x)
+ end
+end
+
+def fun_l0_n636(x)
+ if (x < 1)
+ fun_l1_n170(x)
+ else
+ fun_l1_n527(x)
+ end
+end
+
+def fun_l0_n637(x)
+ if (x < 1)
+ fun_l1_n336(x)
+ else
+ fun_l1_n496(x)
+ end
+end
+
+def fun_l0_n638(x)
+ if (x < 1)
+ fun_l1_n730(x)
+ else
+ fun_l1_n10(x)
+ end
+end
+
+def fun_l0_n639(x)
+ if (x < 1)
+ fun_l1_n939(x)
+ else
+ fun_l1_n940(x)
+ end
+end
+
+def fun_l0_n640(x)
+ if (x < 1)
+ fun_l1_n73(x)
+ else
+ fun_l1_n439(x)
+ end
+end
+
+def fun_l0_n641(x)
+ if (x < 1)
+ fun_l1_n460(x)
+ else
+ fun_l1_n828(x)
+ end
+end
+
+def fun_l0_n642(x)
+ if (x < 1)
+ fun_l1_n90(x)
+ else
+ fun_l1_n113(x)
+ end
+end
+
+def fun_l0_n643(x)
+ if (x < 1)
+ fun_l1_n972(x)
+ else
+ fun_l1_n15(x)
+ end
+end
+
+def fun_l0_n644(x)
+ if (x < 1)
+ fun_l1_n417(x)
+ else
+ fun_l1_n228(x)
+ end
+end
+
+def fun_l0_n645(x)
+ if (x < 1)
+ fun_l1_n876(x)
+ else
+ fun_l1_n152(x)
+ end
+end
+
+def fun_l0_n646(x)
+ if (x < 1)
+ fun_l1_n404(x)
+ else
+ fun_l1_n147(x)
+ end
+end
+
+def fun_l0_n647(x)
+ if (x < 1)
+ fun_l1_n802(x)
+ else
+ fun_l1_n824(x)
+ end
+end
+
+def fun_l0_n648(x)
+ if (x < 1)
+ fun_l1_n771(x)
+ else
+ fun_l1_n421(x)
+ end
+end
+
+def fun_l0_n649(x)
+ if (x < 1)
+ fun_l1_n807(x)
+ else
+ fun_l1_n955(x)
+ end
+end
+
+def fun_l0_n650(x)
+ if (x < 1)
+ fun_l1_n221(x)
+ else
+ fun_l1_n367(x)
+ end
+end
+
+def fun_l0_n651(x)
+ if (x < 1)
+ fun_l1_n955(x)
+ else
+ fun_l1_n401(x)
+ end
+end
+
+def fun_l0_n652(x)
+ if (x < 1)
+ fun_l1_n203(x)
+ else
+ fun_l1_n909(x)
+ end
+end
+
+def fun_l0_n653(x)
+ if (x < 1)
+ fun_l1_n154(x)
+ else
+ fun_l1_n535(x)
+ end
+end
+
+def fun_l0_n654(x)
+ if (x < 1)
+ fun_l1_n420(x)
+ else
+ fun_l1_n393(x)
+ end
+end
+
+def fun_l0_n655(x)
+ if (x < 1)
+ fun_l1_n232(x)
+ else
+ fun_l1_n981(x)
+ end
+end
+
+def fun_l0_n656(x)
+ if (x < 1)
+ fun_l1_n873(x)
+ else
+ fun_l1_n510(x)
+ end
+end
+
+def fun_l0_n657(x)
+ if (x < 1)
+ fun_l1_n919(x)
+ else
+ fun_l1_n706(x)
+ end
+end
+
+def fun_l0_n658(x)
+ if (x < 1)
+ fun_l1_n429(x)
+ else
+ fun_l1_n112(x)
+ end
+end
+
+def fun_l0_n659(x)
+ if (x < 1)
+ fun_l1_n547(x)
+ else
+ fun_l1_n712(x)
+ end
+end
+
+def fun_l0_n660(x)
+ if (x < 1)
+ fun_l1_n498(x)
+ else
+ fun_l1_n695(x)
+ end
+end
+
+def fun_l0_n661(x)
+ if (x < 1)
+ fun_l1_n801(x)
+ else
+ fun_l1_n659(x)
+ end
+end
+
+def fun_l0_n662(x)
+ if (x < 1)
+ fun_l1_n796(x)
+ else
+ fun_l1_n229(x)
+ end
+end
+
+def fun_l0_n663(x)
+ if (x < 1)
+ fun_l1_n11(x)
+ else
+ fun_l1_n620(x)
+ end
+end
+
+def fun_l0_n664(x)
+ if (x < 1)
+ fun_l1_n652(x)
+ else
+ fun_l1_n416(x)
+ end
+end
+
+def fun_l0_n665(x)
+ if (x < 1)
+ fun_l1_n655(x)
+ else
+ fun_l1_n331(x)
+ end
+end
+
+def fun_l0_n666(x)
+ if (x < 1)
+ fun_l1_n846(x)
+ else
+ fun_l1_n1(x)
+ end
+end
+
+def fun_l0_n667(x)
+ if (x < 1)
+ fun_l1_n55(x)
+ else
+ fun_l1_n32(x)
+ end
+end
+
+def fun_l0_n668(x)
+ if (x < 1)
+ fun_l1_n241(x)
+ else
+ fun_l1_n627(x)
+ end
+end
+
+def fun_l0_n669(x)
+ if (x < 1)
+ fun_l1_n234(x)
+ else
+ fun_l1_n996(x)
+ end
+end
+
+def fun_l0_n670(x)
+ if (x < 1)
+ fun_l1_n235(x)
+ else
+ fun_l1_n761(x)
+ end
+end
+
+def fun_l0_n671(x)
+ if (x < 1)
+ fun_l1_n990(x)
+ else
+ fun_l1_n236(x)
+ end
+end
+
+def fun_l0_n672(x)
+ if (x < 1)
+ fun_l1_n970(x)
+ else
+ fun_l1_n595(x)
+ end
+end
+
+def fun_l0_n673(x)
+ if (x < 1)
+ fun_l1_n294(x)
+ else
+ fun_l1_n440(x)
+ end
+end
+
+def fun_l0_n674(x)
+ if (x < 1)
+ fun_l1_n597(x)
+ else
+ fun_l1_n956(x)
+ end
+end
+
+def fun_l0_n675(x)
+ if (x < 1)
+ fun_l1_n942(x)
+ else
+ fun_l1_n352(x)
+ end
+end
+
+def fun_l0_n676(x)
+ if (x < 1)
+ fun_l1_n309(x)
+ else
+ fun_l1_n294(x)
+ end
+end
+
+def fun_l0_n677(x)
+ if (x < 1)
+ fun_l1_n752(x)
+ else
+ fun_l1_n447(x)
+ end
+end
+
+def fun_l0_n678(x)
+ if (x < 1)
+ fun_l1_n890(x)
+ else
+ fun_l1_n497(x)
+ end
+end
+
+def fun_l0_n679(x)
+ if (x < 1)
+ fun_l1_n808(x)
+ else
+ fun_l1_n881(x)
+ end
+end
+
+def fun_l0_n680(x)
+ if (x < 1)
+ fun_l1_n966(x)
+ else
+ fun_l1_n460(x)
+ end
+end
+
+def fun_l0_n681(x)
+ if (x < 1)
+ fun_l1_n104(x)
+ else
+ fun_l1_n262(x)
+ end
+end
+
+def fun_l0_n682(x)
+ if (x < 1)
+ fun_l1_n425(x)
+ else
+ fun_l1_n177(x)
+ end
+end
+
+def fun_l0_n683(x)
+ if (x < 1)
+ fun_l1_n15(x)
+ else
+ fun_l1_n458(x)
+ end
+end
+
+def fun_l0_n684(x)
+ if (x < 1)
+ fun_l1_n760(x)
+ else
+ fun_l1_n997(x)
+ end
+end
+
+def fun_l0_n685(x)
+ if (x < 1)
+ fun_l1_n496(x)
+ else
+ fun_l1_n223(x)
+ end
+end
+
+def fun_l0_n686(x)
+ if (x < 1)
+ fun_l1_n363(x)
+ else
+ fun_l1_n543(x)
+ end
+end
+
+def fun_l0_n687(x)
+ if (x < 1)
+ fun_l1_n758(x)
+ else
+ fun_l1_n473(x)
+ end
+end
+
+def fun_l0_n688(x)
+ if (x < 1)
+ fun_l1_n854(x)
+ else
+ fun_l1_n999(x)
+ end
+end
+
+def fun_l0_n689(x)
+ if (x < 1)
+ fun_l1_n336(x)
+ else
+ fun_l1_n388(x)
+ end
+end
+
+def fun_l0_n690(x)
+ if (x < 1)
+ fun_l1_n930(x)
+ else
+ fun_l1_n478(x)
+ end
+end
+
+def fun_l0_n691(x)
+ if (x < 1)
+ fun_l1_n423(x)
+ else
+ fun_l1_n83(x)
+ end
+end
+
+def fun_l0_n692(x)
+ if (x < 1)
+ fun_l1_n797(x)
+ else
+ fun_l1_n427(x)
+ end
+end
+
+def fun_l0_n693(x)
+ if (x < 1)
+ fun_l1_n907(x)
+ else
+ fun_l1_n1(x)
+ end
+end
+
+def fun_l0_n694(x)
+ if (x < 1)
+ fun_l1_n601(x)
+ else
+ fun_l1_n809(x)
+ end
+end
+
+def fun_l0_n695(x)
+ if (x < 1)
+ fun_l1_n252(x)
+ else
+ fun_l1_n233(x)
+ end
+end
+
+def fun_l0_n696(x)
+ if (x < 1)
+ fun_l1_n36(x)
+ else
+ fun_l1_n796(x)
+ end
+end
+
+def fun_l0_n697(x)
+ if (x < 1)
+ fun_l1_n893(x)
+ else
+ fun_l1_n926(x)
+ end
+end
+
+def fun_l0_n698(x)
+ if (x < 1)
+ fun_l1_n511(x)
+ else
+ fun_l1_n88(x)
+ end
+end
+
+def fun_l0_n699(x)
+ if (x < 1)
+ fun_l1_n573(x)
+ else
+ fun_l1_n718(x)
+ end
+end
+
+def fun_l0_n700(x)
+ if (x < 1)
+ fun_l1_n475(x)
+ else
+ fun_l1_n539(x)
+ end
+end
+
+def fun_l0_n701(x)
+ if (x < 1)
+ fun_l1_n238(x)
+ else
+ fun_l1_n253(x)
+ end
+end
+
+def fun_l0_n702(x)
+ if (x < 1)
+ fun_l1_n731(x)
+ else
+ fun_l1_n225(x)
+ end
+end
+
+def fun_l0_n703(x)
+ if (x < 1)
+ fun_l1_n594(x)
+ else
+ fun_l1_n16(x)
+ end
+end
+
+def fun_l0_n704(x)
+ if (x < 1)
+ fun_l1_n732(x)
+ else
+ fun_l1_n354(x)
+ end
+end
+
+def fun_l0_n705(x)
+ if (x < 1)
+ fun_l1_n812(x)
+ else
+ fun_l1_n218(x)
+ end
+end
+
+def fun_l0_n706(x)
+ if (x < 1)
+ fun_l1_n731(x)
+ else
+ fun_l1_n343(x)
+ end
+end
+
+def fun_l0_n707(x)
+ if (x < 1)
+ fun_l1_n134(x)
+ else
+ fun_l1_n752(x)
+ end
+end
+
+def fun_l0_n708(x)
+ if (x < 1)
+ fun_l1_n899(x)
+ else
+ fun_l1_n854(x)
+ end
+end
+
+def fun_l0_n709(x)
+ if (x < 1)
+ fun_l1_n120(x)
+ else
+ fun_l1_n193(x)
+ end
+end
+
+def fun_l0_n710(x)
+ if (x < 1)
+ fun_l1_n22(x)
+ else
+ fun_l1_n254(x)
+ end
+end
+
+def fun_l0_n711(x)
+ if (x < 1)
+ fun_l1_n527(x)
+ else
+ fun_l1_n921(x)
+ end
+end
+
+def fun_l0_n712(x)
+ if (x < 1)
+ fun_l1_n820(x)
+ else
+ fun_l1_n96(x)
+ end
+end
+
+def fun_l0_n713(x)
+ if (x < 1)
+ fun_l1_n145(x)
+ else
+ fun_l1_n226(x)
+ end
+end
+
+def fun_l0_n714(x)
+ if (x < 1)
+ fun_l1_n643(x)
+ else
+ fun_l1_n407(x)
+ end
+end
+
+def fun_l0_n715(x)
+ if (x < 1)
+ fun_l1_n349(x)
+ else
+ fun_l1_n450(x)
+ end
+end
+
+def fun_l0_n716(x)
+ if (x < 1)
+ fun_l1_n954(x)
+ else
+ fun_l1_n707(x)
+ end
+end
+
+def fun_l0_n717(x)
+ if (x < 1)
+ fun_l1_n723(x)
+ else
+ fun_l1_n762(x)
+ end
+end
+
+def fun_l0_n718(x)
+ if (x < 1)
+ fun_l1_n299(x)
+ else
+ fun_l1_n332(x)
+ end
+end
+
+def fun_l0_n719(x)
+ if (x < 1)
+ fun_l1_n493(x)
+ else
+ fun_l1_n521(x)
+ end
+end
+
+def fun_l0_n720(x)
+ if (x < 1)
+ fun_l1_n39(x)
+ else
+ fun_l1_n17(x)
+ end
+end
+
+def fun_l0_n721(x)
+ if (x < 1)
+ fun_l1_n297(x)
+ else
+ fun_l1_n800(x)
+ end
+end
+
+def fun_l0_n722(x)
+ if (x < 1)
+ fun_l1_n758(x)
+ else
+ fun_l1_n135(x)
+ end
+end
+
+def fun_l0_n723(x)
+ if (x < 1)
+ fun_l1_n471(x)
+ else
+ fun_l1_n351(x)
+ end
+end
+
+def fun_l0_n724(x)
+ if (x < 1)
+ fun_l1_n381(x)
+ else
+ fun_l1_n281(x)
+ end
+end
+
+def fun_l0_n725(x)
+ if (x < 1)
+ fun_l1_n624(x)
+ else
+ fun_l1_n162(x)
+ end
+end
+
+def fun_l0_n726(x)
+ if (x < 1)
+ fun_l1_n143(x)
+ else
+ fun_l1_n417(x)
+ end
+end
+
+def fun_l0_n727(x)
+ if (x < 1)
+ fun_l1_n623(x)
+ else
+ fun_l1_n19(x)
+ end
+end
+
+def fun_l0_n728(x)
+ if (x < 1)
+ fun_l1_n687(x)
+ else
+ fun_l1_n574(x)
+ end
+end
+
+def fun_l0_n729(x)
+ if (x < 1)
+ fun_l1_n225(x)
+ else
+ fun_l1_n871(x)
+ end
+end
+
+def fun_l0_n730(x)
+ if (x < 1)
+ fun_l1_n830(x)
+ else
+ fun_l1_n273(x)
+ end
+end
+
+def fun_l0_n731(x)
+ if (x < 1)
+ fun_l1_n95(x)
+ else
+ fun_l1_n864(x)
+ end
+end
+
+def fun_l0_n732(x)
+ if (x < 1)
+ fun_l1_n902(x)
+ else
+ fun_l1_n522(x)
+ end
+end
+
+def fun_l0_n733(x)
+ if (x < 1)
+ fun_l1_n564(x)
+ else
+ fun_l1_n55(x)
+ end
+end
+
+def fun_l0_n734(x)
+ if (x < 1)
+ fun_l1_n481(x)
+ else
+ fun_l1_n880(x)
+ end
+end
+
+def fun_l0_n735(x)
+ if (x < 1)
+ fun_l1_n87(x)
+ else
+ fun_l1_n693(x)
+ end
+end
+
+def fun_l0_n736(x)
+ if (x < 1)
+ fun_l1_n72(x)
+ else
+ fun_l1_n396(x)
+ end
+end
+
+def fun_l0_n737(x)
+ if (x < 1)
+ fun_l1_n920(x)
+ else
+ fun_l1_n852(x)
+ end
+end
+
+def fun_l0_n738(x)
+ if (x < 1)
+ fun_l1_n342(x)
+ else
+ fun_l1_n959(x)
+ end
+end
+
+def fun_l0_n739(x)
+ if (x < 1)
+ fun_l1_n682(x)
+ else
+ fun_l1_n714(x)
+ end
+end
+
+def fun_l0_n740(x)
+ if (x < 1)
+ fun_l1_n264(x)
+ else
+ fun_l1_n325(x)
+ end
+end
+
+def fun_l0_n741(x)
+ if (x < 1)
+ fun_l1_n621(x)
+ else
+ fun_l1_n339(x)
+ end
+end
+
+def fun_l0_n742(x)
+ if (x < 1)
+ fun_l1_n46(x)
+ else
+ fun_l1_n766(x)
+ end
+end
+
+def fun_l0_n743(x)
+ if (x < 1)
+ fun_l1_n333(x)
+ else
+ fun_l1_n353(x)
+ end
+end
+
+def fun_l0_n744(x)
+ if (x < 1)
+ fun_l1_n930(x)
+ else
+ fun_l1_n964(x)
+ end
+end
+
+def fun_l0_n745(x)
+ if (x < 1)
+ fun_l1_n785(x)
+ else
+ fun_l1_n114(x)
+ end
+end
+
+def fun_l0_n746(x)
+ if (x < 1)
+ fun_l1_n402(x)
+ else
+ fun_l1_n803(x)
+ end
+end
+
+def fun_l0_n747(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n870(x)
+ end
+end
+
+def fun_l0_n748(x)
+ if (x < 1)
+ fun_l1_n683(x)
+ else
+ fun_l1_n287(x)
+ end
+end
+
+def fun_l0_n749(x)
+ if (x < 1)
+ fun_l1_n816(x)
+ else
+ fun_l1_n849(x)
+ end
+end
+
+def fun_l0_n750(x)
+ if (x < 1)
+ fun_l1_n523(x)
+ else
+ fun_l1_n555(x)
+ end
+end
+
+def fun_l0_n751(x)
+ if (x < 1)
+ fun_l1_n270(x)
+ else
+ fun_l1_n660(x)
+ end
+end
+
+def fun_l0_n752(x)
+ if (x < 1)
+ fun_l1_n786(x)
+ else
+ fun_l1_n749(x)
+ end
+end
+
+def fun_l0_n753(x)
+ if (x < 1)
+ fun_l1_n567(x)
+ else
+ fun_l1_n325(x)
+ end
+end
+
+def fun_l0_n754(x)
+ if (x < 1)
+ fun_l1_n502(x)
+ else
+ fun_l1_n610(x)
+ end
+end
+
+def fun_l0_n755(x)
+ if (x < 1)
+ fun_l1_n336(x)
+ else
+ fun_l1_n354(x)
+ end
+end
+
+def fun_l0_n756(x)
+ if (x < 1)
+ fun_l1_n435(x)
+ else
+ fun_l1_n484(x)
+ end
+end
+
+def fun_l0_n757(x)
+ if (x < 1)
+ fun_l1_n849(x)
+ else
+ fun_l1_n42(x)
+ end
+end
+
+def fun_l0_n758(x)
+ if (x < 1)
+ fun_l1_n294(x)
+ else
+ fun_l1_n483(x)
+ end
+end
+
+def fun_l0_n759(x)
+ if (x < 1)
+ fun_l1_n14(x)
+ else
+ fun_l1_n9(x)
+ end
+end
+
+def fun_l0_n760(x)
+ if (x < 1)
+ fun_l1_n860(x)
+ else
+ fun_l1_n645(x)
+ end
+end
+
+def fun_l0_n761(x)
+ if (x < 1)
+ fun_l1_n577(x)
+ else
+ fun_l1_n0(x)
+ end
+end
+
+def fun_l0_n762(x)
+ if (x < 1)
+ fun_l1_n28(x)
+ else
+ fun_l1_n834(x)
+ end
+end
+
+def fun_l0_n763(x)
+ if (x < 1)
+ fun_l1_n147(x)
+ else
+ fun_l1_n177(x)
+ end
+end
+
+def fun_l0_n764(x)
+ if (x < 1)
+ fun_l1_n429(x)
+ else
+ fun_l1_n646(x)
+ end
+end
+
+def fun_l0_n765(x)
+ if (x < 1)
+ fun_l1_n474(x)
+ else
+ fun_l1_n22(x)
+ end
+end
+
+def fun_l0_n766(x)
+ if (x < 1)
+ fun_l1_n264(x)
+ else
+ fun_l1_n549(x)
+ end
+end
+
+def fun_l0_n767(x)
+ if (x < 1)
+ fun_l1_n351(x)
+ else
+ fun_l1_n813(x)
+ end
+end
+
+def fun_l0_n768(x)
+ if (x < 1)
+ fun_l1_n798(x)
+ else
+ fun_l1_n684(x)
+ end
+end
+
+def fun_l0_n769(x)
+ if (x < 1)
+ fun_l1_n202(x)
+ else
+ fun_l1_n982(x)
+ end
+end
+
+def fun_l0_n770(x)
+ if (x < 1)
+ fun_l1_n611(x)
+ else
+ fun_l1_n52(x)
+ end
+end
+
+def fun_l0_n771(x)
+ if (x < 1)
+ fun_l1_n754(x)
+ else
+ fun_l1_n7(x)
+ end
+end
+
+def fun_l0_n772(x)
+ if (x < 1)
+ fun_l1_n98(x)
+ else
+ fun_l1_n149(x)
+ end
+end
+
+def fun_l0_n773(x)
+ if (x < 1)
+ fun_l1_n358(x)
+ else
+ fun_l1_n603(x)
+ end
+end
+
+def fun_l0_n774(x)
+ if (x < 1)
+ fun_l1_n604(x)
+ else
+ fun_l1_n318(x)
+ end
+end
+
+def fun_l0_n775(x)
+ if (x < 1)
+ fun_l1_n831(x)
+ else
+ fun_l1_n635(x)
+ end
+end
+
+def fun_l0_n776(x)
+ if (x < 1)
+ fun_l1_n738(x)
+ else
+ fun_l1_n563(x)
+ end
+end
+
+def fun_l0_n777(x)
+ if (x < 1)
+ fun_l1_n570(x)
+ else
+ fun_l1_n671(x)
+ end
+end
+
+def fun_l0_n778(x)
+ if (x < 1)
+ fun_l1_n945(x)
+ else
+ fun_l1_n840(x)
+ end
+end
+
+def fun_l0_n779(x)
+ if (x < 1)
+ fun_l1_n116(x)
+ else
+ fun_l1_n942(x)
+ end
+end
+
+def fun_l0_n780(x)
+ if (x < 1)
+ fun_l1_n835(x)
+ else
+ fun_l1_n244(x)
+ end
+end
+
+def fun_l0_n781(x)
+ if (x < 1)
+ fun_l1_n427(x)
+ else
+ fun_l1_n556(x)
+ end
+end
+
+def fun_l0_n782(x)
+ if (x < 1)
+ fun_l1_n280(x)
+ else
+ fun_l1_n926(x)
+ end
+end
+
+def fun_l0_n783(x)
+ if (x < 1)
+ fun_l1_n674(x)
+ else
+ fun_l1_n560(x)
+ end
+end
+
+def fun_l0_n784(x)
+ if (x < 1)
+ fun_l1_n978(x)
+ else
+ fun_l1_n139(x)
+ end
+end
+
+def fun_l0_n785(x)
+ if (x < 1)
+ fun_l1_n928(x)
+ else
+ fun_l1_n11(x)
+ end
+end
+
+def fun_l0_n786(x)
+ if (x < 1)
+ fun_l1_n829(x)
+ else
+ fun_l1_n239(x)
+ end
+end
+
+def fun_l0_n787(x)
+ if (x < 1)
+ fun_l1_n732(x)
+ else
+ fun_l1_n829(x)
+ end
+end
+
+def fun_l0_n788(x)
+ if (x < 1)
+ fun_l1_n968(x)
+ else
+ fun_l1_n596(x)
+ end
+end
+
+def fun_l0_n789(x)
+ if (x < 1)
+ fun_l1_n214(x)
+ else
+ fun_l1_n158(x)
+ end
+end
+
+def fun_l0_n790(x)
+ if (x < 1)
+ fun_l1_n566(x)
+ else
+ fun_l1_n390(x)
+ end
+end
+
+def fun_l0_n791(x)
+ if (x < 1)
+ fun_l1_n936(x)
+ else
+ fun_l1_n31(x)
+ end
+end
+
+def fun_l0_n792(x)
+ if (x < 1)
+ fun_l1_n291(x)
+ else
+ fun_l1_n835(x)
+ end
+end
+
+def fun_l0_n793(x)
+ if (x < 1)
+ fun_l1_n300(x)
+ else
+ fun_l1_n658(x)
+ end
+end
+
+def fun_l0_n794(x)
+ if (x < 1)
+ fun_l1_n609(x)
+ else
+ fun_l1_n156(x)
+ end
+end
+
+def fun_l0_n795(x)
+ if (x < 1)
+ fun_l1_n419(x)
+ else
+ fun_l1_n534(x)
+ end
+end
+
+def fun_l0_n796(x)
+ if (x < 1)
+ fun_l1_n401(x)
+ else
+ fun_l1_n281(x)
+ end
+end
+
+def fun_l0_n797(x)
+ if (x < 1)
+ fun_l1_n538(x)
+ else
+ fun_l1_n905(x)
+ end
+end
+
+def fun_l0_n798(x)
+ if (x < 1)
+ fun_l1_n427(x)
+ else
+ fun_l1_n978(x)
+ end
+end
+
+def fun_l0_n799(x)
+ if (x < 1)
+ fun_l1_n851(x)
+ else
+ fun_l1_n57(x)
+ end
+end
+
+def fun_l0_n800(x)
+ if (x < 1)
+ fun_l1_n836(x)
+ else
+ fun_l1_n306(x)
+ end
+end
+
+def fun_l0_n801(x)
+ if (x < 1)
+ fun_l1_n414(x)
+ else
+ fun_l1_n679(x)
+ end
+end
+
+def fun_l0_n802(x)
+ if (x < 1)
+ fun_l1_n645(x)
+ else
+ fun_l1_n115(x)
+ end
+end
+
+def fun_l0_n803(x)
+ if (x < 1)
+ fun_l1_n884(x)
+ else
+ fun_l1_n801(x)
+ end
+end
+
+def fun_l0_n804(x)
+ if (x < 1)
+ fun_l1_n713(x)
+ else
+ fun_l1_n974(x)
+ end
+end
+
+def fun_l0_n805(x)
+ if (x < 1)
+ fun_l1_n301(x)
+ else
+ fun_l1_n589(x)
+ end
+end
+
+def fun_l0_n806(x)
+ if (x < 1)
+ fun_l1_n912(x)
+ else
+ fun_l1_n766(x)
+ end
+end
+
+def fun_l0_n807(x)
+ if (x < 1)
+ fun_l1_n656(x)
+ else
+ fun_l1_n765(x)
+ end
+end
+
+def fun_l0_n808(x)
+ if (x < 1)
+ fun_l1_n517(x)
+ else
+ fun_l1_n964(x)
+ end
+end
+
+def fun_l0_n809(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n69(x)
+ end
+end
+
+def fun_l0_n810(x)
+ if (x < 1)
+ fun_l1_n527(x)
+ else
+ fun_l1_n841(x)
+ end
+end
+
+def fun_l0_n811(x)
+ if (x < 1)
+ fun_l1_n564(x)
+ else
+ fun_l1_n541(x)
+ end
+end
+
+def fun_l0_n812(x)
+ if (x < 1)
+ fun_l1_n754(x)
+ else
+ fun_l1_n681(x)
+ end
+end
+
+def fun_l0_n813(x)
+ if (x < 1)
+ fun_l1_n21(x)
+ else
+ fun_l1_n561(x)
+ end
+end
+
+def fun_l0_n814(x)
+ if (x < 1)
+ fun_l1_n547(x)
+ else
+ fun_l1_n631(x)
+ end
+end
+
+def fun_l0_n815(x)
+ if (x < 1)
+ fun_l1_n956(x)
+ else
+ fun_l1_n889(x)
+ end
+end
+
+def fun_l0_n816(x)
+ if (x < 1)
+ fun_l1_n817(x)
+ else
+ fun_l1_n957(x)
+ end
+end
+
+def fun_l0_n817(x)
+ if (x < 1)
+ fun_l1_n622(x)
+ else
+ fun_l1_n827(x)
+ end
+end
+
+def fun_l0_n818(x)
+ if (x < 1)
+ fun_l1_n7(x)
+ else
+ fun_l1_n208(x)
+ end
+end
+
+def fun_l0_n819(x)
+ if (x < 1)
+ fun_l1_n411(x)
+ else
+ fun_l1_n742(x)
+ end
+end
+
+def fun_l0_n820(x)
+ if (x < 1)
+ fun_l1_n676(x)
+ else
+ fun_l1_n144(x)
+ end
+end
+
+def fun_l0_n821(x)
+ if (x < 1)
+ fun_l1_n489(x)
+ else
+ fun_l1_n963(x)
+ end
+end
+
+def fun_l0_n822(x)
+ if (x < 1)
+ fun_l1_n645(x)
+ else
+ fun_l1_n953(x)
+ end
+end
+
+def fun_l0_n823(x)
+ if (x < 1)
+ fun_l1_n974(x)
+ else
+ fun_l1_n75(x)
+ end
+end
+
+def fun_l0_n824(x)
+ if (x < 1)
+ fun_l1_n295(x)
+ else
+ fun_l1_n249(x)
+ end
+end
+
+def fun_l0_n825(x)
+ if (x < 1)
+ fun_l1_n141(x)
+ else
+ fun_l1_n633(x)
+ end
+end
+
+def fun_l0_n826(x)
+ if (x < 1)
+ fun_l1_n317(x)
+ else
+ fun_l1_n152(x)
+ end
+end
+
+def fun_l0_n827(x)
+ if (x < 1)
+ fun_l1_n570(x)
+ else
+ fun_l1_n377(x)
+ end
+end
+
+def fun_l0_n828(x)
+ if (x < 1)
+ fun_l1_n392(x)
+ else
+ fun_l1_n477(x)
+ end
+end
+
+def fun_l0_n829(x)
+ if (x < 1)
+ fun_l1_n277(x)
+ else
+ fun_l1_n276(x)
+ end
+end
+
+def fun_l0_n830(x)
+ if (x < 1)
+ fun_l1_n579(x)
+ else
+ fun_l1_n648(x)
+ end
+end
+
+def fun_l0_n831(x)
+ if (x < 1)
+ fun_l1_n8(x)
+ else
+ fun_l1_n25(x)
+ end
+end
+
+def fun_l0_n832(x)
+ if (x < 1)
+ fun_l1_n724(x)
+ else
+ fun_l1_n617(x)
+ end
+end
+
+def fun_l0_n833(x)
+ if (x < 1)
+ fun_l1_n771(x)
+ else
+ fun_l1_n619(x)
+ end
+end
+
+def fun_l0_n834(x)
+ if (x < 1)
+ fun_l1_n23(x)
+ else
+ fun_l1_n127(x)
+ end
+end
+
+def fun_l0_n835(x)
+ if (x < 1)
+ fun_l1_n322(x)
+ else
+ fun_l1_n327(x)
+ end
+end
+
+def fun_l0_n836(x)
+ if (x < 1)
+ fun_l1_n7(x)
+ else
+ fun_l1_n600(x)
+ end
+end
+
+def fun_l0_n837(x)
+ if (x < 1)
+ fun_l1_n796(x)
+ else
+ fun_l1_n782(x)
+ end
+end
+
+def fun_l0_n838(x)
+ if (x < 1)
+ fun_l1_n937(x)
+ else
+ fun_l1_n899(x)
+ end
+end
+
+def fun_l0_n839(x)
+ if (x < 1)
+ fun_l1_n16(x)
+ else
+ fun_l1_n349(x)
+ end
+end
+
+def fun_l0_n840(x)
+ if (x < 1)
+ fun_l1_n622(x)
+ else
+ fun_l1_n960(x)
+ end
+end
+
+def fun_l0_n841(x)
+ if (x < 1)
+ fun_l1_n295(x)
+ else
+ fun_l1_n176(x)
+ end
+end
+
+def fun_l0_n842(x)
+ if (x < 1)
+ fun_l1_n302(x)
+ else
+ fun_l1_n639(x)
+ end
+end
+
+def fun_l0_n843(x)
+ if (x < 1)
+ fun_l1_n342(x)
+ else
+ fun_l1_n373(x)
+ end
+end
+
+def fun_l0_n844(x)
+ if (x < 1)
+ fun_l1_n5(x)
+ else
+ fun_l1_n787(x)
+ end
+end
+
+def fun_l0_n845(x)
+ if (x < 1)
+ fun_l1_n89(x)
+ else
+ fun_l1_n951(x)
+ end
+end
+
+def fun_l0_n846(x)
+ if (x < 1)
+ fun_l1_n954(x)
+ else
+ fun_l1_n982(x)
+ end
+end
+
+def fun_l0_n847(x)
+ if (x < 1)
+ fun_l1_n971(x)
+ else
+ fun_l1_n917(x)
+ end
+end
+
+def fun_l0_n848(x)
+ if (x < 1)
+ fun_l1_n845(x)
+ else
+ fun_l1_n343(x)
+ end
+end
+
+def fun_l0_n849(x)
+ if (x < 1)
+ fun_l1_n684(x)
+ else
+ fun_l1_n683(x)
+ end
+end
+
+def fun_l0_n850(x)
+ if (x < 1)
+ fun_l1_n670(x)
+ else
+ fun_l1_n256(x)
+ end
+end
+
+def fun_l0_n851(x)
+ if (x < 1)
+ fun_l1_n405(x)
+ else
+ fun_l1_n123(x)
+ end
+end
+
+def fun_l0_n852(x)
+ if (x < 1)
+ fun_l1_n809(x)
+ else
+ fun_l1_n691(x)
+ end
+end
+
+def fun_l0_n853(x)
+ if (x < 1)
+ fun_l1_n937(x)
+ else
+ fun_l1_n92(x)
+ end
+end
+
+def fun_l0_n854(x)
+ if (x < 1)
+ fun_l1_n735(x)
+ else
+ fun_l1_n948(x)
+ end
+end
+
+def fun_l0_n855(x)
+ if (x < 1)
+ fun_l1_n684(x)
+ else
+ fun_l1_n566(x)
+ end
+end
+
+def fun_l0_n856(x)
+ if (x < 1)
+ fun_l1_n508(x)
+ else
+ fun_l1_n35(x)
+ end
+end
+
+def fun_l0_n857(x)
+ if (x < 1)
+ fun_l1_n865(x)
+ else
+ fun_l1_n930(x)
+ end
+end
+
+def fun_l0_n858(x)
+ if (x < 1)
+ fun_l1_n937(x)
+ else
+ fun_l1_n241(x)
+ end
+end
+
+def fun_l0_n859(x)
+ if (x < 1)
+ fun_l1_n938(x)
+ else
+ fun_l1_n108(x)
+ end
+end
+
+def fun_l0_n860(x)
+ if (x < 1)
+ fun_l1_n491(x)
+ else
+ fun_l1_n119(x)
+ end
+end
+
+def fun_l0_n861(x)
+ if (x < 1)
+ fun_l1_n991(x)
+ else
+ fun_l1_n198(x)
+ end
+end
+
+def fun_l0_n862(x)
+ if (x < 1)
+ fun_l1_n846(x)
+ else
+ fun_l1_n513(x)
+ end
+end
+
+def fun_l0_n863(x)
+ if (x < 1)
+ fun_l1_n279(x)
+ else
+ fun_l1_n229(x)
+ end
+end
+
+def fun_l0_n864(x)
+ if (x < 1)
+ fun_l1_n52(x)
+ else
+ fun_l1_n765(x)
+ end
+end
+
+def fun_l0_n865(x)
+ if (x < 1)
+ fun_l1_n35(x)
+ else
+ fun_l1_n572(x)
+ end
+end
+
+def fun_l0_n866(x)
+ if (x < 1)
+ fun_l1_n4(x)
+ else
+ fun_l1_n645(x)
+ end
+end
+
+def fun_l0_n867(x)
+ if (x < 1)
+ fun_l1_n112(x)
+ else
+ fun_l1_n758(x)
+ end
+end
+
+def fun_l0_n868(x)
+ if (x < 1)
+ fun_l1_n924(x)
+ else
+ fun_l1_n251(x)
+ end
+end
+
+def fun_l0_n869(x)
+ if (x < 1)
+ fun_l1_n558(x)
+ else
+ fun_l1_n818(x)
+ end
+end
+
+def fun_l0_n870(x)
+ if (x < 1)
+ fun_l1_n804(x)
+ else
+ fun_l1_n746(x)
+ end
+end
+
+def fun_l0_n871(x)
+ if (x < 1)
+ fun_l1_n111(x)
+ else
+ fun_l1_n407(x)
+ end
+end
+
+def fun_l0_n872(x)
+ if (x < 1)
+ fun_l1_n973(x)
+ else
+ fun_l1_n384(x)
+ end
+end
+
+def fun_l0_n873(x)
+ if (x < 1)
+ fun_l1_n102(x)
+ else
+ fun_l1_n199(x)
+ end
+end
+
+def fun_l0_n874(x)
+ if (x < 1)
+ fun_l1_n735(x)
+ else
+ fun_l1_n903(x)
+ end
+end
+
+def fun_l0_n875(x)
+ if (x < 1)
+ fun_l1_n95(x)
+ else
+ fun_l1_n720(x)
+ end
+end
+
+def fun_l0_n876(x)
+ if (x < 1)
+ fun_l1_n864(x)
+ else
+ fun_l1_n970(x)
+ end
+end
+
+def fun_l0_n877(x)
+ if (x < 1)
+ fun_l1_n729(x)
+ else
+ fun_l1_n207(x)
+ end
+end
+
+def fun_l0_n878(x)
+ if (x < 1)
+ fun_l1_n104(x)
+ else
+ fun_l1_n209(x)
+ end
+end
+
+def fun_l0_n879(x)
+ if (x < 1)
+ fun_l1_n566(x)
+ else
+ fun_l1_n918(x)
+ end
+end
+
+def fun_l0_n880(x)
+ if (x < 1)
+ fun_l1_n457(x)
+ else
+ fun_l1_n104(x)
+ end
+end
+
+def fun_l0_n881(x)
+ if (x < 1)
+ fun_l1_n745(x)
+ else
+ fun_l1_n476(x)
+ end
+end
+
+def fun_l0_n882(x)
+ if (x < 1)
+ fun_l1_n346(x)
+ else
+ fun_l1_n642(x)
+ end
+end
+
+def fun_l0_n883(x)
+ if (x < 1)
+ fun_l1_n78(x)
+ else
+ fun_l1_n210(x)
+ end
+end
+
+def fun_l0_n884(x)
+ if (x < 1)
+ fun_l1_n864(x)
+ else
+ fun_l1_n439(x)
+ end
+end
+
+def fun_l0_n885(x)
+ if (x < 1)
+ fun_l1_n0(x)
+ else
+ fun_l1_n414(x)
+ end
+end
+
+def fun_l0_n886(x)
+ if (x < 1)
+ fun_l1_n217(x)
+ else
+ fun_l1_n444(x)
+ end
+end
+
+def fun_l0_n887(x)
+ if (x < 1)
+ fun_l1_n193(x)
+ else
+ fun_l1_n788(x)
+ end
+end
+
+def fun_l0_n888(x)
+ if (x < 1)
+ fun_l1_n30(x)
+ else
+ fun_l1_n793(x)
+ end
+end
+
+def fun_l0_n889(x)
+ if (x < 1)
+ fun_l1_n222(x)
+ else
+ fun_l1_n936(x)
+ end
+end
+
+def fun_l0_n890(x)
+ if (x < 1)
+ fun_l1_n758(x)
+ else
+ fun_l1_n52(x)
+ end
+end
+
+def fun_l0_n891(x)
+ if (x < 1)
+ fun_l1_n796(x)
+ else
+ fun_l1_n424(x)
+ end
+end
+
+def fun_l0_n892(x)
+ if (x < 1)
+ fun_l1_n627(x)
+ else
+ fun_l1_n284(x)
+ end
+end
+
+def fun_l0_n893(x)
+ if (x < 1)
+ fun_l1_n42(x)
+ else
+ fun_l1_n193(x)
+ end
+end
+
+def fun_l0_n894(x)
+ if (x < 1)
+ fun_l1_n90(x)
+ else
+ fun_l1_n158(x)
+ end
+end
+
+def fun_l0_n895(x)
+ if (x < 1)
+ fun_l1_n878(x)
+ else
+ fun_l1_n396(x)
+ end
+end
+
+def fun_l0_n896(x)
+ if (x < 1)
+ fun_l1_n665(x)
+ else
+ fun_l1_n731(x)
+ end
+end
+
+def fun_l0_n897(x)
+ if (x < 1)
+ fun_l1_n618(x)
+ else
+ fun_l1_n152(x)
+ end
+end
+
+def fun_l0_n898(x)
+ if (x < 1)
+ fun_l1_n64(x)
+ else
+ fun_l1_n697(x)
+ end
+end
+
+def fun_l0_n899(x)
+ if (x < 1)
+ fun_l1_n354(x)
+ else
+ fun_l1_n657(x)
+ end
+end
+
+def fun_l0_n900(x)
+ if (x < 1)
+ fun_l1_n79(x)
+ else
+ fun_l1_n794(x)
+ end
+end
+
+def fun_l0_n901(x)
+ if (x < 1)
+ fun_l1_n623(x)
+ else
+ fun_l1_n392(x)
+ end
+end
+
+def fun_l0_n902(x)
+ if (x < 1)
+ fun_l1_n529(x)
+ else
+ fun_l1_n708(x)
+ end
+end
+
+def fun_l0_n903(x)
+ if (x < 1)
+ fun_l1_n900(x)
+ else
+ fun_l1_n830(x)
+ end
+end
+
+def fun_l0_n904(x)
+ if (x < 1)
+ fun_l1_n424(x)
+ else
+ fun_l1_n564(x)
+ end
+end
+
+def fun_l0_n905(x)
+ if (x < 1)
+ fun_l1_n557(x)
+ else
+ fun_l1_n612(x)
+ end
+end
+
+def fun_l0_n906(x)
+ if (x < 1)
+ fun_l1_n725(x)
+ else
+ fun_l1_n166(x)
+ end
+end
+
+def fun_l0_n907(x)
+ if (x < 1)
+ fun_l1_n534(x)
+ else
+ fun_l1_n159(x)
+ end
+end
+
+def fun_l0_n908(x)
+ if (x < 1)
+ fun_l1_n50(x)
+ else
+ fun_l1_n201(x)
+ end
+end
+
+def fun_l0_n909(x)
+ if (x < 1)
+ fun_l1_n568(x)
+ else
+ fun_l1_n276(x)
+ end
+end
+
+def fun_l0_n910(x)
+ if (x < 1)
+ fun_l1_n0(x)
+ else
+ fun_l1_n324(x)
+ end
+end
+
+def fun_l0_n911(x)
+ if (x < 1)
+ fun_l1_n926(x)
+ else
+ fun_l1_n524(x)
+ end
+end
+
+def fun_l0_n912(x)
+ if (x < 1)
+ fun_l1_n498(x)
+ else
+ fun_l1_n650(x)
+ end
+end
+
+def fun_l0_n913(x)
+ if (x < 1)
+ fun_l1_n593(x)
+ else
+ fun_l1_n860(x)
+ end
+end
+
+def fun_l0_n914(x)
+ if (x < 1)
+ fun_l1_n726(x)
+ else
+ fun_l1_n440(x)
+ end
+end
+
+def fun_l0_n915(x)
+ if (x < 1)
+ fun_l1_n422(x)
+ else
+ fun_l1_n627(x)
+ end
+end
+
+def fun_l0_n916(x)
+ if (x < 1)
+ fun_l1_n346(x)
+ else
+ fun_l1_n932(x)
+ end
+end
+
+def fun_l0_n917(x)
+ if (x < 1)
+ fun_l1_n403(x)
+ else
+ fun_l1_n58(x)
+ end
+end
+
+def fun_l0_n918(x)
+ if (x < 1)
+ fun_l1_n989(x)
+ else
+ fun_l1_n579(x)
+ end
+end
+
+def fun_l0_n919(x)
+ if (x < 1)
+ fun_l1_n933(x)
+ else
+ fun_l1_n434(x)
+ end
+end
+
+def fun_l0_n920(x)
+ if (x < 1)
+ fun_l1_n899(x)
+ else
+ fun_l1_n377(x)
+ end
+end
+
+def fun_l0_n921(x)
+ if (x < 1)
+ fun_l1_n17(x)
+ else
+ fun_l1_n637(x)
+ end
+end
+
+def fun_l0_n922(x)
+ if (x < 1)
+ fun_l1_n551(x)
+ else
+ fun_l1_n693(x)
+ end
+end
+
+def fun_l0_n923(x)
+ if (x < 1)
+ fun_l1_n861(x)
+ else
+ fun_l1_n248(x)
+ end
+end
+
+def fun_l0_n924(x)
+ if (x < 1)
+ fun_l1_n171(x)
+ else
+ fun_l1_n75(x)
+ end
+end
+
+def fun_l0_n925(x)
+ if (x < 1)
+ fun_l1_n233(x)
+ else
+ fun_l1_n444(x)
+ end
+end
+
+def fun_l0_n926(x)
+ if (x < 1)
+ fun_l1_n310(x)
+ else
+ fun_l1_n941(x)
+ end
+end
+
+def fun_l0_n927(x)
+ if (x < 1)
+ fun_l1_n363(x)
+ else
+ fun_l1_n567(x)
+ end
+end
+
+def fun_l0_n928(x)
+ if (x < 1)
+ fun_l1_n632(x)
+ else
+ fun_l1_n840(x)
+ end
+end
+
+def fun_l0_n929(x)
+ if (x < 1)
+ fun_l1_n368(x)
+ else
+ fun_l1_n713(x)
+ end
+end
+
+def fun_l0_n930(x)
+ if (x < 1)
+ fun_l1_n37(x)
+ else
+ fun_l1_n355(x)
+ end
+end
+
+def fun_l0_n931(x)
+ if (x < 1)
+ fun_l1_n907(x)
+ else
+ fun_l1_n784(x)
+ end
+end
+
+def fun_l0_n932(x)
+ if (x < 1)
+ fun_l1_n591(x)
+ else
+ fun_l1_n844(x)
+ end
+end
+
+def fun_l0_n933(x)
+ if (x < 1)
+ fun_l1_n996(x)
+ else
+ fun_l1_n943(x)
+ end
+end
+
+def fun_l0_n934(x)
+ if (x < 1)
+ fun_l1_n631(x)
+ else
+ fun_l1_n643(x)
+ end
+end
+
+def fun_l0_n935(x)
+ if (x < 1)
+ fun_l1_n875(x)
+ else
+ fun_l1_n89(x)
+ end
+end
+
+def fun_l0_n936(x)
+ if (x < 1)
+ fun_l1_n842(x)
+ else
+ fun_l1_n595(x)
+ end
+end
+
+def fun_l0_n937(x)
+ if (x < 1)
+ fun_l1_n921(x)
+ else
+ fun_l1_n271(x)
+ end
+end
+
+def fun_l0_n938(x)
+ if (x < 1)
+ fun_l1_n222(x)
+ else
+ fun_l1_n170(x)
+ end
+end
+
+def fun_l0_n939(x)
+ if (x < 1)
+ fun_l1_n567(x)
+ else
+ fun_l1_n463(x)
+ end
+end
+
+def fun_l0_n940(x)
+ if (x < 1)
+ fun_l1_n456(x)
+ else
+ fun_l1_n192(x)
+ end
+end
+
+def fun_l0_n941(x)
+ if (x < 1)
+ fun_l1_n32(x)
+ else
+ fun_l1_n951(x)
+ end
+end
+
+def fun_l0_n942(x)
+ if (x < 1)
+ fun_l1_n14(x)
+ else
+ fun_l1_n135(x)
+ end
+end
+
+def fun_l0_n943(x)
+ if (x < 1)
+ fun_l1_n15(x)
+ else
+ fun_l1_n234(x)
+ end
+end
+
+def fun_l0_n944(x)
+ if (x < 1)
+ fun_l1_n119(x)
+ else
+ fun_l1_n33(x)
+ end
+end
+
+def fun_l0_n945(x)
+ if (x < 1)
+ fun_l1_n859(x)
+ else
+ fun_l1_n497(x)
+ end
+end
+
+def fun_l0_n946(x)
+ if (x < 1)
+ fun_l1_n178(x)
+ else
+ fun_l1_n369(x)
+ end
+end
+
+def fun_l0_n947(x)
+ if (x < 1)
+ fun_l1_n64(x)
+ else
+ fun_l1_n356(x)
+ end
+end
+
+def fun_l0_n948(x)
+ if (x < 1)
+ fun_l1_n279(x)
+ else
+ fun_l1_n244(x)
+ end
+end
+
+def fun_l0_n949(x)
+ if (x < 1)
+ fun_l1_n728(x)
+ else
+ fun_l1_n548(x)
+ end
+end
+
+def fun_l0_n950(x)
+ if (x < 1)
+ fun_l1_n3(x)
+ else
+ fun_l1_n698(x)
+ end
+end
+
+def fun_l0_n951(x)
+ if (x < 1)
+ fun_l1_n665(x)
+ else
+ fun_l1_n198(x)
+ end
+end
+
+def fun_l0_n952(x)
+ if (x < 1)
+ fun_l1_n812(x)
+ else
+ fun_l1_n964(x)
+ end
+end
+
+def fun_l0_n953(x)
+ if (x < 1)
+ fun_l1_n851(x)
+ else
+ fun_l1_n877(x)
+ end
+end
+
+def fun_l0_n954(x)
+ if (x < 1)
+ fun_l1_n415(x)
+ else
+ fun_l1_n379(x)
+ end
+end
+
+def fun_l0_n955(x)
+ if (x < 1)
+ fun_l1_n806(x)
+ else
+ fun_l1_n919(x)
+ end
+end
+
+def fun_l0_n956(x)
+ if (x < 1)
+ fun_l1_n207(x)
+ else
+ fun_l1_n798(x)
+ end
+end
+
+def fun_l0_n957(x)
+ if (x < 1)
+ fun_l1_n269(x)
+ else
+ fun_l1_n416(x)
+ end
+end
+
+def fun_l0_n958(x)
+ if (x < 1)
+ fun_l1_n654(x)
+ else
+ fun_l1_n236(x)
+ end
+end
+
+def fun_l0_n959(x)
+ if (x < 1)
+ fun_l1_n392(x)
+ else
+ fun_l1_n623(x)
+ end
+end
+
+def fun_l0_n960(x)
+ if (x < 1)
+ fun_l1_n889(x)
+ else
+ fun_l1_n279(x)
+ end
+end
+
+def fun_l0_n961(x)
+ if (x < 1)
+ fun_l1_n476(x)
+ else
+ fun_l1_n201(x)
+ end
+end
+
+def fun_l0_n962(x)
+ if (x < 1)
+ fun_l1_n799(x)
+ else
+ fun_l1_n570(x)
+ end
+end
+
+def fun_l0_n963(x)
+ if (x < 1)
+ fun_l1_n802(x)
+ else
+ fun_l1_n114(x)
+ end
+end
+
+def fun_l0_n964(x)
+ if (x < 1)
+ fun_l1_n197(x)
+ else
+ fun_l1_n422(x)
+ end
+end
+
+def fun_l0_n965(x)
+ if (x < 1)
+ fun_l1_n37(x)
+ else
+ fun_l1_n691(x)
+ end
+end
+
+def fun_l0_n966(x)
+ if (x < 1)
+ fun_l1_n775(x)
+ else
+ fun_l1_n854(x)
+ end
+end
+
+def fun_l0_n967(x)
+ if (x < 1)
+ fun_l1_n373(x)
+ else
+ fun_l1_n306(x)
+ end
+end
+
+def fun_l0_n968(x)
+ if (x < 1)
+ fun_l1_n154(x)
+ else
+ fun_l1_n122(x)
+ end
+end
+
+def fun_l0_n969(x)
+ if (x < 1)
+ fun_l1_n497(x)
+ else
+ fun_l1_n456(x)
+ end
+end
+
+def fun_l0_n970(x)
+ if (x < 1)
+ fun_l1_n621(x)
+ else
+ fun_l1_n931(x)
+ end
+end
+
+def fun_l0_n971(x)
+ if (x < 1)
+ fun_l1_n963(x)
+ else
+ fun_l1_n613(x)
+ end
+end
+
+def fun_l0_n972(x)
+ if (x < 1)
+ fun_l1_n613(x)
+ else
+ fun_l1_n508(x)
+ end
+end
+
+def fun_l0_n973(x)
+ if (x < 1)
+ fun_l1_n466(x)
+ else
+ fun_l1_n929(x)
+ end
+end
+
+def fun_l0_n974(x)
+ if (x < 1)
+ fun_l1_n247(x)
+ else
+ fun_l1_n610(x)
+ end
+end
+
+def fun_l0_n975(x)
+ if (x < 1)
+ fun_l1_n674(x)
+ else
+ fun_l1_n609(x)
+ end
+end
+
+def fun_l0_n976(x)
+ if (x < 1)
+ fun_l1_n963(x)
+ else
+ fun_l1_n601(x)
+ end
+end
+
+def fun_l0_n977(x)
+ if (x < 1)
+ fun_l1_n728(x)
+ else
+ fun_l1_n242(x)
+ end
+end
+
+def fun_l0_n978(x)
+ if (x < 1)
+ fun_l1_n515(x)
+ else
+ fun_l1_n113(x)
+ end
+end
+
+def fun_l0_n979(x)
+ if (x < 1)
+ fun_l1_n734(x)
+ else
+ fun_l1_n271(x)
+ end
+end
+
+def fun_l0_n980(x)
+ if (x < 1)
+ fun_l1_n837(x)
+ else
+ fun_l1_n733(x)
+ end
+end
+
+def fun_l0_n981(x)
+ if (x < 1)
+ fun_l1_n326(x)
+ else
+ fun_l1_n213(x)
+ end
+end
+
+def fun_l0_n982(x)
+ if (x < 1)
+ fun_l1_n733(x)
+ else
+ fun_l1_n198(x)
+ end
+end
+
+def fun_l0_n983(x)
+ if (x < 1)
+ fun_l1_n989(x)
+ else
+ fun_l1_n700(x)
+ end
+end
+
+def fun_l0_n984(x)
+ if (x < 1)
+ fun_l1_n266(x)
+ else
+ fun_l1_n348(x)
+ end
+end
+
+def fun_l0_n985(x)
+ if (x < 1)
+ fun_l1_n931(x)
+ else
+ fun_l1_n646(x)
+ end
+end
+
+def fun_l0_n986(x)
+ if (x < 1)
+ fun_l1_n435(x)
+ else
+ fun_l1_n747(x)
+ end
+end
+
+def fun_l0_n987(x)
+ if (x < 1)
+ fun_l1_n474(x)
+ else
+ fun_l1_n638(x)
+ end
+end
+
+def fun_l0_n988(x)
+ if (x < 1)
+ fun_l1_n615(x)
+ else
+ fun_l1_n283(x)
+ end
+end
+
+def fun_l0_n989(x)
+ if (x < 1)
+ fun_l1_n410(x)
+ else
+ fun_l1_n289(x)
+ end
+end
+
+def fun_l0_n990(x)
+ if (x < 1)
+ fun_l1_n633(x)
+ else
+ fun_l1_n77(x)
+ end
+end
+
+def fun_l0_n991(x)
+ if (x < 1)
+ fun_l1_n153(x)
+ else
+ fun_l1_n255(x)
+ end
+end
+
+def fun_l0_n992(x)
+ if (x < 1)
+ fun_l1_n447(x)
+ else
+ fun_l1_n239(x)
+ end
+end
+
+def fun_l0_n993(x)
+ if (x < 1)
+ fun_l1_n837(x)
+ else
+ fun_l1_n582(x)
+ end
+end
+
+def fun_l0_n994(x)
+ if (x < 1)
+ fun_l1_n385(x)
+ else
+ fun_l1_n939(x)
+ end
+end
+
+def fun_l0_n995(x)
+ if (x < 1)
+ fun_l1_n236(x)
+ else
+ fun_l1_n497(x)
+ end
+end
+
+def fun_l0_n996(x)
+ if (x < 1)
+ fun_l1_n63(x)
+ else
+ fun_l1_n721(x)
+ end
+end
+
+def fun_l0_n997(x)
+ if (x < 1)
+ fun_l1_n457(x)
+ else
+ fun_l1_n376(x)
+ end
+end
+
+def fun_l0_n998(x)
+ if (x < 1)
+ fun_l1_n362(x)
+ else
+ fun_l1_n478(x)
+ end
+end
+
+def fun_l0_n999(x)
+ if (x < 1)
+ fun_l1_n554(x)
+ else
+ fun_l1_n422(x)
+ end
+end
+
+def fun_l1_n0(x)
+ if (x < 1)
+ fun_l2_n498(x)
+ else
+ fun_l2_n461(x)
+ end
+end
+
+def fun_l1_n1(x)
+ if (x < 1)
+ fun_l2_n424(x)
+ else
+ fun_l2_n137(x)
+ end
+end
+
+def fun_l1_n2(x)
+ if (x < 1)
+ fun_l2_n325(x)
+ else
+ fun_l2_n95(x)
+ end
+end
+
+def fun_l1_n3(x)
+ if (x < 1)
+ fun_l2_n917(x)
+ else
+ fun_l2_n469(x)
+ end
+end
+
+def fun_l1_n4(x)
+ if (x < 1)
+ fun_l2_n730(x)
+ else
+ fun_l2_n147(x)
+ end
+end
+
+def fun_l1_n5(x)
+ if (x < 1)
+ fun_l2_n796(x)
+ else
+ fun_l2_n907(x)
+ end
+end
+
+def fun_l1_n6(x)
+ if (x < 1)
+ fun_l2_n555(x)
+ else
+ fun_l2_n309(x)
+ end
+end
+
+def fun_l1_n7(x)
+ if (x < 1)
+ fun_l2_n475(x)
+ else
+ fun_l2_n193(x)
+ end
+end
+
+def fun_l1_n8(x)
+ if (x < 1)
+ fun_l2_n317(x)
+ else
+ fun_l2_n284(x)
+ end
+end
+
+def fun_l1_n9(x)
+ if (x < 1)
+ fun_l2_n297(x)
+ else
+ fun_l2_n370(x)
+ end
+end
+
+def fun_l1_n10(x)
+ if (x < 1)
+ fun_l2_n66(x)
+ else
+ fun_l2_n959(x)
+ end
+end
+
+def fun_l1_n11(x)
+ if (x < 1)
+ fun_l2_n833(x)
+ else
+ fun_l2_n250(x)
+ end
+end
+
+def fun_l1_n12(x)
+ if (x < 1)
+ fun_l2_n640(x)
+ else
+ fun_l2_n588(x)
+ end
+end
+
+def fun_l1_n13(x)
+ if (x < 1)
+ fun_l2_n91(x)
+ else
+ fun_l2_n294(x)
+ end
+end
+
+def fun_l1_n14(x)
+ if (x < 1)
+ fun_l2_n166(x)
+ else
+ fun_l2_n943(x)
+ end
+end
+
+def fun_l1_n15(x)
+ if (x < 1)
+ fun_l2_n352(x)
+ else
+ fun_l2_n363(x)
+ end
+end
+
+def fun_l1_n16(x)
+ if (x < 1)
+ fun_l2_n84(x)
+ else
+ fun_l2_n278(x)
+ end
+end
+
+def fun_l1_n17(x)
+ if (x < 1)
+ fun_l2_n308(x)
+ else
+ fun_l2_n341(x)
+ end
+end
+
+def fun_l1_n18(x)
+ if (x < 1)
+ fun_l2_n713(x)
+ else
+ fun_l2_n575(x)
+ end
+end
+
+def fun_l1_n19(x)
+ if (x < 1)
+ fun_l2_n81(x)
+ else
+ fun_l2_n301(x)
+ end
+end
+
+def fun_l1_n20(x)
+ if (x < 1)
+ fun_l2_n516(x)
+ else
+ fun_l2_n164(x)
+ end
+end
+
+def fun_l1_n21(x)
+ if (x < 1)
+ fun_l2_n900(x)
+ else
+ fun_l2_n963(x)
+ end
+end
+
+def fun_l1_n22(x)
+ if (x < 1)
+ fun_l2_n472(x)
+ else
+ fun_l2_n288(x)
+ end
+end
+
+def fun_l1_n23(x)
+ if (x < 1)
+ fun_l2_n587(x)
+ else
+ fun_l2_n515(x)
+ end
+end
+
+def fun_l1_n24(x)
+ if (x < 1)
+ fun_l2_n506(x)
+ else
+ fun_l2_n711(x)
+ end
+end
+
+def fun_l1_n25(x)
+ if (x < 1)
+ fun_l2_n935(x)
+ else
+ fun_l2_n177(x)
+ end
+end
+
+def fun_l1_n26(x)
+ if (x < 1)
+ fun_l2_n485(x)
+ else
+ fun_l2_n368(x)
+ end
+end
+
+def fun_l1_n27(x)
+ if (x < 1)
+ fun_l2_n984(x)
+ else
+ fun_l2_n290(x)
+ end
+end
+
+def fun_l1_n28(x)
+ if (x < 1)
+ fun_l2_n36(x)
+ else
+ fun_l2_n837(x)
+ end
+end
+
+def fun_l1_n29(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n311(x)
+ end
+end
+
+def fun_l1_n30(x)
+ if (x < 1)
+ fun_l2_n215(x)
+ else
+ fun_l2_n376(x)
+ end
+end
+
+def fun_l1_n31(x)
+ if (x < 1)
+ fun_l2_n533(x)
+ else
+ fun_l2_n92(x)
+ end
+end
+
+def fun_l1_n32(x)
+ if (x < 1)
+ fun_l2_n386(x)
+ else
+ fun_l2_n283(x)
+ end
+end
+
+def fun_l1_n33(x)
+ if (x < 1)
+ fun_l2_n268(x)
+ else
+ fun_l2_n256(x)
+ end
+end
+
+def fun_l1_n34(x)
+ if (x < 1)
+ fun_l2_n348(x)
+ else
+ fun_l2_n464(x)
+ end
+end
+
+def fun_l1_n35(x)
+ if (x < 1)
+ fun_l2_n25(x)
+ else
+ fun_l2_n33(x)
+ end
+end
+
+def fun_l1_n36(x)
+ if (x < 1)
+ fun_l2_n387(x)
+ else
+ fun_l2_n341(x)
+ end
+end
+
+def fun_l1_n37(x)
+ if (x < 1)
+ fun_l2_n580(x)
+ else
+ fun_l2_n476(x)
+ end
+end
+
+def fun_l1_n38(x)
+ if (x < 1)
+ fun_l2_n33(x)
+ else
+ fun_l2_n33(x)
+ end
+end
+
+def fun_l1_n39(x)
+ if (x < 1)
+ fun_l2_n861(x)
+ else
+ fun_l2_n52(x)
+ end
+end
+
+def fun_l1_n40(x)
+ if (x < 1)
+ fun_l2_n740(x)
+ else
+ fun_l2_n943(x)
+ end
+end
+
+def fun_l1_n41(x)
+ if (x < 1)
+ fun_l2_n956(x)
+ else
+ fun_l2_n159(x)
+ end
+end
+
+def fun_l1_n42(x)
+ if (x < 1)
+ fun_l2_n445(x)
+ else
+ fun_l2_n775(x)
+ end
+end
+
+def fun_l1_n43(x)
+ if (x < 1)
+ fun_l2_n667(x)
+ else
+ fun_l2_n282(x)
+ end
+end
+
+def fun_l1_n44(x)
+ if (x < 1)
+ fun_l2_n185(x)
+ else
+ fun_l2_n210(x)
+ end
+end
+
+def fun_l1_n45(x)
+ if (x < 1)
+ fun_l2_n490(x)
+ else
+ fun_l2_n21(x)
+ end
+end
+
+def fun_l1_n46(x)
+ if (x < 1)
+ fun_l2_n751(x)
+ else
+ fun_l2_n639(x)
+ end
+end
+
+def fun_l1_n47(x)
+ if (x < 1)
+ fun_l2_n431(x)
+ else
+ fun_l2_n917(x)
+ end
+end
+
+def fun_l1_n48(x)
+ if (x < 1)
+ fun_l2_n187(x)
+ else
+ fun_l2_n170(x)
+ end
+end
+
+def fun_l1_n49(x)
+ if (x < 1)
+ fun_l2_n780(x)
+ else
+ fun_l2_n77(x)
+ end
+end
+
+def fun_l1_n50(x)
+ if (x < 1)
+ fun_l2_n546(x)
+ else
+ fun_l2_n759(x)
+ end
+end
+
+def fun_l1_n51(x)
+ if (x < 1)
+ fun_l2_n453(x)
+ else
+ fun_l2_n951(x)
+ end
+end
+
+def fun_l1_n52(x)
+ if (x < 1)
+ fun_l2_n989(x)
+ else
+ fun_l2_n716(x)
+ end
+end
+
+def fun_l1_n53(x)
+ if (x < 1)
+ fun_l2_n652(x)
+ else
+ fun_l2_n36(x)
+ end
+end
+
+def fun_l1_n54(x)
+ if (x < 1)
+ fun_l2_n187(x)
+ else
+ fun_l2_n760(x)
+ end
+end
+
+def fun_l1_n55(x)
+ if (x < 1)
+ fun_l2_n706(x)
+ else
+ fun_l2_n927(x)
+ end
+end
+
+def fun_l1_n56(x)
+ if (x < 1)
+ fun_l2_n666(x)
+ else
+ fun_l2_n295(x)
+ end
+end
+
+def fun_l1_n57(x)
+ if (x < 1)
+ fun_l2_n424(x)
+ else
+ fun_l2_n447(x)
+ end
+end
+
+def fun_l1_n58(x)
+ if (x < 1)
+ fun_l2_n408(x)
+ else
+ fun_l2_n337(x)
+ end
+end
+
+def fun_l1_n59(x)
+ if (x < 1)
+ fun_l2_n567(x)
+ else
+ fun_l2_n765(x)
+ end
+end
+
+def fun_l1_n60(x)
+ if (x < 1)
+ fun_l2_n241(x)
+ else
+ fun_l2_n701(x)
+ end
+end
+
+def fun_l1_n61(x)
+ if (x < 1)
+ fun_l2_n831(x)
+ else
+ fun_l2_n382(x)
+ end
+end
+
+def fun_l1_n62(x)
+ if (x < 1)
+ fun_l2_n634(x)
+ else
+ fun_l2_n908(x)
+ end
+end
+
+def fun_l1_n63(x)
+ if (x < 1)
+ fun_l2_n696(x)
+ else
+ fun_l2_n48(x)
+ end
+end
+
+def fun_l1_n64(x)
+ if (x < 1)
+ fun_l2_n528(x)
+ else
+ fun_l2_n110(x)
+ end
+end
+
+def fun_l1_n65(x)
+ if (x < 1)
+ fun_l2_n767(x)
+ else
+ fun_l2_n973(x)
+ end
+end
+
+def fun_l1_n66(x)
+ if (x < 1)
+ fun_l2_n963(x)
+ else
+ fun_l2_n673(x)
+ end
+end
+
+def fun_l1_n67(x)
+ if (x < 1)
+ fun_l2_n927(x)
+ else
+ fun_l2_n309(x)
+ end
+end
+
+def fun_l1_n68(x)
+ if (x < 1)
+ fun_l2_n851(x)
+ else
+ fun_l2_n160(x)
+ end
+end
+
+def fun_l1_n69(x)
+ if (x < 1)
+ fun_l2_n575(x)
+ else
+ fun_l2_n800(x)
+ end
+end
+
+def fun_l1_n70(x)
+ if (x < 1)
+ fun_l2_n396(x)
+ else
+ fun_l2_n382(x)
+ end
+end
+
+def fun_l1_n71(x)
+ if (x < 1)
+ fun_l2_n508(x)
+ else
+ fun_l2_n763(x)
+ end
+end
+
+def fun_l1_n72(x)
+ if (x < 1)
+ fun_l2_n360(x)
+ else
+ fun_l2_n848(x)
+ end
+end
+
+def fun_l1_n73(x)
+ if (x < 1)
+ fun_l2_n878(x)
+ else
+ fun_l2_n83(x)
+ end
+end
+
+def fun_l1_n74(x)
+ if (x < 1)
+ fun_l2_n573(x)
+ else
+ fun_l2_n284(x)
+ end
+end
+
+def fun_l1_n75(x)
+ if (x < 1)
+ fun_l2_n999(x)
+ else
+ fun_l2_n954(x)
+ end
+end
+
+def fun_l1_n76(x)
+ if (x < 1)
+ fun_l2_n182(x)
+ else
+ fun_l2_n997(x)
+ end
+end
+
+def fun_l1_n77(x)
+ if (x < 1)
+ fun_l2_n802(x)
+ else
+ fun_l2_n409(x)
+ end
+end
+
+def fun_l1_n78(x)
+ if (x < 1)
+ fun_l2_n163(x)
+ else
+ fun_l2_n417(x)
+ end
+end
+
+def fun_l1_n79(x)
+ if (x < 1)
+ fun_l2_n328(x)
+ else
+ fun_l2_n688(x)
+ end
+end
+
+def fun_l1_n80(x)
+ if (x < 1)
+ fun_l2_n699(x)
+ else
+ fun_l2_n356(x)
+ end
+end
+
+def fun_l1_n81(x)
+ if (x < 1)
+ fun_l2_n44(x)
+ else
+ fun_l2_n302(x)
+ end
+end
+
+def fun_l1_n82(x)
+ if (x < 1)
+ fun_l2_n597(x)
+ else
+ fun_l2_n892(x)
+ end
+end
+
+def fun_l1_n83(x)
+ if (x < 1)
+ fun_l2_n494(x)
+ else
+ fun_l2_n547(x)
+ end
+end
+
+def fun_l1_n84(x)
+ if (x < 1)
+ fun_l2_n631(x)
+ else
+ fun_l2_n922(x)
+ end
+end
+
+def fun_l1_n85(x)
+ if (x < 1)
+ fun_l2_n797(x)
+ else
+ fun_l2_n874(x)
+ end
+end
+
+def fun_l1_n86(x)
+ if (x < 1)
+ fun_l2_n209(x)
+ else
+ fun_l2_n365(x)
+ end
+end
+
+def fun_l1_n87(x)
+ if (x < 1)
+ fun_l2_n516(x)
+ else
+ fun_l2_n371(x)
+ end
+end
+
+def fun_l1_n88(x)
+ if (x < 1)
+ fun_l2_n654(x)
+ else
+ fun_l2_n88(x)
+ end
+end
+
+def fun_l1_n89(x)
+ if (x < 1)
+ fun_l2_n70(x)
+ else
+ fun_l2_n521(x)
+ end
+end
+
+def fun_l1_n90(x)
+ if (x < 1)
+ fun_l2_n666(x)
+ else
+ fun_l2_n749(x)
+ end
+end
+
+def fun_l1_n91(x)
+ if (x < 1)
+ fun_l2_n504(x)
+ else
+ fun_l2_n339(x)
+ end
+end
+
+def fun_l1_n92(x)
+ if (x < 1)
+ fun_l2_n734(x)
+ else
+ fun_l2_n277(x)
+ end
+end
+
+def fun_l1_n93(x)
+ if (x < 1)
+ fun_l2_n300(x)
+ else
+ fun_l2_n826(x)
+ end
+end
+
+def fun_l1_n94(x)
+ if (x < 1)
+ fun_l2_n733(x)
+ else
+ fun_l2_n560(x)
+ end
+end
+
+def fun_l1_n95(x)
+ if (x < 1)
+ fun_l2_n834(x)
+ else
+ fun_l2_n644(x)
+ end
+end
+
+def fun_l1_n96(x)
+ if (x < 1)
+ fun_l2_n183(x)
+ else
+ fun_l2_n238(x)
+ end
+end
+
+def fun_l1_n97(x)
+ if (x < 1)
+ fun_l2_n372(x)
+ else
+ fun_l2_n753(x)
+ end
+end
+
+def fun_l1_n98(x)
+ if (x < 1)
+ fun_l2_n208(x)
+ else
+ fun_l2_n543(x)
+ end
+end
+
+def fun_l1_n99(x)
+ if (x < 1)
+ fun_l2_n38(x)
+ else
+ fun_l2_n974(x)
+ end
+end
+
+def fun_l1_n100(x)
+ if (x < 1)
+ fun_l2_n620(x)
+ else
+ fun_l2_n503(x)
+ end
+end
+
+def fun_l1_n101(x)
+ if (x < 1)
+ fun_l2_n248(x)
+ else
+ fun_l2_n189(x)
+ end
+end
+
+def fun_l1_n102(x)
+ if (x < 1)
+ fun_l2_n489(x)
+ else
+ fun_l2_n390(x)
+ end
+end
+
+def fun_l1_n103(x)
+ if (x < 1)
+ fun_l2_n452(x)
+ else
+ fun_l2_n22(x)
+ end
+end
+
+def fun_l1_n104(x)
+ if (x < 1)
+ fun_l2_n542(x)
+ else
+ fun_l2_n135(x)
+ end
+end
+
+def fun_l1_n105(x)
+ if (x < 1)
+ fun_l2_n988(x)
+ else
+ fun_l2_n118(x)
+ end
+end
+
+def fun_l1_n106(x)
+ if (x < 1)
+ fun_l2_n817(x)
+ else
+ fun_l2_n534(x)
+ end
+end
+
+def fun_l1_n107(x)
+ if (x < 1)
+ fun_l2_n812(x)
+ else
+ fun_l2_n206(x)
+ end
+end
+
+def fun_l1_n108(x)
+ if (x < 1)
+ fun_l2_n514(x)
+ else
+ fun_l2_n300(x)
+ end
+end
+
+def fun_l1_n109(x)
+ if (x < 1)
+ fun_l2_n482(x)
+ else
+ fun_l2_n376(x)
+ end
+end
+
+def fun_l1_n110(x)
+ if (x < 1)
+ fun_l2_n571(x)
+ else
+ fun_l2_n758(x)
+ end
+end
+
+def fun_l1_n111(x)
+ if (x < 1)
+ fun_l2_n971(x)
+ else
+ fun_l2_n811(x)
+ end
+end
+
+def fun_l1_n112(x)
+ if (x < 1)
+ fun_l2_n23(x)
+ else
+ fun_l2_n844(x)
+ end
+end
+
+def fun_l1_n113(x)
+ if (x < 1)
+ fun_l2_n865(x)
+ else
+ fun_l2_n149(x)
+ end
+end
+
+def fun_l1_n114(x)
+ if (x < 1)
+ fun_l2_n930(x)
+ else
+ fun_l2_n327(x)
+ end
+end
+
+def fun_l1_n115(x)
+ if (x < 1)
+ fun_l2_n67(x)
+ else
+ fun_l2_n442(x)
+ end
+end
+
+def fun_l1_n116(x)
+ if (x < 1)
+ fun_l2_n278(x)
+ else
+ fun_l2_n653(x)
+ end
+end
+
+def fun_l1_n117(x)
+ if (x < 1)
+ fun_l2_n457(x)
+ else
+ fun_l2_n179(x)
+ end
+end
+
+def fun_l1_n118(x)
+ if (x < 1)
+ fun_l2_n384(x)
+ else
+ fun_l2_n594(x)
+ end
+end
+
+def fun_l1_n119(x)
+ if (x < 1)
+ fun_l2_n361(x)
+ else
+ fun_l2_n770(x)
+ end
+end
+
+def fun_l1_n120(x)
+ if (x < 1)
+ fun_l2_n24(x)
+ else
+ fun_l2_n269(x)
+ end
+end
+
+def fun_l1_n121(x)
+ if (x < 1)
+ fun_l2_n57(x)
+ else
+ fun_l2_n2(x)
+ end
+end
+
+def fun_l1_n122(x)
+ if (x < 1)
+ fun_l2_n421(x)
+ else
+ fun_l2_n339(x)
+ end
+end
+
+def fun_l1_n123(x)
+ if (x < 1)
+ fun_l2_n623(x)
+ else
+ fun_l2_n985(x)
+ end
+end
+
+def fun_l1_n124(x)
+ if (x < 1)
+ fun_l2_n609(x)
+ else
+ fun_l2_n530(x)
+ end
+end
+
+def fun_l1_n125(x)
+ if (x < 1)
+ fun_l2_n565(x)
+ else
+ fun_l2_n155(x)
+ end
+end
+
+def fun_l1_n126(x)
+ if (x < 1)
+ fun_l2_n135(x)
+ else
+ fun_l2_n971(x)
+ end
+end
+
+def fun_l1_n127(x)
+ if (x < 1)
+ fun_l2_n691(x)
+ else
+ fun_l2_n503(x)
+ end
+end
+
+def fun_l1_n128(x)
+ if (x < 1)
+ fun_l2_n555(x)
+ else
+ fun_l2_n67(x)
+ end
+end
+
+def fun_l1_n129(x)
+ if (x < 1)
+ fun_l2_n95(x)
+ else
+ fun_l2_n192(x)
+ end
+end
+
+def fun_l1_n130(x)
+ if (x < 1)
+ fun_l2_n432(x)
+ else
+ fun_l2_n771(x)
+ end
+end
+
+def fun_l1_n131(x)
+ if (x < 1)
+ fun_l2_n993(x)
+ else
+ fun_l2_n539(x)
+ end
+end
+
+def fun_l1_n132(x)
+ if (x < 1)
+ fun_l2_n809(x)
+ else
+ fun_l2_n902(x)
+ end
+end
+
+def fun_l1_n133(x)
+ if (x < 1)
+ fun_l2_n95(x)
+ else
+ fun_l2_n928(x)
+ end
+end
+
+def fun_l1_n134(x)
+ if (x < 1)
+ fun_l2_n781(x)
+ else
+ fun_l2_n832(x)
+ end
+end
+
+def fun_l1_n135(x)
+ if (x < 1)
+ fun_l2_n231(x)
+ else
+ fun_l2_n392(x)
+ end
+end
+
+def fun_l1_n136(x)
+ if (x < 1)
+ fun_l2_n102(x)
+ else
+ fun_l2_n449(x)
+ end
+end
+
+def fun_l1_n137(x)
+ if (x < 1)
+ fun_l2_n196(x)
+ else
+ fun_l2_n909(x)
+ end
+end
+
+def fun_l1_n138(x)
+ if (x < 1)
+ fun_l2_n449(x)
+ else
+ fun_l2_n190(x)
+ end
+end
+
+def fun_l1_n139(x)
+ if (x < 1)
+ fun_l2_n638(x)
+ else
+ fun_l2_n149(x)
+ end
+end
+
+def fun_l1_n140(x)
+ if (x < 1)
+ fun_l2_n523(x)
+ else
+ fun_l2_n297(x)
+ end
+end
+
+def fun_l1_n141(x)
+ if (x < 1)
+ fun_l2_n476(x)
+ else
+ fun_l2_n161(x)
+ end
+end
+
+def fun_l1_n142(x)
+ if (x < 1)
+ fun_l2_n893(x)
+ else
+ fun_l2_n686(x)
+ end
+end
+
+def fun_l1_n143(x)
+ if (x < 1)
+ fun_l2_n958(x)
+ else
+ fun_l2_n899(x)
+ end
+end
+
+def fun_l1_n144(x)
+ if (x < 1)
+ fun_l2_n104(x)
+ else
+ fun_l2_n912(x)
+ end
+end
+
+def fun_l1_n145(x)
+ if (x < 1)
+ fun_l2_n332(x)
+ else
+ fun_l2_n579(x)
+ end
+end
+
+def fun_l1_n146(x)
+ if (x < 1)
+ fun_l2_n40(x)
+ else
+ fun_l2_n468(x)
+ end
+end
+
+def fun_l1_n147(x)
+ if (x < 1)
+ fun_l2_n771(x)
+ else
+ fun_l2_n314(x)
+ end
+end
+
+def fun_l1_n148(x)
+ if (x < 1)
+ fun_l2_n340(x)
+ else
+ fun_l2_n203(x)
+ end
+end
+
+def fun_l1_n149(x)
+ if (x < 1)
+ fun_l2_n952(x)
+ else
+ fun_l2_n265(x)
+ end
+end
+
+def fun_l1_n150(x)
+ if (x < 1)
+ fun_l2_n11(x)
+ else
+ fun_l2_n303(x)
+ end
+end
+
+def fun_l1_n151(x)
+ if (x < 1)
+ fun_l2_n394(x)
+ else
+ fun_l2_n317(x)
+ end
+end
+
+def fun_l1_n152(x)
+ if (x < 1)
+ fun_l2_n140(x)
+ else
+ fun_l2_n906(x)
+ end
+end
+
+def fun_l1_n153(x)
+ if (x < 1)
+ fun_l2_n75(x)
+ else
+ fun_l2_n485(x)
+ end
+end
+
+def fun_l1_n154(x)
+ if (x < 1)
+ fun_l2_n842(x)
+ else
+ fun_l2_n370(x)
+ end
+end
+
+def fun_l1_n155(x)
+ if (x < 1)
+ fun_l2_n346(x)
+ else
+ fun_l2_n833(x)
+ end
+end
+
+def fun_l1_n156(x)
+ if (x < 1)
+ fun_l2_n433(x)
+ else
+ fun_l2_n373(x)
+ end
+end
+
+def fun_l1_n157(x)
+ if (x < 1)
+ fun_l2_n978(x)
+ else
+ fun_l2_n99(x)
+ end
+end
+
+def fun_l1_n158(x)
+ if (x < 1)
+ fun_l2_n540(x)
+ else
+ fun_l2_n987(x)
+ end
+end
+
+def fun_l1_n159(x)
+ if (x < 1)
+ fun_l2_n785(x)
+ else
+ fun_l2_n478(x)
+ end
+end
+
+def fun_l1_n160(x)
+ if (x < 1)
+ fun_l2_n282(x)
+ else
+ fun_l2_n222(x)
+ end
+end
+
+def fun_l1_n161(x)
+ if (x < 1)
+ fun_l2_n29(x)
+ else
+ fun_l2_n946(x)
+ end
+end
+
+def fun_l1_n162(x)
+ if (x < 1)
+ fun_l2_n314(x)
+ else
+ fun_l2_n758(x)
+ end
+end
+
+def fun_l1_n163(x)
+ if (x < 1)
+ fun_l2_n861(x)
+ else
+ fun_l2_n799(x)
+ end
+end
+
+def fun_l1_n164(x)
+ if (x < 1)
+ fun_l2_n403(x)
+ else
+ fun_l2_n413(x)
+ end
+end
+
+def fun_l1_n165(x)
+ if (x < 1)
+ fun_l2_n160(x)
+ else
+ fun_l2_n794(x)
+ end
+end
+
+def fun_l1_n166(x)
+ if (x < 1)
+ fun_l2_n114(x)
+ else
+ fun_l2_n238(x)
+ end
+end
+
+def fun_l1_n167(x)
+ if (x < 1)
+ fun_l2_n806(x)
+ else
+ fun_l2_n233(x)
+ end
+end
+
+def fun_l1_n168(x)
+ if (x < 1)
+ fun_l2_n871(x)
+ else
+ fun_l2_n53(x)
+ end
+end
+
+def fun_l1_n169(x)
+ if (x < 1)
+ fun_l2_n644(x)
+ else
+ fun_l2_n503(x)
+ end
+end
+
+def fun_l1_n170(x)
+ if (x < 1)
+ fun_l2_n172(x)
+ else
+ fun_l2_n289(x)
+ end
+end
+
+def fun_l1_n171(x)
+ if (x < 1)
+ fun_l2_n920(x)
+ else
+ fun_l2_n851(x)
+ end
+end
+
+def fun_l1_n172(x)
+ if (x < 1)
+ fun_l2_n552(x)
+ else
+ fun_l2_n822(x)
+ end
+end
+
+def fun_l1_n173(x)
+ if (x < 1)
+ fun_l2_n747(x)
+ else
+ fun_l2_n265(x)
+ end
+end
+
+def fun_l1_n174(x)
+ if (x < 1)
+ fun_l2_n287(x)
+ else
+ fun_l2_n762(x)
+ end
+end
+
+def fun_l1_n175(x)
+ if (x < 1)
+ fun_l2_n627(x)
+ else
+ fun_l2_n951(x)
+ end
+end
+
+def fun_l1_n176(x)
+ if (x < 1)
+ fun_l2_n459(x)
+ else
+ fun_l2_n962(x)
+ end
+end
+
+def fun_l1_n177(x)
+ if (x < 1)
+ fun_l2_n214(x)
+ else
+ fun_l2_n145(x)
+ end
+end
+
+def fun_l1_n178(x)
+ if (x < 1)
+ fun_l2_n620(x)
+ else
+ fun_l2_n995(x)
+ end
+end
+
+def fun_l1_n179(x)
+ if (x < 1)
+ fun_l2_n136(x)
+ else
+ fun_l2_n283(x)
+ end
+end
+
+def fun_l1_n180(x)
+ if (x < 1)
+ fun_l2_n377(x)
+ else
+ fun_l2_n672(x)
+ end
+end
+
+def fun_l1_n181(x)
+ if (x < 1)
+ fun_l2_n218(x)
+ else
+ fun_l2_n434(x)
+ end
+end
+
+def fun_l1_n182(x)
+ if (x < 1)
+ fun_l2_n522(x)
+ else
+ fun_l2_n525(x)
+ end
+end
+
+def fun_l1_n183(x)
+ if (x < 1)
+ fun_l2_n648(x)
+ else
+ fun_l2_n725(x)
+ end
+end
+
+def fun_l1_n184(x)
+ if (x < 1)
+ fun_l2_n579(x)
+ else
+ fun_l2_n974(x)
+ end
+end
+
+def fun_l1_n185(x)
+ if (x < 1)
+ fun_l2_n10(x)
+ else
+ fun_l2_n514(x)
+ end
+end
+
+def fun_l1_n186(x)
+ if (x < 1)
+ fun_l2_n829(x)
+ else
+ fun_l2_n754(x)
+ end
+end
+
+def fun_l1_n187(x)
+ if (x < 1)
+ fun_l2_n380(x)
+ else
+ fun_l2_n401(x)
+ end
+end
+
+def fun_l1_n188(x)
+ if (x < 1)
+ fun_l2_n839(x)
+ else
+ fun_l2_n453(x)
+ end
+end
+
+def fun_l1_n189(x)
+ if (x < 1)
+ fun_l2_n553(x)
+ else
+ fun_l2_n553(x)
+ end
+end
+
+def fun_l1_n190(x)
+ if (x < 1)
+ fun_l2_n972(x)
+ else
+ fun_l2_n187(x)
+ end
+end
+
+def fun_l1_n191(x)
+ if (x < 1)
+ fun_l2_n275(x)
+ else
+ fun_l2_n11(x)
+ end
+end
+
+def fun_l1_n192(x)
+ if (x < 1)
+ fun_l2_n1(x)
+ else
+ fun_l2_n927(x)
+ end
+end
+
+def fun_l1_n193(x)
+ if (x < 1)
+ fun_l2_n569(x)
+ else
+ fun_l2_n557(x)
+ end
+end
+
+def fun_l1_n194(x)
+ if (x < 1)
+ fun_l2_n380(x)
+ else
+ fun_l2_n187(x)
+ end
+end
+
+def fun_l1_n195(x)
+ if (x < 1)
+ fun_l2_n297(x)
+ else
+ fun_l2_n813(x)
+ end
+end
+
+def fun_l1_n196(x)
+ if (x < 1)
+ fun_l2_n565(x)
+ else
+ fun_l2_n514(x)
+ end
+end
+
+def fun_l1_n197(x)
+ if (x < 1)
+ fun_l2_n473(x)
+ else
+ fun_l2_n64(x)
+ end
+end
+
+def fun_l1_n198(x)
+ if (x < 1)
+ fun_l2_n182(x)
+ else
+ fun_l2_n363(x)
+ end
+end
+
+def fun_l1_n199(x)
+ if (x < 1)
+ fun_l2_n660(x)
+ else
+ fun_l2_n506(x)
+ end
+end
+
+def fun_l1_n200(x)
+ if (x < 1)
+ fun_l2_n834(x)
+ else
+ fun_l2_n348(x)
+ end
+end
+
+def fun_l1_n201(x)
+ if (x < 1)
+ fun_l2_n403(x)
+ else
+ fun_l2_n432(x)
+ end
+end
+
+def fun_l1_n202(x)
+ if (x < 1)
+ fun_l2_n115(x)
+ else
+ fun_l2_n145(x)
+ end
+end
+
+def fun_l1_n203(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n4(x)
+ end
+end
+
+def fun_l1_n204(x)
+ if (x < 1)
+ fun_l2_n951(x)
+ else
+ fun_l2_n753(x)
+ end
+end
+
+def fun_l1_n205(x)
+ if (x < 1)
+ fun_l2_n703(x)
+ else
+ fun_l2_n563(x)
+ end
+end
+
+def fun_l1_n206(x)
+ if (x < 1)
+ fun_l2_n614(x)
+ else
+ fun_l2_n563(x)
+ end
+end
+
+def fun_l1_n207(x)
+ if (x < 1)
+ fun_l2_n210(x)
+ else
+ fun_l2_n139(x)
+ end
+end
+
+def fun_l1_n208(x)
+ if (x < 1)
+ fun_l2_n471(x)
+ else
+ fun_l2_n346(x)
+ end
+end
+
+def fun_l1_n209(x)
+ if (x < 1)
+ fun_l2_n922(x)
+ else
+ fun_l2_n54(x)
+ end
+end
+
+def fun_l1_n210(x)
+ if (x < 1)
+ fun_l2_n494(x)
+ else
+ fun_l2_n41(x)
+ end
+end
+
+def fun_l1_n211(x)
+ if (x < 1)
+ fun_l2_n87(x)
+ else
+ fun_l2_n190(x)
+ end
+end
+
+def fun_l1_n212(x)
+ if (x < 1)
+ fun_l2_n458(x)
+ else
+ fun_l2_n885(x)
+ end
+end
+
+def fun_l1_n213(x)
+ if (x < 1)
+ fun_l2_n48(x)
+ else
+ fun_l2_n225(x)
+ end
+end
+
+def fun_l1_n214(x)
+ if (x < 1)
+ fun_l2_n706(x)
+ else
+ fun_l2_n694(x)
+ end
+end
+
+def fun_l1_n215(x)
+ if (x < 1)
+ fun_l2_n116(x)
+ else
+ fun_l2_n233(x)
+ end
+end
+
+def fun_l1_n216(x)
+ if (x < 1)
+ fun_l2_n279(x)
+ else
+ fun_l2_n857(x)
+ end
+end
+
+def fun_l1_n217(x)
+ if (x < 1)
+ fun_l2_n643(x)
+ else
+ fun_l2_n289(x)
+ end
+end
+
+def fun_l1_n218(x)
+ if (x < 1)
+ fun_l2_n535(x)
+ else
+ fun_l2_n833(x)
+ end
+end
+
+def fun_l1_n219(x)
+ if (x < 1)
+ fun_l2_n478(x)
+ else
+ fun_l2_n793(x)
+ end
+end
+
+def fun_l1_n220(x)
+ if (x < 1)
+ fun_l2_n57(x)
+ else
+ fun_l2_n64(x)
+ end
+end
+
+def fun_l1_n221(x)
+ if (x < 1)
+ fun_l2_n36(x)
+ else
+ fun_l2_n74(x)
+ end
+end
+
+def fun_l1_n222(x)
+ if (x < 1)
+ fun_l2_n438(x)
+ else
+ fun_l2_n616(x)
+ end
+end
+
+def fun_l1_n223(x)
+ if (x < 1)
+ fun_l2_n900(x)
+ else
+ fun_l2_n744(x)
+ end
+end
+
+def fun_l1_n224(x)
+ if (x < 1)
+ fun_l2_n780(x)
+ else
+ fun_l2_n213(x)
+ end
+end
+
+def fun_l1_n225(x)
+ if (x < 1)
+ fun_l2_n916(x)
+ else
+ fun_l2_n471(x)
+ end
+end
+
+def fun_l1_n226(x)
+ if (x < 1)
+ fun_l2_n236(x)
+ else
+ fun_l2_n980(x)
+ end
+end
+
+def fun_l1_n227(x)
+ if (x < 1)
+ fun_l2_n28(x)
+ else
+ fun_l2_n291(x)
+ end
+end
+
+def fun_l1_n228(x)
+ if (x < 1)
+ fun_l2_n35(x)
+ else
+ fun_l2_n353(x)
+ end
+end
+
+def fun_l1_n229(x)
+ if (x < 1)
+ fun_l2_n404(x)
+ else
+ fun_l2_n254(x)
+ end
+end
+
+def fun_l1_n230(x)
+ if (x < 1)
+ fun_l2_n641(x)
+ else
+ fun_l2_n464(x)
+ end
+end
+
+def fun_l1_n231(x)
+ if (x < 1)
+ fun_l2_n592(x)
+ else
+ fun_l2_n646(x)
+ end
+end
+
+def fun_l1_n232(x)
+ if (x < 1)
+ fun_l2_n162(x)
+ else
+ fun_l2_n215(x)
+ end
+end
+
+def fun_l1_n233(x)
+ if (x < 1)
+ fun_l2_n219(x)
+ else
+ fun_l2_n772(x)
+ end
+end
+
+def fun_l1_n234(x)
+ if (x < 1)
+ fun_l2_n304(x)
+ else
+ fun_l2_n963(x)
+ end
+end
+
+def fun_l1_n235(x)
+ if (x < 1)
+ fun_l2_n610(x)
+ else
+ fun_l2_n716(x)
+ end
+end
+
+def fun_l1_n236(x)
+ if (x < 1)
+ fun_l2_n151(x)
+ else
+ fun_l2_n498(x)
+ end
+end
+
+def fun_l1_n237(x)
+ if (x < 1)
+ fun_l2_n288(x)
+ else
+ fun_l2_n261(x)
+ end
+end
+
+def fun_l1_n238(x)
+ if (x < 1)
+ fun_l2_n139(x)
+ else
+ fun_l2_n18(x)
+ end
+end
+
+def fun_l1_n239(x)
+ if (x < 1)
+ fun_l2_n559(x)
+ else
+ fun_l2_n148(x)
+ end
+end
+
+def fun_l1_n240(x)
+ if (x < 1)
+ fun_l2_n520(x)
+ else
+ fun_l2_n250(x)
+ end
+end
+
+def fun_l1_n241(x)
+ if (x < 1)
+ fun_l2_n42(x)
+ else
+ fun_l2_n196(x)
+ end
+end
+
+def fun_l1_n242(x)
+ if (x < 1)
+ fun_l2_n16(x)
+ else
+ fun_l2_n540(x)
+ end
+end
+
+def fun_l1_n243(x)
+ if (x < 1)
+ fun_l2_n539(x)
+ else
+ fun_l2_n890(x)
+ end
+end
+
+def fun_l1_n244(x)
+ if (x < 1)
+ fun_l2_n559(x)
+ else
+ fun_l2_n423(x)
+ end
+end
+
+def fun_l1_n245(x)
+ if (x < 1)
+ fun_l2_n110(x)
+ else
+ fun_l2_n711(x)
+ end
+end
+
+def fun_l1_n246(x)
+ if (x < 1)
+ fun_l2_n151(x)
+ else
+ fun_l2_n407(x)
+ end
+end
+
+def fun_l1_n247(x)
+ if (x < 1)
+ fun_l2_n118(x)
+ else
+ fun_l2_n209(x)
+ end
+end
+
+def fun_l1_n248(x)
+ if (x < 1)
+ fun_l2_n764(x)
+ else
+ fun_l2_n932(x)
+ end
+end
+
+def fun_l1_n249(x)
+ if (x < 1)
+ fun_l2_n991(x)
+ else
+ fun_l2_n828(x)
+ end
+end
+
+def fun_l1_n250(x)
+ if (x < 1)
+ fun_l2_n354(x)
+ else
+ fun_l2_n53(x)
+ end
+end
+
+def fun_l1_n251(x)
+ if (x < 1)
+ fun_l2_n63(x)
+ else
+ fun_l2_n292(x)
+ end
+end
+
+def fun_l1_n252(x)
+ if (x < 1)
+ fun_l2_n874(x)
+ else
+ fun_l2_n544(x)
+ end
+end
+
+def fun_l1_n253(x)
+ if (x < 1)
+ fun_l2_n336(x)
+ else
+ fun_l2_n57(x)
+ end
+end
+
+def fun_l1_n254(x)
+ if (x < 1)
+ fun_l2_n302(x)
+ else
+ fun_l2_n90(x)
+ end
+end
+
+def fun_l1_n255(x)
+ if (x < 1)
+ fun_l2_n122(x)
+ else
+ fun_l2_n888(x)
+ end
+end
+
+def fun_l1_n256(x)
+ if (x < 1)
+ fun_l2_n326(x)
+ else
+ fun_l2_n616(x)
+ end
+end
+
+def fun_l1_n257(x)
+ if (x < 1)
+ fun_l2_n77(x)
+ else
+ fun_l2_n622(x)
+ end
+end
+
+def fun_l1_n258(x)
+ if (x < 1)
+ fun_l2_n785(x)
+ else
+ fun_l2_n229(x)
+ end
+end
+
+def fun_l1_n259(x)
+ if (x < 1)
+ fun_l2_n504(x)
+ else
+ fun_l2_n766(x)
+ end
+end
+
+def fun_l1_n260(x)
+ if (x < 1)
+ fun_l2_n857(x)
+ else
+ fun_l2_n823(x)
+ end
+end
+
+def fun_l1_n261(x)
+ if (x < 1)
+ fun_l2_n72(x)
+ else
+ fun_l2_n875(x)
+ end
+end
+
+def fun_l1_n262(x)
+ if (x < 1)
+ fun_l2_n215(x)
+ else
+ fun_l2_n549(x)
+ end
+end
+
+def fun_l1_n263(x)
+ if (x < 1)
+ fun_l2_n232(x)
+ else
+ fun_l2_n96(x)
+ end
+end
+
+def fun_l1_n264(x)
+ if (x < 1)
+ fun_l2_n183(x)
+ else
+ fun_l2_n351(x)
+ end
+end
+
+def fun_l1_n265(x)
+ if (x < 1)
+ fun_l2_n906(x)
+ else
+ fun_l2_n154(x)
+ end
+end
+
+def fun_l1_n266(x)
+ if (x < 1)
+ fun_l2_n234(x)
+ else
+ fun_l2_n547(x)
+ end
+end
+
+def fun_l1_n267(x)
+ if (x < 1)
+ fun_l2_n882(x)
+ else
+ fun_l2_n802(x)
+ end
+end
+
+def fun_l1_n268(x)
+ if (x < 1)
+ fun_l2_n844(x)
+ else
+ fun_l2_n430(x)
+ end
+end
+
+def fun_l1_n269(x)
+ if (x < 1)
+ fun_l2_n781(x)
+ else
+ fun_l2_n738(x)
+ end
+end
+
+def fun_l1_n270(x)
+ if (x < 1)
+ fun_l2_n88(x)
+ else
+ fun_l2_n439(x)
+ end
+end
+
+def fun_l1_n271(x)
+ if (x < 1)
+ fun_l2_n334(x)
+ else
+ fun_l2_n508(x)
+ end
+end
+
+def fun_l1_n272(x)
+ if (x < 1)
+ fun_l2_n871(x)
+ else
+ fun_l2_n562(x)
+ end
+end
+
+def fun_l1_n273(x)
+ if (x < 1)
+ fun_l2_n328(x)
+ else
+ fun_l2_n356(x)
+ end
+end
+
+def fun_l1_n274(x)
+ if (x < 1)
+ fun_l2_n654(x)
+ else
+ fun_l2_n511(x)
+ end
+end
+
+def fun_l1_n275(x)
+ if (x < 1)
+ fun_l2_n309(x)
+ else
+ fun_l2_n840(x)
+ end
+end
+
+def fun_l1_n276(x)
+ if (x < 1)
+ fun_l2_n729(x)
+ else
+ fun_l2_n72(x)
+ end
+end
+
+def fun_l1_n277(x)
+ if (x < 1)
+ fun_l2_n993(x)
+ else
+ fun_l2_n858(x)
+ end
+end
+
+def fun_l1_n278(x)
+ if (x < 1)
+ fun_l2_n664(x)
+ else
+ fun_l2_n50(x)
+ end
+end
+
+def fun_l1_n279(x)
+ if (x < 1)
+ fun_l2_n225(x)
+ else
+ fun_l2_n403(x)
+ end
+end
+
+def fun_l1_n280(x)
+ if (x < 1)
+ fun_l2_n780(x)
+ else
+ fun_l2_n396(x)
+ end
+end
+
+def fun_l1_n281(x)
+ if (x < 1)
+ fun_l2_n114(x)
+ else
+ fun_l2_n114(x)
+ end
+end
+
+def fun_l1_n282(x)
+ if (x < 1)
+ fun_l2_n568(x)
+ else
+ fun_l2_n610(x)
+ end
+end
+
+def fun_l1_n283(x)
+ if (x < 1)
+ fun_l2_n539(x)
+ else
+ fun_l2_n990(x)
+ end
+end
+
+def fun_l1_n284(x)
+ if (x < 1)
+ fun_l2_n773(x)
+ else
+ fun_l2_n622(x)
+ end
+end
+
+def fun_l1_n285(x)
+ if (x < 1)
+ fun_l2_n695(x)
+ else
+ fun_l2_n101(x)
+ end
+end
+
+def fun_l1_n286(x)
+ if (x < 1)
+ fun_l2_n239(x)
+ else
+ fun_l2_n242(x)
+ end
+end
+
+def fun_l1_n287(x)
+ if (x < 1)
+ fun_l2_n191(x)
+ else
+ fun_l2_n839(x)
+ end
+end
+
+def fun_l1_n288(x)
+ if (x < 1)
+ fun_l2_n246(x)
+ else
+ fun_l2_n179(x)
+ end
+end
+
+def fun_l1_n289(x)
+ if (x < 1)
+ fun_l2_n300(x)
+ else
+ fun_l2_n975(x)
+ end
+end
+
+def fun_l1_n290(x)
+ if (x < 1)
+ fun_l2_n436(x)
+ else
+ fun_l2_n14(x)
+ end
+end
+
+def fun_l1_n291(x)
+ if (x < 1)
+ fun_l2_n33(x)
+ else
+ fun_l2_n303(x)
+ end
+end
+
+def fun_l1_n292(x)
+ if (x < 1)
+ fun_l2_n462(x)
+ else
+ fun_l2_n399(x)
+ end
+end
+
+def fun_l1_n293(x)
+ if (x < 1)
+ fun_l2_n782(x)
+ else
+ fun_l2_n521(x)
+ end
+end
+
+def fun_l1_n294(x)
+ if (x < 1)
+ fun_l2_n995(x)
+ else
+ fun_l2_n944(x)
+ end
+end
+
+def fun_l1_n295(x)
+ if (x < 1)
+ fun_l2_n700(x)
+ else
+ fun_l2_n250(x)
+ end
+end
+
+def fun_l1_n296(x)
+ if (x < 1)
+ fun_l2_n866(x)
+ else
+ fun_l2_n566(x)
+ end
+end
+
+def fun_l1_n297(x)
+ if (x < 1)
+ fun_l2_n373(x)
+ else
+ fun_l2_n881(x)
+ end
+end
+
+def fun_l1_n298(x)
+ if (x < 1)
+ fun_l2_n382(x)
+ else
+ fun_l2_n729(x)
+ end
+end
+
+def fun_l1_n299(x)
+ if (x < 1)
+ fun_l2_n878(x)
+ else
+ fun_l2_n192(x)
+ end
+end
+
+def fun_l1_n300(x)
+ if (x < 1)
+ fun_l2_n65(x)
+ else
+ fun_l2_n434(x)
+ end
+end
+
+def fun_l1_n301(x)
+ if (x < 1)
+ fun_l2_n513(x)
+ else
+ fun_l2_n617(x)
+ end
+end
+
+def fun_l1_n302(x)
+ if (x < 1)
+ fun_l2_n972(x)
+ else
+ fun_l2_n482(x)
+ end
+end
+
+def fun_l1_n303(x)
+ if (x < 1)
+ fun_l2_n533(x)
+ else
+ fun_l2_n774(x)
+ end
+end
+
+def fun_l1_n304(x)
+ if (x < 1)
+ fun_l2_n439(x)
+ else
+ fun_l2_n351(x)
+ end
+end
+
+def fun_l1_n305(x)
+ if (x < 1)
+ fun_l2_n181(x)
+ else
+ fun_l2_n74(x)
+ end
+end
+
+def fun_l1_n306(x)
+ if (x < 1)
+ fun_l2_n117(x)
+ else
+ fun_l2_n962(x)
+ end
+end
+
+def fun_l1_n307(x)
+ if (x < 1)
+ fun_l2_n499(x)
+ else
+ fun_l2_n183(x)
+ end
+end
+
+def fun_l1_n308(x)
+ if (x < 1)
+ fun_l2_n358(x)
+ else
+ fun_l2_n226(x)
+ end
+end
+
+def fun_l1_n309(x)
+ if (x < 1)
+ fun_l2_n227(x)
+ else
+ fun_l2_n425(x)
+ end
+end
+
+def fun_l1_n310(x)
+ if (x < 1)
+ fun_l2_n724(x)
+ else
+ fun_l2_n278(x)
+ end
+end
+
+def fun_l1_n311(x)
+ if (x < 1)
+ fun_l2_n784(x)
+ else
+ fun_l2_n888(x)
+ end
+end
+
+def fun_l1_n312(x)
+ if (x < 1)
+ fun_l2_n952(x)
+ else
+ fun_l2_n849(x)
+ end
+end
+
+def fun_l1_n313(x)
+ if (x < 1)
+ fun_l2_n921(x)
+ else
+ fun_l2_n31(x)
+ end
+end
+
+def fun_l1_n314(x)
+ if (x < 1)
+ fun_l2_n469(x)
+ else
+ fun_l2_n856(x)
+ end
+end
+
+def fun_l1_n315(x)
+ if (x < 1)
+ fun_l2_n89(x)
+ else
+ fun_l2_n949(x)
+ end
+end
+
+def fun_l1_n316(x)
+ if (x < 1)
+ fun_l2_n216(x)
+ else
+ fun_l2_n410(x)
+ end
+end
+
+def fun_l1_n317(x)
+ if (x < 1)
+ fun_l2_n591(x)
+ else
+ fun_l2_n203(x)
+ end
+end
+
+def fun_l1_n318(x)
+ if (x < 1)
+ fun_l2_n19(x)
+ else
+ fun_l2_n461(x)
+ end
+end
+
+def fun_l1_n319(x)
+ if (x < 1)
+ fun_l2_n875(x)
+ else
+ fun_l2_n996(x)
+ end
+end
+
+def fun_l1_n320(x)
+ if (x < 1)
+ fun_l2_n696(x)
+ else
+ fun_l2_n987(x)
+ end
+end
+
+def fun_l1_n321(x)
+ if (x < 1)
+ fun_l2_n708(x)
+ else
+ fun_l2_n150(x)
+ end
+end
+
+def fun_l1_n322(x)
+ if (x < 1)
+ fun_l2_n324(x)
+ else
+ fun_l2_n814(x)
+ end
+end
+
+def fun_l1_n323(x)
+ if (x < 1)
+ fun_l2_n427(x)
+ else
+ fun_l2_n472(x)
+ end
+end
+
+def fun_l1_n324(x)
+ if (x < 1)
+ fun_l2_n847(x)
+ else
+ fun_l2_n482(x)
+ end
+end
+
+def fun_l1_n325(x)
+ if (x < 1)
+ fun_l2_n335(x)
+ else
+ fun_l2_n854(x)
+ end
+end
+
+def fun_l1_n326(x)
+ if (x < 1)
+ fun_l2_n635(x)
+ else
+ fun_l2_n276(x)
+ end
+end
+
+def fun_l1_n327(x)
+ if (x < 1)
+ fun_l2_n539(x)
+ else
+ fun_l2_n885(x)
+ end
+end
+
+def fun_l1_n328(x)
+ if (x < 1)
+ fun_l2_n979(x)
+ else
+ fun_l2_n558(x)
+ end
+end
+
+def fun_l1_n329(x)
+ if (x < 1)
+ fun_l2_n35(x)
+ else
+ fun_l2_n696(x)
+ end
+end
+
+def fun_l1_n330(x)
+ if (x < 1)
+ fun_l2_n483(x)
+ else
+ fun_l2_n218(x)
+ end
+end
+
+def fun_l1_n331(x)
+ if (x < 1)
+ fun_l2_n3(x)
+ else
+ fun_l2_n324(x)
+ end
+end
+
+def fun_l1_n332(x)
+ if (x < 1)
+ fun_l2_n396(x)
+ else
+ fun_l2_n718(x)
+ end
+end
+
+def fun_l1_n333(x)
+ if (x < 1)
+ fun_l2_n973(x)
+ else
+ fun_l2_n663(x)
+ end
+end
+
+def fun_l1_n334(x)
+ if (x < 1)
+ fun_l2_n441(x)
+ else
+ fun_l2_n468(x)
+ end
+end
+
+def fun_l1_n335(x)
+ if (x < 1)
+ fun_l2_n511(x)
+ else
+ fun_l2_n455(x)
+ end
+end
+
+def fun_l1_n336(x)
+ if (x < 1)
+ fun_l2_n732(x)
+ else
+ fun_l2_n14(x)
+ end
+end
+
+def fun_l1_n337(x)
+ if (x < 1)
+ fun_l2_n484(x)
+ else
+ fun_l2_n482(x)
+ end
+end
+
+def fun_l1_n338(x)
+ if (x < 1)
+ fun_l2_n604(x)
+ else
+ fun_l2_n683(x)
+ end
+end
+
+def fun_l1_n339(x)
+ if (x < 1)
+ fun_l2_n334(x)
+ else
+ fun_l2_n710(x)
+ end
+end
+
+def fun_l1_n340(x)
+ if (x < 1)
+ fun_l2_n233(x)
+ else
+ fun_l2_n394(x)
+ end
+end
+
+def fun_l1_n341(x)
+ if (x < 1)
+ fun_l2_n948(x)
+ else
+ fun_l2_n473(x)
+ end
+end
+
+def fun_l1_n342(x)
+ if (x < 1)
+ fun_l2_n858(x)
+ else
+ fun_l2_n466(x)
+ end
+end
+
+def fun_l1_n343(x)
+ if (x < 1)
+ fun_l2_n647(x)
+ else
+ fun_l2_n604(x)
+ end
+end
+
+def fun_l1_n344(x)
+ if (x < 1)
+ fun_l2_n872(x)
+ else
+ fun_l2_n965(x)
+ end
+end
+
+def fun_l1_n345(x)
+ if (x < 1)
+ fun_l2_n845(x)
+ else
+ fun_l2_n701(x)
+ end
+end
+
+def fun_l1_n346(x)
+ if (x < 1)
+ fun_l2_n75(x)
+ else
+ fun_l2_n332(x)
+ end
+end
+
+def fun_l1_n347(x)
+ if (x < 1)
+ fun_l2_n873(x)
+ else
+ fun_l2_n575(x)
+ end
+end
+
+def fun_l1_n348(x)
+ if (x < 1)
+ fun_l2_n303(x)
+ else
+ fun_l2_n445(x)
+ end
+end
+
+def fun_l1_n349(x)
+ if (x < 1)
+ fun_l2_n45(x)
+ else
+ fun_l2_n312(x)
+ end
+end
+
+def fun_l1_n350(x)
+ if (x < 1)
+ fun_l2_n751(x)
+ else
+ fun_l2_n316(x)
+ end
+end
+
+def fun_l1_n351(x)
+ if (x < 1)
+ fun_l2_n781(x)
+ else
+ fun_l2_n165(x)
+ end
+end
+
+def fun_l1_n352(x)
+ if (x < 1)
+ fun_l2_n120(x)
+ else
+ fun_l2_n595(x)
+ end
+end
+
+def fun_l1_n353(x)
+ if (x < 1)
+ fun_l2_n221(x)
+ else
+ fun_l2_n827(x)
+ end
+end
+
+def fun_l1_n354(x)
+ if (x < 1)
+ fun_l2_n290(x)
+ else
+ fun_l2_n27(x)
+ end
+end
+
+def fun_l1_n355(x)
+ if (x < 1)
+ fun_l2_n377(x)
+ else
+ fun_l2_n28(x)
+ end
+end
+
+def fun_l1_n356(x)
+ if (x < 1)
+ fun_l2_n474(x)
+ else
+ fun_l2_n811(x)
+ end
+end
+
+def fun_l1_n357(x)
+ if (x < 1)
+ fun_l2_n90(x)
+ else
+ fun_l2_n559(x)
+ end
+end
+
+def fun_l1_n358(x)
+ if (x < 1)
+ fun_l2_n66(x)
+ else
+ fun_l2_n234(x)
+ end
+end
+
+def fun_l1_n359(x)
+ if (x < 1)
+ fun_l2_n526(x)
+ else
+ fun_l2_n674(x)
+ end
+end
+
+def fun_l1_n360(x)
+ if (x < 1)
+ fun_l2_n449(x)
+ else
+ fun_l2_n364(x)
+ end
+end
+
+def fun_l1_n361(x)
+ if (x < 1)
+ fun_l2_n790(x)
+ else
+ fun_l2_n835(x)
+ end
+end
+
+def fun_l1_n362(x)
+ if (x < 1)
+ fun_l2_n335(x)
+ else
+ fun_l2_n22(x)
+ end
+end
+
+def fun_l1_n363(x)
+ if (x < 1)
+ fun_l2_n982(x)
+ else
+ fun_l2_n449(x)
+ end
+end
+
+def fun_l1_n364(x)
+ if (x < 1)
+ fun_l2_n980(x)
+ else
+ fun_l2_n861(x)
+ end
+end
+
+def fun_l1_n365(x)
+ if (x < 1)
+ fun_l2_n673(x)
+ else
+ fun_l2_n267(x)
+ end
+end
+
+def fun_l1_n366(x)
+ if (x < 1)
+ fun_l2_n862(x)
+ else
+ fun_l2_n559(x)
+ end
+end
+
+def fun_l1_n367(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n275(x)
+ end
+end
+
+def fun_l1_n368(x)
+ if (x < 1)
+ fun_l2_n370(x)
+ else
+ fun_l2_n763(x)
+ end
+end
+
+def fun_l1_n369(x)
+ if (x < 1)
+ fun_l2_n680(x)
+ else
+ fun_l2_n476(x)
+ end
+end
+
+def fun_l1_n370(x)
+ if (x < 1)
+ fun_l2_n799(x)
+ else
+ fun_l2_n724(x)
+ end
+end
+
+def fun_l1_n371(x)
+ if (x < 1)
+ fun_l2_n331(x)
+ else
+ fun_l2_n927(x)
+ end
+end
+
+def fun_l1_n372(x)
+ if (x < 1)
+ fun_l2_n875(x)
+ else
+ fun_l2_n350(x)
+ end
+end
+
+def fun_l1_n373(x)
+ if (x < 1)
+ fun_l2_n734(x)
+ else
+ fun_l2_n172(x)
+ end
+end
+
+def fun_l1_n374(x)
+ if (x < 1)
+ fun_l2_n657(x)
+ else
+ fun_l2_n765(x)
+ end
+end
+
+def fun_l1_n375(x)
+ if (x < 1)
+ fun_l2_n950(x)
+ else
+ fun_l2_n85(x)
+ end
+end
+
+def fun_l1_n376(x)
+ if (x < 1)
+ fun_l2_n276(x)
+ else
+ fun_l2_n892(x)
+ end
+end
+
+def fun_l1_n377(x)
+ if (x < 1)
+ fun_l2_n430(x)
+ else
+ fun_l2_n173(x)
+ end
+end
+
+def fun_l1_n378(x)
+ if (x < 1)
+ fun_l2_n376(x)
+ else
+ fun_l2_n876(x)
+ end
+end
+
+def fun_l1_n379(x)
+ if (x < 1)
+ fun_l2_n981(x)
+ else
+ fun_l2_n314(x)
+ end
+end
+
+def fun_l1_n380(x)
+ if (x < 1)
+ fun_l2_n680(x)
+ else
+ fun_l2_n600(x)
+ end
+end
+
+def fun_l1_n381(x)
+ if (x < 1)
+ fun_l2_n54(x)
+ else
+ fun_l2_n158(x)
+ end
+end
+
+def fun_l1_n382(x)
+ if (x < 1)
+ fun_l2_n692(x)
+ else
+ fun_l2_n673(x)
+ end
+end
+
+def fun_l1_n383(x)
+ if (x < 1)
+ fun_l2_n393(x)
+ else
+ fun_l2_n723(x)
+ end
+end
+
+def fun_l1_n384(x)
+ if (x < 1)
+ fun_l2_n899(x)
+ else
+ fun_l2_n940(x)
+ end
+end
+
+def fun_l1_n385(x)
+ if (x < 1)
+ fun_l2_n473(x)
+ else
+ fun_l2_n846(x)
+ end
+end
+
+def fun_l1_n386(x)
+ if (x < 1)
+ fun_l2_n291(x)
+ else
+ fun_l2_n864(x)
+ end
+end
+
+def fun_l1_n387(x)
+ if (x < 1)
+ fun_l2_n174(x)
+ else
+ fun_l2_n466(x)
+ end
+end
+
+def fun_l1_n388(x)
+ if (x < 1)
+ fun_l2_n883(x)
+ else
+ fun_l2_n613(x)
+ end
+end
+
+def fun_l1_n389(x)
+ if (x < 1)
+ fun_l2_n808(x)
+ else
+ fun_l2_n169(x)
+ end
+end
+
+def fun_l1_n390(x)
+ if (x < 1)
+ fun_l2_n94(x)
+ else
+ fun_l2_n93(x)
+ end
+end
+
+def fun_l1_n391(x)
+ if (x < 1)
+ fun_l2_n874(x)
+ else
+ fun_l2_n400(x)
+ end
+end
+
+def fun_l1_n392(x)
+ if (x < 1)
+ fun_l2_n473(x)
+ else
+ fun_l2_n239(x)
+ end
+end
+
+def fun_l1_n393(x)
+ if (x < 1)
+ fun_l2_n64(x)
+ else
+ fun_l2_n760(x)
+ end
+end
+
+def fun_l1_n394(x)
+ if (x < 1)
+ fun_l2_n947(x)
+ else
+ fun_l2_n354(x)
+ end
+end
+
+def fun_l1_n395(x)
+ if (x < 1)
+ fun_l2_n833(x)
+ else
+ fun_l2_n563(x)
+ end
+end
+
+def fun_l1_n396(x)
+ if (x < 1)
+ fun_l2_n429(x)
+ else
+ fun_l2_n280(x)
+ end
+end
+
+def fun_l1_n397(x)
+ if (x < 1)
+ fun_l2_n132(x)
+ else
+ fun_l2_n486(x)
+ end
+end
+
+def fun_l1_n398(x)
+ if (x < 1)
+ fun_l2_n28(x)
+ else
+ fun_l2_n135(x)
+ end
+end
+
+def fun_l1_n399(x)
+ if (x < 1)
+ fun_l2_n804(x)
+ else
+ fun_l2_n406(x)
+ end
+end
+
+def fun_l1_n400(x)
+ if (x < 1)
+ fun_l2_n661(x)
+ else
+ fun_l2_n216(x)
+ end
+end
+
+def fun_l1_n401(x)
+ if (x < 1)
+ fun_l2_n681(x)
+ else
+ fun_l2_n849(x)
+ end
+end
+
+def fun_l1_n402(x)
+ if (x < 1)
+ fun_l2_n13(x)
+ else
+ fun_l2_n205(x)
+ end
+end
+
+def fun_l1_n403(x)
+ if (x < 1)
+ fun_l2_n911(x)
+ else
+ fun_l2_n63(x)
+ end
+end
+
+def fun_l1_n404(x)
+ if (x < 1)
+ fun_l2_n518(x)
+ else
+ fun_l2_n845(x)
+ end
+end
+
+def fun_l1_n405(x)
+ if (x < 1)
+ fun_l2_n699(x)
+ else
+ fun_l2_n963(x)
+ end
+end
+
+def fun_l1_n406(x)
+ if (x < 1)
+ fun_l2_n373(x)
+ else
+ fun_l2_n485(x)
+ end
+end
+
+def fun_l1_n407(x)
+ if (x < 1)
+ fun_l2_n402(x)
+ else
+ fun_l2_n582(x)
+ end
+end
+
+def fun_l1_n408(x)
+ if (x < 1)
+ fun_l2_n802(x)
+ else
+ fun_l2_n420(x)
+ end
+end
+
+def fun_l1_n409(x)
+ if (x < 1)
+ fun_l2_n728(x)
+ else
+ fun_l2_n50(x)
+ end
+end
+
+def fun_l1_n410(x)
+ if (x < 1)
+ fun_l2_n189(x)
+ else
+ fun_l2_n588(x)
+ end
+end
+
+def fun_l1_n411(x)
+ if (x < 1)
+ fun_l2_n51(x)
+ else
+ fun_l2_n23(x)
+ end
+end
+
+def fun_l1_n412(x)
+ if (x < 1)
+ fun_l2_n548(x)
+ else
+ fun_l2_n200(x)
+ end
+end
+
+def fun_l1_n413(x)
+ if (x < 1)
+ fun_l2_n763(x)
+ else
+ fun_l2_n581(x)
+ end
+end
+
+def fun_l1_n414(x)
+ if (x < 1)
+ fun_l2_n650(x)
+ else
+ fun_l2_n535(x)
+ end
+end
+
+def fun_l1_n415(x)
+ if (x < 1)
+ fun_l2_n500(x)
+ else
+ fun_l2_n579(x)
+ end
+end
+
+def fun_l1_n416(x)
+ if (x < 1)
+ fun_l2_n573(x)
+ else
+ fun_l2_n154(x)
+ end
+end
+
+def fun_l1_n417(x)
+ if (x < 1)
+ fun_l2_n685(x)
+ else
+ fun_l2_n14(x)
+ end
+end
+
+def fun_l1_n418(x)
+ if (x < 1)
+ fun_l2_n849(x)
+ else
+ fun_l2_n91(x)
+ end
+end
+
+def fun_l1_n419(x)
+ if (x < 1)
+ fun_l2_n629(x)
+ else
+ fun_l2_n698(x)
+ end
+end
+
+def fun_l1_n420(x)
+ if (x < 1)
+ fun_l2_n273(x)
+ else
+ fun_l2_n303(x)
+ end
+end
+
+def fun_l1_n421(x)
+ if (x < 1)
+ fun_l2_n8(x)
+ else
+ fun_l2_n476(x)
+ end
+end
+
+def fun_l1_n422(x)
+ if (x < 1)
+ fun_l2_n294(x)
+ else
+ fun_l2_n338(x)
+ end
+end
+
+def fun_l1_n423(x)
+ if (x < 1)
+ fun_l2_n408(x)
+ else
+ fun_l2_n187(x)
+ end
+end
+
+def fun_l1_n424(x)
+ if (x < 1)
+ fun_l2_n349(x)
+ else
+ fun_l2_n896(x)
+ end
+end
+
+def fun_l1_n425(x)
+ if (x < 1)
+ fun_l2_n950(x)
+ else
+ fun_l2_n186(x)
+ end
+end
+
+def fun_l1_n426(x)
+ if (x < 1)
+ fun_l2_n817(x)
+ else
+ fun_l2_n605(x)
+ end
+end
+
+def fun_l1_n427(x)
+ if (x < 1)
+ fun_l2_n317(x)
+ else
+ fun_l2_n31(x)
+ end
+end
+
+def fun_l1_n428(x)
+ if (x < 1)
+ fun_l2_n804(x)
+ else
+ fun_l2_n547(x)
+ end
+end
+
+def fun_l1_n429(x)
+ if (x < 1)
+ fun_l2_n730(x)
+ else
+ fun_l2_n711(x)
+ end
+end
+
+def fun_l1_n430(x)
+ if (x < 1)
+ fun_l2_n822(x)
+ else
+ fun_l2_n749(x)
+ end
+end
+
+def fun_l1_n431(x)
+ if (x < 1)
+ fun_l2_n412(x)
+ else
+ fun_l2_n366(x)
+ end
+end
+
+def fun_l1_n432(x)
+ if (x < 1)
+ fun_l2_n462(x)
+ else
+ fun_l2_n601(x)
+ end
+end
+
+def fun_l1_n433(x)
+ if (x < 1)
+ fun_l2_n971(x)
+ else
+ fun_l2_n878(x)
+ end
+end
+
+def fun_l1_n434(x)
+ if (x < 1)
+ fun_l2_n551(x)
+ else
+ fun_l2_n172(x)
+ end
+end
+
+def fun_l1_n435(x)
+ if (x < 1)
+ fun_l2_n914(x)
+ else
+ fun_l2_n640(x)
+ end
+end
+
+def fun_l1_n436(x)
+ if (x < 1)
+ fun_l2_n957(x)
+ else
+ fun_l2_n846(x)
+ end
+end
+
+def fun_l1_n437(x)
+ if (x < 1)
+ fun_l2_n622(x)
+ else
+ fun_l2_n995(x)
+ end
+end
+
+def fun_l1_n438(x)
+ if (x < 1)
+ fun_l2_n830(x)
+ else
+ fun_l2_n537(x)
+ end
+end
+
+def fun_l1_n439(x)
+ if (x < 1)
+ fun_l2_n415(x)
+ else
+ fun_l2_n863(x)
+ end
+end
+
+def fun_l1_n440(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n354(x)
+ end
+end
+
+def fun_l1_n441(x)
+ if (x < 1)
+ fun_l2_n525(x)
+ else
+ fun_l2_n656(x)
+ end
+end
+
+def fun_l1_n442(x)
+ if (x < 1)
+ fun_l2_n284(x)
+ else
+ fun_l2_n722(x)
+ end
+end
+
+def fun_l1_n443(x)
+ if (x < 1)
+ fun_l2_n485(x)
+ else
+ fun_l2_n794(x)
+ end
+end
+
+def fun_l1_n444(x)
+ if (x < 1)
+ fun_l2_n268(x)
+ else
+ fun_l2_n443(x)
+ end
+end
+
+def fun_l1_n445(x)
+ if (x < 1)
+ fun_l2_n743(x)
+ else
+ fun_l2_n723(x)
+ end
+end
+
+def fun_l1_n446(x)
+ if (x < 1)
+ fun_l2_n651(x)
+ else
+ fun_l2_n544(x)
+ end
+end
+
+def fun_l1_n447(x)
+ if (x < 1)
+ fun_l2_n936(x)
+ else
+ fun_l2_n50(x)
+ end
+end
+
+def fun_l1_n448(x)
+ if (x < 1)
+ fun_l2_n473(x)
+ else
+ fun_l2_n749(x)
+ end
+end
+
+def fun_l1_n449(x)
+ if (x < 1)
+ fun_l2_n218(x)
+ else
+ fun_l2_n266(x)
+ end
+end
+
+def fun_l1_n450(x)
+ if (x < 1)
+ fun_l2_n686(x)
+ else
+ fun_l2_n629(x)
+ end
+end
+
+def fun_l1_n451(x)
+ if (x < 1)
+ fun_l2_n648(x)
+ else
+ fun_l2_n322(x)
+ end
+end
+
+def fun_l1_n452(x)
+ if (x < 1)
+ fun_l2_n380(x)
+ else
+ fun_l2_n720(x)
+ end
+end
+
+def fun_l1_n453(x)
+ if (x < 1)
+ fun_l2_n53(x)
+ else
+ fun_l2_n830(x)
+ end
+end
+
+def fun_l1_n454(x)
+ if (x < 1)
+ fun_l2_n315(x)
+ else
+ fun_l2_n742(x)
+ end
+end
+
+def fun_l1_n455(x)
+ if (x < 1)
+ fun_l2_n902(x)
+ else
+ fun_l2_n111(x)
+ end
+end
+
+def fun_l1_n456(x)
+ if (x < 1)
+ fun_l2_n924(x)
+ else
+ fun_l2_n109(x)
+ end
+end
+
+def fun_l1_n457(x)
+ if (x < 1)
+ fun_l2_n249(x)
+ else
+ fun_l2_n865(x)
+ end
+end
+
+def fun_l1_n458(x)
+ if (x < 1)
+ fun_l2_n650(x)
+ else
+ fun_l2_n960(x)
+ end
+end
+
+def fun_l1_n459(x)
+ if (x < 1)
+ fun_l2_n273(x)
+ else
+ fun_l2_n544(x)
+ end
+end
+
+def fun_l1_n460(x)
+ if (x < 1)
+ fun_l2_n120(x)
+ else
+ fun_l2_n322(x)
+ end
+end
+
+def fun_l1_n461(x)
+ if (x < 1)
+ fun_l2_n366(x)
+ else
+ fun_l2_n534(x)
+ end
+end
+
+def fun_l1_n462(x)
+ if (x < 1)
+ fun_l2_n380(x)
+ else
+ fun_l2_n25(x)
+ end
+end
+
+def fun_l1_n463(x)
+ if (x < 1)
+ fun_l2_n333(x)
+ else
+ fun_l2_n303(x)
+ end
+end
+
+def fun_l1_n464(x)
+ if (x < 1)
+ fun_l2_n16(x)
+ else
+ fun_l2_n239(x)
+ end
+end
+
+def fun_l1_n465(x)
+ if (x < 1)
+ fun_l2_n539(x)
+ else
+ fun_l2_n988(x)
+ end
+end
+
+def fun_l1_n466(x)
+ if (x < 1)
+ fun_l2_n580(x)
+ else
+ fun_l2_n86(x)
+ end
+end
+
+def fun_l1_n467(x)
+ if (x < 1)
+ fun_l2_n406(x)
+ else
+ fun_l2_n706(x)
+ end
+end
+
+def fun_l1_n468(x)
+ if (x < 1)
+ fun_l2_n858(x)
+ else
+ fun_l2_n393(x)
+ end
+end
+
+def fun_l1_n469(x)
+ if (x < 1)
+ fun_l2_n64(x)
+ else
+ fun_l2_n482(x)
+ end
+end
+
+def fun_l1_n470(x)
+ if (x < 1)
+ fun_l2_n654(x)
+ else
+ fun_l2_n833(x)
+ end
+end
+
+def fun_l1_n471(x)
+ if (x < 1)
+ fun_l2_n161(x)
+ else
+ fun_l2_n91(x)
+ end
+end
+
+def fun_l1_n472(x)
+ if (x < 1)
+ fun_l2_n98(x)
+ else
+ fun_l2_n661(x)
+ end
+end
+
+def fun_l1_n473(x)
+ if (x < 1)
+ fun_l2_n574(x)
+ else
+ fun_l2_n133(x)
+ end
+end
+
+def fun_l1_n474(x)
+ if (x < 1)
+ fun_l2_n109(x)
+ else
+ fun_l2_n702(x)
+ end
+end
+
+def fun_l1_n475(x)
+ if (x < 1)
+ fun_l2_n808(x)
+ else
+ fun_l2_n584(x)
+ end
+end
+
+def fun_l1_n476(x)
+ if (x < 1)
+ fun_l2_n495(x)
+ else
+ fun_l2_n708(x)
+ end
+end
+
+def fun_l1_n477(x)
+ if (x < 1)
+ fun_l2_n649(x)
+ else
+ fun_l2_n290(x)
+ end
+end
+
+def fun_l1_n478(x)
+ if (x < 1)
+ fun_l2_n718(x)
+ else
+ fun_l2_n998(x)
+ end
+end
+
+def fun_l1_n479(x)
+ if (x < 1)
+ fun_l2_n557(x)
+ else
+ fun_l2_n359(x)
+ end
+end
+
+def fun_l1_n480(x)
+ if (x < 1)
+ fun_l2_n958(x)
+ else
+ fun_l2_n86(x)
+ end
+end
+
+def fun_l1_n481(x)
+ if (x < 1)
+ fun_l2_n245(x)
+ else
+ fun_l2_n124(x)
+ end
+end
+
+def fun_l1_n482(x)
+ if (x < 1)
+ fun_l2_n510(x)
+ else
+ fun_l2_n170(x)
+ end
+end
+
+def fun_l1_n483(x)
+ if (x < 1)
+ fun_l2_n550(x)
+ else
+ fun_l2_n9(x)
+ end
+end
+
+def fun_l1_n484(x)
+ if (x < 1)
+ fun_l2_n82(x)
+ else
+ fun_l2_n351(x)
+ end
+end
+
+def fun_l1_n485(x)
+ if (x < 1)
+ fun_l2_n760(x)
+ else
+ fun_l2_n560(x)
+ end
+end
+
+def fun_l1_n486(x)
+ if (x < 1)
+ fun_l2_n550(x)
+ else
+ fun_l2_n881(x)
+ end
+end
+
+def fun_l1_n487(x)
+ if (x < 1)
+ fun_l2_n62(x)
+ else
+ fun_l2_n213(x)
+ end
+end
+
+def fun_l1_n488(x)
+ if (x < 1)
+ fun_l2_n336(x)
+ else
+ fun_l2_n855(x)
+ end
+end
+
+def fun_l1_n489(x)
+ if (x < 1)
+ fun_l2_n172(x)
+ else
+ fun_l2_n479(x)
+ end
+end
+
+def fun_l1_n490(x)
+ if (x < 1)
+ fun_l2_n821(x)
+ else
+ fun_l2_n767(x)
+ end
+end
+
+def fun_l1_n491(x)
+ if (x < 1)
+ fun_l2_n388(x)
+ else
+ fun_l2_n307(x)
+ end
+end
+
+def fun_l1_n492(x)
+ if (x < 1)
+ fun_l2_n158(x)
+ else
+ fun_l2_n725(x)
+ end
+end
+
+def fun_l1_n493(x)
+ if (x < 1)
+ fun_l2_n681(x)
+ else
+ fun_l2_n767(x)
+ end
+end
+
+def fun_l1_n494(x)
+ if (x < 1)
+ fun_l2_n799(x)
+ else
+ fun_l2_n458(x)
+ end
+end
+
+def fun_l1_n495(x)
+ if (x < 1)
+ fun_l2_n379(x)
+ else
+ fun_l2_n152(x)
+ end
+end
+
+def fun_l1_n496(x)
+ if (x < 1)
+ fun_l2_n996(x)
+ else
+ fun_l2_n296(x)
+ end
+end
+
+def fun_l1_n497(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n481(x)
+ end
+end
+
+def fun_l1_n498(x)
+ if (x < 1)
+ fun_l2_n887(x)
+ else
+ fun_l2_n343(x)
+ end
+end
+
+def fun_l1_n499(x)
+ if (x < 1)
+ fun_l2_n481(x)
+ else
+ fun_l2_n368(x)
+ end
+end
+
+def fun_l1_n500(x)
+ if (x < 1)
+ fun_l2_n738(x)
+ else
+ fun_l2_n349(x)
+ end
+end
+
+def fun_l1_n501(x)
+ if (x < 1)
+ fun_l2_n104(x)
+ else
+ fun_l2_n841(x)
+ end
+end
+
+def fun_l1_n502(x)
+ if (x < 1)
+ fun_l2_n549(x)
+ else
+ fun_l2_n684(x)
+ end
+end
+
+def fun_l1_n503(x)
+ if (x < 1)
+ fun_l2_n726(x)
+ else
+ fun_l2_n41(x)
+ end
+end
+
+def fun_l1_n504(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n830(x)
+ end
+end
+
+def fun_l1_n505(x)
+ if (x < 1)
+ fun_l2_n38(x)
+ else
+ fun_l2_n815(x)
+ end
+end
+
+def fun_l1_n506(x)
+ if (x < 1)
+ fun_l2_n284(x)
+ else
+ fun_l2_n599(x)
+ end
+end
+
+def fun_l1_n507(x)
+ if (x < 1)
+ fun_l2_n665(x)
+ else
+ fun_l2_n763(x)
+ end
+end
+
+def fun_l1_n508(x)
+ if (x < 1)
+ fun_l2_n755(x)
+ else
+ fun_l2_n51(x)
+ end
+end
+
+def fun_l1_n509(x)
+ if (x < 1)
+ fun_l2_n860(x)
+ else
+ fun_l2_n273(x)
+ end
+end
+
+def fun_l1_n510(x)
+ if (x < 1)
+ fun_l2_n967(x)
+ else
+ fun_l2_n141(x)
+ end
+end
+
+def fun_l1_n511(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n953(x)
+ end
+end
+
+def fun_l1_n512(x)
+ if (x < 1)
+ fun_l2_n784(x)
+ else
+ fun_l2_n941(x)
+ end
+end
+
+def fun_l1_n513(x)
+ if (x < 1)
+ fun_l2_n499(x)
+ else
+ fun_l2_n189(x)
+ end
+end
+
+def fun_l1_n514(x)
+ if (x < 1)
+ fun_l2_n207(x)
+ else
+ fun_l2_n187(x)
+ end
+end
+
+def fun_l1_n515(x)
+ if (x < 1)
+ fun_l2_n174(x)
+ else
+ fun_l2_n316(x)
+ end
+end
+
+def fun_l1_n516(x)
+ if (x < 1)
+ fun_l2_n884(x)
+ else
+ fun_l2_n72(x)
+ end
+end
+
+def fun_l1_n517(x)
+ if (x < 1)
+ fun_l2_n878(x)
+ else
+ fun_l2_n423(x)
+ end
+end
+
+def fun_l1_n518(x)
+ if (x < 1)
+ fun_l2_n452(x)
+ else
+ fun_l2_n733(x)
+ end
+end
+
+def fun_l1_n519(x)
+ if (x < 1)
+ fun_l2_n586(x)
+ else
+ fun_l2_n987(x)
+ end
+end
+
+def fun_l1_n520(x)
+ if (x < 1)
+ fun_l2_n638(x)
+ else
+ fun_l2_n276(x)
+ end
+end
+
+def fun_l1_n521(x)
+ if (x < 1)
+ fun_l2_n186(x)
+ else
+ fun_l2_n498(x)
+ end
+end
+
+def fun_l1_n522(x)
+ if (x < 1)
+ fun_l2_n816(x)
+ else
+ fun_l2_n687(x)
+ end
+end
+
+def fun_l1_n523(x)
+ if (x < 1)
+ fun_l2_n572(x)
+ else
+ fun_l2_n878(x)
+ end
+end
+
+def fun_l1_n524(x)
+ if (x < 1)
+ fun_l2_n528(x)
+ else
+ fun_l2_n188(x)
+ end
+end
+
+def fun_l1_n525(x)
+ if (x < 1)
+ fun_l2_n719(x)
+ else
+ fun_l2_n146(x)
+ end
+end
+
+def fun_l1_n526(x)
+ if (x < 1)
+ fun_l2_n730(x)
+ else
+ fun_l2_n209(x)
+ end
+end
+
+def fun_l1_n527(x)
+ if (x < 1)
+ fun_l2_n998(x)
+ else
+ fun_l2_n544(x)
+ end
+end
+
+def fun_l1_n528(x)
+ if (x < 1)
+ fun_l2_n288(x)
+ else
+ fun_l2_n682(x)
+ end
+end
+
+def fun_l1_n529(x)
+ if (x < 1)
+ fun_l2_n808(x)
+ else
+ fun_l2_n651(x)
+ end
+end
+
+def fun_l1_n530(x)
+ if (x < 1)
+ fun_l2_n674(x)
+ else
+ fun_l2_n643(x)
+ end
+end
+
+def fun_l1_n531(x)
+ if (x < 1)
+ fun_l2_n42(x)
+ else
+ fun_l2_n457(x)
+ end
+end
+
+def fun_l1_n532(x)
+ if (x < 1)
+ fun_l2_n188(x)
+ else
+ fun_l2_n218(x)
+ end
+end
+
+def fun_l1_n533(x)
+ if (x < 1)
+ fun_l2_n529(x)
+ else
+ fun_l2_n541(x)
+ end
+end
+
+def fun_l1_n534(x)
+ if (x < 1)
+ fun_l2_n820(x)
+ else
+ fun_l2_n426(x)
+ end
+end
+
+def fun_l1_n535(x)
+ if (x < 1)
+ fun_l2_n730(x)
+ else
+ fun_l2_n36(x)
+ end
+end
+
+def fun_l1_n536(x)
+ if (x < 1)
+ fun_l2_n187(x)
+ else
+ fun_l2_n96(x)
+ end
+end
+
+def fun_l1_n537(x)
+ if (x < 1)
+ fun_l2_n1(x)
+ else
+ fun_l2_n905(x)
+ end
+end
+
+def fun_l1_n538(x)
+ if (x < 1)
+ fun_l2_n252(x)
+ else
+ fun_l2_n597(x)
+ end
+end
+
+def fun_l1_n539(x)
+ if (x < 1)
+ fun_l2_n959(x)
+ else
+ fun_l2_n26(x)
+ end
+end
+
+def fun_l1_n540(x)
+ if (x < 1)
+ fun_l2_n959(x)
+ else
+ fun_l2_n266(x)
+ end
+end
+
+def fun_l1_n541(x)
+ if (x < 1)
+ fun_l2_n902(x)
+ else
+ fun_l2_n957(x)
+ end
+end
+
+def fun_l1_n542(x)
+ if (x < 1)
+ fun_l2_n244(x)
+ else
+ fun_l2_n407(x)
+ end
+end
+
+def fun_l1_n543(x)
+ if (x < 1)
+ fun_l2_n319(x)
+ else
+ fun_l2_n19(x)
+ end
+end
+
+def fun_l1_n544(x)
+ if (x < 1)
+ fun_l2_n251(x)
+ else
+ fun_l2_n92(x)
+ end
+end
+
+def fun_l1_n545(x)
+ if (x < 1)
+ fun_l2_n482(x)
+ else
+ fun_l2_n177(x)
+ end
+end
+
+def fun_l1_n546(x)
+ if (x < 1)
+ fun_l2_n338(x)
+ else
+ fun_l2_n152(x)
+ end
+end
+
+def fun_l1_n547(x)
+ if (x < 1)
+ fun_l2_n902(x)
+ else
+ fun_l2_n243(x)
+ end
+end
+
+def fun_l1_n548(x)
+ if (x < 1)
+ fun_l2_n943(x)
+ else
+ fun_l2_n930(x)
+ end
+end
+
+def fun_l1_n549(x)
+ if (x < 1)
+ fun_l2_n775(x)
+ else
+ fun_l2_n338(x)
+ end
+end
+
+def fun_l1_n550(x)
+ if (x < 1)
+ fun_l2_n286(x)
+ else
+ fun_l2_n347(x)
+ end
+end
+
+def fun_l1_n551(x)
+ if (x < 1)
+ fun_l2_n611(x)
+ else
+ fun_l2_n108(x)
+ end
+end
+
+def fun_l1_n552(x)
+ if (x < 1)
+ fun_l2_n515(x)
+ else
+ fun_l2_n478(x)
+ end
+end
+
+def fun_l1_n553(x)
+ if (x < 1)
+ fun_l2_n68(x)
+ else
+ fun_l2_n943(x)
+ end
+end
+
+def fun_l1_n554(x)
+ if (x < 1)
+ fun_l2_n16(x)
+ else
+ fun_l2_n280(x)
+ end
+end
+
+def fun_l1_n555(x)
+ if (x < 1)
+ fun_l2_n421(x)
+ else
+ fun_l2_n412(x)
+ end
+end
+
+def fun_l1_n556(x)
+ if (x < 1)
+ fun_l2_n653(x)
+ else
+ fun_l2_n527(x)
+ end
+end
+
+def fun_l1_n557(x)
+ if (x < 1)
+ fun_l2_n181(x)
+ else
+ fun_l2_n179(x)
+ end
+end
+
+def fun_l1_n558(x)
+ if (x < 1)
+ fun_l2_n270(x)
+ else
+ fun_l2_n367(x)
+ end
+end
+
+def fun_l1_n559(x)
+ if (x < 1)
+ fun_l2_n323(x)
+ else
+ fun_l2_n453(x)
+ end
+end
+
+def fun_l1_n560(x)
+ if (x < 1)
+ fun_l2_n699(x)
+ else
+ fun_l2_n904(x)
+ end
+end
+
+def fun_l1_n561(x)
+ if (x < 1)
+ fun_l2_n903(x)
+ else
+ fun_l2_n559(x)
+ end
+end
+
+def fun_l1_n562(x)
+ if (x < 1)
+ fun_l2_n573(x)
+ else
+ fun_l2_n880(x)
+ end
+end
+
+def fun_l1_n563(x)
+ if (x < 1)
+ fun_l2_n674(x)
+ else
+ fun_l2_n420(x)
+ end
+end
+
+def fun_l1_n564(x)
+ if (x < 1)
+ fun_l2_n76(x)
+ else
+ fun_l2_n702(x)
+ end
+end
+
+def fun_l1_n565(x)
+ if (x < 1)
+ fun_l2_n78(x)
+ else
+ fun_l2_n741(x)
+ end
+end
+
+def fun_l1_n566(x)
+ if (x < 1)
+ fun_l2_n542(x)
+ else
+ fun_l2_n762(x)
+ end
+end
+
+def fun_l1_n567(x)
+ if (x < 1)
+ fun_l2_n992(x)
+ else
+ fun_l2_n416(x)
+ end
+end
+
+def fun_l1_n568(x)
+ if (x < 1)
+ fun_l2_n510(x)
+ else
+ fun_l2_n68(x)
+ end
+end
+
+def fun_l1_n569(x)
+ if (x < 1)
+ fun_l2_n36(x)
+ else
+ fun_l2_n152(x)
+ end
+end
+
+def fun_l1_n570(x)
+ if (x < 1)
+ fun_l2_n243(x)
+ else
+ fun_l2_n421(x)
+ end
+end
+
+def fun_l1_n571(x)
+ if (x < 1)
+ fun_l2_n48(x)
+ else
+ fun_l2_n50(x)
+ end
+end
+
+def fun_l1_n572(x)
+ if (x < 1)
+ fun_l2_n647(x)
+ else
+ fun_l2_n614(x)
+ end
+end
+
+def fun_l1_n573(x)
+ if (x < 1)
+ fun_l2_n847(x)
+ else
+ fun_l2_n598(x)
+ end
+end
+
+def fun_l1_n574(x)
+ if (x < 1)
+ fun_l2_n462(x)
+ else
+ fun_l2_n492(x)
+ end
+end
+
+def fun_l1_n575(x)
+ if (x < 1)
+ fun_l2_n805(x)
+ else
+ fun_l2_n23(x)
+ end
+end
+
+def fun_l1_n576(x)
+ if (x < 1)
+ fun_l2_n660(x)
+ else
+ fun_l2_n271(x)
+ end
+end
+
+def fun_l1_n577(x)
+ if (x < 1)
+ fun_l2_n277(x)
+ else
+ fun_l2_n259(x)
+ end
+end
+
+def fun_l1_n578(x)
+ if (x < 1)
+ fun_l2_n645(x)
+ else
+ fun_l2_n638(x)
+ end
+end
+
+def fun_l1_n579(x)
+ if (x < 1)
+ fun_l2_n925(x)
+ else
+ fun_l2_n801(x)
+ end
+end
+
+def fun_l1_n580(x)
+ if (x < 1)
+ fun_l2_n52(x)
+ else
+ fun_l2_n703(x)
+ end
+end
+
+def fun_l1_n581(x)
+ if (x < 1)
+ fun_l2_n126(x)
+ else
+ fun_l2_n511(x)
+ end
+end
+
+def fun_l1_n582(x)
+ if (x < 1)
+ fun_l2_n663(x)
+ else
+ fun_l2_n158(x)
+ end
+end
+
+def fun_l1_n583(x)
+ if (x < 1)
+ fun_l2_n604(x)
+ else
+ fun_l2_n498(x)
+ end
+end
+
+def fun_l1_n584(x)
+ if (x < 1)
+ fun_l2_n889(x)
+ else
+ fun_l2_n197(x)
+ end
+end
+
+def fun_l1_n585(x)
+ if (x < 1)
+ fun_l2_n28(x)
+ else
+ fun_l2_n298(x)
+ end
+end
+
+def fun_l1_n586(x)
+ if (x < 1)
+ fun_l2_n165(x)
+ else
+ fun_l2_n340(x)
+ end
+end
+
+def fun_l1_n587(x)
+ if (x < 1)
+ fun_l2_n89(x)
+ else
+ fun_l2_n947(x)
+ end
+end
+
+def fun_l1_n588(x)
+ if (x < 1)
+ fun_l2_n151(x)
+ else
+ fun_l2_n163(x)
+ end
+end
+
+def fun_l1_n589(x)
+ if (x < 1)
+ fun_l2_n200(x)
+ else
+ fun_l2_n855(x)
+ end
+end
+
+def fun_l1_n590(x)
+ if (x < 1)
+ fun_l2_n749(x)
+ else
+ fun_l2_n232(x)
+ end
+end
+
+def fun_l1_n591(x)
+ if (x < 1)
+ fun_l2_n850(x)
+ else
+ fun_l2_n897(x)
+ end
+end
+
+def fun_l1_n592(x)
+ if (x < 1)
+ fun_l2_n287(x)
+ else
+ fun_l2_n266(x)
+ end
+end
+
+def fun_l1_n593(x)
+ if (x < 1)
+ fun_l2_n547(x)
+ else
+ fun_l2_n937(x)
+ end
+end
+
+def fun_l1_n594(x)
+ if (x < 1)
+ fun_l2_n517(x)
+ else
+ fun_l2_n602(x)
+ end
+end
+
+def fun_l1_n595(x)
+ if (x < 1)
+ fun_l2_n962(x)
+ else
+ fun_l2_n387(x)
+ end
+end
+
+def fun_l1_n596(x)
+ if (x < 1)
+ fun_l2_n959(x)
+ else
+ fun_l2_n885(x)
+ end
+end
+
+def fun_l1_n597(x)
+ if (x < 1)
+ fun_l2_n343(x)
+ else
+ fun_l2_n704(x)
+ end
+end
+
+def fun_l1_n598(x)
+ if (x < 1)
+ fun_l2_n256(x)
+ else
+ fun_l2_n213(x)
+ end
+end
+
+def fun_l1_n599(x)
+ if (x < 1)
+ fun_l2_n653(x)
+ else
+ fun_l2_n630(x)
+ end
+end
+
+def fun_l1_n600(x)
+ if (x < 1)
+ fun_l2_n587(x)
+ else
+ fun_l2_n899(x)
+ end
+end
+
+def fun_l1_n601(x)
+ if (x < 1)
+ fun_l2_n798(x)
+ else
+ fun_l2_n318(x)
+ end
+end
+
+def fun_l1_n602(x)
+ if (x < 1)
+ fun_l2_n286(x)
+ else
+ fun_l2_n586(x)
+ end
+end
+
+def fun_l1_n603(x)
+ if (x < 1)
+ fun_l2_n931(x)
+ else
+ fun_l2_n370(x)
+ end
+end
+
+def fun_l1_n604(x)
+ if (x < 1)
+ fun_l2_n311(x)
+ else
+ fun_l2_n476(x)
+ end
+end
+
+def fun_l1_n605(x)
+ if (x < 1)
+ fun_l2_n998(x)
+ else
+ fun_l2_n953(x)
+ end
+end
+
+def fun_l1_n606(x)
+ if (x < 1)
+ fun_l2_n782(x)
+ else
+ fun_l2_n225(x)
+ end
+end
+
+def fun_l1_n607(x)
+ if (x < 1)
+ fun_l2_n696(x)
+ else
+ fun_l2_n797(x)
+ end
+end
+
+def fun_l1_n608(x)
+ if (x < 1)
+ fun_l2_n344(x)
+ else
+ fun_l2_n247(x)
+ end
+end
+
+def fun_l1_n609(x)
+ if (x < 1)
+ fun_l2_n627(x)
+ else
+ fun_l2_n410(x)
+ end
+end
+
+def fun_l1_n610(x)
+ if (x < 1)
+ fun_l2_n431(x)
+ else
+ fun_l2_n56(x)
+ end
+end
+
+def fun_l1_n611(x)
+ if (x < 1)
+ fun_l2_n307(x)
+ else
+ fun_l2_n857(x)
+ end
+end
+
+def fun_l1_n612(x)
+ if (x < 1)
+ fun_l2_n411(x)
+ else
+ fun_l2_n59(x)
+ end
+end
+
+def fun_l1_n613(x)
+ if (x < 1)
+ fun_l2_n38(x)
+ else
+ fun_l2_n880(x)
+ end
+end
+
+def fun_l1_n614(x)
+ if (x < 1)
+ fun_l2_n945(x)
+ else
+ fun_l2_n723(x)
+ end
+end
+
+def fun_l1_n615(x)
+ if (x < 1)
+ fun_l2_n248(x)
+ else
+ fun_l2_n56(x)
+ end
+end
+
+def fun_l1_n616(x)
+ if (x < 1)
+ fun_l2_n453(x)
+ else
+ fun_l2_n4(x)
+ end
+end
+
+def fun_l1_n617(x)
+ if (x < 1)
+ fun_l2_n599(x)
+ else
+ fun_l2_n966(x)
+ end
+end
+
+def fun_l1_n618(x)
+ if (x < 1)
+ fun_l2_n896(x)
+ else
+ fun_l2_n666(x)
+ end
+end
+
+def fun_l1_n619(x)
+ if (x < 1)
+ fun_l2_n715(x)
+ else
+ fun_l2_n918(x)
+ end
+end
+
+def fun_l1_n620(x)
+ if (x < 1)
+ fun_l2_n663(x)
+ else
+ fun_l2_n144(x)
+ end
+end
+
+def fun_l1_n621(x)
+ if (x < 1)
+ fun_l2_n17(x)
+ else
+ fun_l2_n411(x)
+ end
+end
+
+def fun_l1_n622(x)
+ if (x < 1)
+ fun_l2_n851(x)
+ else
+ fun_l2_n858(x)
+ end
+end
+
+def fun_l1_n623(x)
+ if (x < 1)
+ fun_l2_n552(x)
+ else
+ fun_l2_n503(x)
+ end
+end
+
+def fun_l1_n624(x)
+ if (x < 1)
+ fun_l2_n822(x)
+ else
+ fun_l2_n239(x)
+ end
+end
+
+def fun_l1_n625(x)
+ if (x < 1)
+ fun_l2_n917(x)
+ else
+ fun_l2_n120(x)
+ end
+end
+
+def fun_l1_n626(x)
+ if (x < 1)
+ fun_l2_n640(x)
+ else
+ fun_l2_n603(x)
+ end
+end
+
+def fun_l1_n627(x)
+ if (x < 1)
+ fun_l2_n244(x)
+ else
+ fun_l2_n114(x)
+ end
+end
+
+def fun_l1_n628(x)
+ if (x < 1)
+ fun_l2_n374(x)
+ else
+ fun_l2_n295(x)
+ end
+end
+
+def fun_l1_n629(x)
+ if (x < 1)
+ fun_l2_n761(x)
+ else
+ fun_l2_n920(x)
+ end
+end
+
+def fun_l1_n630(x)
+ if (x < 1)
+ fun_l2_n314(x)
+ else
+ fun_l2_n571(x)
+ end
+end
+
+def fun_l1_n631(x)
+ if (x < 1)
+ fun_l2_n830(x)
+ else
+ fun_l2_n838(x)
+ end
+end
+
+def fun_l1_n632(x)
+ if (x < 1)
+ fun_l2_n523(x)
+ else
+ fun_l2_n453(x)
+ end
+end
+
+def fun_l1_n633(x)
+ if (x < 1)
+ fun_l2_n245(x)
+ else
+ fun_l2_n173(x)
+ end
+end
+
+def fun_l1_n634(x)
+ if (x < 1)
+ fun_l2_n939(x)
+ else
+ fun_l2_n774(x)
+ end
+end
+
+def fun_l1_n635(x)
+ if (x < 1)
+ fun_l2_n17(x)
+ else
+ fun_l2_n166(x)
+ end
+end
+
+def fun_l1_n636(x)
+ if (x < 1)
+ fun_l2_n443(x)
+ else
+ fun_l2_n297(x)
+ end
+end
+
+def fun_l1_n637(x)
+ if (x < 1)
+ fun_l2_n280(x)
+ else
+ fun_l2_n776(x)
+ end
+end
+
+def fun_l1_n638(x)
+ if (x < 1)
+ fun_l2_n761(x)
+ else
+ fun_l2_n866(x)
+ end
+end
+
+def fun_l1_n639(x)
+ if (x < 1)
+ fun_l2_n677(x)
+ else
+ fun_l2_n855(x)
+ end
+end
+
+def fun_l1_n640(x)
+ if (x < 1)
+ fun_l2_n252(x)
+ else
+ fun_l2_n766(x)
+ end
+end
+
+def fun_l1_n641(x)
+ if (x < 1)
+ fun_l2_n3(x)
+ else
+ fun_l2_n115(x)
+ end
+end
+
+def fun_l1_n642(x)
+ if (x < 1)
+ fun_l2_n495(x)
+ else
+ fun_l2_n340(x)
+ end
+end
+
+def fun_l1_n643(x)
+ if (x < 1)
+ fun_l2_n991(x)
+ else
+ fun_l2_n119(x)
+ end
+end
+
+def fun_l1_n644(x)
+ if (x < 1)
+ fun_l2_n379(x)
+ else
+ fun_l2_n519(x)
+ end
+end
+
+def fun_l1_n645(x)
+ if (x < 1)
+ fun_l2_n191(x)
+ else
+ fun_l2_n872(x)
+ end
+end
+
+def fun_l1_n646(x)
+ if (x < 1)
+ fun_l2_n979(x)
+ else
+ fun_l2_n980(x)
+ end
+end
+
+def fun_l1_n647(x)
+ if (x < 1)
+ fun_l2_n918(x)
+ else
+ fun_l2_n455(x)
+ end
+end
+
+def fun_l1_n648(x)
+ if (x < 1)
+ fun_l2_n966(x)
+ else
+ fun_l2_n529(x)
+ end
+end
+
+def fun_l1_n649(x)
+ if (x < 1)
+ fun_l2_n838(x)
+ else
+ fun_l2_n529(x)
+ end
+end
+
+def fun_l1_n650(x)
+ if (x < 1)
+ fun_l2_n542(x)
+ else
+ fun_l2_n42(x)
+ end
+end
+
+def fun_l1_n651(x)
+ if (x < 1)
+ fun_l2_n65(x)
+ else
+ fun_l2_n460(x)
+ end
+end
+
+def fun_l1_n652(x)
+ if (x < 1)
+ fun_l2_n479(x)
+ else
+ fun_l2_n251(x)
+ end
+end
+
+def fun_l1_n653(x)
+ if (x < 1)
+ fun_l2_n243(x)
+ else
+ fun_l2_n77(x)
+ end
+end
+
+def fun_l1_n654(x)
+ if (x < 1)
+ fun_l2_n392(x)
+ else
+ fun_l2_n940(x)
+ end
+end
+
+def fun_l1_n655(x)
+ if (x < 1)
+ fun_l2_n875(x)
+ else
+ fun_l2_n157(x)
+ end
+end
+
+def fun_l1_n656(x)
+ if (x < 1)
+ fun_l2_n279(x)
+ else
+ fun_l2_n237(x)
+ end
+end
+
+def fun_l1_n657(x)
+ if (x < 1)
+ fun_l2_n522(x)
+ else
+ fun_l2_n174(x)
+ end
+end
+
+def fun_l1_n658(x)
+ if (x < 1)
+ fun_l2_n669(x)
+ else
+ fun_l2_n399(x)
+ end
+end
+
+def fun_l1_n659(x)
+ if (x < 1)
+ fun_l2_n251(x)
+ else
+ fun_l2_n56(x)
+ end
+end
+
+def fun_l1_n660(x)
+ if (x < 1)
+ fun_l2_n563(x)
+ else
+ fun_l2_n731(x)
+ end
+end
+
+def fun_l1_n661(x)
+ if (x < 1)
+ fun_l2_n684(x)
+ else
+ fun_l2_n292(x)
+ end
+end
+
+def fun_l1_n662(x)
+ if (x < 1)
+ fun_l2_n952(x)
+ else
+ fun_l2_n1(x)
+ end
+end
+
+def fun_l1_n663(x)
+ if (x < 1)
+ fun_l2_n89(x)
+ else
+ fun_l2_n562(x)
+ end
+end
+
+def fun_l1_n664(x)
+ if (x < 1)
+ fun_l2_n480(x)
+ else
+ fun_l2_n488(x)
+ end
+end
+
+def fun_l1_n665(x)
+ if (x < 1)
+ fun_l2_n398(x)
+ else
+ fun_l2_n493(x)
+ end
+end
+
+def fun_l1_n666(x)
+ if (x < 1)
+ fun_l2_n778(x)
+ else
+ fun_l2_n702(x)
+ end
+end
+
+def fun_l1_n667(x)
+ if (x < 1)
+ fun_l2_n332(x)
+ else
+ fun_l2_n441(x)
+ end
+end
+
+def fun_l1_n668(x)
+ if (x < 1)
+ fun_l2_n866(x)
+ else
+ fun_l2_n442(x)
+ end
+end
+
+def fun_l1_n669(x)
+ if (x < 1)
+ fun_l2_n533(x)
+ else
+ fun_l2_n970(x)
+ end
+end
+
+def fun_l1_n670(x)
+ if (x < 1)
+ fun_l2_n926(x)
+ else
+ fun_l2_n883(x)
+ end
+end
+
+def fun_l1_n671(x)
+ if (x < 1)
+ fun_l2_n204(x)
+ else
+ fun_l2_n769(x)
+ end
+end
+
+def fun_l1_n672(x)
+ if (x < 1)
+ fun_l2_n663(x)
+ else
+ fun_l2_n367(x)
+ end
+end
+
+def fun_l1_n673(x)
+ if (x < 1)
+ fun_l2_n978(x)
+ else
+ fun_l2_n750(x)
+ end
+end
+
+def fun_l1_n674(x)
+ if (x < 1)
+ fun_l2_n296(x)
+ else
+ fun_l2_n608(x)
+ end
+end
+
+def fun_l1_n675(x)
+ if (x < 1)
+ fun_l2_n35(x)
+ else
+ fun_l2_n200(x)
+ end
+end
+
+def fun_l1_n676(x)
+ if (x < 1)
+ fun_l2_n618(x)
+ else
+ fun_l2_n286(x)
+ end
+end
+
+def fun_l1_n677(x)
+ if (x < 1)
+ fun_l2_n98(x)
+ else
+ fun_l2_n264(x)
+ end
+end
+
+def fun_l1_n678(x)
+ if (x < 1)
+ fun_l2_n967(x)
+ else
+ fun_l2_n884(x)
+ end
+end
+
+def fun_l1_n679(x)
+ if (x < 1)
+ fun_l2_n351(x)
+ else
+ fun_l2_n854(x)
+ end
+end
+
+def fun_l1_n680(x)
+ if (x < 1)
+ fun_l2_n397(x)
+ else
+ fun_l2_n56(x)
+ end
+end
+
+def fun_l1_n681(x)
+ if (x < 1)
+ fun_l2_n232(x)
+ else
+ fun_l2_n400(x)
+ end
+end
+
+def fun_l1_n682(x)
+ if (x < 1)
+ fun_l2_n321(x)
+ else
+ fun_l2_n500(x)
+ end
+end
+
+def fun_l1_n683(x)
+ if (x < 1)
+ fun_l2_n315(x)
+ else
+ fun_l2_n509(x)
+ end
+end
+
+def fun_l1_n684(x)
+ if (x < 1)
+ fun_l2_n854(x)
+ else
+ fun_l2_n921(x)
+ end
+end
+
+def fun_l1_n685(x)
+ if (x < 1)
+ fun_l2_n823(x)
+ else
+ fun_l2_n995(x)
+ end
+end
+
+def fun_l1_n686(x)
+ if (x < 1)
+ fun_l2_n42(x)
+ else
+ fun_l2_n92(x)
+ end
+end
+
+def fun_l1_n687(x)
+ if (x < 1)
+ fun_l2_n74(x)
+ else
+ fun_l2_n577(x)
+ end
+end
+
+def fun_l1_n688(x)
+ if (x < 1)
+ fun_l2_n47(x)
+ else
+ fun_l2_n664(x)
+ end
+end
+
+def fun_l1_n689(x)
+ if (x < 1)
+ fun_l2_n709(x)
+ else
+ fun_l2_n92(x)
+ end
+end
+
+def fun_l1_n690(x)
+ if (x < 1)
+ fun_l2_n875(x)
+ else
+ fun_l2_n893(x)
+ end
+end
+
+def fun_l1_n691(x)
+ if (x < 1)
+ fun_l2_n934(x)
+ else
+ fun_l2_n339(x)
+ end
+end
+
+def fun_l1_n692(x)
+ if (x < 1)
+ fun_l2_n194(x)
+ else
+ fun_l2_n915(x)
+ end
+end
+
+def fun_l1_n693(x)
+ if (x < 1)
+ fun_l2_n352(x)
+ else
+ fun_l2_n212(x)
+ end
+end
+
+def fun_l1_n694(x)
+ if (x < 1)
+ fun_l2_n554(x)
+ else
+ fun_l2_n461(x)
+ end
+end
+
+def fun_l1_n695(x)
+ if (x < 1)
+ fun_l2_n372(x)
+ else
+ fun_l2_n652(x)
+ end
+end
+
+def fun_l1_n696(x)
+ if (x < 1)
+ fun_l2_n778(x)
+ else
+ fun_l2_n350(x)
+ end
+end
+
+def fun_l1_n697(x)
+ if (x < 1)
+ fun_l2_n656(x)
+ else
+ fun_l2_n467(x)
+ end
+end
+
+def fun_l1_n698(x)
+ if (x < 1)
+ fun_l2_n799(x)
+ else
+ fun_l2_n983(x)
+ end
+end
+
+def fun_l1_n699(x)
+ if (x < 1)
+ fun_l2_n917(x)
+ else
+ fun_l2_n801(x)
+ end
+end
+
+def fun_l1_n700(x)
+ if (x < 1)
+ fun_l2_n276(x)
+ else
+ fun_l2_n778(x)
+ end
+end
+
+def fun_l1_n701(x)
+ if (x < 1)
+ fun_l2_n562(x)
+ else
+ fun_l2_n558(x)
+ end
+end
+
+def fun_l1_n702(x)
+ if (x < 1)
+ fun_l2_n600(x)
+ else
+ fun_l2_n120(x)
+ end
+end
+
+def fun_l1_n703(x)
+ if (x < 1)
+ fun_l2_n346(x)
+ else
+ fun_l2_n975(x)
+ end
+end
+
+def fun_l1_n704(x)
+ if (x < 1)
+ fun_l2_n139(x)
+ else
+ fun_l2_n241(x)
+ end
+end
+
+def fun_l1_n705(x)
+ if (x < 1)
+ fun_l2_n728(x)
+ else
+ fun_l2_n62(x)
+ end
+end
+
+def fun_l1_n706(x)
+ if (x < 1)
+ fun_l2_n719(x)
+ else
+ fun_l2_n955(x)
+ end
+end
+
+def fun_l1_n707(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n122(x)
+ end
+end
+
+def fun_l1_n708(x)
+ if (x < 1)
+ fun_l2_n456(x)
+ else
+ fun_l2_n128(x)
+ end
+end
+
+def fun_l1_n709(x)
+ if (x < 1)
+ fun_l2_n4(x)
+ else
+ fun_l2_n399(x)
+ end
+end
+
+def fun_l1_n710(x)
+ if (x < 1)
+ fun_l2_n20(x)
+ else
+ fun_l2_n746(x)
+ end
+end
+
+def fun_l1_n711(x)
+ if (x < 1)
+ fun_l2_n978(x)
+ else
+ fun_l2_n886(x)
+ end
+end
+
+def fun_l1_n712(x)
+ if (x < 1)
+ fun_l2_n417(x)
+ else
+ fun_l2_n337(x)
+ end
+end
+
+def fun_l1_n713(x)
+ if (x < 1)
+ fun_l2_n394(x)
+ else
+ fun_l2_n713(x)
+ end
+end
+
+def fun_l1_n714(x)
+ if (x < 1)
+ fun_l2_n433(x)
+ else
+ fun_l2_n985(x)
+ end
+end
+
+def fun_l1_n715(x)
+ if (x < 1)
+ fun_l2_n937(x)
+ else
+ fun_l2_n709(x)
+ end
+end
+
+def fun_l1_n716(x)
+ if (x < 1)
+ fun_l2_n963(x)
+ else
+ fun_l2_n842(x)
+ end
+end
+
+def fun_l1_n717(x)
+ if (x < 1)
+ fun_l2_n671(x)
+ else
+ fun_l2_n954(x)
+ end
+end
+
+def fun_l1_n718(x)
+ if (x < 1)
+ fun_l2_n948(x)
+ else
+ fun_l2_n128(x)
+ end
+end
+
+def fun_l1_n719(x)
+ if (x < 1)
+ fun_l2_n682(x)
+ else
+ fun_l2_n973(x)
+ end
+end
+
+def fun_l1_n720(x)
+ if (x < 1)
+ fun_l2_n336(x)
+ else
+ fun_l2_n643(x)
+ end
+end
+
+def fun_l1_n721(x)
+ if (x < 1)
+ fun_l2_n224(x)
+ else
+ fun_l2_n96(x)
+ end
+end
+
+def fun_l1_n722(x)
+ if (x < 1)
+ fun_l2_n907(x)
+ else
+ fun_l2_n776(x)
+ end
+end
+
+def fun_l1_n723(x)
+ if (x < 1)
+ fun_l2_n93(x)
+ else
+ fun_l2_n410(x)
+ end
+end
+
+def fun_l1_n724(x)
+ if (x < 1)
+ fun_l2_n282(x)
+ else
+ fun_l2_n134(x)
+ end
+end
+
+def fun_l1_n725(x)
+ if (x < 1)
+ fun_l2_n938(x)
+ else
+ fun_l2_n603(x)
+ end
+end
+
+def fun_l1_n726(x)
+ if (x < 1)
+ fun_l2_n574(x)
+ else
+ fun_l2_n976(x)
+ end
+end
+
+def fun_l1_n727(x)
+ if (x < 1)
+ fun_l2_n428(x)
+ else
+ fun_l2_n658(x)
+ end
+end
+
+def fun_l1_n728(x)
+ if (x < 1)
+ fun_l2_n828(x)
+ else
+ fun_l2_n226(x)
+ end
+end
+
+def fun_l1_n729(x)
+ if (x < 1)
+ fun_l2_n663(x)
+ else
+ fun_l2_n292(x)
+ end
+end
+
+def fun_l1_n730(x)
+ if (x < 1)
+ fun_l2_n802(x)
+ else
+ fun_l2_n853(x)
+ end
+end
+
+def fun_l1_n731(x)
+ if (x < 1)
+ fun_l2_n142(x)
+ else
+ fun_l2_n339(x)
+ end
+end
+
+def fun_l1_n732(x)
+ if (x < 1)
+ fun_l2_n211(x)
+ else
+ fun_l2_n35(x)
+ end
+end
+
+def fun_l1_n733(x)
+ if (x < 1)
+ fun_l2_n660(x)
+ else
+ fun_l2_n179(x)
+ end
+end
+
+def fun_l1_n734(x)
+ if (x < 1)
+ fun_l2_n174(x)
+ else
+ fun_l2_n224(x)
+ end
+end
+
+def fun_l1_n735(x)
+ if (x < 1)
+ fun_l2_n490(x)
+ else
+ fun_l2_n564(x)
+ end
+end
+
+def fun_l1_n736(x)
+ if (x < 1)
+ fun_l2_n597(x)
+ else
+ fun_l2_n153(x)
+ end
+end
+
+def fun_l1_n737(x)
+ if (x < 1)
+ fun_l2_n633(x)
+ else
+ fun_l2_n358(x)
+ end
+end
+
+def fun_l1_n738(x)
+ if (x < 1)
+ fun_l2_n0(x)
+ else
+ fun_l2_n858(x)
+ end
+end
+
+def fun_l1_n739(x)
+ if (x < 1)
+ fun_l2_n335(x)
+ else
+ fun_l2_n531(x)
+ end
+end
+
+def fun_l1_n740(x)
+ if (x < 1)
+ fun_l2_n736(x)
+ else
+ fun_l2_n653(x)
+ end
+end
+
+def fun_l1_n741(x)
+ if (x < 1)
+ fun_l2_n280(x)
+ else
+ fun_l2_n684(x)
+ end
+end
+
+def fun_l1_n742(x)
+ if (x < 1)
+ fun_l2_n976(x)
+ else
+ fun_l2_n987(x)
+ end
+end
+
+def fun_l1_n743(x)
+ if (x < 1)
+ fun_l2_n519(x)
+ else
+ fun_l2_n633(x)
+ end
+end
+
+def fun_l1_n744(x)
+ if (x < 1)
+ fun_l2_n314(x)
+ else
+ fun_l2_n579(x)
+ end
+end
+
+def fun_l1_n745(x)
+ if (x < 1)
+ fun_l2_n365(x)
+ else
+ fun_l2_n972(x)
+ end
+end
+
+def fun_l1_n746(x)
+ if (x < 1)
+ fun_l2_n902(x)
+ else
+ fun_l2_n715(x)
+ end
+end
+
+def fun_l1_n747(x)
+ if (x < 1)
+ fun_l2_n363(x)
+ else
+ fun_l2_n407(x)
+ end
+end
+
+def fun_l1_n748(x)
+ if (x < 1)
+ fun_l2_n660(x)
+ else
+ fun_l2_n814(x)
+ end
+end
+
+def fun_l1_n749(x)
+ if (x < 1)
+ fun_l2_n415(x)
+ else
+ fun_l2_n162(x)
+ end
+end
+
+def fun_l1_n750(x)
+ if (x < 1)
+ fun_l2_n157(x)
+ else
+ fun_l2_n406(x)
+ end
+end
+
+def fun_l1_n751(x)
+ if (x < 1)
+ fun_l2_n388(x)
+ else
+ fun_l2_n212(x)
+ end
+end
+
+def fun_l1_n752(x)
+ if (x < 1)
+ fun_l2_n733(x)
+ else
+ fun_l2_n283(x)
+ end
+end
+
+def fun_l1_n753(x)
+ if (x < 1)
+ fun_l2_n960(x)
+ else
+ fun_l2_n20(x)
+ end
+end
+
+def fun_l1_n754(x)
+ if (x < 1)
+ fun_l2_n797(x)
+ else
+ fun_l2_n202(x)
+ end
+end
+
+def fun_l1_n755(x)
+ if (x < 1)
+ fun_l2_n113(x)
+ else
+ fun_l2_n953(x)
+ end
+end
+
+def fun_l1_n756(x)
+ if (x < 1)
+ fun_l2_n84(x)
+ else
+ fun_l2_n390(x)
+ end
+end
+
+def fun_l1_n757(x)
+ if (x < 1)
+ fun_l2_n355(x)
+ else
+ fun_l2_n761(x)
+ end
+end
+
+def fun_l1_n758(x)
+ if (x < 1)
+ fun_l2_n823(x)
+ else
+ fun_l2_n37(x)
+ end
+end
+
+def fun_l1_n759(x)
+ if (x < 1)
+ fun_l2_n428(x)
+ else
+ fun_l2_n130(x)
+ end
+end
+
+def fun_l1_n760(x)
+ if (x < 1)
+ fun_l2_n364(x)
+ else
+ fun_l2_n680(x)
+ end
+end
+
+def fun_l1_n761(x)
+ if (x < 1)
+ fun_l2_n718(x)
+ else
+ fun_l2_n885(x)
+ end
+end
+
+def fun_l1_n762(x)
+ if (x < 1)
+ fun_l2_n795(x)
+ else
+ fun_l2_n342(x)
+ end
+end
+
+def fun_l1_n763(x)
+ if (x < 1)
+ fun_l2_n561(x)
+ else
+ fun_l2_n593(x)
+ end
+end
+
+def fun_l1_n764(x)
+ if (x < 1)
+ fun_l2_n714(x)
+ else
+ fun_l2_n168(x)
+ end
+end
+
+def fun_l1_n765(x)
+ if (x < 1)
+ fun_l2_n377(x)
+ else
+ fun_l2_n109(x)
+ end
+end
+
+def fun_l1_n766(x)
+ if (x < 1)
+ fun_l2_n477(x)
+ else
+ fun_l2_n871(x)
+ end
+end
+
+def fun_l1_n767(x)
+ if (x < 1)
+ fun_l2_n596(x)
+ else
+ fun_l2_n81(x)
+ end
+end
+
+def fun_l1_n768(x)
+ if (x < 1)
+ fun_l2_n609(x)
+ else
+ fun_l2_n454(x)
+ end
+end
+
+def fun_l1_n769(x)
+ if (x < 1)
+ fun_l2_n308(x)
+ else
+ fun_l2_n890(x)
+ end
+end
+
+def fun_l1_n770(x)
+ if (x < 1)
+ fun_l2_n761(x)
+ else
+ fun_l2_n342(x)
+ end
+end
+
+def fun_l1_n771(x)
+ if (x < 1)
+ fun_l2_n44(x)
+ else
+ fun_l2_n1(x)
+ end
+end
+
+def fun_l1_n772(x)
+ if (x < 1)
+ fun_l2_n457(x)
+ else
+ fun_l2_n571(x)
+ end
+end
+
+def fun_l1_n773(x)
+ if (x < 1)
+ fun_l2_n88(x)
+ else
+ fun_l2_n622(x)
+ end
+end
+
+def fun_l1_n774(x)
+ if (x < 1)
+ fun_l2_n459(x)
+ else
+ fun_l2_n446(x)
+ end
+end
+
+def fun_l1_n775(x)
+ if (x < 1)
+ fun_l2_n400(x)
+ else
+ fun_l2_n918(x)
+ end
+end
+
+def fun_l1_n776(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n696(x)
+ end
+end
+
+def fun_l1_n777(x)
+ if (x < 1)
+ fun_l2_n968(x)
+ else
+ fun_l2_n988(x)
+ end
+end
+
+def fun_l1_n778(x)
+ if (x < 1)
+ fun_l2_n242(x)
+ else
+ fun_l2_n496(x)
+ end
+end
+
+def fun_l1_n779(x)
+ if (x < 1)
+ fun_l2_n106(x)
+ else
+ fun_l2_n637(x)
+ end
+end
+
+def fun_l1_n780(x)
+ if (x < 1)
+ fun_l2_n945(x)
+ else
+ fun_l2_n238(x)
+ end
+end
+
+def fun_l1_n781(x)
+ if (x < 1)
+ fun_l2_n269(x)
+ else
+ fun_l2_n582(x)
+ end
+end
+
+def fun_l1_n782(x)
+ if (x < 1)
+ fun_l2_n523(x)
+ else
+ fun_l2_n201(x)
+ end
+end
+
+def fun_l1_n783(x)
+ if (x < 1)
+ fun_l2_n326(x)
+ else
+ fun_l2_n744(x)
+ end
+end
+
+def fun_l1_n784(x)
+ if (x < 1)
+ fun_l2_n49(x)
+ else
+ fun_l2_n943(x)
+ end
+end
+
+def fun_l1_n785(x)
+ if (x < 1)
+ fun_l2_n975(x)
+ else
+ fun_l2_n560(x)
+ end
+end
+
+def fun_l1_n786(x)
+ if (x < 1)
+ fun_l2_n843(x)
+ else
+ fun_l2_n240(x)
+ end
+end
+
+def fun_l1_n787(x)
+ if (x < 1)
+ fun_l2_n179(x)
+ else
+ fun_l2_n423(x)
+ end
+end
+
+def fun_l1_n788(x)
+ if (x < 1)
+ fun_l2_n536(x)
+ else
+ fun_l2_n112(x)
+ end
+end
+
+def fun_l1_n789(x)
+ if (x < 1)
+ fun_l2_n418(x)
+ else
+ fun_l2_n443(x)
+ end
+end
+
+def fun_l1_n790(x)
+ if (x < 1)
+ fun_l2_n770(x)
+ else
+ fun_l2_n127(x)
+ end
+end
+
+def fun_l1_n791(x)
+ if (x < 1)
+ fun_l2_n425(x)
+ else
+ fun_l2_n364(x)
+ end
+end
+
+def fun_l1_n792(x)
+ if (x < 1)
+ fun_l2_n841(x)
+ else
+ fun_l2_n112(x)
+ end
+end
+
+def fun_l1_n793(x)
+ if (x < 1)
+ fun_l2_n64(x)
+ else
+ fun_l2_n294(x)
+ end
+end
+
+def fun_l1_n794(x)
+ if (x < 1)
+ fun_l2_n837(x)
+ else
+ fun_l2_n325(x)
+ end
+end
+
+def fun_l1_n795(x)
+ if (x < 1)
+ fun_l2_n522(x)
+ else
+ fun_l2_n307(x)
+ end
+end
+
+def fun_l1_n796(x)
+ if (x < 1)
+ fun_l2_n526(x)
+ else
+ fun_l2_n957(x)
+ end
+end
+
+def fun_l1_n797(x)
+ if (x < 1)
+ fun_l2_n71(x)
+ else
+ fun_l2_n871(x)
+ end
+end
+
+def fun_l1_n798(x)
+ if (x < 1)
+ fun_l2_n386(x)
+ else
+ fun_l2_n354(x)
+ end
+end
+
+def fun_l1_n799(x)
+ if (x < 1)
+ fun_l2_n669(x)
+ else
+ fun_l2_n237(x)
+ end
+end
+
+def fun_l1_n800(x)
+ if (x < 1)
+ fun_l2_n455(x)
+ else
+ fun_l2_n549(x)
+ end
+end
+
+def fun_l1_n801(x)
+ if (x < 1)
+ fun_l2_n708(x)
+ else
+ fun_l2_n611(x)
+ end
+end
+
+def fun_l1_n802(x)
+ if (x < 1)
+ fun_l2_n35(x)
+ else
+ fun_l2_n239(x)
+ end
+end
+
+def fun_l1_n803(x)
+ if (x < 1)
+ fun_l2_n890(x)
+ else
+ fun_l2_n27(x)
+ end
+end
+
+def fun_l1_n804(x)
+ if (x < 1)
+ fun_l2_n378(x)
+ else
+ fun_l2_n567(x)
+ end
+end
+
+def fun_l1_n805(x)
+ if (x < 1)
+ fun_l2_n672(x)
+ else
+ fun_l2_n320(x)
+ end
+end
+
+def fun_l1_n806(x)
+ if (x < 1)
+ fun_l2_n207(x)
+ else
+ fun_l2_n691(x)
+ end
+end
+
+def fun_l1_n807(x)
+ if (x < 1)
+ fun_l2_n180(x)
+ else
+ fun_l2_n912(x)
+ end
+end
+
+def fun_l1_n808(x)
+ if (x < 1)
+ fun_l2_n370(x)
+ else
+ fun_l2_n529(x)
+ end
+end
+
+def fun_l1_n809(x)
+ if (x < 1)
+ fun_l2_n436(x)
+ else
+ fun_l2_n465(x)
+ end
+end
+
+def fun_l1_n810(x)
+ if (x < 1)
+ fun_l2_n820(x)
+ else
+ fun_l2_n995(x)
+ end
+end
+
+def fun_l1_n811(x)
+ if (x < 1)
+ fun_l2_n821(x)
+ else
+ fun_l2_n898(x)
+ end
+end
+
+def fun_l1_n812(x)
+ if (x < 1)
+ fun_l2_n376(x)
+ else
+ fun_l2_n999(x)
+ end
+end
+
+def fun_l1_n813(x)
+ if (x < 1)
+ fun_l2_n643(x)
+ else
+ fun_l2_n478(x)
+ end
+end
+
+def fun_l1_n814(x)
+ if (x < 1)
+ fun_l2_n475(x)
+ else
+ fun_l2_n137(x)
+ end
+end
+
+def fun_l1_n815(x)
+ if (x < 1)
+ fun_l2_n117(x)
+ else
+ fun_l2_n685(x)
+ end
+end
+
+def fun_l1_n816(x)
+ if (x < 1)
+ fun_l2_n451(x)
+ else
+ fun_l2_n643(x)
+ end
+end
+
+def fun_l1_n817(x)
+ if (x < 1)
+ fun_l2_n22(x)
+ else
+ fun_l2_n939(x)
+ end
+end
+
+def fun_l1_n818(x)
+ if (x < 1)
+ fun_l2_n586(x)
+ else
+ fun_l2_n206(x)
+ end
+end
+
+def fun_l1_n819(x)
+ if (x < 1)
+ fun_l2_n443(x)
+ else
+ fun_l2_n661(x)
+ end
+end
+
+def fun_l1_n820(x)
+ if (x < 1)
+ fun_l2_n656(x)
+ else
+ fun_l2_n93(x)
+ end
+end
+
+def fun_l1_n821(x)
+ if (x < 1)
+ fun_l2_n794(x)
+ else
+ fun_l2_n354(x)
+ end
+end
+
+def fun_l1_n822(x)
+ if (x < 1)
+ fun_l2_n519(x)
+ else
+ fun_l2_n446(x)
+ end
+end
+
+def fun_l1_n823(x)
+ if (x < 1)
+ fun_l2_n0(x)
+ else
+ fun_l2_n233(x)
+ end
+end
+
+def fun_l1_n824(x)
+ if (x < 1)
+ fun_l2_n376(x)
+ else
+ fun_l2_n186(x)
+ end
+end
+
+def fun_l1_n825(x)
+ if (x < 1)
+ fun_l2_n292(x)
+ else
+ fun_l2_n303(x)
+ end
+end
+
+def fun_l1_n826(x)
+ if (x < 1)
+ fun_l2_n871(x)
+ else
+ fun_l2_n515(x)
+ end
+end
+
+def fun_l1_n827(x)
+ if (x < 1)
+ fun_l2_n227(x)
+ else
+ fun_l2_n232(x)
+ end
+end
+
+def fun_l1_n828(x)
+ if (x < 1)
+ fun_l2_n860(x)
+ else
+ fun_l2_n341(x)
+ end
+end
+
+def fun_l1_n829(x)
+ if (x < 1)
+ fun_l2_n140(x)
+ else
+ fun_l2_n304(x)
+ end
+end
+
+def fun_l1_n830(x)
+ if (x < 1)
+ fun_l2_n796(x)
+ else
+ fun_l2_n943(x)
+ end
+end
+
+def fun_l1_n831(x)
+ if (x < 1)
+ fun_l2_n71(x)
+ else
+ fun_l2_n8(x)
+ end
+end
+
+def fun_l1_n832(x)
+ if (x < 1)
+ fun_l2_n328(x)
+ else
+ fun_l2_n836(x)
+ end
+end
+
+def fun_l1_n833(x)
+ if (x < 1)
+ fun_l2_n322(x)
+ else
+ fun_l2_n653(x)
+ end
+end
+
+def fun_l1_n834(x)
+ if (x < 1)
+ fun_l2_n471(x)
+ else
+ fun_l2_n147(x)
+ end
+end
+
+def fun_l1_n835(x)
+ if (x < 1)
+ fun_l2_n601(x)
+ else
+ fun_l2_n249(x)
+ end
+end
+
+def fun_l1_n836(x)
+ if (x < 1)
+ fun_l2_n105(x)
+ else
+ fun_l2_n63(x)
+ end
+end
+
+def fun_l1_n837(x)
+ if (x < 1)
+ fun_l2_n773(x)
+ else
+ fun_l2_n597(x)
+ end
+end
+
+def fun_l1_n838(x)
+ if (x < 1)
+ fun_l2_n933(x)
+ else
+ fun_l2_n964(x)
+ end
+end
+
+def fun_l1_n839(x)
+ if (x < 1)
+ fun_l2_n123(x)
+ else
+ fun_l2_n533(x)
+ end
+end
+
+def fun_l1_n840(x)
+ if (x < 1)
+ fun_l2_n94(x)
+ else
+ fun_l2_n127(x)
+ end
+end
+
+def fun_l1_n841(x)
+ if (x < 1)
+ fun_l2_n981(x)
+ else
+ fun_l2_n819(x)
+ end
+end
+
+def fun_l1_n842(x)
+ if (x < 1)
+ fun_l2_n743(x)
+ else
+ fun_l2_n747(x)
+ end
+end
+
+def fun_l1_n843(x)
+ if (x < 1)
+ fun_l2_n735(x)
+ else
+ fun_l2_n110(x)
+ end
+end
+
+def fun_l1_n844(x)
+ if (x < 1)
+ fun_l2_n273(x)
+ else
+ fun_l2_n753(x)
+ end
+end
+
+def fun_l1_n845(x)
+ if (x < 1)
+ fun_l2_n316(x)
+ else
+ fun_l2_n391(x)
+ end
+end
+
+def fun_l1_n846(x)
+ if (x < 1)
+ fun_l2_n221(x)
+ else
+ fun_l2_n251(x)
+ end
+end
+
+def fun_l1_n847(x)
+ if (x < 1)
+ fun_l2_n795(x)
+ else
+ fun_l2_n513(x)
+ end
+end
+
+def fun_l1_n848(x)
+ if (x < 1)
+ fun_l2_n986(x)
+ else
+ fun_l2_n472(x)
+ end
+end
+
+def fun_l1_n849(x)
+ if (x < 1)
+ fun_l2_n863(x)
+ else
+ fun_l2_n759(x)
+ end
+end
+
+def fun_l1_n850(x)
+ if (x < 1)
+ fun_l2_n512(x)
+ else
+ fun_l2_n502(x)
+ end
+end
+
+def fun_l1_n851(x)
+ if (x < 1)
+ fun_l2_n561(x)
+ else
+ fun_l2_n697(x)
+ end
+end
+
+def fun_l1_n852(x)
+ if (x < 1)
+ fun_l2_n816(x)
+ else
+ fun_l2_n90(x)
+ end
+end
+
+def fun_l1_n853(x)
+ if (x < 1)
+ fun_l2_n656(x)
+ else
+ fun_l2_n174(x)
+ end
+end
+
+def fun_l1_n854(x)
+ if (x < 1)
+ fun_l2_n439(x)
+ else
+ fun_l2_n90(x)
+ end
+end
+
+def fun_l1_n855(x)
+ if (x < 1)
+ fun_l2_n15(x)
+ else
+ fun_l2_n402(x)
+ end
+end
+
+def fun_l1_n856(x)
+ if (x < 1)
+ fun_l2_n224(x)
+ else
+ fun_l2_n177(x)
+ end
+end
+
+def fun_l1_n857(x)
+ if (x < 1)
+ fun_l2_n675(x)
+ else
+ fun_l2_n113(x)
+ end
+end
+
+def fun_l1_n858(x)
+ if (x < 1)
+ fun_l2_n388(x)
+ else
+ fun_l2_n529(x)
+ end
+end
+
+def fun_l1_n859(x)
+ if (x < 1)
+ fun_l2_n628(x)
+ else
+ fun_l2_n93(x)
+ end
+end
+
+def fun_l1_n860(x)
+ if (x < 1)
+ fun_l2_n67(x)
+ else
+ fun_l2_n90(x)
+ end
+end
+
+def fun_l1_n861(x)
+ if (x < 1)
+ fun_l2_n637(x)
+ else
+ fun_l2_n68(x)
+ end
+end
+
+def fun_l1_n862(x)
+ if (x < 1)
+ fun_l2_n767(x)
+ else
+ fun_l2_n86(x)
+ end
+end
+
+def fun_l1_n863(x)
+ if (x < 1)
+ fun_l2_n50(x)
+ else
+ fun_l2_n777(x)
+ end
+end
+
+def fun_l1_n864(x)
+ if (x < 1)
+ fun_l2_n846(x)
+ else
+ fun_l2_n783(x)
+ end
+end
+
+def fun_l1_n865(x)
+ if (x < 1)
+ fun_l2_n756(x)
+ else
+ fun_l2_n703(x)
+ end
+end
+
+def fun_l1_n866(x)
+ if (x < 1)
+ fun_l2_n972(x)
+ else
+ fun_l2_n249(x)
+ end
+end
+
+def fun_l1_n867(x)
+ if (x < 1)
+ fun_l2_n636(x)
+ else
+ fun_l2_n841(x)
+ end
+end
+
+def fun_l1_n868(x)
+ if (x < 1)
+ fun_l2_n889(x)
+ else
+ fun_l2_n899(x)
+ end
+end
+
+def fun_l1_n869(x)
+ if (x < 1)
+ fun_l2_n55(x)
+ else
+ fun_l2_n45(x)
+ end
+end
+
+def fun_l1_n870(x)
+ if (x < 1)
+ fun_l2_n740(x)
+ else
+ fun_l2_n722(x)
+ end
+end
+
+def fun_l1_n871(x)
+ if (x < 1)
+ fun_l2_n865(x)
+ else
+ fun_l2_n695(x)
+ end
+end
+
+def fun_l1_n872(x)
+ if (x < 1)
+ fun_l2_n54(x)
+ else
+ fun_l2_n581(x)
+ end
+end
+
+def fun_l1_n873(x)
+ if (x < 1)
+ fun_l2_n328(x)
+ else
+ fun_l2_n861(x)
+ end
+end
+
+def fun_l1_n874(x)
+ if (x < 1)
+ fun_l2_n645(x)
+ else
+ fun_l2_n121(x)
+ end
+end
+
+def fun_l1_n875(x)
+ if (x < 1)
+ fun_l2_n71(x)
+ else
+ fun_l2_n329(x)
+ end
+end
+
+def fun_l1_n876(x)
+ if (x < 1)
+ fun_l2_n944(x)
+ else
+ fun_l2_n95(x)
+ end
+end
+
+def fun_l1_n877(x)
+ if (x < 1)
+ fun_l2_n270(x)
+ else
+ fun_l2_n801(x)
+ end
+end
+
+def fun_l1_n878(x)
+ if (x < 1)
+ fun_l2_n115(x)
+ else
+ fun_l2_n414(x)
+ end
+end
+
+def fun_l1_n879(x)
+ if (x < 1)
+ fun_l2_n154(x)
+ else
+ fun_l2_n605(x)
+ end
+end
+
+def fun_l1_n880(x)
+ if (x < 1)
+ fun_l2_n859(x)
+ else
+ fun_l2_n307(x)
+ end
+end
+
+def fun_l1_n881(x)
+ if (x < 1)
+ fun_l2_n443(x)
+ else
+ fun_l2_n267(x)
+ end
+end
+
+def fun_l1_n882(x)
+ if (x < 1)
+ fun_l2_n280(x)
+ else
+ fun_l2_n175(x)
+ end
+end
+
+def fun_l1_n883(x)
+ if (x < 1)
+ fun_l2_n176(x)
+ else
+ fun_l2_n286(x)
+ end
+end
+
+def fun_l1_n884(x)
+ if (x < 1)
+ fun_l2_n422(x)
+ else
+ fun_l2_n469(x)
+ end
+end
+
+def fun_l1_n885(x)
+ if (x < 1)
+ fun_l2_n532(x)
+ else
+ fun_l2_n795(x)
+ end
+end
+
+def fun_l1_n886(x)
+ if (x < 1)
+ fun_l2_n966(x)
+ else
+ fun_l2_n46(x)
+ end
+end
+
+def fun_l1_n887(x)
+ if (x < 1)
+ fun_l2_n446(x)
+ else
+ fun_l2_n944(x)
+ end
+end
+
+def fun_l1_n888(x)
+ if (x < 1)
+ fun_l2_n256(x)
+ else
+ fun_l2_n757(x)
+ end
+end
+
+def fun_l1_n889(x)
+ if (x < 1)
+ fun_l2_n566(x)
+ else
+ fun_l2_n992(x)
+ end
+end
+
+def fun_l1_n890(x)
+ if (x < 1)
+ fun_l2_n55(x)
+ else
+ fun_l2_n121(x)
+ end
+end
+
+def fun_l1_n891(x)
+ if (x < 1)
+ fun_l2_n597(x)
+ else
+ fun_l2_n257(x)
+ end
+end
+
+def fun_l1_n892(x)
+ if (x < 1)
+ fun_l2_n79(x)
+ else
+ fun_l2_n249(x)
+ end
+end
+
+def fun_l1_n893(x)
+ if (x < 1)
+ fun_l2_n436(x)
+ else
+ fun_l2_n738(x)
+ end
+end
+
+def fun_l1_n894(x)
+ if (x < 1)
+ fun_l2_n244(x)
+ else
+ fun_l2_n184(x)
+ end
+end
+
+def fun_l1_n895(x)
+ if (x < 1)
+ fun_l2_n342(x)
+ else
+ fun_l2_n794(x)
+ end
+end
+
+def fun_l1_n896(x)
+ if (x < 1)
+ fun_l2_n588(x)
+ else
+ fun_l2_n235(x)
+ end
+end
+
+def fun_l1_n897(x)
+ if (x < 1)
+ fun_l2_n443(x)
+ else
+ fun_l2_n462(x)
+ end
+end
+
+def fun_l1_n898(x)
+ if (x < 1)
+ fun_l2_n986(x)
+ else
+ fun_l2_n282(x)
+ end
+end
+
+def fun_l1_n899(x)
+ if (x < 1)
+ fun_l2_n61(x)
+ else
+ fun_l2_n516(x)
+ end
+end
+
+def fun_l1_n900(x)
+ if (x < 1)
+ fun_l2_n993(x)
+ else
+ fun_l2_n337(x)
+ end
+end
+
+def fun_l1_n901(x)
+ if (x < 1)
+ fun_l2_n398(x)
+ else
+ fun_l2_n425(x)
+ end
+end
+
+def fun_l1_n902(x)
+ if (x < 1)
+ fun_l2_n177(x)
+ else
+ fun_l2_n741(x)
+ end
+end
+
+def fun_l1_n903(x)
+ if (x < 1)
+ fun_l2_n597(x)
+ else
+ fun_l2_n331(x)
+ end
+end
+
+def fun_l1_n904(x)
+ if (x < 1)
+ fun_l2_n740(x)
+ else
+ fun_l2_n527(x)
+ end
+end
+
+def fun_l1_n905(x)
+ if (x < 1)
+ fun_l2_n138(x)
+ else
+ fun_l2_n248(x)
+ end
+end
+
+def fun_l1_n906(x)
+ if (x < 1)
+ fun_l2_n318(x)
+ else
+ fun_l2_n941(x)
+ end
+end
+
+def fun_l1_n907(x)
+ if (x < 1)
+ fun_l2_n493(x)
+ else
+ fun_l2_n376(x)
+ end
+end
+
+def fun_l1_n908(x)
+ if (x < 1)
+ fun_l2_n899(x)
+ else
+ fun_l2_n745(x)
+ end
+end
+
+def fun_l1_n909(x)
+ if (x < 1)
+ fun_l2_n963(x)
+ else
+ fun_l2_n384(x)
+ end
+end
+
+def fun_l1_n910(x)
+ if (x < 1)
+ fun_l2_n490(x)
+ else
+ fun_l2_n702(x)
+ end
+end
+
+def fun_l1_n911(x)
+ if (x < 1)
+ fun_l2_n712(x)
+ else
+ fun_l2_n810(x)
+ end
+end
+
+def fun_l1_n912(x)
+ if (x < 1)
+ fun_l2_n245(x)
+ else
+ fun_l2_n609(x)
+ end
+end
+
+def fun_l1_n913(x)
+ if (x < 1)
+ fun_l2_n997(x)
+ else
+ fun_l2_n241(x)
+ end
+end
+
+def fun_l1_n914(x)
+ if (x < 1)
+ fun_l2_n428(x)
+ else
+ fun_l2_n697(x)
+ end
+end
+
+def fun_l1_n915(x)
+ if (x < 1)
+ fun_l2_n257(x)
+ else
+ fun_l2_n626(x)
+ end
+end
+
+def fun_l1_n916(x)
+ if (x < 1)
+ fun_l2_n378(x)
+ else
+ fun_l2_n457(x)
+ end
+end
+
+def fun_l1_n917(x)
+ if (x < 1)
+ fun_l2_n378(x)
+ else
+ fun_l2_n958(x)
+ end
+end
+
+def fun_l1_n918(x)
+ if (x < 1)
+ fun_l2_n213(x)
+ else
+ fun_l2_n962(x)
+ end
+end
+
+def fun_l1_n919(x)
+ if (x < 1)
+ fun_l2_n466(x)
+ else
+ fun_l2_n461(x)
+ end
+end
+
+def fun_l1_n920(x)
+ if (x < 1)
+ fun_l2_n835(x)
+ else
+ fun_l2_n460(x)
+ end
+end
+
+def fun_l1_n921(x)
+ if (x < 1)
+ fun_l2_n642(x)
+ else
+ fun_l2_n680(x)
+ end
+end
+
+def fun_l1_n922(x)
+ if (x < 1)
+ fun_l2_n467(x)
+ else
+ fun_l2_n225(x)
+ end
+end
+
+def fun_l1_n923(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n462(x)
+ end
+end
+
+def fun_l1_n924(x)
+ if (x < 1)
+ fun_l2_n113(x)
+ else
+ fun_l2_n59(x)
+ end
+end
+
+def fun_l1_n925(x)
+ if (x < 1)
+ fun_l2_n329(x)
+ else
+ fun_l2_n994(x)
+ end
+end
+
+def fun_l1_n926(x)
+ if (x < 1)
+ fun_l2_n815(x)
+ else
+ fun_l2_n249(x)
+ end
+end
+
+def fun_l1_n927(x)
+ if (x < 1)
+ fun_l2_n216(x)
+ else
+ fun_l2_n591(x)
+ end
+end
+
+def fun_l1_n928(x)
+ if (x < 1)
+ fun_l2_n441(x)
+ else
+ fun_l2_n437(x)
+ end
+end
+
+def fun_l1_n929(x)
+ if (x < 1)
+ fun_l2_n433(x)
+ else
+ fun_l2_n185(x)
+ end
+end
+
+def fun_l1_n930(x)
+ if (x < 1)
+ fun_l2_n125(x)
+ else
+ fun_l2_n940(x)
+ end
+end
+
+def fun_l1_n931(x)
+ if (x < 1)
+ fun_l2_n203(x)
+ else
+ fun_l2_n292(x)
+ end
+end
+
+def fun_l1_n932(x)
+ if (x < 1)
+ fun_l2_n986(x)
+ else
+ fun_l2_n234(x)
+ end
+end
+
+def fun_l1_n933(x)
+ if (x < 1)
+ fun_l2_n735(x)
+ else
+ fun_l2_n20(x)
+ end
+end
+
+def fun_l1_n934(x)
+ if (x < 1)
+ fun_l2_n878(x)
+ else
+ fun_l2_n166(x)
+ end
+end
+
+def fun_l1_n935(x)
+ if (x < 1)
+ fun_l2_n123(x)
+ else
+ fun_l2_n52(x)
+ end
+end
+
+def fun_l1_n936(x)
+ if (x < 1)
+ fun_l2_n99(x)
+ else
+ fun_l2_n336(x)
+ end
+end
+
+def fun_l1_n937(x)
+ if (x < 1)
+ fun_l2_n731(x)
+ else
+ fun_l2_n363(x)
+ end
+end
+
+def fun_l1_n938(x)
+ if (x < 1)
+ fun_l2_n988(x)
+ else
+ fun_l2_n978(x)
+ end
+end
+
+def fun_l1_n939(x)
+ if (x < 1)
+ fun_l2_n592(x)
+ else
+ fun_l2_n932(x)
+ end
+end
+
+def fun_l1_n940(x)
+ if (x < 1)
+ fun_l2_n681(x)
+ else
+ fun_l2_n868(x)
+ end
+end
+
+def fun_l1_n941(x)
+ if (x < 1)
+ fun_l2_n863(x)
+ else
+ fun_l2_n457(x)
+ end
+end
+
+def fun_l1_n942(x)
+ if (x < 1)
+ fun_l2_n526(x)
+ else
+ fun_l2_n960(x)
+ end
+end
+
+def fun_l1_n943(x)
+ if (x < 1)
+ fun_l2_n859(x)
+ else
+ fun_l2_n478(x)
+ end
+end
+
+def fun_l1_n944(x)
+ if (x < 1)
+ fun_l2_n947(x)
+ else
+ fun_l2_n889(x)
+ end
+end
+
+def fun_l1_n945(x)
+ if (x < 1)
+ fun_l2_n845(x)
+ else
+ fun_l2_n211(x)
+ end
+end
+
+def fun_l1_n946(x)
+ if (x < 1)
+ fun_l2_n445(x)
+ else
+ fun_l2_n600(x)
+ end
+end
+
+def fun_l1_n947(x)
+ if (x < 1)
+ fun_l2_n932(x)
+ else
+ fun_l2_n534(x)
+ end
+end
+
+def fun_l1_n948(x)
+ if (x < 1)
+ fun_l2_n224(x)
+ else
+ fun_l2_n32(x)
+ end
+end
+
+def fun_l1_n949(x)
+ if (x < 1)
+ fun_l2_n63(x)
+ else
+ fun_l2_n121(x)
+ end
+end
+
+def fun_l1_n950(x)
+ if (x < 1)
+ fun_l2_n55(x)
+ else
+ fun_l2_n90(x)
+ end
+end
+
+def fun_l1_n951(x)
+ if (x < 1)
+ fun_l2_n880(x)
+ else
+ fun_l2_n936(x)
+ end
+end
+
+def fun_l1_n952(x)
+ if (x < 1)
+ fun_l2_n971(x)
+ else
+ fun_l2_n40(x)
+ end
+end
+
+def fun_l1_n953(x)
+ if (x < 1)
+ fun_l2_n880(x)
+ else
+ fun_l2_n200(x)
+ end
+end
+
+def fun_l1_n954(x)
+ if (x < 1)
+ fun_l2_n60(x)
+ else
+ fun_l2_n473(x)
+ end
+end
+
+def fun_l1_n955(x)
+ if (x < 1)
+ fun_l2_n855(x)
+ else
+ fun_l2_n601(x)
+ end
+end
+
+def fun_l1_n956(x)
+ if (x < 1)
+ fun_l2_n282(x)
+ else
+ fun_l2_n542(x)
+ end
+end
+
+def fun_l1_n957(x)
+ if (x < 1)
+ fun_l2_n116(x)
+ else
+ fun_l2_n584(x)
+ end
+end
+
+def fun_l1_n958(x)
+ if (x < 1)
+ fun_l2_n845(x)
+ else
+ fun_l2_n814(x)
+ end
+end
+
+def fun_l1_n959(x)
+ if (x < 1)
+ fun_l2_n443(x)
+ else
+ fun_l2_n239(x)
+ end
+end
+
+def fun_l1_n960(x)
+ if (x < 1)
+ fun_l2_n79(x)
+ else
+ fun_l2_n556(x)
+ end
+end
+
+def fun_l1_n961(x)
+ if (x < 1)
+ fun_l2_n664(x)
+ else
+ fun_l2_n282(x)
+ end
+end
+
+def fun_l1_n962(x)
+ if (x < 1)
+ fun_l2_n273(x)
+ else
+ fun_l2_n393(x)
+ end
+end
+
+def fun_l1_n963(x)
+ if (x < 1)
+ fun_l2_n120(x)
+ else
+ fun_l2_n506(x)
+ end
+end
+
+def fun_l1_n964(x)
+ if (x < 1)
+ fun_l2_n362(x)
+ else
+ fun_l2_n631(x)
+ end
+end
+
+def fun_l1_n965(x)
+ if (x < 1)
+ fun_l2_n219(x)
+ else
+ fun_l2_n260(x)
+ end
+end
+
+def fun_l1_n966(x)
+ if (x < 1)
+ fun_l2_n802(x)
+ else
+ fun_l2_n732(x)
+ end
+end
+
+def fun_l1_n967(x)
+ if (x < 1)
+ fun_l2_n761(x)
+ else
+ fun_l2_n580(x)
+ end
+end
+
+def fun_l1_n968(x)
+ if (x < 1)
+ fun_l2_n529(x)
+ else
+ fun_l2_n783(x)
+ end
+end
+
+def fun_l1_n969(x)
+ if (x < 1)
+ fun_l2_n138(x)
+ else
+ fun_l2_n434(x)
+ end
+end
+
+def fun_l1_n970(x)
+ if (x < 1)
+ fun_l2_n266(x)
+ else
+ fun_l2_n522(x)
+ end
+end
+
+def fun_l1_n971(x)
+ if (x < 1)
+ fun_l2_n352(x)
+ else
+ fun_l2_n51(x)
+ end
+end
+
+def fun_l1_n972(x)
+ if (x < 1)
+ fun_l2_n619(x)
+ else
+ fun_l2_n68(x)
+ end
+end
+
+def fun_l1_n973(x)
+ if (x < 1)
+ fun_l2_n510(x)
+ else
+ fun_l2_n74(x)
+ end
+end
+
+def fun_l1_n974(x)
+ if (x < 1)
+ fun_l2_n442(x)
+ else
+ fun_l2_n258(x)
+ end
+end
+
+def fun_l1_n975(x)
+ if (x < 1)
+ fun_l2_n106(x)
+ else
+ fun_l2_n364(x)
+ end
+end
+
+def fun_l1_n976(x)
+ if (x < 1)
+ fun_l2_n412(x)
+ else
+ fun_l2_n669(x)
+ end
+end
+
+def fun_l1_n977(x)
+ if (x < 1)
+ fun_l2_n394(x)
+ else
+ fun_l2_n435(x)
+ end
+end
+
+def fun_l1_n978(x)
+ if (x < 1)
+ fun_l2_n630(x)
+ else
+ fun_l2_n686(x)
+ end
+end
+
+def fun_l1_n979(x)
+ if (x < 1)
+ fun_l2_n683(x)
+ else
+ fun_l2_n99(x)
+ end
+end
+
+def fun_l1_n980(x)
+ if (x < 1)
+ fun_l2_n352(x)
+ else
+ fun_l2_n394(x)
+ end
+end
+
+def fun_l1_n981(x)
+ if (x < 1)
+ fun_l2_n856(x)
+ else
+ fun_l2_n11(x)
+ end
+end
+
+def fun_l1_n982(x)
+ if (x < 1)
+ fun_l2_n484(x)
+ else
+ fun_l2_n230(x)
+ end
+end
+
+def fun_l1_n983(x)
+ if (x < 1)
+ fun_l2_n609(x)
+ else
+ fun_l2_n882(x)
+ end
+end
+
+def fun_l1_n984(x)
+ if (x < 1)
+ fun_l2_n529(x)
+ else
+ fun_l2_n589(x)
+ end
+end
+
+def fun_l1_n985(x)
+ if (x < 1)
+ fun_l2_n545(x)
+ else
+ fun_l2_n139(x)
+ end
+end
+
+def fun_l1_n986(x)
+ if (x < 1)
+ fun_l2_n679(x)
+ else
+ fun_l2_n938(x)
+ end
+end
+
+def fun_l1_n987(x)
+ if (x < 1)
+ fun_l2_n803(x)
+ else
+ fun_l2_n454(x)
+ end
+end
+
+def fun_l1_n988(x)
+ if (x < 1)
+ fun_l2_n403(x)
+ else
+ fun_l2_n976(x)
+ end
+end
+
+def fun_l1_n989(x)
+ if (x < 1)
+ fun_l2_n364(x)
+ else
+ fun_l2_n96(x)
+ end
+end
+
+def fun_l1_n990(x)
+ if (x < 1)
+ fun_l2_n48(x)
+ else
+ fun_l2_n442(x)
+ end
+end
+
+def fun_l1_n991(x)
+ if (x < 1)
+ fun_l2_n842(x)
+ else
+ fun_l2_n810(x)
+ end
+end
+
+def fun_l1_n992(x)
+ if (x < 1)
+ fun_l2_n237(x)
+ else
+ fun_l2_n145(x)
+ end
+end
+
+def fun_l1_n993(x)
+ if (x < 1)
+ fun_l2_n279(x)
+ else
+ fun_l2_n783(x)
+ end
+end
+
+def fun_l1_n994(x)
+ if (x < 1)
+ fun_l2_n323(x)
+ else
+ fun_l2_n829(x)
+ end
+end
+
+def fun_l1_n995(x)
+ if (x < 1)
+ fun_l2_n904(x)
+ else
+ fun_l2_n738(x)
+ end
+end
+
+def fun_l1_n996(x)
+ if (x < 1)
+ fun_l2_n390(x)
+ else
+ fun_l2_n169(x)
+ end
+end
+
+def fun_l1_n997(x)
+ if (x < 1)
+ fun_l2_n583(x)
+ else
+ fun_l2_n993(x)
+ end
+end
+
+def fun_l1_n998(x)
+ if (x < 1)
+ fun_l2_n752(x)
+ else
+ fun_l2_n240(x)
+ end
+end
+
+def fun_l1_n999(x)
+ if (x < 1)
+ fun_l2_n489(x)
+ else
+ fun_l2_n175(x)
+ end
+end
+
+def fun_l2_n0(x)
+ if (x < 1)
+ fun_l3_n293(x)
+ else
+ fun_l3_n569(x)
+ end
+end
+
+def fun_l2_n1(x)
+ if (x < 1)
+ fun_l3_n310(x)
+ else
+ fun_l3_n785(x)
+ end
+end
+
+def fun_l2_n2(x)
+ if (x < 1)
+ fun_l3_n484(x)
+ else
+ fun_l3_n800(x)
+ end
+end
+
+def fun_l2_n3(x)
+ if (x < 1)
+ fun_l3_n353(x)
+ else
+ fun_l3_n871(x)
+ end
+end
+
+def fun_l2_n4(x)
+ if (x < 1)
+ fun_l3_n100(x)
+ else
+ fun_l3_n796(x)
+ end
+end
+
+def fun_l2_n5(x)
+ if (x < 1)
+ fun_l3_n547(x)
+ else
+ fun_l3_n663(x)
+ end
+end
+
+def fun_l2_n6(x)
+ if (x < 1)
+ fun_l3_n756(x)
+ else
+ fun_l3_n69(x)
+ end
+end
+
+def fun_l2_n7(x)
+ if (x < 1)
+ fun_l3_n393(x)
+ else
+ fun_l3_n333(x)
+ end
+end
+
+def fun_l2_n8(x)
+ if (x < 1)
+ fun_l3_n167(x)
+ else
+ fun_l3_n47(x)
+ end
+end
+
+def fun_l2_n9(x)
+ if (x < 1)
+ fun_l3_n969(x)
+ else
+ fun_l3_n772(x)
+ end
+end
+
+def fun_l2_n10(x)
+ if (x < 1)
+ fun_l3_n667(x)
+ else
+ fun_l3_n62(x)
+ end
+end
+
+def fun_l2_n11(x)
+ if (x < 1)
+ fun_l3_n671(x)
+ else
+ fun_l3_n303(x)
+ end
+end
+
+def fun_l2_n12(x)
+ if (x < 1)
+ fun_l3_n116(x)
+ else
+ fun_l3_n537(x)
+ end
+end
+
+def fun_l2_n13(x)
+ if (x < 1)
+ fun_l3_n363(x)
+ else
+ fun_l3_n426(x)
+ end
+end
+
+def fun_l2_n14(x)
+ if (x < 1)
+ fun_l3_n23(x)
+ else
+ fun_l3_n800(x)
+ end
+end
+
+def fun_l2_n15(x)
+ if (x < 1)
+ fun_l3_n344(x)
+ else
+ fun_l3_n590(x)
+ end
+end
+
+def fun_l2_n16(x)
+ if (x < 1)
+ fun_l3_n759(x)
+ else
+ fun_l3_n531(x)
+ end
+end
+
+def fun_l2_n17(x)
+ if (x < 1)
+ fun_l3_n902(x)
+ else
+ fun_l3_n948(x)
+ end
+end
+
+def fun_l2_n18(x)
+ if (x < 1)
+ fun_l3_n407(x)
+ else
+ fun_l3_n743(x)
+ end
+end
+
+def fun_l2_n19(x)
+ if (x < 1)
+ fun_l3_n360(x)
+ else
+ fun_l3_n953(x)
+ end
+end
+
+def fun_l2_n20(x)
+ if (x < 1)
+ fun_l3_n968(x)
+ else
+ fun_l3_n685(x)
+ end
+end
+
+def fun_l2_n21(x)
+ if (x < 1)
+ fun_l3_n964(x)
+ else
+ fun_l3_n210(x)
+ end
+end
+
+def fun_l2_n22(x)
+ if (x < 1)
+ fun_l3_n346(x)
+ else
+ fun_l3_n902(x)
+ end
+end
+
+def fun_l2_n23(x)
+ if (x < 1)
+ fun_l3_n154(x)
+ else
+ fun_l3_n52(x)
+ end
+end
+
+def fun_l2_n24(x)
+ if (x < 1)
+ fun_l3_n229(x)
+ else
+ fun_l3_n137(x)
+ end
+end
+
+def fun_l2_n25(x)
+ if (x < 1)
+ fun_l3_n390(x)
+ else
+ fun_l3_n445(x)
+ end
+end
+
+def fun_l2_n26(x)
+ if (x < 1)
+ fun_l3_n11(x)
+ else
+ fun_l3_n113(x)
+ end
+end
+
+def fun_l2_n27(x)
+ if (x < 1)
+ fun_l3_n756(x)
+ else
+ fun_l3_n935(x)
+ end
+end
+
+def fun_l2_n28(x)
+ if (x < 1)
+ fun_l3_n567(x)
+ else
+ fun_l3_n984(x)
+ end
+end
+
+def fun_l2_n29(x)
+ if (x < 1)
+ fun_l3_n982(x)
+ else
+ fun_l3_n335(x)
+ end
+end
+
+def fun_l2_n30(x)
+ if (x < 1)
+ fun_l3_n78(x)
+ else
+ fun_l3_n571(x)
+ end
+end
+
+def fun_l2_n31(x)
+ if (x < 1)
+ fun_l3_n93(x)
+ else
+ fun_l3_n455(x)
+ end
+end
+
+def fun_l2_n32(x)
+ if (x < 1)
+ fun_l3_n118(x)
+ else
+ fun_l3_n713(x)
+ end
+end
+
+def fun_l2_n33(x)
+ if (x < 1)
+ fun_l3_n561(x)
+ else
+ fun_l3_n0(x)
+ end
+end
+
+def fun_l2_n34(x)
+ if (x < 1)
+ fun_l3_n153(x)
+ else
+ fun_l3_n77(x)
+ end
+end
+
+def fun_l2_n35(x)
+ if (x < 1)
+ fun_l3_n815(x)
+ else
+ fun_l3_n642(x)
+ end
+end
+
+def fun_l2_n36(x)
+ if (x < 1)
+ fun_l3_n503(x)
+ else
+ fun_l3_n428(x)
+ end
+end
+
+def fun_l2_n37(x)
+ if (x < 1)
+ fun_l3_n780(x)
+ else
+ fun_l3_n301(x)
+ end
+end
+
+def fun_l2_n38(x)
+ if (x < 1)
+ fun_l3_n827(x)
+ else
+ fun_l3_n444(x)
+ end
+end
+
+def fun_l2_n39(x)
+ if (x < 1)
+ fun_l3_n808(x)
+ else
+ fun_l3_n76(x)
+ end
+end
+
+def fun_l2_n40(x)
+ if (x < 1)
+ fun_l3_n216(x)
+ else
+ fun_l3_n943(x)
+ end
+end
+
+def fun_l2_n41(x)
+ if (x < 1)
+ fun_l3_n237(x)
+ else
+ fun_l3_n935(x)
+ end
+end
+
+def fun_l2_n42(x)
+ if (x < 1)
+ fun_l3_n769(x)
+ else
+ fun_l3_n564(x)
+ end
+end
+
+def fun_l2_n43(x)
+ if (x < 1)
+ fun_l3_n108(x)
+ else
+ fun_l3_n180(x)
+ end
+end
+
+def fun_l2_n44(x)
+ if (x < 1)
+ fun_l3_n750(x)
+ else
+ fun_l3_n614(x)
+ end
+end
+
+def fun_l2_n45(x)
+ if (x < 1)
+ fun_l3_n497(x)
+ else
+ fun_l3_n584(x)
+ end
+end
+
+def fun_l2_n46(x)
+ if (x < 1)
+ fun_l3_n364(x)
+ else
+ fun_l3_n218(x)
+ end
+end
+
+def fun_l2_n47(x)
+ if (x < 1)
+ fun_l3_n938(x)
+ else
+ fun_l3_n707(x)
+ end
+end
+
+def fun_l2_n48(x)
+ if (x < 1)
+ fun_l3_n14(x)
+ else
+ fun_l3_n178(x)
+ end
+end
+
+def fun_l2_n49(x)
+ if (x < 1)
+ fun_l3_n923(x)
+ else
+ fun_l3_n493(x)
+ end
+end
+
+def fun_l2_n50(x)
+ if (x < 1)
+ fun_l3_n481(x)
+ else
+ fun_l3_n193(x)
+ end
+end
+
+def fun_l2_n51(x)
+ if (x < 1)
+ fun_l3_n876(x)
+ else
+ fun_l3_n59(x)
+ end
+end
+
+def fun_l2_n52(x)
+ if (x < 1)
+ fun_l3_n930(x)
+ else
+ fun_l3_n813(x)
+ end
+end
+
+def fun_l2_n53(x)
+ if (x < 1)
+ fun_l3_n369(x)
+ else
+ fun_l3_n972(x)
+ end
+end
+
+def fun_l2_n54(x)
+ if (x < 1)
+ fun_l3_n95(x)
+ else
+ fun_l3_n573(x)
+ end
+end
+
+def fun_l2_n55(x)
+ if (x < 1)
+ fun_l3_n148(x)
+ else
+ fun_l3_n369(x)
+ end
+end
+
+def fun_l2_n56(x)
+ if (x < 1)
+ fun_l3_n476(x)
+ else
+ fun_l3_n54(x)
+ end
+end
+
+def fun_l2_n57(x)
+ if (x < 1)
+ fun_l3_n672(x)
+ else
+ fun_l3_n592(x)
+ end
+end
+
+def fun_l2_n58(x)
+ if (x < 1)
+ fun_l3_n648(x)
+ else
+ fun_l3_n169(x)
+ end
+end
+
+def fun_l2_n59(x)
+ if (x < 1)
+ fun_l3_n844(x)
+ else
+ fun_l3_n422(x)
+ end
+end
+
+def fun_l2_n60(x)
+ if (x < 1)
+ fun_l3_n6(x)
+ else
+ fun_l3_n763(x)
+ end
+end
+
+def fun_l2_n61(x)
+ if (x < 1)
+ fun_l3_n35(x)
+ else
+ fun_l3_n316(x)
+ end
+end
+
+def fun_l2_n62(x)
+ if (x < 1)
+ fun_l3_n487(x)
+ else
+ fun_l3_n469(x)
+ end
+end
+
+def fun_l2_n63(x)
+ if (x < 1)
+ fun_l3_n272(x)
+ else
+ fun_l3_n909(x)
+ end
+end
+
+def fun_l2_n64(x)
+ if (x < 1)
+ fun_l3_n266(x)
+ else
+ fun_l3_n347(x)
+ end
+end
+
+def fun_l2_n65(x)
+ if (x < 1)
+ fun_l3_n696(x)
+ else
+ fun_l3_n499(x)
+ end
+end
+
+def fun_l2_n66(x)
+ if (x < 1)
+ fun_l3_n523(x)
+ else
+ fun_l3_n834(x)
+ end
+end
+
+def fun_l2_n67(x)
+ if (x < 1)
+ fun_l3_n966(x)
+ else
+ fun_l3_n454(x)
+ end
+end
+
+def fun_l2_n68(x)
+ if (x < 1)
+ fun_l3_n406(x)
+ else
+ fun_l3_n644(x)
+ end
+end
+
+def fun_l2_n69(x)
+ if (x < 1)
+ fun_l3_n616(x)
+ else
+ fun_l3_n90(x)
+ end
+end
+
+def fun_l2_n70(x)
+ if (x < 1)
+ fun_l3_n158(x)
+ else
+ fun_l3_n910(x)
+ end
+end
+
+def fun_l2_n71(x)
+ if (x < 1)
+ fun_l3_n391(x)
+ else
+ fun_l3_n761(x)
+ end
+end
+
+def fun_l2_n72(x)
+ if (x < 1)
+ fun_l3_n585(x)
+ else
+ fun_l3_n405(x)
+ end
+end
+
+def fun_l2_n73(x)
+ if (x < 1)
+ fun_l3_n227(x)
+ else
+ fun_l3_n583(x)
+ end
+end
+
+def fun_l2_n74(x)
+ if (x < 1)
+ fun_l3_n580(x)
+ else
+ fun_l3_n110(x)
+ end
+end
+
+def fun_l2_n75(x)
+ if (x < 1)
+ fun_l3_n393(x)
+ else
+ fun_l3_n643(x)
+ end
+end
+
+def fun_l2_n76(x)
+ if (x < 1)
+ fun_l3_n935(x)
+ else
+ fun_l3_n593(x)
+ end
+end
+
+def fun_l2_n77(x)
+ if (x < 1)
+ fun_l3_n239(x)
+ else
+ fun_l3_n704(x)
+ end
+end
+
+def fun_l2_n78(x)
+ if (x < 1)
+ fun_l3_n192(x)
+ else
+ fun_l3_n722(x)
+ end
+end
+
+def fun_l2_n79(x)
+ if (x < 1)
+ fun_l3_n119(x)
+ else
+ fun_l3_n426(x)
+ end
+end
+
+def fun_l2_n80(x)
+ if (x < 1)
+ fun_l3_n692(x)
+ else
+ fun_l3_n895(x)
+ end
+end
+
+def fun_l2_n81(x)
+ if (x < 1)
+ fun_l3_n246(x)
+ else
+ fun_l3_n340(x)
+ end
+end
+
+def fun_l2_n82(x)
+ if (x < 1)
+ fun_l3_n368(x)
+ else
+ fun_l3_n255(x)
+ end
+end
+
+def fun_l2_n83(x)
+ if (x < 1)
+ fun_l3_n942(x)
+ else
+ fun_l3_n595(x)
+ end
+end
+
+def fun_l2_n84(x)
+ if (x < 1)
+ fun_l3_n629(x)
+ else
+ fun_l3_n622(x)
+ end
+end
+
+def fun_l2_n85(x)
+ if (x < 1)
+ fun_l3_n415(x)
+ else
+ fun_l3_n615(x)
+ end
+end
+
+def fun_l2_n86(x)
+ if (x < 1)
+ fun_l3_n295(x)
+ else
+ fun_l3_n809(x)
+ end
+end
+
+def fun_l2_n87(x)
+ if (x < 1)
+ fun_l3_n957(x)
+ else
+ fun_l3_n452(x)
+ end
+end
+
+def fun_l2_n88(x)
+ if (x < 1)
+ fun_l3_n490(x)
+ else
+ fun_l3_n184(x)
+ end
+end
+
+def fun_l2_n89(x)
+ if (x < 1)
+ fun_l3_n483(x)
+ else
+ fun_l3_n963(x)
+ end
+end
+
+def fun_l2_n90(x)
+ if (x < 1)
+ fun_l3_n262(x)
+ else
+ fun_l3_n458(x)
+ end
+end
+
+def fun_l2_n91(x)
+ if (x < 1)
+ fun_l3_n277(x)
+ else
+ fun_l3_n30(x)
+ end
+end
+
+def fun_l2_n92(x)
+ if (x < 1)
+ fun_l3_n310(x)
+ else
+ fun_l3_n215(x)
+ end
+end
+
+def fun_l2_n93(x)
+ if (x < 1)
+ fun_l3_n660(x)
+ else
+ fun_l3_n798(x)
+ end
+end
+
+def fun_l2_n94(x)
+ if (x < 1)
+ fun_l3_n761(x)
+ else
+ fun_l3_n10(x)
+ end
+end
+
+def fun_l2_n95(x)
+ if (x < 1)
+ fun_l3_n4(x)
+ else
+ fun_l3_n65(x)
+ end
+end
+
+def fun_l2_n96(x)
+ if (x < 1)
+ fun_l3_n444(x)
+ else
+ fun_l3_n378(x)
+ end
+end
+
+def fun_l2_n97(x)
+ if (x < 1)
+ fun_l3_n119(x)
+ else
+ fun_l3_n96(x)
+ end
+end
+
+def fun_l2_n98(x)
+ if (x < 1)
+ fun_l3_n970(x)
+ else
+ fun_l3_n471(x)
+ end
+end
+
+def fun_l2_n99(x)
+ if (x < 1)
+ fun_l3_n544(x)
+ else
+ fun_l3_n1(x)
+ end
+end
+
+def fun_l2_n100(x)
+ if (x < 1)
+ fun_l3_n253(x)
+ else
+ fun_l3_n332(x)
+ end
+end
+
+def fun_l2_n101(x)
+ if (x < 1)
+ fun_l3_n69(x)
+ else
+ fun_l3_n946(x)
+ end
+end
+
+def fun_l2_n102(x)
+ if (x < 1)
+ fun_l3_n458(x)
+ else
+ fun_l3_n885(x)
+ end
+end
+
+def fun_l2_n103(x)
+ if (x < 1)
+ fun_l3_n732(x)
+ else
+ fun_l3_n601(x)
+ end
+end
+
+def fun_l2_n104(x)
+ if (x < 1)
+ fun_l3_n737(x)
+ else
+ fun_l3_n530(x)
+ end
+end
+
+def fun_l2_n105(x)
+ if (x < 1)
+ fun_l3_n125(x)
+ else
+ fun_l3_n561(x)
+ end
+end
+
+def fun_l2_n106(x)
+ if (x < 1)
+ fun_l3_n717(x)
+ else
+ fun_l3_n660(x)
+ end
+end
+
+def fun_l2_n107(x)
+ if (x < 1)
+ fun_l3_n863(x)
+ else
+ fun_l3_n211(x)
+ end
+end
+
+def fun_l2_n108(x)
+ if (x < 1)
+ fun_l3_n221(x)
+ else
+ fun_l3_n718(x)
+ end
+end
+
+def fun_l2_n109(x)
+ if (x < 1)
+ fun_l3_n100(x)
+ else
+ fun_l3_n673(x)
+ end
+end
+
+def fun_l2_n110(x)
+ if (x < 1)
+ fun_l3_n434(x)
+ else
+ fun_l3_n348(x)
+ end
+end
+
+def fun_l2_n111(x)
+ if (x < 1)
+ fun_l3_n923(x)
+ else
+ fun_l3_n413(x)
+ end
+end
+
+def fun_l2_n112(x)
+ if (x < 1)
+ fun_l3_n253(x)
+ else
+ fun_l3_n461(x)
+ end
+end
+
+def fun_l2_n113(x)
+ if (x < 1)
+ fun_l3_n946(x)
+ else
+ fun_l3_n406(x)
+ end
+end
+
+def fun_l2_n114(x)
+ if (x < 1)
+ fun_l3_n976(x)
+ else
+ fun_l3_n354(x)
+ end
+end
+
+def fun_l2_n115(x)
+ if (x < 1)
+ fun_l3_n205(x)
+ else
+ fun_l3_n798(x)
+ end
+end
+
+def fun_l2_n116(x)
+ if (x < 1)
+ fun_l3_n304(x)
+ else
+ fun_l3_n145(x)
+ end
+end
+
+def fun_l2_n117(x)
+ if (x < 1)
+ fun_l3_n917(x)
+ else
+ fun_l3_n276(x)
+ end
+end
+
+def fun_l2_n118(x)
+ if (x < 1)
+ fun_l3_n880(x)
+ else
+ fun_l3_n532(x)
+ end
+end
+
+def fun_l2_n119(x)
+ if (x < 1)
+ fun_l3_n39(x)
+ else
+ fun_l3_n549(x)
+ end
+end
+
+def fun_l2_n120(x)
+ if (x < 1)
+ fun_l3_n325(x)
+ else
+ fun_l3_n250(x)
+ end
+end
+
+def fun_l2_n121(x)
+ if (x < 1)
+ fun_l3_n953(x)
+ else
+ fun_l3_n259(x)
+ end
+end
+
+def fun_l2_n122(x)
+ if (x < 1)
+ fun_l3_n572(x)
+ else
+ fun_l3_n747(x)
+ end
+end
+
+def fun_l2_n123(x)
+ if (x < 1)
+ fun_l3_n639(x)
+ else
+ fun_l3_n810(x)
+ end
+end
+
+def fun_l2_n124(x)
+ if (x < 1)
+ fun_l3_n954(x)
+ else
+ fun_l3_n814(x)
+ end
+end
+
+def fun_l2_n125(x)
+ if (x < 1)
+ fun_l3_n932(x)
+ else
+ fun_l3_n275(x)
+ end
+end
+
+def fun_l2_n126(x)
+ if (x < 1)
+ fun_l3_n472(x)
+ else
+ fun_l3_n184(x)
+ end
+end
+
+def fun_l2_n127(x)
+ if (x < 1)
+ fun_l3_n725(x)
+ else
+ fun_l3_n497(x)
+ end
+end
+
+def fun_l2_n128(x)
+ if (x < 1)
+ fun_l3_n94(x)
+ else
+ fun_l3_n801(x)
+ end
+end
+
+def fun_l2_n129(x)
+ if (x < 1)
+ fun_l3_n476(x)
+ else
+ fun_l3_n936(x)
+ end
+end
+
+def fun_l2_n130(x)
+ if (x < 1)
+ fun_l3_n706(x)
+ else
+ fun_l3_n738(x)
+ end
+end
+
+def fun_l2_n131(x)
+ if (x < 1)
+ fun_l3_n535(x)
+ else
+ fun_l3_n401(x)
+ end
+end
+
+def fun_l2_n132(x)
+ if (x < 1)
+ fun_l3_n459(x)
+ else
+ fun_l3_n998(x)
+ end
+end
+
+def fun_l2_n133(x)
+ if (x < 1)
+ fun_l3_n158(x)
+ else
+ fun_l3_n288(x)
+ end
+end
+
+def fun_l2_n134(x)
+ if (x < 1)
+ fun_l3_n47(x)
+ else
+ fun_l3_n104(x)
+ end
+end
+
+def fun_l2_n135(x)
+ if (x < 1)
+ fun_l3_n154(x)
+ else
+ fun_l3_n239(x)
+ end
+end
+
+def fun_l2_n136(x)
+ if (x < 1)
+ fun_l3_n634(x)
+ else
+ fun_l3_n718(x)
+ end
+end
+
+def fun_l2_n137(x)
+ if (x < 1)
+ fun_l3_n867(x)
+ else
+ fun_l3_n578(x)
+ end
+end
+
+def fun_l2_n138(x)
+ if (x < 1)
+ fun_l3_n905(x)
+ else
+ fun_l3_n434(x)
+ end
+end
+
+def fun_l2_n139(x)
+ if (x < 1)
+ fun_l3_n596(x)
+ else
+ fun_l3_n516(x)
+ end
+end
+
+def fun_l2_n140(x)
+ if (x < 1)
+ fun_l3_n150(x)
+ else
+ fun_l3_n901(x)
+ end
+end
+
+def fun_l2_n141(x)
+ if (x < 1)
+ fun_l3_n792(x)
+ else
+ fun_l3_n50(x)
+ end
+end
+
+def fun_l2_n142(x)
+ if (x < 1)
+ fun_l3_n539(x)
+ else
+ fun_l3_n206(x)
+ end
+end
+
+def fun_l2_n143(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n788(x)
+ end
+end
+
+def fun_l2_n144(x)
+ if (x < 1)
+ fun_l3_n535(x)
+ else
+ fun_l3_n868(x)
+ end
+end
+
+def fun_l2_n145(x)
+ if (x < 1)
+ fun_l3_n869(x)
+ else
+ fun_l3_n865(x)
+ end
+end
+
+def fun_l2_n146(x)
+ if (x < 1)
+ fun_l3_n574(x)
+ else
+ fun_l3_n798(x)
+ end
+end
+
+def fun_l2_n147(x)
+ if (x < 1)
+ fun_l3_n876(x)
+ else
+ fun_l3_n658(x)
+ end
+end
+
+def fun_l2_n148(x)
+ if (x < 1)
+ fun_l3_n582(x)
+ else
+ fun_l3_n694(x)
+ end
+end
+
+def fun_l2_n149(x)
+ if (x < 1)
+ fun_l3_n137(x)
+ else
+ fun_l3_n187(x)
+ end
+end
+
+def fun_l2_n150(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n666(x)
+ end
+end
+
+def fun_l2_n151(x)
+ if (x < 1)
+ fun_l3_n264(x)
+ else
+ fun_l3_n236(x)
+ end
+end
+
+def fun_l2_n152(x)
+ if (x < 1)
+ fun_l3_n984(x)
+ else
+ fun_l3_n469(x)
+ end
+end
+
+def fun_l2_n153(x)
+ if (x < 1)
+ fun_l3_n152(x)
+ else
+ fun_l3_n578(x)
+ end
+end
+
+def fun_l2_n154(x)
+ if (x < 1)
+ fun_l3_n452(x)
+ else
+ fun_l3_n807(x)
+ end
+end
+
+def fun_l2_n155(x)
+ if (x < 1)
+ fun_l3_n82(x)
+ else
+ fun_l3_n589(x)
+ end
+end
+
+def fun_l2_n156(x)
+ if (x < 1)
+ fun_l3_n356(x)
+ else
+ fun_l3_n454(x)
+ end
+end
+
+def fun_l2_n157(x)
+ if (x < 1)
+ fun_l3_n814(x)
+ else
+ fun_l3_n376(x)
+ end
+end
+
+def fun_l2_n158(x)
+ if (x < 1)
+ fun_l3_n755(x)
+ else
+ fun_l3_n966(x)
+ end
+end
+
+def fun_l2_n159(x)
+ if (x < 1)
+ fun_l3_n167(x)
+ else
+ fun_l3_n571(x)
+ end
+end
+
+def fun_l2_n160(x)
+ if (x < 1)
+ fun_l3_n919(x)
+ else
+ fun_l3_n771(x)
+ end
+end
+
+def fun_l2_n161(x)
+ if (x < 1)
+ fun_l3_n147(x)
+ else
+ fun_l3_n936(x)
+ end
+end
+
+def fun_l2_n162(x)
+ if (x < 1)
+ fun_l3_n638(x)
+ else
+ fun_l3_n23(x)
+ end
+end
+
+def fun_l2_n163(x)
+ if (x < 1)
+ fun_l3_n349(x)
+ else
+ fun_l3_n46(x)
+ end
+end
+
+def fun_l2_n164(x)
+ if (x < 1)
+ fun_l3_n55(x)
+ else
+ fun_l3_n795(x)
+ end
+end
+
+def fun_l2_n165(x)
+ if (x < 1)
+ fun_l3_n131(x)
+ else
+ fun_l3_n233(x)
+ end
+end
+
+def fun_l2_n166(x)
+ if (x < 1)
+ fun_l3_n324(x)
+ else
+ fun_l3_n215(x)
+ end
+end
+
+def fun_l2_n167(x)
+ if (x < 1)
+ fun_l3_n244(x)
+ else
+ fun_l3_n641(x)
+ end
+end
+
+def fun_l2_n168(x)
+ if (x < 1)
+ fun_l3_n744(x)
+ else
+ fun_l3_n337(x)
+ end
+end
+
+def fun_l2_n169(x)
+ if (x < 1)
+ fun_l3_n760(x)
+ else
+ fun_l3_n82(x)
+ end
+end
+
+def fun_l2_n170(x)
+ if (x < 1)
+ fun_l3_n877(x)
+ else
+ fun_l3_n566(x)
+ end
+end
+
+def fun_l2_n171(x)
+ if (x < 1)
+ fun_l3_n211(x)
+ else
+ fun_l3_n101(x)
+ end
+end
+
+def fun_l2_n172(x)
+ if (x < 1)
+ fun_l3_n143(x)
+ else
+ fun_l3_n537(x)
+ end
+end
+
+def fun_l2_n173(x)
+ if (x < 1)
+ fun_l3_n210(x)
+ else
+ fun_l3_n150(x)
+ end
+end
+
+def fun_l2_n174(x)
+ if (x < 1)
+ fun_l3_n772(x)
+ else
+ fun_l3_n42(x)
+ end
+end
+
+def fun_l2_n175(x)
+ if (x < 1)
+ fun_l3_n482(x)
+ else
+ fun_l3_n606(x)
+ end
+end
+
+def fun_l2_n176(x)
+ if (x < 1)
+ fun_l3_n68(x)
+ else
+ fun_l3_n888(x)
+ end
+end
+
+def fun_l2_n177(x)
+ if (x < 1)
+ fun_l3_n313(x)
+ else
+ fun_l3_n947(x)
+ end
+end
+
+def fun_l2_n178(x)
+ if (x < 1)
+ fun_l3_n116(x)
+ else
+ fun_l3_n812(x)
+ end
+end
+
+def fun_l2_n179(x)
+ if (x < 1)
+ fun_l3_n741(x)
+ else
+ fun_l3_n994(x)
+ end
+end
+
+def fun_l2_n180(x)
+ if (x < 1)
+ fun_l3_n667(x)
+ else
+ fun_l3_n335(x)
+ end
+end
+
+def fun_l2_n181(x)
+ if (x < 1)
+ fun_l3_n994(x)
+ else
+ fun_l3_n502(x)
+ end
+end
+
+def fun_l2_n182(x)
+ if (x < 1)
+ fun_l3_n528(x)
+ else
+ fun_l3_n272(x)
+ end
+end
+
+def fun_l2_n183(x)
+ if (x < 1)
+ fun_l3_n649(x)
+ else
+ fun_l3_n200(x)
+ end
+end
+
+def fun_l2_n184(x)
+ if (x < 1)
+ fun_l3_n105(x)
+ else
+ fun_l3_n897(x)
+ end
+end
+
+def fun_l2_n185(x)
+ if (x < 1)
+ fun_l3_n980(x)
+ else
+ fun_l3_n651(x)
+ end
+end
+
+def fun_l2_n186(x)
+ if (x < 1)
+ fun_l3_n835(x)
+ else
+ fun_l3_n388(x)
+ end
+end
+
+def fun_l2_n187(x)
+ if (x < 1)
+ fun_l3_n769(x)
+ else
+ fun_l3_n162(x)
+ end
+end
+
+def fun_l2_n188(x)
+ if (x < 1)
+ fun_l3_n934(x)
+ else
+ fun_l3_n874(x)
+ end
+end
+
+def fun_l2_n189(x)
+ if (x < 1)
+ fun_l3_n407(x)
+ else
+ fun_l3_n180(x)
+ end
+end
+
+def fun_l2_n190(x)
+ if (x < 1)
+ fun_l3_n594(x)
+ else
+ fun_l3_n929(x)
+ end
+end
+
+def fun_l2_n191(x)
+ if (x < 1)
+ fun_l3_n303(x)
+ else
+ fun_l3_n528(x)
+ end
+end
+
+def fun_l2_n192(x)
+ if (x < 1)
+ fun_l3_n768(x)
+ else
+ fun_l3_n226(x)
+ end
+end
+
+def fun_l2_n193(x)
+ if (x < 1)
+ fun_l3_n618(x)
+ else
+ fun_l3_n821(x)
+ end
+end
+
+def fun_l2_n194(x)
+ if (x < 1)
+ fun_l3_n953(x)
+ else
+ fun_l3_n969(x)
+ end
+end
+
+def fun_l2_n195(x)
+ if (x < 1)
+ fun_l3_n574(x)
+ else
+ fun_l3_n344(x)
+ end
+end
+
+def fun_l2_n196(x)
+ if (x < 1)
+ fun_l3_n943(x)
+ else
+ fun_l3_n304(x)
+ end
+end
+
+def fun_l2_n197(x)
+ if (x < 1)
+ fun_l3_n276(x)
+ else
+ fun_l3_n502(x)
+ end
+end
+
+def fun_l2_n198(x)
+ if (x < 1)
+ fun_l3_n597(x)
+ else
+ fun_l3_n197(x)
+ end
+end
+
+def fun_l2_n199(x)
+ if (x < 1)
+ fun_l3_n517(x)
+ else
+ fun_l3_n34(x)
+ end
+end
+
+def fun_l2_n200(x)
+ if (x < 1)
+ fun_l3_n980(x)
+ else
+ fun_l3_n672(x)
+ end
+end
+
+def fun_l2_n201(x)
+ if (x < 1)
+ fun_l3_n510(x)
+ else
+ fun_l3_n804(x)
+ end
+end
+
+def fun_l2_n202(x)
+ if (x < 1)
+ fun_l3_n735(x)
+ else
+ fun_l3_n367(x)
+ end
+end
+
+def fun_l2_n203(x)
+ if (x < 1)
+ fun_l3_n546(x)
+ else
+ fun_l3_n502(x)
+ end
+end
+
+def fun_l2_n204(x)
+ if (x < 1)
+ fun_l3_n189(x)
+ else
+ fun_l3_n639(x)
+ end
+end
+
+def fun_l2_n205(x)
+ if (x < 1)
+ fun_l3_n396(x)
+ else
+ fun_l3_n862(x)
+ end
+end
+
+def fun_l2_n206(x)
+ if (x < 1)
+ fun_l3_n679(x)
+ else
+ fun_l3_n881(x)
+ end
+end
+
+def fun_l2_n207(x)
+ if (x < 1)
+ fun_l3_n342(x)
+ else
+ fun_l3_n522(x)
+ end
+end
+
+def fun_l2_n208(x)
+ if (x < 1)
+ fun_l3_n173(x)
+ else
+ fun_l3_n323(x)
+ end
+end
+
+def fun_l2_n209(x)
+ if (x < 1)
+ fun_l3_n693(x)
+ else
+ fun_l3_n160(x)
+ end
+end
+
+def fun_l2_n210(x)
+ if (x < 1)
+ fun_l3_n827(x)
+ else
+ fun_l3_n580(x)
+ end
+end
+
+def fun_l2_n211(x)
+ if (x < 1)
+ fun_l3_n213(x)
+ else
+ fun_l3_n100(x)
+ end
+end
+
+def fun_l2_n212(x)
+ if (x < 1)
+ fun_l3_n915(x)
+ else
+ fun_l3_n531(x)
+ end
+end
+
+def fun_l2_n213(x)
+ if (x < 1)
+ fun_l3_n260(x)
+ else
+ fun_l3_n279(x)
+ end
+end
+
+def fun_l2_n214(x)
+ if (x < 1)
+ fun_l3_n468(x)
+ else
+ fun_l3_n257(x)
+ end
+end
+
+def fun_l2_n215(x)
+ if (x < 1)
+ fun_l3_n990(x)
+ else
+ fun_l3_n740(x)
+ end
+end
+
+def fun_l2_n216(x)
+ if (x < 1)
+ fun_l3_n291(x)
+ else
+ fun_l3_n625(x)
+ end
+end
+
+def fun_l2_n217(x)
+ if (x < 1)
+ fun_l3_n493(x)
+ else
+ fun_l3_n726(x)
+ end
+end
+
+def fun_l2_n218(x)
+ if (x < 1)
+ fun_l3_n714(x)
+ else
+ fun_l3_n793(x)
+ end
+end
+
+def fun_l2_n219(x)
+ if (x < 1)
+ fun_l3_n683(x)
+ else
+ fun_l3_n715(x)
+ end
+end
+
+def fun_l2_n220(x)
+ if (x < 1)
+ fun_l3_n249(x)
+ else
+ fun_l3_n266(x)
+ end
+end
+
+def fun_l2_n221(x)
+ if (x < 1)
+ fun_l3_n324(x)
+ else
+ fun_l3_n22(x)
+ end
+end
+
+def fun_l2_n222(x)
+ if (x < 1)
+ fun_l3_n978(x)
+ else
+ fun_l3_n885(x)
+ end
+end
+
+def fun_l2_n223(x)
+ if (x < 1)
+ fun_l3_n821(x)
+ else
+ fun_l3_n412(x)
+ end
+end
+
+def fun_l2_n224(x)
+ if (x < 1)
+ fun_l3_n636(x)
+ else
+ fun_l3_n641(x)
+ end
+end
+
+def fun_l2_n225(x)
+ if (x < 1)
+ fun_l3_n971(x)
+ else
+ fun_l3_n288(x)
+ end
+end
+
+def fun_l2_n226(x)
+ if (x < 1)
+ fun_l3_n429(x)
+ else
+ fun_l3_n323(x)
+ end
+end
+
+def fun_l2_n227(x)
+ if (x < 1)
+ fun_l3_n909(x)
+ else
+ fun_l3_n267(x)
+ end
+end
+
+def fun_l2_n228(x)
+ if (x < 1)
+ fun_l3_n437(x)
+ else
+ fun_l3_n985(x)
+ end
+end
+
+def fun_l2_n229(x)
+ if (x < 1)
+ fun_l3_n131(x)
+ else
+ fun_l3_n298(x)
+ end
+end
+
+def fun_l2_n230(x)
+ if (x < 1)
+ fun_l3_n865(x)
+ else
+ fun_l3_n288(x)
+ end
+end
+
+def fun_l2_n231(x)
+ if (x < 1)
+ fun_l3_n772(x)
+ else
+ fun_l3_n531(x)
+ end
+end
+
+def fun_l2_n232(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n422(x)
+ end
+end
+
+def fun_l2_n233(x)
+ if (x < 1)
+ fun_l3_n82(x)
+ else
+ fun_l3_n32(x)
+ end
+end
+
+def fun_l2_n234(x)
+ if (x < 1)
+ fun_l3_n25(x)
+ else
+ fun_l3_n518(x)
+ end
+end
+
+def fun_l2_n235(x)
+ if (x < 1)
+ fun_l3_n313(x)
+ else
+ fun_l3_n179(x)
+ end
+end
+
+def fun_l2_n236(x)
+ if (x < 1)
+ fun_l3_n819(x)
+ else
+ fun_l3_n586(x)
+ end
+end
+
+def fun_l2_n237(x)
+ if (x < 1)
+ fun_l3_n398(x)
+ else
+ fun_l3_n921(x)
+ end
+end
+
+def fun_l2_n238(x)
+ if (x < 1)
+ fun_l3_n667(x)
+ else
+ fun_l3_n795(x)
+ end
+end
+
+def fun_l2_n239(x)
+ if (x < 1)
+ fun_l3_n862(x)
+ else
+ fun_l3_n222(x)
+ end
+end
+
+def fun_l2_n240(x)
+ if (x < 1)
+ fun_l3_n968(x)
+ else
+ fun_l3_n320(x)
+ end
+end
+
+def fun_l2_n241(x)
+ if (x < 1)
+ fun_l3_n559(x)
+ else
+ fun_l3_n50(x)
+ end
+end
+
+def fun_l2_n242(x)
+ if (x < 1)
+ fun_l3_n647(x)
+ else
+ fun_l3_n232(x)
+ end
+end
+
+def fun_l2_n243(x)
+ if (x < 1)
+ fun_l3_n425(x)
+ else
+ fun_l3_n815(x)
+ end
+end
+
+def fun_l2_n244(x)
+ if (x < 1)
+ fun_l3_n752(x)
+ else
+ fun_l3_n690(x)
+ end
+end
+
+def fun_l2_n245(x)
+ if (x < 1)
+ fun_l3_n382(x)
+ else
+ fun_l3_n817(x)
+ end
+end
+
+def fun_l2_n246(x)
+ if (x < 1)
+ fun_l3_n880(x)
+ else
+ fun_l3_n380(x)
+ end
+end
+
+def fun_l2_n247(x)
+ if (x < 1)
+ fun_l3_n444(x)
+ else
+ fun_l3_n75(x)
+ end
+end
+
+def fun_l2_n248(x)
+ if (x < 1)
+ fun_l3_n368(x)
+ else
+ fun_l3_n314(x)
+ end
+end
+
+def fun_l2_n249(x)
+ if (x < 1)
+ fun_l3_n131(x)
+ else
+ fun_l3_n398(x)
+ end
+end
+
+def fun_l2_n250(x)
+ if (x < 1)
+ fun_l3_n376(x)
+ else
+ fun_l3_n449(x)
+ end
+end
+
+def fun_l2_n251(x)
+ if (x < 1)
+ fun_l3_n404(x)
+ else
+ fun_l3_n301(x)
+ end
+end
+
+def fun_l2_n252(x)
+ if (x < 1)
+ fun_l3_n274(x)
+ else
+ fun_l3_n430(x)
+ end
+end
+
+def fun_l2_n253(x)
+ if (x < 1)
+ fun_l3_n734(x)
+ else
+ fun_l3_n255(x)
+ end
+end
+
+def fun_l2_n254(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n944(x)
+ end
+end
+
+def fun_l2_n255(x)
+ if (x < 1)
+ fun_l3_n978(x)
+ else
+ fun_l3_n898(x)
+ end
+end
+
+def fun_l2_n256(x)
+ if (x < 1)
+ fun_l3_n175(x)
+ else
+ fun_l3_n477(x)
+ end
+end
+
+def fun_l2_n257(x)
+ if (x < 1)
+ fun_l3_n84(x)
+ else
+ fun_l3_n772(x)
+ end
+end
+
+def fun_l2_n258(x)
+ if (x < 1)
+ fun_l3_n605(x)
+ else
+ fun_l3_n144(x)
+ end
+end
+
+def fun_l2_n259(x)
+ if (x < 1)
+ fun_l3_n51(x)
+ else
+ fun_l3_n542(x)
+ end
+end
+
+def fun_l2_n260(x)
+ if (x < 1)
+ fun_l3_n940(x)
+ else
+ fun_l3_n316(x)
+ end
+end
+
+def fun_l2_n261(x)
+ if (x < 1)
+ fun_l3_n702(x)
+ else
+ fun_l3_n197(x)
+ end
+end
+
+def fun_l2_n262(x)
+ if (x < 1)
+ fun_l3_n164(x)
+ else
+ fun_l3_n21(x)
+ end
+end
+
+def fun_l2_n263(x)
+ if (x < 1)
+ fun_l3_n432(x)
+ else
+ fun_l3_n496(x)
+ end
+end
+
+def fun_l2_n264(x)
+ if (x < 1)
+ fun_l3_n265(x)
+ else
+ fun_l3_n40(x)
+ end
+end
+
+def fun_l2_n265(x)
+ if (x < 1)
+ fun_l3_n951(x)
+ else
+ fun_l3_n723(x)
+ end
+end
+
+def fun_l2_n266(x)
+ if (x < 1)
+ fun_l3_n279(x)
+ else
+ fun_l3_n167(x)
+ end
+end
+
+def fun_l2_n267(x)
+ if (x < 1)
+ fun_l3_n51(x)
+ else
+ fun_l3_n283(x)
+ end
+end
+
+def fun_l2_n268(x)
+ if (x < 1)
+ fun_l3_n389(x)
+ else
+ fun_l3_n264(x)
+ end
+end
+
+def fun_l2_n269(x)
+ if (x < 1)
+ fun_l3_n68(x)
+ else
+ fun_l3_n484(x)
+ end
+end
+
+def fun_l2_n270(x)
+ if (x < 1)
+ fun_l3_n435(x)
+ else
+ fun_l3_n204(x)
+ end
+end
+
+def fun_l2_n271(x)
+ if (x < 1)
+ fun_l3_n717(x)
+ else
+ fun_l3_n763(x)
+ end
+end
+
+def fun_l2_n272(x)
+ if (x < 1)
+ fun_l3_n901(x)
+ else
+ fun_l3_n332(x)
+ end
+end
+
+def fun_l2_n273(x)
+ if (x < 1)
+ fun_l3_n358(x)
+ else
+ fun_l3_n608(x)
+ end
+end
+
+def fun_l2_n274(x)
+ if (x < 1)
+ fun_l3_n885(x)
+ else
+ fun_l3_n490(x)
+ end
+end
+
+def fun_l2_n275(x)
+ if (x < 1)
+ fun_l3_n82(x)
+ else
+ fun_l3_n87(x)
+ end
+end
+
+def fun_l2_n276(x)
+ if (x < 1)
+ fun_l3_n698(x)
+ else
+ fun_l3_n846(x)
+ end
+end
+
+def fun_l2_n277(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n457(x)
+ end
+end
+
+def fun_l2_n278(x)
+ if (x < 1)
+ fun_l3_n925(x)
+ else
+ fun_l3_n674(x)
+ end
+end
+
+def fun_l2_n279(x)
+ if (x < 1)
+ fun_l3_n797(x)
+ else
+ fun_l3_n315(x)
+ end
+end
+
+def fun_l2_n280(x)
+ if (x < 1)
+ fun_l3_n73(x)
+ else
+ fun_l3_n2(x)
+ end
+end
+
+def fun_l2_n281(x)
+ if (x < 1)
+ fun_l3_n301(x)
+ else
+ fun_l3_n315(x)
+ end
+end
+
+def fun_l2_n282(x)
+ if (x < 1)
+ fun_l3_n473(x)
+ else
+ fun_l3_n639(x)
+ end
+end
+
+def fun_l2_n283(x)
+ if (x < 1)
+ fun_l3_n812(x)
+ else
+ fun_l3_n241(x)
+ end
+end
+
+def fun_l2_n284(x)
+ if (x < 1)
+ fun_l3_n0(x)
+ else
+ fun_l3_n445(x)
+ end
+end
+
+def fun_l2_n285(x)
+ if (x < 1)
+ fun_l3_n587(x)
+ else
+ fun_l3_n806(x)
+ end
+end
+
+def fun_l2_n286(x)
+ if (x < 1)
+ fun_l3_n169(x)
+ else
+ fun_l3_n546(x)
+ end
+end
+
+def fun_l2_n287(x)
+ if (x < 1)
+ fun_l3_n623(x)
+ else
+ fun_l3_n677(x)
+ end
+end
+
+def fun_l2_n288(x)
+ if (x < 1)
+ fun_l3_n804(x)
+ else
+ fun_l3_n80(x)
+ end
+end
+
+def fun_l2_n289(x)
+ if (x < 1)
+ fun_l3_n812(x)
+ else
+ fun_l3_n197(x)
+ end
+end
+
+def fun_l2_n290(x)
+ if (x < 1)
+ fun_l3_n551(x)
+ else
+ fun_l3_n896(x)
+ end
+end
+
+def fun_l2_n291(x)
+ if (x < 1)
+ fun_l3_n686(x)
+ else
+ fun_l3_n884(x)
+ end
+end
+
+def fun_l2_n292(x)
+ if (x < 1)
+ fun_l3_n427(x)
+ else
+ fun_l3_n251(x)
+ end
+end
+
+def fun_l2_n293(x)
+ if (x < 1)
+ fun_l3_n375(x)
+ else
+ fun_l3_n309(x)
+ end
+end
+
+def fun_l2_n294(x)
+ if (x < 1)
+ fun_l3_n371(x)
+ else
+ fun_l3_n184(x)
+ end
+end
+
+def fun_l2_n295(x)
+ if (x < 1)
+ fun_l3_n332(x)
+ else
+ fun_l3_n250(x)
+ end
+end
+
+def fun_l2_n296(x)
+ if (x < 1)
+ fun_l3_n333(x)
+ else
+ fun_l3_n254(x)
+ end
+end
+
+def fun_l2_n297(x)
+ if (x < 1)
+ fun_l3_n24(x)
+ else
+ fun_l3_n528(x)
+ end
+end
+
+def fun_l2_n298(x)
+ if (x < 1)
+ fun_l3_n96(x)
+ else
+ fun_l3_n653(x)
+ end
+end
+
+def fun_l2_n299(x)
+ if (x < 1)
+ fun_l3_n920(x)
+ else
+ fun_l3_n475(x)
+ end
+end
+
+def fun_l2_n300(x)
+ if (x < 1)
+ fun_l3_n337(x)
+ else
+ fun_l3_n378(x)
+ end
+end
+
+def fun_l2_n301(x)
+ if (x < 1)
+ fun_l3_n778(x)
+ else
+ fun_l3_n216(x)
+ end
+end
+
+def fun_l2_n302(x)
+ if (x < 1)
+ fun_l3_n366(x)
+ else
+ fun_l3_n562(x)
+ end
+end
+
+def fun_l2_n303(x)
+ if (x < 1)
+ fun_l3_n656(x)
+ else
+ fun_l3_n779(x)
+ end
+end
+
+def fun_l2_n304(x)
+ if (x < 1)
+ fun_l3_n526(x)
+ else
+ fun_l3_n783(x)
+ end
+end
+
+def fun_l2_n305(x)
+ if (x < 1)
+ fun_l3_n500(x)
+ else
+ fun_l3_n744(x)
+ end
+end
+
+def fun_l2_n306(x)
+ if (x < 1)
+ fun_l3_n953(x)
+ else
+ fun_l3_n394(x)
+ end
+end
+
+def fun_l2_n307(x)
+ if (x < 1)
+ fun_l3_n385(x)
+ else
+ fun_l3_n937(x)
+ end
+end
+
+def fun_l2_n308(x)
+ if (x < 1)
+ fun_l3_n742(x)
+ else
+ fun_l3_n984(x)
+ end
+end
+
+def fun_l2_n309(x)
+ if (x < 1)
+ fun_l3_n388(x)
+ else
+ fun_l3_n704(x)
+ end
+end
+
+def fun_l2_n310(x)
+ if (x < 1)
+ fun_l3_n252(x)
+ else
+ fun_l3_n585(x)
+ end
+end
+
+def fun_l2_n311(x)
+ if (x < 1)
+ fun_l3_n121(x)
+ else
+ fun_l3_n815(x)
+ end
+end
+
+def fun_l2_n312(x)
+ if (x < 1)
+ fun_l3_n657(x)
+ else
+ fun_l3_n338(x)
+ end
+end
+
+def fun_l2_n313(x)
+ if (x < 1)
+ fun_l3_n115(x)
+ else
+ fun_l3_n748(x)
+ end
+end
+
+def fun_l2_n314(x)
+ if (x < 1)
+ fun_l3_n237(x)
+ else
+ fun_l3_n319(x)
+ end
+end
+
+def fun_l2_n315(x)
+ if (x < 1)
+ fun_l3_n684(x)
+ else
+ fun_l3_n428(x)
+ end
+end
+
+def fun_l2_n316(x)
+ if (x < 1)
+ fun_l3_n416(x)
+ else
+ fun_l3_n499(x)
+ end
+end
+
+def fun_l2_n317(x)
+ if (x < 1)
+ fun_l3_n305(x)
+ else
+ fun_l3_n888(x)
+ end
+end
+
+def fun_l2_n318(x)
+ if (x < 1)
+ fun_l3_n506(x)
+ else
+ fun_l3_n579(x)
+ end
+end
+
+def fun_l2_n319(x)
+ if (x < 1)
+ fun_l3_n324(x)
+ else
+ fun_l3_n459(x)
+ end
+end
+
+def fun_l2_n320(x)
+ if (x < 1)
+ fun_l3_n278(x)
+ else
+ fun_l3_n89(x)
+ end
+end
+
+def fun_l2_n321(x)
+ if (x < 1)
+ fun_l3_n319(x)
+ else
+ fun_l3_n903(x)
+ end
+end
+
+def fun_l2_n322(x)
+ if (x < 1)
+ fun_l3_n96(x)
+ else
+ fun_l3_n334(x)
+ end
+end
+
+def fun_l2_n323(x)
+ if (x < 1)
+ fun_l3_n913(x)
+ else
+ fun_l3_n309(x)
+ end
+end
+
+def fun_l2_n324(x)
+ if (x < 1)
+ fun_l3_n186(x)
+ else
+ fun_l3_n453(x)
+ end
+end
+
+def fun_l2_n325(x)
+ if (x < 1)
+ fun_l3_n223(x)
+ else
+ fun_l3_n761(x)
+ end
+end
+
+def fun_l2_n326(x)
+ if (x < 1)
+ fun_l3_n757(x)
+ else
+ fun_l3_n700(x)
+ end
+end
+
+def fun_l2_n327(x)
+ if (x < 1)
+ fun_l3_n316(x)
+ else
+ fun_l3_n3(x)
+ end
+end
+
+def fun_l2_n328(x)
+ if (x < 1)
+ fun_l3_n680(x)
+ else
+ fun_l3_n275(x)
+ end
+end
+
+def fun_l2_n329(x)
+ if (x < 1)
+ fun_l3_n731(x)
+ else
+ fun_l3_n971(x)
+ end
+end
+
+def fun_l2_n330(x)
+ if (x < 1)
+ fun_l3_n672(x)
+ else
+ fun_l3_n389(x)
+ end
+end
+
+def fun_l2_n331(x)
+ if (x < 1)
+ fun_l3_n947(x)
+ else
+ fun_l3_n778(x)
+ end
+end
+
+def fun_l2_n332(x)
+ if (x < 1)
+ fun_l3_n23(x)
+ else
+ fun_l3_n478(x)
+ end
+end
+
+def fun_l2_n333(x)
+ if (x < 1)
+ fun_l3_n778(x)
+ else
+ fun_l3_n894(x)
+ end
+end
+
+def fun_l2_n334(x)
+ if (x < 1)
+ fun_l3_n198(x)
+ else
+ fun_l3_n830(x)
+ end
+end
+
+def fun_l2_n335(x)
+ if (x < 1)
+ fun_l3_n874(x)
+ else
+ fun_l3_n861(x)
+ end
+end
+
+def fun_l2_n336(x)
+ if (x < 1)
+ fun_l3_n66(x)
+ else
+ fun_l3_n47(x)
+ end
+end
+
+def fun_l2_n337(x)
+ if (x < 1)
+ fun_l3_n65(x)
+ else
+ fun_l3_n849(x)
+ end
+end
+
+def fun_l2_n338(x)
+ if (x < 1)
+ fun_l3_n122(x)
+ else
+ fun_l3_n891(x)
+ end
+end
+
+def fun_l2_n339(x)
+ if (x < 1)
+ fun_l3_n377(x)
+ else
+ fun_l3_n862(x)
+ end
+end
+
+def fun_l2_n340(x)
+ if (x < 1)
+ fun_l3_n278(x)
+ else
+ fun_l3_n495(x)
+ end
+end
+
+def fun_l2_n341(x)
+ if (x < 1)
+ fun_l3_n396(x)
+ else
+ fun_l3_n842(x)
+ end
+end
+
+def fun_l2_n342(x)
+ if (x < 1)
+ fun_l3_n971(x)
+ else
+ fun_l3_n296(x)
+ end
+end
+
+def fun_l2_n343(x)
+ if (x < 1)
+ fun_l3_n137(x)
+ else
+ fun_l3_n815(x)
+ end
+end
+
+def fun_l2_n344(x)
+ if (x < 1)
+ fun_l3_n910(x)
+ else
+ fun_l3_n515(x)
+ end
+end
+
+def fun_l2_n345(x)
+ if (x < 1)
+ fun_l3_n415(x)
+ else
+ fun_l3_n766(x)
+ end
+end
+
+def fun_l2_n346(x)
+ if (x < 1)
+ fun_l3_n816(x)
+ else
+ fun_l3_n169(x)
+ end
+end
+
+def fun_l2_n347(x)
+ if (x < 1)
+ fun_l3_n223(x)
+ else
+ fun_l3_n776(x)
+ end
+end
+
+def fun_l2_n348(x)
+ if (x < 1)
+ fun_l3_n316(x)
+ else
+ fun_l3_n497(x)
+ end
+end
+
+def fun_l2_n349(x)
+ if (x < 1)
+ fun_l3_n116(x)
+ else
+ fun_l3_n536(x)
+ end
+end
+
+def fun_l2_n350(x)
+ if (x < 1)
+ fun_l3_n252(x)
+ else
+ fun_l3_n981(x)
+ end
+end
+
+def fun_l2_n351(x)
+ if (x < 1)
+ fun_l3_n783(x)
+ else
+ fun_l3_n596(x)
+ end
+end
+
+def fun_l2_n352(x)
+ if (x < 1)
+ fun_l3_n72(x)
+ else
+ fun_l3_n978(x)
+ end
+end
+
+def fun_l2_n353(x)
+ if (x < 1)
+ fun_l3_n910(x)
+ else
+ fun_l3_n493(x)
+ end
+end
+
+def fun_l2_n354(x)
+ if (x < 1)
+ fun_l3_n671(x)
+ else
+ fun_l3_n297(x)
+ end
+end
+
+def fun_l2_n355(x)
+ if (x < 1)
+ fun_l3_n820(x)
+ else
+ fun_l3_n456(x)
+ end
+end
+
+def fun_l2_n356(x)
+ if (x < 1)
+ fun_l3_n23(x)
+ else
+ fun_l3_n760(x)
+ end
+end
+
+def fun_l2_n357(x)
+ if (x < 1)
+ fun_l3_n676(x)
+ else
+ fun_l3_n531(x)
+ end
+end
+
+def fun_l2_n358(x)
+ if (x < 1)
+ fun_l3_n849(x)
+ else
+ fun_l3_n592(x)
+ end
+end
+
+def fun_l2_n359(x)
+ if (x < 1)
+ fun_l3_n492(x)
+ else
+ fun_l3_n845(x)
+ end
+end
+
+def fun_l2_n360(x)
+ if (x < 1)
+ fun_l3_n58(x)
+ else
+ fun_l3_n896(x)
+ end
+end
+
+def fun_l2_n361(x)
+ if (x < 1)
+ fun_l3_n427(x)
+ else
+ fun_l3_n434(x)
+ end
+end
+
+def fun_l2_n362(x)
+ if (x < 1)
+ fun_l3_n129(x)
+ else
+ fun_l3_n582(x)
+ end
+end
+
+def fun_l2_n363(x)
+ if (x < 1)
+ fun_l3_n901(x)
+ else
+ fun_l3_n405(x)
+ end
+end
+
+def fun_l2_n364(x)
+ if (x < 1)
+ fun_l3_n577(x)
+ else
+ fun_l3_n550(x)
+ end
+end
+
+def fun_l2_n365(x)
+ if (x < 1)
+ fun_l3_n717(x)
+ else
+ fun_l3_n660(x)
+ end
+end
+
+def fun_l2_n366(x)
+ if (x < 1)
+ fun_l3_n605(x)
+ else
+ fun_l3_n755(x)
+ end
+end
+
+def fun_l2_n367(x)
+ if (x < 1)
+ fun_l3_n875(x)
+ else
+ fun_l3_n784(x)
+ end
+end
+
+def fun_l2_n368(x)
+ if (x < 1)
+ fun_l3_n914(x)
+ else
+ fun_l3_n351(x)
+ end
+end
+
+def fun_l2_n369(x)
+ if (x < 1)
+ fun_l3_n684(x)
+ else
+ fun_l3_n932(x)
+ end
+end
+
+def fun_l2_n370(x)
+ if (x < 1)
+ fun_l3_n796(x)
+ else
+ fun_l3_n920(x)
+ end
+end
+
+def fun_l2_n371(x)
+ if (x < 1)
+ fun_l3_n456(x)
+ else
+ fun_l3_n188(x)
+ end
+end
+
+def fun_l2_n372(x)
+ if (x < 1)
+ fun_l3_n891(x)
+ else
+ fun_l3_n905(x)
+ end
+end
+
+def fun_l2_n373(x)
+ if (x < 1)
+ fun_l3_n906(x)
+ else
+ fun_l3_n993(x)
+ end
+end
+
+def fun_l2_n374(x)
+ if (x < 1)
+ fun_l3_n811(x)
+ else
+ fun_l3_n629(x)
+ end
+end
+
+def fun_l2_n375(x)
+ if (x < 1)
+ fun_l3_n5(x)
+ else
+ fun_l3_n304(x)
+ end
+end
+
+def fun_l2_n376(x)
+ if (x < 1)
+ fun_l3_n240(x)
+ else
+ fun_l3_n859(x)
+ end
+end
+
+def fun_l2_n377(x)
+ if (x < 1)
+ fun_l3_n346(x)
+ else
+ fun_l3_n196(x)
+ end
+end
+
+def fun_l2_n378(x)
+ if (x < 1)
+ fun_l3_n918(x)
+ else
+ fun_l3_n371(x)
+ end
+end
+
+def fun_l2_n379(x)
+ if (x < 1)
+ fun_l3_n112(x)
+ else
+ fun_l3_n269(x)
+ end
+end
+
+def fun_l2_n380(x)
+ if (x < 1)
+ fun_l3_n46(x)
+ else
+ fun_l3_n397(x)
+ end
+end
+
+def fun_l2_n381(x)
+ if (x < 1)
+ fun_l3_n977(x)
+ else
+ fun_l3_n647(x)
+ end
+end
+
+def fun_l2_n382(x)
+ if (x < 1)
+ fun_l3_n788(x)
+ else
+ fun_l3_n418(x)
+ end
+end
+
+def fun_l2_n383(x)
+ if (x < 1)
+ fun_l3_n395(x)
+ else
+ fun_l3_n268(x)
+ end
+end
+
+def fun_l2_n384(x)
+ if (x < 1)
+ fun_l3_n39(x)
+ else
+ fun_l3_n950(x)
+ end
+end
+
+def fun_l2_n385(x)
+ if (x < 1)
+ fun_l3_n301(x)
+ else
+ fun_l3_n241(x)
+ end
+end
+
+def fun_l2_n386(x)
+ if (x < 1)
+ fun_l3_n936(x)
+ else
+ fun_l3_n416(x)
+ end
+end
+
+def fun_l2_n387(x)
+ if (x < 1)
+ fun_l3_n750(x)
+ else
+ fun_l3_n152(x)
+ end
+end
+
+def fun_l2_n388(x)
+ if (x < 1)
+ fun_l3_n210(x)
+ else
+ fun_l3_n824(x)
+ end
+end
+
+def fun_l2_n389(x)
+ if (x < 1)
+ fun_l3_n3(x)
+ else
+ fun_l3_n872(x)
+ end
+end
+
+def fun_l2_n390(x)
+ if (x < 1)
+ fun_l3_n944(x)
+ else
+ fun_l3_n49(x)
+ end
+end
+
+def fun_l2_n391(x)
+ if (x < 1)
+ fun_l3_n645(x)
+ else
+ fun_l3_n604(x)
+ end
+end
+
+def fun_l2_n392(x)
+ if (x < 1)
+ fun_l3_n539(x)
+ else
+ fun_l3_n374(x)
+ end
+end
+
+def fun_l2_n393(x)
+ if (x < 1)
+ fun_l3_n728(x)
+ else
+ fun_l3_n620(x)
+ end
+end
+
+def fun_l2_n394(x)
+ if (x < 1)
+ fun_l3_n538(x)
+ else
+ fun_l3_n233(x)
+ end
+end
+
+def fun_l2_n395(x)
+ if (x < 1)
+ fun_l3_n977(x)
+ else
+ fun_l3_n351(x)
+ end
+end
+
+def fun_l2_n396(x)
+ if (x < 1)
+ fun_l3_n54(x)
+ else
+ fun_l3_n958(x)
+ end
+end
+
+def fun_l2_n397(x)
+ if (x < 1)
+ fun_l3_n237(x)
+ else
+ fun_l3_n54(x)
+ end
+end
+
+def fun_l2_n398(x)
+ if (x < 1)
+ fun_l3_n846(x)
+ else
+ fun_l3_n234(x)
+ end
+end
+
+def fun_l2_n399(x)
+ if (x < 1)
+ fun_l3_n934(x)
+ else
+ fun_l3_n128(x)
+ end
+end
+
+def fun_l2_n400(x)
+ if (x < 1)
+ fun_l3_n15(x)
+ else
+ fun_l3_n288(x)
+ end
+end
+
+def fun_l2_n401(x)
+ if (x < 1)
+ fun_l3_n944(x)
+ else
+ fun_l3_n455(x)
+ end
+end
+
+def fun_l2_n402(x)
+ if (x < 1)
+ fun_l3_n962(x)
+ else
+ fun_l3_n785(x)
+ end
+end
+
+def fun_l2_n403(x)
+ if (x < 1)
+ fun_l3_n408(x)
+ else
+ fun_l3_n689(x)
+ end
+end
+
+def fun_l2_n404(x)
+ if (x < 1)
+ fun_l3_n722(x)
+ else
+ fun_l3_n704(x)
+ end
+end
+
+def fun_l2_n405(x)
+ if (x < 1)
+ fun_l3_n410(x)
+ else
+ fun_l3_n543(x)
+ end
+end
+
+def fun_l2_n406(x)
+ if (x < 1)
+ fun_l3_n953(x)
+ else
+ fun_l3_n351(x)
+ end
+end
+
+def fun_l2_n407(x)
+ if (x < 1)
+ fun_l3_n426(x)
+ else
+ fun_l3_n467(x)
+ end
+end
+
+def fun_l2_n408(x)
+ if (x < 1)
+ fun_l3_n204(x)
+ else
+ fun_l3_n163(x)
+ end
+end
+
+def fun_l2_n409(x)
+ if (x < 1)
+ fun_l3_n418(x)
+ else
+ fun_l3_n896(x)
+ end
+end
+
+def fun_l2_n410(x)
+ if (x < 1)
+ fun_l3_n915(x)
+ else
+ fun_l3_n800(x)
+ end
+end
+
+def fun_l2_n411(x)
+ if (x < 1)
+ fun_l3_n580(x)
+ else
+ fun_l3_n507(x)
+ end
+end
+
+def fun_l2_n412(x)
+ if (x < 1)
+ fun_l3_n672(x)
+ else
+ fun_l3_n938(x)
+ end
+end
+
+def fun_l2_n413(x)
+ if (x < 1)
+ fun_l3_n112(x)
+ else
+ fun_l3_n927(x)
+ end
+end
+
+def fun_l2_n414(x)
+ if (x < 1)
+ fun_l3_n801(x)
+ else
+ fun_l3_n604(x)
+ end
+end
+
+def fun_l2_n415(x)
+ if (x < 1)
+ fun_l3_n773(x)
+ else
+ fun_l3_n951(x)
+ end
+end
+
+def fun_l2_n416(x)
+ if (x < 1)
+ fun_l3_n335(x)
+ else
+ fun_l3_n157(x)
+ end
+end
+
+def fun_l2_n417(x)
+ if (x < 1)
+ fun_l3_n480(x)
+ else
+ fun_l3_n106(x)
+ end
+end
+
+def fun_l2_n418(x)
+ if (x < 1)
+ fun_l3_n523(x)
+ else
+ fun_l3_n969(x)
+ end
+end
+
+def fun_l2_n419(x)
+ if (x < 1)
+ fun_l3_n371(x)
+ else
+ fun_l3_n698(x)
+ end
+end
+
+def fun_l2_n420(x)
+ if (x < 1)
+ fun_l3_n102(x)
+ else
+ fun_l3_n47(x)
+ end
+end
+
+def fun_l2_n421(x)
+ if (x < 1)
+ fun_l3_n64(x)
+ else
+ fun_l3_n574(x)
+ end
+end
+
+def fun_l2_n422(x)
+ if (x < 1)
+ fun_l3_n208(x)
+ else
+ fun_l3_n904(x)
+ end
+end
+
+def fun_l2_n423(x)
+ if (x < 1)
+ fun_l3_n715(x)
+ else
+ fun_l3_n414(x)
+ end
+end
+
+def fun_l2_n424(x)
+ if (x < 1)
+ fun_l3_n455(x)
+ else
+ fun_l3_n219(x)
+ end
+end
+
+def fun_l2_n425(x)
+ if (x < 1)
+ fun_l3_n210(x)
+ else
+ fun_l3_n160(x)
+ end
+end
+
+def fun_l2_n426(x)
+ if (x < 1)
+ fun_l3_n729(x)
+ else
+ fun_l3_n512(x)
+ end
+end
+
+def fun_l2_n427(x)
+ if (x < 1)
+ fun_l3_n159(x)
+ else
+ fun_l3_n482(x)
+ end
+end
+
+def fun_l2_n428(x)
+ if (x < 1)
+ fun_l3_n182(x)
+ else
+ fun_l3_n687(x)
+ end
+end
+
+def fun_l2_n429(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n856(x)
+ end
+end
+
+def fun_l2_n430(x)
+ if (x < 1)
+ fun_l3_n494(x)
+ else
+ fun_l3_n365(x)
+ end
+end
+
+def fun_l2_n431(x)
+ if (x < 1)
+ fun_l3_n346(x)
+ else
+ fun_l3_n82(x)
+ end
+end
+
+def fun_l2_n432(x)
+ if (x < 1)
+ fun_l3_n311(x)
+ else
+ fun_l3_n412(x)
+ end
+end
+
+def fun_l2_n433(x)
+ if (x < 1)
+ fun_l3_n824(x)
+ else
+ fun_l3_n494(x)
+ end
+end
+
+def fun_l2_n434(x)
+ if (x < 1)
+ fun_l3_n471(x)
+ else
+ fun_l3_n174(x)
+ end
+end
+
+def fun_l2_n435(x)
+ if (x < 1)
+ fun_l3_n10(x)
+ else
+ fun_l3_n319(x)
+ end
+end
+
+def fun_l2_n436(x)
+ if (x < 1)
+ fun_l3_n223(x)
+ else
+ fun_l3_n518(x)
+ end
+end
+
+def fun_l2_n437(x)
+ if (x < 1)
+ fun_l3_n497(x)
+ else
+ fun_l3_n685(x)
+ end
+end
+
+def fun_l2_n438(x)
+ if (x < 1)
+ fun_l3_n639(x)
+ else
+ fun_l3_n695(x)
+ end
+end
+
+def fun_l2_n439(x)
+ if (x < 1)
+ fun_l3_n898(x)
+ else
+ fun_l3_n114(x)
+ end
+end
+
+def fun_l2_n440(x)
+ if (x < 1)
+ fun_l3_n12(x)
+ else
+ fun_l3_n344(x)
+ end
+end
+
+def fun_l2_n441(x)
+ if (x < 1)
+ fun_l3_n556(x)
+ else
+ fun_l3_n684(x)
+ end
+end
+
+def fun_l2_n442(x)
+ if (x < 1)
+ fun_l3_n403(x)
+ else
+ fun_l3_n528(x)
+ end
+end
+
+def fun_l2_n443(x)
+ if (x < 1)
+ fun_l3_n514(x)
+ else
+ fun_l3_n943(x)
+ end
+end
+
+def fun_l2_n444(x)
+ if (x < 1)
+ fun_l3_n218(x)
+ else
+ fun_l3_n94(x)
+ end
+end
+
+def fun_l2_n445(x)
+ if (x < 1)
+ fun_l3_n0(x)
+ else
+ fun_l3_n731(x)
+ end
+end
+
+def fun_l2_n446(x)
+ if (x < 1)
+ fun_l3_n468(x)
+ else
+ fun_l3_n197(x)
+ end
+end
+
+def fun_l2_n447(x)
+ if (x < 1)
+ fun_l3_n79(x)
+ else
+ fun_l3_n900(x)
+ end
+end
+
+def fun_l2_n448(x)
+ if (x < 1)
+ fun_l3_n706(x)
+ else
+ fun_l3_n250(x)
+ end
+end
+
+def fun_l2_n449(x)
+ if (x < 1)
+ fun_l3_n607(x)
+ else
+ fun_l3_n514(x)
+ end
+end
+
+def fun_l2_n450(x)
+ if (x < 1)
+ fun_l3_n855(x)
+ else
+ fun_l3_n223(x)
+ end
+end
+
+def fun_l2_n451(x)
+ if (x < 1)
+ fun_l3_n824(x)
+ else
+ fun_l3_n426(x)
+ end
+end
+
+def fun_l2_n452(x)
+ if (x < 1)
+ fun_l3_n137(x)
+ else
+ fun_l3_n555(x)
+ end
+end
+
+def fun_l2_n453(x)
+ if (x < 1)
+ fun_l3_n553(x)
+ else
+ fun_l3_n130(x)
+ end
+end
+
+def fun_l2_n454(x)
+ if (x < 1)
+ fun_l3_n350(x)
+ else
+ fun_l3_n545(x)
+ end
+end
+
+def fun_l2_n455(x)
+ if (x < 1)
+ fun_l3_n181(x)
+ else
+ fun_l3_n950(x)
+ end
+end
+
+def fun_l2_n456(x)
+ if (x < 1)
+ fun_l3_n581(x)
+ else
+ fun_l3_n957(x)
+ end
+end
+
+def fun_l2_n457(x)
+ if (x < 1)
+ fun_l3_n688(x)
+ else
+ fun_l3_n560(x)
+ end
+end
+
+def fun_l2_n458(x)
+ if (x < 1)
+ fun_l3_n655(x)
+ else
+ fun_l3_n323(x)
+ end
+end
+
+def fun_l2_n459(x)
+ if (x < 1)
+ fun_l3_n92(x)
+ else
+ fun_l3_n796(x)
+ end
+end
+
+def fun_l2_n460(x)
+ if (x < 1)
+ fun_l3_n68(x)
+ else
+ fun_l3_n152(x)
+ end
+end
+
+def fun_l2_n461(x)
+ if (x < 1)
+ fun_l3_n153(x)
+ else
+ fun_l3_n929(x)
+ end
+end
+
+def fun_l2_n462(x)
+ if (x < 1)
+ fun_l3_n401(x)
+ else
+ fun_l3_n248(x)
+ end
+end
+
+def fun_l2_n463(x)
+ if (x < 1)
+ fun_l3_n4(x)
+ else
+ fun_l3_n906(x)
+ end
+end
+
+def fun_l2_n464(x)
+ if (x < 1)
+ fun_l3_n313(x)
+ else
+ fun_l3_n911(x)
+ end
+end
+
+def fun_l2_n465(x)
+ if (x < 1)
+ fun_l3_n490(x)
+ else
+ fun_l3_n430(x)
+ end
+end
+
+def fun_l2_n466(x)
+ if (x < 1)
+ fun_l3_n537(x)
+ else
+ fun_l3_n470(x)
+ end
+end
+
+def fun_l2_n467(x)
+ if (x < 1)
+ fun_l3_n666(x)
+ else
+ fun_l3_n695(x)
+ end
+end
+
+def fun_l2_n468(x)
+ if (x < 1)
+ fun_l3_n126(x)
+ else
+ fun_l3_n201(x)
+ end
+end
+
+def fun_l2_n469(x)
+ if (x < 1)
+ fun_l3_n111(x)
+ else
+ fun_l3_n741(x)
+ end
+end
+
+def fun_l2_n470(x)
+ if (x < 1)
+ fun_l3_n391(x)
+ else
+ fun_l3_n83(x)
+ end
+end
+
+def fun_l2_n471(x)
+ if (x < 1)
+ fun_l3_n619(x)
+ else
+ fun_l3_n425(x)
+ end
+end
+
+def fun_l2_n472(x)
+ if (x < 1)
+ fun_l3_n637(x)
+ else
+ fun_l3_n865(x)
+ end
+end
+
+def fun_l2_n473(x)
+ if (x < 1)
+ fun_l3_n182(x)
+ else
+ fun_l3_n350(x)
+ end
+end
+
+def fun_l2_n474(x)
+ if (x < 1)
+ fun_l3_n752(x)
+ else
+ fun_l3_n815(x)
+ end
+end
+
+def fun_l2_n475(x)
+ if (x < 1)
+ fun_l3_n184(x)
+ else
+ fun_l3_n683(x)
+ end
+end
+
+def fun_l2_n476(x)
+ if (x < 1)
+ fun_l3_n324(x)
+ else
+ fun_l3_n232(x)
+ end
+end
+
+def fun_l2_n477(x)
+ if (x < 1)
+ fun_l3_n588(x)
+ else
+ fun_l3_n586(x)
+ end
+end
+
+def fun_l2_n478(x)
+ if (x < 1)
+ fun_l3_n320(x)
+ else
+ fun_l3_n599(x)
+ end
+end
+
+def fun_l2_n479(x)
+ if (x < 1)
+ fun_l3_n999(x)
+ else
+ fun_l3_n678(x)
+ end
+end
+
+def fun_l2_n480(x)
+ if (x < 1)
+ fun_l3_n523(x)
+ else
+ fun_l3_n637(x)
+ end
+end
+
+def fun_l2_n481(x)
+ if (x < 1)
+ fun_l3_n291(x)
+ else
+ fun_l3_n347(x)
+ end
+end
+
+def fun_l2_n482(x)
+ if (x < 1)
+ fun_l3_n873(x)
+ else
+ fun_l3_n435(x)
+ end
+end
+
+def fun_l2_n483(x)
+ if (x < 1)
+ fun_l3_n718(x)
+ else
+ fun_l3_n903(x)
+ end
+end
+
+def fun_l2_n484(x)
+ if (x < 1)
+ fun_l3_n188(x)
+ else
+ fun_l3_n751(x)
+ end
+end
+
+def fun_l2_n485(x)
+ if (x < 1)
+ fun_l3_n501(x)
+ else
+ fun_l3_n235(x)
+ end
+end
+
+def fun_l2_n486(x)
+ if (x < 1)
+ fun_l3_n578(x)
+ else
+ fun_l3_n224(x)
+ end
+end
+
+def fun_l2_n487(x)
+ if (x < 1)
+ fun_l3_n757(x)
+ else
+ fun_l3_n145(x)
+ end
+end
+
+def fun_l2_n488(x)
+ if (x < 1)
+ fun_l3_n17(x)
+ else
+ fun_l3_n727(x)
+ end
+end
+
+def fun_l2_n489(x)
+ if (x < 1)
+ fun_l3_n699(x)
+ else
+ fun_l3_n102(x)
+ end
+end
+
+def fun_l2_n490(x)
+ if (x < 1)
+ fun_l3_n518(x)
+ else
+ fun_l3_n15(x)
+ end
+end
+
+def fun_l2_n491(x)
+ if (x < 1)
+ fun_l3_n889(x)
+ else
+ fun_l3_n798(x)
+ end
+end
+
+def fun_l2_n492(x)
+ if (x < 1)
+ fun_l3_n715(x)
+ else
+ fun_l3_n27(x)
+ end
+end
+
+def fun_l2_n493(x)
+ if (x < 1)
+ fun_l3_n237(x)
+ else
+ fun_l3_n130(x)
+ end
+end
+
+def fun_l2_n494(x)
+ if (x < 1)
+ fun_l3_n99(x)
+ else
+ fun_l3_n223(x)
+ end
+end
+
+def fun_l2_n495(x)
+ if (x < 1)
+ fun_l3_n65(x)
+ else
+ fun_l3_n811(x)
+ end
+end
+
+def fun_l2_n496(x)
+ if (x < 1)
+ fun_l3_n457(x)
+ else
+ fun_l3_n527(x)
+ end
+end
+
+def fun_l2_n497(x)
+ if (x < 1)
+ fun_l3_n312(x)
+ else
+ fun_l3_n902(x)
+ end
+end
+
+def fun_l2_n498(x)
+ if (x < 1)
+ fun_l3_n63(x)
+ else
+ fun_l3_n948(x)
+ end
+end
+
+def fun_l2_n499(x)
+ if (x < 1)
+ fun_l3_n652(x)
+ else
+ fun_l3_n752(x)
+ end
+end
+
+def fun_l2_n500(x)
+ if (x < 1)
+ fun_l3_n583(x)
+ else
+ fun_l3_n427(x)
+ end
+end
+
+def fun_l2_n501(x)
+ if (x < 1)
+ fun_l3_n536(x)
+ else
+ fun_l3_n671(x)
+ end
+end
+
+def fun_l2_n502(x)
+ if (x < 1)
+ fun_l3_n122(x)
+ else
+ fun_l3_n170(x)
+ end
+end
+
+def fun_l2_n503(x)
+ if (x < 1)
+ fun_l3_n280(x)
+ else
+ fun_l3_n390(x)
+ end
+end
+
+def fun_l2_n504(x)
+ if (x < 1)
+ fun_l3_n427(x)
+ else
+ fun_l3_n267(x)
+ end
+end
+
+def fun_l2_n505(x)
+ if (x < 1)
+ fun_l3_n241(x)
+ else
+ fun_l3_n345(x)
+ end
+end
+
+def fun_l2_n506(x)
+ if (x < 1)
+ fun_l3_n960(x)
+ else
+ fun_l3_n537(x)
+ end
+end
+
+def fun_l2_n507(x)
+ if (x < 1)
+ fun_l3_n947(x)
+ else
+ fun_l3_n3(x)
+ end
+end
+
+def fun_l2_n508(x)
+ if (x < 1)
+ fun_l3_n974(x)
+ else
+ fun_l3_n597(x)
+ end
+end
+
+def fun_l2_n509(x)
+ if (x < 1)
+ fun_l3_n978(x)
+ else
+ fun_l3_n70(x)
+ end
+end
+
+def fun_l2_n510(x)
+ if (x < 1)
+ fun_l3_n855(x)
+ else
+ fun_l3_n259(x)
+ end
+end
+
+def fun_l2_n511(x)
+ if (x < 1)
+ fun_l3_n987(x)
+ else
+ fun_l3_n182(x)
+ end
+end
+
+def fun_l2_n512(x)
+ if (x < 1)
+ fun_l3_n787(x)
+ else
+ fun_l3_n656(x)
+ end
+end
+
+def fun_l2_n513(x)
+ if (x < 1)
+ fun_l3_n348(x)
+ else
+ fun_l3_n242(x)
+ end
+end
+
+def fun_l2_n514(x)
+ if (x < 1)
+ fun_l3_n530(x)
+ else
+ fun_l3_n718(x)
+ end
+end
+
+def fun_l2_n515(x)
+ if (x < 1)
+ fun_l3_n840(x)
+ else
+ fun_l3_n302(x)
+ end
+end
+
+def fun_l2_n516(x)
+ if (x < 1)
+ fun_l3_n678(x)
+ else
+ fun_l3_n732(x)
+ end
+end
+
+def fun_l2_n517(x)
+ if (x < 1)
+ fun_l3_n160(x)
+ else
+ fun_l3_n344(x)
+ end
+end
+
+def fun_l2_n518(x)
+ if (x < 1)
+ fun_l3_n518(x)
+ else
+ fun_l3_n830(x)
+ end
+end
+
+def fun_l2_n519(x)
+ if (x < 1)
+ fun_l3_n595(x)
+ else
+ fun_l3_n95(x)
+ end
+end
+
+def fun_l2_n520(x)
+ if (x < 1)
+ fun_l3_n939(x)
+ else
+ fun_l3_n954(x)
+ end
+end
+
+def fun_l2_n521(x)
+ if (x < 1)
+ fun_l3_n931(x)
+ else
+ fun_l3_n686(x)
+ end
+end
+
+def fun_l2_n522(x)
+ if (x < 1)
+ fun_l3_n117(x)
+ else
+ fun_l3_n501(x)
+ end
+end
+
+def fun_l2_n523(x)
+ if (x < 1)
+ fun_l3_n727(x)
+ else
+ fun_l3_n712(x)
+ end
+end
+
+def fun_l2_n524(x)
+ if (x < 1)
+ fun_l3_n152(x)
+ else
+ fun_l3_n453(x)
+ end
+end
+
+def fun_l2_n525(x)
+ if (x < 1)
+ fun_l3_n375(x)
+ else
+ fun_l3_n186(x)
+ end
+end
+
+def fun_l2_n526(x)
+ if (x < 1)
+ fun_l3_n835(x)
+ else
+ fun_l3_n465(x)
+ end
+end
+
+def fun_l2_n527(x)
+ if (x < 1)
+ fun_l3_n411(x)
+ else
+ fun_l3_n208(x)
+ end
+end
+
+def fun_l2_n528(x)
+ if (x < 1)
+ fun_l3_n696(x)
+ else
+ fun_l3_n537(x)
+ end
+end
+
+def fun_l2_n529(x)
+ if (x < 1)
+ fun_l3_n606(x)
+ else
+ fun_l3_n682(x)
+ end
+end
+
+def fun_l2_n530(x)
+ if (x < 1)
+ fun_l3_n920(x)
+ else
+ fun_l3_n592(x)
+ end
+end
+
+def fun_l2_n531(x)
+ if (x < 1)
+ fun_l3_n201(x)
+ else
+ fun_l3_n27(x)
+ end
+end
+
+def fun_l2_n532(x)
+ if (x < 1)
+ fun_l3_n643(x)
+ else
+ fun_l3_n642(x)
+ end
+end
+
+def fun_l2_n533(x)
+ if (x < 1)
+ fun_l3_n92(x)
+ else
+ fun_l3_n576(x)
+ end
+end
+
+def fun_l2_n534(x)
+ if (x < 1)
+ fun_l3_n135(x)
+ else
+ fun_l3_n738(x)
+ end
+end
+
+def fun_l2_n535(x)
+ if (x < 1)
+ fun_l3_n706(x)
+ else
+ fun_l3_n810(x)
+ end
+end
+
+def fun_l2_n536(x)
+ if (x < 1)
+ fun_l3_n922(x)
+ else
+ fun_l3_n456(x)
+ end
+end
+
+def fun_l2_n537(x)
+ if (x < 1)
+ fun_l3_n511(x)
+ else
+ fun_l3_n279(x)
+ end
+end
+
+def fun_l2_n538(x)
+ if (x < 1)
+ fun_l3_n541(x)
+ else
+ fun_l3_n826(x)
+ end
+end
+
+def fun_l2_n539(x)
+ if (x < 1)
+ fun_l3_n7(x)
+ else
+ fun_l3_n362(x)
+ end
+end
+
+def fun_l2_n540(x)
+ if (x < 1)
+ fun_l3_n132(x)
+ else
+ fun_l3_n819(x)
+ end
+end
+
+def fun_l2_n541(x)
+ if (x < 1)
+ fun_l3_n600(x)
+ else
+ fun_l3_n155(x)
+ end
+end
+
+def fun_l2_n542(x)
+ if (x < 1)
+ fun_l3_n930(x)
+ else
+ fun_l3_n827(x)
+ end
+end
+
+def fun_l2_n543(x)
+ if (x < 1)
+ fun_l3_n974(x)
+ else
+ fun_l3_n957(x)
+ end
+end
+
+def fun_l2_n544(x)
+ if (x < 1)
+ fun_l3_n912(x)
+ else
+ fun_l3_n503(x)
+ end
+end
+
+def fun_l2_n545(x)
+ if (x < 1)
+ fun_l3_n605(x)
+ else
+ fun_l3_n966(x)
+ end
+end
+
+def fun_l2_n546(x)
+ if (x < 1)
+ fun_l3_n523(x)
+ else
+ fun_l3_n105(x)
+ end
+end
+
+def fun_l2_n547(x)
+ if (x < 1)
+ fun_l3_n352(x)
+ else
+ fun_l3_n762(x)
+ end
+end
+
+def fun_l2_n548(x)
+ if (x < 1)
+ fun_l3_n65(x)
+ else
+ fun_l3_n714(x)
+ end
+end
+
+def fun_l2_n549(x)
+ if (x < 1)
+ fun_l3_n665(x)
+ else
+ fun_l3_n799(x)
+ end
+end
+
+def fun_l2_n550(x)
+ if (x < 1)
+ fun_l3_n624(x)
+ else
+ fun_l3_n131(x)
+ end
+end
+
+def fun_l2_n551(x)
+ if (x < 1)
+ fun_l3_n53(x)
+ else
+ fun_l3_n377(x)
+ end
+end
+
+def fun_l2_n552(x)
+ if (x < 1)
+ fun_l3_n377(x)
+ else
+ fun_l3_n532(x)
+ end
+end
+
+def fun_l2_n553(x)
+ if (x < 1)
+ fun_l3_n302(x)
+ else
+ fun_l3_n593(x)
+ end
+end
+
+def fun_l2_n554(x)
+ if (x < 1)
+ fun_l3_n573(x)
+ else
+ fun_l3_n727(x)
+ end
+end
+
+def fun_l2_n555(x)
+ if (x < 1)
+ fun_l3_n575(x)
+ else
+ fun_l3_n838(x)
+ end
+end
+
+def fun_l2_n556(x)
+ if (x < 1)
+ fun_l3_n92(x)
+ else
+ fun_l3_n137(x)
+ end
+end
+
+def fun_l2_n557(x)
+ if (x < 1)
+ fun_l3_n921(x)
+ else
+ fun_l3_n683(x)
+ end
+end
+
+def fun_l2_n558(x)
+ if (x < 1)
+ fun_l3_n987(x)
+ else
+ fun_l3_n646(x)
+ end
+end
+
+def fun_l2_n559(x)
+ if (x < 1)
+ fun_l3_n574(x)
+ else
+ fun_l3_n493(x)
+ end
+end
+
+def fun_l2_n560(x)
+ if (x < 1)
+ fun_l3_n950(x)
+ else
+ fun_l3_n139(x)
+ end
+end
+
+def fun_l2_n561(x)
+ if (x < 1)
+ fun_l3_n276(x)
+ else
+ fun_l3_n491(x)
+ end
+end
+
+def fun_l2_n562(x)
+ if (x < 1)
+ fun_l3_n226(x)
+ else
+ fun_l3_n840(x)
+ end
+end
+
+def fun_l2_n563(x)
+ if (x < 1)
+ fun_l3_n473(x)
+ else
+ fun_l3_n907(x)
+ end
+end
+
+def fun_l2_n564(x)
+ if (x < 1)
+ fun_l3_n695(x)
+ else
+ fun_l3_n951(x)
+ end
+end
+
+def fun_l2_n565(x)
+ if (x < 1)
+ fun_l3_n415(x)
+ else
+ fun_l3_n12(x)
+ end
+end
+
+def fun_l2_n566(x)
+ if (x < 1)
+ fun_l3_n32(x)
+ else
+ fun_l3_n759(x)
+ end
+end
+
+def fun_l2_n567(x)
+ if (x < 1)
+ fun_l3_n876(x)
+ else
+ fun_l3_n297(x)
+ end
+end
+
+def fun_l2_n568(x)
+ if (x < 1)
+ fun_l3_n520(x)
+ else
+ fun_l3_n713(x)
+ end
+end
+
+def fun_l2_n569(x)
+ if (x < 1)
+ fun_l3_n819(x)
+ else
+ fun_l3_n505(x)
+ end
+end
+
+def fun_l2_n570(x)
+ if (x < 1)
+ fun_l3_n661(x)
+ else
+ fun_l3_n447(x)
+ end
+end
+
+def fun_l2_n571(x)
+ if (x < 1)
+ fun_l3_n538(x)
+ else
+ fun_l3_n532(x)
+ end
+end
+
+def fun_l2_n572(x)
+ if (x < 1)
+ fun_l3_n584(x)
+ else
+ fun_l3_n304(x)
+ end
+end
+
+def fun_l2_n573(x)
+ if (x < 1)
+ fun_l3_n76(x)
+ else
+ fun_l3_n512(x)
+ end
+end
+
+def fun_l2_n574(x)
+ if (x < 1)
+ fun_l3_n22(x)
+ else
+ fun_l3_n328(x)
+ end
+end
+
+def fun_l2_n575(x)
+ if (x < 1)
+ fun_l3_n397(x)
+ else
+ fun_l3_n640(x)
+ end
+end
+
+def fun_l2_n576(x)
+ if (x < 1)
+ fun_l3_n227(x)
+ else
+ fun_l3_n236(x)
+ end
+end
+
+def fun_l2_n577(x)
+ if (x < 1)
+ fun_l3_n743(x)
+ else
+ fun_l3_n974(x)
+ end
+end
+
+def fun_l2_n578(x)
+ if (x < 1)
+ fun_l3_n970(x)
+ else
+ fun_l3_n229(x)
+ end
+end
+
+def fun_l2_n579(x)
+ if (x < 1)
+ fun_l3_n401(x)
+ else
+ fun_l3_n672(x)
+ end
+end
+
+def fun_l2_n580(x)
+ if (x < 1)
+ fun_l3_n837(x)
+ else
+ fun_l3_n804(x)
+ end
+end
+
+def fun_l2_n581(x)
+ if (x < 1)
+ fun_l3_n526(x)
+ else
+ fun_l3_n763(x)
+ end
+end
+
+def fun_l2_n582(x)
+ if (x < 1)
+ fun_l3_n2(x)
+ else
+ fun_l3_n692(x)
+ end
+end
+
+def fun_l2_n583(x)
+ if (x < 1)
+ fun_l3_n561(x)
+ else
+ fun_l3_n394(x)
+ end
+end
+
+def fun_l2_n584(x)
+ if (x < 1)
+ fun_l3_n60(x)
+ else
+ fun_l3_n682(x)
+ end
+end
+
+def fun_l2_n585(x)
+ if (x < 1)
+ fun_l3_n646(x)
+ else
+ fun_l3_n776(x)
+ end
+end
+
+def fun_l2_n586(x)
+ if (x < 1)
+ fun_l3_n466(x)
+ else
+ fun_l3_n91(x)
+ end
+end
+
+def fun_l2_n587(x)
+ if (x < 1)
+ fun_l3_n294(x)
+ else
+ fun_l3_n813(x)
+ end
+end
+
+def fun_l2_n588(x)
+ if (x < 1)
+ fun_l3_n958(x)
+ else
+ fun_l3_n64(x)
+ end
+end
+
+def fun_l2_n589(x)
+ if (x < 1)
+ fun_l3_n703(x)
+ else
+ fun_l3_n937(x)
+ end
+end
+
+def fun_l2_n590(x)
+ if (x < 1)
+ fun_l3_n1(x)
+ else
+ fun_l3_n970(x)
+ end
+end
+
+def fun_l2_n591(x)
+ if (x < 1)
+ fun_l3_n566(x)
+ else
+ fun_l3_n750(x)
+ end
+end
+
+def fun_l2_n592(x)
+ if (x < 1)
+ fun_l3_n905(x)
+ else
+ fun_l3_n840(x)
+ end
+end
+
+def fun_l2_n593(x)
+ if (x < 1)
+ fun_l3_n23(x)
+ else
+ fun_l3_n862(x)
+ end
+end
+
+def fun_l2_n594(x)
+ if (x < 1)
+ fun_l3_n739(x)
+ else
+ fun_l3_n4(x)
+ end
+end
+
+def fun_l2_n595(x)
+ if (x < 1)
+ fun_l3_n818(x)
+ else
+ fun_l3_n117(x)
+ end
+end
+
+def fun_l2_n596(x)
+ if (x < 1)
+ fun_l3_n891(x)
+ else
+ fun_l3_n599(x)
+ end
+end
+
+def fun_l2_n597(x)
+ if (x < 1)
+ fun_l3_n731(x)
+ else
+ fun_l3_n960(x)
+ end
+end
+
+def fun_l2_n598(x)
+ if (x < 1)
+ fun_l3_n323(x)
+ else
+ fun_l3_n811(x)
+ end
+end
+
+def fun_l2_n599(x)
+ if (x < 1)
+ fun_l3_n299(x)
+ else
+ fun_l3_n188(x)
+ end
+end
+
+def fun_l2_n600(x)
+ if (x < 1)
+ fun_l3_n129(x)
+ else
+ fun_l3_n730(x)
+ end
+end
+
+def fun_l2_n601(x)
+ if (x < 1)
+ fun_l3_n412(x)
+ else
+ fun_l3_n353(x)
+ end
+end
+
+def fun_l2_n602(x)
+ if (x < 1)
+ fun_l3_n658(x)
+ else
+ fun_l3_n774(x)
+ end
+end
+
+def fun_l2_n603(x)
+ if (x < 1)
+ fun_l3_n378(x)
+ else
+ fun_l3_n722(x)
+ end
+end
+
+def fun_l2_n604(x)
+ if (x < 1)
+ fun_l3_n482(x)
+ else
+ fun_l3_n949(x)
+ end
+end
+
+def fun_l2_n605(x)
+ if (x < 1)
+ fun_l3_n996(x)
+ else
+ fun_l3_n169(x)
+ end
+end
+
+def fun_l2_n606(x)
+ if (x < 1)
+ fun_l3_n653(x)
+ else
+ fun_l3_n966(x)
+ end
+end
+
+def fun_l2_n607(x)
+ if (x < 1)
+ fun_l3_n179(x)
+ else
+ fun_l3_n113(x)
+ end
+end
+
+def fun_l2_n608(x)
+ if (x < 1)
+ fun_l3_n157(x)
+ else
+ fun_l3_n692(x)
+ end
+end
+
+def fun_l2_n609(x)
+ if (x < 1)
+ fun_l3_n648(x)
+ else
+ fun_l3_n318(x)
+ end
+end
+
+def fun_l2_n610(x)
+ if (x < 1)
+ fun_l3_n979(x)
+ else
+ fun_l3_n642(x)
+ end
+end
+
+def fun_l2_n611(x)
+ if (x < 1)
+ fun_l3_n909(x)
+ else
+ fun_l3_n986(x)
+ end
+end
+
+def fun_l2_n612(x)
+ if (x < 1)
+ fun_l3_n387(x)
+ else
+ fun_l3_n586(x)
+ end
+end
+
+def fun_l2_n613(x)
+ if (x < 1)
+ fun_l3_n99(x)
+ else
+ fun_l3_n690(x)
+ end
+end
+
+def fun_l2_n614(x)
+ if (x < 1)
+ fun_l3_n485(x)
+ else
+ fun_l3_n733(x)
+ end
+end
+
+def fun_l2_n615(x)
+ if (x < 1)
+ fun_l3_n735(x)
+ else
+ fun_l3_n827(x)
+ end
+end
+
+def fun_l2_n616(x)
+ if (x < 1)
+ fun_l3_n496(x)
+ else
+ fun_l3_n912(x)
+ end
+end
+
+def fun_l2_n617(x)
+ if (x < 1)
+ fun_l3_n363(x)
+ else
+ fun_l3_n845(x)
+ end
+end
+
+def fun_l2_n618(x)
+ if (x < 1)
+ fun_l3_n891(x)
+ else
+ fun_l3_n964(x)
+ end
+end
+
+def fun_l2_n619(x)
+ if (x < 1)
+ fun_l3_n266(x)
+ else
+ fun_l3_n189(x)
+ end
+end
+
+def fun_l2_n620(x)
+ if (x < 1)
+ fun_l3_n906(x)
+ else
+ fun_l3_n218(x)
+ end
+end
+
+def fun_l2_n621(x)
+ if (x < 1)
+ fun_l3_n145(x)
+ else
+ fun_l3_n279(x)
+ end
+end
+
+def fun_l2_n622(x)
+ if (x < 1)
+ fun_l3_n797(x)
+ else
+ fun_l3_n328(x)
+ end
+end
+
+def fun_l2_n623(x)
+ if (x < 1)
+ fun_l3_n910(x)
+ else
+ fun_l3_n250(x)
+ end
+end
+
+def fun_l2_n624(x)
+ if (x < 1)
+ fun_l3_n111(x)
+ else
+ fun_l3_n884(x)
+ end
+end
+
+def fun_l2_n625(x)
+ if (x < 1)
+ fun_l3_n852(x)
+ else
+ fun_l3_n985(x)
+ end
+end
+
+def fun_l2_n626(x)
+ if (x < 1)
+ fun_l3_n163(x)
+ else
+ fun_l3_n885(x)
+ end
+end
+
+def fun_l2_n627(x)
+ if (x < 1)
+ fun_l3_n338(x)
+ else
+ fun_l3_n562(x)
+ end
+end
+
+def fun_l2_n628(x)
+ if (x < 1)
+ fun_l3_n300(x)
+ else
+ fun_l3_n245(x)
+ end
+end
+
+def fun_l2_n629(x)
+ if (x < 1)
+ fun_l3_n747(x)
+ else
+ fun_l3_n123(x)
+ end
+end
+
+def fun_l2_n630(x)
+ if (x < 1)
+ fun_l3_n42(x)
+ else
+ fun_l3_n46(x)
+ end
+end
+
+def fun_l2_n631(x)
+ if (x < 1)
+ fun_l3_n256(x)
+ else
+ fun_l3_n960(x)
+ end
+end
+
+def fun_l2_n632(x)
+ if (x < 1)
+ fun_l3_n679(x)
+ else
+ fun_l3_n393(x)
+ end
+end
+
+def fun_l2_n633(x)
+ if (x < 1)
+ fun_l3_n286(x)
+ else
+ fun_l3_n147(x)
+ end
+end
+
+def fun_l2_n634(x)
+ if (x < 1)
+ fun_l3_n62(x)
+ else
+ fun_l3_n994(x)
+ end
+end
+
+def fun_l2_n635(x)
+ if (x < 1)
+ fun_l3_n479(x)
+ else
+ fun_l3_n502(x)
+ end
+end
+
+def fun_l2_n636(x)
+ if (x < 1)
+ fun_l3_n504(x)
+ else
+ fun_l3_n557(x)
+ end
+end
+
+def fun_l2_n637(x)
+ if (x < 1)
+ fun_l3_n716(x)
+ else
+ fun_l3_n763(x)
+ end
+end
+
+def fun_l2_n638(x)
+ if (x < 1)
+ fun_l3_n972(x)
+ else
+ fun_l3_n391(x)
+ end
+end
+
+def fun_l2_n639(x)
+ if (x < 1)
+ fun_l3_n842(x)
+ else
+ fun_l3_n740(x)
+ end
+end
+
+def fun_l2_n640(x)
+ if (x < 1)
+ fun_l3_n854(x)
+ else
+ fun_l3_n52(x)
+ end
+end
+
+def fun_l2_n641(x)
+ if (x < 1)
+ fun_l3_n321(x)
+ else
+ fun_l3_n109(x)
+ end
+end
+
+def fun_l2_n642(x)
+ if (x < 1)
+ fun_l3_n868(x)
+ else
+ fun_l3_n926(x)
+ end
+end
+
+def fun_l2_n643(x)
+ if (x < 1)
+ fun_l3_n864(x)
+ else
+ fun_l3_n98(x)
+ end
+end
+
+def fun_l2_n644(x)
+ if (x < 1)
+ fun_l3_n373(x)
+ else
+ fun_l3_n105(x)
+ end
+end
+
+def fun_l2_n645(x)
+ if (x < 1)
+ fun_l3_n293(x)
+ else
+ fun_l3_n846(x)
+ end
+end
+
+def fun_l2_n646(x)
+ if (x < 1)
+ fun_l3_n24(x)
+ else
+ fun_l3_n83(x)
+ end
+end
+
+def fun_l2_n647(x)
+ if (x < 1)
+ fun_l3_n431(x)
+ else
+ fun_l3_n772(x)
+ end
+end
+
+def fun_l2_n648(x)
+ if (x < 1)
+ fun_l3_n667(x)
+ else
+ fun_l3_n108(x)
+ end
+end
+
+def fun_l2_n649(x)
+ if (x < 1)
+ fun_l3_n93(x)
+ else
+ fun_l3_n394(x)
+ end
+end
+
+def fun_l2_n650(x)
+ if (x < 1)
+ fun_l3_n176(x)
+ else
+ fun_l3_n315(x)
+ end
+end
+
+def fun_l2_n651(x)
+ if (x < 1)
+ fun_l3_n684(x)
+ else
+ fun_l3_n635(x)
+ end
+end
+
+def fun_l2_n652(x)
+ if (x < 1)
+ fun_l3_n554(x)
+ else
+ fun_l3_n88(x)
+ end
+end
+
+def fun_l2_n653(x)
+ if (x < 1)
+ fun_l3_n165(x)
+ else
+ fun_l3_n962(x)
+ end
+end
+
+def fun_l2_n654(x)
+ if (x < 1)
+ fun_l3_n631(x)
+ else
+ fun_l3_n80(x)
+ end
+end
+
+def fun_l2_n655(x)
+ if (x < 1)
+ fun_l3_n529(x)
+ else
+ fun_l3_n711(x)
+ end
+end
+
+def fun_l2_n656(x)
+ if (x < 1)
+ fun_l3_n809(x)
+ else
+ fun_l3_n44(x)
+ end
+end
+
+def fun_l2_n657(x)
+ if (x < 1)
+ fun_l3_n226(x)
+ else
+ fun_l3_n939(x)
+ end
+end
+
+def fun_l2_n658(x)
+ if (x < 1)
+ fun_l3_n355(x)
+ else
+ fun_l3_n750(x)
+ end
+end
+
+def fun_l2_n659(x)
+ if (x < 1)
+ fun_l3_n111(x)
+ else
+ fun_l3_n883(x)
+ end
+end
+
+def fun_l2_n660(x)
+ if (x < 1)
+ fun_l3_n22(x)
+ else
+ fun_l3_n544(x)
+ end
+end
+
+def fun_l2_n661(x)
+ if (x < 1)
+ fun_l3_n334(x)
+ else
+ fun_l3_n58(x)
+ end
+end
+
+def fun_l2_n662(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n647(x)
+ end
+end
+
+def fun_l2_n663(x)
+ if (x < 1)
+ fun_l3_n886(x)
+ else
+ fun_l3_n142(x)
+ end
+end
+
+def fun_l2_n664(x)
+ if (x < 1)
+ fun_l3_n713(x)
+ else
+ fun_l3_n710(x)
+ end
+end
+
+def fun_l2_n665(x)
+ if (x < 1)
+ fun_l3_n657(x)
+ else
+ fun_l3_n24(x)
+ end
+end
+
+def fun_l2_n666(x)
+ if (x < 1)
+ fun_l3_n993(x)
+ else
+ fun_l3_n741(x)
+ end
+end
+
+def fun_l2_n667(x)
+ if (x < 1)
+ fun_l3_n265(x)
+ else
+ fun_l3_n143(x)
+ end
+end
+
+def fun_l2_n668(x)
+ if (x < 1)
+ fun_l3_n725(x)
+ else
+ fun_l3_n272(x)
+ end
+end
+
+def fun_l2_n669(x)
+ if (x < 1)
+ fun_l3_n171(x)
+ else
+ fun_l3_n95(x)
+ end
+end
+
+def fun_l2_n670(x)
+ if (x < 1)
+ fun_l3_n409(x)
+ else
+ fun_l3_n774(x)
+ end
+end
+
+def fun_l2_n671(x)
+ if (x < 1)
+ fun_l3_n566(x)
+ else
+ fun_l3_n251(x)
+ end
+end
+
+def fun_l2_n672(x)
+ if (x < 1)
+ fun_l3_n914(x)
+ else
+ fun_l3_n716(x)
+ end
+end
+
+def fun_l2_n673(x)
+ if (x < 1)
+ fun_l3_n889(x)
+ else
+ fun_l3_n339(x)
+ end
+end
+
+def fun_l2_n674(x)
+ if (x < 1)
+ fun_l3_n808(x)
+ else
+ fun_l3_n858(x)
+ end
+end
+
+def fun_l2_n675(x)
+ if (x < 1)
+ fun_l3_n895(x)
+ else
+ fun_l3_n180(x)
+ end
+end
+
+def fun_l2_n676(x)
+ if (x < 1)
+ fun_l3_n674(x)
+ else
+ fun_l3_n183(x)
+ end
+end
+
+def fun_l2_n677(x)
+ if (x < 1)
+ fun_l3_n934(x)
+ else
+ fun_l3_n292(x)
+ end
+end
+
+def fun_l2_n678(x)
+ if (x < 1)
+ fun_l3_n302(x)
+ else
+ fun_l3_n511(x)
+ end
+end
+
+def fun_l2_n679(x)
+ if (x < 1)
+ fun_l3_n847(x)
+ else
+ fun_l3_n70(x)
+ end
+end
+
+def fun_l2_n680(x)
+ if (x < 1)
+ fun_l3_n200(x)
+ else
+ fun_l3_n436(x)
+ end
+end
+
+def fun_l2_n681(x)
+ if (x < 1)
+ fun_l3_n44(x)
+ else
+ fun_l3_n145(x)
+ end
+end
+
+def fun_l2_n682(x)
+ if (x < 1)
+ fun_l3_n929(x)
+ else
+ fun_l3_n605(x)
+ end
+end
+
+def fun_l2_n683(x)
+ if (x < 1)
+ fun_l3_n990(x)
+ else
+ fun_l3_n641(x)
+ end
+end
+
+def fun_l2_n684(x)
+ if (x < 1)
+ fun_l3_n679(x)
+ else
+ fun_l3_n976(x)
+ end
+end
+
+def fun_l2_n685(x)
+ if (x < 1)
+ fun_l3_n405(x)
+ else
+ fun_l3_n658(x)
+ end
+end
+
+def fun_l2_n686(x)
+ if (x < 1)
+ fun_l3_n685(x)
+ else
+ fun_l3_n379(x)
+ end
+end
+
+def fun_l2_n687(x)
+ if (x < 1)
+ fun_l3_n279(x)
+ else
+ fun_l3_n415(x)
+ end
+end
+
+def fun_l2_n688(x)
+ if (x < 1)
+ fun_l3_n234(x)
+ else
+ fun_l3_n634(x)
+ end
+end
+
+def fun_l2_n689(x)
+ if (x < 1)
+ fun_l3_n119(x)
+ else
+ fun_l3_n234(x)
+ end
+end
+
+def fun_l2_n690(x)
+ if (x < 1)
+ fun_l3_n213(x)
+ else
+ fun_l3_n102(x)
+ end
+end
+
+def fun_l2_n691(x)
+ if (x < 1)
+ fun_l3_n744(x)
+ else
+ fun_l3_n31(x)
+ end
+end
+
+def fun_l2_n692(x)
+ if (x < 1)
+ fun_l3_n29(x)
+ else
+ fun_l3_n238(x)
+ end
+end
+
+def fun_l2_n693(x)
+ if (x < 1)
+ fun_l3_n323(x)
+ else
+ fun_l3_n388(x)
+ end
+end
+
+def fun_l2_n694(x)
+ if (x < 1)
+ fun_l3_n70(x)
+ else
+ fun_l3_n356(x)
+ end
+end
+
+def fun_l2_n695(x)
+ if (x < 1)
+ fun_l3_n589(x)
+ else
+ fun_l3_n949(x)
+ end
+end
+
+def fun_l2_n696(x)
+ if (x < 1)
+ fun_l3_n328(x)
+ else
+ fun_l3_n472(x)
+ end
+end
+
+def fun_l2_n697(x)
+ if (x < 1)
+ fun_l3_n705(x)
+ else
+ fun_l3_n709(x)
+ end
+end
+
+def fun_l2_n698(x)
+ if (x < 1)
+ fun_l3_n817(x)
+ else
+ fun_l3_n927(x)
+ end
+end
+
+def fun_l2_n699(x)
+ if (x < 1)
+ fun_l3_n916(x)
+ else
+ fun_l3_n66(x)
+ end
+end
+
+def fun_l2_n700(x)
+ if (x < 1)
+ fun_l3_n461(x)
+ else
+ fun_l3_n648(x)
+ end
+end
+
+def fun_l2_n701(x)
+ if (x < 1)
+ fun_l3_n71(x)
+ else
+ fun_l3_n218(x)
+ end
+end
+
+def fun_l2_n702(x)
+ if (x < 1)
+ fun_l3_n490(x)
+ else
+ fun_l3_n706(x)
+ end
+end
+
+def fun_l2_n703(x)
+ if (x < 1)
+ fun_l3_n480(x)
+ else
+ fun_l3_n665(x)
+ end
+end
+
+def fun_l2_n704(x)
+ if (x < 1)
+ fun_l3_n965(x)
+ else
+ fun_l3_n394(x)
+ end
+end
+
+def fun_l2_n705(x)
+ if (x < 1)
+ fun_l3_n65(x)
+ else
+ fun_l3_n761(x)
+ end
+end
+
+def fun_l2_n706(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n50(x)
+ end
+end
+
+def fun_l2_n707(x)
+ if (x < 1)
+ fun_l3_n665(x)
+ else
+ fun_l3_n589(x)
+ end
+end
+
+def fun_l2_n708(x)
+ if (x < 1)
+ fun_l3_n331(x)
+ else
+ fun_l3_n299(x)
+ end
+end
+
+def fun_l2_n709(x)
+ if (x < 1)
+ fun_l3_n656(x)
+ else
+ fun_l3_n966(x)
+ end
+end
+
+def fun_l2_n710(x)
+ if (x < 1)
+ fun_l3_n610(x)
+ else
+ fun_l3_n767(x)
+ end
+end
+
+def fun_l2_n711(x)
+ if (x < 1)
+ fun_l3_n281(x)
+ else
+ fun_l3_n942(x)
+ end
+end
+
+def fun_l2_n712(x)
+ if (x < 1)
+ fun_l3_n474(x)
+ else
+ fun_l3_n373(x)
+ end
+end
+
+def fun_l2_n713(x)
+ if (x < 1)
+ fun_l3_n668(x)
+ else
+ fun_l3_n881(x)
+ end
+end
+
+def fun_l2_n714(x)
+ if (x < 1)
+ fun_l3_n112(x)
+ else
+ fun_l3_n914(x)
+ end
+end
+
+def fun_l2_n715(x)
+ if (x < 1)
+ fun_l3_n276(x)
+ else
+ fun_l3_n946(x)
+ end
+end
+
+def fun_l2_n716(x)
+ if (x < 1)
+ fun_l3_n340(x)
+ else
+ fun_l3_n474(x)
+ end
+end
+
+def fun_l2_n717(x)
+ if (x < 1)
+ fun_l3_n179(x)
+ else
+ fun_l3_n740(x)
+ end
+end
+
+def fun_l2_n718(x)
+ if (x < 1)
+ fun_l3_n830(x)
+ else
+ fun_l3_n139(x)
+ end
+end
+
+def fun_l2_n719(x)
+ if (x < 1)
+ fun_l3_n945(x)
+ else
+ fun_l3_n98(x)
+ end
+end
+
+def fun_l2_n720(x)
+ if (x < 1)
+ fun_l3_n912(x)
+ else
+ fun_l3_n457(x)
+ end
+end
+
+def fun_l2_n721(x)
+ if (x < 1)
+ fun_l3_n4(x)
+ else
+ fun_l3_n798(x)
+ end
+end
+
+def fun_l2_n722(x)
+ if (x < 1)
+ fun_l3_n438(x)
+ else
+ fun_l3_n677(x)
+ end
+end
+
+def fun_l2_n723(x)
+ if (x < 1)
+ fun_l3_n447(x)
+ else
+ fun_l3_n418(x)
+ end
+end
+
+def fun_l2_n724(x)
+ if (x < 1)
+ fun_l3_n936(x)
+ else
+ fun_l3_n572(x)
+ end
+end
+
+def fun_l2_n725(x)
+ if (x < 1)
+ fun_l3_n856(x)
+ else
+ fun_l3_n429(x)
+ end
+end
+
+def fun_l2_n726(x)
+ if (x < 1)
+ fun_l3_n747(x)
+ else
+ fun_l3_n823(x)
+ end
+end
+
+def fun_l2_n727(x)
+ if (x < 1)
+ fun_l3_n908(x)
+ else
+ fun_l3_n446(x)
+ end
+end
+
+def fun_l2_n728(x)
+ if (x < 1)
+ fun_l3_n170(x)
+ else
+ fun_l3_n546(x)
+ end
+end
+
+def fun_l2_n729(x)
+ if (x < 1)
+ fun_l3_n45(x)
+ else
+ fun_l3_n76(x)
+ end
+end
+
+def fun_l2_n730(x)
+ if (x < 1)
+ fun_l3_n688(x)
+ else
+ fun_l3_n826(x)
+ end
+end
+
+def fun_l2_n731(x)
+ if (x < 1)
+ fun_l3_n805(x)
+ else
+ fun_l3_n88(x)
+ end
+end
+
+def fun_l2_n732(x)
+ if (x < 1)
+ fun_l3_n191(x)
+ else
+ fun_l3_n395(x)
+ end
+end
+
+def fun_l2_n733(x)
+ if (x < 1)
+ fun_l3_n161(x)
+ else
+ fun_l3_n600(x)
+ end
+end
+
+def fun_l2_n734(x)
+ if (x < 1)
+ fun_l3_n586(x)
+ else
+ fun_l3_n770(x)
+ end
+end
+
+def fun_l2_n735(x)
+ if (x < 1)
+ fun_l3_n139(x)
+ else
+ fun_l3_n108(x)
+ end
+end
+
+def fun_l2_n736(x)
+ if (x < 1)
+ fun_l3_n719(x)
+ else
+ fun_l3_n210(x)
+ end
+end
+
+def fun_l2_n737(x)
+ if (x < 1)
+ fun_l3_n327(x)
+ else
+ fun_l3_n138(x)
+ end
+end
+
+def fun_l2_n738(x)
+ if (x < 1)
+ fun_l3_n755(x)
+ else
+ fun_l3_n785(x)
+ end
+end
+
+def fun_l2_n739(x)
+ if (x < 1)
+ fun_l3_n499(x)
+ else
+ fun_l3_n998(x)
+ end
+end
+
+def fun_l2_n740(x)
+ if (x < 1)
+ fun_l3_n303(x)
+ else
+ fun_l3_n646(x)
+ end
+end
+
+def fun_l2_n741(x)
+ if (x < 1)
+ fun_l3_n385(x)
+ else
+ fun_l3_n202(x)
+ end
+end
+
+def fun_l2_n742(x)
+ if (x < 1)
+ fun_l3_n290(x)
+ else
+ fun_l3_n617(x)
+ end
+end
+
+def fun_l2_n743(x)
+ if (x < 1)
+ fun_l3_n735(x)
+ else
+ fun_l3_n322(x)
+ end
+end
+
+def fun_l2_n744(x)
+ if (x < 1)
+ fun_l3_n541(x)
+ else
+ fun_l3_n841(x)
+ end
+end
+
+def fun_l2_n745(x)
+ if (x < 1)
+ fun_l3_n124(x)
+ else
+ fun_l3_n927(x)
+ end
+end
+
+def fun_l2_n746(x)
+ if (x < 1)
+ fun_l3_n909(x)
+ else
+ fun_l3_n981(x)
+ end
+end
+
+def fun_l2_n747(x)
+ if (x < 1)
+ fun_l3_n535(x)
+ else
+ fun_l3_n154(x)
+ end
+end
+
+def fun_l2_n748(x)
+ if (x < 1)
+ fun_l3_n804(x)
+ else
+ fun_l3_n837(x)
+ end
+end
+
+def fun_l2_n749(x)
+ if (x < 1)
+ fun_l3_n787(x)
+ else
+ fun_l3_n890(x)
+ end
+end
+
+def fun_l2_n750(x)
+ if (x < 1)
+ fun_l3_n273(x)
+ else
+ fun_l3_n539(x)
+ end
+end
+
+def fun_l2_n751(x)
+ if (x < 1)
+ fun_l3_n397(x)
+ else
+ fun_l3_n630(x)
+ end
+end
+
+def fun_l2_n752(x)
+ if (x < 1)
+ fun_l3_n757(x)
+ else
+ fun_l3_n294(x)
+ end
+end
+
+def fun_l2_n753(x)
+ if (x < 1)
+ fun_l3_n731(x)
+ else
+ fun_l3_n121(x)
+ end
+end
+
+def fun_l2_n754(x)
+ if (x < 1)
+ fun_l3_n391(x)
+ else
+ fun_l3_n640(x)
+ end
+end
+
+def fun_l2_n755(x)
+ if (x < 1)
+ fun_l3_n441(x)
+ else
+ fun_l3_n731(x)
+ end
+end
+
+def fun_l2_n756(x)
+ if (x < 1)
+ fun_l3_n947(x)
+ else
+ fun_l3_n175(x)
+ end
+end
+
+def fun_l2_n757(x)
+ if (x < 1)
+ fun_l3_n294(x)
+ else
+ fun_l3_n732(x)
+ end
+end
+
+def fun_l2_n758(x)
+ if (x < 1)
+ fun_l3_n862(x)
+ else
+ fun_l3_n490(x)
+ end
+end
+
+def fun_l2_n759(x)
+ if (x < 1)
+ fun_l3_n959(x)
+ else
+ fun_l3_n58(x)
+ end
+end
+
+def fun_l2_n760(x)
+ if (x < 1)
+ fun_l3_n245(x)
+ else
+ fun_l3_n201(x)
+ end
+end
+
+def fun_l2_n761(x)
+ if (x < 1)
+ fun_l3_n174(x)
+ else
+ fun_l3_n763(x)
+ end
+end
+
+def fun_l2_n762(x)
+ if (x < 1)
+ fun_l3_n276(x)
+ else
+ fun_l3_n624(x)
+ end
+end
+
+def fun_l2_n763(x)
+ if (x < 1)
+ fun_l3_n130(x)
+ else
+ fun_l3_n452(x)
+ end
+end
+
+def fun_l2_n764(x)
+ if (x < 1)
+ fun_l3_n476(x)
+ else
+ fun_l3_n519(x)
+ end
+end
+
+def fun_l2_n765(x)
+ if (x < 1)
+ fun_l3_n911(x)
+ else
+ fun_l3_n28(x)
+ end
+end
+
+def fun_l2_n766(x)
+ if (x < 1)
+ fun_l3_n290(x)
+ else
+ fun_l3_n528(x)
+ end
+end
+
+def fun_l2_n767(x)
+ if (x < 1)
+ fun_l3_n89(x)
+ else
+ fun_l3_n284(x)
+ end
+end
+
+def fun_l2_n768(x)
+ if (x < 1)
+ fun_l3_n307(x)
+ else
+ fun_l3_n832(x)
+ end
+end
+
+def fun_l2_n769(x)
+ if (x < 1)
+ fun_l3_n204(x)
+ else
+ fun_l3_n358(x)
+ end
+end
+
+def fun_l2_n770(x)
+ if (x < 1)
+ fun_l3_n380(x)
+ else
+ fun_l3_n938(x)
+ end
+end
+
+def fun_l2_n771(x)
+ if (x < 1)
+ fun_l3_n245(x)
+ else
+ fun_l3_n156(x)
+ end
+end
+
+def fun_l2_n772(x)
+ if (x < 1)
+ fun_l3_n77(x)
+ else
+ fun_l3_n842(x)
+ end
+end
+
+def fun_l2_n773(x)
+ if (x < 1)
+ fun_l3_n972(x)
+ else
+ fun_l3_n143(x)
+ end
+end
+
+def fun_l2_n774(x)
+ if (x < 1)
+ fun_l3_n308(x)
+ else
+ fun_l3_n713(x)
+ end
+end
+
+def fun_l2_n775(x)
+ if (x < 1)
+ fun_l3_n714(x)
+ else
+ fun_l3_n329(x)
+ end
+end
+
+def fun_l2_n776(x)
+ if (x < 1)
+ fun_l3_n805(x)
+ else
+ fun_l3_n141(x)
+ end
+end
+
+def fun_l2_n777(x)
+ if (x < 1)
+ fun_l3_n155(x)
+ else
+ fun_l3_n873(x)
+ end
+end
+
+def fun_l2_n778(x)
+ if (x < 1)
+ fun_l3_n551(x)
+ else
+ fun_l3_n293(x)
+ end
+end
+
+def fun_l2_n779(x)
+ if (x < 1)
+ fun_l3_n857(x)
+ else
+ fun_l3_n551(x)
+ end
+end
+
+def fun_l2_n780(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n230(x)
+ end
+end
+
+def fun_l2_n781(x)
+ if (x < 1)
+ fun_l3_n958(x)
+ else
+ fun_l3_n463(x)
+ end
+end
+
+def fun_l2_n782(x)
+ if (x < 1)
+ fun_l3_n89(x)
+ else
+ fun_l3_n514(x)
+ end
+end
+
+def fun_l2_n783(x)
+ if (x < 1)
+ fun_l3_n290(x)
+ else
+ fun_l3_n394(x)
+ end
+end
+
+def fun_l2_n784(x)
+ if (x < 1)
+ fun_l3_n582(x)
+ else
+ fun_l3_n927(x)
+ end
+end
+
+def fun_l2_n785(x)
+ if (x < 1)
+ fun_l3_n739(x)
+ else
+ fun_l3_n822(x)
+ end
+end
+
+def fun_l2_n786(x)
+ if (x < 1)
+ fun_l3_n1(x)
+ else
+ fun_l3_n162(x)
+ end
+end
+
+def fun_l2_n787(x)
+ if (x < 1)
+ fun_l3_n88(x)
+ else
+ fun_l3_n800(x)
+ end
+end
+
+def fun_l2_n788(x)
+ if (x < 1)
+ fun_l3_n592(x)
+ else
+ fun_l3_n235(x)
+ end
+end
+
+def fun_l2_n789(x)
+ if (x < 1)
+ fun_l3_n337(x)
+ else
+ fun_l3_n204(x)
+ end
+end
+
+def fun_l2_n790(x)
+ if (x < 1)
+ fun_l3_n481(x)
+ else
+ fun_l3_n361(x)
+ end
+end
+
+def fun_l2_n791(x)
+ if (x < 1)
+ fun_l3_n441(x)
+ else
+ fun_l3_n883(x)
+ end
+end
+
+def fun_l2_n792(x)
+ if (x < 1)
+ fun_l3_n424(x)
+ else
+ fun_l3_n387(x)
+ end
+end
+
+def fun_l2_n793(x)
+ if (x < 1)
+ fun_l3_n961(x)
+ else
+ fun_l3_n710(x)
+ end
+end
+
+def fun_l2_n794(x)
+ if (x < 1)
+ fun_l3_n653(x)
+ else
+ fun_l3_n869(x)
+ end
+end
+
+def fun_l2_n795(x)
+ if (x < 1)
+ fun_l3_n466(x)
+ else
+ fun_l3_n195(x)
+ end
+end
+
+def fun_l2_n796(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n137(x)
+ end
+end
+
+def fun_l2_n797(x)
+ if (x < 1)
+ fun_l3_n974(x)
+ else
+ fun_l3_n911(x)
+ end
+end
+
+def fun_l2_n798(x)
+ if (x < 1)
+ fun_l3_n500(x)
+ else
+ fun_l3_n607(x)
+ end
+end
+
+def fun_l2_n799(x)
+ if (x < 1)
+ fun_l3_n964(x)
+ else
+ fun_l3_n425(x)
+ end
+end
+
+def fun_l2_n800(x)
+ if (x < 1)
+ fun_l3_n381(x)
+ else
+ fun_l3_n618(x)
+ end
+end
+
+def fun_l2_n801(x)
+ if (x < 1)
+ fun_l3_n803(x)
+ else
+ fun_l3_n697(x)
+ end
+end
+
+def fun_l2_n802(x)
+ if (x < 1)
+ fun_l3_n372(x)
+ else
+ fun_l3_n331(x)
+ end
+end
+
+def fun_l2_n803(x)
+ if (x < 1)
+ fun_l3_n450(x)
+ else
+ fun_l3_n707(x)
+ end
+end
+
+def fun_l2_n804(x)
+ if (x < 1)
+ fun_l3_n760(x)
+ else
+ fun_l3_n800(x)
+ end
+end
+
+def fun_l2_n805(x)
+ if (x < 1)
+ fun_l3_n695(x)
+ else
+ fun_l3_n426(x)
+ end
+end
+
+def fun_l2_n806(x)
+ if (x < 1)
+ fun_l3_n312(x)
+ else
+ fun_l3_n517(x)
+ end
+end
+
+def fun_l2_n807(x)
+ if (x < 1)
+ fun_l3_n794(x)
+ else
+ fun_l3_n37(x)
+ end
+end
+
+def fun_l2_n808(x)
+ if (x < 1)
+ fun_l3_n591(x)
+ else
+ fun_l3_n933(x)
+ end
+end
+
+def fun_l2_n809(x)
+ if (x < 1)
+ fun_l3_n974(x)
+ else
+ fun_l3_n69(x)
+ end
+end
+
+def fun_l2_n810(x)
+ if (x < 1)
+ fun_l3_n263(x)
+ else
+ fun_l3_n628(x)
+ end
+end
+
+def fun_l2_n811(x)
+ if (x < 1)
+ fun_l3_n647(x)
+ else
+ fun_l3_n133(x)
+ end
+end
+
+def fun_l2_n812(x)
+ if (x < 1)
+ fun_l3_n396(x)
+ else
+ fun_l3_n872(x)
+ end
+end
+
+def fun_l2_n813(x)
+ if (x < 1)
+ fun_l3_n716(x)
+ else
+ fun_l3_n254(x)
+ end
+end
+
+def fun_l2_n814(x)
+ if (x < 1)
+ fun_l3_n181(x)
+ else
+ fun_l3_n786(x)
+ end
+end
+
+def fun_l2_n815(x)
+ if (x < 1)
+ fun_l3_n163(x)
+ else
+ fun_l3_n175(x)
+ end
+end
+
+def fun_l2_n816(x)
+ if (x < 1)
+ fun_l3_n835(x)
+ else
+ fun_l3_n713(x)
+ end
+end
+
+def fun_l2_n817(x)
+ if (x < 1)
+ fun_l3_n54(x)
+ else
+ fun_l3_n280(x)
+ end
+end
+
+def fun_l2_n818(x)
+ if (x < 1)
+ fun_l3_n261(x)
+ else
+ fun_l3_n958(x)
+ end
+end
+
+def fun_l2_n819(x)
+ if (x < 1)
+ fun_l3_n821(x)
+ else
+ fun_l3_n418(x)
+ end
+end
+
+def fun_l2_n820(x)
+ if (x < 1)
+ fun_l3_n541(x)
+ else
+ fun_l3_n547(x)
+ end
+end
+
+def fun_l2_n821(x)
+ if (x < 1)
+ fun_l3_n726(x)
+ else
+ fun_l3_n386(x)
+ end
+end
+
+def fun_l2_n822(x)
+ if (x < 1)
+ fun_l3_n369(x)
+ else
+ fun_l3_n781(x)
+ end
+end
+
+def fun_l2_n823(x)
+ if (x < 1)
+ fun_l3_n392(x)
+ else
+ fun_l3_n357(x)
+ end
+end
+
+def fun_l2_n824(x)
+ if (x < 1)
+ fun_l3_n167(x)
+ else
+ fun_l3_n764(x)
+ end
+end
+
+def fun_l2_n825(x)
+ if (x < 1)
+ fun_l3_n339(x)
+ else
+ fun_l3_n853(x)
+ end
+end
+
+def fun_l2_n826(x)
+ if (x < 1)
+ fun_l3_n613(x)
+ else
+ fun_l3_n767(x)
+ end
+end
+
+def fun_l2_n827(x)
+ if (x < 1)
+ fun_l3_n31(x)
+ else
+ fun_l3_n35(x)
+ end
+end
+
+def fun_l2_n828(x)
+ if (x < 1)
+ fun_l3_n838(x)
+ else
+ fun_l3_n939(x)
+ end
+end
+
+def fun_l2_n829(x)
+ if (x < 1)
+ fun_l3_n344(x)
+ else
+ fun_l3_n568(x)
+ end
+end
+
+def fun_l2_n830(x)
+ if (x < 1)
+ fun_l3_n892(x)
+ else
+ fun_l3_n564(x)
+ end
+end
+
+def fun_l2_n831(x)
+ if (x < 1)
+ fun_l3_n520(x)
+ else
+ fun_l3_n897(x)
+ end
+end
+
+def fun_l2_n832(x)
+ if (x < 1)
+ fun_l3_n986(x)
+ else
+ fun_l3_n523(x)
+ end
+end
+
+def fun_l2_n833(x)
+ if (x < 1)
+ fun_l3_n649(x)
+ else
+ fun_l3_n776(x)
+ end
+end
+
+def fun_l2_n834(x)
+ if (x < 1)
+ fun_l3_n613(x)
+ else
+ fun_l3_n170(x)
+ end
+end
+
+def fun_l2_n835(x)
+ if (x < 1)
+ fun_l3_n657(x)
+ else
+ fun_l3_n790(x)
+ end
+end
+
+def fun_l2_n836(x)
+ if (x < 1)
+ fun_l3_n976(x)
+ else
+ fun_l3_n785(x)
+ end
+end
+
+def fun_l2_n837(x)
+ if (x < 1)
+ fun_l3_n746(x)
+ else
+ fun_l3_n448(x)
+ end
+end
+
+def fun_l2_n838(x)
+ if (x < 1)
+ fun_l3_n911(x)
+ else
+ fun_l3_n978(x)
+ end
+end
+
+def fun_l2_n839(x)
+ if (x < 1)
+ fun_l3_n917(x)
+ else
+ fun_l3_n484(x)
+ end
+end
+
+def fun_l2_n840(x)
+ if (x < 1)
+ fun_l3_n930(x)
+ else
+ fun_l3_n617(x)
+ end
+end
+
+def fun_l2_n841(x)
+ if (x < 1)
+ fun_l3_n753(x)
+ else
+ fun_l3_n587(x)
+ end
+end
+
+def fun_l2_n842(x)
+ if (x < 1)
+ fun_l3_n21(x)
+ else
+ fun_l3_n256(x)
+ end
+end
+
+def fun_l2_n843(x)
+ if (x < 1)
+ fun_l3_n697(x)
+ else
+ fun_l3_n828(x)
+ end
+end
+
+def fun_l2_n844(x)
+ if (x < 1)
+ fun_l3_n59(x)
+ else
+ fun_l3_n855(x)
+ end
+end
+
+def fun_l2_n845(x)
+ if (x < 1)
+ fun_l3_n637(x)
+ else
+ fun_l3_n667(x)
+ end
+end
+
+def fun_l2_n846(x)
+ if (x < 1)
+ fun_l3_n229(x)
+ else
+ fun_l3_n379(x)
+ end
+end
+
+def fun_l2_n847(x)
+ if (x < 1)
+ fun_l3_n908(x)
+ else
+ fun_l3_n53(x)
+ end
+end
+
+def fun_l2_n848(x)
+ if (x < 1)
+ fun_l3_n72(x)
+ else
+ fun_l3_n882(x)
+ end
+end
+
+def fun_l2_n849(x)
+ if (x < 1)
+ fun_l3_n890(x)
+ else
+ fun_l3_n153(x)
+ end
+end
+
+def fun_l2_n850(x)
+ if (x < 1)
+ fun_l3_n301(x)
+ else
+ fun_l3_n404(x)
+ end
+end
+
+def fun_l2_n851(x)
+ if (x < 1)
+ fun_l3_n451(x)
+ else
+ fun_l3_n365(x)
+ end
+end
+
+def fun_l2_n852(x)
+ if (x < 1)
+ fun_l3_n591(x)
+ else
+ fun_l3_n974(x)
+ end
+end
+
+def fun_l2_n853(x)
+ if (x < 1)
+ fun_l3_n534(x)
+ else
+ fun_l3_n649(x)
+ end
+end
+
+def fun_l2_n854(x)
+ if (x < 1)
+ fun_l3_n438(x)
+ else
+ fun_l3_n853(x)
+ end
+end
+
+def fun_l2_n855(x)
+ if (x < 1)
+ fun_l3_n181(x)
+ else
+ fun_l3_n888(x)
+ end
+end
+
+def fun_l2_n856(x)
+ if (x < 1)
+ fun_l3_n856(x)
+ else
+ fun_l3_n139(x)
+ end
+end
+
+def fun_l2_n857(x)
+ if (x < 1)
+ fun_l3_n664(x)
+ else
+ fun_l3_n659(x)
+ end
+end
+
+def fun_l2_n858(x)
+ if (x < 1)
+ fun_l3_n838(x)
+ else
+ fun_l3_n157(x)
+ end
+end
+
+def fun_l2_n859(x)
+ if (x < 1)
+ fun_l3_n542(x)
+ else
+ fun_l3_n512(x)
+ end
+end
+
+def fun_l2_n860(x)
+ if (x < 1)
+ fun_l3_n213(x)
+ else
+ fun_l3_n954(x)
+ end
+end
+
+def fun_l2_n861(x)
+ if (x < 1)
+ fun_l3_n580(x)
+ else
+ fun_l3_n525(x)
+ end
+end
+
+def fun_l2_n862(x)
+ if (x < 1)
+ fun_l3_n649(x)
+ else
+ fun_l3_n376(x)
+ end
+end
+
+def fun_l2_n863(x)
+ if (x < 1)
+ fun_l3_n846(x)
+ else
+ fun_l3_n643(x)
+ end
+end
+
+def fun_l2_n864(x)
+ if (x < 1)
+ fun_l3_n899(x)
+ else
+ fun_l3_n667(x)
+ end
+end
+
+def fun_l2_n865(x)
+ if (x < 1)
+ fun_l3_n326(x)
+ else
+ fun_l3_n664(x)
+ end
+end
+
+def fun_l2_n866(x)
+ if (x < 1)
+ fun_l3_n155(x)
+ else
+ fun_l3_n369(x)
+ end
+end
+
+def fun_l2_n867(x)
+ if (x < 1)
+ fun_l3_n583(x)
+ else
+ fun_l3_n12(x)
+ end
+end
+
+def fun_l2_n868(x)
+ if (x < 1)
+ fun_l3_n637(x)
+ else
+ fun_l3_n711(x)
+ end
+end
+
+def fun_l2_n869(x)
+ if (x < 1)
+ fun_l3_n120(x)
+ else
+ fun_l3_n449(x)
+ end
+end
+
+def fun_l2_n870(x)
+ if (x < 1)
+ fun_l3_n459(x)
+ else
+ fun_l3_n83(x)
+ end
+end
+
+def fun_l2_n871(x)
+ if (x < 1)
+ fun_l3_n298(x)
+ else
+ fun_l3_n6(x)
+ end
+end
+
+def fun_l2_n872(x)
+ if (x < 1)
+ fun_l3_n640(x)
+ else
+ fun_l3_n319(x)
+ end
+end
+
+def fun_l2_n873(x)
+ if (x < 1)
+ fun_l3_n777(x)
+ else
+ fun_l3_n903(x)
+ end
+end
+
+def fun_l2_n874(x)
+ if (x < 1)
+ fun_l3_n16(x)
+ else
+ fun_l3_n50(x)
+ end
+end
+
+def fun_l2_n875(x)
+ if (x < 1)
+ fun_l3_n732(x)
+ else
+ fun_l3_n711(x)
+ end
+end
+
+def fun_l2_n876(x)
+ if (x < 1)
+ fun_l3_n958(x)
+ else
+ fun_l3_n949(x)
+ end
+end
+
+def fun_l2_n877(x)
+ if (x < 1)
+ fun_l3_n992(x)
+ else
+ fun_l3_n592(x)
+ end
+end
+
+def fun_l2_n878(x)
+ if (x < 1)
+ fun_l3_n283(x)
+ else
+ fun_l3_n178(x)
+ end
+end
+
+def fun_l2_n879(x)
+ if (x < 1)
+ fun_l3_n179(x)
+ else
+ fun_l3_n963(x)
+ end
+end
+
+def fun_l2_n880(x)
+ if (x < 1)
+ fun_l3_n345(x)
+ else
+ fun_l3_n585(x)
+ end
+end
+
+def fun_l2_n881(x)
+ if (x < 1)
+ fun_l3_n859(x)
+ else
+ fun_l3_n204(x)
+ end
+end
+
+def fun_l2_n882(x)
+ if (x < 1)
+ fun_l3_n718(x)
+ else
+ fun_l3_n354(x)
+ end
+end
+
+def fun_l2_n883(x)
+ if (x < 1)
+ fun_l3_n58(x)
+ else
+ fun_l3_n34(x)
+ end
+end
+
+def fun_l2_n884(x)
+ if (x < 1)
+ fun_l3_n442(x)
+ else
+ fun_l3_n853(x)
+ end
+end
+
+def fun_l2_n885(x)
+ if (x < 1)
+ fun_l3_n37(x)
+ else
+ fun_l3_n665(x)
+ end
+end
+
+def fun_l2_n886(x)
+ if (x < 1)
+ fun_l3_n468(x)
+ else
+ fun_l3_n283(x)
+ end
+end
+
+def fun_l2_n887(x)
+ if (x < 1)
+ fun_l3_n674(x)
+ else
+ fun_l3_n940(x)
+ end
+end
+
+def fun_l2_n888(x)
+ if (x < 1)
+ fun_l3_n556(x)
+ else
+ fun_l3_n191(x)
+ end
+end
+
+def fun_l2_n889(x)
+ if (x < 1)
+ fun_l3_n451(x)
+ else
+ fun_l3_n33(x)
+ end
+end
+
+def fun_l2_n890(x)
+ if (x < 1)
+ fun_l3_n724(x)
+ else
+ fun_l3_n355(x)
+ end
+end
+
+def fun_l2_n891(x)
+ if (x < 1)
+ fun_l3_n811(x)
+ else
+ fun_l3_n969(x)
+ end
+end
+
+def fun_l2_n892(x)
+ if (x < 1)
+ fun_l3_n122(x)
+ else
+ fun_l3_n956(x)
+ end
+end
+
+def fun_l2_n893(x)
+ if (x < 1)
+ fun_l3_n416(x)
+ else
+ fun_l3_n373(x)
+ end
+end
+
+def fun_l2_n894(x)
+ if (x < 1)
+ fun_l3_n990(x)
+ else
+ fun_l3_n148(x)
+ end
+end
+
+def fun_l2_n895(x)
+ if (x < 1)
+ fun_l3_n52(x)
+ else
+ fun_l3_n605(x)
+ end
+end
+
+def fun_l2_n896(x)
+ if (x < 1)
+ fun_l3_n523(x)
+ else
+ fun_l3_n929(x)
+ end
+end
+
+def fun_l2_n897(x)
+ if (x < 1)
+ fun_l3_n631(x)
+ else
+ fun_l3_n167(x)
+ end
+end
+
+def fun_l2_n898(x)
+ if (x < 1)
+ fun_l3_n366(x)
+ else
+ fun_l3_n666(x)
+ end
+end
+
+def fun_l2_n899(x)
+ if (x < 1)
+ fun_l3_n758(x)
+ else
+ fun_l3_n441(x)
+ end
+end
+
+def fun_l2_n900(x)
+ if (x < 1)
+ fun_l3_n561(x)
+ else
+ fun_l3_n766(x)
+ end
+end
+
+def fun_l2_n901(x)
+ if (x < 1)
+ fun_l3_n323(x)
+ else
+ fun_l3_n348(x)
+ end
+end
+
+def fun_l2_n902(x)
+ if (x < 1)
+ fun_l3_n455(x)
+ else
+ fun_l3_n78(x)
+ end
+end
+
+def fun_l2_n903(x)
+ if (x < 1)
+ fun_l3_n373(x)
+ else
+ fun_l3_n646(x)
+ end
+end
+
+def fun_l2_n904(x)
+ if (x < 1)
+ fun_l3_n595(x)
+ else
+ fun_l3_n742(x)
+ end
+end
+
+def fun_l2_n905(x)
+ if (x < 1)
+ fun_l3_n102(x)
+ else
+ fun_l3_n140(x)
+ end
+end
+
+def fun_l2_n906(x)
+ if (x < 1)
+ fun_l3_n458(x)
+ else
+ fun_l3_n528(x)
+ end
+end
+
+def fun_l2_n907(x)
+ if (x < 1)
+ fun_l3_n970(x)
+ else
+ fun_l3_n841(x)
+ end
+end
+
+def fun_l2_n908(x)
+ if (x < 1)
+ fun_l3_n97(x)
+ else
+ fun_l3_n250(x)
+ end
+end
+
+def fun_l2_n909(x)
+ if (x < 1)
+ fun_l3_n381(x)
+ else
+ fun_l3_n44(x)
+ end
+end
+
+def fun_l2_n910(x)
+ if (x < 1)
+ fun_l3_n812(x)
+ else
+ fun_l3_n225(x)
+ end
+end
+
+def fun_l2_n911(x)
+ if (x < 1)
+ fun_l3_n849(x)
+ else
+ fun_l3_n683(x)
+ end
+end
+
+def fun_l2_n912(x)
+ if (x < 1)
+ fun_l3_n958(x)
+ else
+ fun_l3_n590(x)
+ end
+end
+
+def fun_l2_n913(x)
+ if (x < 1)
+ fun_l3_n858(x)
+ else
+ fun_l3_n140(x)
+ end
+end
+
+def fun_l2_n914(x)
+ if (x < 1)
+ fun_l3_n997(x)
+ else
+ fun_l3_n959(x)
+ end
+end
+
+def fun_l2_n915(x)
+ if (x < 1)
+ fun_l3_n184(x)
+ else
+ fun_l3_n910(x)
+ end
+end
+
+def fun_l2_n916(x)
+ if (x < 1)
+ fun_l3_n369(x)
+ else
+ fun_l3_n180(x)
+ end
+end
+
+def fun_l2_n917(x)
+ if (x < 1)
+ fun_l3_n537(x)
+ else
+ fun_l3_n927(x)
+ end
+end
+
+def fun_l2_n918(x)
+ if (x < 1)
+ fun_l3_n739(x)
+ else
+ fun_l3_n222(x)
+ end
+end
+
+def fun_l2_n919(x)
+ if (x < 1)
+ fun_l3_n640(x)
+ else
+ fun_l3_n406(x)
+ end
+end
+
+def fun_l2_n920(x)
+ if (x < 1)
+ fun_l3_n371(x)
+ else
+ fun_l3_n976(x)
+ end
+end
+
+def fun_l2_n921(x)
+ if (x < 1)
+ fun_l3_n262(x)
+ else
+ fun_l3_n532(x)
+ end
+end
+
+def fun_l2_n922(x)
+ if (x < 1)
+ fun_l3_n772(x)
+ else
+ fun_l3_n368(x)
+ end
+end
+
+def fun_l2_n923(x)
+ if (x < 1)
+ fun_l3_n935(x)
+ else
+ fun_l3_n109(x)
+ end
+end
+
+def fun_l2_n924(x)
+ if (x < 1)
+ fun_l3_n982(x)
+ else
+ fun_l3_n643(x)
+ end
+end
+
+def fun_l2_n925(x)
+ if (x < 1)
+ fun_l3_n849(x)
+ else
+ fun_l3_n266(x)
+ end
+end
+
+def fun_l2_n926(x)
+ if (x < 1)
+ fun_l3_n977(x)
+ else
+ fun_l3_n803(x)
+ end
+end
+
+def fun_l2_n927(x)
+ if (x < 1)
+ fun_l3_n706(x)
+ else
+ fun_l3_n441(x)
+ end
+end
+
+def fun_l2_n928(x)
+ if (x < 1)
+ fun_l3_n781(x)
+ else
+ fun_l3_n374(x)
+ end
+end
+
+def fun_l2_n929(x)
+ if (x < 1)
+ fun_l3_n122(x)
+ else
+ fun_l3_n851(x)
+ end
+end
+
+def fun_l2_n930(x)
+ if (x < 1)
+ fun_l3_n821(x)
+ else
+ fun_l3_n904(x)
+ end
+end
+
+def fun_l2_n931(x)
+ if (x < 1)
+ fun_l3_n379(x)
+ else
+ fun_l3_n211(x)
+ end
+end
+
+def fun_l2_n932(x)
+ if (x < 1)
+ fun_l3_n572(x)
+ else
+ fun_l3_n169(x)
+ end
+end
+
+def fun_l2_n933(x)
+ if (x < 1)
+ fun_l3_n620(x)
+ else
+ fun_l3_n703(x)
+ end
+end
+
+def fun_l2_n934(x)
+ if (x < 1)
+ fun_l3_n238(x)
+ else
+ fun_l3_n220(x)
+ end
+end
+
+def fun_l2_n935(x)
+ if (x < 1)
+ fun_l3_n652(x)
+ else
+ fun_l3_n822(x)
+ end
+end
+
+def fun_l2_n936(x)
+ if (x < 1)
+ fun_l3_n818(x)
+ else
+ fun_l3_n384(x)
+ end
+end
+
+def fun_l2_n937(x)
+ if (x < 1)
+ fun_l3_n560(x)
+ else
+ fun_l3_n875(x)
+ end
+end
+
+def fun_l2_n938(x)
+ if (x < 1)
+ fun_l3_n417(x)
+ else
+ fun_l3_n900(x)
+ end
+end
+
+def fun_l2_n939(x)
+ if (x < 1)
+ fun_l3_n740(x)
+ else
+ fun_l3_n431(x)
+ end
+end
+
+def fun_l2_n940(x)
+ if (x < 1)
+ fun_l3_n1(x)
+ else
+ fun_l3_n147(x)
+ end
+end
+
+def fun_l2_n941(x)
+ if (x < 1)
+ fun_l3_n64(x)
+ else
+ fun_l3_n317(x)
+ end
+end
+
+def fun_l2_n942(x)
+ if (x < 1)
+ fun_l3_n347(x)
+ else
+ fun_l3_n778(x)
+ end
+end
+
+def fun_l2_n943(x)
+ if (x < 1)
+ fun_l3_n819(x)
+ else
+ fun_l3_n446(x)
+ end
+end
+
+def fun_l2_n944(x)
+ if (x < 1)
+ fun_l3_n492(x)
+ else
+ fun_l3_n381(x)
+ end
+end
+
+def fun_l2_n945(x)
+ if (x < 1)
+ fun_l3_n594(x)
+ else
+ fun_l3_n413(x)
+ end
+end
+
+def fun_l2_n946(x)
+ if (x < 1)
+ fun_l3_n580(x)
+ else
+ fun_l3_n838(x)
+ end
+end
+
+def fun_l2_n947(x)
+ if (x < 1)
+ fun_l3_n880(x)
+ else
+ fun_l3_n768(x)
+ end
+end
+
+def fun_l2_n948(x)
+ if (x < 1)
+ fun_l3_n9(x)
+ else
+ fun_l3_n888(x)
+ end
+end
+
+def fun_l2_n949(x)
+ if (x < 1)
+ fun_l3_n365(x)
+ else
+ fun_l3_n322(x)
+ end
+end
+
+def fun_l2_n950(x)
+ if (x < 1)
+ fun_l3_n283(x)
+ else
+ fun_l3_n921(x)
+ end
+end
+
+def fun_l2_n951(x)
+ if (x < 1)
+ fun_l3_n740(x)
+ else
+ fun_l3_n336(x)
+ end
+end
+
+def fun_l2_n952(x)
+ if (x < 1)
+ fun_l3_n827(x)
+ else
+ fun_l3_n683(x)
+ end
+end
+
+def fun_l2_n953(x)
+ if (x < 1)
+ fun_l3_n289(x)
+ else
+ fun_l3_n915(x)
+ end
+end
+
+def fun_l2_n954(x)
+ if (x < 1)
+ fun_l3_n234(x)
+ else
+ fun_l3_n198(x)
+ end
+end
+
+def fun_l2_n955(x)
+ if (x < 1)
+ fun_l3_n364(x)
+ else
+ fun_l3_n152(x)
+ end
+end
+
+def fun_l2_n956(x)
+ if (x < 1)
+ fun_l3_n370(x)
+ else
+ fun_l3_n786(x)
+ end
+end
+
+def fun_l2_n957(x)
+ if (x < 1)
+ fun_l3_n672(x)
+ else
+ fun_l3_n375(x)
+ end
+end
+
+def fun_l2_n958(x)
+ if (x < 1)
+ fun_l3_n423(x)
+ else
+ fun_l3_n448(x)
+ end
+end
+
+def fun_l2_n959(x)
+ if (x < 1)
+ fun_l3_n887(x)
+ else
+ fun_l3_n33(x)
+ end
+end
+
+def fun_l2_n960(x)
+ if (x < 1)
+ fun_l3_n280(x)
+ else
+ fun_l3_n334(x)
+ end
+end
+
+def fun_l2_n961(x)
+ if (x < 1)
+ fun_l3_n535(x)
+ else
+ fun_l3_n524(x)
+ end
+end
+
+def fun_l2_n962(x)
+ if (x < 1)
+ fun_l3_n689(x)
+ else
+ fun_l3_n426(x)
+ end
+end
+
+def fun_l2_n963(x)
+ if (x < 1)
+ fun_l3_n235(x)
+ else
+ fun_l3_n286(x)
+ end
+end
+
+def fun_l2_n964(x)
+ if (x < 1)
+ fun_l3_n116(x)
+ else
+ fun_l3_n308(x)
+ end
+end
+
+def fun_l2_n965(x)
+ if (x < 1)
+ fun_l3_n174(x)
+ else
+ fun_l3_n823(x)
+ end
+end
+
+def fun_l2_n966(x)
+ if (x < 1)
+ fun_l3_n792(x)
+ else
+ fun_l3_n29(x)
+ end
+end
+
+def fun_l2_n967(x)
+ if (x < 1)
+ fun_l3_n755(x)
+ else
+ fun_l3_n689(x)
+ end
+end
+
+def fun_l2_n968(x)
+ if (x < 1)
+ fun_l3_n167(x)
+ else
+ fun_l3_n287(x)
+ end
+end
+
+def fun_l2_n969(x)
+ if (x < 1)
+ fun_l3_n836(x)
+ else
+ fun_l3_n892(x)
+ end
+end
+
+def fun_l2_n970(x)
+ if (x < 1)
+ fun_l3_n201(x)
+ else
+ fun_l3_n677(x)
+ end
+end
+
+def fun_l2_n971(x)
+ if (x < 1)
+ fun_l3_n990(x)
+ else
+ fun_l3_n251(x)
+ end
+end
+
+def fun_l2_n972(x)
+ if (x < 1)
+ fun_l3_n500(x)
+ else
+ fun_l3_n686(x)
+ end
+end
+
+def fun_l2_n973(x)
+ if (x < 1)
+ fun_l3_n969(x)
+ else
+ fun_l3_n819(x)
+ end
+end
+
+def fun_l2_n974(x)
+ if (x < 1)
+ fun_l3_n87(x)
+ else
+ fun_l3_n120(x)
+ end
+end
+
+def fun_l2_n975(x)
+ if (x < 1)
+ fun_l3_n701(x)
+ else
+ fun_l3_n569(x)
+ end
+end
+
+def fun_l2_n976(x)
+ if (x < 1)
+ fun_l3_n128(x)
+ else
+ fun_l3_n310(x)
+ end
+end
+
+def fun_l2_n977(x)
+ if (x < 1)
+ fun_l3_n690(x)
+ else
+ fun_l3_n5(x)
+ end
+end
+
+def fun_l2_n978(x)
+ if (x < 1)
+ fun_l3_n432(x)
+ else
+ fun_l3_n964(x)
+ end
+end
+
+def fun_l2_n979(x)
+ if (x < 1)
+ fun_l3_n198(x)
+ else
+ fun_l3_n161(x)
+ end
+end
+
+def fun_l2_n980(x)
+ if (x < 1)
+ fun_l3_n415(x)
+ else
+ fun_l3_n768(x)
+ end
+end
+
+def fun_l2_n981(x)
+ if (x < 1)
+ fun_l3_n635(x)
+ else
+ fun_l3_n569(x)
+ end
+end
+
+def fun_l2_n982(x)
+ if (x < 1)
+ fun_l3_n326(x)
+ else
+ fun_l3_n338(x)
+ end
+end
+
+def fun_l2_n983(x)
+ if (x < 1)
+ fun_l3_n243(x)
+ else
+ fun_l3_n48(x)
+ end
+end
+
+def fun_l2_n984(x)
+ if (x < 1)
+ fun_l3_n204(x)
+ else
+ fun_l3_n141(x)
+ end
+end
+
+def fun_l2_n985(x)
+ if (x < 1)
+ fun_l3_n805(x)
+ else
+ fun_l3_n577(x)
+ end
+end
+
+def fun_l2_n986(x)
+ if (x < 1)
+ fun_l3_n237(x)
+ else
+ fun_l3_n833(x)
+ end
+end
+
+def fun_l2_n987(x)
+ if (x < 1)
+ fun_l3_n643(x)
+ else
+ fun_l3_n629(x)
+ end
+end
+
+def fun_l2_n988(x)
+ if (x < 1)
+ fun_l3_n911(x)
+ else
+ fun_l3_n712(x)
+ end
+end
+
+def fun_l2_n989(x)
+ if (x < 1)
+ fun_l3_n936(x)
+ else
+ fun_l3_n300(x)
+ end
+end
+
+def fun_l2_n990(x)
+ if (x < 1)
+ fun_l3_n561(x)
+ else
+ fun_l3_n281(x)
+ end
+end
+
+def fun_l2_n991(x)
+ if (x < 1)
+ fun_l3_n226(x)
+ else
+ fun_l3_n203(x)
+ end
+end
+
+def fun_l2_n992(x)
+ if (x < 1)
+ fun_l3_n727(x)
+ else
+ fun_l3_n437(x)
+ end
+end
+
+def fun_l2_n993(x)
+ if (x < 1)
+ fun_l3_n608(x)
+ else
+ fun_l3_n169(x)
+ end
+end
+
+def fun_l2_n994(x)
+ if (x < 1)
+ fun_l3_n30(x)
+ else
+ fun_l3_n980(x)
+ end
+end
+
+def fun_l2_n995(x)
+ if (x < 1)
+ fun_l3_n652(x)
+ else
+ fun_l3_n122(x)
+ end
+end
+
+def fun_l2_n996(x)
+ if (x < 1)
+ fun_l3_n334(x)
+ else
+ fun_l3_n668(x)
+ end
+end
+
+def fun_l2_n997(x)
+ if (x < 1)
+ fun_l3_n241(x)
+ else
+ fun_l3_n515(x)
+ end
+end
+
+def fun_l2_n998(x)
+ if (x < 1)
+ fun_l3_n665(x)
+ else
+ fun_l3_n54(x)
+ end
+end
+
+def fun_l2_n999(x)
+ if (x < 1)
+ fun_l3_n568(x)
+ else
+ fun_l3_n652(x)
+ end
+end
+
+def fun_l3_n0(x)
+ if (x < 1)
+ fun_l4_n169(x)
+ else
+ fun_l4_n923(x)
+ end
+end
+
+def fun_l3_n1(x)
+ if (x < 1)
+ fun_l4_n214(x)
+ else
+ fun_l4_n506(x)
+ end
+end
+
+def fun_l3_n2(x)
+ if (x < 1)
+ fun_l4_n513(x)
+ else
+ fun_l4_n409(x)
+ end
+end
+
+def fun_l3_n3(x)
+ if (x < 1)
+ fun_l4_n133(x)
+ else
+ fun_l4_n293(x)
+ end
+end
+
+def fun_l3_n4(x)
+ if (x < 1)
+ fun_l4_n550(x)
+ else
+ fun_l4_n95(x)
+ end
+end
+
+def fun_l3_n5(x)
+ if (x < 1)
+ fun_l4_n13(x)
+ else
+ fun_l4_n508(x)
+ end
+end
+
+def fun_l3_n6(x)
+ if (x < 1)
+ fun_l4_n607(x)
+ else
+ fun_l4_n140(x)
+ end
+end
+
+def fun_l3_n7(x)
+ if (x < 1)
+ fun_l4_n65(x)
+ else
+ fun_l4_n90(x)
+ end
+end
+
+def fun_l3_n8(x)
+ if (x < 1)
+ fun_l4_n516(x)
+ else
+ fun_l4_n445(x)
+ end
+end
+
+def fun_l3_n9(x)
+ if (x < 1)
+ fun_l4_n713(x)
+ else
+ fun_l4_n487(x)
+ end
+end
+
+def fun_l3_n10(x)
+ if (x < 1)
+ fun_l4_n16(x)
+ else
+ fun_l4_n547(x)
+ end
+end
+
+def fun_l3_n11(x)
+ if (x < 1)
+ fun_l4_n561(x)
+ else
+ fun_l4_n530(x)
+ end
+end
+
+def fun_l3_n12(x)
+ if (x < 1)
+ fun_l4_n866(x)
+ else
+ fun_l4_n187(x)
+ end
+end
+
+def fun_l3_n13(x)
+ if (x < 1)
+ fun_l4_n8(x)
+ else
+ fun_l4_n458(x)
+ end
+end
+
+def fun_l3_n14(x)
+ if (x < 1)
+ fun_l4_n627(x)
+ else
+ fun_l4_n122(x)
+ end
+end
+
+def fun_l3_n15(x)
+ if (x < 1)
+ fun_l4_n988(x)
+ else
+ fun_l4_n4(x)
+ end
+end
+
+def fun_l3_n16(x)
+ if (x < 1)
+ fun_l4_n654(x)
+ else
+ fun_l4_n863(x)
+ end
+end
+
+def fun_l3_n17(x)
+ if (x < 1)
+ fun_l4_n112(x)
+ else
+ fun_l4_n223(x)
+ end
+end
+
+def fun_l3_n18(x)
+ if (x < 1)
+ fun_l4_n808(x)
+ else
+ fun_l4_n161(x)
+ end
+end
+
+def fun_l3_n19(x)
+ if (x < 1)
+ fun_l4_n265(x)
+ else
+ fun_l4_n860(x)
+ end
+end
+
+def fun_l3_n20(x)
+ if (x < 1)
+ fun_l4_n60(x)
+ else
+ fun_l4_n943(x)
+ end
+end
+
+def fun_l3_n21(x)
+ if (x < 1)
+ fun_l4_n707(x)
+ else
+ fun_l4_n990(x)
+ end
+end
+
+def fun_l3_n22(x)
+ if (x < 1)
+ fun_l4_n774(x)
+ else
+ fun_l4_n686(x)
+ end
+end
+
+def fun_l3_n23(x)
+ if (x < 1)
+ fun_l4_n552(x)
+ else
+ fun_l4_n935(x)
+ end
+end
+
+def fun_l3_n24(x)
+ if (x < 1)
+ fun_l4_n752(x)
+ else
+ fun_l4_n279(x)
+ end
+end
+
+def fun_l3_n25(x)
+ if (x < 1)
+ fun_l4_n325(x)
+ else
+ fun_l4_n440(x)
+ end
+end
+
+def fun_l3_n26(x)
+ if (x < 1)
+ fun_l4_n330(x)
+ else
+ fun_l4_n233(x)
+ end
+end
+
+def fun_l3_n27(x)
+ if (x < 1)
+ fun_l4_n112(x)
+ else
+ fun_l4_n399(x)
+ end
+end
+
+def fun_l3_n28(x)
+ if (x < 1)
+ fun_l4_n420(x)
+ else
+ fun_l4_n570(x)
+ end
+end
+
+def fun_l3_n29(x)
+ if (x < 1)
+ fun_l4_n515(x)
+ else
+ fun_l4_n485(x)
+ end
+end
+
+def fun_l3_n30(x)
+ if (x < 1)
+ fun_l4_n694(x)
+ else
+ fun_l4_n279(x)
+ end
+end
+
+def fun_l3_n31(x)
+ if (x < 1)
+ fun_l4_n683(x)
+ else
+ fun_l4_n396(x)
+ end
+end
+
+def fun_l3_n32(x)
+ if (x < 1)
+ fun_l4_n997(x)
+ else
+ fun_l4_n978(x)
+ end
+end
+
+def fun_l3_n33(x)
+ if (x < 1)
+ fun_l4_n260(x)
+ else
+ fun_l4_n895(x)
+ end
+end
+
+def fun_l3_n34(x)
+ if (x < 1)
+ fun_l4_n510(x)
+ else
+ fun_l4_n147(x)
+ end
+end
+
+def fun_l3_n35(x)
+ if (x < 1)
+ fun_l4_n415(x)
+ else
+ fun_l4_n590(x)
+ end
+end
+
+def fun_l3_n36(x)
+ if (x < 1)
+ fun_l4_n164(x)
+ else
+ fun_l4_n990(x)
+ end
+end
+
+def fun_l3_n37(x)
+ if (x < 1)
+ fun_l4_n744(x)
+ else
+ fun_l4_n981(x)
+ end
+end
+
+def fun_l3_n38(x)
+ if (x < 1)
+ fun_l4_n243(x)
+ else
+ fun_l4_n385(x)
+ end
+end
+
+def fun_l3_n39(x)
+ if (x < 1)
+ fun_l4_n874(x)
+ else
+ fun_l4_n941(x)
+ end
+end
+
+def fun_l3_n40(x)
+ if (x < 1)
+ fun_l4_n39(x)
+ else
+ fun_l4_n115(x)
+ end
+end
+
+def fun_l3_n41(x)
+ if (x < 1)
+ fun_l4_n829(x)
+ else
+ fun_l4_n991(x)
+ end
+end
+
+def fun_l3_n42(x)
+ if (x < 1)
+ fun_l4_n234(x)
+ else
+ fun_l4_n359(x)
+ end
+end
+
+def fun_l3_n43(x)
+ if (x < 1)
+ fun_l4_n481(x)
+ else
+ fun_l4_n368(x)
+ end
+end
+
+def fun_l3_n44(x)
+ if (x < 1)
+ fun_l4_n969(x)
+ else
+ fun_l4_n716(x)
+ end
+end
+
+def fun_l3_n45(x)
+ if (x < 1)
+ fun_l4_n858(x)
+ else
+ fun_l4_n446(x)
+ end
+end
+
+def fun_l3_n46(x)
+ if (x < 1)
+ fun_l4_n786(x)
+ else
+ fun_l4_n418(x)
+ end
+end
+
+def fun_l3_n47(x)
+ if (x < 1)
+ fun_l4_n261(x)
+ else
+ fun_l4_n346(x)
+ end
+end
+
+def fun_l3_n48(x)
+ if (x < 1)
+ fun_l4_n422(x)
+ else
+ fun_l4_n710(x)
+ end
+end
+
+def fun_l3_n49(x)
+ if (x < 1)
+ fun_l4_n533(x)
+ else
+ fun_l4_n599(x)
+ end
+end
+
+def fun_l3_n50(x)
+ if (x < 1)
+ fun_l4_n922(x)
+ else
+ fun_l4_n90(x)
+ end
+end
+
+def fun_l3_n51(x)
+ if (x < 1)
+ fun_l4_n718(x)
+ else
+ fun_l4_n854(x)
+ end
+end
+
+def fun_l3_n52(x)
+ if (x < 1)
+ fun_l4_n993(x)
+ else
+ fun_l4_n996(x)
+ end
+end
+
+def fun_l3_n53(x)
+ if (x < 1)
+ fun_l4_n628(x)
+ else
+ fun_l4_n589(x)
+ end
+end
+
+def fun_l3_n54(x)
+ if (x < 1)
+ fun_l4_n735(x)
+ else
+ fun_l4_n258(x)
+ end
+end
+
+def fun_l3_n55(x)
+ if (x < 1)
+ fun_l4_n794(x)
+ else
+ fun_l4_n559(x)
+ end
+end
+
+def fun_l3_n56(x)
+ if (x < 1)
+ fun_l4_n771(x)
+ else
+ fun_l4_n812(x)
+ end
+end
+
+def fun_l3_n57(x)
+ if (x < 1)
+ fun_l4_n106(x)
+ else
+ fun_l4_n144(x)
+ end
+end
+
+def fun_l3_n58(x)
+ if (x < 1)
+ fun_l4_n2(x)
+ else
+ fun_l4_n49(x)
+ end
+end
+
+def fun_l3_n59(x)
+ if (x < 1)
+ fun_l4_n540(x)
+ else
+ fun_l4_n164(x)
+ end
+end
+
+def fun_l3_n60(x)
+ if (x < 1)
+ fun_l4_n638(x)
+ else
+ fun_l4_n984(x)
+ end
+end
+
+def fun_l3_n61(x)
+ if (x < 1)
+ fun_l4_n144(x)
+ else
+ fun_l4_n236(x)
+ end
+end
+
+def fun_l3_n62(x)
+ if (x < 1)
+ fun_l4_n345(x)
+ else
+ fun_l4_n65(x)
+ end
+end
+
+def fun_l3_n63(x)
+ if (x < 1)
+ fun_l4_n112(x)
+ else
+ fun_l4_n216(x)
+ end
+end
+
+def fun_l3_n64(x)
+ if (x < 1)
+ fun_l4_n213(x)
+ else
+ fun_l4_n370(x)
+ end
+end
+
+def fun_l3_n65(x)
+ if (x < 1)
+ fun_l4_n845(x)
+ else
+ fun_l4_n672(x)
+ end
+end
+
+def fun_l3_n66(x)
+ if (x < 1)
+ fun_l4_n951(x)
+ else
+ fun_l4_n415(x)
+ end
+end
+
+def fun_l3_n67(x)
+ if (x < 1)
+ fun_l4_n997(x)
+ else
+ fun_l4_n760(x)
+ end
+end
+
+def fun_l3_n68(x)
+ if (x < 1)
+ fun_l4_n595(x)
+ else
+ fun_l4_n517(x)
+ end
+end
+
+def fun_l3_n69(x)
+ if (x < 1)
+ fun_l4_n776(x)
+ else
+ fun_l4_n550(x)
+ end
+end
+
+def fun_l3_n70(x)
+ if (x < 1)
+ fun_l4_n360(x)
+ else
+ fun_l4_n836(x)
+ end
+end
+
+def fun_l3_n71(x)
+ if (x < 1)
+ fun_l4_n214(x)
+ else
+ fun_l4_n532(x)
+ end
+end
+
+def fun_l3_n72(x)
+ if (x < 1)
+ fun_l4_n138(x)
+ else
+ fun_l4_n881(x)
+ end
+end
+
+def fun_l3_n73(x)
+ if (x < 1)
+ fun_l4_n793(x)
+ else
+ fun_l4_n866(x)
+ end
+end
+
+def fun_l3_n74(x)
+ if (x < 1)
+ fun_l4_n883(x)
+ else
+ fun_l4_n730(x)
+ end
+end
+
+def fun_l3_n75(x)
+ if (x < 1)
+ fun_l4_n525(x)
+ else
+ fun_l4_n188(x)
+ end
+end
+
+def fun_l3_n76(x)
+ if (x < 1)
+ fun_l4_n528(x)
+ else
+ fun_l4_n723(x)
+ end
+end
+
+def fun_l3_n77(x)
+ if (x < 1)
+ fun_l4_n954(x)
+ else
+ fun_l4_n581(x)
+ end
+end
+
+def fun_l3_n78(x)
+ if (x < 1)
+ fun_l4_n614(x)
+ else
+ fun_l4_n941(x)
+ end
+end
+
+def fun_l3_n79(x)
+ if (x < 1)
+ fun_l4_n396(x)
+ else
+ fun_l4_n539(x)
+ end
+end
+
+def fun_l3_n80(x)
+ if (x < 1)
+ fun_l4_n1(x)
+ else
+ fun_l4_n708(x)
+ end
+end
+
+def fun_l3_n81(x)
+ if (x < 1)
+ fun_l4_n626(x)
+ else
+ fun_l4_n418(x)
+ end
+end
+
+def fun_l3_n82(x)
+ if (x < 1)
+ fun_l4_n5(x)
+ else
+ fun_l4_n108(x)
+ end
+end
+
+def fun_l3_n83(x)
+ if (x < 1)
+ fun_l4_n683(x)
+ else
+ fun_l4_n679(x)
+ end
+end
+
+def fun_l3_n84(x)
+ if (x < 1)
+ fun_l4_n613(x)
+ else
+ fun_l4_n596(x)
+ end
+end
+
+def fun_l3_n85(x)
+ if (x < 1)
+ fun_l4_n490(x)
+ else
+ fun_l4_n178(x)
+ end
+end
+
+def fun_l3_n86(x)
+ if (x < 1)
+ fun_l4_n286(x)
+ else
+ fun_l4_n724(x)
+ end
+end
+
+def fun_l3_n87(x)
+ if (x < 1)
+ fun_l4_n989(x)
+ else
+ fun_l4_n711(x)
+ end
+end
+
+def fun_l3_n88(x)
+ if (x < 1)
+ fun_l4_n422(x)
+ else
+ fun_l4_n259(x)
+ end
+end
+
+def fun_l3_n89(x)
+ if (x < 1)
+ fun_l4_n938(x)
+ else
+ fun_l4_n123(x)
+ end
+end
+
+def fun_l3_n90(x)
+ if (x < 1)
+ fun_l4_n589(x)
+ else
+ fun_l4_n231(x)
+ end
+end
+
+def fun_l3_n91(x)
+ if (x < 1)
+ fun_l4_n484(x)
+ else
+ fun_l4_n439(x)
+ end
+end
+
+def fun_l3_n92(x)
+ if (x < 1)
+ fun_l4_n469(x)
+ else
+ fun_l4_n737(x)
+ end
+end
+
+def fun_l3_n93(x)
+ if (x < 1)
+ fun_l4_n93(x)
+ else
+ fun_l4_n907(x)
+ end
+end
+
+def fun_l3_n94(x)
+ if (x < 1)
+ fun_l4_n468(x)
+ else
+ fun_l4_n219(x)
+ end
+end
+
+def fun_l3_n95(x)
+ if (x < 1)
+ fun_l4_n409(x)
+ else
+ fun_l4_n921(x)
+ end
+end
+
+def fun_l3_n96(x)
+ if (x < 1)
+ fun_l4_n952(x)
+ else
+ fun_l4_n167(x)
+ end
+end
+
+def fun_l3_n97(x)
+ if (x < 1)
+ fun_l4_n177(x)
+ else
+ fun_l4_n462(x)
+ end
+end
+
+def fun_l3_n98(x)
+ if (x < 1)
+ fun_l4_n351(x)
+ else
+ fun_l4_n89(x)
+ end
+end
+
+def fun_l3_n99(x)
+ if (x < 1)
+ fun_l4_n869(x)
+ else
+ fun_l4_n502(x)
+ end
+end
+
+def fun_l3_n100(x)
+ if (x < 1)
+ fun_l4_n985(x)
+ else
+ fun_l4_n297(x)
+ end
+end
+
+def fun_l3_n101(x)
+ if (x < 1)
+ fun_l4_n48(x)
+ else
+ fun_l4_n895(x)
+ end
+end
+
+def fun_l3_n102(x)
+ if (x < 1)
+ fun_l4_n92(x)
+ else
+ fun_l4_n36(x)
+ end
+end
+
+def fun_l3_n103(x)
+ if (x < 1)
+ fun_l4_n610(x)
+ else
+ fun_l4_n616(x)
+ end
+end
+
+def fun_l3_n104(x)
+ if (x < 1)
+ fun_l4_n472(x)
+ else
+ fun_l4_n689(x)
+ end
+end
+
+def fun_l3_n105(x)
+ if (x < 1)
+ fun_l4_n75(x)
+ else
+ fun_l4_n161(x)
+ end
+end
+
+def fun_l3_n106(x)
+ if (x < 1)
+ fun_l4_n300(x)
+ else
+ fun_l4_n767(x)
+ end
+end
+
+def fun_l3_n107(x)
+ if (x < 1)
+ fun_l4_n707(x)
+ else
+ fun_l4_n229(x)
+ end
+end
+
+def fun_l3_n108(x)
+ if (x < 1)
+ fun_l4_n761(x)
+ else
+ fun_l4_n97(x)
+ end
+end
+
+def fun_l3_n109(x)
+ if (x < 1)
+ fun_l4_n734(x)
+ else
+ fun_l4_n290(x)
+ end
+end
+
+def fun_l3_n110(x)
+ if (x < 1)
+ fun_l4_n819(x)
+ else
+ fun_l4_n567(x)
+ end
+end
+
+def fun_l3_n111(x)
+ if (x < 1)
+ fun_l4_n904(x)
+ else
+ fun_l4_n322(x)
+ end
+end
+
+def fun_l3_n112(x)
+ if (x < 1)
+ fun_l4_n907(x)
+ else
+ fun_l4_n667(x)
+ end
+end
+
+def fun_l3_n113(x)
+ if (x < 1)
+ fun_l4_n473(x)
+ else
+ fun_l4_n620(x)
+ end
+end
+
+def fun_l3_n114(x)
+ if (x < 1)
+ fun_l4_n278(x)
+ else
+ fun_l4_n998(x)
+ end
+end
+
+def fun_l3_n115(x)
+ if (x < 1)
+ fun_l4_n185(x)
+ else
+ fun_l4_n962(x)
+ end
+end
+
+def fun_l3_n116(x)
+ if (x < 1)
+ fun_l4_n989(x)
+ else
+ fun_l4_n993(x)
+ end
+end
+
+def fun_l3_n117(x)
+ if (x < 1)
+ fun_l4_n140(x)
+ else
+ fun_l4_n456(x)
+ end
+end
+
+def fun_l3_n118(x)
+ if (x < 1)
+ fun_l4_n920(x)
+ else
+ fun_l4_n701(x)
+ end
+end
+
+def fun_l3_n119(x)
+ if (x < 1)
+ fun_l4_n263(x)
+ else
+ fun_l4_n837(x)
+ end
+end
+
+def fun_l3_n120(x)
+ if (x < 1)
+ fun_l4_n54(x)
+ else
+ fun_l4_n964(x)
+ end
+end
+
+def fun_l3_n121(x)
+ if (x < 1)
+ fun_l4_n540(x)
+ else
+ fun_l4_n543(x)
+ end
+end
+
+def fun_l3_n122(x)
+ if (x < 1)
+ fun_l4_n51(x)
+ else
+ fun_l4_n453(x)
+ end
+end
+
+def fun_l3_n123(x)
+ if (x < 1)
+ fun_l4_n726(x)
+ else
+ fun_l4_n785(x)
+ end
+end
+
+def fun_l3_n124(x)
+ if (x < 1)
+ fun_l4_n932(x)
+ else
+ fun_l4_n583(x)
+ end
+end
+
+def fun_l3_n125(x)
+ if (x < 1)
+ fun_l4_n471(x)
+ else
+ fun_l4_n518(x)
+ end
+end
+
+def fun_l3_n126(x)
+ if (x < 1)
+ fun_l4_n351(x)
+ else
+ fun_l4_n825(x)
+ end
+end
+
+def fun_l3_n127(x)
+ if (x < 1)
+ fun_l4_n759(x)
+ else
+ fun_l4_n203(x)
+ end
+end
+
+def fun_l3_n128(x)
+ if (x < 1)
+ fun_l4_n336(x)
+ else
+ fun_l4_n861(x)
+ end
+end
+
+def fun_l3_n129(x)
+ if (x < 1)
+ fun_l4_n573(x)
+ else
+ fun_l4_n568(x)
+ end
+end
+
+def fun_l3_n130(x)
+ if (x < 1)
+ fun_l4_n788(x)
+ else
+ fun_l4_n259(x)
+ end
+end
+
+def fun_l3_n131(x)
+ if (x < 1)
+ fun_l4_n392(x)
+ else
+ fun_l4_n932(x)
+ end
+end
+
+def fun_l3_n132(x)
+ if (x < 1)
+ fun_l4_n919(x)
+ else
+ fun_l4_n650(x)
+ end
+end
+
+def fun_l3_n133(x)
+ if (x < 1)
+ fun_l4_n895(x)
+ else
+ fun_l4_n983(x)
+ end
+end
+
+def fun_l3_n134(x)
+ if (x < 1)
+ fun_l4_n389(x)
+ else
+ fun_l4_n358(x)
+ end
+end
+
+def fun_l3_n135(x)
+ if (x < 1)
+ fun_l4_n732(x)
+ else
+ fun_l4_n747(x)
+ end
+end
+
+def fun_l3_n136(x)
+ if (x < 1)
+ fun_l4_n756(x)
+ else
+ fun_l4_n592(x)
+ end
+end
+
+def fun_l3_n137(x)
+ if (x < 1)
+ fun_l4_n581(x)
+ else
+ fun_l4_n24(x)
+ end
+end
+
+def fun_l3_n138(x)
+ if (x < 1)
+ fun_l4_n932(x)
+ else
+ fun_l4_n599(x)
+ end
+end
+
+def fun_l3_n139(x)
+ if (x < 1)
+ fun_l4_n955(x)
+ else
+ fun_l4_n148(x)
+ end
+end
+
+def fun_l3_n140(x)
+ if (x < 1)
+ fun_l4_n332(x)
+ else
+ fun_l4_n677(x)
+ end
+end
+
+def fun_l3_n141(x)
+ if (x < 1)
+ fun_l4_n152(x)
+ else
+ fun_l4_n696(x)
+ end
+end
+
+def fun_l3_n142(x)
+ if (x < 1)
+ fun_l4_n295(x)
+ else
+ fun_l4_n205(x)
+ end
+end
+
+def fun_l3_n143(x)
+ if (x < 1)
+ fun_l4_n543(x)
+ else
+ fun_l4_n951(x)
+ end
+end
+
+def fun_l3_n144(x)
+ if (x < 1)
+ fun_l4_n656(x)
+ else
+ fun_l4_n494(x)
+ end
+end
+
+def fun_l3_n145(x)
+ if (x < 1)
+ fun_l4_n729(x)
+ else
+ fun_l4_n749(x)
+ end
+end
+
+def fun_l3_n146(x)
+ if (x < 1)
+ fun_l4_n197(x)
+ else
+ fun_l4_n3(x)
+ end
+end
+
+def fun_l3_n147(x)
+ if (x < 1)
+ fun_l4_n519(x)
+ else
+ fun_l4_n36(x)
+ end
+end
+
+def fun_l3_n148(x)
+ if (x < 1)
+ fun_l4_n100(x)
+ else
+ fun_l4_n463(x)
+ end
+end
+
+def fun_l3_n149(x)
+ if (x < 1)
+ fun_l4_n890(x)
+ else
+ fun_l4_n947(x)
+ end
+end
+
+def fun_l3_n150(x)
+ if (x < 1)
+ fun_l4_n512(x)
+ else
+ fun_l4_n982(x)
+ end
+end
+
+def fun_l3_n151(x)
+ if (x < 1)
+ fun_l4_n750(x)
+ else
+ fun_l4_n781(x)
+ end
+end
+
+def fun_l3_n152(x)
+ if (x < 1)
+ fun_l4_n193(x)
+ else
+ fun_l4_n530(x)
+ end
+end
+
+def fun_l3_n153(x)
+ if (x < 1)
+ fun_l4_n189(x)
+ else
+ fun_l4_n209(x)
+ end
+end
+
+def fun_l3_n154(x)
+ if (x < 1)
+ fun_l4_n343(x)
+ else
+ fun_l4_n44(x)
+ end
+end
+
+def fun_l3_n155(x)
+ if (x < 1)
+ fun_l4_n536(x)
+ else
+ fun_l4_n228(x)
+ end
+end
+
+def fun_l3_n156(x)
+ if (x < 1)
+ fun_l4_n475(x)
+ else
+ fun_l4_n790(x)
+ end
+end
+
+def fun_l3_n157(x)
+ if (x < 1)
+ fun_l4_n954(x)
+ else
+ fun_l4_n242(x)
+ end
+end
+
+def fun_l3_n158(x)
+ if (x < 1)
+ fun_l4_n19(x)
+ else
+ fun_l4_n735(x)
+ end
+end
+
+def fun_l3_n159(x)
+ if (x < 1)
+ fun_l4_n900(x)
+ else
+ fun_l4_n456(x)
+ end
+end
+
+def fun_l3_n160(x)
+ if (x < 1)
+ fun_l4_n193(x)
+ else
+ fun_l4_n606(x)
+ end
+end
+
+def fun_l3_n161(x)
+ if (x < 1)
+ fun_l4_n684(x)
+ else
+ fun_l4_n622(x)
+ end
+end
+
+def fun_l3_n162(x)
+ if (x < 1)
+ fun_l4_n260(x)
+ else
+ fun_l4_n582(x)
+ end
+end
+
+def fun_l3_n163(x)
+ if (x < 1)
+ fun_l4_n713(x)
+ else
+ fun_l4_n601(x)
+ end
+end
+
+def fun_l3_n164(x)
+ if (x < 1)
+ fun_l4_n819(x)
+ else
+ fun_l4_n642(x)
+ end
+end
+
+def fun_l3_n165(x)
+ if (x < 1)
+ fun_l4_n45(x)
+ else
+ fun_l4_n777(x)
+ end
+end
+
+def fun_l3_n166(x)
+ if (x < 1)
+ fun_l4_n256(x)
+ else
+ fun_l4_n92(x)
+ end
+end
+
+def fun_l3_n167(x)
+ if (x < 1)
+ fun_l4_n975(x)
+ else
+ fun_l4_n962(x)
+ end
+end
+
+def fun_l3_n168(x)
+ if (x < 1)
+ fun_l4_n579(x)
+ else
+ fun_l4_n208(x)
+ end
+end
+
+def fun_l3_n169(x)
+ if (x < 1)
+ fun_l4_n133(x)
+ else
+ fun_l4_n636(x)
+ end
+end
+
+def fun_l3_n170(x)
+ if (x < 1)
+ fun_l4_n863(x)
+ else
+ fun_l4_n168(x)
+ end
+end
+
+def fun_l3_n171(x)
+ if (x < 1)
+ fun_l4_n396(x)
+ else
+ fun_l4_n654(x)
+ end
+end
+
+def fun_l3_n172(x)
+ if (x < 1)
+ fun_l4_n963(x)
+ else
+ fun_l4_n420(x)
+ end
+end
+
+def fun_l3_n173(x)
+ if (x < 1)
+ fun_l4_n487(x)
+ else
+ fun_l4_n573(x)
+ end
+end
+
+def fun_l3_n174(x)
+ if (x < 1)
+ fun_l4_n847(x)
+ else
+ fun_l4_n476(x)
+ end
+end
+
+def fun_l3_n175(x)
+ if (x < 1)
+ fun_l4_n712(x)
+ else
+ fun_l4_n522(x)
+ end
+end
+
+def fun_l3_n176(x)
+ if (x < 1)
+ fun_l4_n292(x)
+ else
+ fun_l4_n717(x)
+ end
+end
+
+def fun_l3_n177(x)
+ if (x < 1)
+ fun_l4_n945(x)
+ else
+ fun_l4_n146(x)
+ end
+end
+
+def fun_l3_n178(x)
+ if (x < 1)
+ fun_l4_n163(x)
+ else
+ fun_l4_n28(x)
+ end
+end
+
+def fun_l3_n179(x)
+ if (x < 1)
+ fun_l4_n738(x)
+ else
+ fun_l4_n502(x)
+ end
+end
+
+def fun_l3_n180(x)
+ if (x < 1)
+ fun_l4_n8(x)
+ else
+ fun_l4_n56(x)
+ end
+end
+
+def fun_l3_n181(x)
+ if (x < 1)
+ fun_l4_n58(x)
+ else
+ fun_l4_n155(x)
+ end
+end
+
+def fun_l3_n182(x)
+ if (x < 1)
+ fun_l4_n298(x)
+ else
+ fun_l4_n580(x)
+ end
+end
+
+def fun_l3_n183(x)
+ if (x < 1)
+ fun_l4_n860(x)
+ else
+ fun_l4_n176(x)
+ end
+end
+
+def fun_l3_n184(x)
+ if (x < 1)
+ fun_l4_n108(x)
+ else
+ fun_l4_n986(x)
+ end
+end
+
+def fun_l3_n185(x)
+ if (x < 1)
+ fun_l4_n366(x)
+ else
+ fun_l4_n110(x)
+ end
+end
+
+def fun_l3_n186(x)
+ if (x < 1)
+ fun_l4_n177(x)
+ else
+ fun_l4_n158(x)
+ end
+end
+
+def fun_l3_n187(x)
+ if (x < 1)
+ fun_l4_n212(x)
+ else
+ fun_l4_n803(x)
+ end
+end
+
+def fun_l3_n188(x)
+ if (x < 1)
+ fun_l4_n946(x)
+ else
+ fun_l4_n281(x)
+ end
+end
+
+def fun_l3_n189(x)
+ if (x < 1)
+ fun_l4_n610(x)
+ else
+ fun_l4_n691(x)
+ end
+end
+
+def fun_l3_n190(x)
+ if (x < 1)
+ fun_l4_n784(x)
+ else
+ fun_l4_n300(x)
+ end
+end
+
+def fun_l3_n191(x)
+ if (x < 1)
+ fun_l4_n272(x)
+ else
+ fun_l4_n809(x)
+ end
+end
+
+def fun_l3_n192(x)
+ if (x < 1)
+ fun_l4_n812(x)
+ else
+ fun_l4_n633(x)
+ end
+end
+
+def fun_l3_n193(x)
+ if (x < 1)
+ fun_l4_n880(x)
+ else
+ fun_l4_n267(x)
+ end
+end
+
+def fun_l3_n194(x)
+ if (x < 1)
+ fun_l4_n454(x)
+ else
+ fun_l4_n567(x)
+ end
+end
+
+def fun_l3_n195(x)
+ if (x < 1)
+ fun_l4_n919(x)
+ else
+ fun_l4_n184(x)
+ end
+end
+
+def fun_l3_n196(x)
+ if (x < 1)
+ fun_l4_n294(x)
+ else
+ fun_l4_n150(x)
+ end
+end
+
+def fun_l3_n197(x)
+ if (x < 1)
+ fun_l4_n543(x)
+ else
+ fun_l4_n319(x)
+ end
+end
+
+def fun_l3_n198(x)
+ if (x < 1)
+ fun_l4_n91(x)
+ else
+ fun_l4_n378(x)
+ end
+end
+
+def fun_l3_n199(x)
+ if (x < 1)
+ fun_l4_n590(x)
+ else
+ fun_l4_n195(x)
+ end
+end
+
+def fun_l3_n200(x)
+ if (x < 1)
+ fun_l4_n532(x)
+ else
+ fun_l4_n346(x)
+ end
+end
+
+def fun_l3_n201(x)
+ if (x < 1)
+ fun_l4_n340(x)
+ else
+ fun_l4_n129(x)
+ end
+end
+
+def fun_l3_n202(x)
+ if (x < 1)
+ fun_l4_n193(x)
+ else
+ fun_l4_n676(x)
+ end
+end
+
+def fun_l3_n203(x)
+ if (x < 1)
+ fun_l4_n210(x)
+ else
+ fun_l4_n982(x)
+ end
+end
+
+def fun_l3_n204(x)
+ if (x < 1)
+ fun_l4_n247(x)
+ else
+ fun_l4_n550(x)
+ end
+end
+
+def fun_l3_n205(x)
+ if (x < 1)
+ fun_l4_n727(x)
+ else
+ fun_l4_n737(x)
+ end
+end
+
+def fun_l3_n206(x)
+ if (x < 1)
+ fun_l4_n111(x)
+ else
+ fun_l4_n952(x)
+ end
+end
+
+def fun_l3_n207(x)
+ if (x < 1)
+ fun_l4_n996(x)
+ else
+ fun_l4_n865(x)
+ end
+end
+
+def fun_l3_n208(x)
+ if (x < 1)
+ fun_l4_n945(x)
+ else
+ fun_l4_n488(x)
+ end
+end
+
+def fun_l3_n209(x)
+ if (x < 1)
+ fun_l4_n697(x)
+ else
+ fun_l4_n366(x)
+ end
+end
+
+def fun_l3_n210(x)
+ if (x < 1)
+ fun_l4_n180(x)
+ else
+ fun_l4_n995(x)
+ end
+end
+
+def fun_l3_n211(x)
+ if (x < 1)
+ fun_l4_n972(x)
+ else
+ fun_l4_n783(x)
+ end
+end
+
+def fun_l3_n212(x)
+ if (x < 1)
+ fun_l4_n58(x)
+ else
+ fun_l4_n430(x)
+ end
+end
+
+def fun_l3_n213(x)
+ if (x < 1)
+ fun_l4_n904(x)
+ else
+ fun_l4_n703(x)
+ end
+end
+
+def fun_l3_n214(x)
+ if (x < 1)
+ fun_l4_n882(x)
+ else
+ fun_l4_n648(x)
+ end
+end
+
+def fun_l3_n215(x)
+ if (x < 1)
+ fun_l4_n800(x)
+ else
+ fun_l4_n680(x)
+ end
+end
+
+def fun_l3_n216(x)
+ if (x < 1)
+ fun_l4_n205(x)
+ else
+ fun_l4_n185(x)
+ end
+end
+
+def fun_l3_n217(x)
+ if (x < 1)
+ fun_l4_n242(x)
+ else
+ fun_l4_n834(x)
+ end
+end
+
+def fun_l3_n218(x)
+ if (x < 1)
+ fun_l4_n551(x)
+ else
+ fun_l4_n399(x)
+ end
+end
+
+def fun_l3_n219(x)
+ if (x < 1)
+ fun_l4_n820(x)
+ else
+ fun_l4_n403(x)
+ end
+end
+
+def fun_l3_n220(x)
+ if (x < 1)
+ fun_l4_n874(x)
+ else
+ fun_l4_n584(x)
+ end
+end
+
+def fun_l3_n221(x)
+ if (x < 1)
+ fun_l4_n845(x)
+ else
+ fun_l4_n56(x)
+ end
+end
+
+def fun_l3_n222(x)
+ if (x < 1)
+ fun_l4_n947(x)
+ else
+ fun_l4_n299(x)
+ end
+end
+
+def fun_l3_n223(x)
+ if (x < 1)
+ fun_l4_n533(x)
+ else
+ fun_l4_n184(x)
+ end
+end
+
+def fun_l3_n224(x)
+ if (x < 1)
+ fun_l4_n760(x)
+ else
+ fun_l4_n507(x)
+ end
+end
+
+def fun_l3_n225(x)
+ if (x < 1)
+ fun_l4_n47(x)
+ else
+ fun_l4_n712(x)
+ end
+end
+
+def fun_l3_n226(x)
+ if (x < 1)
+ fun_l4_n470(x)
+ else
+ fun_l4_n760(x)
+ end
+end
+
+def fun_l3_n227(x)
+ if (x < 1)
+ fun_l4_n932(x)
+ else
+ fun_l4_n292(x)
+ end
+end
+
+def fun_l3_n228(x)
+ if (x < 1)
+ fun_l4_n44(x)
+ else
+ fun_l4_n855(x)
+ end
+end
+
+def fun_l3_n229(x)
+ if (x < 1)
+ fun_l4_n385(x)
+ else
+ fun_l4_n284(x)
+ end
+end
+
+def fun_l3_n230(x)
+ if (x < 1)
+ fun_l4_n272(x)
+ else
+ fun_l4_n407(x)
+ end
+end
+
+def fun_l3_n231(x)
+ if (x < 1)
+ fun_l4_n820(x)
+ else
+ fun_l4_n375(x)
+ end
+end
+
+def fun_l3_n232(x)
+ if (x < 1)
+ fun_l4_n165(x)
+ else
+ fun_l4_n38(x)
+ end
+end
+
+def fun_l3_n233(x)
+ if (x < 1)
+ fun_l4_n772(x)
+ else
+ fun_l4_n179(x)
+ end
+end
+
+def fun_l3_n234(x)
+ if (x < 1)
+ fun_l4_n980(x)
+ else
+ fun_l4_n678(x)
+ end
+end
+
+def fun_l3_n235(x)
+ if (x < 1)
+ fun_l4_n279(x)
+ else
+ fun_l4_n834(x)
+ end
+end
+
+def fun_l3_n236(x)
+ if (x < 1)
+ fun_l4_n227(x)
+ else
+ fun_l4_n11(x)
+ end
+end
+
+def fun_l3_n237(x)
+ if (x < 1)
+ fun_l4_n724(x)
+ else
+ fun_l4_n659(x)
+ end
+end
+
+def fun_l3_n238(x)
+ if (x < 1)
+ fun_l4_n569(x)
+ else
+ fun_l4_n693(x)
+ end
+end
+
+def fun_l3_n239(x)
+ if (x < 1)
+ fun_l4_n933(x)
+ else
+ fun_l4_n897(x)
+ end
+end
+
+def fun_l3_n240(x)
+ if (x < 1)
+ fun_l4_n215(x)
+ else
+ fun_l4_n784(x)
+ end
+end
+
+def fun_l3_n241(x)
+ if (x < 1)
+ fun_l4_n964(x)
+ else
+ fun_l4_n430(x)
+ end
+end
+
+def fun_l3_n242(x)
+ if (x < 1)
+ fun_l4_n91(x)
+ else
+ fun_l4_n190(x)
+ end
+end
+
+def fun_l3_n243(x)
+ if (x < 1)
+ fun_l4_n375(x)
+ else
+ fun_l4_n638(x)
+ end
+end
+
+def fun_l3_n244(x)
+ if (x < 1)
+ fun_l4_n381(x)
+ else
+ fun_l4_n324(x)
+ end
+end
+
+def fun_l3_n245(x)
+ if (x < 1)
+ fun_l4_n983(x)
+ else
+ fun_l4_n248(x)
+ end
+end
+
+def fun_l3_n246(x)
+ if (x < 1)
+ fun_l4_n336(x)
+ else
+ fun_l4_n647(x)
+ end
+end
+
+def fun_l3_n247(x)
+ if (x < 1)
+ fun_l4_n64(x)
+ else
+ fun_l4_n957(x)
+ end
+end
+
+def fun_l3_n248(x)
+ if (x < 1)
+ fun_l4_n313(x)
+ else
+ fun_l4_n662(x)
+ end
+end
+
+def fun_l3_n249(x)
+ if (x < 1)
+ fun_l4_n528(x)
+ else
+ fun_l4_n448(x)
+ end
+end
+
+def fun_l3_n250(x)
+ if (x < 1)
+ fun_l4_n9(x)
+ else
+ fun_l4_n424(x)
+ end
+end
+
+def fun_l3_n251(x)
+ if (x < 1)
+ fun_l4_n290(x)
+ else
+ fun_l4_n416(x)
+ end
+end
+
+def fun_l3_n252(x)
+ if (x < 1)
+ fun_l4_n159(x)
+ else
+ fun_l4_n780(x)
+ end
+end
+
+def fun_l3_n253(x)
+ if (x < 1)
+ fun_l4_n863(x)
+ else
+ fun_l4_n192(x)
+ end
+end
+
+def fun_l3_n254(x)
+ if (x < 1)
+ fun_l4_n658(x)
+ else
+ fun_l4_n816(x)
+ end
+end
+
+def fun_l3_n255(x)
+ if (x < 1)
+ fun_l4_n686(x)
+ else
+ fun_l4_n586(x)
+ end
+end
+
+def fun_l3_n256(x)
+ if (x < 1)
+ fun_l4_n110(x)
+ else
+ fun_l4_n290(x)
+ end
+end
+
+def fun_l3_n257(x)
+ if (x < 1)
+ fun_l4_n355(x)
+ else
+ fun_l4_n862(x)
+ end
+end
+
+def fun_l3_n258(x)
+ if (x < 1)
+ fun_l4_n63(x)
+ else
+ fun_l4_n205(x)
+ end
+end
+
+def fun_l3_n259(x)
+ if (x < 1)
+ fun_l4_n766(x)
+ else
+ fun_l4_n130(x)
+ end
+end
+
+def fun_l3_n260(x)
+ if (x < 1)
+ fun_l4_n670(x)
+ else
+ fun_l4_n313(x)
+ end
+end
+
+def fun_l3_n261(x)
+ if (x < 1)
+ fun_l4_n738(x)
+ else
+ fun_l4_n796(x)
+ end
+end
+
+def fun_l3_n262(x)
+ if (x < 1)
+ fun_l4_n925(x)
+ else
+ fun_l4_n267(x)
+ end
+end
+
+def fun_l3_n263(x)
+ if (x < 1)
+ fun_l4_n515(x)
+ else
+ fun_l4_n298(x)
+ end
+end
+
+def fun_l3_n264(x)
+ if (x < 1)
+ fun_l4_n883(x)
+ else
+ fun_l4_n809(x)
+ end
+end
+
+def fun_l3_n265(x)
+ if (x < 1)
+ fun_l4_n138(x)
+ else
+ fun_l4_n665(x)
+ end
+end
+
+def fun_l3_n266(x)
+ if (x < 1)
+ fun_l4_n141(x)
+ else
+ fun_l4_n641(x)
+ end
+end
+
+def fun_l3_n267(x)
+ if (x < 1)
+ fun_l4_n936(x)
+ else
+ fun_l4_n233(x)
+ end
+end
+
+def fun_l3_n268(x)
+ if (x < 1)
+ fun_l4_n28(x)
+ else
+ fun_l4_n351(x)
+ end
+end
+
+def fun_l3_n269(x)
+ if (x < 1)
+ fun_l4_n62(x)
+ else
+ fun_l4_n17(x)
+ end
+end
+
+def fun_l3_n270(x)
+ if (x < 1)
+ fun_l4_n489(x)
+ else
+ fun_l4_n408(x)
+ end
+end
+
+def fun_l3_n271(x)
+ if (x < 1)
+ fun_l4_n276(x)
+ else
+ fun_l4_n799(x)
+ end
+end
+
+def fun_l3_n272(x)
+ if (x < 1)
+ fun_l4_n103(x)
+ else
+ fun_l4_n804(x)
+ end
+end
+
+def fun_l3_n273(x)
+ if (x < 1)
+ fun_l4_n850(x)
+ else
+ fun_l4_n388(x)
+ end
+end
+
+def fun_l3_n274(x)
+ if (x < 1)
+ fun_l4_n651(x)
+ else
+ fun_l4_n484(x)
+ end
+end
+
+def fun_l3_n275(x)
+ if (x < 1)
+ fun_l4_n693(x)
+ else
+ fun_l4_n20(x)
+ end
+end
+
+def fun_l3_n276(x)
+ if (x < 1)
+ fun_l4_n897(x)
+ else
+ fun_l4_n328(x)
+ end
+end
+
+def fun_l3_n277(x)
+ if (x < 1)
+ fun_l4_n632(x)
+ else
+ fun_l4_n120(x)
+ end
+end
+
+def fun_l3_n278(x)
+ if (x < 1)
+ fun_l4_n919(x)
+ else
+ fun_l4_n921(x)
+ end
+end
+
+def fun_l3_n279(x)
+ if (x < 1)
+ fun_l4_n461(x)
+ else
+ fun_l4_n219(x)
+ end
+end
+
+def fun_l3_n280(x)
+ if (x < 1)
+ fun_l4_n867(x)
+ else
+ fun_l4_n682(x)
+ end
+end
+
+def fun_l3_n281(x)
+ if (x < 1)
+ fun_l4_n233(x)
+ else
+ fun_l4_n589(x)
+ end
+end
+
+def fun_l3_n282(x)
+ if (x < 1)
+ fun_l4_n516(x)
+ else
+ fun_l4_n970(x)
+ end
+end
+
+def fun_l3_n283(x)
+ if (x < 1)
+ fun_l4_n300(x)
+ else
+ fun_l4_n934(x)
+ end
+end
+
+def fun_l3_n284(x)
+ if (x < 1)
+ fun_l4_n736(x)
+ else
+ fun_l4_n516(x)
+ end
+end
+
+def fun_l3_n285(x)
+ if (x < 1)
+ fun_l4_n401(x)
+ else
+ fun_l4_n539(x)
+ end
+end
+
+def fun_l3_n286(x)
+ if (x < 1)
+ fun_l4_n342(x)
+ else
+ fun_l4_n142(x)
+ end
+end
+
+def fun_l3_n287(x)
+ if (x < 1)
+ fun_l4_n44(x)
+ else
+ fun_l4_n311(x)
+ end
+end
+
+def fun_l3_n288(x)
+ if (x < 1)
+ fun_l4_n698(x)
+ else
+ fun_l4_n407(x)
+ end
+end
+
+def fun_l3_n289(x)
+ if (x < 1)
+ fun_l4_n714(x)
+ else
+ fun_l4_n324(x)
+ end
+end
+
+def fun_l3_n290(x)
+ if (x < 1)
+ fun_l4_n862(x)
+ else
+ fun_l4_n807(x)
+ end
+end
+
+def fun_l3_n291(x)
+ if (x < 1)
+ fun_l4_n446(x)
+ else
+ fun_l4_n378(x)
+ end
+end
+
+def fun_l3_n292(x)
+ if (x < 1)
+ fun_l4_n418(x)
+ else
+ fun_l4_n194(x)
+ end
+end
+
+def fun_l3_n293(x)
+ if (x < 1)
+ fun_l4_n336(x)
+ else
+ fun_l4_n895(x)
+ end
+end
+
+def fun_l3_n294(x)
+ if (x < 1)
+ fun_l4_n928(x)
+ else
+ fun_l4_n154(x)
+ end
+end
+
+def fun_l3_n295(x)
+ if (x < 1)
+ fun_l4_n764(x)
+ else
+ fun_l4_n335(x)
+ end
+end
+
+def fun_l3_n296(x)
+ if (x < 1)
+ fun_l4_n840(x)
+ else
+ fun_l4_n513(x)
+ end
+end
+
+def fun_l3_n297(x)
+ if (x < 1)
+ fun_l4_n520(x)
+ else
+ fun_l4_n838(x)
+ end
+end
+
+def fun_l3_n298(x)
+ if (x < 1)
+ fun_l4_n831(x)
+ else
+ fun_l4_n344(x)
+ end
+end
+
+def fun_l3_n299(x)
+ if (x < 1)
+ fun_l4_n110(x)
+ else
+ fun_l4_n19(x)
+ end
+end
+
+def fun_l3_n300(x)
+ if (x < 1)
+ fun_l4_n272(x)
+ else
+ fun_l4_n952(x)
+ end
+end
+
+def fun_l3_n301(x)
+ if (x < 1)
+ fun_l4_n659(x)
+ else
+ fun_l4_n439(x)
+ end
+end
+
+def fun_l3_n302(x)
+ if (x < 1)
+ fun_l4_n787(x)
+ else
+ fun_l4_n189(x)
+ end
+end
+
+def fun_l3_n303(x)
+ if (x < 1)
+ fun_l4_n549(x)
+ else
+ fun_l4_n594(x)
+ end
+end
+
+def fun_l3_n304(x)
+ if (x < 1)
+ fun_l4_n255(x)
+ else
+ fun_l4_n822(x)
+ end
+end
+
+def fun_l3_n305(x)
+ if (x < 1)
+ fun_l4_n312(x)
+ else
+ fun_l4_n935(x)
+ end
+end
+
+def fun_l3_n306(x)
+ if (x < 1)
+ fun_l4_n831(x)
+ else
+ fun_l4_n299(x)
+ end
+end
+
+def fun_l3_n307(x)
+ if (x < 1)
+ fun_l4_n154(x)
+ else
+ fun_l4_n520(x)
+ end
+end
+
+def fun_l3_n308(x)
+ if (x < 1)
+ fun_l4_n768(x)
+ else
+ fun_l4_n676(x)
+ end
+end
+
+def fun_l3_n309(x)
+ if (x < 1)
+ fun_l4_n816(x)
+ else
+ fun_l4_n447(x)
+ end
+end
+
+def fun_l3_n310(x)
+ if (x < 1)
+ fun_l4_n689(x)
+ else
+ fun_l4_n244(x)
+ end
+end
+
+def fun_l3_n311(x)
+ if (x < 1)
+ fun_l4_n389(x)
+ else
+ fun_l4_n326(x)
+ end
+end
+
+def fun_l3_n312(x)
+ if (x < 1)
+ fun_l4_n125(x)
+ else
+ fun_l4_n502(x)
+ end
+end
+
+def fun_l3_n313(x)
+ if (x < 1)
+ fun_l4_n327(x)
+ else
+ fun_l4_n123(x)
+ end
+end
+
+def fun_l3_n314(x)
+ if (x < 1)
+ fun_l4_n558(x)
+ else
+ fun_l4_n940(x)
+ end
+end
+
+def fun_l3_n315(x)
+ if (x < 1)
+ fun_l4_n652(x)
+ else
+ fun_l4_n10(x)
+ end
+end
+
+def fun_l3_n316(x)
+ if (x < 1)
+ fun_l4_n483(x)
+ else
+ fun_l4_n315(x)
+ end
+end
+
+def fun_l3_n317(x)
+ if (x < 1)
+ fun_l4_n567(x)
+ else
+ fun_l4_n540(x)
+ end
+end
+
+def fun_l3_n318(x)
+ if (x < 1)
+ fun_l4_n449(x)
+ else
+ fun_l4_n760(x)
+ end
+end
+
+def fun_l3_n319(x)
+ if (x < 1)
+ fun_l4_n111(x)
+ else
+ fun_l4_n173(x)
+ end
+end
+
+def fun_l3_n320(x)
+ if (x < 1)
+ fun_l4_n373(x)
+ else
+ fun_l4_n615(x)
+ end
+end
+
+def fun_l3_n321(x)
+ if (x < 1)
+ fun_l4_n570(x)
+ else
+ fun_l4_n27(x)
+ end
+end
+
+def fun_l3_n322(x)
+ if (x < 1)
+ fun_l4_n235(x)
+ else
+ fun_l4_n695(x)
+ end
+end
+
+def fun_l3_n323(x)
+ if (x < 1)
+ fun_l4_n788(x)
+ else
+ fun_l4_n57(x)
+ end
+end
+
+def fun_l3_n324(x)
+ if (x < 1)
+ fun_l4_n7(x)
+ else
+ fun_l4_n75(x)
+ end
+end
+
+def fun_l3_n325(x)
+ if (x < 1)
+ fun_l4_n502(x)
+ else
+ fun_l4_n459(x)
+ end
+end
+
+def fun_l3_n326(x)
+ if (x < 1)
+ fun_l4_n572(x)
+ else
+ fun_l4_n324(x)
+ end
+end
+
+def fun_l3_n327(x)
+ if (x < 1)
+ fun_l4_n860(x)
+ else
+ fun_l4_n250(x)
+ end
+end
+
+def fun_l3_n328(x)
+ if (x < 1)
+ fun_l4_n242(x)
+ else
+ fun_l4_n667(x)
+ end
+end
+
+def fun_l3_n329(x)
+ if (x < 1)
+ fun_l4_n589(x)
+ else
+ fun_l4_n236(x)
+ end
+end
+
+def fun_l3_n330(x)
+ if (x < 1)
+ fun_l4_n100(x)
+ else
+ fun_l4_n476(x)
+ end
+end
+
+def fun_l3_n331(x)
+ if (x < 1)
+ fun_l4_n779(x)
+ else
+ fun_l4_n667(x)
+ end
+end
+
+def fun_l3_n332(x)
+ if (x < 1)
+ fun_l4_n277(x)
+ else
+ fun_l4_n441(x)
+ end
+end
+
+def fun_l3_n333(x)
+ if (x < 1)
+ fun_l4_n379(x)
+ else
+ fun_l4_n331(x)
+ end
+end
+
+def fun_l3_n334(x)
+ if (x < 1)
+ fun_l4_n802(x)
+ else
+ fun_l4_n588(x)
+ end
+end
+
+def fun_l3_n335(x)
+ if (x < 1)
+ fun_l4_n385(x)
+ else
+ fun_l4_n918(x)
+ end
+end
+
+def fun_l3_n336(x)
+ if (x < 1)
+ fun_l4_n532(x)
+ else
+ fun_l4_n254(x)
+ end
+end
+
+def fun_l3_n337(x)
+ if (x < 1)
+ fun_l4_n920(x)
+ else
+ fun_l4_n134(x)
+ end
+end
+
+def fun_l3_n338(x)
+ if (x < 1)
+ fun_l4_n803(x)
+ else
+ fun_l4_n746(x)
+ end
+end
+
+def fun_l3_n339(x)
+ if (x < 1)
+ fun_l4_n924(x)
+ else
+ fun_l4_n878(x)
+ end
+end
+
+def fun_l3_n340(x)
+ if (x < 1)
+ fun_l4_n166(x)
+ else
+ fun_l4_n776(x)
+ end
+end
+
+def fun_l3_n341(x)
+ if (x < 1)
+ fun_l4_n240(x)
+ else
+ fun_l4_n898(x)
+ end
+end
+
+def fun_l3_n342(x)
+ if (x < 1)
+ fun_l4_n810(x)
+ else
+ fun_l4_n423(x)
+ end
+end
+
+def fun_l3_n343(x)
+ if (x < 1)
+ fun_l4_n209(x)
+ else
+ fun_l4_n514(x)
+ end
+end
+
+def fun_l3_n344(x)
+ if (x < 1)
+ fun_l4_n505(x)
+ else
+ fun_l4_n321(x)
+ end
+end
+
+def fun_l3_n345(x)
+ if (x < 1)
+ fun_l4_n88(x)
+ else
+ fun_l4_n39(x)
+ end
+end
+
+def fun_l3_n346(x)
+ if (x < 1)
+ fun_l4_n848(x)
+ else
+ fun_l4_n357(x)
+ end
+end
+
+def fun_l3_n347(x)
+ if (x < 1)
+ fun_l4_n450(x)
+ else
+ fun_l4_n704(x)
+ end
+end
+
+def fun_l3_n348(x)
+ if (x < 1)
+ fun_l4_n881(x)
+ else
+ fun_l4_n916(x)
+ end
+end
+
+def fun_l3_n349(x)
+ if (x < 1)
+ fun_l4_n16(x)
+ else
+ fun_l4_n996(x)
+ end
+end
+
+def fun_l3_n350(x)
+ if (x < 1)
+ fun_l4_n839(x)
+ else
+ fun_l4_n697(x)
+ end
+end
+
+def fun_l3_n351(x)
+ if (x < 1)
+ fun_l4_n177(x)
+ else
+ fun_l4_n859(x)
+ end
+end
+
+def fun_l3_n352(x)
+ if (x < 1)
+ fun_l4_n684(x)
+ else
+ fun_l4_n778(x)
+ end
+end
+
+def fun_l3_n353(x)
+ if (x < 1)
+ fun_l4_n604(x)
+ else
+ fun_l4_n280(x)
+ end
+end
+
+def fun_l3_n354(x)
+ if (x < 1)
+ fun_l4_n366(x)
+ else
+ fun_l4_n576(x)
+ end
+end
+
+def fun_l3_n355(x)
+ if (x < 1)
+ fun_l4_n584(x)
+ else
+ fun_l4_n228(x)
+ end
+end
+
+def fun_l3_n356(x)
+ if (x < 1)
+ fun_l4_n844(x)
+ else
+ fun_l4_n799(x)
+ end
+end
+
+def fun_l3_n357(x)
+ if (x < 1)
+ fun_l4_n489(x)
+ else
+ fun_l4_n905(x)
+ end
+end
+
+def fun_l3_n358(x)
+ if (x < 1)
+ fun_l4_n781(x)
+ else
+ fun_l4_n565(x)
+ end
+end
+
+def fun_l3_n359(x)
+ if (x < 1)
+ fun_l4_n110(x)
+ else
+ fun_l4_n326(x)
+ end
+end
+
+def fun_l3_n360(x)
+ if (x < 1)
+ fun_l4_n915(x)
+ else
+ fun_l4_n489(x)
+ end
+end
+
+def fun_l3_n361(x)
+ if (x < 1)
+ fun_l4_n110(x)
+ else
+ fun_l4_n733(x)
+ end
+end
+
+def fun_l3_n362(x)
+ if (x < 1)
+ fun_l4_n93(x)
+ else
+ fun_l4_n549(x)
+ end
+end
+
+def fun_l3_n363(x)
+ if (x < 1)
+ fun_l4_n270(x)
+ else
+ fun_l4_n883(x)
+ end
+end
+
+def fun_l3_n364(x)
+ if (x < 1)
+ fun_l4_n512(x)
+ else
+ fun_l4_n555(x)
+ end
+end
+
+def fun_l3_n365(x)
+ if (x < 1)
+ fun_l4_n800(x)
+ else
+ fun_l4_n672(x)
+ end
+end
+
+def fun_l3_n366(x)
+ if (x < 1)
+ fun_l4_n535(x)
+ else
+ fun_l4_n320(x)
+ end
+end
+
+def fun_l3_n367(x)
+ if (x < 1)
+ fun_l4_n883(x)
+ else
+ fun_l4_n365(x)
+ end
+end
+
+def fun_l3_n368(x)
+ if (x < 1)
+ fun_l4_n306(x)
+ else
+ fun_l4_n614(x)
+ end
+end
+
+def fun_l3_n369(x)
+ if (x < 1)
+ fun_l4_n914(x)
+ else
+ fun_l4_n20(x)
+ end
+end
+
+def fun_l3_n370(x)
+ if (x < 1)
+ fun_l4_n230(x)
+ else
+ fun_l4_n585(x)
+ end
+end
+
+def fun_l3_n371(x)
+ if (x < 1)
+ fun_l4_n544(x)
+ else
+ fun_l4_n752(x)
+ end
+end
+
+def fun_l3_n372(x)
+ if (x < 1)
+ fun_l4_n984(x)
+ else
+ fun_l4_n738(x)
+ end
+end
+
+def fun_l3_n373(x)
+ if (x < 1)
+ fun_l4_n478(x)
+ else
+ fun_l4_n618(x)
+ end
+end
+
+def fun_l3_n374(x)
+ if (x < 1)
+ fun_l4_n941(x)
+ else
+ fun_l4_n746(x)
+ end
+end
+
+def fun_l3_n375(x)
+ if (x < 1)
+ fun_l4_n121(x)
+ else
+ fun_l4_n798(x)
+ end
+end
+
+def fun_l3_n376(x)
+ if (x < 1)
+ fun_l4_n851(x)
+ else
+ fun_l4_n681(x)
+ end
+end
+
+def fun_l3_n377(x)
+ if (x < 1)
+ fun_l4_n502(x)
+ else
+ fun_l4_n538(x)
+ end
+end
+
+def fun_l3_n378(x)
+ if (x < 1)
+ fun_l4_n432(x)
+ else
+ fun_l4_n226(x)
+ end
+end
+
+def fun_l3_n379(x)
+ if (x < 1)
+ fun_l4_n734(x)
+ else
+ fun_l4_n684(x)
+ end
+end
+
+def fun_l3_n380(x)
+ if (x < 1)
+ fun_l4_n912(x)
+ else
+ fun_l4_n116(x)
+ end
+end
+
+def fun_l3_n381(x)
+ if (x < 1)
+ fun_l4_n291(x)
+ else
+ fun_l4_n464(x)
+ end
+end
+
+def fun_l3_n382(x)
+ if (x < 1)
+ fun_l4_n285(x)
+ else
+ fun_l4_n943(x)
+ end
+end
+
+def fun_l3_n383(x)
+ if (x < 1)
+ fun_l4_n738(x)
+ else
+ fun_l4_n532(x)
+ end
+end
+
+def fun_l3_n384(x)
+ if (x < 1)
+ fun_l4_n503(x)
+ else
+ fun_l4_n724(x)
+ end
+end
+
+def fun_l3_n385(x)
+ if (x < 1)
+ fun_l4_n208(x)
+ else
+ fun_l4_n683(x)
+ end
+end
+
+def fun_l3_n386(x)
+ if (x < 1)
+ fun_l4_n673(x)
+ else
+ fun_l4_n230(x)
+ end
+end
+
+def fun_l3_n387(x)
+ if (x < 1)
+ fun_l4_n921(x)
+ else
+ fun_l4_n800(x)
+ end
+end
+
+def fun_l3_n388(x)
+ if (x < 1)
+ fun_l4_n461(x)
+ else
+ fun_l4_n369(x)
+ end
+end
+
+def fun_l3_n389(x)
+ if (x < 1)
+ fun_l4_n86(x)
+ else
+ fun_l4_n403(x)
+ end
+end
+
+def fun_l3_n390(x)
+ if (x < 1)
+ fun_l4_n883(x)
+ else
+ fun_l4_n92(x)
+ end
+end
+
+def fun_l3_n391(x)
+ if (x < 1)
+ fun_l4_n562(x)
+ else
+ fun_l4_n826(x)
+ end
+end
+
+def fun_l3_n392(x)
+ if (x < 1)
+ fun_l4_n459(x)
+ else
+ fun_l4_n821(x)
+ end
+end
+
+def fun_l3_n393(x)
+ if (x < 1)
+ fun_l4_n774(x)
+ else
+ fun_l4_n376(x)
+ end
+end
+
+def fun_l3_n394(x)
+ if (x < 1)
+ fun_l4_n114(x)
+ else
+ fun_l4_n451(x)
+ end
+end
+
+def fun_l3_n395(x)
+ if (x < 1)
+ fun_l4_n689(x)
+ else
+ fun_l4_n13(x)
+ end
+end
+
+def fun_l3_n396(x)
+ if (x < 1)
+ fun_l4_n929(x)
+ else
+ fun_l4_n777(x)
+ end
+end
+
+def fun_l3_n397(x)
+ if (x < 1)
+ fun_l4_n634(x)
+ else
+ fun_l4_n329(x)
+ end
+end
+
+def fun_l3_n398(x)
+ if (x < 1)
+ fun_l4_n972(x)
+ else
+ fun_l4_n572(x)
+ end
+end
+
+def fun_l3_n399(x)
+ if (x < 1)
+ fun_l4_n231(x)
+ else
+ fun_l4_n14(x)
+ end
+end
+
+def fun_l3_n400(x)
+ if (x < 1)
+ fun_l4_n357(x)
+ else
+ fun_l4_n881(x)
+ end
+end
+
+def fun_l3_n401(x)
+ if (x < 1)
+ fun_l4_n283(x)
+ else
+ fun_l4_n614(x)
+ end
+end
+
+def fun_l3_n402(x)
+ if (x < 1)
+ fun_l4_n634(x)
+ else
+ fun_l4_n653(x)
+ end
+end
+
+def fun_l3_n403(x)
+ if (x < 1)
+ fun_l4_n660(x)
+ else
+ fun_l4_n127(x)
+ end
+end
+
+def fun_l3_n404(x)
+ if (x < 1)
+ fun_l4_n523(x)
+ else
+ fun_l4_n467(x)
+ end
+end
+
+def fun_l3_n405(x)
+ if (x < 1)
+ fun_l4_n593(x)
+ else
+ fun_l4_n78(x)
+ end
+end
+
+def fun_l3_n406(x)
+ if (x < 1)
+ fun_l4_n514(x)
+ else
+ fun_l4_n783(x)
+ end
+end
+
+def fun_l3_n407(x)
+ if (x < 1)
+ fun_l4_n460(x)
+ else
+ fun_l4_n137(x)
+ end
+end
+
+def fun_l3_n408(x)
+ if (x < 1)
+ fun_l4_n3(x)
+ else
+ fun_l4_n224(x)
+ end
+end
+
+def fun_l3_n409(x)
+ if (x < 1)
+ fun_l4_n11(x)
+ else
+ fun_l4_n531(x)
+ end
+end
+
+def fun_l3_n410(x)
+ if (x < 1)
+ fun_l4_n94(x)
+ else
+ fun_l4_n717(x)
+ end
+end
+
+def fun_l3_n411(x)
+ if (x < 1)
+ fun_l4_n729(x)
+ else
+ fun_l4_n526(x)
+ end
+end
+
+def fun_l3_n412(x)
+ if (x < 1)
+ fun_l4_n86(x)
+ else
+ fun_l4_n26(x)
+ end
+end
+
+def fun_l3_n413(x)
+ if (x < 1)
+ fun_l4_n249(x)
+ else
+ fun_l4_n572(x)
+ end
+end
+
+def fun_l3_n414(x)
+ if (x < 1)
+ fun_l4_n578(x)
+ else
+ fun_l4_n512(x)
+ end
+end
+
+def fun_l3_n415(x)
+ if (x < 1)
+ fun_l4_n176(x)
+ else
+ fun_l4_n414(x)
+ end
+end
+
+def fun_l3_n416(x)
+ if (x < 1)
+ fun_l4_n757(x)
+ else
+ fun_l4_n385(x)
+ end
+end
+
+def fun_l3_n417(x)
+ if (x < 1)
+ fun_l4_n249(x)
+ else
+ fun_l4_n180(x)
+ end
+end
+
+def fun_l3_n418(x)
+ if (x < 1)
+ fun_l4_n193(x)
+ else
+ fun_l4_n294(x)
+ end
+end
+
+def fun_l3_n419(x)
+ if (x < 1)
+ fun_l4_n441(x)
+ else
+ fun_l4_n932(x)
+ end
+end
+
+def fun_l3_n420(x)
+ if (x < 1)
+ fun_l4_n492(x)
+ else
+ fun_l4_n239(x)
+ end
+end
+
+def fun_l3_n421(x)
+ if (x < 1)
+ fun_l4_n49(x)
+ else
+ fun_l4_n738(x)
+ end
+end
+
+def fun_l3_n422(x)
+ if (x < 1)
+ fun_l4_n546(x)
+ else
+ fun_l4_n285(x)
+ end
+end
+
+def fun_l3_n423(x)
+ if (x < 1)
+ fun_l4_n687(x)
+ else
+ fun_l4_n973(x)
+ end
+end
+
+def fun_l3_n424(x)
+ if (x < 1)
+ fun_l4_n876(x)
+ else
+ fun_l4_n591(x)
+ end
+end
+
+def fun_l3_n425(x)
+ if (x < 1)
+ fun_l4_n626(x)
+ else
+ fun_l4_n739(x)
+ end
+end
+
+def fun_l3_n426(x)
+ if (x < 1)
+ fun_l4_n439(x)
+ else
+ fun_l4_n709(x)
+ end
+end
+
+def fun_l3_n427(x)
+ if (x < 1)
+ fun_l4_n710(x)
+ else
+ fun_l4_n305(x)
+ end
+end
+
+def fun_l3_n428(x)
+ if (x < 1)
+ fun_l4_n61(x)
+ else
+ fun_l4_n520(x)
+ end
+end
+
+def fun_l3_n429(x)
+ if (x < 1)
+ fun_l4_n172(x)
+ else
+ fun_l4_n12(x)
+ end
+end
+
+def fun_l3_n430(x)
+ if (x < 1)
+ fun_l4_n432(x)
+ else
+ fun_l4_n174(x)
+ end
+end
+
+def fun_l3_n431(x)
+ if (x < 1)
+ fun_l4_n194(x)
+ else
+ fun_l4_n673(x)
+ end
+end
+
+def fun_l3_n432(x)
+ if (x < 1)
+ fun_l4_n952(x)
+ else
+ fun_l4_n798(x)
+ end
+end
+
+def fun_l3_n433(x)
+ if (x < 1)
+ fun_l4_n915(x)
+ else
+ fun_l4_n263(x)
+ end
+end
+
+def fun_l3_n434(x)
+ if (x < 1)
+ fun_l4_n735(x)
+ else
+ fun_l4_n882(x)
+ end
+end
+
+def fun_l3_n435(x)
+ if (x < 1)
+ fun_l4_n499(x)
+ else
+ fun_l4_n947(x)
+ end
+end
+
+def fun_l3_n436(x)
+ if (x < 1)
+ fun_l4_n744(x)
+ else
+ fun_l4_n187(x)
+ end
+end
+
+def fun_l3_n437(x)
+ if (x < 1)
+ fun_l4_n244(x)
+ else
+ fun_l4_n366(x)
+ end
+end
+
+def fun_l3_n438(x)
+ if (x < 1)
+ fun_l4_n228(x)
+ else
+ fun_l4_n866(x)
+ end
+end
+
+def fun_l3_n439(x)
+ if (x < 1)
+ fun_l4_n617(x)
+ else
+ fun_l4_n924(x)
+ end
+end
+
+def fun_l3_n440(x)
+ if (x < 1)
+ fun_l4_n302(x)
+ else
+ fun_l4_n691(x)
+ end
+end
+
+def fun_l3_n441(x)
+ if (x < 1)
+ fun_l4_n559(x)
+ else
+ fun_l4_n758(x)
+ end
+end
+
+def fun_l3_n442(x)
+ if (x < 1)
+ fun_l4_n412(x)
+ else
+ fun_l4_n544(x)
+ end
+end
+
+def fun_l3_n443(x)
+ if (x < 1)
+ fun_l4_n130(x)
+ else
+ fun_l4_n764(x)
+ end
+end
+
+def fun_l3_n444(x)
+ if (x < 1)
+ fun_l4_n135(x)
+ else
+ fun_l4_n65(x)
+ end
+end
+
+def fun_l3_n445(x)
+ if (x < 1)
+ fun_l4_n224(x)
+ else
+ fun_l4_n148(x)
+ end
+end
+
+def fun_l3_n446(x)
+ if (x < 1)
+ fun_l4_n238(x)
+ else
+ fun_l4_n808(x)
+ end
+end
+
+def fun_l3_n447(x)
+ if (x < 1)
+ fun_l4_n832(x)
+ else
+ fun_l4_n460(x)
+ end
+end
+
+def fun_l3_n448(x)
+ if (x < 1)
+ fun_l4_n897(x)
+ else
+ fun_l4_n817(x)
+ end
+end
+
+def fun_l3_n449(x)
+ if (x < 1)
+ fun_l4_n587(x)
+ else
+ fun_l4_n926(x)
+ end
+end
+
+def fun_l3_n450(x)
+ if (x < 1)
+ fun_l4_n575(x)
+ else
+ fun_l4_n274(x)
+ end
+end
+
+def fun_l3_n451(x)
+ if (x < 1)
+ fun_l4_n42(x)
+ else
+ fun_l4_n714(x)
+ end
+end
+
+def fun_l3_n452(x)
+ if (x < 1)
+ fun_l4_n101(x)
+ else
+ fun_l4_n470(x)
+ end
+end
+
+def fun_l3_n453(x)
+ if (x < 1)
+ fun_l4_n906(x)
+ else
+ fun_l4_n724(x)
+ end
+end
+
+def fun_l3_n454(x)
+ if (x < 1)
+ fun_l4_n682(x)
+ else
+ fun_l4_n709(x)
+ end
+end
+
+def fun_l3_n455(x)
+ if (x < 1)
+ fun_l4_n929(x)
+ else
+ fun_l4_n274(x)
+ end
+end
+
+def fun_l3_n456(x)
+ if (x < 1)
+ fun_l4_n10(x)
+ else
+ fun_l4_n101(x)
+ end
+end
+
+def fun_l3_n457(x)
+ if (x < 1)
+ fun_l4_n825(x)
+ else
+ fun_l4_n632(x)
+ end
+end
+
+def fun_l3_n458(x)
+ if (x < 1)
+ fun_l4_n2(x)
+ else
+ fun_l4_n723(x)
+ end
+end
+
+def fun_l3_n459(x)
+ if (x < 1)
+ fun_l4_n998(x)
+ else
+ fun_l4_n546(x)
+ end
+end
+
+def fun_l3_n460(x)
+ if (x < 1)
+ fun_l4_n483(x)
+ else
+ fun_l4_n445(x)
+ end
+end
+
+def fun_l3_n461(x)
+ if (x < 1)
+ fun_l4_n896(x)
+ else
+ fun_l4_n993(x)
+ end
+end
+
+def fun_l3_n462(x)
+ if (x < 1)
+ fun_l4_n710(x)
+ else
+ fun_l4_n529(x)
+ end
+end
+
+def fun_l3_n463(x)
+ if (x < 1)
+ fun_l4_n913(x)
+ else
+ fun_l4_n65(x)
+ end
+end
+
+def fun_l3_n464(x)
+ if (x < 1)
+ fun_l4_n712(x)
+ else
+ fun_l4_n412(x)
+ end
+end
+
+def fun_l3_n465(x)
+ if (x < 1)
+ fun_l4_n296(x)
+ else
+ fun_l4_n37(x)
+ end
+end
+
+def fun_l3_n466(x)
+ if (x < 1)
+ fun_l4_n241(x)
+ else
+ fun_l4_n649(x)
+ end
+end
+
+def fun_l3_n467(x)
+ if (x < 1)
+ fun_l4_n296(x)
+ else
+ fun_l4_n80(x)
+ end
+end
+
+def fun_l3_n468(x)
+ if (x < 1)
+ fun_l4_n270(x)
+ else
+ fun_l4_n192(x)
+ end
+end
+
+def fun_l3_n469(x)
+ if (x < 1)
+ fun_l4_n655(x)
+ else
+ fun_l4_n605(x)
+ end
+end
+
+def fun_l3_n470(x)
+ if (x < 1)
+ fun_l4_n180(x)
+ else
+ fun_l4_n807(x)
+ end
+end
+
+def fun_l3_n471(x)
+ if (x < 1)
+ fun_l4_n915(x)
+ else
+ fun_l4_n902(x)
+ end
+end
+
+def fun_l3_n472(x)
+ if (x < 1)
+ fun_l4_n527(x)
+ else
+ fun_l4_n638(x)
+ end
+end
+
+def fun_l3_n473(x)
+ if (x < 1)
+ fun_l4_n775(x)
+ else
+ fun_l4_n572(x)
+ end
+end
+
+def fun_l3_n474(x)
+ if (x < 1)
+ fun_l4_n856(x)
+ else
+ fun_l4_n182(x)
+ end
+end
+
+def fun_l3_n475(x)
+ if (x < 1)
+ fun_l4_n434(x)
+ else
+ fun_l4_n232(x)
+ end
+end
+
+def fun_l3_n476(x)
+ if (x < 1)
+ fun_l4_n208(x)
+ else
+ fun_l4_n37(x)
+ end
+end
+
+def fun_l3_n477(x)
+ if (x < 1)
+ fun_l4_n146(x)
+ else
+ fun_l4_n764(x)
+ end
+end
+
+def fun_l3_n478(x)
+ if (x < 1)
+ fun_l4_n806(x)
+ else
+ fun_l4_n148(x)
+ end
+end
+
+def fun_l3_n479(x)
+ if (x < 1)
+ fun_l4_n46(x)
+ else
+ fun_l4_n488(x)
+ end
+end
+
+def fun_l3_n480(x)
+ if (x < 1)
+ fun_l4_n637(x)
+ else
+ fun_l4_n48(x)
+ end
+end
+
+def fun_l3_n481(x)
+ if (x < 1)
+ fun_l4_n496(x)
+ else
+ fun_l4_n891(x)
+ end
+end
+
+def fun_l3_n482(x)
+ if (x < 1)
+ fun_l4_n282(x)
+ else
+ fun_l4_n736(x)
+ end
+end
+
+def fun_l3_n483(x)
+ if (x < 1)
+ fun_l4_n377(x)
+ else
+ fun_l4_n603(x)
+ end
+end
+
+def fun_l3_n484(x)
+ if (x < 1)
+ fun_l4_n689(x)
+ else
+ fun_l4_n201(x)
+ end
+end
+
+def fun_l3_n485(x)
+ if (x < 1)
+ fun_l4_n495(x)
+ else
+ fun_l4_n721(x)
+ end
+end
+
+def fun_l3_n486(x)
+ if (x < 1)
+ fun_l4_n128(x)
+ else
+ fun_l4_n400(x)
+ end
+end
+
+def fun_l3_n487(x)
+ if (x < 1)
+ fun_l4_n993(x)
+ else
+ fun_l4_n53(x)
+ end
+end
+
+def fun_l3_n488(x)
+ if (x < 1)
+ fun_l4_n913(x)
+ else
+ fun_l4_n814(x)
+ end
+end
+
+def fun_l3_n489(x)
+ if (x < 1)
+ fun_l4_n816(x)
+ else
+ fun_l4_n196(x)
+ end
+end
+
+def fun_l3_n490(x)
+ if (x < 1)
+ fun_l4_n754(x)
+ else
+ fun_l4_n451(x)
+ end
+end
+
+def fun_l3_n491(x)
+ if (x < 1)
+ fun_l4_n57(x)
+ else
+ fun_l4_n597(x)
+ end
+end
+
+def fun_l3_n492(x)
+ if (x < 1)
+ fun_l4_n539(x)
+ else
+ fun_l4_n893(x)
+ end
+end
+
+def fun_l3_n493(x)
+ if (x < 1)
+ fun_l4_n542(x)
+ else
+ fun_l4_n956(x)
+ end
+end
+
+def fun_l3_n494(x)
+ if (x < 1)
+ fun_l4_n479(x)
+ else
+ fun_l4_n448(x)
+ end
+end
+
+def fun_l3_n495(x)
+ if (x < 1)
+ fun_l4_n263(x)
+ else
+ fun_l4_n912(x)
+ end
+end
+
+def fun_l3_n496(x)
+ if (x < 1)
+ fun_l4_n463(x)
+ else
+ fun_l4_n112(x)
+ end
+end
+
+def fun_l3_n497(x)
+ if (x < 1)
+ fun_l4_n806(x)
+ else
+ fun_l4_n486(x)
+ end
+end
+
+def fun_l3_n498(x)
+ if (x < 1)
+ fun_l4_n155(x)
+ else
+ fun_l4_n298(x)
+ end
+end
+
+def fun_l3_n499(x)
+ if (x < 1)
+ fun_l4_n538(x)
+ else
+ fun_l4_n908(x)
+ end
+end
+
+def fun_l3_n500(x)
+ if (x < 1)
+ fun_l4_n769(x)
+ else
+ fun_l4_n681(x)
+ end
+end
+
+def fun_l3_n501(x)
+ if (x < 1)
+ fun_l4_n544(x)
+ else
+ fun_l4_n749(x)
+ end
+end
+
+def fun_l3_n502(x)
+ if (x < 1)
+ fun_l4_n505(x)
+ else
+ fun_l4_n66(x)
+ end
+end
+
+def fun_l3_n503(x)
+ if (x < 1)
+ fun_l4_n900(x)
+ else
+ fun_l4_n917(x)
+ end
+end
+
+def fun_l3_n504(x)
+ if (x < 1)
+ fun_l4_n982(x)
+ else
+ fun_l4_n707(x)
+ end
+end
+
+def fun_l3_n505(x)
+ if (x < 1)
+ fun_l4_n102(x)
+ else
+ fun_l4_n564(x)
+ end
+end
+
+def fun_l3_n506(x)
+ if (x < 1)
+ fun_l4_n332(x)
+ else
+ fun_l4_n367(x)
+ end
+end
+
+def fun_l3_n507(x)
+ if (x < 1)
+ fun_l4_n969(x)
+ else
+ fun_l4_n354(x)
+ end
+end
+
+def fun_l3_n508(x)
+ if (x < 1)
+ fun_l4_n405(x)
+ else
+ fun_l4_n485(x)
+ end
+end
+
+def fun_l3_n509(x)
+ if (x < 1)
+ fun_l4_n477(x)
+ else
+ fun_l4_n629(x)
+ end
+end
+
+def fun_l3_n510(x)
+ if (x < 1)
+ fun_l4_n753(x)
+ else
+ fun_l4_n78(x)
+ end
+end
+
+def fun_l3_n511(x)
+ if (x < 1)
+ fun_l4_n221(x)
+ else
+ fun_l4_n637(x)
+ end
+end
+
+def fun_l3_n512(x)
+ if (x < 1)
+ fun_l4_n540(x)
+ else
+ fun_l4_n267(x)
+ end
+end
+
+def fun_l3_n513(x)
+ if (x < 1)
+ fun_l4_n750(x)
+ else
+ fun_l4_n626(x)
+ end
+end
+
+def fun_l3_n514(x)
+ if (x < 1)
+ fun_l4_n160(x)
+ else
+ fun_l4_n32(x)
+ end
+end
+
+def fun_l3_n515(x)
+ if (x < 1)
+ fun_l4_n914(x)
+ else
+ fun_l4_n967(x)
+ end
+end
+
+def fun_l3_n516(x)
+ if (x < 1)
+ fun_l4_n380(x)
+ else
+ fun_l4_n83(x)
+ end
+end
+
+def fun_l3_n517(x)
+ if (x < 1)
+ fun_l4_n175(x)
+ else
+ fun_l4_n830(x)
+ end
+end
+
+def fun_l3_n518(x)
+ if (x < 1)
+ fun_l4_n579(x)
+ else
+ fun_l4_n773(x)
+ end
+end
+
+def fun_l3_n519(x)
+ if (x < 1)
+ fun_l4_n707(x)
+ else
+ fun_l4_n690(x)
+ end
+end
+
+def fun_l3_n520(x)
+ if (x < 1)
+ fun_l4_n587(x)
+ else
+ fun_l4_n754(x)
+ end
+end
+
+def fun_l3_n521(x)
+ if (x < 1)
+ fun_l4_n922(x)
+ else
+ fun_l4_n156(x)
+ end
+end
+
+def fun_l3_n522(x)
+ if (x < 1)
+ fun_l4_n299(x)
+ else
+ fun_l4_n937(x)
+ end
+end
+
+def fun_l3_n523(x)
+ if (x < 1)
+ fun_l4_n996(x)
+ else
+ fun_l4_n786(x)
+ end
+end
+
+def fun_l3_n524(x)
+ if (x < 1)
+ fun_l4_n988(x)
+ else
+ fun_l4_n930(x)
+ end
+end
+
+def fun_l3_n525(x)
+ if (x < 1)
+ fun_l4_n475(x)
+ else
+ fun_l4_n43(x)
+ end
+end
+
+def fun_l3_n526(x)
+ if (x < 1)
+ fun_l4_n367(x)
+ else
+ fun_l4_n167(x)
+ end
+end
+
+def fun_l3_n527(x)
+ if (x < 1)
+ fun_l4_n31(x)
+ else
+ fun_l4_n394(x)
+ end
+end
+
+def fun_l3_n528(x)
+ if (x < 1)
+ fun_l4_n92(x)
+ else
+ fun_l4_n304(x)
+ end
+end
+
+def fun_l3_n529(x)
+ if (x < 1)
+ fun_l4_n369(x)
+ else
+ fun_l4_n458(x)
+ end
+end
+
+def fun_l3_n530(x)
+ if (x < 1)
+ fun_l4_n475(x)
+ else
+ fun_l4_n8(x)
+ end
+end
+
+def fun_l3_n531(x)
+ if (x < 1)
+ fun_l4_n678(x)
+ else
+ fun_l4_n970(x)
+ end
+end
+
+def fun_l3_n532(x)
+ if (x < 1)
+ fun_l4_n349(x)
+ else
+ fun_l4_n853(x)
+ end
+end
+
+def fun_l3_n533(x)
+ if (x < 1)
+ fun_l4_n918(x)
+ else
+ fun_l4_n820(x)
+ end
+end
+
+def fun_l3_n534(x)
+ if (x < 1)
+ fun_l4_n369(x)
+ else
+ fun_l4_n445(x)
+ end
+end
+
+def fun_l3_n535(x)
+ if (x < 1)
+ fun_l4_n437(x)
+ else
+ fun_l4_n930(x)
+ end
+end
+
+def fun_l3_n536(x)
+ if (x < 1)
+ fun_l4_n143(x)
+ else
+ fun_l4_n986(x)
+ end
+end
+
+def fun_l3_n537(x)
+ if (x < 1)
+ fun_l4_n603(x)
+ else
+ fun_l4_n818(x)
+ end
+end
+
+def fun_l3_n538(x)
+ if (x < 1)
+ fun_l4_n14(x)
+ else
+ fun_l4_n994(x)
+ end
+end
+
+def fun_l3_n539(x)
+ if (x < 1)
+ fun_l4_n650(x)
+ else
+ fun_l4_n115(x)
+ end
+end
+
+def fun_l3_n540(x)
+ if (x < 1)
+ fun_l4_n74(x)
+ else
+ fun_l4_n559(x)
+ end
+end
+
+def fun_l3_n541(x)
+ if (x < 1)
+ fun_l4_n601(x)
+ else
+ fun_l4_n756(x)
+ end
+end
+
+def fun_l3_n542(x)
+ if (x < 1)
+ fun_l4_n733(x)
+ else
+ fun_l4_n274(x)
+ end
+end
+
+def fun_l3_n543(x)
+ if (x < 1)
+ fun_l4_n819(x)
+ else
+ fun_l4_n97(x)
+ end
+end
+
+def fun_l3_n544(x)
+ if (x < 1)
+ fun_l4_n949(x)
+ else
+ fun_l4_n868(x)
+ end
+end
+
+def fun_l3_n545(x)
+ if (x < 1)
+ fun_l4_n346(x)
+ else
+ fun_l4_n0(x)
+ end
+end
+
+def fun_l3_n546(x)
+ if (x < 1)
+ fun_l4_n820(x)
+ else
+ fun_l4_n188(x)
+ end
+end
+
+def fun_l3_n547(x)
+ if (x < 1)
+ fun_l4_n403(x)
+ else
+ fun_l4_n670(x)
+ end
+end
+
+def fun_l3_n548(x)
+ if (x < 1)
+ fun_l4_n449(x)
+ else
+ fun_l4_n96(x)
+ end
+end
+
+def fun_l3_n549(x)
+ if (x < 1)
+ fun_l4_n585(x)
+ else
+ fun_l4_n388(x)
+ end
+end
+
+def fun_l3_n550(x)
+ if (x < 1)
+ fun_l4_n963(x)
+ else
+ fun_l4_n979(x)
+ end
+end
+
+def fun_l3_n551(x)
+ if (x < 1)
+ fun_l4_n892(x)
+ else
+ fun_l4_n583(x)
+ end
+end
+
+def fun_l3_n552(x)
+ if (x < 1)
+ fun_l4_n846(x)
+ else
+ fun_l4_n508(x)
+ end
+end
+
+def fun_l3_n553(x)
+ if (x < 1)
+ fun_l4_n160(x)
+ else
+ fun_l4_n428(x)
+ end
+end
+
+def fun_l3_n554(x)
+ if (x < 1)
+ fun_l4_n538(x)
+ else
+ fun_l4_n641(x)
+ end
+end
+
+def fun_l3_n555(x)
+ if (x < 1)
+ fun_l4_n523(x)
+ else
+ fun_l4_n697(x)
+ end
+end
+
+def fun_l3_n556(x)
+ if (x < 1)
+ fun_l4_n212(x)
+ else
+ fun_l4_n0(x)
+ end
+end
+
+def fun_l3_n557(x)
+ if (x < 1)
+ fun_l4_n255(x)
+ else
+ fun_l4_n860(x)
+ end
+end
+
+def fun_l3_n558(x)
+ if (x < 1)
+ fun_l4_n807(x)
+ else
+ fun_l4_n865(x)
+ end
+end
+
+def fun_l3_n559(x)
+ if (x < 1)
+ fun_l4_n735(x)
+ else
+ fun_l4_n352(x)
+ end
+end
+
+def fun_l3_n560(x)
+ if (x < 1)
+ fun_l4_n327(x)
+ else
+ fun_l4_n739(x)
+ end
+end
+
+def fun_l3_n561(x)
+ if (x < 1)
+ fun_l4_n637(x)
+ else
+ fun_l4_n628(x)
+ end
+end
+
+def fun_l3_n562(x)
+ if (x < 1)
+ fun_l4_n281(x)
+ else
+ fun_l4_n394(x)
+ end
+end
+
+def fun_l3_n563(x)
+ if (x < 1)
+ fun_l4_n440(x)
+ else
+ fun_l4_n179(x)
+ end
+end
+
+def fun_l3_n564(x)
+ if (x < 1)
+ fun_l4_n893(x)
+ else
+ fun_l4_n396(x)
+ end
+end
+
+def fun_l3_n565(x)
+ if (x < 1)
+ fun_l4_n94(x)
+ else
+ fun_l4_n134(x)
+ end
+end
+
+def fun_l3_n566(x)
+ if (x < 1)
+ fun_l4_n968(x)
+ else
+ fun_l4_n444(x)
+ end
+end
+
+def fun_l3_n567(x)
+ if (x < 1)
+ fun_l4_n85(x)
+ else
+ fun_l4_n281(x)
+ end
+end
+
+def fun_l3_n568(x)
+ if (x < 1)
+ fun_l4_n164(x)
+ else
+ fun_l4_n229(x)
+ end
+end
+
+def fun_l3_n569(x)
+ if (x < 1)
+ fun_l4_n594(x)
+ else
+ fun_l4_n756(x)
+ end
+end
+
+def fun_l3_n570(x)
+ if (x < 1)
+ fun_l4_n77(x)
+ else
+ fun_l4_n370(x)
+ end
+end
+
+def fun_l3_n571(x)
+ if (x < 1)
+ fun_l4_n724(x)
+ else
+ fun_l4_n965(x)
+ end
+end
+
+def fun_l3_n572(x)
+ if (x < 1)
+ fun_l4_n394(x)
+ else
+ fun_l4_n595(x)
+ end
+end
+
+def fun_l3_n573(x)
+ if (x < 1)
+ fun_l4_n54(x)
+ else
+ fun_l4_n41(x)
+ end
+end
+
+def fun_l3_n574(x)
+ if (x < 1)
+ fun_l4_n951(x)
+ else
+ fun_l4_n414(x)
+ end
+end
+
+def fun_l3_n575(x)
+ if (x < 1)
+ fun_l4_n297(x)
+ else
+ fun_l4_n126(x)
+ end
+end
+
+def fun_l3_n576(x)
+ if (x < 1)
+ fun_l4_n538(x)
+ else
+ fun_l4_n276(x)
+ end
+end
+
+def fun_l3_n577(x)
+ if (x < 1)
+ fun_l4_n882(x)
+ else
+ fun_l4_n152(x)
+ end
+end
+
+def fun_l3_n578(x)
+ if (x < 1)
+ fun_l4_n950(x)
+ else
+ fun_l4_n822(x)
+ end
+end
+
+def fun_l3_n579(x)
+ if (x < 1)
+ fun_l4_n484(x)
+ else
+ fun_l4_n99(x)
+ end
+end
+
+def fun_l3_n580(x)
+ if (x < 1)
+ fun_l4_n160(x)
+ else
+ fun_l4_n98(x)
+ end
+end
+
+def fun_l3_n581(x)
+ if (x < 1)
+ fun_l4_n10(x)
+ else
+ fun_l4_n537(x)
+ end
+end
+
+def fun_l3_n582(x)
+ if (x < 1)
+ fun_l4_n419(x)
+ else
+ fun_l4_n285(x)
+ end
+end
+
+def fun_l3_n583(x)
+ if (x < 1)
+ fun_l4_n330(x)
+ else
+ fun_l4_n732(x)
+ end
+end
+
+def fun_l3_n584(x)
+ if (x < 1)
+ fun_l4_n64(x)
+ else
+ fun_l4_n461(x)
+ end
+end
+
+def fun_l3_n585(x)
+ if (x < 1)
+ fun_l4_n326(x)
+ else
+ fun_l4_n134(x)
+ end
+end
+
+def fun_l3_n586(x)
+ if (x < 1)
+ fun_l4_n423(x)
+ else
+ fun_l4_n945(x)
+ end
+end
+
+def fun_l3_n587(x)
+ if (x < 1)
+ fun_l4_n192(x)
+ else
+ fun_l4_n459(x)
+ end
+end
+
+def fun_l3_n588(x)
+ if (x < 1)
+ fun_l4_n292(x)
+ else
+ fun_l4_n697(x)
+ end
+end
+
+def fun_l3_n589(x)
+ if (x < 1)
+ fun_l4_n612(x)
+ else
+ fun_l4_n902(x)
+ end
+end
+
+def fun_l3_n590(x)
+ if (x < 1)
+ fun_l4_n842(x)
+ else
+ fun_l4_n300(x)
+ end
+end
+
+def fun_l3_n591(x)
+ if (x < 1)
+ fun_l4_n265(x)
+ else
+ fun_l4_n906(x)
+ end
+end
+
+def fun_l3_n592(x)
+ if (x < 1)
+ fun_l4_n82(x)
+ else
+ fun_l4_n417(x)
+ end
+end
+
+def fun_l3_n593(x)
+ if (x < 1)
+ fun_l4_n896(x)
+ else
+ fun_l4_n794(x)
+ end
+end
+
+def fun_l3_n594(x)
+ if (x < 1)
+ fun_l4_n760(x)
+ else
+ fun_l4_n83(x)
+ end
+end
+
+def fun_l3_n595(x)
+ if (x < 1)
+ fun_l4_n750(x)
+ else
+ fun_l4_n778(x)
+ end
+end
+
+def fun_l3_n596(x)
+ if (x < 1)
+ fun_l4_n655(x)
+ else
+ fun_l4_n8(x)
+ end
+end
+
+def fun_l3_n597(x)
+ if (x < 1)
+ fun_l4_n810(x)
+ else
+ fun_l4_n824(x)
+ end
+end
+
+def fun_l3_n598(x)
+ if (x < 1)
+ fun_l4_n904(x)
+ else
+ fun_l4_n921(x)
+ end
+end
+
+def fun_l3_n599(x)
+ if (x < 1)
+ fun_l4_n16(x)
+ else
+ fun_l4_n96(x)
+ end
+end
+
+def fun_l3_n600(x)
+ if (x < 1)
+ fun_l4_n879(x)
+ else
+ fun_l4_n757(x)
+ end
+end
+
+def fun_l3_n601(x)
+ if (x < 1)
+ fun_l4_n840(x)
+ else
+ fun_l4_n62(x)
+ end
+end
+
+def fun_l3_n602(x)
+ if (x < 1)
+ fun_l4_n547(x)
+ else
+ fun_l4_n45(x)
+ end
+end
+
+def fun_l3_n603(x)
+ if (x < 1)
+ fun_l4_n978(x)
+ else
+ fun_l4_n646(x)
+ end
+end
+
+def fun_l3_n604(x)
+ if (x < 1)
+ fun_l4_n100(x)
+ else
+ fun_l4_n654(x)
+ end
+end
+
+def fun_l3_n605(x)
+ if (x < 1)
+ fun_l4_n257(x)
+ else
+ fun_l4_n465(x)
+ end
+end
+
+def fun_l3_n606(x)
+ if (x < 1)
+ fun_l4_n427(x)
+ else
+ fun_l4_n489(x)
+ end
+end
+
+def fun_l3_n607(x)
+ if (x < 1)
+ fun_l4_n465(x)
+ else
+ fun_l4_n48(x)
+ end
+end
+
+def fun_l3_n608(x)
+ if (x < 1)
+ fun_l4_n571(x)
+ else
+ fun_l4_n332(x)
+ end
+end
+
+def fun_l3_n609(x)
+ if (x < 1)
+ fun_l4_n813(x)
+ else
+ fun_l4_n462(x)
+ end
+end
+
+def fun_l3_n610(x)
+ if (x < 1)
+ fun_l4_n931(x)
+ else
+ fun_l4_n913(x)
+ end
+end
+
+def fun_l3_n611(x)
+ if (x < 1)
+ fun_l4_n20(x)
+ else
+ fun_l4_n933(x)
+ end
+end
+
+def fun_l3_n612(x)
+ if (x < 1)
+ fun_l4_n913(x)
+ else
+ fun_l4_n787(x)
+ end
+end
+
+def fun_l3_n613(x)
+ if (x < 1)
+ fun_l4_n523(x)
+ else
+ fun_l4_n735(x)
+ end
+end
+
+def fun_l3_n614(x)
+ if (x < 1)
+ fun_l4_n315(x)
+ else
+ fun_l4_n913(x)
+ end
+end
+
+def fun_l3_n615(x)
+ if (x < 1)
+ fun_l4_n308(x)
+ else
+ fun_l4_n865(x)
+ end
+end
+
+def fun_l3_n616(x)
+ if (x < 1)
+ fun_l4_n847(x)
+ else
+ fun_l4_n506(x)
+ end
+end
+
+def fun_l3_n617(x)
+ if (x < 1)
+ fun_l4_n387(x)
+ else
+ fun_l4_n551(x)
+ end
+end
+
+def fun_l3_n618(x)
+ if (x < 1)
+ fun_l4_n276(x)
+ else
+ fun_l4_n991(x)
+ end
+end
+
+def fun_l3_n619(x)
+ if (x < 1)
+ fun_l4_n524(x)
+ else
+ fun_l4_n202(x)
+ end
+end
+
+def fun_l3_n620(x)
+ if (x < 1)
+ fun_l4_n836(x)
+ else
+ fun_l4_n548(x)
+ end
+end
+
+def fun_l3_n621(x)
+ if (x < 1)
+ fun_l4_n76(x)
+ else
+ fun_l4_n5(x)
+ end
+end
+
+def fun_l3_n622(x)
+ if (x < 1)
+ fun_l4_n223(x)
+ else
+ fun_l4_n438(x)
+ end
+end
+
+def fun_l3_n623(x)
+ if (x < 1)
+ fun_l4_n31(x)
+ else
+ fun_l4_n590(x)
+ end
+end
+
+def fun_l3_n624(x)
+ if (x < 1)
+ fun_l4_n609(x)
+ else
+ fun_l4_n513(x)
+ end
+end
+
+def fun_l3_n625(x)
+ if (x < 1)
+ fun_l4_n966(x)
+ else
+ fun_l4_n278(x)
+ end
+end
+
+def fun_l3_n626(x)
+ if (x < 1)
+ fun_l4_n82(x)
+ else
+ fun_l4_n100(x)
+ end
+end
+
+def fun_l3_n627(x)
+ if (x < 1)
+ fun_l4_n312(x)
+ else
+ fun_l4_n746(x)
+ end
+end
+
+def fun_l3_n628(x)
+ if (x < 1)
+ fun_l4_n682(x)
+ else
+ fun_l4_n791(x)
+ end
+end
+
+def fun_l3_n629(x)
+ if (x < 1)
+ fun_l4_n166(x)
+ else
+ fun_l4_n678(x)
+ end
+end
+
+def fun_l3_n630(x)
+ if (x < 1)
+ fun_l4_n507(x)
+ else
+ fun_l4_n778(x)
+ end
+end
+
+def fun_l3_n631(x)
+ if (x < 1)
+ fun_l4_n97(x)
+ else
+ fun_l4_n13(x)
+ end
+end
+
+def fun_l3_n632(x)
+ if (x < 1)
+ fun_l4_n976(x)
+ else
+ fun_l4_n794(x)
+ end
+end
+
+def fun_l3_n633(x)
+ if (x < 1)
+ fun_l4_n994(x)
+ else
+ fun_l4_n743(x)
+ end
+end
+
+def fun_l3_n634(x)
+ if (x < 1)
+ fun_l4_n212(x)
+ else
+ fun_l4_n754(x)
+ end
+end
+
+def fun_l3_n635(x)
+ if (x < 1)
+ fun_l4_n602(x)
+ else
+ fun_l4_n997(x)
+ end
+end
+
+def fun_l3_n636(x)
+ if (x < 1)
+ fun_l4_n282(x)
+ else
+ fun_l4_n133(x)
+ end
+end
+
+def fun_l3_n637(x)
+ if (x < 1)
+ fun_l4_n413(x)
+ else
+ fun_l4_n952(x)
+ end
+end
+
+def fun_l3_n638(x)
+ if (x < 1)
+ fun_l4_n843(x)
+ else
+ fun_l4_n783(x)
+ end
+end
+
+def fun_l3_n639(x)
+ if (x < 1)
+ fun_l4_n946(x)
+ else
+ fun_l4_n833(x)
+ end
+end
+
+def fun_l3_n640(x)
+ if (x < 1)
+ fun_l4_n384(x)
+ else
+ fun_l4_n444(x)
+ end
+end
+
+def fun_l3_n641(x)
+ if (x < 1)
+ fun_l4_n699(x)
+ else
+ fun_l4_n26(x)
+ end
+end
+
+def fun_l3_n642(x)
+ if (x < 1)
+ fun_l4_n96(x)
+ else
+ fun_l4_n623(x)
+ end
+end
+
+def fun_l3_n643(x)
+ if (x < 1)
+ fun_l4_n928(x)
+ else
+ fun_l4_n8(x)
+ end
+end
+
+def fun_l3_n644(x)
+ if (x < 1)
+ fun_l4_n804(x)
+ else
+ fun_l4_n618(x)
+ end
+end
+
+def fun_l3_n645(x)
+ if (x < 1)
+ fun_l4_n513(x)
+ else
+ fun_l4_n214(x)
+ end
+end
+
+def fun_l3_n646(x)
+ if (x < 1)
+ fun_l4_n605(x)
+ else
+ fun_l4_n920(x)
+ end
+end
+
+def fun_l3_n647(x)
+ if (x < 1)
+ fun_l4_n774(x)
+ else
+ fun_l4_n297(x)
+ end
+end
+
+def fun_l3_n648(x)
+ if (x < 1)
+ fun_l4_n871(x)
+ else
+ fun_l4_n75(x)
+ end
+end
+
+def fun_l3_n649(x)
+ if (x < 1)
+ fun_l4_n196(x)
+ else
+ fun_l4_n277(x)
+ end
+end
+
+def fun_l3_n650(x)
+ if (x < 1)
+ fun_l4_n25(x)
+ else
+ fun_l4_n681(x)
+ end
+end
+
+def fun_l3_n651(x)
+ if (x < 1)
+ fun_l4_n603(x)
+ else
+ fun_l4_n46(x)
+ end
+end
+
+def fun_l3_n652(x)
+ if (x < 1)
+ fun_l4_n623(x)
+ else
+ fun_l4_n604(x)
+ end
+end
+
+def fun_l3_n653(x)
+ if (x < 1)
+ fun_l4_n854(x)
+ else
+ fun_l4_n955(x)
+ end
+end
+
+def fun_l3_n654(x)
+ if (x < 1)
+ fun_l4_n667(x)
+ else
+ fun_l4_n988(x)
+ end
+end
+
+def fun_l3_n655(x)
+ if (x < 1)
+ fun_l4_n263(x)
+ else
+ fun_l4_n831(x)
+ end
+end
+
+def fun_l3_n656(x)
+ if (x < 1)
+ fun_l4_n591(x)
+ else
+ fun_l4_n593(x)
+ end
+end
+
+def fun_l3_n657(x)
+ if (x < 1)
+ fun_l4_n308(x)
+ else
+ fun_l4_n547(x)
+ end
+end
+
+def fun_l3_n658(x)
+ if (x < 1)
+ fun_l4_n780(x)
+ else
+ fun_l4_n174(x)
+ end
+end
+
+def fun_l3_n659(x)
+ if (x < 1)
+ fun_l4_n54(x)
+ else
+ fun_l4_n681(x)
+ end
+end
+
+def fun_l3_n660(x)
+ if (x < 1)
+ fun_l4_n279(x)
+ else
+ fun_l4_n282(x)
+ end
+end
+
+def fun_l3_n661(x)
+ if (x < 1)
+ fun_l4_n953(x)
+ else
+ fun_l4_n832(x)
+ end
+end
+
+def fun_l3_n662(x)
+ if (x < 1)
+ fun_l4_n525(x)
+ else
+ fun_l4_n850(x)
+ end
+end
+
+def fun_l3_n663(x)
+ if (x < 1)
+ fun_l4_n606(x)
+ else
+ fun_l4_n167(x)
+ end
+end
+
+def fun_l3_n664(x)
+ if (x < 1)
+ fun_l4_n941(x)
+ else
+ fun_l4_n591(x)
+ end
+end
+
+def fun_l3_n665(x)
+ if (x < 1)
+ fun_l4_n781(x)
+ else
+ fun_l4_n162(x)
+ end
+end
+
+def fun_l3_n666(x)
+ if (x < 1)
+ fun_l4_n848(x)
+ else
+ fun_l4_n133(x)
+ end
+end
+
+def fun_l3_n667(x)
+ if (x < 1)
+ fun_l4_n341(x)
+ else
+ fun_l4_n212(x)
+ end
+end
+
+def fun_l3_n668(x)
+ if (x < 1)
+ fun_l4_n320(x)
+ else
+ fun_l4_n131(x)
+ end
+end
+
+def fun_l3_n669(x)
+ if (x < 1)
+ fun_l4_n18(x)
+ else
+ fun_l4_n385(x)
+ end
+end
+
+def fun_l3_n670(x)
+ if (x < 1)
+ fun_l4_n917(x)
+ else
+ fun_l4_n988(x)
+ end
+end
+
+def fun_l3_n671(x)
+ if (x < 1)
+ fun_l4_n50(x)
+ else
+ fun_l4_n27(x)
+ end
+end
+
+def fun_l3_n672(x)
+ if (x < 1)
+ fun_l4_n277(x)
+ else
+ fun_l4_n238(x)
+ end
+end
+
+def fun_l3_n673(x)
+ if (x < 1)
+ fun_l4_n303(x)
+ else
+ fun_l4_n643(x)
+ end
+end
+
+def fun_l3_n674(x)
+ if (x < 1)
+ fun_l4_n794(x)
+ else
+ fun_l4_n906(x)
+ end
+end
+
+def fun_l3_n675(x)
+ if (x < 1)
+ fun_l4_n688(x)
+ else
+ fun_l4_n312(x)
+ end
+end
+
+def fun_l3_n676(x)
+ if (x < 1)
+ fun_l4_n833(x)
+ else
+ fun_l4_n900(x)
+ end
+end
+
+def fun_l3_n677(x)
+ if (x < 1)
+ fun_l4_n649(x)
+ else
+ fun_l4_n822(x)
+ end
+end
+
+def fun_l3_n678(x)
+ if (x < 1)
+ fun_l4_n958(x)
+ else
+ fun_l4_n939(x)
+ end
+end
+
+def fun_l3_n679(x)
+ if (x < 1)
+ fun_l4_n949(x)
+ else
+ fun_l4_n887(x)
+ end
+end
+
+def fun_l3_n680(x)
+ if (x < 1)
+ fun_l4_n630(x)
+ else
+ fun_l4_n508(x)
+ end
+end
+
+def fun_l3_n681(x)
+ if (x < 1)
+ fun_l4_n553(x)
+ else
+ fun_l4_n940(x)
+ end
+end
+
+def fun_l3_n682(x)
+ if (x < 1)
+ fun_l4_n180(x)
+ else
+ fun_l4_n950(x)
+ end
+end
+
+def fun_l3_n683(x)
+ if (x < 1)
+ fun_l4_n898(x)
+ else
+ fun_l4_n374(x)
+ end
+end
+
+def fun_l3_n684(x)
+ if (x < 1)
+ fun_l4_n802(x)
+ else
+ fun_l4_n527(x)
+ end
+end
+
+def fun_l3_n685(x)
+ if (x < 1)
+ fun_l4_n751(x)
+ else
+ fun_l4_n967(x)
+ end
+end
+
+def fun_l3_n686(x)
+ if (x < 1)
+ fun_l4_n235(x)
+ else
+ fun_l4_n559(x)
+ end
+end
+
+def fun_l3_n687(x)
+ if (x < 1)
+ fun_l4_n694(x)
+ else
+ fun_l4_n819(x)
+ end
+end
+
+def fun_l3_n688(x)
+ if (x < 1)
+ fun_l4_n167(x)
+ else
+ fun_l4_n91(x)
+ end
+end
+
+def fun_l3_n689(x)
+ if (x < 1)
+ fun_l4_n692(x)
+ else
+ fun_l4_n422(x)
+ end
+end
+
+def fun_l3_n690(x)
+ if (x < 1)
+ fun_l4_n344(x)
+ else
+ fun_l4_n738(x)
+ end
+end
+
+def fun_l3_n691(x)
+ if (x < 1)
+ fun_l4_n394(x)
+ else
+ fun_l4_n603(x)
+ end
+end
+
+def fun_l3_n692(x)
+ if (x < 1)
+ fun_l4_n909(x)
+ else
+ fun_l4_n528(x)
+ end
+end
+
+def fun_l3_n693(x)
+ if (x < 1)
+ fun_l4_n180(x)
+ else
+ fun_l4_n22(x)
+ end
+end
+
+def fun_l3_n694(x)
+ if (x < 1)
+ fun_l4_n6(x)
+ else
+ fun_l4_n777(x)
+ end
+end
+
+def fun_l3_n695(x)
+ if (x < 1)
+ fun_l4_n327(x)
+ else
+ fun_l4_n948(x)
+ end
+end
+
+def fun_l3_n696(x)
+ if (x < 1)
+ fun_l4_n748(x)
+ else
+ fun_l4_n706(x)
+ end
+end
+
+def fun_l3_n697(x)
+ if (x < 1)
+ fun_l4_n720(x)
+ else
+ fun_l4_n693(x)
+ end
+end
+
+def fun_l3_n698(x)
+ if (x < 1)
+ fun_l4_n282(x)
+ else
+ fun_l4_n755(x)
+ end
+end
+
+def fun_l3_n699(x)
+ if (x < 1)
+ fun_l4_n975(x)
+ else
+ fun_l4_n415(x)
+ end
+end
+
+def fun_l3_n700(x)
+ if (x < 1)
+ fun_l4_n684(x)
+ else
+ fun_l4_n738(x)
+ end
+end
+
+def fun_l3_n701(x)
+ if (x < 1)
+ fun_l4_n58(x)
+ else
+ fun_l4_n892(x)
+ end
+end
+
+def fun_l3_n702(x)
+ if (x < 1)
+ fun_l4_n366(x)
+ else
+ fun_l4_n189(x)
+ end
+end
+
+def fun_l3_n703(x)
+ if (x < 1)
+ fun_l4_n422(x)
+ else
+ fun_l4_n535(x)
+ end
+end
+
+def fun_l3_n704(x)
+ if (x < 1)
+ fun_l4_n886(x)
+ else
+ fun_l4_n223(x)
+ end
+end
+
+def fun_l3_n705(x)
+ if (x < 1)
+ fun_l4_n57(x)
+ else
+ fun_l4_n62(x)
+ end
+end
+
+def fun_l3_n706(x)
+ if (x < 1)
+ fun_l4_n629(x)
+ else
+ fun_l4_n479(x)
+ end
+end
+
+def fun_l3_n707(x)
+ if (x < 1)
+ fun_l4_n477(x)
+ else
+ fun_l4_n302(x)
+ end
+end
+
+def fun_l3_n708(x)
+ if (x < 1)
+ fun_l4_n790(x)
+ else
+ fun_l4_n262(x)
+ end
+end
+
+def fun_l3_n709(x)
+ if (x < 1)
+ fun_l4_n772(x)
+ else
+ fun_l4_n995(x)
+ end
+end
+
+def fun_l3_n710(x)
+ if (x < 1)
+ fun_l4_n549(x)
+ else
+ fun_l4_n651(x)
+ end
+end
+
+def fun_l3_n711(x)
+ if (x < 1)
+ fun_l4_n77(x)
+ else
+ fun_l4_n555(x)
+ end
+end
+
+def fun_l3_n712(x)
+ if (x < 1)
+ fun_l4_n515(x)
+ else
+ fun_l4_n734(x)
+ end
+end
+
+def fun_l3_n713(x)
+ if (x < 1)
+ fun_l4_n778(x)
+ else
+ fun_l4_n884(x)
+ end
+end
+
+def fun_l3_n714(x)
+ if (x < 1)
+ fun_l4_n235(x)
+ else
+ fun_l4_n637(x)
+ end
+end
+
+def fun_l3_n715(x)
+ if (x < 1)
+ fun_l4_n516(x)
+ else
+ fun_l4_n249(x)
+ end
+end
+
+def fun_l3_n716(x)
+ if (x < 1)
+ fun_l4_n44(x)
+ else
+ fun_l4_n307(x)
+ end
+end
+
+def fun_l3_n717(x)
+ if (x < 1)
+ fun_l4_n482(x)
+ else
+ fun_l4_n4(x)
+ end
+end
+
+def fun_l3_n718(x)
+ if (x < 1)
+ fun_l4_n195(x)
+ else
+ fun_l4_n410(x)
+ end
+end
+
+def fun_l3_n719(x)
+ if (x < 1)
+ fun_l4_n862(x)
+ else
+ fun_l4_n91(x)
+ end
+end
+
+def fun_l3_n720(x)
+ if (x < 1)
+ fun_l4_n591(x)
+ else
+ fun_l4_n391(x)
+ end
+end
+
+def fun_l3_n721(x)
+ if (x < 1)
+ fun_l4_n776(x)
+ else
+ fun_l4_n129(x)
+ end
+end
+
+def fun_l3_n722(x)
+ if (x < 1)
+ fun_l4_n857(x)
+ else
+ fun_l4_n160(x)
+ end
+end
+
+def fun_l3_n723(x)
+ if (x < 1)
+ fun_l4_n772(x)
+ else
+ fun_l4_n567(x)
+ end
+end
+
+def fun_l3_n724(x)
+ if (x < 1)
+ fun_l4_n582(x)
+ else
+ fun_l4_n100(x)
+ end
+end
+
+def fun_l3_n725(x)
+ if (x < 1)
+ fun_l4_n962(x)
+ else
+ fun_l4_n846(x)
+ end
+end
+
+def fun_l3_n726(x)
+ if (x < 1)
+ fun_l4_n892(x)
+ else
+ fun_l4_n334(x)
+ end
+end
+
+def fun_l3_n727(x)
+ if (x < 1)
+ fun_l4_n17(x)
+ else
+ fun_l4_n690(x)
+ end
+end
+
+def fun_l3_n728(x)
+ if (x < 1)
+ fun_l4_n453(x)
+ else
+ fun_l4_n234(x)
+ end
+end
+
+def fun_l3_n729(x)
+ if (x < 1)
+ fun_l4_n562(x)
+ else
+ fun_l4_n139(x)
+ end
+end
+
+def fun_l3_n730(x)
+ if (x < 1)
+ fun_l4_n87(x)
+ else
+ fun_l4_n513(x)
+ end
+end
+
+def fun_l3_n731(x)
+ if (x < 1)
+ fun_l4_n565(x)
+ else
+ fun_l4_n289(x)
+ end
+end
+
+def fun_l3_n732(x)
+ if (x < 1)
+ fun_l4_n821(x)
+ else
+ fun_l4_n290(x)
+ end
+end
+
+def fun_l3_n733(x)
+ if (x < 1)
+ fun_l4_n464(x)
+ else
+ fun_l4_n929(x)
+ end
+end
+
+def fun_l3_n734(x)
+ if (x < 1)
+ fun_l4_n617(x)
+ else
+ fun_l4_n230(x)
+ end
+end
+
+def fun_l3_n735(x)
+ if (x < 1)
+ fun_l4_n942(x)
+ else
+ fun_l4_n770(x)
+ end
+end
+
+def fun_l3_n736(x)
+ if (x < 1)
+ fun_l4_n826(x)
+ else
+ fun_l4_n414(x)
+ end
+end
+
+def fun_l3_n737(x)
+ if (x < 1)
+ fun_l4_n47(x)
+ else
+ fun_l4_n357(x)
+ end
+end
+
+def fun_l3_n738(x)
+ if (x < 1)
+ fun_l4_n582(x)
+ else
+ fun_l4_n652(x)
+ end
+end
+
+def fun_l3_n739(x)
+ if (x < 1)
+ fun_l4_n641(x)
+ else
+ fun_l4_n479(x)
+ end
+end
+
+def fun_l3_n740(x)
+ if (x < 1)
+ fun_l4_n11(x)
+ else
+ fun_l4_n965(x)
+ end
+end
+
+def fun_l3_n741(x)
+ if (x < 1)
+ fun_l4_n402(x)
+ else
+ fun_l4_n512(x)
+ end
+end
+
+def fun_l3_n742(x)
+ if (x < 1)
+ fun_l4_n300(x)
+ else
+ fun_l4_n942(x)
+ end
+end
+
+def fun_l3_n743(x)
+ if (x < 1)
+ fun_l4_n770(x)
+ else
+ fun_l4_n690(x)
+ end
+end
+
+def fun_l3_n744(x)
+ if (x < 1)
+ fun_l4_n575(x)
+ else
+ fun_l4_n158(x)
+ end
+end
+
+def fun_l3_n745(x)
+ if (x < 1)
+ fun_l4_n760(x)
+ else
+ fun_l4_n552(x)
+ end
+end
+
+def fun_l3_n746(x)
+ if (x < 1)
+ fun_l4_n887(x)
+ else
+ fun_l4_n319(x)
+ end
+end
+
+def fun_l3_n747(x)
+ if (x < 1)
+ fun_l4_n967(x)
+ else
+ fun_l4_n561(x)
+ end
+end
+
+def fun_l3_n748(x)
+ if (x < 1)
+ fun_l4_n4(x)
+ else
+ fun_l4_n766(x)
+ end
+end
+
+def fun_l3_n749(x)
+ if (x < 1)
+ fun_l4_n993(x)
+ else
+ fun_l4_n991(x)
+ end
+end
+
+def fun_l3_n750(x)
+ if (x < 1)
+ fun_l4_n890(x)
+ else
+ fun_l4_n663(x)
+ end
+end
+
+def fun_l3_n751(x)
+ if (x < 1)
+ fun_l4_n267(x)
+ else
+ fun_l4_n449(x)
+ end
+end
+
+def fun_l3_n752(x)
+ if (x < 1)
+ fun_l4_n540(x)
+ else
+ fun_l4_n226(x)
+ end
+end
+
+def fun_l3_n753(x)
+ if (x < 1)
+ fun_l4_n893(x)
+ else
+ fun_l4_n116(x)
+ end
+end
+
+def fun_l3_n754(x)
+ if (x < 1)
+ fun_l4_n570(x)
+ else
+ fun_l4_n192(x)
+ end
+end
+
+def fun_l3_n755(x)
+ if (x < 1)
+ fun_l4_n712(x)
+ else
+ fun_l4_n81(x)
+ end
+end
+
+def fun_l3_n756(x)
+ if (x < 1)
+ fun_l4_n833(x)
+ else
+ fun_l4_n24(x)
+ end
+end
+
+def fun_l3_n757(x)
+ if (x < 1)
+ fun_l4_n740(x)
+ else
+ fun_l4_n803(x)
+ end
+end
+
+def fun_l3_n758(x)
+ if (x < 1)
+ fun_l4_n552(x)
+ else
+ fun_l4_n551(x)
+ end
+end
+
+def fun_l3_n759(x)
+ if (x < 1)
+ fun_l4_n570(x)
+ else
+ fun_l4_n677(x)
+ end
+end
+
+def fun_l3_n760(x)
+ if (x < 1)
+ fun_l4_n243(x)
+ else
+ fun_l4_n677(x)
+ end
+end
+
+def fun_l3_n761(x)
+ if (x < 1)
+ fun_l4_n65(x)
+ else
+ fun_l4_n660(x)
+ end
+end
+
+def fun_l3_n762(x)
+ if (x < 1)
+ fun_l4_n989(x)
+ else
+ fun_l4_n761(x)
+ end
+end
+
+def fun_l3_n763(x)
+ if (x < 1)
+ fun_l4_n971(x)
+ else
+ fun_l4_n280(x)
+ end
+end
+
+def fun_l3_n764(x)
+ if (x < 1)
+ fun_l4_n441(x)
+ else
+ fun_l4_n506(x)
+ end
+end
+
+def fun_l3_n765(x)
+ if (x < 1)
+ fun_l4_n577(x)
+ else
+ fun_l4_n586(x)
+ end
+end
+
+def fun_l3_n766(x)
+ if (x < 1)
+ fun_l4_n385(x)
+ else
+ fun_l4_n60(x)
+ end
+end
+
+def fun_l3_n767(x)
+ if (x < 1)
+ fun_l4_n380(x)
+ else
+ fun_l4_n32(x)
+ end
+end
+
+def fun_l3_n768(x)
+ if (x < 1)
+ fun_l4_n797(x)
+ else
+ fun_l4_n437(x)
+ end
+end
+
+def fun_l3_n769(x)
+ if (x < 1)
+ fun_l4_n615(x)
+ else
+ fun_l4_n369(x)
+ end
+end
+
+def fun_l3_n770(x)
+ if (x < 1)
+ fun_l4_n779(x)
+ else
+ fun_l4_n194(x)
+ end
+end
+
+def fun_l3_n771(x)
+ if (x < 1)
+ fun_l4_n287(x)
+ else
+ fun_l4_n819(x)
+ end
+end
+
+def fun_l3_n772(x)
+ if (x < 1)
+ fun_l4_n405(x)
+ else
+ fun_l4_n738(x)
+ end
+end
+
+def fun_l3_n773(x)
+ if (x < 1)
+ fun_l4_n706(x)
+ else
+ fun_l4_n174(x)
+ end
+end
+
+def fun_l3_n774(x)
+ if (x < 1)
+ fun_l4_n690(x)
+ else
+ fun_l4_n841(x)
+ end
+end
+
+def fun_l3_n775(x)
+ if (x < 1)
+ fun_l4_n256(x)
+ else
+ fun_l4_n179(x)
+ end
+end
+
+def fun_l3_n776(x)
+ if (x < 1)
+ fun_l4_n342(x)
+ else
+ fun_l4_n359(x)
+ end
+end
+
+def fun_l3_n777(x)
+ if (x < 1)
+ fun_l4_n371(x)
+ else
+ fun_l4_n680(x)
+ end
+end
+
+def fun_l3_n778(x)
+ if (x < 1)
+ fun_l4_n996(x)
+ else
+ fun_l4_n343(x)
+ end
+end
+
+def fun_l3_n779(x)
+ if (x < 1)
+ fun_l4_n96(x)
+ else
+ fun_l4_n893(x)
+ end
+end
+
+def fun_l3_n780(x)
+ if (x < 1)
+ fun_l4_n706(x)
+ else
+ fun_l4_n140(x)
+ end
+end
+
+def fun_l3_n781(x)
+ if (x < 1)
+ fun_l4_n349(x)
+ else
+ fun_l4_n317(x)
+ end
+end
+
+def fun_l3_n782(x)
+ if (x < 1)
+ fun_l4_n491(x)
+ else
+ fun_l4_n616(x)
+ end
+end
+
+def fun_l3_n783(x)
+ if (x < 1)
+ fun_l4_n227(x)
+ else
+ fun_l4_n356(x)
+ end
+end
+
+def fun_l3_n784(x)
+ if (x < 1)
+ fun_l4_n387(x)
+ else
+ fun_l4_n532(x)
+ end
+end
+
+def fun_l3_n785(x)
+ if (x < 1)
+ fun_l4_n648(x)
+ else
+ fun_l4_n34(x)
+ end
+end
+
+def fun_l3_n786(x)
+ if (x < 1)
+ fun_l4_n562(x)
+ else
+ fun_l4_n476(x)
+ end
+end
+
+def fun_l3_n787(x)
+ if (x < 1)
+ fun_l4_n162(x)
+ else
+ fun_l4_n384(x)
+ end
+end
+
+def fun_l3_n788(x)
+ if (x < 1)
+ fun_l4_n221(x)
+ else
+ fun_l4_n617(x)
+ end
+end
+
+def fun_l3_n789(x)
+ if (x < 1)
+ fun_l4_n670(x)
+ else
+ fun_l4_n350(x)
+ end
+end
+
+def fun_l3_n790(x)
+ if (x < 1)
+ fun_l4_n202(x)
+ else
+ fun_l4_n112(x)
+ end
+end
+
+def fun_l3_n791(x)
+ if (x < 1)
+ fun_l4_n390(x)
+ else
+ fun_l4_n868(x)
+ end
+end
+
+def fun_l3_n792(x)
+ if (x < 1)
+ fun_l4_n746(x)
+ else
+ fun_l4_n833(x)
+ end
+end
+
+def fun_l3_n793(x)
+ if (x < 1)
+ fun_l4_n471(x)
+ else
+ fun_l4_n60(x)
+ end
+end
+
+def fun_l3_n794(x)
+ if (x < 1)
+ fun_l4_n583(x)
+ else
+ fun_l4_n470(x)
+ end
+end
+
+def fun_l3_n795(x)
+ if (x < 1)
+ fun_l4_n567(x)
+ else
+ fun_l4_n218(x)
+ end
+end
+
+def fun_l3_n796(x)
+ if (x < 1)
+ fun_l4_n140(x)
+ else
+ fun_l4_n690(x)
+ end
+end
+
+def fun_l3_n797(x)
+ if (x < 1)
+ fun_l4_n190(x)
+ else
+ fun_l4_n437(x)
+ end
+end
+
+def fun_l3_n798(x)
+ if (x < 1)
+ fun_l4_n684(x)
+ else
+ fun_l4_n843(x)
+ end
+end
+
+def fun_l3_n799(x)
+ if (x < 1)
+ fun_l4_n825(x)
+ else
+ fun_l4_n354(x)
+ end
+end
+
+def fun_l3_n800(x)
+ if (x < 1)
+ fun_l4_n711(x)
+ else
+ fun_l4_n606(x)
+ end
+end
+
+def fun_l3_n801(x)
+ if (x < 1)
+ fun_l4_n756(x)
+ else
+ fun_l4_n464(x)
+ end
+end
+
+def fun_l3_n802(x)
+ if (x < 1)
+ fun_l4_n143(x)
+ else
+ fun_l4_n962(x)
+ end
+end
+
+def fun_l3_n803(x)
+ if (x < 1)
+ fun_l4_n223(x)
+ else
+ fun_l4_n293(x)
+ end
+end
+
+def fun_l3_n804(x)
+ if (x < 1)
+ fun_l4_n832(x)
+ else
+ fun_l4_n632(x)
+ end
+end
+
+def fun_l3_n805(x)
+ if (x < 1)
+ fun_l4_n649(x)
+ else
+ fun_l4_n259(x)
+ end
+end
+
+def fun_l3_n806(x)
+ if (x < 1)
+ fun_l4_n617(x)
+ else
+ fun_l4_n993(x)
+ end
+end
+
+def fun_l3_n807(x)
+ if (x < 1)
+ fun_l4_n257(x)
+ else
+ fun_l4_n712(x)
+ end
+end
+
+def fun_l3_n808(x)
+ if (x < 1)
+ fun_l4_n632(x)
+ else
+ fun_l4_n563(x)
+ end
+end
+
+def fun_l3_n809(x)
+ if (x < 1)
+ fun_l4_n154(x)
+ else
+ fun_l4_n561(x)
+ end
+end
+
+def fun_l3_n810(x)
+ if (x < 1)
+ fun_l4_n411(x)
+ else
+ fun_l4_n42(x)
+ end
+end
+
+def fun_l3_n811(x)
+ if (x < 1)
+ fun_l4_n560(x)
+ else
+ fun_l4_n531(x)
+ end
+end
+
+def fun_l3_n812(x)
+ if (x < 1)
+ fun_l4_n759(x)
+ else
+ fun_l4_n588(x)
+ end
+end
+
+def fun_l3_n813(x)
+ if (x < 1)
+ fun_l4_n311(x)
+ else
+ fun_l4_n813(x)
+ end
+end
+
+def fun_l3_n814(x)
+ if (x < 1)
+ fun_l4_n521(x)
+ else
+ fun_l4_n877(x)
+ end
+end
+
+def fun_l3_n815(x)
+ if (x < 1)
+ fun_l4_n578(x)
+ else
+ fun_l4_n37(x)
+ end
+end
+
+def fun_l3_n816(x)
+ if (x < 1)
+ fun_l4_n337(x)
+ else
+ fun_l4_n562(x)
+ end
+end
+
+def fun_l3_n817(x)
+ if (x < 1)
+ fun_l4_n523(x)
+ else
+ fun_l4_n445(x)
+ end
+end
+
+def fun_l3_n818(x)
+ if (x < 1)
+ fun_l4_n256(x)
+ else
+ fun_l4_n551(x)
+ end
+end
+
+def fun_l3_n819(x)
+ if (x < 1)
+ fun_l4_n718(x)
+ else
+ fun_l4_n463(x)
+ end
+end
+
+def fun_l3_n820(x)
+ if (x < 1)
+ fun_l4_n780(x)
+ else
+ fun_l4_n103(x)
+ end
+end
+
+def fun_l3_n821(x)
+ if (x < 1)
+ fun_l4_n729(x)
+ else
+ fun_l4_n331(x)
+ end
+end
+
+def fun_l3_n822(x)
+ if (x < 1)
+ fun_l4_n84(x)
+ else
+ fun_l4_n176(x)
+ end
+end
+
+def fun_l3_n823(x)
+ if (x < 1)
+ fun_l4_n231(x)
+ else
+ fun_l4_n681(x)
+ end
+end
+
+def fun_l3_n824(x)
+ if (x < 1)
+ fun_l4_n675(x)
+ else
+ fun_l4_n837(x)
+ end
+end
+
+def fun_l3_n825(x)
+ if (x < 1)
+ fun_l4_n140(x)
+ else
+ fun_l4_n932(x)
+ end
+end
+
+def fun_l3_n826(x)
+ if (x < 1)
+ fun_l4_n268(x)
+ else
+ fun_l4_n908(x)
+ end
+end
+
+def fun_l3_n827(x)
+ if (x < 1)
+ fun_l4_n959(x)
+ else
+ fun_l4_n643(x)
+ end
+end
+
+def fun_l3_n828(x)
+ if (x < 1)
+ fun_l4_n290(x)
+ else
+ fun_l4_n718(x)
+ end
+end
+
+def fun_l3_n829(x)
+ if (x < 1)
+ fun_l4_n430(x)
+ else
+ fun_l4_n114(x)
+ end
+end
+
+def fun_l3_n830(x)
+ if (x < 1)
+ fun_l4_n817(x)
+ else
+ fun_l4_n296(x)
+ end
+end
+
+def fun_l3_n831(x)
+ if (x < 1)
+ fun_l4_n586(x)
+ else
+ fun_l4_n345(x)
+ end
+end
+
+def fun_l3_n832(x)
+ if (x < 1)
+ fun_l4_n321(x)
+ else
+ fun_l4_n805(x)
+ end
+end
+
+def fun_l3_n833(x)
+ if (x < 1)
+ fun_l4_n57(x)
+ else
+ fun_l4_n373(x)
+ end
+end
+
+def fun_l3_n834(x)
+ if (x < 1)
+ fun_l4_n344(x)
+ else
+ fun_l4_n654(x)
+ end
+end
+
+def fun_l3_n835(x)
+ if (x < 1)
+ fun_l4_n761(x)
+ else
+ fun_l4_n295(x)
+ end
+end
+
+def fun_l3_n836(x)
+ if (x < 1)
+ fun_l4_n169(x)
+ else
+ fun_l4_n184(x)
+ end
+end
+
+def fun_l3_n837(x)
+ if (x < 1)
+ fun_l4_n482(x)
+ else
+ fun_l4_n127(x)
+ end
+end
+
+def fun_l3_n838(x)
+ if (x < 1)
+ fun_l4_n260(x)
+ else
+ fun_l4_n662(x)
+ end
+end
+
+def fun_l3_n839(x)
+ if (x < 1)
+ fun_l4_n548(x)
+ else
+ fun_l4_n197(x)
+ end
+end
+
+def fun_l3_n840(x)
+ if (x < 1)
+ fun_l4_n96(x)
+ else
+ fun_l4_n17(x)
+ end
+end
+
+def fun_l3_n841(x)
+ if (x < 1)
+ fun_l4_n946(x)
+ else
+ fun_l4_n447(x)
+ end
+end
+
+def fun_l3_n842(x)
+ if (x < 1)
+ fun_l4_n66(x)
+ else
+ fun_l4_n110(x)
+ end
+end
+
+def fun_l3_n843(x)
+ if (x < 1)
+ fun_l4_n574(x)
+ else
+ fun_l4_n887(x)
+ end
+end
+
+def fun_l3_n844(x)
+ if (x < 1)
+ fun_l4_n912(x)
+ else
+ fun_l4_n465(x)
+ end
+end
+
+def fun_l3_n845(x)
+ if (x < 1)
+ fun_l4_n401(x)
+ else
+ fun_l4_n903(x)
+ end
+end
+
+def fun_l3_n846(x)
+ if (x < 1)
+ fun_l4_n929(x)
+ else
+ fun_l4_n238(x)
+ end
+end
+
+def fun_l3_n847(x)
+ if (x < 1)
+ fun_l4_n579(x)
+ else
+ fun_l4_n924(x)
+ end
+end
+
+def fun_l3_n848(x)
+ if (x < 1)
+ fun_l4_n697(x)
+ else
+ fun_l4_n157(x)
+ end
+end
+
+def fun_l3_n849(x)
+ if (x < 1)
+ fun_l4_n608(x)
+ else
+ fun_l4_n426(x)
+ end
+end
+
+def fun_l3_n850(x)
+ if (x < 1)
+ fun_l4_n710(x)
+ else
+ fun_l4_n360(x)
+ end
+end
+
+def fun_l3_n851(x)
+ if (x < 1)
+ fun_l4_n558(x)
+ else
+ fun_l4_n152(x)
+ end
+end
+
+def fun_l3_n852(x)
+ if (x < 1)
+ fun_l4_n276(x)
+ else
+ fun_l4_n895(x)
+ end
+end
+
+def fun_l3_n853(x)
+ if (x < 1)
+ fun_l4_n945(x)
+ else
+ fun_l4_n251(x)
+ end
+end
+
+def fun_l3_n854(x)
+ if (x < 1)
+ fun_l4_n131(x)
+ else
+ fun_l4_n677(x)
+ end
+end
+
+def fun_l3_n855(x)
+ if (x < 1)
+ fun_l4_n493(x)
+ else
+ fun_l4_n631(x)
+ end
+end
+
+def fun_l3_n856(x)
+ if (x < 1)
+ fun_l4_n608(x)
+ else
+ fun_l4_n556(x)
+ end
+end
+
+def fun_l3_n857(x)
+ if (x < 1)
+ fun_l4_n808(x)
+ else
+ fun_l4_n672(x)
+ end
+end
+
+def fun_l3_n858(x)
+ if (x < 1)
+ fun_l4_n407(x)
+ else
+ fun_l4_n648(x)
+ end
+end
+
+def fun_l3_n859(x)
+ if (x < 1)
+ fun_l4_n217(x)
+ else
+ fun_l4_n763(x)
+ end
+end
+
+def fun_l3_n860(x)
+ if (x < 1)
+ fun_l4_n941(x)
+ else
+ fun_l4_n159(x)
+ end
+end
+
+def fun_l3_n861(x)
+ if (x < 1)
+ fun_l4_n364(x)
+ else
+ fun_l4_n241(x)
+ end
+end
+
+def fun_l3_n862(x)
+ if (x < 1)
+ fun_l4_n915(x)
+ else
+ fun_l4_n729(x)
+ end
+end
+
+def fun_l3_n863(x)
+ if (x < 1)
+ fun_l4_n137(x)
+ else
+ fun_l4_n317(x)
+ end
+end
+
+def fun_l3_n864(x)
+ if (x < 1)
+ fun_l4_n818(x)
+ else
+ fun_l4_n782(x)
+ end
+end
+
+def fun_l3_n865(x)
+ if (x < 1)
+ fun_l4_n577(x)
+ else
+ fun_l4_n418(x)
+ end
+end
+
+def fun_l3_n866(x)
+ if (x < 1)
+ fun_l4_n882(x)
+ else
+ fun_l4_n7(x)
+ end
+end
+
+def fun_l3_n867(x)
+ if (x < 1)
+ fun_l4_n238(x)
+ else
+ fun_l4_n944(x)
+ end
+end
+
+def fun_l3_n868(x)
+ if (x < 1)
+ fun_l4_n105(x)
+ else
+ fun_l4_n465(x)
+ end
+end
+
+def fun_l3_n869(x)
+ if (x < 1)
+ fun_l4_n841(x)
+ else
+ fun_l4_n262(x)
+ end
+end
+
+def fun_l3_n870(x)
+ if (x < 1)
+ fun_l4_n32(x)
+ else
+ fun_l4_n992(x)
+ end
+end
+
+def fun_l3_n871(x)
+ if (x < 1)
+ fun_l4_n431(x)
+ else
+ fun_l4_n391(x)
+ end
+end
+
+def fun_l3_n872(x)
+ if (x < 1)
+ fun_l4_n829(x)
+ else
+ fun_l4_n879(x)
+ end
+end
+
+def fun_l3_n873(x)
+ if (x < 1)
+ fun_l4_n617(x)
+ else
+ fun_l4_n657(x)
+ end
+end
+
+def fun_l3_n874(x)
+ if (x < 1)
+ fun_l4_n529(x)
+ else
+ fun_l4_n717(x)
+ end
+end
+
+def fun_l3_n875(x)
+ if (x < 1)
+ fun_l4_n928(x)
+ else
+ fun_l4_n476(x)
+ end
+end
+
+def fun_l3_n876(x)
+ if (x < 1)
+ fun_l4_n388(x)
+ else
+ fun_l4_n949(x)
+ end
+end
+
+def fun_l3_n877(x)
+ if (x < 1)
+ fun_l4_n826(x)
+ else
+ fun_l4_n560(x)
+ end
+end
+
+def fun_l3_n878(x)
+ if (x < 1)
+ fun_l4_n863(x)
+ else
+ fun_l4_n122(x)
+ end
+end
+
+def fun_l3_n879(x)
+ if (x < 1)
+ fun_l4_n964(x)
+ else
+ fun_l4_n793(x)
+ end
+end
+
+def fun_l3_n880(x)
+ if (x < 1)
+ fun_l4_n141(x)
+ else
+ fun_l4_n132(x)
+ end
+end
+
+def fun_l3_n881(x)
+ if (x < 1)
+ fun_l4_n735(x)
+ else
+ fun_l4_n592(x)
+ end
+end
+
+def fun_l3_n882(x)
+ if (x < 1)
+ fun_l4_n585(x)
+ else
+ fun_l4_n341(x)
+ end
+end
+
+def fun_l3_n883(x)
+ if (x < 1)
+ fun_l4_n843(x)
+ else
+ fun_l4_n692(x)
+ end
+end
+
+def fun_l3_n884(x)
+ if (x < 1)
+ fun_l4_n360(x)
+ else
+ fun_l4_n833(x)
+ end
+end
+
+def fun_l3_n885(x)
+ if (x < 1)
+ fun_l4_n31(x)
+ else
+ fun_l4_n62(x)
+ end
+end
+
+def fun_l3_n886(x)
+ if (x < 1)
+ fun_l4_n756(x)
+ else
+ fun_l4_n699(x)
+ end
+end
+
+def fun_l3_n887(x)
+ if (x < 1)
+ fun_l4_n71(x)
+ else
+ fun_l4_n256(x)
+ end
+end
+
+def fun_l3_n888(x)
+ if (x < 1)
+ fun_l4_n406(x)
+ else
+ fun_l4_n493(x)
+ end
+end
+
+def fun_l3_n889(x)
+ if (x < 1)
+ fun_l4_n489(x)
+ else
+ fun_l4_n874(x)
+ end
+end
+
+def fun_l3_n890(x)
+ if (x < 1)
+ fun_l4_n365(x)
+ else
+ fun_l4_n910(x)
+ end
+end
+
+def fun_l3_n891(x)
+ if (x < 1)
+ fun_l4_n262(x)
+ else
+ fun_l4_n665(x)
+ end
+end
+
+def fun_l3_n892(x)
+ if (x < 1)
+ fun_l4_n274(x)
+ else
+ fun_l4_n849(x)
+ end
+end
+
+def fun_l3_n893(x)
+ if (x < 1)
+ fun_l4_n880(x)
+ else
+ fun_l4_n739(x)
+ end
+end
+
+def fun_l3_n894(x)
+ if (x < 1)
+ fun_l4_n504(x)
+ else
+ fun_l4_n128(x)
+ end
+end
+
+def fun_l3_n895(x)
+ if (x < 1)
+ fun_l4_n555(x)
+ else
+ fun_l4_n281(x)
+ end
+end
+
+def fun_l3_n896(x)
+ if (x < 1)
+ fun_l4_n270(x)
+ else
+ fun_l4_n225(x)
+ end
+end
+
+def fun_l3_n897(x)
+ if (x < 1)
+ fun_l4_n38(x)
+ else
+ fun_l4_n26(x)
+ end
+end
+
+def fun_l3_n898(x)
+ if (x < 1)
+ fun_l4_n944(x)
+ else
+ fun_l4_n217(x)
+ end
+end
+
+def fun_l3_n899(x)
+ if (x < 1)
+ fun_l4_n967(x)
+ else
+ fun_l4_n853(x)
+ end
+end
+
+def fun_l3_n900(x)
+ if (x < 1)
+ fun_l4_n686(x)
+ else
+ fun_l4_n760(x)
+ end
+end
+
+def fun_l3_n901(x)
+ if (x < 1)
+ fun_l4_n698(x)
+ else
+ fun_l4_n842(x)
+ end
+end
+
+def fun_l3_n902(x)
+ if (x < 1)
+ fun_l4_n344(x)
+ else
+ fun_l4_n701(x)
+ end
+end
+
+def fun_l3_n903(x)
+ if (x < 1)
+ fun_l4_n756(x)
+ else
+ fun_l4_n321(x)
+ end
+end
+
+def fun_l3_n904(x)
+ if (x < 1)
+ fun_l4_n504(x)
+ else
+ fun_l4_n228(x)
+ end
+end
+
+def fun_l3_n905(x)
+ if (x < 1)
+ fun_l4_n135(x)
+ else
+ fun_l4_n57(x)
+ end
+end
+
+def fun_l3_n906(x)
+ if (x < 1)
+ fun_l4_n279(x)
+ else
+ fun_l4_n912(x)
+ end
+end
+
+def fun_l3_n907(x)
+ if (x < 1)
+ fun_l4_n962(x)
+ else
+ fun_l4_n418(x)
+ end
+end
+
+def fun_l3_n908(x)
+ if (x < 1)
+ fun_l4_n972(x)
+ else
+ fun_l4_n14(x)
+ end
+end
+
+def fun_l3_n909(x)
+ if (x < 1)
+ fun_l4_n231(x)
+ else
+ fun_l4_n763(x)
+ end
+end
+
+def fun_l3_n910(x)
+ if (x < 1)
+ fun_l4_n859(x)
+ else
+ fun_l4_n243(x)
+ end
+end
+
+def fun_l3_n911(x)
+ if (x < 1)
+ fun_l4_n153(x)
+ else
+ fun_l4_n136(x)
+ end
+end
+
+def fun_l3_n912(x)
+ if (x < 1)
+ fun_l4_n325(x)
+ else
+ fun_l4_n113(x)
+ end
+end
+
+def fun_l3_n913(x)
+ if (x < 1)
+ fun_l4_n625(x)
+ else
+ fun_l4_n179(x)
+ end
+end
+
+def fun_l3_n914(x)
+ if (x < 1)
+ fun_l4_n54(x)
+ else
+ fun_l4_n88(x)
+ end
+end
+
+def fun_l3_n915(x)
+ if (x < 1)
+ fun_l4_n332(x)
+ else
+ fun_l4_n3(x)
+ end
+end
+
+def fun_l3_n916(x)
+ if (x < 1)
+ fun_l4_n748(x)
+ else
+ fun_l4_n21(x)
+ end
+end
+
+def fun_l3_n917(x)
+ if (x < 1)
+ fun_l4_n132(x)
+ else
+ fun_l4_n132(x)
+ end
+end
+
+def fun_l3_n918(x)
+ if (x < 1)
+ fun_l4_n295(x)
+ else
+ fun_l4_n429(x)
+ end
+end
+
+def fun_l3_n919(x)
+ if (x < 1)
+ fun_l4_n105(x)
+ else
+ fun_l4_n984(x)
+ end
+end
+
+def fun_l3_n920(x)
+ if (x < 1)
+ fun_l4_n319(x)
+ else
+ fun_l4_n304(x)
+ end
+end
+
+def fun_l3_n921(x)
+ if (x < 1)
+ fun_l4_n756(x)
+ else
+ fun_l4_n639(x)
+ end
+end
+
+def fun_l3_n922(x)
+ if (x < 1)
+ fun_l4_n678(x)
+ else
+ fun_l4_n209(x)
+ end
+end
+
+def fun_l3_n923(x)
+ if (x < 1)
+ fun_l4_n755(x)
+ else
+ fun_l4_n941(x)
+ end
+end
+
+def fun_l3_n924(x)
+ if (x < 1)
+ fun_l4_n311(x)
+ else
+ fun_l4_n272(x)
+ end
+end
+
+def fun_l3_n925(x)
+ if (x < 1)
+ fun_l4_n543(x)
+ else
+ fun_l4_n896(x)
+ end
+end
+
+def fun_l3_n926(x)
+ if (x < 1)
+ fun_l4_n994(x)
+ else
+ fun_l4_n671(x)
+ end
+end
+
+def fun_l3_n927(x)
+ if (x < 1)
+ fun_l4_n125(x)
+ else
+ fun_l4_n852(x)
+ end
+end
+
+def fun_l3_n928(x)
+ if (x < 1)
+ fun_l4_n483(x)
+ else
+ fun_l4_n350(x)
+ end
+end
+
+def fun_l3_n929(x)
+ if (x < 1)
+ fun_l4_n622(x)
+ else
+ fun_l4_n511(x)
+ end
+end
+
+def fun_l3_n930(x)
+ if (x < 1)
+ fun_l4_n134(x)
+ else
+ fun_l4_n288(x)
+ end
+end
+
+def fun_l3_n931(x)
+ if (x < 1)
+ fun_l4_n278(x)
+ else
+ fun_l4_n800(x)
+ end
+end
+
+def fun_l3_n932(x)
+ if (x < 1)
+ fun_l4_n139(x)
+ else
+ fun_l4_n966(x)
+ end
+end
+
+def fun_l3_n933(x)
+ if (x < 1)
+ fun_l4_n275(x)
+ else
+ fun_l4_n506(x)
+ end
+end
+
+def fun_l3_n934(x)
+ if (x < 1)
+ fun_l4_n503(x)
+ else
+ fun_l4_n204(x)
+ end
+end
+
+def fun_l3_n935(x)
+ if (x < 1)
+ fun_l4_n993(x)
+ else
+ fun_l4_n126(x)
+ end
+end
+
+def fun_l3_n936(x)
+ if (x < 1)
+ fun_l4_n704(x)
+ else
+ fun_l4_n462(x)
+ end
+end
+
+def fun_l3_n937(x)
+ if (x < 1)
+ fun_l4_n922(x)
+ else
+ fun_l4_n722(x)
+ end
+end
+
+def fun_l3_n938(x)
+ if (x < 1)
+ fun_l4_n937(x)
+ else
+ fun_l4_n195(x)
+ end
+end
+
+def fun_l3_n939(x)
+ if (x < 1)
+ fun_l4_n661(x)
+ else
+ fun_l4_n265(x)
+ end
+end
+
+def fun_l3_n940(x)
+ if (x < 1)
+ fun_l4_n423(x)
+ else
+ fun_l4_n230(x)
+ end
+end
+
+def fun_l3_n941(x)
+ if (x < 1)
+ fun_l4_n698(x)
+ else
+ fun_l4_n226(x)
+ end
+end
+
+def fun_l3_n942(x)
+ if (x < 1)
+ fun_l4_n501(x)
+ else
+ fun_l4_n816(x)
+ end
+end
+
+def fun_l3_n943(x)
+ if (x < 1)
+ fun_l4_n650(x)
+ else
+ fun_l4_n925(x)
+ end
+end
+
+def fun_l3_n944(x)
+ if (x < 1)
+ fun_l4_n829(x)
+ else
+ fun_l4_n647(x)
+ end
+end
+
+def fun_l3_n945(x)
+ if (x < 1)
+ fun_l4_n401(x)
+ else
+ fun_l4_n791(x)
+ end
+end
+
+def fun_l3_n946(x)
+ if (x < 1)
+ fun_l4_n551(x)
+ else
+ fun_l4_n104(x)
+ end
+end
+
+def fun_l3_n947(x)
+ if (x < 1)
+ fun_l4_n927(x)
+ else
+ fun_l4_n213(x)
+ end
+end
+
+def fun_l3_n948(x)
+ if (x < 1)
+ fun_l4_n912(x)
+ else
+ fun_l4_n609(x)
+ end
+end
+
+def fun_l3_n949(x)
+ if (x < 1)
+ fun_l4_n302(x)
+ else
+ fun_l4_n157(x)
+ end
+end
+
+def fun_l3_n950(x)
+ if (x < 1)
+ fun_l4_n955(x)
+ else
+ fun_l4_n492(x)
+ end
+end
+
+def fun_l3_n951(x)
+ if (x < 1)
+ fun_l4_n486(x)
+ else
+ fun_l4_n412(x)
+ end
+end
+
+def fun_l3_n952(x)
+ if (x < 1)
+ fun_l4_n850(x)
+ else
+ fun_l4_n885(x)
+ end
+end
+
+def fun_l3_n953(x)
+ if (x < 1)
+ fun_l4_n84(x)
+ else
+ fun_l4_n622(x)
+ end
+end
+
+def fun_l3_n954(x)
+ if (x < 1)
+ fun_l4_n235(x)
+ else
+ fun_l4_n67(x)
+ end
+end
+
+def fun_l3_n955(x)
+ if (x < 1)
+ fun_l4_n347(x)
+ else
+ fun_l4_n757(x)
+ end
+end
+
+def fun_l3_n956(x)
+ if (x < 1)
+ fun_l4_n825(x)
+ else
+ fun_l4_n10(x)
+ end
+end
+
+def fun_l3_n957(x)
+ if (x < 1)
+ fun_l4_n393(x)
+ else
+ fun_l4_n482(x)
+ end
+end
+
+def fun_l3_n958(x)
+ if (x < 1)
+ fun_l4_n0(x)
+ else
+ fun_l4_n556(x)
+ end
+end
+
+def fun_l3_n959(x)
+ if (x < 1)
+ fun_l4_n806(x)
+ else
+ fun_l4_n783(x)
+ end
+end
+
+def fun_l3_n960(x)
+ if (x < 1)
+ fun_l4_n964(x)
+ else
+ fun_l4_n843(x)
+ end
+end
+
+def fun_l3_n961(x)
+ if (x < 1)
+ fun_l4_n508(x)
+ else
+ fun_l4_n874(x)
+ end
+end
+
+def fun_l3_n962(x)
+ if (x < 1)
+ fun_l4_n15(x)
+ else
+ fun_l4_n197(x)
+ end
+end
+
+def fun_l3_n963(x)
+ if (x < 1)
+ fun_l4_n989(x)
+ else
+ fun_l4_n380(x)
+ end
+end
+
+def fun_l3_n964(x)
+ if (x < 1)
+ fun_l4_n315(x)
+ else
+ fun_l4_n196(x)
+ end
+end
+
+def fun_l3_n965(x)
+ if (x < 1)
+ fun_l4_n510(x)
+ else
+ fun_l4_n275(x)
+ end
+end
+
+def fun_l3_n966(x)
+ if (x < 1)
+ fun_l4_n725(x)
+ else
+ fun_l4_n94(x)
+ end
+end
+
+def fun_l3_n967(x)
+ if (x < 1)
+ fun_l4_n733(x)
+ else
+ fun_l4_n577(x)
+ end
+end
+
+def fun_l3_n968(x)
+ if (x < 1)
+ fun_l4_n280(x)
+ else
+ fun_l4_n702(x)
+ end
+end
+
+def fun_l3_n969(x)
+ if (x < 1)
+ fun_l4_n41(x)
+ else
+ fun_l4_n343(x)
+ end
+end
+
+def fun_l3_n970(x)
+ if (x < 1)
+ fun_l4_n102(x)
+ else
+ fun_l4_n785(x)
+ end
+end
+
+def fun_l3_n971(x)
+ if (x < 1)
+ fun_l4_n460(x)
+ else
+ fun_l4_n388(x)
+ end
+end
+
+def fun_l3_n972(x)
+ if (x < 1)
+ fun_l4_n31(x)
+ else
+ fun_l4_n421(x)
+ end
+end
+
+def fun_l3_n973(x)
+ if (x < 1)
+ fun_l4_n587(x)
+ else
+ fun_l4_n401(x)
+ end
+end
+
+def fun_l3_n974(x)
+ if (x < 1)
+ fun_l4_n593(x)
+ else
+ fun_l4_n418(x)
+ end
+end
+
+def fun_l3_n975(x)
+ if (x < 1)
+ fun_l4_n12(x)
+ else
+ fun_l4_n929(x)
+ end
+end
+
+def fun_l3_n976(x)
+ if (x < 1)
+ fun_l4_n516(x)
+ else
+ fun_l4_n402(x)
+ end
+end
+
+def fun_l3_n977(x)
+ if (x < 1)
+ fun_l4_n590(x)
+ else
+ fun_l4_n876(x)
+ end
+end
+
+def fun_l3_n978(x)
+ if (x < 1)
+ fun_l4_n505(x)
+ else
+ fun_l4_n94(x)
+ end
+end
+
+def fun_l3_n979(x)
+ if (x < 1)
+ fun_l4_n625(x)
+ else
+ fun_l4_n344(x)
+ end
+end
+
+def fun_l3_n980(x)
+ if (x < 1)
+ fun_l4_n128(x)
+ else
+ fun_l4_n454(x)
+ end
+end
+
+def fun_l3_n981(x)
+ if (x < 1)
+ fun_l4_n937(x)
+ else
+ fun_l4_n277(x)
+ end
+end
+
+def fun_l3_n982(x)
+ if (x < 1)
+ fun_l4_n237(x)
+ else
+ fun_l4_n113(x)
+ end
+end
+
+def fun_l3_n983(x)
+ if (x < 1)
+ fun_l4_n668(x)
+ else
+ fun_l4_n668(x)
+ end
+end
+
+def fun_l3_n984(x)
+ if (x < 1)
+ fun_l4_n783(x)
+ else
+ fun_l4_n771(x)
+ end
+end
+
+def fun_l3_n985(x)
+ if (x < 1)
+ fun_l4_n135(x)
+ else
+ fun_l4_n967(x)
+ end
+end
+
+def fun_l3_n986(x)
+ if (x < 1)
+ fun_l4_n29(x)
+ else
+ fun_l4_n313(x)
+ end
+end
+
+def fun_l3_n987(x)
+ if (x < 1)
+ fun_l4_n765(x)
+ else
+ fun_l4_n885(x)
+ end
+end
+
+def fun_l3_n988(x)
+ if (x < 1)
+ fun_l4_n242(x)
+ else
+ fun_l4_n622(x)
+ end
+end
+
+def fun_l3_n989(x)
+ if (x < 1)
+ fun_l4_n916(x)
+ else
+ fun_l4_n518(x)
+ end
+end
+
+def fun_l3_n990(x)
+ if (x < 1)
+ fun_l4_n523(x)
+ else
+ fun_l4_n468(x)
+ end
+end
+
+def fun_l3_n991(x)
+ if (x < 1)
+ fun_l4_n904(x)
+ else
+ fun_l4_n601(x)
+ end
+end
+
+def fun_l3_n992(x)
+ if (x < 1)
+ fun_l4_n437(x)
+ else
+ fun_l4_n77(x)
+ end
+end
+
+def fun_l3_n993(x)
+ if (x < 1)
+ fun_l4_n957(x)
+ else
+ fun_l4_n619(x)
+ end
+end
+
+def fun_l3_n994(x)
+ if (x < 1)
+ fun_l4_n540(x)
+ else
+ fun_l4_n108(x)
+ end
+end
+
+def fun_l3_n995(x)
+ if (x < 1)
+ fun_l4_n8(x)
+ else
+ fun_l4_n428(x)
+ end
+end
+
+def fun_l3_n996(x)
+ if (x < 1)
+ fun_l4_n53(x)
+ else
+ fun_l4_n278(x)
+ end
+end
+
+def fun_l3_n997(x)
+ if (x < 1)
+ fun_l4_n930(x)
+ else
+ fun_l4_n671(x)
+ end
+end
+
+def fun_l3_n998(x)
+ if (x < 1)
+ fun_l4_n574(x)
+ else
+ fun_l4_n879(x)
+ end
+end
+
+def fun_l3_n999(x)
+ if (x < 1)
+ fun_l4_n316(x)
+ else
+ fun_l4_n93(x)
+ end
+end
+
+def fun_l4_n0(x)
+ if (x < 1)
+ fun_l5_n524(x)
+ else
+ fun_l5_n284(x)
+ end
+end
+
+def fun_l4_n1(x)
+ if (x < 1)
+ fun_l5_n845(x)
+ else
+ fun_l5_n863(x)
+ end
+end
+
+def fun_l4_n2(x)
+ if (x < 1)
+ fun_l5_n258(x)
+ else
+ fun_l5_n860(x)
+ end
+end
+
+def fun_l4_n3(x)
+ if (x < 1)
+ fun_l5_n253(x)
+ else
+ fun_l5_n763(x)
+ end
+end
+
+def fun_l4_n4(x)
+ if (x < 1)
+ fun_l5_n833(x)
+ else
+ fun_l5_n807(x)
+ end
+end
+
+def fun_l4_n5(x)
+ if (x < 1)
+ fun_l5_n890(x)
+ else
+ fun_l5_n669(x)
+ end
+end
+
+def fun_l4_n6(x)
+ if (x < 1)
+ fun_l5_n396(x)
+ else
+ fun_l5_n388(x)
+ end
+end
+
+def fun_l4_n7(x)
+ if (x < 1)
+ fun_l5_n926(x)
+ else
+ fun_l5_n661(x)
+ end
+end
+
+def fun_l4_n8(x)
+ if (x < 1)
+ fun_l5_n990(x)
+ else
+ fun_l5_n765(x)
+ end
+end
+
+def fun_l4_n9(x)
+ if (x < 1)
+ fun_l5_n978(x)
+ else
+ fun_l5_n342(x)
+ end
+end
+
+def fun_l4_n10(x)
+ if (x < 1)
+ fun_l5_n500(x)
+ else
+ fun_l5_n758(x)
+ end
+end
+
+def fun_l4_n11(x)
+ if (x < 1)
+ fun_l5_n10(x)
+ else
+ fun_l5_n796(x)
+ end
+end
+
+def fun_l4_n12(x)
+ if (x < 1)
+ fun_l5_n173(x)
+ else
+ fun_l5_n87(x)
+ end
+end
+
+def fun_l4_n13(x)
+ if (x < 1)
+ fun_l5_n852(x)
+ else
+ fun_l5_n93(x)
+ end
+end
+
+def fun_l4_n14(x)
+ if (x < 1)
+ fun_l5_n526(x)
+ else
+ fun_l5_n144(x)
+ end
+end
+
+def fun_l4_n15(x)
+ if (x < 1)
+ fun_l5_n398(x)
+ else
+ fun_l5_n632(x)
+ end
+end
+
+def fun_l4_n16(x)
+ if (x < 1)
+ fun_l5_n774(x)
+ else
+ fun_l5_n716(x)
+ end
+end
+
+def fun_l4_n17(x)
+ if (x < 1)
+ fun_l5_n412(x)
+ else
+ fun_l5_n95(x)
+ end
+end
+
+def fun_l4_n18(x)
+ if (x < 1)
+ fun_l5_n446(x)
+ else
+ fun_l5_n885(x)
+ end
+end
+
+def fun_l4_n19(x)
+ if (x < 1)
+ fun_l5_n420(x)
+ else
+ fun_l5_n420(x)
+ end
+end
+
+def fun_l4_n20(x)
+ if (x < 1)
+ fun_l5_n274(x)
+ else
+ fun_l5_n813(x)
+ end
+end
+
+def fun_l4_n21(x)
+ if (x < 1)
+ fun_l5_n174(x)
+ else
+ fun_l5_n781(x)
+ end
+end
+
+def fun_l4_n22(x)
+ if (x < 1)
+ fun_l5_n903(x)
+ else
+ fun_l5_n224(x)
+ end
+end
+
+def fun_l4_n23(x)
+ if (x < 1)
+ fun_l5_n317(x)
+ else
+ fun_l5_n900(x)
+ end
+end
+
+def fun_l4_n24(x)
+ if (x < 1)
+ fun_l5_n600(x)
+ else
+ fun_l5_n515(x)
+ end
+end
+
+def fun_l4_n25(x)
+ if (x < 1)
+ fun_l5_n151(x)
+ else
+ fun_l5_n790(x)
+ end
+end
+
+def fun_l4_n26(x)
+ if (x < 1)
+ fun_l5_n256(x)
+ else
+ fun_l5_n449(x)
+ end
+end
+
+def fun_l4_n27(x)
+ if (x < 1)
+ fun_l5_n985(x)
+ else
+ fun_l5_n763(x)
+ end
+end
+
+def fun_l4_n28(x)
+ if (x < 1)
+ fun_l5_n961(x)
+ else
+ fun_l5_n86(x)
+ end
+end
+
+def fun_l4_n29(x)
+ if (x < 1)
+ fun_l5_n359(x)
+ else
+ fun_l5_n894(x)
+ end
+end
+
+def fun_l4_n30(x)
+ if (x < 1)
+ fun_l5_n426(x)
+ else
+ fun_l5_n983(x)
+ end
+end
+
+def fun_l4_n31(x)
+ if (x < 1)
+ fun_l5_n996(x)
+ else
+ fun_l5_n343(x)
+ end
+end
+
+def fun_l4_n32(x)
+ if (x < 1)
+ fun_l5_n300(x)
+ else
+ fun_l5_n719(x)
+ end
+end
+
+def fun_l4_n33(x)
+ if (x < 1)
+ fun_l5_n755(x)
+ else
+ fun_l5_n623(x)
+ end
+end
+
+def fun_l4_n34(x)
+ if (x < 1)
+ fun_l5_n681(x)
+ else
+ fun_l5_n410(x)
+ end
+end
+
+def fun_l4_n35(x)
+ if (x < 1)
+ fun_l5_n356(x)
+ else
+ fun_l5_n351(x)
+ end
+end
+
+def fun_l4_n36(x)
+ if (x < 1)
+ fun_l5_n463(x)
+ else
+ fun_l5_n402(x)
+ end
+end
+
+def fun_l4_n37(x)
+ if (x < 1)
+ fun_l5_n250(x)
+ else
+ fun_l5_n681(x)
+ end
+end
+
+def fun_l4_n38(x)
+ if (x < 1)
+ fun_l5_n573(x)
+ else
+ fun_l5_n622(x)
+ end
+end
+
+def fun_l4_n39(x)
+ if (x < 1)
+ fun_l5_n545(x)
+ else
+ fun_l5_n210(x)
+ end
+end
+
+def fun_l4_n40(x)
+ if (x < 1)
+ fun_l5_n264(x)
+ else
+ fun_l5_n239(x)
+ end
+end
+
+def fun_l4_n41(x)
+ if (x < 1)
+ fun_l5_n635(x)
+ else
+ fun_l5_n224(x)
+ end
+end
+
+def fun_l4_n42(x)
+ if (x < 1)
+ fun_l5_n806(x)
+ else
+ fun_l5_n125(x)
+ end
+end
+
+def fun_l4_n43(x)
+ if (x < 1)
+ fun_l5_n480(x)
+ else
+ fun_l5_n625(x)
+ end
+end
+
+def fun_l4_n44(x)
+ if (x < 1)
+ fun_l5_n644(x)
+ else
+ fun_l5_n465(x)
+ end
+end
+
+def fun_l4_n45(x)
+ if (x < 1)
+ fun_l5_n999(x)
+ else
+ fun_l5_n759(x)
+ end
+end
+
+def fun_l4_n46(x)
+ if (x < 1)
+ fun_l5_n866(x)
+ else
+ fun_l5_n536(x)
+ end
+end
+
+def fun_l4_n47(x)
+ if (x < 1)
+ fun_l5_n328(x)
+ else
+ fun_l5_n533(x)
+ end
+end
+
+def fun_l4_n48(x)
+ if (x < 1)
+ fun_l5_n902(x)
+ else
+ fun_l5_n919(x)
+ end
+end
+
+def fun_l4_n49(x)
+ if (x < 1)
+ fun_l5_n197(x)
+ else
+ fun_l5_n262(x)
+ end
+end
+
+def fun_l4_n50(x)
+ if (x < 1)
+ fun_l5_n172(x)
+ else
+ fun_l5_n731(x)
+ end
+end
+
+def fun_l4_n51(x)
+ if (x < 1)
+ fun_l5_n502(x)
+ else
+ fun_l5_n149(x)
+ end
+end
+
+def fun_l4_n52(x)
+ if (x < 1)
+ fun_l5_n69(x)
+ else
+ fun_l5_n536(x)
+ end
+end
+
+def fun_l4_n53(x)
+ if (x < 1)
+ fun_l5_n932(x)
+ else
+ fun_l5_n482(x)
+ end
+end
+
+def fun_l4_n54(x)
+ if (x < 1)
+ fun_l5_n982(x)
+ else
+ fun_l5_n207(x)
+ end
+end
+
+def fun_l4_n55(x)
+ if (x < 1)
+ fun_l5_n949(x)
+ else
+ fun_l5_n9(x)
+ end
+end
+
+def fun_l4_n56(x)
+ if (x < 1)
+ fun_l5_n672(x)
+ else
+ fun_l5_n924(x)
+ end
+end
+
+def fun_l4_n57(x)
+ if (x < 1)
+ fun_l5_n757(x)
+ else
+ fun_l5_n609(x)
+ end
+end
+
+def fun_l4_n58(x)
+ if (x < 1)
+ fun_l5_n251(x)
+ else
+ fun_l5_n471(x)
+ end
+end
+
+def fun_l4_n59(x)
+ if (x < 1)
+ fun_l5_n878(x)
+ else
+ fun_l5_n626(x)
+ end
+end
+
+def fun_l4_n60(x)
+ if (x < 1)
+ fun_l5_n859(x)
+ else
+ fun_l5_n646(x)
+ end
+end
+
+def fun_l4_n61(x)
+ if (x < 1)
+ fun_l5_n417(x)
+ else
+ fun_l5_n587(x)
+ end
+end
+
+def fun_l4_n62(x)
+ if (x < 1)
+ fun_l5_n164(x)
+ else
+ fun_l5_n861(x)
+ end
+end
+
+def fun_l4_n63(x)
+ if (x < 1)
+ fun_l5_n591(x)
+ else
+ fun_l5_n79(x)
+ end
+end
+
+def fun_l4_n64(x)
+ if (x < 1)
+ fun_l5_n269(x)
+ else
+ fun_l5_n336(x)
+ end
+end
+
+def fun_l4_n65(x)
+ if (x < 1)
+ fun_l5_n420(x)
+ else
+ fun_l5_n557(x)
+ end
+end
+
+def fun_l4_n66(x)
+ if (x < 1)
+ fun_l5_n61(x)
+ else
+ fun_l5_n690(x)
+ end
+end
+
+def fun_l4_n67(x)
+ if (x < 1)
+ fun_l5_n939(x)
+ else
+ fun_l5_n139(x)
+ end
+end
+
+def fun_l4_n68(x)
+ if (x < 1)
+ fun_l5_n430(x)
+ else
+ fun_l5_n625(x)
+ end
+end
+
+def fun_l4_n69(x)
+ if (x < 1)
+ fun_l5_n532(x)
+ else
+ fun_l5_n909(x)
+ end
+end
+
+def fun_l4_n70(x)
+ if (x < 1)
+ fun_l5_n937(x)
+ else
+ fun_l5_n886(x)
+ end
+end
+
+def fun_l4_n71(x)
+ if (x < 1)
+ fun_l5_n554(x)
+ else
+ fun_l5_n898(x)
+ end
+end
+
+def fun_l4_n72(x)
+ if (x < 1)
+ fun_l5_n390(x)
+ else
+ fun_l5_n690(x)
+ end
+end
+
+def fun_l4_n73(x)
+ if (x < 1)
+ fun_l5_n980(x)
+ else
+ fun_l5_n248(x)
+ end
+end
+
+def fun_l4_n74(x)
+ if (x < 1)
+ fun_l5_n438(x)
+ else
+ fun_l5_n247(x)
+ end
+end
+
+def fun_l4_n75(x)
+ if (x < 1)
+ fun_l5_n798(x)
+ else
+ fun_l5_n399(x)
+ end
+end
+
+def fun_l4_n76(x)
+ if (x < 1)
+ fun_l5_n419(x)
+ else
+ fun_l5_n754(x)
+ end
+end
+
+def fun_l4_n77(x)
+ if (x < 1)
+ fun_l5_n875(x)
+ else
+ fun_l5_n18(x)
+ end
+end
+
+def fun_l4_n78(x)
+ if (x < 1)
+ fun_l5_n695(x)
+ else
+ fun_l5_n336(x)
+ end
+end
+
+def fun_l4_n79(x)
+ if (x < 1)
+ fun_l5_n185(x)
+ else
+ fun_l5_n627(x)
+ end
+end
+
+def fun_l4_n80(x)
+ if (x < 1)
+ fun_l5_n359(x)
+ else
+ fun_l5_n465(x)
+ end
+end
+
+def fun_l4_n81(x)
+ if (x < 1)
+ fun_l5_n284(x)
+ else
+ fun_l5_n232(x)
+ end
+end
+
+def fun_l4_n82(x)
+ if (x < 1)
+ fun_l5_n947(x)
+ else
+ fun_l5_n748(x)
+ end
+end
+
+def fun_l4_n83(x)
+ if (x < 1)
+ fun_l5_n254(x)
+ else
+ fun_l5_n836(x)
+ end
+end
+
+def fun_l4_n84(x)
+ if (x < 1)
+ fun_l5_n181(x)
+ else
+ fun_l5_n789(x)
+ end
+end
+
+def fun_l4_n85(x)
+ if (x < 1)
+ fun_l5_n682(x)
+ else
+ fun_l5_n547(x)
+ end
+end
+
+def fun_l4_n86(x)
+ if (x < 1)
+ fun_l5_n35(x)
+ else
+ fun_l5_n157(x)
+ end
+end
+
+def fun_l4_n87(x)
+ if (x < 1)
+ fun_l5_n981(x)
+ else
+ fun_l5_n724(x)
+ end
+end
+
+def fun_l4_n88(x)
+ if (x < 1)
+ fun_l5_n35(x)
+ else
+ fun_l5_n914(x)
+ end
+end
+
+def fun_l4_n89(x)
+ if (x < 1)
+ fun_l5_n844(x)
+ else
+ fun_l5_n668(x)
+ end
+end
+
+def fun_l4_n90(x)
+ if (x < 1)
+ fun_l5_n615(x)
+ else
+ fun_l5_n415(x)
+ end
+end
+
+def fun_l4_n91(x)
+ if (x < 1)
+ fun_l5_n141(x)
+ else
+ fun_l5_n538(x)
+ end
+end
+
+def fun_l4_n92(x)
+ if (x < 1)
+ fun_l5_n563(x)
+ else
+ fun_l5_n60(x)
+ end
+end
+
+def fun_l4_n93(x)
+ if (x < 1)
+ fun_l5_n967(x)
+ else
+ fun_l5_n549(x)
+ end
+end
+
+def fun_l4_n94(x)
+ if (x < 1)
+ fun_l5_n992(x)
+ else
+ fun_l5_n34(x)
+ end
+end
+
+def fun_l4_n95(x)
+ if (x < 1)
+ fun_l5_n187(x)
+ else
+ fun_l5_n980(x)
+ end
+end
+
+def fun_l4_n96(x)
+ if (x < 1)
+ fun_l5_n543(x)
+ else
+ fun_l5_n318(x)
+ end
+end
+
+def fun_l4_n97(x)
+ if (x < 1)
+ fun_l5_n253(x)
+ else
+ fun_l5_n709(x)
+ end
+end
+
+def fun_l4_n98(x)
+ if (x < 1)
+ fun_l5_n233(x)
+ else
+ fun_l5_n963(x)
+ end
+end
+
+def fun_l4_n99(x)
+ if (x < 1)
+ fun_l5_n944(x)
+ else
+ fun_l5_n688(x)
+ end
+end
+
+def fun_l4_n100(x)
+ if (x < 1)
+ fun_l5_n422(x)
+ else
+ fun_l5_n805(x)
+ end
+end
+
+def fun_l4_n101(x)
+ if (x < 1)
+ fun_l5_n125(x)
+ else
+ fun_l5_n729(x)
+ end
+end
+
+def fun_l4_n102(x)
+ if (x < 1)
+ fun_l5_n339(x)
+ else
+ fun_l5_n394(x)
+ end
+end
+
+def fun_l4_n103(x)
+ if (x < 1)
+ fun_l5_n149(x)
+ else
+ fun_l5_n839(x)
+ end
+end
+
+def fun_l4_n104(x)
+ if (x < 1)
+ fun_l5_n750(x)
+ else
+ fun_l5_n514(x)
+ end
+end
+
+def fun_l4_n105(x)
+ if (x < 1)
+ fun_l5_n726(x)
+ else
+ fun_l5_n251(x)
+ end
+end
+
+def fun_l4_n106(x)
+ if (x < 1)
+ fun_l5_n810(x)
+ else
+ fun_l5_n46(x)
+ end
+end
+
+def fun_l4_n107(x)
+ if (x < 1)
+ fun_l5_n702(x)
+ else
+ fun_l5_n224(x)
+ end
+end
+
+def fun_l4_n108(x)
+ if (x < 1)
+ fun_l5_n604(x)
+ else
+ fun_l5_n24(x)
+ end
+end
+
+def fun_l4_n109(x)
+ if (x < 1)
+ fun_l5_n511(x)
+ else
+ fun_l5_n529(x)
+ end
+end
+
+def fun_l4_n110(x)
+ if (x < 1)
+ fun_l5_n193(x)
+ else
+ fun_l5_n210(x)
+ end
+end
+
+def fun_l4_n111(x)
+ if (x < 1)
+ fun_l5_n599(x)
+ else
+ fun_l5_n85(x)
+ end
+end
+
+def fun_l4_n112(x)
+ if (x < 1)
+ fun_l5_n910(x)
+ else
+ fun_l5_n292(x)
+ end
+end
+
+def fun_l4_n113(x)
+ if (x < 1)
+ fun_l5_n851(x)
+ else
+ fun_l5_n269(x)
+ end
+end
+
+def fun_l4_n114(x)
+ if (x < 1)
+ fun_l5_n739(x)
+ else
+ fun_l5_n439(x)
+ end
+end
+
+def fun_l4_n115(x)
+ if (x < 1)
+ fun_l5_n580(x)
+ else
+ fun_l5_n656(x)
+ end
+end
+
+def fun_l4_n116(x)
+ if (x < 1)
+ fun_l5_n992(x)
+ else
+ fun_l5_n703(x)
+ end
+end
+
+def fun_l4_n117(x)
+ if (x < 1)
+ fun_l5_n549(x)
+ else
+ fun_l5_n300(x)
+ end
+end
+
+def fun_l4_n118(x)
+ if (x < 1)
+ fun_l5_n785(x)
+ else
+ fun_l5_n596(x)
+ end
+end
+
+def fun_l4_n119(x)
+ if (x < 1)
+ fun_l5_n236(x)
+ else
+ fun_l5_n84(x)
+ end
+end
+
+def fun_l4_n120(x)
+ if (x < 1)
+ fun_l5_n78(x)
+ else
+ fun_l5_n610(x)
+ end
+end
+
+def fun_l4_n121(x)
+ if (x < 1)
+ fun_l5_n591(x)
+ else
+ fun_l5_n557(x)
+ end
+end
+
+def fun_l4_n122(x)
+ if (x < 1)
+ fun_l5_n927(x)
+ else
+ fun_l5_n40(x)
+ end
+end
+
+def fun_l4_n123(x)
+ if (x < 1)
+ fun_l5_n620(x)
+ else
+ fun_l5_n173(x)
+ end
+end
+
+def fun_l4_n124(x)
+ if (x < 1)
+ fun_l5_n558(x)
+ else
+ fun_l5_n330(x)
+ end
+end
+
+def fun_l4_n125(x)
+ if (x < 1)
+ fun_l5_n535(x)
+ else
+ fun_l5_n636(x)
+ end
+end
+
+def fun_l4_n126(x)
+ if (x < 1)
+ fun_l5_n401(x)
+ else
+ fun_l5_n747(x)
+ end
+end
+
+def fun_l4_n127(x)
+ if (x < 1)
+ fun_l5_n172(x)
+ else
+ fun_l5_n124(x)
+ end
+end
+
+def fun_l4_n128(x)
+ if (x < 1)
+ fun_l5_n449(x)
+ else
+ fun_l5_n619(x)
+ end
+end
+
+def fun_l4_n129(x)
+ if (x < 1)
+ fun_l5_n564(x)
+ else
+ fun_l5_n306(x)
+ end
+end
+
+def fun_l4_n130(x)
+ if (x < 1)
+ fun_l5_n196(x)
+ else
+ fun_l5_n170(x)
+ end
+end
+
+def fun_l4_n131(x)
+ if (x < 1)
+ fun_l5_n383(x)
+ else
+ fun_l5_n87(x)
+ end
+end
+
+def fun_l4_n132(x)
+ if (x < 1)
+ fun_l5_n568(x)
+ else
+ fun_l5_n54(x)
+ end
+end
+
+def fun_l4_n133(x)
+ if (x < 1)
+ fun_l5_n780(x)
+ else
+ fun_l5_n184(x)
+ end
+end
+
+def fun_l4_n134(x)
+ if (x < 1)
+ fun_l5_n880(x)
+ else
+ fun_l5_n38(x)
+ end
+end
+
+def fun_l4_n135(x)
+ if (x < 1)
+ fun_l5_n819(x)
+ else
+ fun_l5_n440(x)
+ end
+end
+
+def fun_l4_n136(x)
+ if (x < 1)
+ fun_l5_n301(x)
+ else
+ fun_l5_n676(x)
+ end
+end
+
+def fun_l4_n137(x)
+ if (x < 1)
+ fun_l5_n69(x)
+ else
+ fun_l5_n333(x)
+ end
+end
+
+def fun_l4_n138(x)
+ if (x < 1)
+ fun_l5_n303(x)
+ else
+ fun_l5_n69(x)
+ end
+end
+
+def fun_l4_n139(x)
+ if (x < 1)
+ fun_l5_n939(x)
+ else
+ fun_l5_n103(x)
+ end
+end
+
+def fun_l4_n140(x)
+ if (x < 1)
+ fun_l5_n517(x)
+ else
+ fun_l5_n24(x)
+ end
+end
+
+def fun_l4_n141(x)
+ if (x < 1)
+ fun_l5_n923(x)
+ else
+ fun_l5_n968(x)
+ end
+end
+
+def fun_l4_n142(x)
+ if (x < 1)
+ fun_l5_n196(x)
+ else
+ fun_l5_n841(x)
+ end
+end
+
+def fun_l4_n143(x)
+ if (x < 1)
+ fun_l5_n726(x)
+ else
+ fun_l5_n715(x)
+ end
+end
+
+def fun_l4_n144(x)
+ if (x < 1)
+ fun_l5_n434(x)
+ else
+ fun_l5_n771(x)
+ end
+end
+
+def fun_l4_n145(x)
+ if (x < 1)
+ fun_l5_n211(x)
+ else
+ fun_l5_n963(x)
+ end
+end
+
+def fun_l4_n146(x)
+ if (x < 1)
+ fun_l5_n534(x)
+ else
+ fun_l5_n5(x)
+ end
+end
+
+def fun_l4_n147(x)
+ if (x < 1)
+ fun_l5_n409(x)
+ else
+ fun_l5_n298(x)
+ end
+end
+
+def fun_l4_n148(x)
+ if (x < 1)
+ fun_l5_n447(x)
+ else
+ fun_l5_n474(x)
+ end
+end
+
+def fun_l4_n149(x)
+ if (x < 1)
+ fun_l5_n181(x)
+ else
+ fun_l5_n87(x)
+ end
+end
+
+def fun_l4_n150(x)
+ if (x < 1)
+ fun_l5_n871(x)
+ else
+ fun_l5_n201(x)
+ end
+end
+
+def fun_l4_n151(x)
+ if (x < 1)
+ fun_l5_n539(x)
+ else
+ fun_l5_n855(x)
+ end
+end
+
+def fun_l4_n152(x)
+ if (x < 1)
+ fun_l5_n387(x)
+ else
+ fun_l5_n730(x)
+ end
+end
+
+def fun_l4_n153(x)
+ if (x < 1)
+ fun_l5_n785(x)
+ else
+ fun_l5_n774(x)
+ end
+end
+
+def fun_l4_n154(x)
+ if (x < 1)
+ fun_l5_n924(x)
+ else
+ fun_l5_n414(x)
+ end
+end
+
+def fun_l4_n155(x)
+ if (x < 1)
+ fun_l5_n110(x)
+ else
+ fun_l5_n669(x)
+ end
+end
+
+def fun_l4_n156(x)
+ if (x < 1)
+ fun_l5_n551(x)
+ else
+ fun_l5_n456(x)
+ end
+end
+
+def fun_l4_n157(x)
+ if (x < 1)
+ fun_l5_n872(x)
+ else
+ fun_l5_n397(x)
+ end
+end
+
+def fun_l4_n158(x)
+ if (x < 1)
+ fun_l5_n208(x)
+ else
+ fun_l5_n464(x)
+ end
+end
+
+def fun_l4_n159(x)
+ if (x < 1)
+ fun_l5_n236(x)
+ else
+ fun_l5_n532(x)
+ end
+end
+
+def fun_l4_n160(x)
+ if (x < 1)
+ fun_l5_n820(x)
+ else
+ fun_l5_n146(x)
+ end
+end
+
+def fun_l4_n161(x)
+ if (x < 1)
+ fun_l5_n154(x)
+ else
+ fun_l5_n388(x)
+ end
+end
+
+def fun_l4_n162(x)
+ if (x < 1)
+ fun_l5_n456(x)
+ else
+ fun_l5_n309(x)
+ end
+end
+
+def fun_l4_n163(x)
+ if (x < 1)
+ fun_l5_n201(x)
+ else
+ fun_l5_n728(x)
+ end
+end
+
+def fun_l4_n164(x)
+ if (x < 1)
+ fun_l5_n806(x)
+ else
+ fun_l5_n156(x)
+ end
+end
+
+def fun_l4_n165(x)
+ if (x < 1)
+ fun_l5_n984(x)
+ else
+ fun_l5_n996(x)
+ end
+end
+
+def fun_l4_n166(x)
+ if (x < 1)
+ fun_l5_n253(x)
+ else
+ fun_l5_n527(x)
+ end
+end
+
+def fun_l4_n167(x)
+ if (x < 1)
+ fun_l5_n513(x)
+ else
+ fun_l5_n145(x)
+ end
+end
+
+def fun_l4_n168(x)
+ if (x < 1)
+ fun_l5_n694(x)
+ else
+ fun_l5_n841(x)
+ end
+end
+
+def fun_l4_n169(x)
+ if (x < 1)
+ fun_l5_n463(x)
+ else
+ fun_l5_n193(x)
+ end
+end
+
+def fun_l4_n170(x)
+ if (x < 1)
+ fun_l5_n638(x)
+ else
+ fun_l5_n252(x)
+ end
+end
+
+def fun_l4_n171(x)
+ if (x < 1)
+ fun_l5_n166(x)
+ else
+ fun_l5_n134(x)
+ end
+end
+
+def fun_l4_n172(x)
+ if (x < 1)
+ fun_l5_n172(x)
+ else
+ fun_l5_n179(x)
+ end
+end
+
+def fun_l4_n173(x)
+ if (x < 1)
+ fun_l5_n218(x)
+ else
+ fun_l5_n124(x)
+ end
+end
+
+def fun_l4_n174(x)
+ if (x < 1)
+ fun_l5_n370(x)
+ else
+ fun_l5_n742(x)
+ end
+end
+
+def fun_l4_n175(x)
+ if (x < 1)
+ fun_l5_n593(x)
+ else
+ fun_l5_n542(x)
+ end
+end
+
+def fun_l4_n176(x)
+ if (x < 1)
+ fun_l5_n438(x)
+ else
+ fun_l5_n606(x)
+ end
+end
+
+def fun_l4_n177(x)
+ if (x < 1)
+ fun_l5_n316(x)
+ else
+ fun_l5_n92(x)
+ end
+end
+
+def fun_l4_n178(x)
+ if (x < 1)
+ fun_l5_n222(x)
+ else
+ fun_l5_n461(x)
+ end
+end
+
+def fun_l4_n179(x)
+ if (x < 1)
+ fun_l5_n244(x)
+ else
+ fun_l5_n536(x)
+ end
+end
+
+def fun_l4_n180(x)
+ if (x < 1)
+ fun_l5_n120(x)
+ else
+ fun_l5_n905(x)
+ end
+end
+
+def fun_l4_n181(x)
+ if (x < 1)
+ fun_l5_n601(x)
+ else
+ fun_l5_n62(x)
+ end
+end
+
+def fun_l4_n182(x)
+ if (x < 1)
+ fun_l5_n701(x)
+ else
+ fun_l5_n25(x)
+ end
+end
+
+def fun_l4_n183(x)
+ if (x < 1)
+ fun_l5_n361(x)
+ else
+ fun_l5_n433(x)
+ end
+end
+
+def fun_l4_n184(x)
+ if (x < 1)
+ fun_l5_n29(x)
+ else
+ fun_l5_n302(x)
+ end
+end
+
+def fun_l4_n185(x)
+ if (x < 1)
+ fun_l5_n697(x)
+ else
+ fun_l5_n849(x)
+ end
+end