Skip to content

n-api: enable napi_wrap() to work with any object

Rodrigo Muino Tomonari requested to merge github/fork/jasongin/napi-wrap into master

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. (ChakraCore doesn't have ObjectPrototypes or object internal fields.)

I encountered this problem when testing the N-API port of node-sass: it worked on V8, but failed on Node-ChakraCore, because it used napi_wrap() in a slightly different way from our existing unit tests and other examples. I also submitted a corresponding PR to Node-ChakraCore to update the napi_wrap() implementation there to similarly allow any object. (So then the test case added here will pass there.)

Regarding the updated napi_wrap() implementation: 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().

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

n-api

Merge request reports

Loading