@@ -69,7 +69,6 @@ struct CallbackInfo {
6969 uint16_t argc;
7070 napi_value* argv;
7171 void * data;
72- napi_value returnValue;
7372};
7473
7574struct napi_env__ {
@@ -219,30 +218,9 @@ class ExternalCallback {
219218 CallbackInfo cbInfo;
220219 cbInfo.thisArg = reinterpret_cast <napi_value>(arguments[0 ]);
221220 cbInfo.isConstructCall = isConstructCall;
222-
223- if (isConstructCall) {
224- // For constructor callbacks, replace the 'this' arg with a new external
225- // object, to support wrapping a native object in the external object.
226- JsValueRef externalThis;
227- if (JsNoError == JsCreateExternalObject (
228- nullptr , jsrtimpl::ExternalData::Finalize, &externalThis)) {
229- // Copy the prototype from the default 'this' arg to the new
230- // 'external' this arg.
231- if (arguments[0 ] != nullptr ) {
232- JsValueRef thisPrototype;
233- if (JsNoError == JsGetPrototype (arguments[0 ], &thisPrototype)) {
234- JsSetPrototype (externalThis, thisPrototype);
235- }
236- }
237-
238- cbInfo.thisArg = reinterpret_cast <napi_value>(externalThis);
239- }
240- }
241-
242221 cbInfo.argc = argumentCount - 1 ;
243222 cbInfo.argv = reinterpret_cast <napi_value*>(arguments + 1 );
244223 cbInfo.data = externalCallback->_data ;
245- cbInfo.returnValue = reinterpret_cast <napi_value>(undefinedValue);
246224
247225 napi_value result = externalCallback->_cb (
248226 externalCallback->_env , reinterpret_cast <napi_callback_info>(&cbInfo));
@@ -986,21 +964,12 @@ napi_status napi_typeof(napi_env env, napi_value vv, napi_valuetype* result) {
986964 case JsError: *result = napi_object; break ;
987965
988966 default :
989- // An "external" value is represented in JSRT as an Object that has
990- // external data and DOES NOT allow extensions. (A wrapped object has
991- // external data and DOES allow extensions.)
992967 bool hasExternalData;
993968 if (JsHasExternalData (value, &hasExternalData) != JsNoError) {
994969 hasExternalData = false ;
995970 }
996971
997- bool isExtensionAllowed;
998- if (JsGetExtensionAllowed (value, &isExtensionAllowed) != JsNoError) {
999- isExtensionAllowed = false ;
1000- }
1001-
1002- *result =
1003- (hasExternalData && !isExtensionAllowed) ? napi_external : napi_object;
972+ *result = hasExternalData ? napi_external : napi_object;
1004973 break ;
1005974 }
1006975 return napi_ok;
@@ -1385,17 +1354,47 @@ napi_status napi_wrap(napi_env env,
13851354 env, native_object, finalize_cb, finalize_hint);
13861355 if (externalData == nullptr ) return napi_set_last_error (napi_generic_failure);
13871356
1388- CHECK_JSRT (JsSetExternalData (value, externalData));
1357+ // Create an external object that will hold the external data pointer.
1358+ JsValueRef external;
1359+ CHECK_JSRT (JsCreateExternalObject (
1360+ externalData, jsrtimpl::ExternalData::Finalize, &external));
1361+
1362+ // Insert the external object into the value's prototype chain.
1363+ JsValueRef valuePrototype;
1364+ CHECK_JSRT (JsGetPrototype (value, &valuePrototype));
1365+ CHECK_JSRT (JsSetPrototype (external, valuePrototype));
1366+ CHECK_JSRT (JsSetPrototype (value, external));
13891367
13901368 if (result != nullptr ) {
1391- napi_create_reference (env, js_object, 0 , result);
1369+ CHECK_NAPI ( napi_create_reference (env, js_object, 0 , result) );
13921370 }
13931371
13941372 return napi_ok;
13951373}
13961374
1397- napi_status napi_unwrap (napi_env env, napi_value jsObject, void ** result) {
1398- return napi_get_value_external (env, jsObject, result);
1375+ napi_status napi_unwrap (napi_env env, napi_value js_object, void ** result) {
1376+ JsValueRef value = reinterpret_cast <JsValueRef>(js_object);
1377+
1378+ // Search the object's prototype chain for the wrapper with external data.
1379+ // Usually the wrapper would be the first in the chain, but it is OK for
1380+ // other objects to be inserted in the prototype chain.
1381+ JsValueRef wrapper = value;
1382+ bool hasExternalData = false ;
1383+ do {
1384+ CHECK_JSRT (JsGetPrototype (wrapper, &wrapper));
1385+ if (wrapper == JS_INVALID_REFERENCE) {
1386+ return napi_invalid_arg;
1387+ }
1388+ CHECK_JSRT (JsHasExternalData (wrapper, &hasExternalData));
1389+ } while (!hasExternalData);
1390+
1391+ jsrtimpl::ExternalData* externalData;
1392+ CHECK_JSRT (JsGetExternalData (
1393+ wrapper, reinterpret_cast <void **>(&externalData)));
1394+
1395+ *result = (externalData != nullptr ? externalData->Data () : nullptr );
1396+
1397+ return napi_ok;
13991398}
14001399
14011400napi_status napi_create_external (napi_env env,
@@ -1413,7 +1412,6 @@ napi_status napi_create_external(napi_env env,
14131412 externalData,
14141413 jsrtimpl::ExternalData::Finalize,
14151414 reinterpret_cast <JsValueRef*>(result)));
1416- CHECK_JSRT (JsPreventExtension (*reinterpret_cast <JsValueRef*>(result)));
14171415
14181416 return napi_ok;
14191417}
0 commit comments