зеркало из https://github.com/github/ruby.git
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:
Родитель
f4d5273989
Коммит
af5e87ab21
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative "../auto_ext.rb"
|
||||
auto_ext(inc: true)
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
348
random.c
348
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;
|
||||
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) {
|
||||
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);
|
||||
vseed = random_seed(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). */
|
||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче