rusty_racer 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,18 +46,18 @@ use std::sync::{Arc, Mutex, Once, Weak};
46
46
  use magnus::block::Proc;
47
47
  use magnus::value::{BoxValue, ReprValue};
48
48
  use magnus::{
49
- function, method, prelude::*, Error, Exception, ExceptionClass, RHash, Ruby, TryConvert, Value,
49
+ Error, Exception, ExceptionClass, RHash, Ruby, TryConvert, Value, function, method, prelude::*,
50
50
  };
51
51
 
52
52
  mod marshal;
53
- use marshal::{js_to_jsval, jsval_to_js, jsval_to_ruby, ruby_to_jsval, JsVal};
53
+ use marshal::{JsVal, js_to_jsval, jsval_to_js, jsval_to_ruby, ruby_to_jsval};
54
54
  mod ops;
55
- use ops::{run_source, service_request, Compiled, Request, VmReply};
55
+ use ops::{Compiled, Request, VmReply, run_source, service_request};
56
56
  mod stack;
57
- use stack::{current_real_isolate, discover_scan_start_field, StackScope, STACK_DEBUG};
57
+ use stack::{STACK_DEBUG, StackScope, current_real_isolate, discover_scan_start_field};
58
58
  mod watchdog;
59
59
  use watchdog::{
60
- arm_watchdog, disarm_watchdog, run_js_bracketed, watchdog_loop, WatchdogShared, WATCHDOG_DEBUG,
60
+ WATCHDOG_DEBUG, WatchdogShared, arm_watchdog, disarm_watchdog, run_js_bracketed, watchdog_loop,
61
61
  };
62
62
 
63
63
  // A Ruby Proc rooted for as long as the Core holds it. BoxValue registers a
@@ -203,7 +203,11 @@ enum VmError {
203
203
  // Core::run, once the op has unwound, forces a GC to reclaim and resets the
204
204
  // ceiling — see the OOM recovery there. The bump is a no-op-after-the-fact:
205
205
  // doubling here, GC + reset after, so the limit keeps protecting later ops.
206
- unsafe extern "C" fn near_heap_limit_cb(data: *mut c_void, current_heap_limit: usize, initial: usize) -> usize {
206
+ unsafe extern "C" fn near_heap_limit_cb(
207
+ data: *mut c_void,
208
+ current_heap_limit: usize,
209
+ initial: usize,
210
+ ) -> usize {
207
211
  let isolate = unsafe { &mut *(data as *mut v8::Isolate) };
208
212
  // get_slot_mut (not istate!): this runs as an extern "C" callback from V8's
209
213
  // C++ allocator, where a panic would unwind across the FFI boundary. The slot
@@ -263,7 +267,10 @@ where
263
267
  job.r = Some((job.f.take().unwrap())());
264
268
  null_mut()
265
269
  }
266
- let mut job = Job::<F, R> { f: Some(f), r: None };
270
+ let mut job = Job::<F, R> {
271
+ f: Some(f),
272
+ r: None,
273
+ };
267
274
  unsafe {
268
275
  rb_sys::rb_thread_call_without_gvl(
269
276
  Some(run::<F, R>),
@@ -295,7 +302,10 @@ where
295
302
  job.r = Some((job.f.take().unwrap())());
296
303
  null_mut()
297
304
  }
298
- let mut job = Job::<F, R> { f: Some(f), r: None };
305
+ let mut job = Job::<F, R> {
306
+ f: Some(f),
307
+ r: None,
308
+ };
299
309
  unsafe {
300
310
  rb_sys::rb_thread_call_with_gvl(Some(run::<F, R>), &mut job as *mut _ as *mut c_void);
301
311
  }
@@ -433,12 +443,12 @@ fn parse_js_stack(stack: &str) -> Vec<String> {
433
443
  }
434
444
  // "NAME (LOC)" -> "LOC:in 'NAME'". Split on the FIRST " (" so a LOC
435
445
  // path that itself contains parentheses stays intact.
436
- if frame.ends_with(')') {
437
- if let Some(open) = frame.find(" (") {
438
- let name = &frame[..open];
439
- let loc = &frame[open + 2..frame.len() - 1];
440
- return Some(format!("{loc}:in '{name}'"));
441
- }
446
+ if frame.ends_with(')')
447
+ && let Some(open) = frame.find(" (")
448
+ {
449
+ let name = &frame[..open];
450
+ let loc = &frame[open + 2..frame.len() - 1];
451
+ return Some(format!("{loc}:in '{name}'"));
442
452
  }
443
453
  Some(frame.to_string())
444
454
  })
@@ -458,21 +468,18 @@ fn capture_js_error(
458
468
  .map(|e| e.to_rust_string_lossy(scope))
459
469
  .unwrap_or_else(|| "unexpected failure".to_string());
460
470
  let mut stack_str = None;
461
- if let Some(e) = exception {
462
- if let Some(obj) = e.to_object(scope) {
463
- if let Some(key) = v8::String::new(scope, "stack") {
464
- if let Some(s) = obj.get(scope, key.into()) {
465
- if s.is_string() {
466
- stack_str = Some(s.to_rust_string_lossy(scope));
467
- }
468
- }
469
- }
470
- }
471
+ if let Some(e) = exception
472
+ && let Some(obj) = e.to_object(scope)
473
+ && let Some(key) = v8::String::new(scope, "stack")
474
+ && let Some(s) = obj.get(scope, key.into())
475
+ && s.is_string()
476
+ {
477
+ stack_str = Some(s.to_rust_string_lossy(scope));
471
478
  }
472
- if stack_str.is_none() {
473
- if let Some(s) = fallback_stack {
474
- stack_str = Some(s.to_rust_string_lossy(scope));
475
- }
479
+ if stack_str.is_none()
480
+ && let Some(s) = fallback_stack
481
+ {
482
+ stack_str = Some(s.to_rust_string_lossy(scope));
476
483
  }
477
484
  let backtrace = stack_str
478
485
  .map(|s| parse_js_stack(s.as_str()))
@@ -487,7 +494,17 @@ fn capture_js_error(
487
494
  fn module_origin<'s>(scope: &v8::PinScope<'s, '_>, url: &str) -> v8::ScriptOrigin<'s> {
488
495
  let name = v8::String::new(scope, url).unwrap();
489
496
  v8::ScriptOrigin::new(
490
- scope, name.into(), 0, 0, false, -1, None, false, false, /*is_module*/ true, None,
497
+ scope,
498
+ name.into(),
499
+ 0,
500
+ 0,
501
+ false,
502
+ -1,
503
+ None,
504
+ false,
505
+ false,
506
+ /*is_module*/ true,
507
+ None,
491
508
  )
492
509
  }
493
510
 
@@ -773,7 +790,7 @@ fn drain_all_realms(scope: &mut v8::PinScope<'_, '_>) {
773
790
  .collect()
774
791
  };
775
792
  for q in queues {
776
- unsafe { (*q).perform_checkpoint(&mut ***scope) };
793
+ unsafe { (*q).perform_checkpoint(scope) };
777
794
  }
778
795
  }
779
796
 
@@ -833,7 +850,10 @@ fn drop_context_artifacts(state: &mut IsolateState, context_id: i32) {
833
850
  }
834
851
 
835
852
  // A script's (unbound handle, owning context id), for running it in that context.
836
- fn script_handle(state: &IsolateState, script_id: i32) -> Option<(v8::Global<v8::UnboundScript>, i32)> {
853
+ fn script_handle(
854
+ state: &IsolateState,
855
+ script_id: i32,
856
+ ) -> Option<(v8::Global<v8::UnboundScript>, i32)> {
837
857
  state
838
858
  .scripts
839
859
  .by_id
@@ -1081,7 +1101,9 @@ fn finish_dynamic_import(
1081
1101
  Some(exc) => {
1082
1102
  resolver.reject(tc, exc);
1083
1103
  }
1084
- None => reject_with_error(tc, resolver, "failed to link dynamically imported module"),
1104
+ None => {
1105
+ reject_with_error(tc, resolver, "failed to link dynamically imported module")
1106
+ }
1085
1107
  }
1086
1108
  return;
1087
1109
  }
@@ -1097,7 +1119,11 @@ fn finish_dynamic_import(
1097
1119
  match module.evaluate(tc) {
1098
1120
  Some(value) => {
1099
1121
  let Ok(eval_promise) = v8::Local::<v8::Promise>::try_from(value) else {
1100
- reject_with_error(tc, resolver, "module evaluation did not yield a promise");
1122
+ reject_with_error(
1123
+ tc,
1124
+ resolver,
1125
+ "module evaluation did not yield a promise",
1126
+ );
1101
1127
  return;
1102
1128
  };
1103
1129
  // Settle the import() promise from the evaluation promise
@@ -1501,10 +1527,13 @@ fn transfer_out(
1501
1527
  return;
1502
1528
  }
1503
1529
  let token = NEXT_TRANSFER_TOKEN.fetch_add(1, Ordering::Relaxed);
1504
- transfer_registry()
1505
- .lock()
1506
- .unwrap()
1507
- .insert(token, SendBackingStore { store, shared: false });
1530
+ transfer_registry().lock().unwrap().insert(
1531
+ token,
1532
+ SendBackingStore {
1533
+ store,
1534
+ shared: false,
1535
+ },
1536
+ );
1508
1537
  rv.set(v8::Number::new(scope, token as f64).into());
1509
1538
  }
1510
1539
 
@@ -1525,10 +1554,13 @@ fn share_out(
1525
1554
  };
1526
1555
  let store = sab.get_backing_store();
1527
1556
  let token = NEXT_TRANSFER_TOKEN.fetch_add(1, Ordering::Relaxed);
1528
- transfer_registry()
1529
- .lock()
1530
- .unwrap()
1531
- .insert(token, SendBackingStore { store, shared: true });
1557
+ transfer_registry().lock().unwrap().insert(
1558
+ token,
1559
+ SendBackingStore {
1560
+ store,
1561
+ shared: true,
1562
+ },
1563
+ );
1532
1564
  rv.set(v8::Number::new(scope, token as f64).into());
1533
1565
  }
1534
1566
 
@@ -1671,12 +1703,15 @@ fn new_realm(
1671
1703
  ) -> (v8::Global<v8::Context>, v8::UniqueRef<v8::MicrotaskQueue>) {
1672
1704
  // Explicit policy like the isolate's: rusty drives every drain by hand
1673
1705
  // (auto_drain / NS.drainMicrotasks), so V8 must never auto-run this queue.
1674
- let mut queue = v8::MicrotaskQueue::new(&mut **scope, v8::MicrotasksPolicy::Explicit);
1706
+ let mut queue = v8::MicrotaskQueue::new(scope, v8::MicrotasksPolicy::Explicit);
1675
1707
  let fresh = {
1676
- let context = v8::Context::new(scope, v8::ContextOptions {
1677
- microtask_queue: Some(&mut *queue as *mut _),
1678
- ..Default::default()
1679
- });
1708
+ let context = v8::Context::new(
1709
+ scope,
1710
+ v8::ContextOptions {
1711
+ microtask_queue: Some(&mut *queue as *mut _),
1712
+ ..Default::default()
1713
+ },
1714
+ );
1680
1715
  v8::Global::new(scope, context)
1681
1716
  };
1682
1717
  // DESIGN DECISION: every realm of an isolate shares ONE security token, so
@@ -1729,7 +1764,8 @@ fn flush_retiring(scope: &mut v8::PinScope<'_, '_, ()>) {
1729
1764
  if istate!(scope).realms.retiring.is_empty() {
1730
1765
  return;
1731
1766
  }
1732
- let graveyard: *const v8::MicrotaskQueue = match istate!(scope).realms.graveyard_queue.as_ref() {
1767
+ let graveyard: *const v8::MicrotaskQueue = match istate!(scope).realms.graveyard_queue.as_ref()
1768
+ {
1733
1769
  Some(q) => &**q as *const _,
1734
1770
  // The graveyard is created at boot and never cleared, so with entries
1735
1771
  // waiting this is unreachable; assert so a future refactor that defers its
@@ -1769,7 +1805,10 @@ fn install_host_namespace(
1769
1805
  let scope = &mut v8::ContextScope::new(scope, context);
1770
1806
  let ns = v8::Object::new(scope);
1771
1807
  let members: [(&str, Option<v8::Local<v8::Function>>); 9] = [
1772
- ("drainMicrotasks", v8::Function::new(scope, drain_microtasks)),
1808
+ (
1809
+ "drainMicrotasks",
1810
+ v8::Function::new(scope, drain_microtasks),
1811
+ ),
1773
1812
  ("contextGlobal", v8::Function::new(scope, context_global)),
1774
1813
  ("contextOf", v8::Function::new(scope, context_of)),
1775
1814
  (
@@ -1813,8 +1852,8 @@ fn attach_at_path(
1813
1852
  if part.is_empty() {
1814
1853
  return Err(VmError::Runtime(format!("invalid attach name `{name}`")));
1815
1854
  }
1816
- let key =
1817
- v8::String::new(scope, part).ok_or_else(|| VmError::Runtime("name too large".into()))?;
1855
+ let key = v8::String::new(scope, part)
1856
+ .ok_or_else(|| VmError::Runtime("name too large".into()))?;
1818
1857
  holder = match holder.get(scope, key.into()) {
1819
1858
  Some(v) if v.is_object() => v8::Local::<v8::Object>::try_from(v).unwrap(),
1820
1859
  // Don't clobber an existing non-object (e.g. a primitive global that
@@ -1827,7 +1866,9 @@ fn attach_at_path(
1827
1866
  _ => {
1828
1867
  let obj = v8::Object::new(scope);
1829
1868
  if holder.set(scope, key.into(), obj.into()) != Some(true) {
1830
- return Err(VmError::Runtime(format!("`{name}`: cannot create `{part}`")));
1869
+ return Err(VmError::Runtime(format!(
1870
+ "`{name}`: cannot create `{part}`"
1871
+ )));
1831
1872
  }
1832
1873
  obj
1833
1874
  }
@@ -1874,17 +1915,18 @@ fn build_snapshot(code: &str, base: Option<Vec<u8>>, warmup: bool) -> Result<Vec
1874
1915
  let context = v8::Context::new(scope, Default::default());
1875
1916
  {
1876
1917
  let cscope = &mut v8::ContextScope::new(scope, context);
1877
- if !code.is_empty() {
1878
- if let Err(e) = run_source(cscope, code, if warmup { "<warmup>" } else { "<snapshot>" }) {
1879
- err = Some(match e {
1880
- VmError::Parse(m) | VmError::Runtime(m) => m,
1881
- VmError::JsError { message, .. } => message,
1882
- VmError::Terminated => "snapshot code was terminated".to_string(),
1883
- // Unreachable: the snapshot-creator is a separate isolate
1884
- // that never registers near_heap_limit_cb.
1885
- VmError::OutOfMemory => "snapshot code ran out of memory".to_string(),
1886
- });
1887
- }
1918
+ if !code.is_empty()
1919
+ && let Err(e) =
1920
+ run_source(cscope, code, if warmup { "<warmup>" } else { "<snapshot>" })
1921
+ {
1922
+ err = Some(match e {
1923
+ VmError::Parse(m) | VmError::Runtime(m) => m,
1924
+ VmError::JsError { message, .. } => message,
1925
+ VmError::Terminated => "snapshot code was terminated".to_string(),
1926
+ // Unreachable: the snapshot-creator is a separate isolate
1927
+ // that never registers near_heap_limit_cb.
1928
+ VmError::OutOfMemory => "snapshot code ran out of memory".to_string(),
1929
+ });
1888
1930
  }
1889
1931
  }
1890
1932
  // Mark the context to deserialize on boot (after the ContextScope is
@@ -1970,7 +2012,7 @@ impl Isolate {
1970
2012
  istate!(scope).realms.main_context = Some(main_context);
1971
2013
  istate!(scope).realms.main_queue = Some(main_queue);
1972
2014
  // The shared graveyard for retired realms' contexts (see V8State).
1973
- let graveyard = v8::MicrotaskQueue::new(&mut **scope, v8::MicrotasksPolicy::Explicit);
2015
+ let graveyard = v8::MicrotaskQueue::new(scope, v8::MicrotasksPolicy::Explicit);
1974
2016
  istate!(scope).realms.graveyard_queue = Some(graveyard);
1975
2017
  }
1976
2018
  // Box the OwnedIsolate so it has a STABLE address, then capture a raw ptr
@@ -1998,7 +2040,10 @@ impl Isolate {
1998
2040
  let owner_thread = unsafe { Value::from_raw(rb_sys::rb_thread_current()) };
1999
2041
  let core = Arc::new_cyclic(|me| Core {
2000
2042
  me: me.clone(),
2001
- shared: Mutex::new(Shared { handle, disposed: false }),
2043
+ shared: Mutex::new(Shared {
2044
+ handle,
2045
+ disposed: false,
2046
+ }),
2002
2047
  iso_id,
2003
2048
  owner: owner_thread.as_raw() as usize,
2004
2049
  _owner_root: RootedThread(BoxValue::new(owner_thread)),
@@ -2058,7 +2103,10 @@ impl Core {
2058
2103
  ));
2059
2104
  }
2060
2105
  if self.shared.lock().unwrap().disposed {
2061
- return Err(Error::new(ruby.exception_runtime_error(), "disposed context"));
2106
+ return Err(Error::new(
2107
+ ruby.exception_runtime_error(),
2108
+ "disposed context",
2109
+ ));
2062
2110
  }
2063
2111
  Ok(())
2064
2112
  }
@@ -2265,15 +2313,12 @@ impl Core {
2265
2313
  // access pattern as swap_instantiate. Does NOT clear it (run() clears at the
2266
2314
  // next outermost op) so a nested timeout's outer frame can read it too.
2267
2315
  fn peek_timeout_backtrace(&self) -> Option<Vec<String>> {
2268
- istate!(unsafe { &mut *self.iso_ptr.0 }).timeout_backtrace.clone()
2316
+ istate!(unsafe { &mut *self.iso_ptr.0 })
2317
+ .timeout_backtrace
2318
+ .clone()
2269
2319
  }
2270
2320
 
2271
- fn call_proc(
2272
- &self,
2273
- ruby: &Ruby,
2274
- host_fn_id: usize,
2275
- args: &[JsVal],
2276
- ) -> Result<JsVal, String> {
2321
+ fn call_proc(&self, ruby: &Ruby, host_fn_id: usize, args: &[JsVal]) -> Result<JsVal, String> {
2277
2322
  let proc = {
2278
2323
  let procs = self.procs.lock().unwrap();
2279
2324
  procs
@@ -2309,7 +2354,13 @@ impl Core {
2309
2354
  // Context#call (and call_void). Resolves a dotted function path
2310
2355
  // on globalThis and invokes it via v8::Function::call. |void| skips
2311
2356
  // marshalling the return for fire-and-forget calls.
2312
- fn call(&self, ruby: &Ruby, context_id: i32, args: &[Value], void: bool) -> Result<Value, Error> {
2357
+ fn call(
2358
+ &self,
2359
+ ruby: &Ruby,
2360
+ context_id: i32,
2361
+ args: &[Value],
2362
+ void: bool,
2363
+ ) -> Result<Value, Error> {
2313
2364
  let Some((name, call_args)) = args.split_first() else {
2314
2365
  return Err(Error::new(
2315
2366
  ruby.exception_arg_error(),
@@ -2322,20 +2373,26 @@ impl Core {
2322
2373
  .map(|v| ruby_to_jsval(*v))
2323
2374
  .collect::<Result<_, _>>()?;
2324
2375
 
2325
- let reply = self.run(ruby, Request::Call {
2326
- context_id,
2327
- name,
2328
- args: jsargs,
2329
- void,
2330
- timeout_ms: self.default_timeout_ms,
2331
- })?;
2376
+ let reply = self.run(
2377
+ ruby,
2378
+ Request::Call {
2379
+ context_id,
2380
+ name,
2381
+ args: jsargs,
2382
+ void,
2383
+ timeout_ms: self.default_timeout_ms,
2384
+ },
2385
+ )?;
2332
2386
  self.reply_value(ruby, reply)
2333
2387
  }
2334
2388
 
2335
2389
  fn drain_microtasks(&self, ruby: &Ruby) -> Result<Value, Error> {
2336
- let reply = self.run(ruby, Request::DrainMicrotasks {
2337
- timeout_ms: self.default_timeout_ms,
2338
- })?;
2390
+ let reply = self.run(
2391
+ ruby,
2392
+ Request::DrainMicrotasks {
2393
+ timeout_ms: self.default_timeout_ms,
2394
+ },
2395
+ )?;
2339
2396
  self.reply_value(ruby, reply)
2340
2397
  }
2341
2398
 
@@ -2354,10 +2411,19 @@ impl Core {
2354
2411
  h.aset(ruby.to_symbol("total_heap_size"), s.total_heap_size)?;
2355
2412
  h.aset(ruby.to_symbol("heap_size_limit"), s.heap_size_limit)?;
2356
2413
  h.aset(ruby.to_symbol("malloced_memory"), s.malloced_memory)?;
2357
- h.aset(ruby.to_symbol("peak_malloced_memory"), s.peak_malloced_memory)?;
2414
+ h.aset(
2415
+ ruby.to_symbol("peak_malloced_memory"),
2416
+ s.peak_malloced_memory,
2417
+ )?;
2358
2418
  h.aset(ruby.to_symbol("external_memory"), s.external_memory)?;
2359
- h.aset(ruby.to_symbol("number_of_native_contexts"), s.number_of_native_contexts)?;
2360
- h.aset(ruby.to_symbol("number_of_detached_contexts"), s.number_of_detached_contexts)?;
2419
+ h.aset(
2420
+ ruby.to_symbol("number_of_native_contexts"),
2421
+ s.number_of_native_contexts,
2422
+ )?;
2423
+ h.aset(
2424
+ ruby.to_symbol("number_of_detached_contexts"),
2425
+ s.number_of_detached_contexts,
2426
+ )?;
2361
2427
  Ok(h.as_value())
2362
2428
  }
2363
2429
 
@@ -2376,26 +2442,38 @@ impl Core {
2376
2442
  filename: String,
2377
2443
  timeout_ms: u64,
2378
2444
  ) -> Result<Value, Error> {
2379
- let reply = self.run(ruby, Request::Eval {
2380
- context_id,
2381
- source,
2382
- filename,
2383
- timeout_ms,
2384
- })?;
2445
+ let reply = self.run(
2446
+ ruby,
2447
+ Request::Eval {
2448
+ context_id,
2449
+ source,
2450
+ filename,
2451
+ timeout_ms,
2452
+ },
2453
+ )?;
2385
2454
  self.reply_value(ruby, reply)
2386
2455
  }
2387
2456
 
2388
- fn attach(&self, ruby: &Ruby, context_id: i32, name: String, proc: Proc) -> Result<Value, Error> {
2457
+ fn attach(
2458
+ &self,
2459
+ ruby: &Ruby,
2460
+ context_id: i32,
2461
+ name: String,
2462
+ proc: Proc,
2463
+ ) -> Result<Value, Error> {
2389
2464
  let host_fn_id = self.procs.lock().unwrap().alloc(ProcSlot {
2390
2465
  context_id,
2391
2466
  proc: Some(RootedProc(BoxValue::new(proc))),
2392
2467
  });
2393
- let reply = self.run(ruby, Request::Attach {
2394
- context_id,
2395
- name,
2396
- host_fn_id,
2397
- timeout_ms: self.default_timeout_ms,
2398
- })?;
2468
+ let reply = self.run(
2469
+ ruby,
2470
+ Request::Attach {
2471
+ context_id,
2472
+ name,
2473
+ host_fn_id,
2474
+ timeout_ms: self.default_timeout_ms,
2475
+ },
2476
+ )?;
2399
2477
  self.reply_value(ruby, reply)
2400
2478
  }
2401
2479
 
@@ -2406,7 +2484,12 @@ impl Core {
2406
2484
  // (name-tagged) error WITHOUT rolling back earlier entries (see the
2407
2485
  // AttachMany arm). On that error path the unused slots are reclaimed at the
2408
2486
  // next reset/dispose of the realm, like single attach.
2409
- fn attach_many(&self, ruby: &Ruby, context_id: i32, entries: Vec<(String, Proc)>) -> Result<Value, Error> {
2487
+ fn attach_many(
2488
+ &self,
2489
+ ruby: &Ruby,
2490
+ context_id: i32,
2491
+ entries: Vec<(String, Proc)>,
2492
+ ) -> Result<Value, Error> {
2410
2493
  if entries.is_empty() {
2411
2494
  return Ok(ruby.qnil().as_value()); // nothing to install, skip the round-trip
2412
2495
  }
@@ -2423,11 +2506,14 @@ impl Core {
2423
2506
  })
2424
2507
  .collect()
2425
2508
  };
2426
- let reply = self.run(ruby, Request::AttachMany {
2427
- context_id,
2428
- entries: named_ids,
2429
- timeout_ms: self.default_timeout_ms,
2430
- })?;
2509
+ let reply = self.run(
2510
+ ruby,
2511
+ Request::AttachMany {
2512
+ context_id,
2513
+ entries: named_ids,
2514
+ timeout_ms: self.default_timeout_ms,
2515
+ },
2516
+ )?;
2431
2517
  self.reply_value(ruby, reply)
2432
2518
  }
2433
2519
 
@@ -2475,14 +2561,17 @@ impl Core {
2475
2561
  produce_cache: bool,
2476
2562
  eager: bool,
2477
2563
  ) -> Result<Compiled, Error> {
2478
- let reply = self.run(ruby, Request::CompileModule {
2479
- context_id,
2480
- source,
2481
- filename,
2482
- cached_data,
2483
- produce_cache,
2484
- eager,
2485
- })?;
2564
+ let reply = self.run(
2565
+ ruby,
2566
+ Request::CompileModule {
2567
+ context_id,
2568
+ source,
2569
+ filename,
2570
+ cached_data,
2571
+ produce_cache,
2572
+ eager,
2573
+ },
2574
+ )?;
2486
2575
  match reply {
2487
2576
  VmReply::ModuleCompiled(Ok(cm)) => Ok(cm),
2488
2577
  VmReply::ModuleCompiled(Err(e)) => Err(vm_err(ruby, e)),
@@ -2517,7 +2606,12 @@ impl Core {
2517
2606
  // it per import edge (it may compile a dependency lazily — a re-entrant op
2518
2607
  // that just recurses into run). A resolver that RAISED is re-raised here with
2519
2608
  // its original class.
2520
- fn instantiate_module(&self, ruby: &Ruby, module_id: i32, resolve: Proc) -> Result<Value, Error> {
2609
+ fn instantiate_module(
2610
+ &self,
2611
+ ruby: &Ruby,
2612
+ module_id: i32,
2613
+ resolve: Proc,
2614
+ ) -> Result<Value, Error> {
2521
2615
  // Guard BEFORE touching the slot via iso_ptr: a foreign-thread or
2522
2616
  // post-dispose call must be refused, not deref a freed/foreign isolate.
2523
2617
  self.ensure_owner_and_live(ruby)?;
@@ -2535,10 +2629,13 @@ impl Core {
2535
2629
  }
2536
2630
 
2537
2631
  fn evaluate_module(&self, ruby: &Ruby, module_id: i32) -> Result<Value, Error> {
2538
- let reply = self.run(ruby, Request::EvaluateModule {
2539
- module_id,
2540
- timeout_ms: self.default_timeout_ms,
2541
- })?;
2632
+ let reply = self.run(
2633
+ ruby,
2634
+ Request::EvaluateModule {
2635
+ module_id,
2636
+ timeout_ms: self.default_timeout_ms,
2637
+ },
2638
+ )?;
2542
2639
  self.reply_value(ruby, reply)
2543
2640
  }
2544
2641
 
@@ -2569,14 +2666,17 @@ impl Core {
2569
2666
  produce_cache: bool,
2570
2667
  eager: bool,
2571
2668
  ) -> Result<Compiled, Error> {
2572
- let reply = self.run(ruby, Request::CompileScript {
2573
- context_id,
2574
- source,
2575
- filename,
2576
- cached_data,
2577
- produce_cache,
2578
- eager,
2579
- })?;
2669
+ let reply = self.run(
2670
+ ruby,
2671
+ Request::CompileScript {
2672
+ context_id,
2673
+ source,
2674
+ filename,
2675
+ cached_data,
2676
+ produce_cache,
2677
+ eager,
2678
+ },
2679
+ )?;
2580
2680
  match reply {
2581
2681
  VmReply::ScriptCompiled(Ok(cs)) => Ok(cs),
2582
2682
  VmReply::ScriptCompiled(Err(e)) => Err(vm_err(ruby, e)),
@@ -2588,10 +2688,13 @@ impl Core {
2588
2688
  }
2589
2689
 
2590
2690
  fn run_script(&self, ruby: &Ruby, script_id: i32) -> Result<Value, Error> {
2591
- let reply = self.run(ruby, Request::RunScript {
2592
- script_id,
2593
- timeout_ms: self.default_timeout_ms,
2594
- })?;
2691
+ let reply = self.run(
2692
+ ruby,
2693
+ Request::RunScript {
2694
+ script_id,
2695
+ timeout_ms: self.default_timeout_ms,
2696
+ },
2697
+ )?;
2595
2698
  self.reply_value(ruby, reply)
2596
2699
  }
2597
2700
 
@@ -2811,7 +2914,10 @@ impl Context {
2811
2914
  fn check_live(&self, ruby: &Ruby) -> Result<(), Error> {
2812
2915
  // id 0's lifetime is the isolate's; extras also track their own dispose.
2813
2916
  if self.disposed.load(Ordering::SeqCst) || self.core.is_disposed() {
2814
- return Err(Error::new(ruby.exception_runtime_error(), "disposed context"));
2917
+ return Err(Error::new(
2918
+ ruby.exception_runtime_error(),
2919
+ "disposed context",
2920
+ ));
2815
2921
  }
2816
2922
  Ok(())
2817
2923
  }
@@ -2829,7 +2935,9 @@ impl Context {
2829
2935
  } else {
2830
2936
  timeout_ms
2831
2937
  };
2832
- rb_self.core.eval_t(ruby, rb_self.id, source, filename, timeout)
2938
+ rb_self
2939
+ .core
2940
+ .eval_t(ruby, rb_self.id, source, filename, timeout)
2833
2941
  }
2834
2942
  fn call(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Value, Error> {
2835
2943
  rb_self.check_live(ruby)?;
@@ -2872,9 +2980,15 @@ impl Context {
2872
2980
  ) -> Result<JsModule, Error> {
2873
2981
  rb_self.check_live(ruby)?;
2874
2982
  let cache_in = binary_bytes(ruby, cached_data)?;
2875
- let cm = rb_self
2876
- .core
2877
- .compile_module(ruby, rb_self.id, source, filename, cache_in, produce_cache, eager)?;
2983
+ let cm = rb_self.core.compile_module(
2984
+ ruby,
2985
+ rb_self.id,
2986
+ source,
2987
+ filename,
2988
+ cache_in,
2989
+ produce_cache,
2990
+ eager,
2991
+ )?;
2878
2992
  Ok(JsModule {
2879
2993
  core: rb_self.core.clone(),
2880
2994
  module_id: cm.id,
@@ -2896,9 +3010,15 @@ impl Context {
2896
3010
  ) -> Result<Script, Error> {
2897
3011
  rb_self.check_live(ruby)?;
2898
3012
  let cache_in = binary_bytes(ruby, cached_data)?;
2899
- let cs = rb_self
2900
- .core
2901
- .compile_script(ruby, rb_self.id, source, filename, cache_in, produce_cache, eager)?;
3013
+ let cs = rb_self.core.compile_script(
3014
+ ruby,
3015
+ rb_self.id,
3016
+ source,
3017
+ filename,
3018
+ cache_in,
3019
+ produce_cache,
3020
+ eager,
3021
+ )?;
2902
3022
  Ok(Script {
2903
3023
  core: rb_self.core.clone(),
2904
3024
  script_id: cs.id,
@@ -2991,7 +3111,10 @@ impl JsModule {
2991
3111
  // before run's guard) is gone — without this, instantiate after
2992
3112
  // iso.dispose is a use-after-free.
2993
3113
  if self.disposed.load(Ordering::SeqCst) || self.core.is_disposed() {
2994
- return Err(Error::new(ruby.exception_runtime_error(), "disposed module"));
3114
+ return Err(Error::new(
3115
+ ruby.exception_runtime_error(),
3116
+ "disposed module",
3117
+ ));
2995
3118
  }
2996
3119
  Ok(())
2997
3120
  }
@@ -2999,7 +3122,9 @@ impl JsModule {
2999
3122
  // the lib wrapper). resolver.(specifier, referrer_url) must return a Module.
3000
3123
  fn instantiate(ruby: &Ruby, rb_self: &Self, resolver: Proc) -> Result<Value, Error> {
3001
3124
  rb_self.check_live(ruby)?;
3002
- rb_self.core.instantiate_module(ruby, rb_self.module_id, resolver)
3125
+ rb_self
3126
+ .core
3127
+ .instantiate_module(ruby, rb_self.module_id, resolver)
3003
3128
  }
3004
3129
  fn evaluate(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
3005
3130
  rb_self.check_live(ruby)?;
@@ -3050,7 +3175,10 @@ impl Script {
3050
3175
  fn check_live(&self, ruby: &Ruby) -> Result<(), Error> {
3051
3176
  // Also refuse once the isolate is disposed (see JsModule::check_live).
3052
3177
  if self.disposed.load(Ordering::SeqCst) || self.core.is_disposed() {
3053
- return Err(Error::new(ruby.exception_runtime_error(), "disposed script"));
3178
+ return Err(Error::new(
3179
+ ruby.exception_runtime_error(),
3180
+ "disposed script",
3181
+ ));
3054
3182
  }
3055
3183
  Ok(())
3056
3184
  }
@@ -3112,7 +3240,10 @@ fn code_cache_from_reply(ruby: &Ruby, reply: VmReply) -> Result<Option<Vec<u8>>,
3112
3240
  // Read a Ruby cached_data arg as raw bytes, refusing a non-binary string so a
3113
3241
  // cache file read without 'rb' (silently transcoded) fails loudly rather than
3114
3242
  // being consumed as garbage and rejected with no signal.
3115
- fn binary_bytes(ruby: &Ruby, cached_data: Option<magnus::RString>) -> Result<Option<Vec<u8>>, Error> {
3243
+ fn binary_bytes(
3244
+ ruby: &Ruby,
3245
+ cached_data: Option<magnus::RString>,
3246
+ ) -> Result<Option<Vec<u8>>, Error> {
3116
3247
  match cached_data {
3117
3248
  None => Ok(None),
3118
3249
  Some(s) => {
@@ -3324,7 +3455,10 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
3324
3455
  // JS Map instead of a plain object. It behaves exactly like a Hash (so
3325
3456
  // `assert_kind_of Hash` / `h[k]` still work); users may also construct one to
3326
3457
  // hand a JS Map to JS. See marshal.rs.
3327
- module.define_class("JSMap", ruby.class_object().const_get::<_, magnus::RClass>("Hash")?)?;
3458
+ module.define_class(
3459
+ "JSMap",
3460
+ ruby.class_object().const_get::<_, magnus::RClass>("Hash")?,
3461
+ )?;
3328
3462
 
3329
3463
  let platform = module.define_module("Platform")?;
3330
3464
  platform.define_singleton_method("set_flags!", function!(platform_set_flags, -1))?;
@@ -3338,6 +3472,9 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
3338
3472
  // Observability for the thread-confined lifecycle (see Drop for Core).
3339
3473
  module.define_singleton_method("live_isolate_count", function!(live_isolate_count, 0))?;
3340
3474
  module.define_singleton_method("leaked_isolate_count", function!(leaked_isolate_count, 0))?;
3341
- module.define_singleton_method("pending_transfer_count", function!(pending_transfer_count, 0))?;
3475
+ module.define_singleton_method(
3476
+ "pending_transfer_count",
3477
+ function!(pending_transfer_count, 0),
3478
+ )?;
3342
3479
  Ok(())
3343
3480
  }