-
Notifications
You must be signed in to change notification settings - Fork 122
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
Support automatic heap-copies of temporary objects #113
Comments
…r_traits A wrapped function may return a wrapped C++ object, so we need to use appropriate converter specialization (e.g. `convert<std::shared_ptr<T>`) for such a wrapped class `T`. Reusing `call_from_v8_traits<F>::arg_converter<return_type, Traits>` meta-function to get the converter type in `forward_ret()` for the certain function result type. Extracted `call_from_v8_traits<F>::arg_converter<Arg, Traits>` to use a type instead of argument index. Added optional `Traits = raw_ptr_traits` template argument to `wrap_function()` and `wrap_function_template()` in order to allow `forward_function()` instantiation for the specified `Traits` Work in context of issue #113
Added `class_::auto_wrap_objects()` function to set an `auto_wrap_objects_` flag in the `object_registry` for a wrapped class. Added `class_::find_object(obj)` overloaded function for an object reference, to create a clone of the `obj` with `Traits::clone()` and to wrap the cloned object for the JavaScript side, if no such an instance was found. Added `clone(T const& src)` template function into `raw_ptr_traits, `shared_ptr_traits`, to create a copy of `src` with a copy constructor of class T. Using the added `class_::find_object(obj)` overloading in `convert<T>` specializations for a wrapped class T references, both for `raw_ptr_traits and `shared_ptr_traits`. Added a simple test case with a function returning an unwrapped C++ object, and accessing it from JavaScript. The returned objects shall be valid in JavaScript, since the `vpp8:class_.auto_wrap_objects(true)` for the test class.
Added `class_::auto_wrap_objects()` function to set an `auto_wrap_objects_` flag in the `object_registry` for a wrapped class. Added `class_::find_object(obj)` overloaded function for an object reference, to create a clone of the `obj` with `Traits::clone()` and to wrap the cloned object for the JavaScript side, if no such an instance was found. Added `clone(T const& src)` template function into `raw_ptr_traits, `shared_ptr_traits`, to create a copy of `src` with a copy constructor of class T. Using the added `class_::find_object(obj)` overloading in `convert<T>` specializations for a wrapped class T references, both for `raw_ptr_traits and `shared_ptr_traits`. Added a simple test case with a function returning an unwrapped C++ object, and accessing it from JavaScript. The returned objects shall be valid in JavaScript, since the `vpp8:class_.auto_wrap_objects(true)` for the test class.
Added `class_::auto_wrap_objects()` function to set an `auto_wrap_objects_` flag in the `object_registry` for a wrapped class. Added `class_::find_object(obj)` overloaded function for an object reference, to create a clone of the `obj` with `Traits::clone()` and to wrap the cloned object for the JavaScript side, if no such an instance was found. Added `clone(T const& src)` template function into `raw_ptr_traits, `shared_ptr_traits`, to create a copy of `src` with a copy constructor of class T. Using the added `class_::find_object(obj)` overloading in `convert<T>` specializations for a wrapped class T references, both for `raw_ptr_traits and `shared_ptr_traits`. Added a simple test case with a function returning an unwrapped C++ object, and accessing it from JavaScript. The returned objects shall be valid in JavaScript, since the `vpp8:class_.auto_wrap_objects(true)` for the test class.
Added `class_::auto_wrap_objects()` function to set an `auto_wrap_objects_` flag in the `object_registry` for a wrapped class. Added `class_::find_object(obj)` overloaded function for an object reference, to create a clone of the `obj` with `Traits::clone()` and to wrap the cloned object for the JavaScript side, if no such an instance was found. Added `clone(T const& src)` template function into `raw_ptr_traits, `shared_ptr_traits`, to create a copy of `src` with a copy constructor of class T. Using the added `class_::find_object(obj)` overloading in `convert<T>` specializations for a wrapped class T references, both for `raw_ptr_traits and `shared_ptr_traits`. Added a simple test case with a function returning an unwrapped C++ object, and accessing it from JavaScript. The returned objects shall be valid in JavaScript, since the `vpp8:class_.auto_wrap_objects(true)` for the test class.
Backported implementation of #113 Conflicts resolved: # v8pp/call_from_v8.hpp # v8pp/class.hpp # v8pp/function.hpp
Backported implementation of #113 Conflicts resolved: # v8pp/call_from_v8.hpp # v8pp/class.hpp # v8pp/function.hpp
...using it only in test_call_from_v8.cpp Refine in context of #113
Hi @tim-janik I've added Please see the This implementation has also been backported from Best regards, |
Thanks @pmed. One question, I was expecting auto_wrap_objects() to instantiate a template that calls the copy ctor. So that having a copy ctor only becomes a requirement for class_<> instances that call auto_wrap_objects() and not for others. Wouldn't the current implementation cause compiler errors when class_<> wraps a non-copyable type (e.g. a singleton) without calling auto_wrap_objects() ? As an aside, I've run into major stability problems with my v8pp-based electron module (likely due to Electron instead of v8pp). But since debugging in Electron is exceptionally hard, we're probably moving to a JSON+IPC solution instead of using a v8pp based module. Our Jsonipc binding has taken lots of inspiration from the v8pp API, thank you for a great design. Here's the function implementing automatic copying/wrapping behavior via template instantiation as suggested above: https://github.com/tim-janik/beast/blob/a48588c8d838fc008c2c0651aa67b9f43c5c1162/jsonipc/jsonipc.hh#L891 |
Hi @pmed.
After more than 2 years, I'm still dragging along an important v8pp patch for heap-allocated temporary objects in my fork (in fact it's the only reason I still need to keep my own fork).
See, I have a large number of auto generated C++ functions (from IDL), some of which return temporary objects, and a large number of corresponding auto generated
.set ("accessor", &ObjectType::accessor)
method registrations.I'd really like to find a way to upstream the possibility of automatically copying return values that are temporary objects onto the heap, so they can be passed on to V8. My patch essentially adds a one-liner to
convert<T>::to_v8()
, that doesimport_external (new Class (value))
.Since you didn't seem to like to take the patch in #39 (comment), I'm trying to find another way:
I need to avoid changing all my auto-generated C++ functions (or to manually sort them apart for ones that return a temporary class and those that don't).
I need to avoid changing hand-picked
.set ("accessor", &ObjectType::accessor)
statements. I could change all of them easily though, if that helped...So I'd like to have your feedback on what could work:
Would a variant of .set() be acceptable, e.g.
.xset ("accessor", &ObjectType::accessor)
where xset() works exactly like set() for all types but additionally copies temporary return values instead of just throwing "failed to wrap C++ object"?Or, would my patch be acceptable, if convert::to_v8() is special cased, so it only creates a heap copy if
std::is_copy_constructible<T>::value
or ifstd::is_move_constructible<T>::value
?Or, since you mentioned in Question: function that returns object by value #39 that you wanted some explicit user involvement to enable the copies, would a define like V8PP_AUTO_COPY_TEMPORARIES (defaulting to false) help to accept and activate the patch?
Are there any other ways I'm missing?
Here's the latest version of my patch (against v1.6.0): tim-janik@f272053
Here's the original patch (against v1.4.1): tim-janik@cda26b6
PS: FWIW, I'd consider #39 essentially answered and closable. This issue in contrast is about actually merging functionality that seems to be useful to several downstream projects.
The text was updated successfully, but these errors were encountered: