Using rusty_v8, how to create a Persistent scope?

Hello EveryOne.

I'm trying to write bindings to V8 for Java using rust as programming languge, I'm using rusty_v8 which comes with precompiled V8 which is why I'm using it, I'm also using the jni crate.

Right now I have two functions: one is runVoidScript and the other is runPromiseFunction, the first one takes javascript code and runs it inside an Isolate, the other one takes a function name and arguments, it looks for that function inside global scope, call that function with the arguments. it expects the function to return a Promise which should be converted to Java's CompletableFuture.

Right Now my code compiles, just when I run runVoidScript("async function test(){return true}") and then runPromiseFunction("test",[]) the second call panics with undefined is not a function message.

I'm storing isolate in a pointer referenced from java code as long variable, I could not store handle scope or context because the borrow checker prevented me, In annother attempt to store handle scope rusty_v8 panicked with "active scope cannot be dropped" so it seems those structs aren't meant to be stored.

I know that v8 c++ API has got Persistent but I can't find their equivalent in rusty_v8, Global is the closest thing to what I want but I can't figure out how to use it, I searched the docs and the test code, I've looked everywhere with no use.

Here I list code that shows what I'm trying to do:

fn runVoidScript(isolate: &mut v8::OwnedIsolate,code: &str){
    let scope = &mut v8::HandleScope::new(isolate);
    let context = v8::Context::new(scope);
    let scope = &mut v8::ContextScope::new(scope, context);        
    let code = v8::String::new(scope, code).unwrap();

    let script = v8::Script::compile(scope, code, None).expect("failed to compile javascript code");"runtime exception");
fn runFunction(isolate: &mut v8::OwnedIsolate,function_name: &str){
    let scope = &mut v8::HandleScope::new(isolate);
    let context = v8::Context::new(scope);
    let scope = &mut v8::ContextScope::new(scope, context);
    let global =;
        // getting the javascript function whose name is function_name parameter   
    let function_name_string= v8::String::new(scope, function_name)
            .expect("failed to convert Rust string to javascript string");
    let function = global.get(scope, function_name_string.into()).expect(&*format!(
        "could not find function {}",
    let function: v8::Local<v8::Function> = unsafe { v8::Local::cast(function) };
    // call that function with arguments
    let recv = v8::Integer::new(scope, 2).into();, recv, &[])

I tried passing global variable as recv as I thought maybe the function doesn't like integer, but that didn't work.

So how do I implement runVoidScript in a way that variables and functions defined top-level will be persisted on the isolate itself ?

Some Info:
Rust Version: 1.46.0 stable
rusty_v8 version: 0.10.0

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.