Skip to content

Commit 240dce1

Browse files
committed
Stop initializing python in Rust headless if user plugins or repo plugins is disabled
This will speed up InitCorePlugins by 5x for headless rust scripts that do not need python to be initialized. For rust scripts that do use python user plugins or repo plugins this keeps the behavior the same.
1 parent ec89e9c commit 240dce1

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

rust/src/headless.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use std::sync::mpsc::Sender;
3131
use std::sync::Mutex;
3232
use std::thread::JoinHandle;
3333
use std::time::Duration;
34+
use crate::settings::Settings;
3435

3536
static MAIN_THREAD_HANDLE: Mutex<Option<JoinHandle<()>>> = Mutex::new(None);
3637

@@ -49,13 +50,13 @@ pub enum InitializationError {
4950
NoLicenseFound,
5051
}
5152

52-
/// Loads plugins, core architecture, platform, etc.
53+
/// Loads core plugins, core architecture, platform, etc.
5354
///
5455
/// ⚠️ Important! Must be called at the beginning of scripts. Plugins do not need to call this. ⚠️
5556
///
5657
/// You can instead call this through [`Session`].
5758
///
58-
/// If you need to customize initialization, use [`init_with_opts`] instead.
59+
/// If you need to customize initialization, use [`init_with_opts`] instead, for example to set [`InitializationOptions::with_user_plugins`].
5960
pub fn init() -> Result<(), InitializationError> {
6061
let options = InitializationOptions::default();
6162
init_with_opts(options)
@@ -172,6 +173,21 @@ impl Default for InitializationOptions {
172173
}
173174
}
174175

176+
/// Adjust settings temporarily so that we can screw with the core settings and not impact user settings.
177+
fn init_adjusted_settings(options: &InitializationOptions, cb: impl FnOnce(&mut Settings)) {
178+
let mut settings = Settings::new();
179+
let is_python_enabled = settings.get_bool("corePlugins.python");
180+
// Because we don't ship core python plugins, we don't need to load
181+
// python if we are not loading user plugins.
182+
settings.set_bool("corePlugins.python", options.user_plugins);
183+
if options.repo_plugins {
184+
settings.set_bool("corePlugins.python", options.repo_plugins);
185+
}
186+
cb(&mut settings);
187+
// Reset the settings to the previous value.
188+
settings.set_bool("corePlugins.python", is_python_enabled);
189+
}
190+
175191
/// This initializes the core with the given [`InitializationOptions`].
176192
pub fn init_with_opts(options: InitializationOptions) -> Result<(), InitializationError> {
177193
// If we are the main thread that means there is no main thread, we should register a main thread handler.
@@ -207,20 +223,22 @@ pub fn init_with_opts(options: InitializationOptions) -> Result<(), Initializati
207223
_ => {}
208224
}
209225

210-
if let Some(license) = options.license {
226+
if let Some(license) = options.license.clone() {
211227
// We were given a license override, use it!
212228
set_license(Some(license));
213229
}
214230

215-
set_bundled_plugin_directory(options.bundled_plugin_directory);
231+
set_bundled_plugin_directory(&options.bundled_plugin_directory);
216232

217-
unsafe {
218-
BNInitPlugins(options.user_plugins);
219-
if options.repo_plugins {
220-
// We are allowed to initialize repo plugins, so do it!
221-
BNInitRepoPlugins();
233+
init_adjusted_settings(&options, |_| {
234+
unsafe {
235+
BNInitPlugins(options.user_plugins);
236+
if options.repo_plugins {
237+
// We are allowed to initialize repo plugins, so do it!
238+
BNInitRepoPlugins();
239+
}
222240
}
223-
}
241+
});
224242

225243
if !is_license_validated() {
226244
// Unfortunately you must have a valid license to use Binary Ninja.
@@ -291,6 +309,9 @@ impl Session {
291309
///
292310
/// If you cannot otherwise provide a license via `BN_LICENSE_FILE` environment variable or the Binary Ninja user directory
293311
/// you can call [`Session::new_with_opts`] instead of this function.
312+
///
313+
/// If you need to use a user plugin you should call [`Session::new_with_opts`] instead, as by default
314+
/// [`Session::new`] will only initialize core plugins.
294315
pub fn new() -> Result<Self, InitializationError> {
295316
if license_location().is_some() {
296317
// We were able to locate a license, continue with initialization.

0 commit comments

Comments
 (0)