From 4e8eaf94c3f411c673e39cdded57f1d3b8db079a Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 7 Dec 2020 22:46:38 +0100 Subject: [PATCH] Add set_flags_from_command_line_with_usage (#536) The motivation for this is to enable embedders of rusty_v8 to pass their own usage string and have their usage printed before V8's options. --- src/V8.rs | 22 ++++++++++++++++++++-- src/binding.cc | 9 +++++++-- tests/test_api.rs | 9 +++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/V8.rs b/src/V8.rs index 9dd83cf7..0639cef0 100644 --- a/src/V8.rs +++ b/src/V8.rs @@ -11,7 +11,11 @@ use crate::support::UniqueRef; use crate::support::UnitType; extern "C" { - fn v8__V8__SetFlagsFromCommandLine(argc: *mut c_int, argv: *mut *mut c_char); + fn v8__V8__SetFlagsFromCommandLine( + argc: *mut c_int, + argv: *mut *mut c_char, + usage: *const c_char, + ); fn v8__V8__SetFlagsFromString(flags: *const u8, length: usize); fn v8__V8__SetEntropySource(callback: EntropySource); fn v8__V8__GetVersion() -> *const c_char; @@ -83,6 +87,12 @@ pub fn assert_initialized() { /// Returns a vector of command line arguments that V8 did not understand. /// TODO: Check whether this is safe to do after globally initializing v8. pub fn set_flags_from_command_line(args: Vec) -> Vec { + set_flags_from_command_line_with_usage(args, None) +} +pub fn set_flags_from_command_line_with_usage( + args: Vec, + usage: Option<&str>, +) -> Vec { // deno_set_v8_flags(int* argc, char** argv) mutates argc and argv to remove // flags that v8 understands. @@ -102,8 +112,16 @@ pub fn set_flags_from_command_line(args: Vec) -> Vec { // updates its value. let mut c_argv_len = c_argv.len() as c_int; // Let v8 parse the arguments it recognizes and remove them from c_argv. + let c_usage = match usage { + Some(str) => CString::new(str).unwrap().into_raw() as *const c_char, + None => std::ptr::null(), + }; unsafe { - v8__V8__SetFlagsFromCommandLine(&mut c_argv_len, c_argv.as_mut_ptr()) + v8__V8__SetFlagsFromCommandLine( + &mut c_argv_len, + c_argv.as_mut_ptr(), + c_usage, + ); }; // If c_argv_len was updated we have to change the length of c_argv to match. c_argv.truncate(c_argv_len as usize); diff --git a/src/binding.cc b/src/binding.cc index d3873938..bfd5e5bd 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -10,6 +10,7 @@ #include "v8/include/v8.h" #include "v8/src/execution/isolate-utils-inl.h" #include "v8/src/execution/isolate-utils.h" +#include "v8/src/flags/flags.h" #include "v8/src/objects/objects-inl.h" #include "v8/src/objects/objects.h" #include "v8/src/objects/smi.h" @@ -89,8 +90,12 @@ v8::MaybeLocal HostImportModuleDynamicallyCallback( } extern "C" { -void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv) { - v8::V8::SetFlagsFromCommandLine(argc, argv, true); +void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv, + const char* usage) { + namespace i = v8::internal; + using HelpOptions = i::FlagList::HelpOptions; + HelpOptions help_options = HelpOptions(HelpOptions::kExit, usage); + i::FlagList::SetFlagsFromCommandLine(argc, argv, true, help_options); } void v8__V8__SetFlagsFromString(const char* flags, size_t length) { diff --git a/tests/test_api.rs b/tests/test_api.rs index 02ea2c57..f4ffb6fb 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -999,6 +999,15 @@ fn set_flags_from_command_line() { ); } +#[test] +fn set_flags_from_command_line_with_usage() { + let r = v8::V8::set_flags_from_command_line_with_usage( + vec!["binaryname".to_string(), "--help".to_string()], + Some("Usage: binaryname --startup-src=file\n\n"), + ); + assert_eq!(r, vec!["binaryname".to_string()]); +} + #[test] fn inspector_string_view() { let chars = b"Hello world!";