Skip to content

EXPERIMENTAL: compiled vm callback - #1144

Draft
schungx wants to merge 5 commits into
mainfrom
experimental-compiled-vm-callback
Draft

EXPERIMENTAL: compiled vm callback#1144
schungx wants to merge 5 commits into
mainfrom
experimental-compiled-vm-callback

Conversation

@schungx

@schungx schungx commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

@ImTheSquid I have pushed an experimental branch called experimental-compiled-vm-callback which illustrates my idea. Can you take a look? For reference only at this point.

What it does:

  • Eliminated a lot of the stuff such as makes_pointer, needs_this, etc.

  • Eliminated the need to keep a lib of the AST for walking. This has the side effect that some features such as import, eval etc. won't compile.

  • Seems to work with anything I've thrown at it so far...

  • Eliminated the need to consider arity in callbacks... everything just works, because the arity is not in question -- the function is scripted, and it always has this (even if unused), so the shape is fixed.

  • Surgical changes in fn_ptr.rs... It is now simply FnPtrType::Compiled with no attached info. Just a marker.

  • There is no observed regression in performance.

The essence is these two changes. They make sure compiled chunks are always called with a this pointer at the front (it may be a dummy if not used). This takes care of all our arity problems.

#[cfg(all(feature = "grain", not(feature = "no_function")))]
// VM-compiled chunk
FnPtrType::Compiled => {
    // Since the chunk is actually a script-ed function, the `this` pointer goes into
    // the first position.
    let args = &mut arg_values.iter_mut().collect::<FnArgsVec<_>>();
    if let Some(this_ptr) = this_ptr.as_deref_mut() {
        args.insert(0, this_ptr);
    } else {
        args.insert(0, &mut dummy);
    }
    return context.call_native_fn_raw(self.fn_name(), true, args);
}
// A compiled chunk automatically takes an additional argument
// for `this`, push to the very front.
let arity = function.params.len() + 1;

                :

let wrapper = move |context: Option<NativeCallContext>, args: &mut [&mut Dynamic]| {
    // Always extracts the first argument for `this`.
    let (this_ptr, args) = args
        .split_first_mut()
        .ok_or_else(|| malformed("a callback wrapper was given no `this`".into()))?;

    invoke_with_this(&owner, &called, context.as_ref(), args, Some(this_ptr))
};

@schungx
schungx requested a review from ImTheSquid August 20, 2026 09:20
@schungx
schungx marked this pull request as draft August 20, 2026 09:21
@schungx
schungx force-pushed the experimental-compiled-vm-callback branch from dd10480 to 5e606ad Compare August 20, 2026 10:18
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.

1 participant