forked from Samsung/escargot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArrayObject.h
More file actions
200 lines (164 loc) · 7.44 KB
/
ArrayObject.h
File metadata and controls
200 lines (164 loc) · 7.44 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* Copyright (c) 2016-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef __EscargotArrayObject__
#define __EscargotArrayObject__
#include "runtime/Object.h"
#include "runtime/ErrorObject.h"
#include "runtime/IteratorObject.h"
namespace Escargot {
#define ESCARGOT_ARRAY_NON_FASTMODE_MIN_SIZE 65536 * 16
#define ESCARGOT_ARRAY_NON_FASTMODE_START_MIN_GAP 1024
class ArrayIteratorObject;
class ArrayObject : public DerivedObject {
friend class VMInstance;
friend class Global;
friend class Interpreter;
friend class InterpreterSlowPath;
friend class EnumerateObject;
friend class EnumerateObjectWithDestruction;
friend class EnumerateObjectWithIteration;
friend Value builtinArrayConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget);
friend void initializeCustomAllocators();
friend int getValidValueInArrayObject(void* ptr, GC_mark_custom_result* arr);
// dummy element to represent non-fast mode array
static ObjectPropertyValue DummyArrayElement;
enum ForSpreadArray { __ForSpreadArray__ };
public:
explicit ArrayObject(ExecutionState& state);
explicit ArrayObject(ExecutionState& state, Object* proto);
ArrayObject(ExecutionState& state, const uint64_t& size, bool shouldConsiderHole = true);
ArrayObject(ExecutionState& state, Object* proto, const uint64_t& size, bool shouldConsiderHole = true);
ArrayObject(ExecutionState& state, const Value* src, const uint64_t& size);
ArrayObject(ExecutionState& state, Object* proto, const Value* src, const uint64_t& size);
static ArrayObject* createSpreadArray(ExecutionState& state);
virtual bool hasOwnEnumeration() const override
{
return true;
}
virtual ObjectHasPropertyResult hasProperty(ExecutionState& state, const ObjectPropertyName& P) override;
virtual ObjectGetResult getOwnProperty(ExecutionState& state, const ObjectPropertyName& P) override;
virtual bool defineOwnProperty(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc) override;
virtual bool deleteOwnProperty(ExecutionState& state, const ObjectPropertyName& P) override;
virtual void enumeration(ExecutionState& state, bool (*callback)(ExecutionState& state, Object* self, const ObjectPropertyName&, const ObjectStructurePropertyDescriptor& desc, void* data), void* data, bool shouldSkipSymbolKey = true) override;
virtual void sort(ExecutionState& state, uint64_t length, const std::function<bool(const Value& a, const Value& b)>& comp) override;
virtual void toSorted(ExecutionState& state, Object* target, uint64_t length, const std::function<bool(const Value& a, const Value& b)>& comp) override;
virtual ObjectGetResult getIndexedProperty(ExecutionState& state, const Value& property, const Value& receiver) override;
virtual ObjectHasPropertyResult hasIndexedProperty(ExecutionState& state, const Value& propertyName) override;
virtual bool setIndexedProperty(ExecutionState& state, const Value& property, const Value& value, const Value& receiver) override;
virtual bool preventExtensions(ExecutionState&) override;
virtual uint64_t length(ExecutionState& state) override;
virtual void markAsPrototypeObject(ExecutionState& state) override;
// Use custom allocator for Array object (for Badtime)
void* operator new(size_t size);
void* operator new[](size_t size) = delete;
static void iterateArrays(ExecutionState& state, HeapObjectIteratorCallback callback);
void defineOwnIndexedPropertyWithoutExpanding(ExecutionState& state, const size_t& index, const Value& value)
{
ASSERT(index < arrayLength(state));
if (LIKELY(isFastModeArray())) {
setFastModeArrayValueWithoutExpanding(state, index, value);
} else {
DerivedObject::defineOwnProperty(state, ObjectPropertyName(state, index), ObjectPropertyDescriptor(value, ObjectPropertyDescriptor::AllPresent));
}
}
protected:
ArrayObject()
: DerivedObject()
, m_arrayLength(0)
#if defined(ESCARGOT_64) && defined(ESCARGOT_USE_32BIT_IN_64BIT)
, m_fastModeData()
#else
, m_fastModeData(nullptr)
#endif
{
// default constructor
// only called by Global::initialize to set tag value
}
// constructor for SpreadArray (ArrayObject::createSpreadArray)
ArrayObject(ExecutionState& state, ForSpreadArray);
void convertIntoNonFastMode(ExecutionState& state);
private:
ALWAYS_INLINE bool isFastModeArray()
{
#if defined(ESCARGOT_64) && defined(ESCARGOT_USE_32BIT_IN_64BIT)
return (m_fastModeData.data() != &ArrayObject::DummyArrayElement);
#else
return (m_fastModeData != &ArrayObject::DummyArrayElement);
#endif
}
bool isLengthPropertyWritable()
{
return hasRareData() ? rareData()->m_isArrayObjectLengthWritable : true;
}
void setFastModeArrayValueWithoutExpanding(ExecutionState& state, size_t idx, const Value& v)
{
ASSERT(isFastModeArray());
ASSERT(idx < arrayLength(state));
m_fastModeData[idx] = v;
}
ALWAYS_INLINE const uint32_t& arrayLength(ExecutionState&)
{
return m_arrayLength;
}
bool setArrayLength(ExecutionState& state, const Value& newLength);
bool setArrayLength(ExecutionState& state, const uint32_t newLength, bool useFitStorage = false, bool considerHole = true);
ObjectGetResult getVirtualValue(ExecutionState& state, const ObjectPropertyName& P);
uint32_t m_arrayLength;
#if defined(ESCARGOT_64) && defined(ESCARGOT_USE_32BIT_IN_64BIT)
TightVectorWithNoSize<ObjectPropertyValue, CustomAllocator<ObjectPropertyValue>> m_fastModeData;
#else
ObjectPropertyValue* m_fastModeData;
#endif
};
class ArrayPrototypeObject : public ArrayObject {
friend class Global;
public:
explicit ArrayPrototypeObject(ExecutionState& state);
virtual void markAsPrototypeObject(ExecutionState& state) override;
virtual bool isEverSetAsPrototypeObject() const override;
private:
ArrayPrototypeObject()
: ArrayObject()
{
// dummy default constructor
// only called by Global::initialize to set tag value
}
};
class ArrayIteratorObject : public IteratorObject {
public:
enum Type {
TypeKey,
TypeValue,
TypeKeyValue
};
ArrayIteratorObject(ExecutionState& state, Object* array, Type type);
virtual bool isArrayIteratorObject() const override
{
return true;
}
virtual std::pair<Value, bool> advance(ExecutionState& state) override;
void* operator new(size_t size);
void* operator new[](size_t size) = delete;
private:
Object* m_array;
size_t m_iteratorNextIndex;
Type m_type;
};
} // namespace Escargot
#endif