mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	separate rb_random_t
* random.c: separate abstract rb_random_t and rb_random_mt_t for Mersenne Twister implementation. * include/ruby/random.h: the interface for extensions of Random class. * DLL imported symbol reference is not constant on Windows. * check if properly initialized.
This commit is contained in:
		
							parent
							
								
									f4d5273989
								
							
						
					
					
						commit
						af5e87ab21
					
				
				
				Notes:
				
					git
				
				2020-09-07 20:08:35 +09:00 
				
			
			
			
		
		
					 8 changed files with 774 additions and 121 deletions
				
			
		| 
						 | 
				
			
			@ -10385,6 +10385,7 @@ random.$(OBJEXT): {$(VPATH)}mt19937.c
 | 
			
		|||
random.$(OBJEXT): {$(VPATH)}onigmo.h
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}oniguruma.h
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}random.c
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}random.h
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}ruby_atomic.h
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}siphash.c
 | 
			
		||||
random.$(OBJEXT): {$(VPATH)}siphash.h
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										328
									
								
								ext/-test-/random/depend
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								ext/-test-/random/depend
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,328 @@
 | 
			
		|||
# AUTOGENERATED DEPENDENCIES START
 | 
			
		||||
init.o: $(RUBY_EXTCONF_H)
 | 
			
		||||
init.o: $(arch_hdrdir)/ruby/config.h
 | 
			
		||||
init.o: $(hdrdir)/ruby.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/assert.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/assume.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/attributes.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/bool.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/inttypes.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/limits.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/long_long.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/r_cast.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/rmodule.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/stdalign.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/backward/2/stdarg.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/defines.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/intern.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/anyargs.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/assume.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/artificial.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/cold.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/const.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/error.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/format.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/noalias.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/noinline.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/pure.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/restrict.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/warning.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/attr/weakref.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/cast.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/compiler_since.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/config.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/constant_p.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rarray.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rbasic.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rbignum.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rclass.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rdata.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rfile.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rhash.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/robject.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rregexp.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rstring.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rstruct.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/ctype.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/dllexport.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/dosish.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/error.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/eval.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/event.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/fl_type.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/gc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/glob.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/globals.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/attribute.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/builtin.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/extension.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/feature.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/has/warning.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/array.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/bignum.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/class.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/compar.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/complex.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/cont.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/dir.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/enum.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/error.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/eval.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/file.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/gc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/hash.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/io.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/load.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/marshal.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/numeric.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/object.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/parse.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/proc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/process.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/random.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/range.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/rational.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/re.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/ruby.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/select.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/signal.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/string.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/struct.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/thread.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/time.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/variable.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/intern/vm.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/interpreter.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/iterator.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/memory.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/method.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/module.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/newobj.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/rgengc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/scan_args.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/special_consts.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/static_assert.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/stdalign.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/stdbool.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/symbol.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/token_paste.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/value.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/value_type.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/variable.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/warning_push.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/internal/xmalloc.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/missing.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/ruby.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/st.h
 | 
			
		||||
init.o: $(hdrdir)/ruby/subst.h
 | 
			
		||||
init.o: init.c
 | 
			
		||||
loop.o: $(RUBY_EXTCONF_H)
 | 
			
		||||
loop.o: $(arch_hdrdir)/ruby/config.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/assert.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/assume.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/attributes.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/bool.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/inttypes.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/limits.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/long_long.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/r_cast.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/rmodule.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/stdalign.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/backward/2/stdarg.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/defines.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/intern.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/anyargs.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/char.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/double.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/int.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/long.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/short.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/assume.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/artificial.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/cold.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/const.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/constexpr.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/deprecated.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/error.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/forceinline.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/format.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/noalias.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/noexcept.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/noinline.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/nonnull.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/noreturn.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/pure.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/restrict.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/warning.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/attr/weakref.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/cast.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/compiler_since.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/config.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/constant_p.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rarray.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rbasic.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rbignum.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rclass.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rdata.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rfile.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rhash.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/robject.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rregexp.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rstring.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rstruct.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/ctype.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/dllexport.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/dosish.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/error.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/eval.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/event.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/fl_type.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/gc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/glob.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/globals.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/attribute.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/builtin.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/c_attribute.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/extension.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/feature.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/has/warning.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/array.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/bignum.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/class.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/compar.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/complex.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/cont.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/dir.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/enum.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/enumerator.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/error.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/eval.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/file.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/gc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/hash.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/io.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/load.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/marshal.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/numeric.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/object.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/parse.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/proc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/process.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/random.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/range.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/rational.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/re.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/ruby.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/select.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/signal.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/sprintf.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/string.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/struct.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/thread.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/time.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/variable.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/intern/vm.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/interpreter.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/iterator.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/memory.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/method.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/module.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/newobj.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/rgengc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/scan_args.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/special_consts.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/static_assert.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/stdalign.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/stdbool.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/symbol.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/token_paste.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/value.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/value_type.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/variable.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/warning_push.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/internal/xmalloc.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/missing.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/random.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/ruby.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/st.h
 | 
			
		||||
loop.o: $(hdrdir)/ruby/subst.h
 | 
			
		||||
loop.o: loop.c
 | 
			
		||||
# AUTOGENERATED DEPENDENCIES END
 | 
			
		||||
							
								
								
									
										3
									
								
								ext/-test-/random/extconf.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ext/-test-/random/extconf.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
# frozen_string_literal: false
 | 
			
		||||
require_relative "../auto_ext.rb"
 | 
			
		||||
auto_ext(inc: true)
 | 
			
		||||
							
								
								
									
										11
									
								
								ext/-test-/random/init.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ext/-test-/random/init.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
#include "ruby.h"
 | 
			
		||||
 | 
			
		||||
#define init(n) {void Init_random_##n(VALUE mod, VALUE base); Init_random_##n(mod, base);}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Init_random(void)
 | 
			
		||||
{
 | 
			
		||||
    VALUE base = rb_const_get(rb_cRandom, rb_intern_const("Base"));
 | 
			
		||||
    VALUE mod = rb_define_module_under(rb_define_module("Bug"), "Random");
 | 
			
		||||
    TEST_INIT_FUNCS(init);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								ext/-test-/random/loop.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								ext/-test-/random/loop.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
#include "ruby/random.h"
 | 
			
		||||
 | 
			
		||||
static const uint32_t max_seeds = 1024;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    rb_random_t base;
 | 
			
		||||
    uint32_t num, idx, *buf;
 | 
			
		||||
} rand_loop_t;
 | 
			
		||||
 | 
			
		||||
RB_RANDOM_INTERFACE_DECLARE(loop)
 | 
			
		||||
static const rb_random_interface_t random_loop_if = {
 | 
			
		||||
    32,
 | 
			
		||||
    RB_RANDOM_INTERFACE_DEFINE(loop)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
random_loop_memsize(const void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    const rand_loop_t *r = ptr;
 | 
			
		||||
    return sizeof(*r) + r->num * sizeof(r->buf[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_random_data_type_t random_loop_type = {
 | 
			
		||||
    "random/loop",
 | 
			
		||||
    {
 | 
			
		||||
        rb_random_mark,
 | 
			
		||||
        RUBY_TYPED_DEFAULT_FREE,
 | 
			
		||||
        random_loop_memsize,
 | 
			
		||||
    },
 | 
			
		||||
    RB_RANDOM_PARENT,
 | 
			
		||||
    (void *)&random_loop_if,
 | 
			
		||||
    RUBY_TYPED_FREE_IMMEDIATELY
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
loop_alloc(VALUE klass)
 | 
			
		||||
{
 | 
			
		||||
    rand_loop_t *rnd;
 | 
			
		||||
    VALUE obj = TypedData_Make_Struct(klass, rand_loop_t, &random_loop_type, rnd);
 | 
			
		||||
    rnd->base.seed = INT2FIX(0);
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
loop_init(rb_random_t *rnd, const uint32_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    rand_loop_t *r = (rand_loop_t *)rnd;
 | 
			
		||||
 | 
			
		||||
    if (len > max_seeds) len = max_seeds;
 | 
			
		||||
 | 
			
		||||
    REALLOC_N(r->buf, uint32_t, len);
 | 
			
		||||
    MEMCPY(r->buf, buf, uint32_t, (r->num = (uint32_t)len));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
loop_get_bytes(rb_random_t *rnd, void *p, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *buf = p;
 | 
			
		||||
    while (n > 0) {
 | 
			
		||||
        uint32_t x = loop_get_int32(rnd);
 | 
			
		||||
        switch (n % 4) {
 | 
			
		||||
          case 0:
 | 
			
		||||
            *buf++ = (uint8_t)x;
 | 
			
		||||
            n--;
 | 
			
		||||
          case 3:
 | 
			
		||||
            *buf++ = (uint8_t)x;
 | 
			
		||||
            n--;
 | 
			
		||||
          case 2:
 | 
			
		||||
            *buf++ = (uint8_t)x;
 | 
			
		||||
            n--;
 | 
			
		||||
          case 1:
 | 
			
		||||
            *buf++ = (uint8_t)x;
 | 
			
		||||
            n--;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t
 | 
			
		||||
loop_get_int32(rb_random_t *rnd)
 | 
			
		||||
{
 | 
			
		||||
    rand_loop_t *r = (rand_loop_t *)rnd;
 | 
			
		||||
    if (r->idx < r->num) {
 | 
			
		||||
        uint32_t x = r->buf[r->idx++];
 | 
			
		||||
        if (r->idx >= r->num) r->idx = 0;
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
    else if (r->num) {
 | 
			
		||||
        return r->buf[r->idx = 0];
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Init_random_loop(VALUE mod, VALUE base)
 | 
			
		||||
{
 | 
			
		||||
    VALUE c = rb_define_class_under(mod, "Loop", base);
 | 
			
		||||
    rb_define_alloc_func(c, loop_alloc);
 | 
			
		||||
    RB_RANDOM_DATA_INIT_PARENT(random_loop_type);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								include/ruby/random.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								include/ruby/random.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
#ifndef RUBY_RANDOM_H
 | 
			
		||||
#define RUBY_RANDOM_H 1
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * @date       Sat May  7 11:51:14 JST 2016
 | 
			
		||||
 * @copyright  2007-2020 Yukihiro Matsumoto
 | 
			
		||||
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 | 
			
		||||
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 | 
			
		||||
 *             modify this file, provided that  the conditions mentioned in the
 | 
			
		||||
 *             file COPYING are met.  Consult the file for details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ruby/ruby.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
extern "C" {
 | 
			
		||||
#if 0
 | 
			
		||||
} /* satisfy cc-mode */
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
RUBY_SYMBOL_EXPORT_BEGIN
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    VALUE seed;
 | 
			
		||||
} rb_random_t;
 | 
			
		||||
 | 
			
		||||
typedef void rb_random_init_func(rb_random_t *, const uint32_t *, size_t);
 | 
			
		||||
typedef unsigned int rb_random_get_int32_func(rb_random_t *);
 | 
			
		||||
typedef void rb_random_get_bytes_func(rb_random_t *, void *, size_t);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    size_t default_seed_bits;
 | 
			
		||||
    rb_random_init_func *init;
 | 
			
		||||
    rb_random_get_int32_func *get_int32;
 | 
			
		||||
    rb_random_get_bytes_func *get_bytes;
 | 
			
		||||
} rb_random_interface_t;
 | 
			
		||||
 | 
			
		||||
#define rb_rand_if(obj) \
 | 
			
		||||
    ((const rb_random_interface_t *)RTYPEDDATA_TYPE(obj)->data)
 | 
			
		||||
 | 
			
		||||
#define RB_RANDOM_INTERFACE_DECLARE(prefix) \
 | 
			
		||||
    static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
 | 
			
		||||
    static unsigned int prefix##_get_int32(rb_random_t *); \
 | 
			
		||||
    static void prefix##_get_bytes(rb_random_t *, void *, size_t); \
 | 
			
		||||
    /* end */
 | 
			
		||||
 | 
			
		||||
#define RB_RANDOM_INTERFACE_DEFINE(prefix) \
 | 
			
		||||
    prefix##_init, \
 | 
			
		||||
    prefix##_get_int32, \
 | 
			
		||||
    prefix##_get_bytes, \
 | 
			
		||||
    /* end */
 | 
			
		||||
 | 
			
		||||
#if defined _WIN32 && !defined __CYGWIN__
 | 
			
		||||
typedef rb_data_type_t rb_random_data_type_t;
 | 
			
		||||
# define RB_RANDOM_PARENT 0
 | 
			
		||||
# define RB_RANDOM_DATA_INIT_PARENT(random_data) \
 | 
			
		||||
    (random_data.parent = &rb_random_data_type)
 | 
			
		||||
#else
 | 
			
		||||
typedef const rb_data_type_t rb_random_data_type_t;
 | 
			
		||||
# define RB_RANDOM_PARENT &rb_random_data_type
 | 
			
		||||
# define RB_RANDOM_DATA_INIT_PARENT(random_data) ((void)0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void rb_random_mark(void *ptr);
 | 
			
		||||
double rb_int_pair_to_real_exclusive(uint32_t a, uint32_t b);
 | 
			
		||||
double rb_int_pair_to_real_inclusive(uint32_t a, uint32_t b);
 | 
			
		||||
void rb_rand_bytes_int32(rb_random_get_int32_func *, rb_random_t *, void *, size_t);
 | 
			
		||||
RUBY_EXTERN const rb_data_type_t rb_random_data_type;
 | 
			
		||||
 | 
			
		||||
RUBY_SYMBOL_EXPORT_END
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
#if 0
 | 
			
		||||
{ /* satisfy cc-mode */
 | 
			
		||||
#endif
 | 
			
		||||
}  /* extern "C" { */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* RUBY_RANDOM_H */
 | 
			
		||||
							
								
								
									
										352
									
								
								random.c
									
										
									
									
									
								
							
							
						
						
									
										352
									
								
								random.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -62,6 +62,7 @@
 | 
			
		|||
#include "internal/random.h"
 | 
			
		||||
#include "internal/sanitizers.h"
 | 
			
		||||
#include "ruby_atomic.h"
 | 
			
		||||
#include "ruby/random.h"
 | 
			
		||||
 | 
			
		||||
typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,44 +114,57 @@ genrand_real2(struct MT *mt)
 | 
			
		|||
#undef M
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    VALUE seed;
 | 
			
		||||
    rb_random_t base;
 | 
			
		||||
    struct MT mt;
 | 
			
		||||
} rb_random_t;
 | 
			
		||||
} rb_random_mt_t;
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_SEED_CNT 4
 | 
			
		||||
 | 
			
		||||
static rb_random_t default_rand;
 | 
			
		||||
static rb_random_mt_t default_rand;
 | 
			
		||||
 | 
			
		||||
static VALUE rand_init(struct MT *mt, VALUE vseed);
 | 
			
		||||
static VALUE rand_init(const rb_random_interface_t *, rb_random_t *, VALUE);
 | 
			
		||||
static VALUE random_seed(VALUE);
 | 
			
		||||
static void fill_random_seed(uint32_t *seed, size_t cnt);
 | 
			
		||||
static VALUE make_seed_value(uint32_t *ptr, size_t len);
 | 
			
		||||
 | 
			
		||||
static rb_random_t *
 | 
			
		||||
rand_start(rb_random_t *r)
 | 
			
		||||
RB_RANDOM_INTERFACE_DECLARE(rand_mt)
 | 
			
		||||
static const rb_random_interface_t random_mt_if = {
 | 
			
		||||
    DEFAULT_SEED_CNT * 32,
 | 
			
		||||
    RB_RANDOM_INTERFACE_DEFINE(rand_mt)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static rb_random_mt_t *
 | 
			
		||||
rand_mt_start(rb_random_mt_t *r)
 | 
			
		||||
{
 | 
			
		||||
    struct MT *mt = &r->mt;
 | 
			
		||||
    if (!genrand_initialized(mt)) {
 | 
			
		||||
        r->seed = rand_init(mt, random_seed(Qundef));
 | 
			
		||||
    if (!genrand_initialized(&r->mt)) {
 | 
			
		||||
	r->base.seed = rand_init(&random_mt_if, &r->base, random_seed(Qundef));
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct MT *
 | 
			
		||||
static rb_random_t *
 | 
			
		||||
rand_start(rb_random_mt_t *r)
 | 
			
		||||
{
 | 
			
		||||
    return &rand_mt_start(r)->base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_random_mt_t *
 | 
			
		||||
default_mt(void)
 | 
			
		||||
{
 | 
			
		||||
    return &rand_start(&default_rand)->mt;
 | 
			
		||||
    return rand_mt_start(&default_rand);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int
 | 
			
		||||
rb_genrand_int32(void)
 | 
			
		||||
{
 | 
			
		||||
    struct MT *mt = default_mt();
 | 
			
		||||
    struct MT *mt = &default_mt()->mt;
 | 
			
		||||
    return genrand_int32(mt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double
 | 
			
		||||
rb_genrand_real(void)
 | 
			
		||||
{
 | 
			
		||||
    struct MT *mt = default_mt();
 | 
			
		||||
    struct MT *mt = &default_mt()->mt;
 | 
			
		||||
    return genrand_real(mt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -185,18 +199,15 @@ static ID id_rand, id_bytes;
 | 
			
		|||
NORETURN(static void domain_error(void));
 | 
			
		||||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static void
 | 
			
		||||
#define random_mark rb_random_mark
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
random_mark(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    rb_gc_mark(((rb_random_t *)ptr)->seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
random_free(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    if (ptr != &default_rand)
 | 
			
		||||
	xfree(ptr);
 | 
			
		||||
}
 | 
			
		||||
#define random_free RUBY_TYPED_DEFAULT_FREE
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
random_memsize(const void *ptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -204,8 +215,8 @@ random_memsize(const void *ptr)
 | 
			
		|||
    return sizeof(rb_random_t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const rb_data_type_t random_mt_type = {
 | 
			
		||||
    "random/MT",
 | 
			
		||||
const rb_data_type_t rb_random_data_type = {
 | 
			
		||||
    "random",
 | 
			
		||||
    {
 | 
			
		||||
	random_mark,
 | 
			
		||||
	random_free,
 | 
			
		||||
| 
						 | 
				
			
			@ -214,12 +225,49 @@ static const rb_data_type_t random_mt_type = {
 | 
			
		|||
    0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define random_mt_mark rb_random_mark
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
random_mt_free(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    if (ptr != &default_rand)
 | 
			
		||||
	xfree(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
random_mt_memsize(const void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    return sizeof(rb_random_mt_t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const rb_data_type_t random_mt_type = {
 | 
			
		||||
    "random/MT",
 | 
			
		||||
    {
 | 
			
		||||
	random_mt_mark,
 | 
			
		||||
	random_mt_free,
 | 
			
		||||
	random_mt_memsize,
 | 
			
		||||
    },
 | 
			
		||||
    &rb_random_data_type,
 | 
			
		||||
    (void *)&random_mt_if,
 | 
			
		||||
    RUBY_TYPED_FREE_IMMEDIATELY
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static rb_random_t *
 | 
			
		||||
get_rnd(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *ptr;
 | 
			
		||||
    TypedData_Get_Struct(obj, rb_random_t, &random_mt_type, ptr);
 | 
			
		||||
    return rand_start(ptr);
 | 
			
		||||
    TypedData_Get_Struct(obj, rb_random_t, &rb_random_data_type, ptr);
 | 
			
		||||
    if (RTYPEDDATA_TYPE(obj) == &random_mt_type)
 | 
			
		||||
        return rand_start((rb_random_mt_t *)ptr);
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_random_mt_t *
 | 
			
		||||
get_rnd_mt(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_mt_t *ptr;
 | 
			
		||||
    TypedData_Get_Struct(obj, rb_random_mt_t, &random_mt_type, ptr);
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_random_t *
 | 
			
		||||
| 
						 | 
				
			
			@ -228,30 +276,61 @@ try_get_rnd(VALUE obj)
 | 
			
		|||
    if (obj == rb_cRandom) {
 | 
			
		||||
	return rand_start(&default_rand);
 | 
			
		||||
    }
 | 
			
		||||
    if (!rb_typeddata_is_kind_of(obj, &random_mt_type)) return NULL;
 | 
			
		||||
    return rand_start(DATA_PTR(obj));
 | 
			
		||||
    if (!rb_typeddata_is_kind_of(obj, &rb_random_data_type)) return NULL;
 | 
			
		||||
    if (RTYPEDDATA_TYPE(obj) == &random_mt_type)
 | 
			
		||||
        return rand_start(DATA_PTR(obj));
 | 
			
		||||
    rb_random_t *rnd = DATA_PTR(obj);
 | 
			
		||||
    if (!rnd) {
 | 
			
		||||
        rb_raise(rb_eArgError, "uninitialized random: %s",
 | 
			
		||||
                 RTYPEDDATA_TYPE(obj)->wrap_struct_name);
 | 
			
		||||
    }
 | 
			
		||||
    return rnd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const rb_random_interface_t *
 | 
			
		||||
try_rand_if(VALUE obj, rb_random_t *rnd)
 | 
			
		||||
{
 | 
			
		||||
    if (rnd == &default_rand.base) {
 | 
			
		||||
	return &random_mt_if;
 | 
			
		||||
    }
 | 
			
		||||
    return rb_rand_if(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_alloc(VALUE klass)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd;
 | 
			
		||||
    VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_mt_type, rnd);
 | 
			
		||||
    rnd->seed = INT2FIX(0);
 | 
			
		||||
    rb_random_mt_t *rnd;
 | 
			
		||||
    VALUE obj = TypedData_Make_Struct(klass, rb_random_mt_t, &random_mt_type, rnd);
 | 
			
		||||
    rnd->base.seed = INT2FIX(0);
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rand_init(struct MT *mt, VALUE seed)
 | 
			
		||||
rand_init_default(const rb_random_interface_t *rng, rb_random_t *rnd)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
 | 
			
		||||
    VALUE seed, buf0 = 0;
 | 
			
		||||
    size_t len = roomof(rng->default_seed_bits, 32);
 | 
			
		||||
    uint32_t *buf = ALLOCV_N(uint32_t, buf0, len+1);
 | 
			
		||||
 | 
			
		||||
    fill_random_seed(buf, len);
 | 
			
		||||
    rng->init(rnd, buf, len);
 | 
			
		||||
    seed = make_seed_value(buf, len);
 | 
			
		||||
    explicit_bzero(buf, len * sizeof(*buf));
 | 
			
		||||
    ALLOCV_END(buf0);
 | 
			
		||||
    return seed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rand_init(const rb_random_interface_t *rng, rb_random_t *rnd, VALUE seed)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t *buf;
 | 
			
		||||
    VALUE buf0 = 0;
 | 
			
		||||
    size_t len;
 | 
			
		||||
    int sign;
 | 
			
		||||
 | 
			
		||||
    len = rb_absint_numwords(seed, 32, NULL);
 | 
			
		||||
    if (len > numberof(buf0))
 | 
			
		||||
        buf = ALLOC_N(uint32_t, len);
 | 
			
		||||
    buf = ALLOCV_N(uint32_t, buf0, len);
 | 
			
		||||
    sign = rb_integer_pack(seed, buf, len, sizeof(uint32_t), 0,
 | 
			
		||||
        INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
 | 
			
		||||
    if (sign < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -260,16 +339,13 @@ rand_init(struct MT *mt, VALUE seed)
 | 
			
		|||
        buf[0] = 0;
 | 
			
		||||
        len = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (len <= 1) {
 | 
			
		||||
        init_genrand(mt, buf[0]);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
    if (len > 1) {
 | 
			
		||||
        if (sign != 2 && buf[len-1] == 1) /* remove leading-zero-guard */
 | 
			
		||||
            len--;
 | 
			
		||||
        init_by_array(mt, buf, (int)len);
 | 
			
		||||
    }
 | 
			
		||||
    rng->init(rnd, buf, len);
 | 
			
		||||
    explicit_bzero(buf, len * sizeof(*buf));
 | 
			
		||||
    if (buf != buf0) xfree(buf);
 | 
			
		||||
    ALLOCV_END(buf0);
 | 
			
		||||
    return seed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,19 +361,21 @@ rand_init(struct MT *mt, VALUE seed)
 | 
			
		|||
static VALUE
 | 
			
		||||
random_init(int argc, VALUE *argv, VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    VALUE vseed;
 | 
			
		||||
    rb_random_t *rnd = get_rnd(obj);
 | 
			
		||||
    rb_random_t *rnd = try_get_rnd(obj);
 | 
			
		||||
    const rb_random_interface_t *rng = rb_rand_if(obj);
 | 
			
		||||
 | 
			
		||||
    if (rb_check_arity(argc, 0, 1) == 0) {
 | 
			
		||||
	rb_check_frozen(obj);
 | 
			
		||||
        vseed = random_seed(obj);
 | 
			
		||||
    if (!rng) {
 | 
			
		||||
        rb_raise(rb_eTypeError, "undefined random interface: %s",
 | 
			
		||||
                 RTYPEDDATA_TYPE(obj)->wrap_struct_name);
 | 
			
		||||
    }
 | 
			
		||||
    argc = rb_check_arity(argc, 0, 1);
 | 
			
		||||
    rb_check_frozen(obj);
 | 
			
		||||
    if (argc == 0) {
 | 
			
		||||
        rnd->seed = rand_init_default(rng, rnd);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	vseed = argv[0];
 | 
			
		||||
	rb_check_copyable(obj, vseed);
 | 
			
		||||
	vseed = rb_to_int(vseed);
 | 
			
		||||
        rnd->seed = rand_init(rng, rnd, rb_to_int(argv[0]));
 | 
			
		||||
    }
 | 
			
		||||
    rnd->seed = rand_init(&rnd->mt, vseed);
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -588,15 +666,15 @@ random_get_seed(VALUE obj)
 | 
			
		|||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_copy(VALUE obj, VALUE orig)
 | 
			
		||||
rand_mt_copy(VALUE obj, VALUE orig)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd1, *rnd2;
 | 
			
		||||
    rb_random_mt_t *rnd1, *rnd2;
 | 
			
		||||
    struct MT *mt;
 | 
			
		||||
 | 
			
		||||
    if (!OBJ_INIT_COPY(obj, orig)) return obj;
 | 
			
		||||
 | 
			
		||||
    rnd1 = get_rnd(obj);
 | 
			
		||||
    rnd2 = get_rnd(orig);
 | 
			
		||||
    rnd1 = get_rnd_mt(obj);
 | 
			
		||||
    rnd2 = get_rnd_mt(orig);
 | 
			
		||||
    mt = &rnd1->mt;
 | 
			
		||||
 | 
			
		||||
    *rnd1 = *rnd2;
 | 
			
		||||
| 
						 | 
				
			
			@ -614,9 +692,9 @@ mt_state(const struct MT *mt)
 | 
			
		|||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_state(VALUE obj)
 | 
			
		||||
rand_mt_state(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd = get_rnd(obj);
 | 
			
		||||
    rb_random_mt_t *rnd = get_rnd_mt(obj);
 | 
			
		||||
    return mt_state(&rnd->mt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -629,9 +707,9 @@ random_s_state(VALUE klass)
 | 
			
		|||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_left(VALUE obj)
 | 
			
		||||
rand_mt_left(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd = get_rnd(obj);
 | 
			
		||||
    rb_random_mt_t *rnd = get_rnd_mt(obj);
 | 
			
		||||
    return INT2FIX(rnd->mt.left);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -644,23 +722,23 @@ random_s_left(VALUE klass)
 | 
			
		|||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_dump(VALUE obj)
 | 
			
		||||
rand_mt_dump(VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd = get_rnd(obj);
 | 
			
		||||
    rb_random_mt_t *rnd = rb_check_typeddata(obj, &random_mt_type);
 | 
			
		||||
    VALUE dump = rb_ary_new2(3);
 | 
			
		||||
 | 
			
		||||
    rb_ary_push(dump, mt_state(&rnd->mt));
 | 
			
		||||
    rb_ary_push(dump, INT2FIX(rnd->mt.left));
 | 
			
		||||
    rb_ary_push(dump, rnd->seed);
 | 
			
		||||
    rb_ary_push(dump, rnd->base.seed);
 | 
			
		||||
 | 
			
		||||
    return dump;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* :nodoc: */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_load(VALUE obj, VALUE dump)
 | 
			
		||||
rand_mt_load(VALUE obj, VALUE dump)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd = get_rnd(obj);
 | 
			
		||||
    rb_random_mt_t *rnd = rb_check_typeddata(obj, &random_mt_type);
 | 
			
		||||
    struct MT *mt = &rnd->mt;
 | 
			
		||||
    VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
 | 
			
		||||
    unsigned long x;
 | 
			
		||||
| 
						 | 
				
			
			@ -687,11 +765,36 @@ random_load(VALUE obj, VALUE dump)
 | 
			
		|||
    }
 | 
			
		||||
    mt->left = (unsigned int)x;
 | 
			
		||||
    mt->next = mt->state + numberof(mt->state) - x + 1;
 | 
			
		||||
    rnd->seed = rb_to_int(seed);
 | 
			
		||||
    rnd->base.seed = rb_to_int(seed);
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rand_mt_init(rb_random_t *rnd, const uint32_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    struct MT *mt = &((rb_random_mt_t *)rnd)->mt;
 | 
			
		||||
    if (len <= 1) {
 | 
			
		||||
        init_genrand(mt, buf[0]);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        init_by_array(mt, buf, (int)len);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
rand_mt_get_int32(rb_random_t *rnd)
 | 
			
		||||
{
 | 
			
		||||
    struct MT *mt = &((rb_random_mt_t *)rnd)->mt;
 | 
			
		||||
    return genrand_int32(mt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rand_mt_get_bytes(rb_random_t *rnd, void *ptr, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    rb_rand_bytes_int32(rand_mt_get_int32, rnd, ptr, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *   srand(number = Random.new_seed) -> old_seed
 | 
			
		||||
| 
						 | 
				
			
			@ -719,7 +822,7 @@ static VALUE
 | 
			
		|||
rb_f_srand(int argc, VALUE *argv, VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    VALUE seed, old;
 | 
			
		||||
    rb_random_t *r = &default_rand;
 | 
			
		||||
    rb_random_mt_t *r = &default_rand;
 | 
			
		||||
 | 
			
		||||
    if (rb_check_arity(argc, 0, 1) == 0) {
 | 
			
		||||
        seed = random_seed(obj);
 | 
			
		||||
| 
						 | 
				
			
			@ -727,8 +830,9 @@ rb_f_srand(int argc, VALUE *argv, VALUE obj)
 | 
			
		|||
    else {
 | 
			
		||||
	seed = rb_to_int(argv[0]);
 | 
			
		||||
    }
 | 
			
		||||
    old = r->seed;
 | 
			
		||||
    r->seed = rand_init(&r->mt, seed);
 | 
			
		||||
    old = r->base.seed;
 | 
			
		||||
    rand_init(&random_mt_if, &r->base, seed);
 | 
			
		||||
    r->base.seed = seed;
 | 
			
		||||
 | 
			
		||||
    return old;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -748,7 +852,7 @@ make_mask(unsigned long x)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long
 | 
			
		||||
limited_rand(struct MT *mt, unsigned long limit)
 | 
			
		||||
limited_rand(const rb_random_interface_t *rng, rb_random_t *rnd, unsigned long limit)
 | 
			
		||||
{
 | 
			
		||||
    /* mt must be initialized */
 | 
			
		||||
    unsigned long val, mask;
 | 
			
		||||
| 
						 | 
				
			
			@ -763,7 +867,7 @@ limited_rand(struct MT *mt, unsigned long limit)
 | 
			
		|||
        val = 0;
 | 
			
		||||
        for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
 | 
			
		||||
            if ((mask >> (i * 32)) & 0xffffffff) {
 | 
			
		||||
                val |= (unsigned long)genrand_int32(mt) << (i * 32);
 | 
			
		||||
                val |= (unsigned long)rng->get_int32(rnd) << (i * 32);
 | 
			
		||||
                val &= mask;
 | 
			
		||||
                if (limit < val)
 | 
			
		||||
                    goto retry;
 | 
			
		||||
| 
						 | 
				
			
			@ -774,13 +878,13 @@ limited_rand(struct MT *mt, unsigned long limit)
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        val = genrand_int32(mt) & mask;
 | 
			
		||||
        val = rng->get_int32(rnd) & mask;
 | 
			
		||||
    } while (limit < val);
 | 
			
		||||
    return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
limited_big_rand(struct MT *mt, VALUE limit)
 | 
			
		||||
limited_big_rand(const rb_random_interface_t *rng, rb_random_t *rnd, VALUE limit)
 | 
			
		||||
{
 | 
			
		||||
    /* mt must be initialized */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -804,22 +908,19 @@ limited_big_rand(struct MT *mt, VALUE limit)
 | 
			
		|||
    mask = 0;
 | 
			
		||||
    boundary = 1;
 | 
			
		||||
    for (i = len-1; 0 <= i; i--) {
 | 
			
		||||
	uint32_t rnd;
 | 
			
		||||
        uint32_t r = 0;
 | 
			
		||||
        uint32_t lim = lim_array[i];
 | 
			
		||||
        mask = mask ? 0xffffffff : (uint32_t)make_mask(lim);
 | 
			
		||||
        if (mask) {
 | 
			
		||||
            rnd = genrand_int32(mt) & mask;
 | 
			
		||||
            r = rng->get_int32(rnd) & mask;
 | 
			
		||||
            if (boundary) {
 | 
			
		||||
                if (lim < rnd)
 | 
			
		||||
                if (lim < r)
 | 
			
		||||
                    goto retry;
 | 
			
		||||
                if (rnd < lim)
 | 
			
		||||
                if (r < lim)
 | 
			
		||||
                    boundary = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            rnd = 0;
 | 
			
		||||
        }
 | 
			
		||||
        rnd_array[i] = rnd;
 | 
			
		||||
        rnd_array[i] = r;
 | 
			
		||||
    }
 | 
			
		||||
    val = rb_integer_unpack(rnd_array, len, sizeof(uint32_t), 0,
 | 
			
		||||
        INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
 | 
			
		||||
| 
						 | 
				
			
			@ -837,7 +938,8 @@ limited_big_rand(struct MT *mt, VALUE limit)
 | 
			
		|||
unsigned long
 | 
			
		||||
rb_genrand_ulong_limited(unsigned long limit)
 | 
			
		||||
{
 | 
			
		||||
    return limited_rand(default_mt(), limit);
 | 
			
		||||
    rb_random_mt_t *mt = default_mt();
 | 
			
		||||
    return limited_rand(&random_mt_if, &mt->base, limit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -857,9 +959,9 @@ obj_random_bytes(VALUE obj, void *p, long n)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
random_int32(rb_random_t *rnd)
 | 
			
		||||
random_int32(const rb_random_interface_t *rng, rb_random_t *rnd)
 | 
			
		||||
{
 | 
			
		||||
    return genrand_int32(&rnd->mt);
 | 
			
		||||
    return rng->get_int32(rnd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int
 | 
			
		||||
| 
						 | 
				
			
			@ -871,7 +973,7 @@ rb_random_int32(VALUE obj)
 | 
			
		|||
	obj_random_bytes(obj, &x, sizeof(x));
 | 
			
		||||
	return (unsigned int)x;
 | 
			
		||||
    }
 | 
			
		||||
    return random_int32(rnd);
 | 
			
		||||
    return random_int32(try_rand_if(obj, rnd), rnd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double
 | 
			
		||||
| 
						 | 
				
			
			@ -886,8 +988,9 @@ random_real(VALUE obj, rb_random_t *rnd, int excl)
 | 
			
		|||
	b = x[1];
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	a = random_int32(rnd);
 | 
			
		||||
	b = random_int32(rnd);
 | 
			
		||||
        const rb_random_interface_t *rng = try_rand_if(obj, rnd);
 | 
			
		||||
        a = random_int32(rng, rnd);
 | 
			
		||||
        b = random_int32(rng, rnd);
 | 
			
		||||
    }
 | 
			
		||||
    if (excl) {
 | 
			
		||||
	return int_pair_to_real_exclusive(a, b);
 | 
			
		||||
| 
						 | 
				
			
			@ -912,7 +1015,7 @@ rb_random_real(VALUE obj)
 | 
			
		|||
	}
 | 
			
		||||
	return d;
 | 
			
		||||
    }
 | 
			
		||||
    return genrand_real(&rnd->mt);
 | 
			
		||||
    return random_real(obj, rnd, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -954,7 +1057,7 @@ random_ulong_limited(VALUE obj, rb_random_t *rnd, unsigned long limit)
 | 
			
		|||
	} while (limit < val);
 | 
			
		||||
	return val;
 | 
			
		||||
    }
 | 
			
		||||
    return limited_rand(&rnd->mt, limit);
 | 
			
		||||
    return limited_rand(try_rand_if(obj, rnd), rnd, limit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned long
 | 
			
		||||
| 
						 | 
				
			
			@ -973,7 +1076,7 @@ rb_random_ulong_limited(VALUE obj, unsigned long limit)
 | 
			
		|||
	}
 | 
			
		||||
	return r;
 | 
			
		||||
    }
 | 
			
		||||
    return limited_rand(&rnd->mt, limit);
 | 
			
		||||
    return limited_rand(try_rand_if(obj, rnd), rnd, limit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -1002,10 +1105,20 @@ random_ulong_limited_big(VALUE obj, rb_random_t *rnd, VALUE vmax)
 | 
			
		|||
	ALLOCV_END(vtmp);
 | 
			
		||||
	return v;
 | 
			
		||||
    }
 | 
			
		||||
    return limited_big_rand(&rnd->mt, vmax);
 | 
			
		||||
    return limited_big_rand(try_rand_if(obj, rnd), rnd, vmax);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE genrand_bytes(rb_random_t *rnd, long n);
 | 
			
		||||
static VALUE
 | 
			
		||||
rand_bytes(const rb_random_interface_t *rng, rb_random_t *rnd, long n)
 | 
			
		||||
{
 | 
			
		||||
    VALUE bytes;
 | 
			
		||||
    char *ptr;
 | 
			
		||||
 | 
			
		||||
    bytes = rb_str_new(0, n);
 | 
			
		||||
    ptr = RSTRING_PTR(bytes);
 | 
			
		||||
    rb_rand_bytes_int32(rng->get_int32, rnd, ptr, n);
 | 
			
		||||
    return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq: prng.bytes(size) -> string
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,20 +1131,18 @@ static VALUE genrand_bytes(rb_random_t *rnd, long n);
 | 
			
		|||
static VALUE
 | 
			
		||||
random_bytes(VALUE obj, VALUE len)
 | 
			
		||||
{
 | 
			
		||||
    return genrand_bytes(get_rnd(obj), NUM2LONG(rb_to_int(len)));
 | 
			
		||||
    rb_random_t *rnd = try_get_rnd(obj);
 | 
			
		||||
    return rand_bytes(rb_rand_if(obj), rnd, NUM2LONG(rb_to_int(len)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
genrand_bytes(rb_random_t *rnd, long n)
 | 
			
		||||
void
 | 
			
		||||
rb_rand_bytes_int32(rb_random_get_int32_func *get_int32,
 | 
			
		||||
                    rb_random_t *rnd, void *p, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    VALUE bytes;
 | 
			
		||||
    char *ptr;
 | 
			
		||||
    char *ptr = p;
 | 
			
		||||
    unsigned int r, i;
 | 
			
		||||
 | 
			
		||||
    bytes = rb_str_new(0, n);
 | 
			
		||||
    ptr = RSTRING_PTR(bytes);
 | 
			
		||||
    for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
 | 
			
		||||
	r = genrand_int32(&rnd->mt);
 | 
			
		||||
        r = get_int32(rnd);
 | 
			
		||||
	i = SIZEOF_INT32;
 | 
			
		||||
	do {
 | 
			
		||||
	    *ptr++ = (char)r;
 | 
			
		||||
| 
						 | 
				
			
			@ -1039,13 +1150,12 @@ genrand_bytes(rb_random_t *rnd, long n)
 | 
			
		|||
        } while (--i);
 | 
			
		||||
    }
 | 
			
		||||
    if (n > 0) {
 | 
			
		||||
	r = genrand_int32(&rnd->mt);
 | 
			
		||||
        r = get_int32(rnd);
 | 
			
		||||
	do {
 | 
			
		||||
	    *ptr++ = (char)r;
 | 
			
		||||
	    r >>= CHAR_BIT;
 | 
			
		||||
	} while (--n);
 | 
			
		||||
    }
 | 
			
		||||
    return bytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -1055,7 +1165,7 @@ rb_random_bytes(VALUE obj, long n)
 | 
			
		|||
    if (!rnd) {
 | 
			
		||||
	return obj_random_bytes(obj, NULL, n);
 | 
			
		||||
    }
 | 
			
		||||
    return genrand_bytes(rnd, n);
 | 
			
		||||
    return rand_bytes(try_rand_if(obj, rnd), rnd, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,7 +1178,7 @@ static VALUE
 | 
			
		|||
random_s_bytes(VALUE obj, VALUE len)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *rnd = rand_start(&default_rand);
 | 
			
		||||
    return genrand_bytes(rnd, NUM2LONG(rb_to_int(len)));
 | 
			
		||||
    return rand_bytes(&random_mt_if, rnd, NUM2LONG(rb_to_int(len)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,7 +1378,7 @@ static VALUE rand_random(int argc, VALUE *argv, VALUE obj, rb_random_t *rnd);
 | 
			
		|||
static VALUE
 | 
			
		||||
random_rand(int argc, VALUE *argv, VALUE obj)
 | 
			
		||||
{
 | 
			
		||||
    VALUE v = rand_random(argc, argv, obj, get_rnd(obj));
 | 
			
		||||
    VALUE v = rand_random(argc, argv, obj, try_get_rnd(obj));
 | 
			
		||||
    check_random_number(v, argv);
 | 
			
		||||
    return v;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1347,16 +1457,16 @@ rand_random_number(int argc, VALUE *argv, VALUE obj)
 | 
			
		|||
 *   prng1 == prng2 # => true
 | 
			
		||||
 */
 | 
			
		||||
static VALUE
 | 
			
		||||
random_equal(VALUE self, VALUE other)
 | 
			
		||||
rand_mt_equal(VALUE self, VALUE other)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *r1, *r2;
 | 
			
		||||
    rb_random_mt_t *r1, *r2;
 | 
			
		||||
    if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
 | 
			
		||||
    r1 = get_rnd(self);
 | 
			
		||||
    r2 = get_rnd(other);
 | 
			
		||||
    r1 = get_rnd_mt(self);
 | 
			
		||||
    r2 = get_rnd_mt(other);
 | 
			
		||||
    if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
 | 
			
		||||
    if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
 | 
			
		||||
    if (r1->mt.left != r2->mt.left) return Qfalse;
 | 
			
		||||
    return rb_equal(r1->seed, r2->seed);
 | 
			
		||||
    return rb_equal(r1->base.seed, r2->base.seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1397,15 +1507,15 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
 | 
			
		|||
    rb_random_t *rnd = rand_start(&default_rand);
 | 
			
		||||
 | 
			
		||||
    if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
 | 
			
		||||
	VALUE v = rand_range(Qnil, rnd, vmax);
 | 
			
		||||
        VALUE v = rand_range(obj, rnd, vmax);
 | 
			
		||||
	if (v != Qfalse) return v;
 | 
			
		||||
	vmax = rb_to_int(vmax);
 | 
			
		||||
	if (vmax != INT2FIX(0)) {
 | 
			
		||||
	    v = rand_int(Qnil, rnd, vmax, 0);
 | 
			
		||||
            v = rand_int(obj, rnd, vmax, 0);
 | 
			
		||||
	    if (!NIL_P(v)) return v;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    return DBL2NUM(genrand_real(&rnd->mt));
 | 
			
		||||
    return DBL2NUM(random_real(obj, rnd, TRUE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1506,14 +1616,14 @@ Init_RandomSeedCore(void)
 | 
			
		|||
static VALUE
 | 
			
		||||
Init_Random_default(VALUE klass)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *r = &default_rand;
 | 
			
		||||
    rb_random_mt_t *r = &default_rand;
 | 
			
		||||
    struct MT *mt = &r->mt;
 | 
			
		||||
    VALUE v = TypedData_Wrap_Struct(klass, &random_mt_type, r);
 | 
			
		||||
 | 
			
		||||
    rb_gc_register_mark_object(v);
 | 
			
		||||
    with_random_seed(DEFAULT_SEED_CNT, 1) {
 | 
			
		||||
        init_by_array(mt, seedbuf, DEFAULT_SEED_CNT);
 | 
			
		||||
        r->seed = make_seed_value(seedbuf, DEFAULT_SEED_CNT);
 | 
			
		||||
        r->base.seed = make_seed_value(seedbuf, DEFAULT_SEED_CNT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return v;
 | 
			
		||||
| 
						 | 
				
			
			@ -1522,9 +1632,9 @@ Init_Random_default(VALUE klass)
 | 
			
		|||
void
 | 
			
		||||
rb_reset_random_seed(void)
 | 
			
		||||
{
 | 
			
		||||
    rb_random_t *r = &default_rand;
 | 
			
		||||
    rb_random_mt_t *r = &default_rand;
 | 
			
		||||
    uninit_genrand(&r->mt);
 | 
			
		||||
    r->seed = INT2FIX(0);
 | 
			
		||||
    r->base.seed = INT2FIX(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1569,13 +1679,13 @@ InitVM_Random(void)
 | 
			
		|||
    rb_define_method(base, "initialize", random_init, -1);
 | 
			
		||||
    rb_define_method(base, "rand", random_rand, -1);
 | 
			
		||||
    rb_define_method(base, "bytes", random_bytes, 1);
 | 
			
		||||
    rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
 | 
			
		||||
    rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "state", random_state, 0);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "left", random_left, 0);
 | 
			
		||||
    rb_define_method(rb_cRandom, "==", random_equal, 1);
 | 
			
		||||
    rb_define_method(base, "seed", random_get_seed, 0);
 | 
			
		||||
    rb_define_method(rb_cRandom, "initialize_copy", rand_mt_copy, 1);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "marshal_dump", rand_mt_dump, 0);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "marshal_load", rand_mt_load, 1);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "state", rand_mt_state, 0);
 | 
			
		||||
    rb_define_private_method(rb_cRandom, "left", rand_mt_left, 0);
 | 
			
		||||
    rb_define_method(rb_cRandom, "==", rand_mt_equal, 1);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
	/* Direct access to Ruby's Pseudorandom number generator (PRNG). */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								test/-ext-/test_random.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								test/-ext-/test_random.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
require 'test/unit'
 | 
			
		||||
 | 
			
		||||
module TestRandomExt
 | 
			
		||||
  class TestLoop < Test::Unit::TestCase
 | 
			
		||||
    def setup
 | 
			
		||||
      super
 | 
			
		||||
      assert_nothing_raised(LoadError) {require '-test-/random'}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def test_bytes
 | 
			
		||||
      rnd = Bug::Random::Loop.new(1)
 | 
			
		||||
      assert_equal("\1", rnd.bytes(1))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def test_rand
 | 
			
		||||
      rnd = Bug::Random::Loop.new(1)
 | 
			
		||||
      assert_equal(1, rnd.rand(10))
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue