From 8ab8c33985b273cd682842a26091da53ce3c3048 Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Thu, 25 May 2017 17:05:21 -0700 Subject: [PATCH] n-api: enable napi_wrap() to work with any object Previously, napi_wrap() would only work with objects created from a constructor returned by napi_define_class(). While the N-API team was aware of this limitation, it was not clearly documented and is likely to cause confusion anyway. It's much simpler if addons are allowed to use any JS object. Also, the specific behavior of the limitation is difficult to reimplement on other VMs that work differently from V8. V8 requires object internal fields to be declared on the object prototype (which napi_define_class() used to do). Since it's too late to modify the object prototype by the time napi_wrap() is called, napi_wrap() now inserts a new object (with the internal field) into the supplied object's prototype chain. Then it can be retrieved from there later by napi_unwrap(). This change also includes improvements to the documentation for napi_create_external(), partly to explain how it is different from napi_wrap(). PR-URL: https://github.com/nodejs/node/pull/13250 Reviewed-By: Michael Dawson --- doc/api/n-api.md | 57 ++++++++----- src/node_api.cc | 42 ++++++---- test/addons-napi/test_object/test.js | 98 +++++++++++++++------- test/addons-napi/test_object/test_object.c | 27 ++++++ 4 files changed, 159 insertions(+), 65 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index d1fb432d7d..fe3786aaaf 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -1059,20 +1059,24 @@ napi_status napi_create_external(napi_env env, ``` - `[in] env`: The environment that the API is invoked under. -- `[in] data`: Raw pointer to the external data being wrapped. -- `[in] finalize_cb`: Optional callback to call when the wrapped object +- `[in] data`: Raw pointer to the external data. +- `[in] finalize_cb`: Optional callback to call when the external value is being collected. - `[in] finalize_hint`: Optional hint to pass to the finalize callback during collection. -- `[out] result`: A `napi_value` representing an external object. +- `[out] result`: A `napi_value` representing an external value. Returns `napi_ok` if the API succeeded. -This API allocates a JavaScript object with external data attached to it. -This is used to wrap native objects and project them into JavaScript. -The API allows the caller to pass in a finalize callback, in case the -underlying native resource needs to be cleaned up when the wrapper -JavaScript object gets collected. +This API allocates a JavaScript value with external data attached to it. This +is used to pass external data through JavaScript code, so it can be retrieved +later by native code. The API allows the caller to pass in a finalize callback, +in case the underlying native resource needs to be cleaned up when the external +JavaScript value gets collected. + +*Note*: The created value is not an object, and therefore does not support +additional properties. It is considered a distinct value type: calling +`napi_typeof()` with an external value yields `napi_external`. #### napi_create_external_arraybuffer