JavascriptEnumeratorIterator.cpp 4.1 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. namespace Js
  7. {
  8. Var JavascriptEnumeratorIterator::Create(JavascriptEnumerator* enumerator, RecyclableObject* target, ScriptContext* scriptContext)
  9. {
  10. Recycler* recycler = scriptContext->GetThreadContext()->GetRecycler();
  11. JavascriptLibrary* library = scriptContext->GetLibrary();
  12. return (JavascriptEnumeratorIterator*)RecyclerNew(recycler,
  13. JavascriptEnumeratorIterator,
  14. library->GetJavascriptEnumeratorIteratorType(),
  15. enumerator,
  16. target);
  17. }
  18. JavascriptEnumeratorIterator::JavascriptEnumeratorIterator(DynamicType* type, JavascriptEnumerator* enumerator, RecyclableObject* target) :
  19. DynamicObject(type),
  20. enumerator(enumerator),
  21. object(target),
  22. objectIndex(0)
  23. {
  24. Assert(type->GetTypeId() == TypeIds_JavascriptEnumeratorIterator);
  25. }
  26. bool JavascriptEnumeratorIterator::Is(Var obj)
  27. {
  28. return JavascriptOperators::GetTypeId(obj) == TypeIds_JavascriptEnumeratorIterator;
  29. }
  30. JavascriptEnumeratorIterator* JavascriptEnumeratorIterator::FromVar(Var obj)
  31. {
  32. Assert(JavascriptEnumeratorIterator::Is(obj));
  33. return static_cast<JavascriptEnumeratorIterator*>(obj);
  34. }
  35. Var JavascriptEnumeratorIterator::EntryNext(RecyclableObject* function, CallInfo callInfo, ...)
  36. {
  37. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  38. ARGUMENTS(args, callInfo);
  39. ScriptContext* scriptContext = function->GetScriptContext();
  40. Assert(!(callInfo.Flags & CallFlags_New));
  41. AssertMsg(args.Info.Count > 0, "must have this pointer");
  42. AUTO_TAG_NATIVE_LIBRARY_ENTRY(function, callInfo, L"Iterator.next");
  43. if (!JavascriptEnumeratorIterator::Is(args[0]))
  44. {
  45. JavascriptError::ThrowTypeError(scriptContext, JSERR_This_NeedArrayIterator, L"Iterator.next");
  46. }
  47. JavascriptEnumeratorIterator* iterator = JavascriptEnumeratorIterator::FromVar(args[0]);
  48. return iterator->InternalGetNext();
  49. }
  50. Var JavascriptEnumeratorIterator::InternalGetNext()
  51. {
  52. PropertyId propertyId;
  53. Var index = nullptr;
  54. JavascriptLibrary* library = GetLibrary();
  55. ScriptContext* scriptContext = library->GetScriptContext();
  56. if (enumerator != nullptr)
  57. {
  58. index = enumerator->GetCurrentAndMoveNext(propertyId);
  59. if (index == nullptr)
  60. {
  61. // when done with iterator, cleanup the enumerator to avoid GC pressure.
  62. enumerator = nullptr;
  63. }
  64. else
  65. {
  66. const PropertyRecord* propertyRecord = scriptContext->GetThreadContext()->GetPropertyName(propertyId);
  67. Var name = index;
  68. // This iterator is created using ForInObjectEnumeratorWrapper that doesn't enum symbols.
  69. // If this changes in future, remove this assert.
  70. AssertMsg(!propertyRecord->IsSymbol(), "JavascriptEnumeratorIterator created from ForInObjectEnumeratorWrapper shouldn't enumerate over symbols.");
  71. return library->CreateIteratorResultObjectValueFalse(name);
  72. }
  73. }
  74. Assert(index == nullptr);
  75. Var propertyName = nullptr;
  76. if (object != nullptr)
  77. {
  78. if (object->GetSpecialPropertyName(objectIndex, &propertyName, scriptContext))
  79. {
  80. if (!JavascriptOperators::IsUndefinedObject(propertyName, library->GetUndefined()))
  81. {
  82. objectIndex++;
  83. return library->CreateIteratorResultObjectValueFalse(propertyName);
  84. }
  85. }
  86. object = nullptr;
  87. }
  88. return library->CreateIteratorResultObjectUndefinedTrue();
  89. }
  90. }