diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/flags.rs | 68 | ||||
-rw-r--r-- | cli/ops.rs | 11 | ||||
-rw-r--r-- | cli/state.rs | 9 |
3 files changed, 86 insertions, 2 deletions
diff --git a/cli/flags.rs b/cli/flags.rs index 9f37fb184..fa86df594 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -29,6 +29,7 @@ pub struct DenoFlags { pub allow_hrtime: bool, pub no_prompts: bool, pub no_fetch: bool, + pub seed: Option<u64>, pub v8_flags: Option<Vec<String>>, pub xeval_replvar: Option<String>, pub xeval_delim: Option<String>, @@ -146,6 +147,19 @@ To get help on the another subcommands (run in this case): .takes_value(true) .global(true), ).arg( + Arg::with_name("seed") + .long("seed") + .value_name("NUMBER") + .help("Seed Math.random()") + .takes_value(true) + .validator(|val: String| { + match val.parse::<u64>() { + Ok(_) => Ok(()), + Err(_) => Err("Seed should be a number".to_string()) + } + }) + .global(true), + ).arg( Arg::with_name("v8-options") .long("v8-options") .help("Print V8 command line options") @@ -379,6 +393,22 @@ pub fn parse_flags(matches: &ArgMatches) -> DenoFlags { v8_flags.insert(0, "deno".to_string()); flags.v8_flags = Some(v8_flags); } + if matches.is_present("seed") { + let seed_string = matches.value_of("seed").unwrap(); + let seed = seed_string.parse::<u64>().unwrap(); + flags.seed = Some(seed); + + let v8_seed_flag = format!("--random-seed={}", seed); + + match flags.v8_flags { + Some(ref mut v8_flags) => { + v8_flags.push(v8_seed_flag); + } + None => { + flags.v8_flags = Some(svec!["deno", v8_seed_flag]); + } + } + } flags = parse_run_args(flags, matches); // flags specific to "run" subcommand @@ -1112,4 +1142,42 @@ mod tests { assert_eq!(subcommand, DenoSubcommand::Run); assert_eq!(argv, svec!["deno", "script.ts"]); } + + #[test] + fn test_flags_from_vec_28() { + let (flags, subcommand, argv) = + flags_from_vec(svec!["deno", "--seed", "250", "run", "script.ts"]); + assert_eq!( + flags, + DenoFlags { + seed: Some(250 as u64), + v8_flags: Some(svec!["deno", "--random-seed=250"]), + ..DenoFlags::default() + } + ); + assert_eq!(subcommand, DenoSubcommand::Run); + assert_eq!(argv, svec!["deno", "script.ts"]) + } + + #[test] + fn test_flags_from_vec_29() { + let (flags, subcommand, argv) = flags_from_vec(svec![ + "deno", + "--seed", + "250", + "--v8-flags=--expose-gc", + "run", + "script.ts" + ]); + assert_eq!( + flags, + DenoFlags { + seed: Some(250 as u64), + v8_flags: Some(svec!["deno", "--expose-gc", "--random-seed=250"]), + ..DenoFlags::default() + } + ); + assert_eq!(subcommand, DenoSubcommand::Run); + assert_eq!(argv, svec!["deno", "script.ts"]) + } } diff --git a/cli/ops.rs b/cli/ops.rs index f39daaab6..61f29ac9f 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -2211,10 +2211,17 @@ fn op_host_post_message( } fn op_get_random_values( - _state: &ThreadSafeState, + state: &ThreadSafeState, _base: &msg::Base<'_>, data: Option<PinnedBuf>, ) -> Box<OpWithError> { - thread_rng().fill(&mut data.unwrap()[..]); + if let Some(ref seeded_rng) = state.seeded_rng { + let mut rng = seeded_rng.lock().unwrap(); + rng.fill(&mut data.unwrap()[..]); + } else { + let mut rng = thread_rng(); + rng.fill(&mut data.unwrap()[..]); + } + Box::new(ok_future(empty_buf())) } diff --git a/cli/state.rs b/cli/state.rs index 4a2db65c2..255a88144 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -23,6 +23,8 @@ use deno::PinnedBuf; use futures::future::Either; use futures::future::Shared; use futures::Future; +use rand::rngs::StdRng; +use rand::SeedableRng; use std; use std::collections::HashMap; use std::collections::HashSet; @@ -82,6 +84,7 @@ pub struct State { pub dispatch_selector: ops::OpSelector, /// Reference to global progress bar. pub progress: Progress, + pub seeded_rng: Option<Mutex<StdRng>>, /// Set of all URLs that have been compiled. This is a hacky way to work /// around the fact that --reload will force multiple compilations of the same @@ -295,6 +298,11 @@ impl ThreadSafeState { } } + let mut seeded_rng = None; + if let Some(seed) = flags.seed { + seeded_rng = Some(Mutex::new(StdRng::seed_from_u64(seed))); + }; + ThreadSafeState(Arc::new(State { main_module, dir, @@ -312,6 +320,7 @@ impl ThreadSafeState { resource, dispatch_selector, progress, + seeded_rng, compiled: Mutex::new(HashSet::new()), })) } |