rusty_racer 0.1.4 → 0.1.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 329c875cb612dccca54a8c70302d26ad0a38b8a1821733aa6eac9c4795e77d8b
4
- data.tar.gz: 4d2665db69e108f6ef37fa9d4f0ae4bc3224ab1756e911abec76cfad558f8bd4
3
+ metadata.gz: 23ab2fe2f98436d0c48cc380809611878f1a7fc0b367d8b4d677a822e718efd4
4
+ data.tar.gz: c23f8e67fb71a192331d63030d66d138dd9b1cdd136b264107b75456f762516b
5
5
  SHA512:
6
- metadata.gz: f95ae2f448af2ade88af369bea7c0b41c500e4028aeed04e34574e148c7d5f460ac068804bc49b409ab55ad352d063fcb0269064b27b1cf3a2a0453a8e245e2f
7
- data.tar.gz: 4b853defb2dbde4c0455b9eefb5b6ba9d40002e94953f5d1540c4035087e8128c6b6df843463429b0e5cbcb404a0d1a1c625d13a24fee301a300eaf50dc9ad84
6
+ metadata.gz: 9f1144b81ef5f02bac43efe2790974f50e4cfcbbca924bea182602c2615419178f5f76376c14daee424e6c7dbbaee93152cf8969275ee61c5bf8891d1a8124b0
7
+ data.tar.gz: cea6a7fbf475ad7ae58cce4556ed1834d3a7aabb3bdf832fc82060b4e386e9ff0e9572dd32a4b759c51e66eedcb3478ed085e49c841958aa2fc20595ce9d55d2
@@ -4,7 +4,7 @@
4
4
  # libv8-rusty needed under the cibuildgem native-per-platform model).
5
5
  [package]
6
6
  name = "rusty_racer"
7
- version = "0.1.4"
7
+ version = "0.1.5"
8
8
  edition = "2021"
9
9
  publish = false
10
10
 
@@ -534,11 +534,6 @@ struct V8State {
534
534
  promise_reject_handler: Option<(i32, v8::Global<v8::Function>)>,
535
535
  }
536
536
 
537
- // Context embedder-data slot holding the realm id (an Integer), stamped by
538
- // new_realm so id_of_context is O(1). Slot 0 is the embedder's own first slot
539
- // (the binding adds INTERNAL_SLOT_COUNT); nothing else here uses embedder data.
540
- const REALM_ID_SLOT: i32 = 0;
541
-
542
537
  // (STATE/MODULES/SCRIPTS/ACTIVE_REALMS/INSTANTIATING/WATCHDOG_FIRED/
543
538
  // AUTO_MICROTASKS/DRAINING moved into IsolateState in the isolate slot, reached
544
539
  // via istate!(scope). Their invariants are documented on IsolateState's fields.)
@@ -1015,17 +1010,35 @@ fn finish_dynamic_import(
1015
1010
  }
1016
1011
  }
1017
1012
 
1018
- // The id of |context|, read O(1) from the realm-id stamped in by new_realm.
1019
- // None when the context is not a LIVE realm of this isolate a context reset
1020
- // away still carries its old stamp, so confirm the id currently maps back to
1021
- // this very context before trusting it.
1013
+ // The id of |context| among this isolate's LIVE realms, or None when it isn't
1014
+ // one (e.g. a context that was reset or disposed away). Scans the realm table:
1015
+ // realm counts are small (a handful of frames) and this only runs off the hot
1016
+ // path (promise rejection, dynamic import, contextOf), so the scan is cheap.
1017
+ //
1018
+ // We deliberately do NOT stamp the id into the context's embedder data. Using a
1019
+ // context slot makes V8 attach a ContextAnnex carrying a guaranteed-finalizer
1020
+ // weak handle to every realm, and that finalizer has crashed the process at
1021
+ // isolate teardown (a first-pass weak callback re-fired during disposal,
1022
+ // panicking on an already-taken handle). Keeping realms free of context slots
1023
+ // keeps teardown clear of that hazard.
1022
1024
  fn id_of_context(scope: &mut v8::PinScope<'_, '_>, context: v8::Local<v8::Context>) -> Option<i32> {
1023
- let id = context
1024
- .get_embedder_data(scope, REALM_ID_SLOT)
1025
- .and_then(|v| v.int32_value(scope))?;
1026
- let current = context_for(istate!(scope), id);
1027
- let live = current.is_some_and(|g| v8::Local::new(scope, &g) == context);
1028
- live.then_some(id)
1025
+ // The main realm (id 0) is overwhelmingly the common case — check it first,
1026
+ // without cloning the whole table.
1027
+ let main = istate!(scope).realms.main_context.clone();
1028
+ if main.is_some_and(|g| v8::Local::new(scope, &g) == context) {
1029
+ return Some(0);
1030
+ }
1031
+ // Extra realms: snapshot the (cloned) Globals so no IsolateState borrow is
1032
+ // held while we mint Locals from `scope`.
1033
+ let extras: Vec<(i32, v8::Global<v8::Context>)> = istate!(scope)
1034
+ .realms
1035
+ .contexts
1036
+ .iter()
1037
+ .map(|(id, g)| (*id, g.clone()))
1038
+ .collect();
1039
+ extras
1040
+ .into_iter()
1041
+ .find_map(|(id, g)| (v8::Local::new(scope, &g) == context).then_some(id))
1029
1042
  }
1030
1043
 
1031
1044
  // Pick the Global context for a realm id: 0 = main, N = an extra realm (None
@@ -1363,18 +1376,11 @@ unsafe extern "C" fn promise_reject_cb(message: v8::PromiseRejectMessage) {
1363
1376
  // Build a fresh v8::Context and install the host namespace (from STATE) into
1364
1377
  // it — the single definition of "a realm of this isolate", shared by boot,
1365
1378
  // reset and create_context so realms can't drift apart.
1366
- fn new_realm(scope: &mut v8::PinScope<'_, '_, ()>, id: i32) -> v8::Global<v8::Context> {
1379
+ fn new_realm(scope: &mut v8::PinScope<'_, '_, ()>) -> v8::Global<v8::Context> {
1367
1380
  let fresh = {
1368
1381
  let context = v8::Context::new(scope, Default::default());
1369
1382
  v8::Global::new(scope, context)
1370
1383
  };
1371
- // Stamp the realm id into the context so id_of_context is O(1) (it would
1372
- // otherwise scan every realm on every promise rejection / contextOf call).
1373
- {
1374
- let context = v8::Local::new(scope, &fresh);
1375
- let id_val: v8::Local<v8::Value> = v8::Integer::new(scope, id).into();
1376
- context.set_embedder_data(REALM_ID_SLOT, id_val);
1377
- }
1378
1384
  // DESIGN DECISION: every realm of an isolate shares ONE security token, so
1379
1385
  // they are all mutually same-origin — the model is "a group of same-origin
1380
1386
  // frames sharing one heap", and NS.contextGlobal gives full cross-realm
@@ -1620,7 +1626,7 @@ impl Isolate {
1620
1626
  // namespace from the slot (seeded above).
1621
1627
  {
1622
1628
  v8::scope!(let scope, &mut isolate);
1623
- let main_context = new_realm(scope, 0);
1629
+ let main_context = new_realm(scope);
1624
1630
  istate!(scope).realms.main_context = Some(main_context);
1625
1631
  }
1626
1632
  // Box the OwnedIsolate so it has a STABLE address, then capture a raw ptr
@@ -574,7 +574,7 @@ fn op_reset(scope: &mut v8::PinScope<'_, '_, ()>, context_id: i32) -> VmReply {
574
574
  .into(),
575
575
  )))
576
576
  } else {
577
- let fresh = new_realm(scope, context_id);
577
+ let fresh = new_realm(scope);
578
578
  {
579
579
  let realms = &mut istate!(scope).realms;
580
580
  if context_id == 0 {
@@ -596,7 +596,7 @@ fn op_create_context(scope: &mut v8::PinScope<'_, '_, ()>) -> VmReply {
596
596
  realms.next_context_id += 1;
597
597
  id
598
598
  };
599
- let fresh = new_realm(scope, id);
599
+ let fresh = new_realm(scope);
600
600
  istate!(scope).realms.contexts.insert(id, fresh);
601
601
  VmReply::Done(Ok(JsVal::Int(id as i64)))
602
602
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RustyRacer
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rusty_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2026-06-14 00:00:00.000000000 Z
@@ -54,7 +54,7 @@ metadata:
54
54
  source_code_uri: https://github.com/ursm/rusty_racer
55
55
  bug_tracker_uri: https://github.com/ursm/rusty_racer/issues
56
56
  rubygems_mfa_required: 'true'
57
- post_install_message:
57
+ post_install_message:
58
58
  rdoc_options: []
59
59
  require_paths:
60
60
  - lib
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
70
  version: '0'
71
71
  requirements: []
72
72
  rubygems_version: 3.5.22
73
- signing_key:
73
+ signing_key:
74
74
  specification_version: 4
75
75
  summary: Embed V8 in Ruby via rusty_v8 + Magnus (rb-sys)
76
76
  test_files: []