Skip to content

[embind] Add support for argument policies to val methods.#26020

Open
brendandahl wants to merge 1 commit intoemscripten-core:mainfrom
brendandahl:embind-add-arg-policies
Open

[embind] Add support for argument policies to val methods.#26020
brendandahl wants to merge 1 commit intoemscripten-core:mainfrom
brendandahl:embind-add-arg-policies

Conversation

@brendandahl
Copy link
Collaborator

This change adds support for using argument policies with val::set, val::operator(), val::call, val::new_, and the val constructor.

Previously, these methods used default behavior (usually copy) or required manual handling. Now policies like policy::take_ownership or policy::reference can be used directly to control how values are passed between C++ and JS.

See test/embind/test_val.cpp for usage examples.

Fixes #25412

This change adds support for using argument policies with val::set,
val::operator(), val::call, val::new_, and the val constructor.

Previously, these methods used default behavior (usually copy) or required
manual handling. Now policies like policy::take_ownership or
policy::reference can be used directly to control how values are passed
between C++ and JS.

See test/embind/test_val.cpp for usage examples.

Fixes emscripten-core#25412
@brendandahl
Copy link
Collaborator Author

Another idea I've been toying with is to rely more on the C++ semantics. i.e. values are moved if possible, otherwise they're copied. Pointers would be how you reference an object. The downside of that approach is it doesn't really signal whether JS should delete the object or it's managed by C++.

@stevenwdv
Copy link
Contributor

stevenwdv commented Feb 3, 2026

The downside of that approach is it doesn't really signal whether JS should delete the object or it's managed by C++.

I have a couple questions about this:

  1. If a value is moved (or constructed in-place), then there's no situation where C++ would delete the object, right? Since it doesn't have a reference to it anymore, it won't be able to.
  2. Currently, what does "signal" actually mean? What effect do argument / return value policies have except for regulating copies / moves? How is ownership indicated in the generated bindings? Only that calling .delete() from JS with a reference policy aborts?

@brendandahl
Copy link
Collaborator Author

  1. Yeah, the signal part is more about pointers flowing from C++ to JS (more below). For pointers, it not obvious who should be responsible for freeing the object.
  2. By signal, I mean "what should the developer should consider on the JS/C++ side on how to manage objects when they cross the boundary." We don't currently really enforce anything here, it's more a hint (we could do more here). The policies probably make more sense for the regular EMSCRIPTEN_BINDINGS where it's nice to look at the binding and see if the JS that uses an exposed API needs to clean up the returned values.

@stevenwdv
Copy link
Contributor

Thanks, that clarifies it more! Does that mean that for (non-pointer) rvalues move will become the default? (I hope so)

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.

Avoid copying rvalue object passed to Embind

2 participants