@@ -203,15 +203,6 @@ to enable the closure compiler.
203203Memory management
204204=================
205205
206- JavaScript only gained support for `finalizers `_ in ECMAScript 2021, or ECMA-262
207- Edition 12. The new API is called `FinalizationRegistry `_ and it still does not
208- offer any guarantees that the provided finalization callback will be called.
209- Embind uses this for cleanup if available, but only for smart pointers,
210- and only as a last resort.
211-
212- .. warning :: It is strongly recommended that JavaScript code explicitly deletes
213- any C++ object handles it has received.
214-
215206The :js:func: `delete() ` JavaScript method is provided to manually signal that
216207a C++ object is no longer needed and can be deleted:
217208
@@ -226,7 +217,8 @@ a C++ object is no longer needed and can be deleted:
226217 y .delete ();
227218
228219 .. note :: Both C++ objects constructed from the JavaScript side as well as
229- those returned from C++ methods must be explicitly deleted.
220+ those returned from C++ methods must be explicitly deleted, unless a
221+ ``reference `` return value policy is used (see below).
230222
231223
232224.. tip :: The ``try`` … ``finally`` JavaScript construct can be used to guarantee
@@ -248,6 +240,19 @@ a C++ object is no longer needed and can be deleted:
248240 }
249241 }
250242
243+ Automatic memory management
244+ ---------------------------
245+
246+ JavaScript only gained support for `finalizers `_ in ECMAScript 2021, or ECMA-262
247+ Edition 12. The new API is called `FinalizationRegistry `_ and it still does not
248+ offer any guarantees that the provided finalization callback will be called.
249+ Embind uses this for cleanup if available, but only for smart pointers,
250+ and only as a last resort.
251+
252+ .. warning :: It is strongly recommended that JavaScript code explicitly deletes
253+ any C++ object handles it has received.
254+
255+
251256Cloning and Reference Counting
252257------------------------------
253258
@@ -344,31 +349,96 @@ The JavaScript code does not need to worry about lifetime management.
344349 Advanced class concepts
345350=======================
346351
352+ .. _embind-object-ownership :
353+
354+ Object Ownership
355+ ----------------
356+
357+ JavaScript and C++ have very different memory models which can lead to it being
358+ unclear which language owns and is responsible for deleting an object when it
359+ moves between languages. To make object ownership more explicit, *embind *
360+ supports smart pointers and return value policies. Return value
361+ polices dictate what happens to a C++ object when it is returned to JavaScript.
362+
363+ To use a return value policy, pass the desired policy into function or method
364+ bindings. For example:
365+
366+ .. code :: cpp
367+
368+ EMSCRIPTEN_BINDINGS(module) {
369+ function("createData", &createData, return_value_policy::take_ownership());
370+ }
371+
372+ Embind supports three return value policies that behave differently depending
373+ on the return type of the function. The policies work as follows:
374+
375+ * *default (no argument) * - For return by value and reference a new object will be allocated using the
376+ object's copy constructor. JS then owns the object and is responsible for deleting it. Returning a
377+ pointer is not allowed by default (use an explicit policy below).
378+ * :cpp:type: `return_value_policy::take_ownership ` - Ownership is transferred to JS.
379+ * :cpp:type: `return_value_policy::reference ` - Reference an existing object but do not take
380+ ownership. Care must be taken to not delete the object while it is still in use in JS.
381+
382+ More details below:
383+
384+ +--------------------+-------------+---------------------------------------------------------------+
385+ | Return Type | Constructor | Cleanup |
386+ +====================+=============+===============================================================+
387+ | **default ** |
388+ +--------------------+-------------+---------------------------------------------------------------+
389+ | Value (``T ``) | copy | JS must delete the copied object. |
390+ +--------------------+-------------+---------------------------------------------------------------+
391+ | Reference (``T& ``) | copy | JS must delete the copied object. |
392+ +--------------------+-------------+---------------------------------------------------------------+
393+ | Pointer (``T* ``) | n/a | Pointers must explicitly use a return policy. |
394+ +--------------------+-------------+---------------------------------------------------------------+
395+ | **take_ownership ** |
396+ +--------------------+-------------+---------------------------------------------------------------+
397+ | Value (``T ``) | move | JS must delete the moved object. |
398+ +--------------------+-------------+---------------------------------------------------------------+
399+ | Reference (``T& ``) | move | JS must delete the moved object. |
400+ +--------------------+-------------+---------------------------------------------------------------+
401+ | Pointer (``T* ``) | none | JS must delete the object. |
402+ +--------------------+-------------+---------------------------------------------------------------+
403+ | **reference ** |
404+ +--------------------+-------------+---------------------------------------------------------------+
405+ | Value (``T ``) | n/a | Reference to a value is not allowed. |
406+ +--------------------+-------------+---------------------------------------------------------------+
407+ | Reference (``T& ``) | none | C++ must delete the object. |
408+ +--------------------+-------------+---------------------------------------------------------------+
409+ | Pointer (``T* ``) | none | C++ must delete the object. |
410+ +--------------------+-------------+---------------------------------------------------------------+
411+
347412.. _embind-raw-pointers :
348413
349414Raw pointers
350415------------
351416
352417Because raw pointers have unclear lifetime semantics, *embind * requires
353- their use to be marked with :cpp:type: `allow_raw_pointers `.
418+ their use to be marked with either :cpp:type: `allow_raw_pointers ` or with a
419+ :cpp:type: `return_value_policy `. If the function returns a pointer it is
420+ recommended to use a :cpp:type: `return_value_policy ` instead of the general
421+ :cpp:type: `allow_raw_pointers `.
354422
355423For example:
356424
357425.. code :: cpp
358426
359427 class C {};
360428 C* passThrough(C* ptr) { return ptr; }
429+ C* createC() { return new C(); }
361430 EMSCRIPTEN_BINDINGS(raw_pointers) {
362431 class_<C>("C");
363432 function("passThrough", &passThrough, allow_raw_pointers());
433+ function("createC", &createC, return_value_policy::take_ownership());
364434 }
365435
366436 .. note ::
367437
368- Currently the markup serves only to allow raw pointer use, and
369- show that you've thought about the use of the raw pointers. Eventually
370- we hope to implement `Boost.Python-like raw pointer policies `_ for
371- managing object ownership.
438+ Currently allow_raw_pointers for pointer arguments only serves to allow raw
439+ pointer use, and show that you've thought about the use of the raw pointers.
440+ Eventually we hope to implement `Boost.Python-like raw pointer policies `_ for
441+ managing object ownership of arguments as well .
372442
373443.. _embind-external-constructors :
374444
0 commit comments