@@ -69,7 +69,6 @@ struct CallbackInfo {
69
69
uint16_t argc;
70
70
napi_value* argv;
71
71
void * data;
72
- napi_value returnValue;
73
72
};
74
73
75
74
struct napi_env__ {
@@ -219,30 +218,9 @@ class ExternalCallback {
219
218
CallbackInfo cbInfo;
220
219
cbInfo.thisArg = reinterpret_cast <napi_value>(arguments[0 ]);
221
220
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
-
242
221
cbInfo.argc = argumentCount - 1 ;
243
222
cbInfo.argv = reinterpret_cast <napi_value*>(arguments + 1 );
244
223
cbInfo.data = externalCallback->_data ;
245
- cbInfo.returnValue = reinterpret_cast <napi_value>(undefinedValue);
246
224
247
225
napi_value result = externalCallback->_cb (
248
226
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) {
986
964
case JsError: *result = napi_object; break ;
987
965
988
966
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.)
992
967
bool hasExternalData;
993
968
if (JsHasExternalData (value, &hasExternalData) != JsNoError) {
994
969
hasExternalData = false ;
995
970
}
996
971
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;
1004
973
break ;
1005
974
}
1006
975
return napi_ok;
@@ -1385,17 +1354,47 @@ napi_status napi_wrap(napi_env env,
1385
1354
env, native_object, finalize_cb, finalize_hint);
1386
1355
if (externalData == nullptr ) return napi_set_last_error (napi_generic_failure);
1387
1356
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));
1389
1367
1390
1368
if (result != nullptr ) {
1391
- napi_create_reference (env, js_object, 0 , result);
1369
+ CHECK_NAPI ( napi_create_reference (env, js_object, 0 , result) );
1392
1370
}
1393
1371
1394
1372
return napi_ok;
1395
1373
}
1396
1374
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;
1399
1398
}
1400
1399
1401
1400
napi_status napi_create_external (napi_env env,
@@ -1413,7 +1412,6 @@ napi_status napi_create_external(napi_env env,
1413
1412
externalData,
1414
1413
jsrtimpl::ExternalData::Finalize,
1415
1414
reinterpret_cast <JsValueRef*>(result)));
1416
- CHECK_JSRT (JsPreventExtension (*reinterpret_cast <JsValueRef*>(result)));
1417
1415
1418
1416
return napi_ok;
1419
1417
}
0 commit comments