@@ -892,74 +892,48 @@ namespace Js
892892 if (!threadContext->RecordImplicitException ())
893893 return FALSE ;
894894 JavascriptError::ThrowTypeError (GetScriptContext (), JSERR_ErrorOnRevokedProxy, _u (" ownKeys" ));
895- }
896-
897- // going through for-in spec
898- JavascriptFunction* getEnumeratorMethod = GetMethodHelper (PropertyIds::ownKeys, scriptContext);
899- Assert (!GetScriptContext ()->IsHeapEnumInProgress ());
900- if (nullptr == getEnumeratorMethod)
901- {
902- return target->GetEnumerator (enumNonEnumerable, enumerator, requestContext, preferSnapshotSemantics, enumSymbols);
903- }
904-
905- CallInfo callInfo (CallFlags_Value, 2 );
906- Var varArgs[2 ];
907- Js::Arguments arguments (callInfo, varArgs);
908- varArgs[0 ] = handler;
909- varArgs[1 ] = target;
910-
911- Js::ImplicitCallFlags saveImplicitCallFlags = threadContext->GetImplicitCallFlags ();
912- Var trapResult = getEnumeratorMethod->CallFunction (arguments);
913- threadContext->SetImplicitCallFlags ((Js::ImplicitCallFlags)(saveImplicitCallFlags | ImplicitCall_Accessor));
914-
915- if (!JavascriptOperators::IsArray (trapResult))
916- {
917- JavascriptError::ThrowTypeError (scriptContext, JSERR_InconsistentTrapResult, _u (" ownKeys" ));
918- }
919-
895+ }
896+
897+ Var enmeratorObj;
898+ Var propertyName = nullptr ;
899+ PropertyId propertyId;
900+ int index = 0 ;
920901 JsUtil::BaseDictionary<const char16*, Var, Recycler> dict (scriptContext->GetRecycler ());
921902 JavascriptArray* arrResult = scriptContext->GetLibrary ()->CreateArray ();
922- int index = 0 ;
923903
924- Js::RecyclableObject* arrayIterator = JavascriptOperators::GetIterator (RecyclableObject::FromVar (trapResult), scriptContext);
925- Js::RecyclableObject* next = JavascriptOperators::IteratorNext (arrayIterator, scriptContext);
926-
927- while (RecyclableObject::Is (next))
928- {
929- if (Js::JavascriptOperators::HasProperty (next, PropertyIds::value))
904+ // 13.7.5.15EnumerateObjectProperties(O)#
905+ // for (let key of Reflect.ownKeys(obj)) {
906+ Var trapResult = JavascriptOperators::GetOwnPropertyNames (this , scriptContext);
907+ Assert (JavascriptArray::Is (trapResult));
908+ ((JavascriptArray*)trapResult)->GetEnumerator (false , &enmeratorObj, scriptContext);
909+ JavascriptEnumerator* pEnumerator = JavascriptEnumerator::FromVar (enmeratorObj);
910+ while ((propertyName = pEnumerator->GetCurrentAndMoveNext (propertyId)) != NULL )
911+ {
912+ PropertyId propId = JavascriptOperators::GetPropertyId (propertyName, scriptContext);
913+ Var prop = JavascriptOperators::GetProperty (RecyclableObject::FromVar (trapResult), propId, scriptContext);
914+ // if (typeof key === "string") {
915+ if (JavascriptString::Is (prop))
930916 {
931- Js::Var element = JavascriptOperators::GetProperty (next, PropertyIds::value, scriptContext);
932- if (JavascriptString::Is (element))
917+ Js::PropertyDescriptor desc;
918+ JavascriptString* str = JavascriptString::FromVar (prop);
919+ // let desc = Reflect.getOwnPropertyDescriptor(obj, key);
920+ BOOL ret = JavascriptOperators::GetOwnPropertyDescriptor (this , str, scriptContext, &desc);
921+ // if (desc && !visited.has(key)) {
922+ if (ret && !dict.ContainsKey (str->GetSz ()))
933923 {
934- Js::PropertyDescriptor desc;
935- JavascriptString* str = JavascriptString::FromVar (element);
936- BOOL ret = JavascriptOperators::GetOwnPropertyDescriptor (this , str, scriptContext, &desc);
937- if (ret && !dict.ContainsKey (str->GetSz ()))
924+ dict.Add (str->GetSz (), prop);
925+ // if (desc.enumerable) yield key;
926+ if (desc.IsEnumerable ())
938927 {
939- dict.Add (str->GetSz (), element);
940- if (desc.IsEnumerable ())
941- {
942- ret = arrResult->SetItem (index++, element, PropertyOperation_None);
943- Assert (ret);
944- }
928+ ret = arrResult->SetItem (index++, prop, PropertyOperation_None);
929+ Assert (ret);
945930 }
946931 }
947- }
948-
949- if (Js::JavascriptOperators::HasProperty (next, PropertyIds::done))
950- {
951- Js::Var done = JavascriptOperators::GetProperty (next, PropertyIds::done, scriptContext);
952- if (Js::JavascriptConversion::ToBoolean_Full (done, scriptContext))
953- {
954- break ;
955- }
956- }
957- next = JavascriptOperators::IteratorNext (arrayIterator, scriptContext);
932+ }
958933 }
959934
960- arrayIterator = JavascriptOperators::GetIterator (RecyclableObject::FromVar (arrResult), scriptContext);
961- *enumerator = IteratorObjectEnumerator::Create (scriptContext, arrayIterator);
962-
935+ *enumerator = IteratorObjectEnumerator::Create (scriptContext,
936+ JavascriptOperators::GetIterator (RecyclableObject::FromVar (arrResult), scriptContext));
963937 return TRUE ;
964938 }
965939
0 commit comments