ArgumentsObjectEnumerator.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. #include "Library/ArgumentsObjectEnumerator.h"
  7. namespace Js
  8. {
  9. ArgumentsObjectPrefixEnumerator::ArgumentsObjectPrefixEnumerator(ArgumentsObject* argumentsObject, EnumeratorFlags flags, ScriptContext* requestContext)
  10. : JavascriptEnumerator(requestContext),
  11. argumentsObject(argumentsObject),
  12. flags(flags)
  13. {
  14. Reset();
  15. }
  16. JavascriptString * ArgumentsObjectPrefixEnumerator::MoveAndGetNext(PropertyId& propertyId, PropertyAttributes* attributes)
  17. {
  18. propertyId = Constants::NoProperty;
  19. if (!doneFormalArgs)
  20. {
  21. formalArgIndex = argumentsObject->GetNextFormalArgIndex(formalArgIndex, !!(flags & EnumeratorFlags::EnumNonEnumerable), attributes);
  22. if (formalArgIndex != JavascriptArray::InvalidIndex
  23. && formalArgIndex < argumentsObject->GetNumberOfArguments())
  24. {
  25. return this->GetScriptContext()->GetIntegerString(formalArgIndex);
  26. }
  27. doneFormalArgs = true;
  28. }
  29. return nullptr;
  30. }
  31. void ArgumentsObjectPrefixEnumerator::Reset()
  32. {
  33. formalArgIndex = JavascriptArray::InvalidIndex;
  34. doneFormalArgs = false;
  35. }
  36. //---------------------- ES5ArgumentsObjectEnumerator -------------------------------
  37. ES5ArgumentsObjectEnumerator * ES5ArgumentsObjectEnumerator::New(ArgumentsObject* argumentsObject, EnumeratorFlags flags, ScriptContext* requestContext, EnumeratorCache * enumeratorCache)
  38. {
  39. ES5ArgumentsObjectEnumerator * enumerator = RecyclerNew(requestContext->GetRecycler(), ES5ArgumentsObjectEnumerator, argumentsObject, flags, requestContext);
  40. if (!enumerator->Init(enumeratorCache))
  41. {
  42. return nullptr;
  43. }
  44. return enumerator;
  45. }
  46. ES5ArgumentsObjectEnumerator::ES5ArgumentsObjectEnumerator(ArgumentsObject* argumentsObject, EnumeratorFlags flags, ScriptContext* requestcontext)
  47. : ArgumentsObjectPrefixEnumerator(argumentsObject, flags, requestcontext),
  48. enumeratedFormalsInObjectArrayCount(0)
  49. {
  50. }
  51. BOOL ES5ArgumentsObjectEnumerator::Init(EnumeratorCache * enumeratorCache)
  52. {
  53. __super::Reset();
  54. this->enumeratedFormalsInObjectArrayCount = 0;
  55. return argumentsObject->DynamicObject::GetEnumerator(&objectEnumerator, flags, GetScriptContext(), enumeratorCache);
  56. }
  57. JavascriptString * ES5ArgumentsObjectEnumerator::MoveAndGetNext(PropertyId& propertyId, PropertyAttributes* attributes)
  58. {
  59. // Formals:
  60. // - deleted => not in objectArray && not connected -- do not enum, do not advance
  61. // - connected, in objectArray -- if (enumerable) enum it, advance objectEnumerator
  62. // - disconnected =>in objectArray -- if (enumerable) enum it, advance objectEnumerator
  63. if (!doneFormalArgs)
  64. {
  65. ES5HeapArgumentsObject* es5HAO = static_cast<ES5HeapArgumentsObject*>(
  66. static_cast<ArgumentsObject*>(argumentsObject));
  67. formalArgIndex = es5HAO->GetNextFormalArgIndexHelper(formalArgIndex, !!(flags & EnumeratorFlags::EnumNonEnumerable), attributes);
  68. if (formalArgIndex != JavascriptArray::InvalidIndex
  69. && formalArgIndex < argumentsObject->GetNumberOfArguments())
  70. {
  71. if (argumentsObject->HasObjectArrayItem(formalArgIndex))
  72. {
  73. PropertyId tempPropertyId;
  74. JavascriptString * tempIndex = objectEnumerator.MoveAndGetNext(tempPropertyId, attributes);
  75. AssertMsg(tempIndex, "We advanced objectEnumerator->MoveNext() too many times.");
  76. }
  77. propertyId = Constants::NoProperty;
  78. return this->GetScriptContext()->GetIntegerString(formalArgIndex);
  79. }
  80. doneFormalArgs = true;
  81. }
  82. return objectEnumerator.MoveAndGetNext(propertyId, attributes);
  83. }
  84. void ES5ArgumentsObjectEnumerator::Reset()
  85. {
  86. Init(nullptr);
  87. }
  88. }