-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathES5ArrayIndexStaticEnumerator.h
More file actions
101 lines (91 loc) · 3.45 KB
/
ES5ArrayIndexStaticEnumerator.h
File metadata and controls
101 lines (91 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
namespace Js
{
//
// An enumerator to enumerate ES5Array index property names as uint32 indices.
//
template <bool enumNonEnumerable = false>
class ES5ArrayIndexStaticEnumerator
{
public:
typedef ES5Array ArrayType;
private:
ES5Array* m_array; // The ES5Array to enumerate on
uint32 m_initialLength; // Initial length of the array, for snapshot
uint32 m_index; // Current index
uint32 m_dataIndex; // Current data item index
uint32 m_descriptorIndex; // Current descriptor item index
IndexPropertyDescriptor* m_descriptor; // Current descriptor associated with m_descriptorIndex
void * m_descriptorValidationToken;
public:
ES5ArrayIndexStaticEnumerator(ES5Array* array)
: m_array(array)
{
Reset();
}
//
// Reset to enumerate from beginning.
//
void Reset()
{
m_initialLength = m_array->GetLength();
m_index = JavascriptArray::InvalidIndex;
m_dataIndex = JavascriptArray::InvalidIndex;
m_descriptorIndex = JavascriptArray::InvalidIndex;
m_descriptor = NULL;
m_descriptorValidationToken = nullptr;
}
//
// Get the current index. Valid only when MoveNext() returns true.
//
uint32 GetIndex() const
{
return m_index;
}
//
// Move to next index. If successful, use GetIndex() to get the index.
//
bool MoveNext(PropertyAttributes* attributes = nullptr)
{
while (true)
{
Assert(m_index == min(m_dataIndex, m_descriptorIndex));
if (m_index == m_dataIndex)
{
m_dataIndex = m_array->GetNextIndex(m_dataIndex);
}
if (m_index == m_descriptorIndex || !m_array->IsValidDescriptorToken(m_descriptorValidationToken))
{
m_descriptorIndex = m_array->GetNextDescriptor(m_index, &m_descriptor, &m_descriptorValidationToken);
}
m_index = min(m_dataIndex, m_descriptorIndex);
if (m_index >= m_initialLength) // End of array
{
break;
}
if (enumNonEnumerable
|| m_index < m_descriptorIndex
|| (m_descriptor->Attributes & PropertyEnumerable))
{
if (attributes != nullptr)
{
if (m_index < m_descriptorIndex)
{
*attributes = PropertyEnumerable;
}
else
{
*attributes = m_descriptor->Attributes;
}
}
return true;
}
}
return false;
}
};
}