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
186 lines (155 loc) · 6.84 KB
/
ArrayObject.h
File metadata and controls
186 lines (155 loc) · 6.84 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
/*
* 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 Object {
friend class VMInstance;
friend class Global;
friend class ByteCodeInterpreter;
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);
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 isInlineCacheable() override
{
return false;
}
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;
void defineOwnPropertyThrowsException(ExecutionState& state, const ObjectPropertyName& P, const ObjectPropertyDescriptor& desc)
{
if (!ArrayObject::defineOwnProperty(state, P, desc)) {
throwCannotDefineError(state, P.toObjectStructurePropertyName(state));
}
}
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, int64_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;
// 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 defineOwnIndexedPropertyWithExpandedLength(ExecutionState& state, const size_t& index, const Value& value)
{
ASSERT(index < arrayLength(state));
if (LIKELY(isFastModeArray())) {
setFastModeArrayValueWithoutExpanding(state, index, value);
} else {
defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(index)), ObjectPropertyDescriptor(value, ObjectPropertyDescriptor::AllPresent));
}
}
protected:
ArrayObject()
: Object()
, m_arrayLength(0)
#if !defined(ESCARGOT_64) || !defined(ESCARGOT_USE_32BIT_IN_64BIT)
, m_fastModeData(nullptr)
#endif
{
// dummy default constructor
// only called by Global::initialize to set tag value
}
private:
ALWAYS_INLINE bool isFastModeArray()
{
if (UNLIKELY(hasRareData())) {
return rareData()->m_isFastModeArrayObject;
}
return true;
}
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 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);
void convertIntoNonFastMode(ExecutionState& state);
ObjectGetResult getVirtualValue(ExecutionState& state, const ObjectPropertyName& P);
uint32_t m_arrayLength;
#if defined(ESCARGOT_64) && defined(ESCARGOT_USE_32BIT_IN_64BIT)
TightVectorWithNoSize<EncodedSmallValue, CustomAllocator<EncodedSmallValue>> m_fastModeData;
#else
ObjectPropertyValue* m_fastModeData;
#endif
};
class ArrayPrototypeObject : public ArrayObject {
friend class Global;
public:
explicit ArrayPrototypeObject(ExecutionState& state);
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