rusty_racer 0.2.5 → 0.2.6
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 +4 -4
- data/CHANGELOG.md +60 -0
- data/README.md +62 -0
- data/ext/rusty_racer/Cargo.toml +6 -1
- data/ext/rusty_racer/src/lib.rs +267 -77
- data/ext/rusty_racer/src/marshal.rs +356 -117
- data/ext/rusty_racer/src/ops.rs +244 -89
- data/lib/rusty_racer/version.rb +1 -1
- metadata +3 -2
data/ext/rusty_racer/src/ops.rs
CHANGED
|
@@ -29,14 +29,25 @@ macro_rules! marshalled {
|
|
|
29
29
|
($tc:expr, $value:expr) => {{
|
|
30
30
|
let tc = $tc;
|
|
31
31
|
let out = js_to_jsval(tc, $value);
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if tc.has_caught() {
|
|
33
|
+
Err(caught!(tc))
|
|
34
|
+
} else {
|
|
34
35
|
Ok(out)
|
|
35
|
-
}
|
|
36
|
-
|
|
36
|
+
}
|
|
37
|
+
}};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The failure a TryCatch holds once a JS step came back empty: a termination, or
|
|
41
|
+
// the exception with its stack (and the thrown value kept — `keep_thrown`).
|
|
42
|
+
macro_rules! caught {
|
|
43
|
+
($tc:expr) => {{
|
|
44
|
+
let tc = $tc;
|
|
45
|
+
if tc.has_terminated() {
|
|
46
|
+
VmError::Terminated
|
|
37
47
|
} else {
|
|
48
|
+
let exc = tc.exception();
|
|
38
49
|
let stack = tc.stack_trace();
|
|
39
|
-
|
|
50
|
+
capture_js_error(tc, exc, stack)
|
|
40
51
|
}
|
|
41
52
|
}};
|
|
42
53
|
}
|
|
@@ -76,6 +87,22 @@ pub(crate) enum Request {
|
|
|
76
87
|
void: bool,
|
|
77
88
|
timeout_ms: u64,
|
|
78
89
|
},
|
|
90
|
+
// Context#function: resolve the path as Call does, once, and keep the
|
|
91
|
+
// function and its holder (FunctionReg); replies with the handle's id.
|
|
92
|
+
ResolveFunction {
|
|
93
|
+
context_id: i32,
|
|
94
|
+
path: String,
|
|
95
|
+
timeout_ms: u64,
|
|
96
|
+
},
|
|
97
|
+
// Function#call: invoke a resolved handle as Call invokes what it resolves,
|
|
98
|
+
// with no path walk and no property name made.
|
|
99
|
+
CallFunction {
|
|
100
|
+
context_id: i32,
|
|
101
|
+
function_id: u64,
|
|
102
|
+
args: Vec<JsVal>,
|
|
103
|
+
void: bool,
|
|
104
|
+
timeout_ms: u64,
|
|
105
|
+
},
|
|
79
106
|
// Drain the isolate's microtask queue once (no auto event loop).
|
|
80
107
|
DrainMicrotasks {
|
|
81
108
|
timeout_ms: u64,
|
|
@@ -148,9 +175,6 @@ pub(crate) enum Request {
|
|
|
148
175
|
ModuleGraphAsync {
|
|
149
176
|
module_id: i32,
|
|
150
177
|
},
|
|
151
|
-
DisposeModule {
|
|
152
|
-
module_id: i32,
|
|
153
|
-
},
|
|
154
178
|
// Classic <script> primitives (V8 ScriptCompiler::CompileUnboundScript): an
|
|
155
179
|
// unbound script, compiled in a context, runnable repeatedly, with the same
|
|
156
180
|
// bytecode-cache options as modules. Addressed by id like a module.
|
|
@@ -169,9 +193,6 @@ pub(crate) enum Request {
|
|
|
169
193
|
timeout_ms: u64,
|
|
170
194
|
void: bool,
|
|
171
195
|
},
|
|
172
|
-
DisposeScript {
|
|
173
|
-
script_id: i32,
|
|
174
|
-
},
|
|
175
196
|
// Serialize a bytecode cache from a compiled handle's CURRENT compile state
|
|
176
197
|
// (Script#create_code_cache / Module#create_code_cache). Called after run/
|
|
177
198
|
// evaluate, it captures the inner functions V8 lazily compiled while running
|
|
@@ -269,67 +290,80 @@ pub(crate) fn run_source(
|
|
|
269
290
|
Completion::Primitive => marshalled!(tc, value),
|
|
270
291
|
Completion::Void => Ok(JsVal::Undefined),
|
|
271
292
|
},
|
|
272
|
-
None
|
|
273
|
-
None => {
|
|
274
|
-
let exc = tc.exception();
|
|
275
|
-
let stack = tc.stack_trace();
|
|
276
|
-
Err(capture_js_error(tc, exc, stack))
|
|
277
|
-
}
|
|
293
|
+
None => Err(caught!(tc)),
|
|
278
294
|
}
|
|
279
295
|
}
|
|
280
296
|
|
|
281
|
-
// Resolve a dotted property path on globalThis to a
|
|
282
|
-
//
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
) -> Result<
|
|
290
|
-
|
|
291
|
-
let
|
|
292
|
-
let global = context.global(tc);
|
|
293
|
-
let mut recv: v8::Local<v8::Value> = global.into();
|
|
297
|
+
// Resolve a dotted property path on the current realm's globalThis to a
|
|
298
|
+
// function and the holder it was read off — its `this`, so `a.b.f` gets the right
|
|
299
|
+
// receiver. Each segment is an ordinary [[Get]], so a getter or Proxy trap on the
|
|
300
|
+
// path runs; when one throws, the error is Err(None): the caller's TryCatch holds
|
|
301
|
+
// it (`caught!`).
|
|
302
|
+
fn resolve_function<'s>(
|
|
303
|
+
scope: &mut v8::PinScope<'s, '_>,
|
|
304
|
+
path: &str,
|
|
305
|
+
) -> Result<(v8::Local<'s, v8::Function>, v8::Local<'s, v8::Value>), Option<VmError>> {
|
|
306
|
+
let global = scope.get_current_context().global(scope);
|
|
307
|
+
let mut holder: v8::Local<v8::Value> = global.into();
|
|
294
308
|
let mut target: v8::Local<v8::Value> = global.into();
|
|
295
|
-
for part in
|
|
296
|
-
let Some(obj) = target.to_object(
|
|
309
|
+
for part in path.split('.') {
|
|
310
|
+
let Some(obj) = target.to_object(scope) else {
|
|
297
311
|
// The holder of `part` (a preceding segment) was null/undefined, so
|
|
298
312
|
// there's nothing to read `part` from — name the holder, not `part`.
|
|
299
|
-
return Err(VmError::Runtime(format!(
|
|
300
|
-
"`{
|
|
301
|
-
)));
|
|
313
|
+
return Err(Some(VmError::Runtime(format!(
|
|
314
|
+
"`{path}`: cannot read `{part}` (a preceding path segment is not an object)"
|
|
315
|
+
))));
|
|
302
316
|
};
|
|
303
|
-
let Some(key) = v8::String::new(
|
|
304
|
-
return Err(VmError::Runtime("property name too large".into()));
|
|
317
|
+
let Some(key) = v8::String::new(scope, part) else {
|
|
318
|
+
return Err(Some(VmError::Runtime("property name too large".into())));
|
|
305
319
|
};
|
|
306
|
-
let Some(next) = obj.get(
|
|
307
|
-
|
|
308
|
-
return Err(VmError::Terminated);
|
|
309
|
-
}
|
|
310
|
-
let msg = tc
|
|
311
|
-
.exception()
|
|
312
|
-
.map(|e| e.to_rust_string_lossy(tc))
|
|
313
|
-
.unwrap_or_else(|| format!("cannot read `{part}` of `{name}`"));
|
|
314
|
-
return Err(VmError::Runtime(msg));
|
|
320
|
+
let Some(next) = obj.get(scope, key.into()) else {
|
|
321
|
+
return Err(None);
|
|
315
322
|
};
|
|
316
|
-
|
|
323
|
+
holder = target;
|
|
317
324
|
target = next;
|
|
318
325
|
}
|
|
319
|
-
|
|
320
|
-
|
|
326
|
+
match v8::Local::<v8::Function>::try_from(target) {
|
|
327
|
+
Ok(function) => Ok((function, holder)),
|
|
328
|
+
Err(_) => Err(Some(VmError::Runtime(format!(
|
|
329
|
+
"`{path}` is not a function"
|
|
330
|
+
)))),
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Context#call: resolve |name| (above), then call what it names.
|
|
335
|
+
fn call_function(
|
|
336
|
+
scope: &mut v8::PinScope<'_, '_>,
|
|
337
|
+
name: &str,
|
|
338
|
+
args: Vec<JsVal>,
|
|
339
|
+
void: bool,
|
|
340
|
+
) -> Result<JsVal, VmError> {
|
|
341
|
+
let (function, receiver) = {
|
|
342
|
+
v8::tc_scope!(let tc, scope);
|
|
343
|
+
match resolve_function(tc, name) {
|
|
344
|
+
Ok(resolved) => resolved,
|
|
345
|
+
Err(failure) => return Err(failure.unwrap_or_else(|| caught!(tc))),
|
|
346
|
+
}
|
|
321
347
|
};
|
|
348
|
+
call_resolved(scope, function, receiver, args, void)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Invoke |function| via v8::Function::call with |receiver| as `this`.
|
|
352
|
+
// Args/result marshal through the ref-preserving paths.
|
|
353
|
+
fn call_resolved(
|
|
354
|
+
scope: &mut v8::PinScope<'_, '_>,
|
|
355
|
+
function: v8::Local<v8::Function>,
|
|
356
|
+
receiver: v8::Local<v8::Value>,
|
|
357
|
+
args: Vec<JsVal>,
|
|
358
|
+
void: bool,
|
|
359
|
+
) -> Result<JsVal, VmError> {
|
|
360
|
+
v8::tc_scope!(let tc, scope);
|
|
322
361
|
let argv: Vec<v8::Local<v8::Value>> = args.into_iter().map(|a| jsval_to_js(tc, a)).collect();
|
|
323
|
-
match
|
|
362
|
+
match function.call(tc, receiver, &argv) {
|
|
324
363
|
// void: skip marshalling the return so a huge/cyclic result is never walked.
|
|
325
364
|
Some(_) if void => Ok(JsVal::Undefined),
|
|
326
365
|
Some(value) => marshalled!(tc, value),
|
|
327
|
-
None
|
|
328
|
-
None => {
|
|
329
|
-
let exc = tc.exception();
|
|
330
|
-
let stack = tc.stack_trace();
|
|
331
|
-
Err(capture_js_error(tc, exc, stack))
|
|
332
|
-
}
|
|
366
|
+
None => Err(caught!(tc)),
|
|
333
367
|
}
|
|
334
368
|
}
|
|
335
369
|
|
|
@@ -413,6 +447,7 @@ pub(crate) fn service_request(
|
|
|
413
447
|
// (the graveyard repoint inside) requires that.
|
|
414
448
|
if outermost {
|
|
415
449
|
flush_retiring(scope);
|
|
450
|
+
forget_released_handles(scope);
|
|
416
451
|
}
|
|
417
452
|
reply
|
|
418
453
|
}
|
|
@@ -423,6 +458,8 @@ fn request_realm(state: &IsolateState, request: &Request) -> Option<i32> {
|
|
|
423
458
|
match request {
|
|
424
459
|
Request::Eval { context_id, .. }
|
|
425
460
|
| Request::Call { context_id, .. }
|
|
461
|
+
| Request::ResolveFunction { context_id, .. }
|
|
462
|
+
| Request::CallFunction { context_id, .. }
|
|
426
463
|
| Request::Attach { context_id, .. }
|
|
427
464
|
| Request::AttachMany { context_id, .. }
|
|
428
465
|
| Request::CompileModule { context_id, .. }
|
|
@@ -441,8 +478,6 @@ fn request_realm(state: &IsolateState, request: &Request) -> Option<i32> {
|
|
|
441
478
|
| Request::DisposeContext { .. }
|
|
442
479
|
| Request::ModuleStatus { .. }
|
|
443
480
|
| Request::ModuleGraphAsync { .. }
|
|
444
|
-
| Request::DisposeModule { .. }
|
|
445
|
-
| Request::DisposeScript { .. }
|
|
446
481
|
| Request::ScriptCodeCache { .. }
|
|
447
482
|
| Request::ModuleCodeCache { .. }
|
|
448
483
|
| Request::HeapStatistics
|
|
@@ -476,6 +511,26 @@ fn dispatch_one(
|
|
|
476
511
|
void,
|
|
477
512
|
timeout_ms,
|
|
478
513
|
} => op_call(scope, context_id, name, args, void, timeout_ms, outermost),
|
|
514
|
+
Request::ResolveFunction {
|
|
515
|
+
context_id,
|
|
516
|
+
path,
|
|
517
|
+
timeout_ms,
|
|
518
|
+
} => op_resolve_function(scope, context_id, path, timeout_ms, outermost),
|
|
519
|
+
Request::CallFunction {
|
|
520
|
+
context_id,
|
|
521
|
+
function_id,
|
|
522
|
+
args,
|
|
523
|
+
void,
|
|
524
|
+
timeout_ms,
|
|
525
|
+
} => op_call_function(
|
|
526
|
+
scope,
|
|
527
|
+
context_id,
|
|
528
|
+
function_id,
|
|
529
|
+
args,
|
|
530
|
+
void,
|
|
531
|
+
timeout_ms,
|
|
532
|
+
outermost,
|
|
533
|
+
),
|
|
479
534
|
Request::DrainMicrotasks { timeout_ms } => op_drain_microtasks(scope, timeout_ms),
|
|
480
535
|
Request::Attach {
|
|
481
536
|
context_id,
|
|
@@ -516,7 +571,6 @@ fn dispatch_one(
|
|
|
516
571
|
Request::ModuleNamespace { module_id } => op_module_namespace(scope, module_id),
|
|
517
572
|
Request::ModuleStatus { module_id } => op_module_status(scope, module_id),
|
|
518
573
|
Request::ModuleGraphAsync { module_id } => op_module_graph_async(scope, module_id),
|
|
519
|
-
Request::DisposeModule { module_id } => op_dispose_module(scope, module_id),
|
|
520
574
|
Request::CompileScript {
|
|
521
575
|
context_id,
|
|
522
576
|
source,
|
|
@@ -538,7 +592,6 @@ fn dispatch_one(
|
|
|
538
592
|
timeout_ms,
|
|
539
593
|
void,
|
|
540
594
|
} => op_run_script(scope, script_id, timeout_ms, void, outermost),
|
|
541
|
-
Request::DisposeScript { script_id } => op_dispose_script(scope, script_id),
|
|
542
595
|
// Serialize the script's CURRENT compile state. The stored handle is
|
|
543
596
|
// the UnboundScript, which V8 fills in with inner-function bytecode as
|
|
544
597
|
// run() lazily compiles them — so calling this after run() captures
|
|
@@ -673,6 +726,132 @@ fn op_call(
|
|
|
673
726
|
VmReply::Done(outcome)
|
|
674
727
|
}
|
|
675
728
|
|
|
729
|
+
fn op_resolve_function(
|
|
730
|
+
scope: &mut v8::PinScope<'_, '_, ()>,
|
|
731
|
+
context_id: i32,
|
|
732
|
+
path: String,
|
|
733
|
+
timeout_ms: u64,
|
|
734
|
+
outermost: bool,
|
|
735
|
+
) -> VmReply {
|
|
736
|
+
// The id this resolve registered, for a terminate after it (in the drain, or
|
|
737
|
+
// the watchdog's verdict over the bracket) to take back: a failed resolve hands
|
|
738
|
+
// Ruby no wrapper, so nothing else would ever release it.
|
|
739
|
+
let mut registered = None;
|
|
740
|
+
let outcome = run_js_bracketed(
|
|
741
|
+
scope,
|
|
742
|
+
outermost,
|
|
743
|
+
timeout_ms,
|
|
744
|
+
"function",
|
|
745
|
+
|scope, outermost| {
|
|
746
|
+
let Some(ctx) = context_for(istate!(scope), context_id) else {
|
|
747
|
+
return (false, Err(VmError::Disposed(REALM_GONE.into())));
|
|
748
|
+
};
|
|
749
|
+
let context = v8::Local::new(scope, &ctx);
|
|
750
|
+
let scope = &mut v8::ContextScope::new(scope, context);
|
|
751
|
+
let resolved = {
|
|
752
|
+
v8::tc_scope!(let tc, scope);
|
|
753
|
+
match resolve_function(tc, &path) {
|
|
754
|
+
Ok((function, receiver)) => {
|
|
755
|
+
Ok((v8::Global::new(tc, function), v8::Global::new(tc, receiver)))
|
|
756
|
+
}
|
|
757
|
+
Err(failure) => Err(failure.unwrap_or_else(|| caught!(tc))),
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
let out = resolved.map(|(function, receiver)| {
|
|
761
|
+
let functions = &mut istate!(scope).functions;
|
|
762
|
+
let id = functions.next_id;
|
|
763
|
+
functions.next_id += 1;
|
|
764
|
+
functions.by_id.insert(
|
|
765
|
+
id,
|
|
766
|
+
FunctionEntry {
|
|
767
|
+
function,
|
|
768
|
+
receiver,
|
|
769
|
+
context_id,
|
|
770
|
+
},
|
|
771
|
+
);
|
|
772
|
+
registered = Some(id);
|
|
773
|
+
JsVal::Int(id as i64)
|
|
774
|
+
});
|
|
775
|
+
auto_drain(scope, outermost);
|
|
776
|
+
(true, out)
|
|
777
|
+
},
|
|
778
|
+
);
|
|
779
|
+
if let (Err(_), Some(id)) = (&outcome, registered) {
|
|
780
|
+
istate!(scope).functions.by_id.remove(&id);
|
|
781
|
+
}
|
|
782
|
+
VmReply::Done(outcome)
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// What a call or a resolve of a handle whose realm is gone raises.
|
|
786
|
+
const REALM_GONE: &str = "function's realm was reset or disposed";
|
|
787
|
+
|
|
788
|
+
// Remove the handles whose Ruby wrappers were disposed or collected
|
|
789
|
+
// (Core.released) from their registries: a wrapper could not drop its Globals
|
|
790
|
+
// itself. At the outermost request boundary, and only when one was released — a
|
|
791
|
+
// flag read, not a lock, on every other op.
|
|
792
|
+
fn forget_released_handles(scope: &mut v8::PinScope<'_, '_, ()>) {
|
|
793
|
+
let core = istate!(scope).core_ptr;
|
|
794
|
+
if core.is_null() {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
let core = unsafe { &*core };
|
|
798
|
+
if !core.handles_released.swap(false, Ordering::Relaxed) {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
let released = std::mem::take(&mut *core.released.lock().unwrap());
|
|
802
|
+
let state = istate!(scope);
|
|
803
|
+
for handle in released {
|
|
804
|
+
match handle {
|
|
805
|
+
Released::Function(id) => {
|
|
806
|
+
state.functions.by_id.remove(&id);
|
|
807
|
+
}
|
|
808
|
+
Released::Module(id) => {
|
|
809
|
+
state.modules.by_id.remove(&id);
|
|
810
|
+
}
|
|
811
|
+
Released::Script(id) => {
|
|
812
|
+
state.scripts.by_id.remove(&id);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
#[allow(clippy::too_many_arguments)]
|
|
819
|
+
fn op_call_function(
|
|
820
|
+
scope: &mut v8::PinScope<'_, '_, ()>,
|
|
821
|
+
context_id: i32,
|
|
822
|
+
function_id: u64,
|
|
823
|
+
args: Vec<JsVal>,
|
|
824
|
+
void: bool,
|
|
825
|
+
timeout_ms: u64,
|
|
826
|
+
outermost: bool,
|
|
827
|
+
) -> VmReply {
|
|
828
|
+
let outcome = run_js_bracketed(scope, outermost, timeout_ms, "call", |scope, outermost| {
|
|
829
|
+
let Some(ctx) = context_for(istate!(scope), context_id) else {
|
|
830
|
+
return (false, Err(VmError::Disposed(REALM_GONE.into())));
|
|
831
|
+
};
|
|
832
|
+
let context = v8::Local::new(scope, &ctx);
|
|
833
|
+
let scope = &mut v8::ContextScope::new(scope, context);
|
|
834
|
+
// Locals straight off the registry's Globals: a shared borrow of the slot
|
|
835
|
+
// beside the shared one Local::new takes, so nothing is cloned per call.
|
|
836
|
+
let target = scope
|
|
837
|
+
.get_slot::<IsolateState>()
|
|
838
|
+
.and_then(|state| state.functions.by_id.get(&function_id))
|
|
839
|
+
.map(|entry| {
|
|
840
|
+
(
|
|
841
|
+
v8::Local::new(scope, &entry.function),
|
|
842
|
+
v8::Local::new(scope, &entry.receiver),
|
|
843
|
+
)
|
|
844
|
+
});
|
|
845
|
+
let Some((function, receiver)) = target else {
|
|
846
|
+
return (false, Err(VmError::Disposed(REALM_GONE.into())));
|
|
847
|
+
};
|
|
848
|
+
let out = call_resolved(scope, function, receiver, args, void);
|
|
849
|
+
auto_drain(scope, outermost);
|
|
850
|
+
(true, out)
|
|
851
|
+
});
|
|
852
|
+
VmReply::Done(outcome)
|
|
853
|
+
}
|
|
854
|
+
|
|
676
855
|
fn op_drain_microtasks(scope: &mut v8::PinScope<'_, '_, ()>, timeout_ms: u64) -> VmReply {
|
|
677
856
|
// A microtask may call an attached host fn (a Promise .then ->
|
|
678
857
|
// ruby), which runs inline via host_fn_callback — no routing
|
|
@@ -939,13 +1118,13 @@ fn op_compile_module(
|
|
|
939
1118
|
};
|
|
940
1119
|
let hash = module.get_identity_hash().get();
|
|
941
1120
|
let g = v8::Global::new(tc, module);
|
|
1121
|
+
let weak = v8::Weak::new(tc, module);
|
|
942
1122
|
let id = {
|
|
943
1123
|
let m = &mut istate!(tc).modules;
|
|
944
1124
|
let id = m.next_id;
|
|
945
1125
|
m.next_id += 1;
|
|
946
|
-
m.by_id
|
|
947
|
-
|
|
948
|
-
m.by_hash.entry(hash).or_default().push((g, id));
|
|
1126
|
+
m.by_id.insert(id, (g, context_id));
|
|
1127
|
+
m.add_url(hash, weak, filename.clone());
|
|
949
1128
|
id
|
|
950
1129
|
};
|
|
951
1130
|
Ok(Compiled {
|
|
@@ -1130,12 +1309,7 @@ fn op_evaluate_module(
|
|
|
1130
1309
|
_ => Ok(JsVal::Undefined),
|
|
1131
1310
|
}
|
|
1132
1311
|
}
|
|
1133
|
-
None
|
|
1134
|
-
None => {
|
|
1135
|
-
let exc = tc.exception();
|
|
1136
|
-
let stack = tc.stack_trace();
|
|
1137
|
-
Err(capture_js_error(tc, exc, stack))
|
|
1138
|
-
}
|
|
1312
|
+
None => Err(caught!(tc)),
|
|
1139
1313
|
}
|
|
1140
1314
|
}
|
|
1141
1315
|
_ => Err(VmError::Runtime(
|
|
@@ -1265,15 +1439,6 @@ fn op_module_graph_async(scope: &mut v8::PinScope<'_, '_, ()>, module_id: i32) -
|
|
|
1265
1439
|
VmReply::Done(outcome)
|
|
1266
1440
|
}
|
|
1267
1441
|
|
|
1268
|
-
fn op_dispose_module(scope: &mut v8::PinScope<'_, '_, ()>, module_id: i32) -> VmReply {
|
|
1269
|
-
let m = &mut istate!(scope).modules;
|
|
1270
|
-
m.by_id.remove(&module_id);
|
|
1271
|
-
for bucket in m.by_hash.values_mut() {
|
|
1272
|
-
bucket.retain(|(_, id)| *id != module_id);
|
|
1273
|
-
}
|
|
1274
|
-
VmReply::Done(Ok(JsVal::Undefined))
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
1442
|
#[allow(clippy::too_many_arguments)]
|
|
1278
1443
|
fn op_compile_script(
|
|
1279
1444
|
scope: &mut v8::PinScope<'_, '_, ()>,
|
|
@@ -1375,12 +1540,7 @@ fn op_run_script(
|
|
|
1375
1540
|
match script.run(tc) {
|
|
1376
1541
|
Some(_) if void => Ok(JsVal::Undefined),
|
|
1377
1542
|
Some(value) => marshalled!(tc, value),
|
|
1378
|
-
None
|
|
1379
|
-
None => {
|
|
1380
|
-
let exc = tc.exception();
|
|
1381
|
-
let stack = tc.stack_trace();
|
|
1382
|
-
Err(capture_js_error(tc, exc, stack))
|
|
1383
|
-
}
|
|
1543
|
+
None => Err(caught!(tc)),
|
|
1384
1544
|
}
|
|
1385
1545
|
};
|
|
1386
1546
|
auto_drain(scope, outermost);
|
|
@@ -1393,11 +1553,6 @@ fn op_run_script(
|
|
|
1393
1553
|
VmReply::Done(outcome)
|
|
1394
1554
|
}
|
|
1395
1555
|
|
|
1396
|
-
fn op_dispose_script(scope: &mut v8::PinScope<'_, '_, ()>, script_id: i32) -> VmReply {
|
|
1397
|
-
istate!(scope).scripts.by_id.remove(&script_id);
|
|
1398
|
-
VmReply::Done(Ok(JsVal::Undefined))
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
1556
|
fn op_script_code_cache(scope: &mut v8::PinScope<'_, '_, ()>, script_id: i32) -> VmReply {
|
|
1402
1557
|
let handle = script_handle(istate!(scope), script_id);
|
|
1403
1558
|
let outcome = match handle {
|
data/lib/rusty_racer/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rusty_racer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keita Urashima
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -34,6 +34,7 @@ extensions:
|
|
|
34
34
|
- ext/rusty_racer/extconf.rb
|
|
35
35
|
extra_rdoc_files: []
|
|
36
36
|
files:
|
|
37
|
+
- CHANGELOG.md
|
|
37
38
|
- Cargo.toml
|
|
38
39
|
- README.md
|
|
39
40
|
- ext/rusty_racer/Cargo.lock
|