CVSROOT: /sources/gnash Module name: gnash Changes by: Benjamin Wolsey <bwy> 07/12/10 10:54:34
Modified files: . : ChangeLog libbase : Makefile.am server : movie_root.cpp server/asobj : Math.cpp server/vm : ASHandlers.cpp VM.cpp VM.h action.cpp Removed files: libbase : tu_random.cpp tu_random.h Log message: * server/vm/VM.{h,cpp}: add randomNumberGenerator() to return pointer to a boost pseudo-RNG. * server/vm/ASHandlers.cpp: (ActionRandom) use boost RNG instead of tu_random. * server/asobj/Math.cpp: use boost RND instead of tu_random. * server/action.cpp: remove tu_random include. * libbase/tu_random{cpp,h}: removed. * libbase/Makefile: remove deleted files I have used the mersenne-twister based boost generator mt11213b. This has some memory requirements (about 1.4KB once initialized), but is fast and has a massive cycle length of 2^11213-1 - so probably good enough for anything but security-critical applications: no implementing GPG key pair generation in flash yet. The hellekalek1995 generator is much smaller (1*sizeof(uint32_t)) but by far the slowest of all options (see http://www.boost.org/libs/random/random-generators.html#performance). I'm not particularly fixed on that generator; they are easy to swap in and out through the VM::RNG typedef in VM.h. Some platforms have a non-deterministic source of randomness; using that would be good, but needs a compile-time method of working out whether a random device exists. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5116&r2=1.5117 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/Makefile.am?cvsroot=gnash&r1=1.93&r2=1.94 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/tu_random.cpp?cvsroot=gnash&r1=1.8&r2=0 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/tu_random.h?cvsroot=gnash&r1=1.5&r2=0 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.132&r2=1.133 http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Math.cpp?cvsroot=gnash&r1=1.24&r2=1.25 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.167&r2=1.168 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.cpp?cvsroot=gnash&r1=1.26&r2=1.27 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.h?cvsroot=gnash&r1=1.21&r2=1.22 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/action.cpp?cvsroot=gnash&r1=1.29&r2=1.30 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.5116 retrieving revision 1.5117 diff -u -b -r1.5116 -r1.5117 --- ChangeLog 10 Dec 2007 10:25:55 -0000 1.5116 +++ ChangeLog 10 Dec 2007 10:54:32 -0000 1.5117 @@ -1,3 +1,16 @@ +2007-12-10 Benjamin Wolsey <[EMAIL PROTECTED]> + + * server/vm/VM.{h,cpp}: add randomNumberGenerator() to return + pointer to a boost pseudo-RNG. + * server/vm/ASHandlers.cpp: use boost RNG instead of tu_random + in ActionRandom(). + * server/asobj/Math.cpp: use boost RNG instead of tu_random in + math_random(). + * server/movie_root.cpp: remove calls to tu_random::next_random. + * server/action.cpp: remove tu_random include. + * libbase/tu_random{cpp,h}: removed. + * libbase/Makefile: remove deleted files + 2007-12-10 Sandro Santilli <[EMAIL PROTECTED]> * server/parser/movie_def_impl.cpp (readHeader): 0 FPS Index: libbase/Makefile.am =================================================================== RCS file: /sources/gnash/gnash/libbase/Makefile.am,v retrieving revision 1.93 retrieving revision 1.94 diff -u -b -r1.93 -r1.94 --- libbase/Makefile.am 4 Dec 2007 11:45:23 -0000 1.93 +++ libbase/Makefile.am 10 Dec 2007 10:54:33 -0000 1.94 @@ -92,7 +92,6 @@ string_table.cpp \ tu_file.cpp \ $(SDL_FILE) \ - tu_random.cpp \ tu_timer.cpp \ WallClockTimer.cpp \ utf8.cpp \ @@ -133,7 +132,6 @@ tu_file.h \ tu_math.h \ tu_opengl_includes.h \ - tu_random.h \ tu_timer.h \ WallClockTimer.h \ utf8.h \ Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.132 retrieving revision 1.133 diff -u -b -r1.132 -r1.133 --- server/movie_root.cpp 30 Nov 2007 11:26:05 -0000 1.132 +++ server/movie_root.cpp 10 Dec 2007 10:54:33 -0000 1.133 @@ -27,7 +27,6 @@ #include "movie_instance.h" // for implicit upcast to sprite_instance #include "render.h" #include "VM.h" -#include "tu_random.h" #include "ExecutableCode.h" #include "Stage.h" #include "utility.h" @@ -916,11 +915,6 @@ // NOTE: can throw ActionLimitException executeTimers(); - // random should go continuously that: - // 1. after restart of the player the situation has not repeated - // 2. by different machines the random gave different numbers - tu_random::next_random(); - // Advance all non-unloaded characters in the LiveChars list // in reverse order (last added, first advanced) // NOTE: can throw ActionLimitException Index: server/asobj/Math.cpp =================================================================== RCS file: /sources/gnash/gnash/server/asobj/Math.cpp,v retrieving revision 1.24 retrieving revision 1.25 diff -u -b -r1.24 -r1.25 --- server/asobj/Math.cpp 4 Dec 2007 11:45:31 -0000 1.24 +++ server/asobj/Math.cpp 10 Dec 2007 10:54:33 -0000 1.25 @@ -16,7 +16,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: Math.cpp,v 1.24 2007/12/04 11:45:31 strk Exp $ */ +/* $Id: Math.cpp,v 1.25 2007/12/10 10:54:33 bwy Exp $ */ // // This file implements methods of the ActionScript Math class. @@ -34,7 +34,9 @@ #endif #include <cmath> #include <string> -#include "tu_random.h" +#include <boost/random.hpp> + +#include "VM.h" // get random generator #include "fn_call.h" #include "GMath.h" #include "log.h" @@ -142,13 +144,22 @@ MATH_WRAP_FUNC2_EXP(pow, (pow(arg0, arg1))) // A couple of oddballs. -as_value math_random(const fn_call& /* fn */) +as_value +math_random(const fn_call& /* fn */) { - // Random number between 0 and 1. - return as_value(tu_random::next_random() / double(boost::uint32_t(0x0FFFFFFFF))); + + VM::RNG& rnd = VM::get().randomNumberGenerator(); + + // Produces double ( 0 <= n < 1) + boost::uniform_real<> uni_dist(0, 1); + boost::variate_generator<VM::RNG&, boost::uniform_real<> > uni(rnd, uni_dist); + + return as_value(uni()); + } -as_value math_round(const fn_call& fn) +as_value +math_round(const fn_call& fn) { // round argument to nearest int. 0.5 goes to 1 and -0.5 goes to 0 double result; Index: server/vm/ASHandlers.cpp =================================================================== RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v retrieving revision 1.167 retrieving revision 1.168 diff -u -b -r1.167 -r1.168 --- server/vm/ASHandlers.cpp 4 Dec 2007 11:45:33 -0000 1.167 +++ server/vm/ASHandlers.cpp 10 Dec 2007 10:54:33 -0000 1.168 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: ASHandlers.cpp,v 1.167 2007/12/04 11:45:33 strk Exp $ */ +/* $Id: ASHandlers.cpp,v 1.168 2007/12/10 10:54:33 bwy Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -31,7 +31,6 @@ #include "array.h" #include "swf_function.h" #include "as_function.h" -#include "tu_random.h" #include "fn_call.h" #include "ActionExec.h" #include "sprite_instance.h" @@ -58,6 +57,7 @@ #include <utility> // for std::pair #include <locale.h> #include <boost/scoped_array.hpp> +#include <boost/random.hpp> using namespace std; @@ -1479,13 +1479,28 @@ SWFHandlers::ActionRandom(ActionExec& thread) { // GNASH_REPORT_FUNCTION; + + // Action random(n) should return an integer from 0 up to (not + // including) n. + // It was introduced in SWF4 and deprecated in favour of + // Math.random() in SWF5. + as_environment& env = thread.env; thread.ensureStack(1); // max int max = int(env.top(0).to_number()); // TODO: use to_int ? + if (max < 1) max = 1; - env.top(0).set_int(tu_random::next_random() % max); + + // Get pointer to static random generator in VM + VM::RNG& rnd = VM::get().randomNumberGenerator(); + + // Produces int (0 <= n <= max - 1) + boost::uniform_int<> uni_dist(0, max - 1); + boost::variate_generator<VM::RNG&, boost::uniform_int<> > uni(rnd, uni_dist); + + env.top(0).set_int(uni()); } as_encoding_guess_t Index: server/vm/VM.cpp =================================================================== RCS file: /sources/gnash/gnash/server/vm/VM.cpp,v retrieving revision 1.26 retrieving revision 1.27 diff -u -b -r1.26 -r1.27 --- server/vm/VM.cpp 7 Dec 2007 15:34:37 -0000 1.26 +++ server/vm/VM.cpp 10 Dec 2007 10:54:34 -0000 1.27 @@ -16,7 +16,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -/* $Id: VM.cpp,v 1.26 2007/12/07 15:34:37 strk Exp $ */ +/* $Id: VM.cpp,v 1.27 2007/12/10 10:54:34 bwy Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -34,6 +34,7 @@ #include "VirtualClock.h" // for getTime() #include <memory> +#include <boost/random.hpp> // for random generator namespace { gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance(); @@ -111,6 +112,14 @@ return _swfversion; } +VM::RNG& +VM::randomNumberGenerator() const +{ + + static RNG rnd(tu_timer::get_ticks()); + return rnd; +} + const std::string& VM::getPlayerVersion() const { Index: server/vm/VM.h =================================================================== RCS file: /sources/gnash/gnash/server/vm/VM.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/vm/VM.h 7 Dec 2007 15:34:37 -0000 1.21 +++ server/vm/VM.h 10 Dec 2007 10:54:34 -0000 1.22 @@ -31,6 +31,7 @@ #include <memory> // for auto_ptr #include <locale> #include <boost/cstdint.hpp> // for boost::?int??_t +#include <boost/random.hpp> // Forward declarations namespace gnash { @@ -208,6 +209,32 @@ /// const std::string& getPlayerVersion() const; + // The boost Random Number Generator to use. + // + // http://www.boost.org/libs/random/random-generators.html + // + // TODO: boost/nondet_random.hpp provides access to a random device, + // which can be used in preference to a pseudo-RNG. It is only + // presently available on some platforms. + // http://www.boost.org/libs/random/nondet_random.html + // + // Generators have different limits on the size of the seed. Please + // check if replacing the generator. + // + // The mt11213b provides a pseudo-random number cycle + // of length 2^11213-1 and requires approx 352*sizeof(uint32_t) memory + // once initialized. It is more than adequate for most purposes. + typedef boost::mt11213b RNG; + + // Get a pointer to the random number generator for + // use by Math.random() and random(). + // + // The seed is the system time in milliseconds at the first call + // to a random function. This allows a potentially variable amount + // of time to elapse between starting gnash and initialization of + // the generator, so decreasing predictability. + RNG& randomNumberGenerator() const; + /// Get a pointer to this VM's Root movie (stage) movie_root& getRoot() const; Index: server/vm/action.cpp =================================================================== RCS file: /sources/gnash/gnash/server/vm/action.cpp,v retrieving revision 1.29 retrieving revision 1.30 diff -u -b -r1.29 -r1.30 --- server/vm/action.cpp 2 Dec 2007 14:54:33 -0000 1.29 +++ server/vm/action.cpp 10 Dec 2007 10:54:34 -0000 1.30 @@ -24,7 +24,6 @@ #include "action.h" #include "as_object.h" #include "log.h" -#include "tu_random.h" #include "movie_definition.h" #include "MovieClipLoader.h" #include "as_function.h" Index: libbase/tu_random.cpp =================================================================== RCS file: libbase/tu_random.cpp diff -N libbase/tu_random.cpp --- libbase/tu_random.cpp 4 Dec 2007 11:45:24 -0000 1.8 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,151 +0,0 @@ -// tu_random.cpp -- Thatcher Ulrich 2003 - -// This source code has been donated to the Public Domain. Do -// whatever you want with it. - -// Pseudorandom number generator. - - -#include "tu_random.h" - -#ifdef TEST_TU_RANDOM - #include <cstdio> -#endif - -namespace tu_random -{ - // Global generator. - static generator s_generator; - - boost::uint32_t next_random() - { - return s_generator.next_random(); - } - - void seed_random(boost::uint32_t seed) - { - s_generator.seed_random(seed); - } - - float get_unit_float() - { - return s_generator.get_unit_float(); - } - - - // PRNG code adapted from the complimentary-multiply-with-carry - // code in the article: George Marsaglia, "Seeds for Random Number - // Generators", Communications of the ACM, May 2003, Vol 46 No 5, - // pp90-93. - // - // The article says: - // - // "Any one of the choices for seed table size and multiplier will - // provide a RNG that has passed extensive tests of randomness, - // particularly those in [3], yet is simple and fast -- - // approximately 30 million random 32-bit integers per second on a - // 850MHz PC. The period is a*b^n, where a is the multiplier, n - // the size of the seed table and b=2^32-1. (a is chosen so that - // b is a primitive root of the prime a*b^n + 1.)" - // - // [3] Marsaglia, G., Zaman, A., and Tsang, W. Toward a universal - // random number generator. _Statistics and Probability Letters - // 8_ (1990), 35-39. - -// const boost::uint64_t a = 123471786; // for SEED_COUNT=1024 -// const boost::uint64_t a = 123554632; // for SEED_COUNT=512 -// const boost::uint64_t a = 8001634; // for SEED_COUNT=255 -// const boost::uint64_t a = 8007626; // for SEED_COUNT=128 -// const boost::uint64_t a = 647535442; // for SEED_COUNT=64 -// const boost::uint64_t a = 547416522; // for SEED_COUNT=32 -// const boost::uint64_t a = 487198574; // for SEED_COUNT=16 - const boost::uint64_t a = 716514398; // for SEED_COUNT=8 - - - generator::generator() - : - c(362436), - i(SEED_COUNT - 1) - { - seed_random(987654321); - } - - - void generator::seed_random(boost::uint32_t seed) - { - // Simple pseudo-random to reseed the seeds. - // Suggested by the above article. - boost::uint32_t j = seed; - for (int i = 0; i < SEED_COUNT; i++) - { - j = j ^ (j << 13); - j = j ^ (j >> 17); - j = j ^ (j << 5); - Q[i] = j; - } - } - - - boost::uint32_t generator::next_random() - // Return the next pseudo-random number in the sequence. - { - boost::uint64_t t; - boost::uint32_t x; - - //static boost::uint32_t c = 362436; - //static boost::uint32_t i = SEED_COUNT - 1; - const boost::uint32_t r = 0xFFFFFFFE; - - i = (i+1) & (SEED_COUNT - 1); - t = a * Q[i] + c; - c = (boost::uint32_t) (t >> 32); - x = (boost::uint32_t) (t + c); - if (x < c) - { - x++; - c++; - } - - boost::uint32_t val = r - x; - Q[i] = val; - return val; - } - - - float generator::get_unit_float() - { - boost::uint32_t r = next_random(); - - // 24 bits of precision. - return float(r >> 8) / (16777216.0f - 1.0f); - } - -} // end namespace tu_random - - -#ifdef TEST_TU_RANDOM - -// Compile with e.g.: -// -// gcc -o tu_random_test tu_random.cpp -I.. -g -DTEST_TU_RANDOM -lstdc++ -// -// Generate a test file of random numbers for DIEHARD. -int main() -{ - const int COUNT = 15000000 / 4; // number of 4-byte words; DIEHARD needs ~80M bits - - for (int i = 0; i < COUNT; i++) - { - boost::uint32_t val = tu_random::next_random(); - fwrite(&val, sizeof(val), 1, stdout); - } -} - - -#endif // TEST_TU_RANDOM - - -// Local Variables: -// mode: C++ -// indent-tabs-mode: t -// End: Index: libbase/tu_random.h =================================================================== RCS file: libbase/tu_random.h diff -N libbase/tu_random.h --- libbase/tu_random.h 4 Dec 2007 11:45:24 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,52 +0,0 @@ -// tu_random.h -- Thatcher Ulrich 2003 - -// This source code has been donated to the Public Domain. Do -// whatever you want with it. - -// Pseudorandom number generator. - - -#ifndef TU_RANDOM_H -#define TU_RANDOM_H - - -#include "tu_config.h" // needed ? - -#include <boost/cstdint.hpp> // for boost::uint32_t used in this file - -namespace tu_random -{ - // Global generator. - DSOEXPORT boost::uint32_t next_random(); - void seed_random(boost::uint32_t seed); - DSOEXPORT float get_unit_float(); - - // In case you need independent generators. The global - // generator is just an instance of this. - const int SEED_COUNT = 8; - class generator - { - public: - generator(); - void seed_random(boost::uint32_t seed); // not necessary - boost::uint32_t next_random(); - float get_unit_float(); - - private: - boost::uint32_t Q[SEED_COUNT]; - boost::uint32_t c; - boost::uint32_t i; - }; - -} // end namespace tu_random - - -#endif // TU_RANDOM_H - - -// Local Variables: -// mode: C++ -// c-basic-offset: 8 -// tab-width: 8 -// indent-tabs-mode: t -// End: _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit