Skip to content
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
61f5d8d
wip
nathanwhit Aug 1, 2025
fd64c42
update
nathanwhit Aug 6, 2025
77fd0d8
init try catch
nathanwhit Aug 6, 2025
ee8d37f
real isolateification
nathanwhit Aug 11, 2025
5d27e0e
hmmmm
nathanwhit Aug 12, 2025
cd03976
closer
nathanwhit Aug 12, 2025
2973c1c
rework contextscope, fix callbackscope leak
nathanwhit Aug 12, 2025
765b0f8
add trycatch methods
nathanwhit Aug 12, 2025
16b4201
sync up changes
nathanwhit Aug 15, 2025
2263708
escapable handle scope, more examples working
nathanwhit Aug 19, 2025
d23f37a
disallow/allow execution scope, phantom pinned
nathanwhit Aug 20, 2025
00bc4c5
fix derefmut, warnings, remove old scopes
nathanwhit Aug 20, 2025
e948db2
fix cppgc example
nathanwhit Aug 20, 2025
3fe398d
update compile_fail tests
nathanwhit Aug 20, 2025
65aacf7
asref impls, get some more tests passing
nathanwhit Aug 20, 2025
f1c92ea
fix bug, start fixing api tests
nathanwhit Aug 20, 2025
8483fa3
get more passing
nathanwhit Aug 21, 2025
7dd1195
add missing methods, callbacks are borked
nathanwhit Aug 21, 2025
c8b24d0
wip
nathanwhit Aug 21, 2025
f19b865
working on it
nathanwhit Aug 21, 2025
bb8e7c3
rework trycatch a bit
nathanwhit Aug 21, 2025
8bc77cb
fix newhandlescope lt
nathanwhit Aug 21, 2025
55c223c
small fixes
nathanwhit Aug 21, 2025
5de1908
get it all compiling
nathanwhit Aug 21, 2025
2e41a35
update ui tests
nathanwhit Aug 22, 2025
76ef1c0
finish todos
nathanwhit Aug 22, 2025
eda9247
inlining
nathanwhit Aug 22, 2025
3388351
fix context scope bug, ignore broken tests, fix examples
nathanwhit Aug 22, 2025
2bfa95f
fix remaining tests
nathanwhit Aug 22, 2025
6f76ade
fix doctests
nathanwhit Aug 22, 2025
0bbe6c0
temporarily run ci on the old branch
nathanwhit Aug 22, 2025
b9ed173
fmt
nathanwhit Aug 22, 2025
aa05aeb
unignore snapshot tests
nathanwhit Aug 22, 2025
dd2976e
fix benchmark
nathanwhit Aug 22, 2025
bb7dbd5
tweak some lifetimes, add new type alias
nathanwhit Aug 23, 2025
7b75905
appease clippy
nathanwhit Aug 23, 2025
a42dc34
change fast api
nathanwhit Aug 23, 2025
aed4a66
fmt
nathanwhit Aug 23, 2025
4c3e3a0
new raw isolate pointer api
nathanwhit Aug 23, 2025
1db7c67
fix ui test
nathanwhit Aug 23, 2025
c591137
rebase fixup
nathanwhit Sep 10, 2025
da358ce
remove old scope code
nathanwhit Sep 10, 2025
543d51c
rename scope2 -> scope
nathanwhit Sep 10, 2025
7dbf7d3
more explicit implied lifetimes
nathanwhit Sep 10, 2025
70368cd
rename some methods
nathanwhit Sep 11, 2025
2253ae9
appease clippy
nathanwhit Sep 11, 2025
44c92cf
scope tweaks
nathanwhit Sep 11, 2025
55fe409
trycatch/escapablehandlescope lifetimes
nathanwhit Sep 11, 2025
6498559
appease clippy
nathanwhit Sep 11, 2025
3f07a1a
fmt
nathanwhit Sep 11, 2025
22c58ea
update tests
nathanwhit Sep 11, 2025
fa2ef6d
reduce null checks
nathanwhit Sep 11, 2025
eb094c5
windows
nathanwhit Sep 12, 2025
6b41d94
windows?
nathanwhit Sep 12, 2025
a1429dd
remove dead code
nathanwhit Sep 12, 2025
0f4a583
small cleanup
nathanwhit Sep 12, 2025
3c2f8b7
impl AsMut<Isolate>
nathanwhit Sep 12, 2025
6b55d6e
add feature for dchecks
nathanwhit Sep 12, 2025
21bb788
cleanup, start on docs
nathanwhit Sep 15, 2025
516d6f7
cleanup, add back deref tests, fix some impls
nathanwhit Sep 15, 2025
78f78ff
cleanup
nathanwhit Sep 16, 2025
167d0bc
add some comments, appease clippy
nathanwhit Sep 16, 2025
24407f0
comments
nathanwhit Sep 16, 2025
0e1dcec
replace w macro
nathanwhit Sep 16, 2025
6250365
use macro more
nathanwhit Sep 16, 2025
933b77e
revert ci change
nathanwhit Sep 16, 2025
caf953b
fmt
nathanwhit Sep 16, 2025
b0ca013
change macro expansion to improve borrowing error messages
nathanwhit Sep 16, 2025
5502f94
remove unnecessary reborrows
nathanwhit Sep 16, 2025
820307b
address comments
nathanwhit Sep 18, 2025
970df18
Merge main into scope-rework
nathanwhit Sep 18, 2025
b6315e7
rename macros to be more succinct
nathanwhit Sep 19, 2025
d278fe5
copy over rustdocs
nathanwhit Sep 22, 2025
7bc1b8b
add funtion to extend lifetime
nathanwhit Sep 22, 2025
7a9ee54
add compile fail test for zombie scope issue
nathanwhit Sep 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,14 @@ opt-level = 1
default = ["use_custom_libcxx"]
use_custom_libcxx = []
v8_enable_pointer_compression = []
v8_enable_v8_checks = []

[dependencies]
bitflags = "2.5"
paste = "1.0"
temporal_capi = { package = "ry_temporal_capi", version = "=0.0.11-ry.1", features = [ "compiled_data" ] }
temporal_capi = { package = "ry_temporal_capi", version = "=0.0.11-ry.1", features = [
"compiled_data",
] }

[build-dependencies]
miniz_oxide = "0.8.8"
Expand Down
19 changes: 11 additions & 8 deletions benches/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ fn main() {
v8::V8::initialize_platform(platform);
v8::V8::initialize();
let isolate = &mut v8::Isolate::new(v8::CreateParams::default());
let handle_scope = &mut v8::HandleScope::new(isolate);
v8::make_handle_scope!(let handle_scope, isolate);
let context = v8::Context::new(handle_scope, Default::default());
let scope = &mut v8::ContextScope::new(handle_scope, context);
let global = context.global(scope);
{
let func = v8::Function::new(
scope,
|scope: &mut v8::HandleScope,
|scope: &mut v8::PinScope,
_: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
rv.set(v8::Integer::new(scope, 42).into());
Expand All @@ -30,7 +30,8 @@ fn main() {
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let info = unsafe { &*info };
let scope = unsafe { &mut v8::CallbackScope::new(info) };
let scope = std::pin::pin!(unsafe { v8::CallbackScope::new(info) });
let scope = &scope.init();
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set(v8::Integer::new(scope, 42).into());
}
Expand All @@ -51,7 +52,7 @@ fn main() {
{
let func = v8::Function::new(
scope,
|_: &mut v8::HandleScope,
|_: &mut v8::PinScope,
_: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
rv.set_uint32(42);
Expand All @@ -74,7 +75,7 @@ fn main() {
),
);
let template = v8::FunctionTemplate::builder(
|scope: &mut v8::HandleScope,
|scope: &mut v8::PinScope,
_: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
rv.set(v8::Integer::new(scope, 42).into());
Expand All @@ -90,7 +91,8 @@ fn main() {
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let info = unsafe { &*info };
let scope = unsafe { &mut v8::CallbackScope::new(info) };
let scope = std::pin::pin!(unsafe { v8::CallbackScope::new(info) });
let scope = &scope.init();
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set(v8::undefined(scope).into());
}
Expand Down Expand Up @@ -156,10 +158,11 @@ fn main() {
}

fn eval<'s>(
scope: &mut v8::HandleScope<'s>,
scope: &mut v8::PinScope<'s, '_>,
code: &str,
) -> Option<v8::Local<'s, v8::Value>> {
let scope = &mut v8::EscapableHandleScope::new(scope);
v8::make_escapable_handle_scope!(let scope, scope);

let source = v8::String::new(scope, code).unwrap();
let script = v8::Script::compile(scope, source, None).unwrap();
let r = script.run(scope);
Expand Down
4 changes: 4 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ fn build_v8(is_asan: bool) {
"v8_enable_pointer_compression={}",
env::var("CARGO_FEATURE_V8_ENABLE_POINTER_COMPRESSION").is_ok()
));
gn_args.push(format!(
"v8_enable_v8_checks={}",
env::var("CARGO_FEATURE_V8_ENABLE_V8_CHECKS").is_ok()
));
// Fix GN's host_cpu detection when using x86_64 bins on Apple Silicon
if cfg!(target_os = "macos") && cfg!(target_arch = "aarch64") {
gn_args.push("host_cpu=\"arm64\"".to_string());
Expand Down
14 changes: 7 additions & 7 deletions examples/cppgc-object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,31 @@ const TAG: u16 = 1;
fn main() {
let platform = v8::new_default_platform(0, false).make_shared();
v8::V8::set_flags_from_string("--no_freeze_flags_after_init --expose-gc");
v8::V8::initialize_platform(platform.clone());
v8::V8::initialize();

v8::V8::initialize_platform(platform.clone());
v8::cppgc::initialize_process(platform.clone());
v8::V8::initialize();

{
let heap =
v8::cppgc::Heap::create(platform, v8::cppgc::HeapCreateParams::default());
let isolate =
&mut v8::Isolate::new(v8::CreateParams::default().cpp_heap(heap));

let handle_scope = &mut v8::HandleScope::new(isolate);
v8::make_handle_scope!(handle_scope, isolate);
let context = v8::Context::new(handle_scope, Default::default());
let scope = &mut v8::ContextScope::new(handle_scope, context);
let global = context.global(scope);
{
let func = v8::Function::new(
scope,
|scope: &mut v8::HandleScope,
|scope: &mut v8::PinScope<'_, '_>,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
let id = args.get(0).to_rust_string_lossy(scope);

fn empty(
_scope: &mut v8::HandleScope,
_scope: &mut v8::PinScope<'_, '_>,
_args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
Expand Down Expand Up @@ -113,8 +113,8 @@ fn execute_script(
context_scope: &mut v8::ContextScope<v8::HandleScope>,
script: v8::Local<v8::String>,
) {
let scope = &mut v8::HandleScope::new(context_scope);
let try_catch = &mut v8::TryCatch::new(scope);
v8::make_handle_scope!(handle_scope, context_scope);
v8::make_try_catch!(let try_catch, handle_scope);

let script = v8::Script::compile(try_catch, script, None)
.expect("failed to compile script");
Expand Down
2 changes: 1 addition & 1 deletion examples/cppgc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ impl Drop for Rope {
fn main() {
let platform = v8::new_default_platform(0, false).make_shared();
v8::V8::initialize_platform(platform.clone());
v8::V8::initialize();
v8::cppgc::initialize_process(platform.clone());
v8::V8::initialize();

{
// Create a managed heap.
Expand Down
5 changes: 2 additions & 3 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ fn main() {
let isolate = &mut v8::Isolate::new(v8::CreateParams::default());

// Create a stack-allocated handle scope.
let handle_scope = &mut v8::HandleScope::new(isolate);
v8::make_handle_scope!(let handle_scope, isolate);

// Create a new context.
let context = v8::Context::new(handle_scope, Default::default());

// Enter the context for compiling and running the hello world script.
let scope = &mut v8::ContextScope::new(handle_scope, context);

let scope = &v8::ContextScope::new(handle_scope, context);
// Create a string containing the JavaScript source code.
let code = v8::String::new(scope, "'Hello' + ' World!'").unwrap();

Expand Down
81 changes: 39 additions & 42 deletions examples/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::convert::TryFrom;

#[allow(clippy::needless_pass_by_value)] // this function should follow the callback type
fn log_callback(
scope: &mut v8::HandleScope,
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
mut _retval: v8::ReturnValue,
) {
Expand All @@ -29,13 +29,13 @@ fn main() {
}

let mut isolate = v8::Isolate::new(v8::CreateParams::default());
let mut scope = v8::HandleScope::new(&mut isolate);
v8::make_handle_scope!(let scope, &mut isolate);

let source = std::fs::read_to_string(&file)
.unwrap_or_else(|err| panic!("failed to open {file}: {err}"));
let source = v8::String::new(&mut scope, &source).unwrap();
let source = v8::String::new(scope, &source).unwrap();

let mut processor = JsHttpRequestProcessor::new(&mut scope, source, options);
let mut processor = JsHttpRequestProcessor::new(scope, source, options);

let requests = vec![
StringHttpRequest::new("/process.cc", "localhost", "google.com", "firefox"),
Expand Down Expand Up @@ -124,22 +124,19 @@ impl HttpRequest for StringHttpRequest {
}

/// An http request processor that is scriptable using JavaScript.
struct JsHttpRequestProcessor<'s, 'i> {
context: v8::Local<'s, v8::Context>,
context_scope: v8::ContextScope<'i, v8::HandleScope<'s>>,
process_fn: Option<v8::Local<'s, v8::Function>>,
struct JsHttpRequestProcessor<'scope, 'obj, 'isolate> {
context: v8::Local<'obj, v8::Context>,
context_scope: v8::ContextScope<'scope, 'obj, v8::HandleScope<'isolate>>,
process_fn: Option<v8::Local<'obj, v8::Function>>,
request_template: v8::Global<v8::ObjectTemplate>,
_map_template: Option<v8::Global<v8::ObjectTemplate>>,
}

impl<'s, 'i> JsHttpRequestProcessor<'s, 'i>
where
's: 'i,
{
impl<'scope, 'obj, 'isolate> JsHttpRequestProcessor<'scope, 'obj, 'isolate> {
/// Creates a scriptable HTTP request processor.
pub fn new(
isolate_scope: &'i mut v8::HandleScope<'s, ()>,
source: v8::Local<'s, v8::String>,
isolate_scope: &'scope mut v8::PinScope<'obj, 'isolate, ()>,
source: v8::Local<'obj, v8::String>,
options: HashMap<String, String>,
) -> Self {
let global = v8::ObjectTemplate::new(isolate_scope);
Expand All @@ -155,14 +152,13 @@ where
..Default::default()
},
);
let mut context_scope = v8::ContextScope::new(isolate_scope, context);
let context_scope = v8::ContextScope::new(isolate_scope, context);

let request_template = v8::ObjectTemplate::new(&mut context_scope);
let request_template = v8::ObjectTemplate::new(&context_scope);
request_template.set_internal_field_count(1);

// make it global
let request_template =
v8::Global::new(&mut context_scope, request_template);
let request_template = v8::Global::new(&context_scope, request_template);

let mut self_ = JsHttpRequestProcessor {
context,
Expand All @@ -174,32 +170,29 @@ where

// loads options and output
let options = self_.wrap_map(options);
let options_str =
v8::String::new(&mut self_.context_scope, "options").unwrap();
self_.context.global(&mut self_.context_scope).set(
&mut self_.context_scope,
let options_str = v8::String::new(&self_.context_scope, "options").unwrap();
self_.context.global(&self_.context_scope).set(
&self_.context_scope,
options_str.into(),
options.into(),
);

let output = v8::Object::new(&mut self_.context_scope);
let output_str =
v8::String::new(&mut self_.context_scope, "output").unwrap();
self_.context.global(&mut self_.context_scope).set(
&mut self_.context_scope,
let output = v8::Object::new(&self_.context_scope);
let output_str = v8::String::new(&self_.context_scope, "output").unwrap();
self_.context.global(&self_.context_scope).set(
&self_.context_scope,
output_str.into(),
output.into(),
);

// execute script
self_.execute_script(source);

let process_str =
v8::String::new(&mut self_.context_scope, "Process").unwrap();
let process_str = v8::String::new(&self_.context_scope, "Process").unwrap();
let process_fn = self_
.context
.global(&mut self_.context_scope)
.get(&mut self_.context_scope, process_str.into())
.global(&self_.context_scope)
.get(&self_.context_scope, process_str.into())
.expect("missing function Process");

let process_fn = v8::Local::<v8::Function>::try_from(process_fn)
Expand All @@ -209,9 +202,10 @@ where
self_
}

fn execute_script(&mut self, script: v8::Local<'s, v8::String>) {
let scope = &mut v8::HandleScope::new(&mut self.context_scope);
let try_catch = &mut v8::TryCatch::new(scope);
fn execute_script(&mut self, script: v8::Local<'scope, v8::String>) {
v8::make_handle_scope!(let scope, &mut self.context_scope);

v8::make_try_catch!(let try_catch, scope);

let script = v8::Script::compile(try_catch, script, None)
.expect("failed to compile script");
Expand All @@ -235,8 +229,9 @@ where
let request: Box<dyn HttpRequest> = Box::new(request);
let request = self.wrap_request(request);

let scope = &mut v8::HandleScope::new(&mut self.context_scope);
let try_catch = &mut v8::TryCatch::new(scope);
v8::make_handle_scope!(let scope, &mut self.context_scope);

v8::make_try_catch!(let try_catch, scope);

let process_fn = self.process_fn.as_mut().unwrap();
let global = self.context.global(try_catch).into();
Expand All @@ -259,7 +254,7 @@ where
fn wrap_request(
&mut self,
request: Box<dyn HttpRequest>,
) -> v8::Local<'s, v8::Object> {
) -> v8::Local<'scope, v8::Object> {
// TODO: fix memory leak

use std::ffi::c_void;
Expand Down Expand Up @@ -295,7 +290,7 @@ where
/// This handles the properties of `HttpRequest`
#[allow(clippy::needless_pass_by_value)] // this function should follow the callback type
fn request_prop_handler(
scope: &mut v8::HandleScope,
scope: &mut v8::PinScope,
key: v8::Local<v8::Name>,
args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue,
Expand Down Expand Up @@ -327,7 +322,7 @@ where

/// Utility function that extracts the http request object from a wrapper object.
fn unwrap_request(
scope: &mut v8::HandleScope,
scope: &v8::PinScope,
request: v8::Local<v8::Object>,
) -> *mut Box<dyn HttpRequest> {
let external = request
Expand All @@ -340,9 +335,9 @@ where
fn wrap_map(
&mut self,
options: HashMap<String, String>,
) -> v8::Local<'s, v8::Object> {
) -> v8::Local<'scope, v8::Object> {
// TODO: wrap map, not convert into Object
let scope = &mut self.context_scope;
let scope = &self.context_scope;
let result = v8::Object::new(scope);

for (key, value) in options {
Expand All @@ -356,7 +351,9 @@ where

/// Prints the output.
pub fn print_output(&mut self) {
let scope = &mut v8::HandleScope::new(&mut self.context_scope);
let scope: std::pin::Pin<&mut v8::ScopeStorage<v8::HandleScope<'_>>> =
std::pin::pin!(v8::HandleScope::new(&mut self.context_scope));
let scope = &scope.init();
let key = v8::String::new(scope, "output").unwrap();
let output = self
.context
Expand Down
Loading
Loading