Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global context #83

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Global context #83

wants to merge 2 commits into from

Conversation

tertsdiepraam
Copy link
Contributor

@tertsdiepraam tertsdiepraam commented Dec 13, 2024

We wanted to have some implicit global variables that are exposed to the script by the runtime. In contrast with global constants, these are defined per invocation and are therefore more flexible. There's a test in here that shows how to use it:

#[derive(Context)]
struct Ctx {
    pub foo: i32,
    pub bar: bool,
}

let mut rt = Runtime::basic().unwrap();
rt.register_context_type::<Ctx>().unwrap();

let s = src!(
    "
    filter-map main() {
        apply {
            if bar {
                accept foo + 1
            } else {
                accept foo
            } 
        }
    }"
);

let mut p = compile_with_runtime(s, rt);

// Try getting the wrong ctx, which should fail
p.get_function::<(), (), Verdict<i32, ()>>("main")
   .unwrap_err();

// And then with the correct ctx type
let f = p.get_function::<Ctx, (), Verdict<i32, ()>>("main").unwrap();

let mut ctx = Ctx { foo: 9, bar: false };
let output = f.call(&mut ctx);
assert_eq!(output, Verdict::Accept(9));

let mut ctx = Ctx { foo: 10, bar: true };
let output = f.call(&mut ctx);
assert_eq!(output, Verdict::Accept(11));

The default context is just (), so if no context is defined a &mut () should be passed in.

Under the hood, this is implemented as passing around a single pointer to all functions which refers to the location of the context struct. Note that the context type does not need #[repr(C)] or anything like that, because we get the information on the field offsets in that struct from Rust. All the types mentioned in the context type should be registered in Roto though.

There's a couple of things to do in follow-up PRs:

  • Add context to rotodoc
  • Add context to runtime functions

Also, this could use some more complex tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants