@@ -1184,192 +1184,6 @@ BOOL CustomExternalWrapperObject::DeleteProperty(Js::JavascriptString *propertyN
11841184 return TRUE ;
11851185}
11861186
1187- Js::JavascriptArray * CustomExternalWrapperObject::PropertyKeysTrap (KeysTrapKind keysTrapKind, Js::ScriptContext * requestContext)
1188- {
1189- PROBE_STACK (GetScriptContext (), Js::Constants::MinStackDefault);
1190-
1191- // Reject implicit call
1192- ThreadContext* threadContext = requestContext->GetThreadContext ();
1193- if (threadContext->IsDisableImplicitCall ())
1194- {
1195- threadContext->AddImplicitCallFlags (Js::ImplicitCall_External);
1196- return nullptr ;
1197- }
1198-
1199- if (!this ->EnsureInitialized (requestContext))
1200- {
1201- return nullptr ;
1202- }
1203-
1204- Js::RecyclableObject * targetObj = this ;
1205- CustomExternalWrapperType * type = this ->GetExternalType ();
1206- Js::JavascriptFunction* ownKeysMethod = nullptr ;
1207- if (type->GetJsGetterSetterInterceptor ()->ownKeysTrap != nullptr )
1208- {
1209- ownKeysMethod = Js::VarTo<JavascriptFunction>(type->GetJsGetterSetterInterceptor ()->ownKeysTrap );
1210- }
1211-
1212- Assert (!GetScriptContext ()->IsHeapEnumInProgress ());
1213-
1214- if (nullptr == ownKeysMethod)
1215- {
1216- switch (keysTrapKind)
1217- {
1218- case KeysTrapKind::GetOwnPropertyNamesKind:
1219- return JavascriptObject::CreateOwnStringPropertiesHelper (this , requestContext);
1220- case KeysTrapKind::GetOwnPropertySymbolKind:
1221- return JavascriptObject::CreateOwnSymbolPropertiesHelper (this , requestContext);
1222- case KeysTrapKind::KeysKind:
1223- return JavascriptObject::CreateOwnStringSymbolPropertiesHelper (this , requestContext);
1224- case KeysTrapKind::GetOwnEnumerablePropertyNamesKind:
1225- return JavascriptObject::CreateOwnEnumerableStringPropertiesHelper (this , requestContext);
1226- case KeysTrapKind::EnumerableKeysKind:
1227- return JavascriptObject::CreateOwnEnumerableStringSymbolPropertiesHelper (this , requestContext);
1228- default :
1229- Assume (UNREACHED);
1230- }
1231- }
1232-
1233- Js::Var ownKeysResult = threadContext->ExecuteImplicitCall (ownKeysMethod, Js::ImplicitCall_Accessor, [=]()->Js ::Var
1234- {
1235- return CALL_FUNCTION (threadContext, ownKeysMethod, Js::CallInfo (Js::CallFlags_Value, 1 ), targetObj);
1236- });
1237-
1238- if (!Js::JavascriptOperators::IsObject (ownKeysResult))
1239- {
1240- Js::JavascriptError::ThrowTypeError (requestContext, JSERR_InconsistentTrapResult, _u (" ownKeys" ));
1241- }
1242-
1243- Js::RecyclableObject* trapResultArray = Js::VarTo<RecyclableObject>(ownKeysResult);
1244- Js::JavascriptArray* trapResult = requestContext->GetLibrary ()->CreateArray (0 );
1245- bool isConfigurableKeyMissingFromTrapResult = false ;
1246- bool isNonconfigurableKeyMissingFromTrapResult = false ;
1247- bool isKeyMissingFromTrapResult = false ;
1248- bool isKeyMissingFromTargetResult = false ;
1249- bool isAnyNonconfigurableKeyPresent = false ;
1250- Js::Var element;
1251- Js::PropertyId propertyId;
1252- const Js::PropertyRecord* propertyRecord = nullptr ;
1253- BOOL isTargetExtensible = FALSE ;
1254-
1255- BEGIN_TEMP_ALLOCATOR (tempAllocator, requestContext, _u (" Runtime" ))
1256- {
1257- // Dictionary containing intersection of keys present in targetKeys and trapResult
1258- Js::Var lenValue = Js::JavascriptOperators::OP_GetLength (trapResultArray, requestContext);
1259- uint32 len = (uint32)Js::JavascriptConversion::ToLength (lenValue, requestContext);
1260- JsUtil::BaseDictionary<Js::PropertyId, bool , Memory::ArenaAllocator> targetToTrapResultMap (tempAllocator, len);
1261-
1262- // Trap result to return.
1263- // Note : This will not necessarily have all elements present in trapResultArray. E.g. If trap was called from GetOwnPropertySymbols()
1264- // trapResult will only contain symbol elements from trapResultArray.
1265- switch (keysTrapKind)
1266- {
1267- case GetOwnPropertyNamesKind:
1268- case KeysTrapKind::GetOwnEnumerablePropertyNamesKind:
1269- GetOwnPropertyKeysHelper (requestContext, trapResultArray, len, trapResult, targetToTrapResultMap,
1270- [&](const Js::PropertyRecord *propertyRecord)->bool
1271- {
1272- return !propertyRecord->IsSymbol ();
1273- });
1274- break ;
1275- case GetOwnPropertySymbolKind:
1276- GetOwnPropertyKeysHelper (requestContext, trapResultArray, len, trapResult, targetToTrapResultMap,
1277- [&](const Js::PropertyRecord *propertyRecord)->bool
1278- {
1279- return propertyRecord->IsSymbol ();
1280- });
1281- break ;
1282- case KeysKind:
1283- case EnumerableKeysKind:
1284- GetOwnPropertyKeysHelper (requestContext, trapResultArray, len, trapResult, targetToTrapResultMap,
1285- [&](const Js::PropertyRecord *propertyRecord)->bool
1286- {
1287- return true ;
1288- });
1289- break ;
1290- }
1291-
1292- isTargetExtensible = targetObj->IsExtensible ();
1293- Js::JavascriptArray * targetKeys = Js::JavascriptOperators::GetOwnPropertyKeys (targetObj, requestContext);
1294-
1295- for (uint32 i = 0 ; i < targetKeys->GetLength (); i++)
1296- {
1297- element = targetKeys->DirectGetItem (i);
1298- AssertMsg (Js::VarIs<JavascriptSymbol>(element) || Js::VarIs<JavascriptString>(element), " Invariant check during ownKeys wrapper trap should make sure we only get property key here. (symbol or string primitives)" );
1299- Js::JavascriptConversion::ToPropertyKey (element, requestContext, &propertyRecord, nullptr );
1300- propertyId = propertyRecord->GetPropertyId ();
1301-
1302- if (propertyId == Js::Constants::NoProperty)
1303- continue ;
1304-
1305- // If not present in intersection means either the property is not present in targetKeys or
1306- // we have already visited the property in targetKeys
1307- if (targetToTrapResultMap.ContainsKey (propertyId))
1308- {
1309- isKeyMissingFromTrapResult = false ;
1310- targetToTrapResultMap.Remove (propertyId);
1311- }
1312- else
1313- {
1314- isKeyMissingFromTrapResult = true ;
1315- }
1316-
1317- Js::PropertyDescriptor targetKeyPropertyDescriptor;
1318- if (Js::JavascriptOperators::GetOwnPropertyDescriptor (targetObj, propertyId, requestContext, &targetKeyPropertyDescriptor) && !targetKeyPropertyDescriptor.IsConfigurable ())
1319- {
1320- isAnyNonconfigurableKeyPresent = true ;
1321- if (isKeyMissingFromTrapResult)
1322- {
1323- isNonconfigurableKeyMissingFromTrapResult = true ;
1324- }
1325- }
1326- else
1327- {
1328- if (isKeyMissingFromTrapResult)
1329- {
1330- isConfigurableKeyMissingFromTrapResult = true ;
1331- }
1332- }
1333- }
1334- // Keys that were not found in targetKeys will continue to remain in the map
1335- isKeyMissingFromTargetResult = targetToTrapResultMap.Count () != 0 ;
1336- }
1337- END_TEMP_ALLOCATOR (tempAllocator, requestContext)
1338-
1339-
1340- // 19.
1341- if (isTargetExtensible && !isAnyNonconfigurableKeyPresent)
1342- {
1343- return trapResult;
1344- }
1345-
1346- // 21.
1347- if (isNonconfigurableKeyMissingFromTrapResult)
1348- {
1349- Js::JavascriptError::ThrowTypeError (requestContext, JSERR_InconsistentTrapResult, _u (" ownKeys" ));
1350- }
1351-
1352- // 22.
1353- if (isTargetExtensible)
1354- {
1355- return trapResult;
1356- }
1357-
1358- // 23.
1359- if (isConfigurableKeyMissingFromTrapResult)
1360- {
1361- Js::JavascriptError::ThrowTypeError (requestContext, JSERR_InconsistentTrapResult, _u (" ownKeys" ));
1362- }
1363-
1364- // 24.
1365- if (isKeyMissingFromTargetResult)
1366- {
1367- Js::JavascriptError::ThrowTypeError (requestContext, JSERR_InconsistentTrapResult, _u (" ownKeys" ));
1368- }
1369-
1370- return trapResult;
1371- }
1372-
13731187#if ENABLE_TTD
13741188TTD::NSSnapObjects::SnapObjectType CustomExternalWrapperObject::GetSnapTag_TTD () const
13751189{
0 commit comments