@@ -90,23 +90,69 @@ v8::Local<v8::Value> V8LocalValueFromJsValue(napi_value v) {
9090 return local;
9191}
9292
93+ // Adapter for napi_finalize callbacks.
94+ class Finalizer {
95+ protected:
96+ Finalizer (v8::Isolate* isolate,
97+ napi_finalize finalize_callback,
98+ void * finalize_data,
99+ void * finalize_hint)
100+ : _isolate(isolate),
101+ _finalize_callback (finalize_callback),
102+ _finalize_data(finalize_data),
103+ _finalize_hint(finalize_hint) {
104+ }
105+
106+ ~Finalizer () {
107+ }
108+
109+ public:
110+ static Finalizer* New (v8::Isolate* isolate,
111+ napi_finalize finalize_callback = nullptr ,
112+ void * finalize_data = nullptr ,
113+ void * finalize_hint = nullptr ) {
114+ return new Finalizer (
115+ isolate, finalize_callback, finalize_data, finalize_hint);
116+ }
117+
118+ static void Delete (Finalizer* finalizer) {
119+ delete finalizer;
120+ }
121+
122+ // node::Buffer::FreeCallback
123+ static void FinalizeBufferCallback (char * data, void * hint) {
124+ Finalizer* finalizer = static_cast <Finalizer*>(hint);
125+ if (finalizer->_finalize_callback != nullptr ) {
126+ finalizer->_finalize_callback (
127+ v8impl::JsEnvFromV8Isolate (finalizer->_isolate ),
128+ data,
129+ finalizer->_finalize_hint );
130+ }
131+
132+ Delete (finalizer);
133+ }
134+
135+ protected:
136+ v8::Isolate* _isolate;
137+ napi_finalize _finalize_callback;
138+ void * _finalize_data;
139+ void * _finalize_hint;
140+ };
141+
93142// Wrapper around v8::Persistent that implements reference counting.
94- class Reference {
143+ class Reference : private Finalizer {
95144 private:
96145 Reference (v8::Isolate* isolate,
97146 v8::Local<v8::Value> value,
98147 int initial_refcount,
99148 bool delete_self,
100- napi_finalize finalize_callback = nullptr ,
101- void * finalize_data = nullptr ,
102- void * finalize_hint = nullptr )
103- : _isolate (isolate),
149+ napi_finalize finalize_callback,
150+ void * finalize_data,
151+ void * finalize_hint)
152+ : Finalizer (isolate, finalize_callback, finalize_data, finalize_hint ),
104153 _persistent (isolate, value),
105154 _refcount(initial_refcount),
106- _delete_self(delete_self),
107- _finalize_callback(finalize_callback),
108- _finalize_data(finalize_data),
109- _finalize_hint(finalize_hint) {
155+ _delete_self(delete_self) {
110156 if (initial_refcount == 0 ) {
111157 _persistent.SetWeak (
112158 this , FinalizeCallback, v8::WeakCallbackType::kParameter );
@@ -181,7 +227,9 @@ class Reference {
181227 bool delete_self = reference->_delete_self ;
182228
183229 if (reference->_finalize_callback != nullptr ) {
184- reference->_finalize_callback (reference->_finalize_data ,
230+ reference->_finalize_callback (
231+ v8impl::JsEnvFromV8Isolate (reference->_isolate ),
232+ reference->_finalize_data ,
185233 reference->_finalize_hint );
186234 }
187235
@@ -190,13 +238,9 @@ class Reference {
190238 }
191239 }
192240
193- v8::Isolate* _isolate;
194241 v8::Persistent<v8::Value> _persistent;
195242 int _refcount;
196243 bool _delete_self;
197- napi_finalize _finalize_callback;
198- void * _finalize_data;
199- void * _finalize_hint;
200244};
201245
202246class TryCatch : public v8 ::TryCatch {
@@ -419,7 +463,7 @@ v8::Local<v8::Object> CreateFunctionCallbackData(napi_env env,
419463 v8::External::New (isolate, reinterpret_cast <void *>(cb)));
420464 cbdata->SetInternalField (
421465 v8impl::kDataIndex ,
422- v8::External::New (isolate, reinterpret_cast < void *>( data) ));
466+ v8::External::New (isolate, data));
423467 return cbdata;
424468}
425469
@@ -451,7 +495,7 @@ v8::Local<v8::Object> CreateAccessorCallbackData(napi_env env,
451495
452496 cbdata->SetInternalField (
453497 v8impl::kDataIndex ,
454- v8::External::New (isolate, reinterpret_cast < void *>( data) ));
498+ v8::External::New (isolate, data));
455499 return cbdata;
456500}
457501
@@ -1011,9 +1055,7 @@ napi_status napi_define_properties(napi_env env,
10111055 auto define_maybe =
10121056 obj->DefineOwnProperty (context, name, t->GetFunction (), attributes);
10131057
1014- // IsNothing seems like a serious failure,
1015- // should we return a different error code if the define failed?
1016- if (define_maybe.IsNothing () || !define_maybe.FromMaybe (false )) {
1058+ if (!define_maybe.FromMaybe (false )) {
10171059 return napi_set_last_error (napi_generic_failure);
10181060 }
10191061 } else if (p->getter || p->setter ) {
@@ -1422,7 +1464,6 @@ napi_status napi_call_function(napi_env env,
14221464 const napi_value* argv,
14231465 napi_value* result) {
14241466 NAPI_PREAMBLE (env);
1425- CHECK_ARG (result);
14261467
14271468 v8::Isolate* isolate = v8impl::V8IsolateFromJsEnv (env);
14281469 v8::Local<v8::Context> context = isolate->GetCurrentContext ();
@@ -1439,8 +1480,10 @@ napi_status napi_call_function(napi_env env,
14391480 if (try_catch.HasCaught ()) {
14401481 return napi_set_last_error (napi_pending_exception);
14411482 } else {
1442- CHECK_MAYBE_EMPTY (maybe, napi_generic_failure);
1443- *result = v8impl::JsValueFromV8LocalValue (maybe.ToLocalChecked ());
1483+ if (result != nullptr ) {
1484+ CHECK_MAYBE_EMPTY (maybe, napi_generic_failure);
1485+ *result = v8impl::JsValueFromV8LocalValue (maybe.ToLocalChecked ());
1486+ }
14441487 return napi_ok;
14451488 }
14461489}
@@ -1773,7 +1816,7 @@ napi_status napi_wrap(napi_env env,
17731816 // via napi_define_class() can be (un)wrapped.
17741817 RETURN_STATUS_IF_FALSE (obj->InternalFieldCount () > 0 , napi_invalid_arg);
17751818
1776- obj->SetAlignedPointerInInternalField (0 , native_object);
1819+ obj->SetInternalField (0 , v8::External::New (isolate, native_object) );
17771820
17781821 if (result != nullptr ) {
17791822 // The returned reference should be deleted via napi_delete_reference()
@@ -1807,7 +1850,7 @@ napi_status napi_unwrap(napi_env env, napi_value js_object, void** result) {
18071850 // via napi_define_class() can be (un)wrapped.
18081851 RETURN_STATUS_IF_FALSE (obj->InternalFieldCount () > 0 , napi_invalid_arg);
18091852
1810- *result = obj->GetAlignedPointerFromInternalField ( 0 );
1853+ *result = v8::Local<v8::External>:: Cast ( obj->GetInternalField ( 0 ))-> Value ( );
18111854
18121855 return napi_ok;
18131856}
@@ -2124,17 +2167,20 @@ napi_status napi_make_callback(napi_env env,
21242167 const napi_value* argv,
21252168 napi_value* result) {
21262169 NAPI_PREAMBLE (env);
2127- CHECK_ARG (result);
21282170
21292171 v8::Isolate* isolate = v8impl::V8IsolateFromJsEnv (env);
21302172 v8::Local<v8::Object> v8recv =
21312173 v8impl::V8LocalValueFromJsValue (recv).As <v8::Object>();
21322174 v8::Local<v8::Function> v8func =
21332175 v8impl::V8LocalValueFromJsValue (func).As <v8::Function>();
21342176
2135- *result = v8impl::JsValueFromV8LocalValue (
2136- node::MakeCallback (isolate, v8recv, v8func, argc,
2137- reinterpret_cast <v8::Local<v8::Value>*>(const_cast <napi_value*>(argv))));
2177+ v8::Local<v8::Value> callback_result = node::MakeCallback (
2178+ isolate, v8recv, v8func, argc,
2179+ reinterpret_cast <v8::Local<v8::Value>*>(const_cast <napi_value*>(argv)));
2180+
2181+ if (result != nullptr ) {
2182+ *result = v8impl::JsValueFromV8LocalValue (callback_result);
2183+ }
21382184
21392185 return GET_RETURN_STATUS ();
21402186}
@@ -2199,11 +2245,17 @@ napi_status napi_create_external_buffer(napi_env env,
21992245 NAPI_PREAMBLE (env);
22002246 CHECK_ARG (result);
22012247
2202- auto maybe = node::Buffer::New (v8impl::V8IsolateFromJsEnv (env),
2248+ v8::Isolate* isolate = v8impl::V8IsolateFromJsEnv (env);
2249+
2250+ // The finalizer object will delete itself after invoking the callback.
2251+ v8impl::Finalizer* finalizer = v8impl::Finalizer::New (
2252+ isolate, finalize_cb, nullptr , finalize_hint);
2253+
2254+ auto maybe = node::Buffer::New (isolate,
22032255 static_cast <char *>(data),
22042256 length,
2205- (node::Buffer::FreeCallback)finalize_cb ,
2206- finalize_hint );
2257+ v8impl::Finalizer::FinalizeBufferCallback ,
2258+ finalizer );
22072259
22082260 CHECK_MAYBE_EMPTY (maybe, napi_generic_failure);
22092261
0 commit comments