@@ -203,15 +203,6 @@ to enable the closure compiler.
203
203
Memory management
204
204
=================
205
205
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
-
215
206
The :js:func: `delete() ` JavaScript method is provided to manually signal that
216
207
a C++ object is no longer needed and can be deleted:
217
208
@@ -226,7 +217,8 @@ a C++ object is no longer needed and can be deleted:
226
217
y .delete ();
227
218
228
219
.. 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).
230
222
231
223
232
224
.. 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:
248
240
}
249
241
}
250
242
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
+
251
256
Cloning and Reference Counting
252
257
------------------------------
253
258
@@ -344,31 +349,96 @@ The JavaScript code does not need to worry about lifetime management.
344
349
Advanced class concepts
345
350
=======================
346
351
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
+
347
412
.. _embind-raw-pointers :
348
413
349
414
Raw pointers
350
415
------------
351
416
352
417
Because 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 `.
354
422
355
423
For example:
356
424
357
425
.. code :: cpp
358
426
359
427
class C {};
360
428
C* passThrough(C* ptr) { return ptr; }
429
+ C* createC() { return new C(); }
361
430
EMSCRIPTEN_BINDINGS(raw_pointers) {
362
431
class_<C>("C");
363
432
function("passThrough", &passThrough, allow_raw_pointers());
433
+ function("createC", &createC, return_value_policy::take_ownership());
364
434
}
365
435
366
436
.. note ::
367
437
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 .
372
442
373
443
.. _embind-external-constructors :
374
444
0 commit comments