]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.3.0/src-separate/duk_hobject.h
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.3.0 / src-separate / duk_hobject.h
1 /*
2 * Heap object representation.
3 *
4 * Heap objects are used for Ecmascript objects, arrays, and functions,
5 * but also for internal control like declarative and object environment
6 * records. Compiled functions, native functions, and threads are also
7 * objects but with an extended C struct.
8 *
9 * Objects provide the required Ecmascript semantics and exotic behaviors
10 * especially for property access.
11 *
12 * Properties are stored in three conceptual parts:
13 *
14 * 1. A linear 'entry part' contains ordered key-value-attributes triples
15 * and is the main method of string properties.
16 *
17 * 2. An optional linear 'array part' is used for array objects to store a
18 * (dense) range of [0,N[ array indexed entries with default attributes
19 * (writable, enumerable, configurable). If the array part would become
20 * sparse or non-default attributes are required, the array part is
21 * abandoned and moved to the 'entry part'.
22 *
23 * 3. An optional 'hash part' is used to optimize lookups of the entry
24 * part; it is used only for objects with sufficiently many properties
25 * and can be abandoned without loss of information.
26 *
27 * These three conceptual parts are stored in a single memory allocated area.
28 * This minimizes memory allocation overhead but also means that all three
29 * parts are resized together, and makes property access a bit complicated.
30 */
31
32 #ifndef DUK_HOBJECT_H_INCLUDED
33 #define DUK_HOBJECT_H_INCLUDED
34
35 /* there are currently 26 flag bits available */
36 #define DUK_HOBJECT_FLAG_EXTENSIBLE DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */
37 #define DUK_HOBJECT_FLAG_CONSTRUCTABLE DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */
38 #define DUK_HOBJECT_FLAG_BOUND DUK_HEAPHDR_USER_FLAG(2) /* object established using Function.prototype.bind() */
39 #define DUK_HOBJECT_FLAG_COMPILEDFUNCTION DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompiledfunction) */
40 #define DUK_HOBJECT_FLAG_NATIVEFUNCTION DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnativefunction) */
41 #define DUK_HOBJECT_FLAG_BUFFEROBJECT DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufferobject) (always exotic) */
42 #define DUK_HOBJECT_FLAG_THREAD DUK_HEAPHDR_USER_FLAG(7) /* object is a thread (duk_hthread) */
43 #define DUK_HOBJECT_FLAG_ARRAY_PART DUK_HEAPHDR_USER_FLAG(8) /* object has an array part (a_size may still be 0) */
44 #define DUK_HOBJECT_FLAG_STRICT DUK_HEAPHDR_USER_FLAG(9) /* function: function object is strict */
45 #define DUK_HOBJECT_FLAG_NOTAIL DUK_HEAPHDR_USER_FLAG(10) /* function: function must not be tail called */
46 #define DUK_HOBJECT_FLAG_NEWENV DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompiledfunction) */
47 #define DUK_HOBJECT_FLAG_NAMEBINDING DUK_HEAPHDR_USER_FLAG(12) /* function: create binding for func name (function templates only, used for named function expressions) */
48 #define DUK_HOBJECT_FLAG_CREATEARGS DUK_HEAPHDR_USER_FLAG(13) /* function: create an arguments object on function call */
49 #define DUK_HOBJECT_FLAG_ENVRECCLOSED DUK_HEAPHDR_USER_FLAG(14) /* envrec: (declarative) record is closed */
50 #define DUK_HOBJECT_FLAG_EXOTIC_ARRAY DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */
51 #define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */
52 #define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */
53 #define DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC DUK_HEAPHDR_USER_FLAG(18) /* Duktape/C (nativefunction) object, exotic 'length' */
54 #define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ DUK_HEAPHDR_USER_FLAG(19) /* 'Proxy' object */
55
56 #define DUK_HOBJECT_FLAG_CLASS_BASE DUK_HEAPHDR_USER_FLAG_NUMBER(21)
57 #define DUK_HOBJECT_FLAG_CLASS_BITS 5
58
59 #define DUK_HOBJECT_GET_CLASS_NUMBER(h) \
60 DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)
61 #define DUK_HOBJECT_SET_CLASS_NUMBER(h,v) \
62 DUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))
63
64 #define DUK_HOBJECT_GET_CLASS_MASK(h) \
65 (1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))
66
67 /* Macro for creating flag initializer from a class number.
68 * Unsigned type cast is needed to avoid warnings about coercing
69 * a signed integer to an unsigned one; the largest class values
70 * have the highest bit (bit 31) set which causes this.
71 */
72 #define DUK_HOBJECT_CLASS_AS_FLAGS(v) (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)
73
74 /* E5 Section 8.6.2 + custom classes */
75 #define DUK_HOBJECT_CLASS_UNUSED 0
76 #define DUK_HOBJECT_CLASS_ARGUMENTS 1
77 #define DUK_HOBJECT_CLASS_ARRAY 2
78 #define DUK_HOBJECT_CLASS_BOOLEAN 3
79 #define DUK_HOBJECT_CLASS_DATE 4
80 #define DUK_HOBJECT_CLASS_ERROR 5
81 #define DUK_HOBJECT_CLASS_FUNCTION 6
82 #define DUK_HOBJECT_CLASS_JSON 7
83 #define DUK_HOBJECT_CLASS_MATH 8
84 #define DUK_HOBJECT_CLASS_NUMBER 9
85 #define DUK_HOBJECT_CLASS_OBJECT 10
86 #define DUK_HOBJECT_CLASS_REGEXP 11
87 #define DUK_HOBJECT_CLASS_STRING 12
88 #define DUK_HOBJECT_CLASS_GLOBAL 13
89 #define DUK_HOBJECT_CLASS_OBJENV 14 /* custom */
90 #define DUK_HOBJECT_CLASS_DECENV 15 /* custom */
91 #define DUK_HOBJECT_CLASS_BUFFER 16 /* custom; implies DUK_HOBJECT_IS_BUFFEROBJECT */
92 #define DUK_HOBJECT_CLASS_POINTER 17 /* custom */
93 #define DUK_HOBJECT_CLASS_THREAD 18 /* custom; implies DUK_HOBJECT_IS_THREAD */
94 #define DUK_HOBJECT_CLASS_ARRAYBUFFER 19 /* implies DUK_HOBJECT_IS_BUFFEROBJECT */
95 #define DUK_HOBJECT_CLASS_DATAVIEW 20
96 #define DUK_HOBJECT_CLASS_INT8ARRAY 21
97 #define DUK_HOBJECT_CLASS_UINT8ARRAY 22
98 #define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY 23
99 #define DUK_HOBJECT_CLASS_INT16ARRAY 24
100 #define DUK_HOBJECT_CLASS_UINT16ARRAY 25
101 #define DUK_HOBJECT_CLASS_INT32ARRAY 26
102 #define DUK_HOBJECT_CLASS_UINT32ARRAY 27
103 #define DUK_HOBJECT_CLASS_FLOAT32ARRAY 28
104 #define DUK_HOBJECT_CLASS_FLOAT64ARRAY 29
105 #define DUK_HOBJECT_CLASS_MAX 29
106
107 /* class masks */
108 #define DUK_HOBJECT_CMASK_ALL ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)
109 #define DUK_HOBJECT_CMASK_UNUSED (1UL << DUK_HOBJECT_CLASS_UNUSED)
110 #define DUK_HOBJECT_CMASK_ARGUMENTS (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)
111 #define DUK_HOBJECT_CMASK_ARRAY (1UL << DUK_HOBJECT_CLASS_ARRAY)
112 #define DUK_HOBJECT_CMASK_BOOLEAN (1UL << DUK_HOBJECT_CLASS_BOOLEAN)
113 #define DUK_HOBJECT_CMASK_DATE (1UL << DUK_HOBJECT_CLASS_DATE)
114 #define DUK_HOBJECT_CMASK_ERROR (1UL << DUK_HOBJECT_CLASS_ERROR)
115 #define DUK_HOBJECT_CMASK_FUNCTION (1UL << DUK_HOBJECT_CLASS_FUNCTION)
116 #define DUK_HOBJECT_CMASK_JSON (1UL << DUK_HOBJECT_CLASS_JSON)
117 #define DUK_HOBJECT_CMASK_MATH (1UL << DUK_HOBJECT_CLASS_MATH)
118 #define DUK_HOBJECT_CMASK_NUMBER (1UL << DUK_HOBJECT_CLASS_NUMBER)
119 #define DUK_HOBJECT_CMASK_OBJECT (1UL << DUK_HOBJECT_CLASS_OBJECT)
120 #define DUK_HOBJECT_CMASK_REGEXP (1UL << DUK_HOBJECT_CLASS_REGEXP)
121 #define DUK_HOBJECT_CMASK_STRING (1UL << DUK_HOBJECT_CLASS_STRING)
122 #define DUK_HOBJECT_CMASK_GLOBAL (1UL << DUK_HOBJECT_CLASS_GLOBAL)
123 #define DUK_HOBJECT_CMASK_OBJENV (1UL << DUK_HOBJECT_CLASS_OBJENV)
124 #define DUK_HOBJECT_CMASK_DECENV (1UL << DUK_HOBJECT_CLASS_DECENV)
125 #define DUK_HOBJECT_CMASK_BUFFER (1UL << DUK_HOBJECT_CLASS_BUFFER)
126 #define DUK_HOBJECT_CMASK_POINTER (1UL << DUK_HOBJECT_CLASS_POINTER)
127 #define DUK_HOBJECT_CMASK_THREAD (1UL << DUK_HOBJECT_CLASS_THREAD)
128 #define DUK_HOBJECT_CMASK_ARRAYBUFFER (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)
129 #define DUK_HOBJECT_CMASK_DATAVIEW (1UL << DUK_HOBJECT_CLASS_DATAVIEW)
130 #define DUK_HOBJECT_CMASK_INT8ARRAY (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)
131 #define DUK_HOBJECT_CMASK_UINT8ARRAY (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)
132 #define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)
133 #define DUK_HOBJECT_CMASK_INT16ARRAY (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)
134 #define DUK_HOBJECT_CMASK_UINT16ARRAY (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)
135 #define DUK_HOBJECT_CMASK_INT32ARRAY (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)
136 #define DUK_HOBJECT_CMASK_UINT32ARRAY (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)
137 #define DUK_HOBJECT_CMASK_FLOAT32ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)
138 #define DUK_HOBJECT_CMASK_FLOAT64ARRAY (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)
139
140 #define DUK_HOBJECT_CMASK_ALL_BUFFEROBJECTS \
141 (DUK_HOBJECT_CMASK_BUFFER | \
142 DUK_HOBJECT_CMASK_ARRAYBUFFER | \
143 DUK_HOBJECT_CMASK_DATAVIEW | \
144 DUK_HOBJECT_CMASK_INT8ARRAY | \
145 DUK_HOBJECT_CMASK_UINT8ARRAY | \
146 DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \
147 DUK_HOBJECT_CMASK_INT16ARRAY | \
148 DUK_HOBJECT_CMASK_UINT16ARRAY | \
149 DUK_HOBJECT_CMASK_INT32ARRAY | \
150 DUK_HOBJECT_CMASK_UINT32ARRAY | \
151 DUK_HOBJECT_CMASK_FLOAT32ARRAY | \
152 DUK_HOBJECT_CMASK_FLOAT64ARRAY)
153
154 #define DUK_HOBJECT_IS_OBJENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)
155 #define DUK_HOBJECT_IS_DECENV(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)
156 #define DUK_HOBJECT_IS_ENV(h) (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))
157 #define DUK_HOBJECT_IS_ARRAY(h) (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY)
158 #define DUK_HOBJECT_IS_COMPILEDFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
159 #define DUK_HOBJECT_IS_NATIVEFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
160 #define DUK_HOBJECT_IS_BUFFEROBJECT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
161 #define DUK_HOBJECT_IS_THREAD(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
162
163 #define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \
164 DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \
165 DUK_HOBJECT_FLAG_NATIVEFUNCTION)
166
167 #define DUK_HOBJECT_IS_FUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \
168 DUK_HOBJECT_FLAG_BOUND | \
169 DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \
170 DUK_HOBJECT_FLAG_NATIVEFUNCTION)
171
172 #define DUK_HOBJECT_IS_CALLABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \
173 DUK_HOBJECT_FLAG_BOUND | \
174 DUK_HOBJECT_FLAG_COMPILEDFUNCTION | \
175 DUK_HOBJECT_FLAG_NATIVEFUNCTION)
176
177 /* object has any exotic behavior(s) */
178 #define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \
179 DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \
180 DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \
181 DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC | \
182 DUK_HOBJECT_FLAG_BUFFEROBJECT | \
183 DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
184
185 #define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)
186
187 #define DUK_HOBJECT_HAS_EXTENSIBLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
188 #define DUK_HOBJECT_HAS_CONSTRUCTABLE(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
189 #define DUK_HOBJECT_HAS_BOUND(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
190 #define DUK_HOBJECT_HAS_COMPILEDFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
191 #define DUK_HOBJECT_HAS_NATIVEFUNCTION(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
192 #define DUK_HOBJECT_HAS_BUFFEROBJECT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
193 #define DUK_HOBJECT_HAS_THREAD(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
194 #define DUK_HOBJECT_HAS_ARRAY_PART(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
195 #define DUK_HOBJECT_HAS_STRICT(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
196 #define DUK_HOBJECT_HAS_NOTAIL(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
197 #define DUK_HOBJECT_HAS_NEWENV(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
198 #define DUK_HOBJECT_HAS_NAMEBINDING(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
199 #define DUK_HOBJECT_HAS_CREATEARGS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
200 #define DUK_HOBJECT_HAS_ENVRECCLOSED(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
201 #define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
202 #define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
203 #define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
204 #define DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
205 #define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
206
207 #define DUK_HOBJECT_SET_EXTENSIBLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
208 #define DUK_HOBJECT_SET_CONSTRUCTABLE(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
209 #define DUK_HOBJECT_SET_BOUND(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
210 #define DUK_HOBJECT_SET_COMPILEDFUNCTION(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
211 #define DUK_HOBJECT_SET_NATIVEFUNCTION(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
212 #define DUK_HOBJECT_SET_BUFFEROBJECT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
213 #define DUK_HOBJECT_SET_THREAD(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
214 #define DUK_HOBJECT_SET_ARRAY_PART(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
215 #define DUK_HOBJECT_SET_STRICT(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
216 #define DUK_HOBJECT_SET_NOTAIL(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
217 #define DUK_HOBJECT_SET_NEWENV(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
218 #define DUK_HOBJECT_SET_NAMEBINDING(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
219 #define DUK_HOBJECT_SET_CREATEARGS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
220 #define DUK_HOBJECT_SET_ENVRECCLOSED(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
221 #define DUK_HOBJECT_SET_EXOTIC_ARRAY(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
222 #define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
223 #define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
224 #define DUK_HOBJECT_SET_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
225 #define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
226
227 #define DUK_HOBJECT_CLEAR_EXTENSIBLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
228 #define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
229 #define DUK_HOBJECT_CLEAR_BOUND(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
230 #define DUK_HOBJECT_CLEAR_COMPILEDFUNCTION(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
231 #define DUK_HOBJECT_CLEAR_NATIVEFUNCTION(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
232 #define DUK_HOBJECT_CLEAR_BUFFEROBJECT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
233 #define DUK_HOBJECT_CLEAR_THREAD(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
234 #define DUK_HOBJECT_CLEAR_ARRAY_PART(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
235 #define DUK_HOBJECT_CLEAR_STRICT(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
236 #define DUK_HOBJECT_CLEAR_NOTAIL(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
237 #define DUK_HOBJECT_CLEAR_NEWENV(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
238 #define DUK_HOBJECT_CLEAR_NAMEBINDING(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
239 #define DUK_HOBJECT_CLEAR_CREATEARGS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
240 #define DUK_HOBJECT_CLEAR_ENVRECCLOSED(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
241 #define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
242 #define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
243 #define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
244 #define DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
245 #define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
246
247 /* flags used for property attributes in duk_propdesc and packed flags */
248 #define DUK_PROPDESC_FLAG_WRITABLE (1 << 0) /* E5 Section 8.6.1 */
249 #define DUK_PROPDESC_FLAG_ENUMERABLE (1 << 1) /* E5 Section 8.6.1 */
250 #define DUK_PROPDESC_FLAG_CONFIGURABLE (1 << 2) /* E5 Section 8.6.1 */
251 #define DUK_PROPDESC_FLAG_ACCESSOR (1 << 3) /* accessor */
252 #define DUK_PROPDESC_FLAG_VIRTUAL (1 << 4) /* property is virtual: used in duk_propdesc, never stored
253 * (used by e.g. buffer virtual properties)
254 */
255 #define DUK_PROPDESC_FLAGS_MASK (DUK_PROPDESC_FLAG_WRITABLE | \
256 DUK_PROPDESC_FLAG_ENUMERABLE | \
257 DUK_PROPDESC_FLAG_CONFIGURABLE | \
258 DUK_PROPDESC_FLAG_ACCESSOR)
259
260 /* additional flags which are passed in the same flags argument as property
261 * flags but are not stored in object properties.
262 */
263 #define DUK_PROPDESC_FLAG_NO_OVERWRITE (1 << 4) /* internal define property: skip write silently if exists */
264
265 /* convenience */
266 #define DUK_PROPDESC_FLAGS_NONE 0
267 #define DUK_PROPDESC_FLAGS_W (DUK_PROPDESC_FLAG_WRITABLE)
268 #define DUK_PROPDESC_FLAGS_E (DUK_PROPDESC_FLAG_ENUMERABLE)
269 #define DUK_PROPDESC_FLAGS_C (DUK_PROPDESC_FLAG_CONFIGURABLE)
270 #define DUK_PROPDESC_FLAGS_WE (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)
271 #define DUK_PROPDESC_FLAGS_WC (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
272 #define DUK_PROPDESC_FLAGS_EC (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
273 #define DUK_PROPDESC_FLAGS_WEC (DUK_PROPDESC_FLAG_WRITABLE | \
274 DUK_PROPDESC_FLAG_ENUMERABLE | \
275 DUK_PROPDESC_FLAG_CONFIGURABLE)
276
277 /*
278 * Macro for object validity check
279 *
280 * Assert for currently guaranteed relations between flags, for instance.
281 */
282
283 #define DUK_ASSERT_HOBJECT_VALID(h) do { \
284 DUK_ASSERT((h) != NULL); \
285 DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE((h)) || \
286 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FUNCTION); \
287 DUK_ASSERT(!DUK_HOBJECT_IS_BUFFEROBJECT((h)) || \
288 (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_BUFFER || \
289 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAYBUFFER || \
290 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DATAVIEW || \
291 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT8ARRAY || \
292 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT8ARRAY || \
293 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY || \
294 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT16ARRAY || \
295 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT16ARRAY || \
296 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_INT32ARRAY || \
297 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_UINT32ARRAY || \
298 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT32ARRAY || \
299 DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_FLOAT64ARRAY)); \
300 } while (0)
301
302 /*
303 * Macros to access the 'props' allocation.
304 */
305
306 #if defined(DUK_USE_HEAPPTR16)
307 #define DUK_HOBJECT_GET_PROPS(heap,h) \
308 ((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))
309 #define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \
310 ((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
311 } while (0)
312 #else
313 #define DUK_HOBJECT_GET_PROPS(heap,h) \
314 ((h)->props)
315 #define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \
316 (h)->props = (duk_uint8_t *) (x); \
317 } while (0)
318 #endif
319
320 #if defined(DUK_USE_HOBJECT_LAYOUT_1)
321 /* LAYOUT 1 */
322 #define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
323 ((duk_hstring **) (void *) ( \
324 DUK_HOBJECT_GET_PROPS((heap), (h)) \
325 ))
326 #define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
327 ((duk_propvalue *) (void *) ( \
328 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
329 DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \
330 ))
331 #define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
332 ((duk_uint8_t *) (void *) ( \
333 DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
334 ))
335 #define DUK_HOBJECT_A_GET_BASE(heap,h) \
336 ((duk_tval *) (void *) ( \
337 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
338 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \
339 ))
340 #define DUK_HOBJECT_H_GET_BASE(heap,h) \
341 ((duk_uint32_t *) (void *) ( \
342 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
343 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
344 DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
345 ))
346 #define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \
347 ( \
348 (n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
349 (n_arr) * sizeof(duk_tval) + \
350 (n_hash) * sizeof(duk_uint32_t) \
351 )
352 #define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \
353 (set_e_k) = (duk_hstring **) (void *) (p_base); \
354 (set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \
355 (set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \
356 (set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \
357 (set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \
358 } while (0)
359 #elif defined(DUK_USE_HOBJECT_LAYOUT_2)
360 /* LAYOUT 2 */
361 #if (DUK_USE_ALIGN_BY == 4)
362 #define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)
363 #elif (DUK_USE_ALIGN_BY == 8)
364 #define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)
365 #elif (DUK_USE_ALIGN_BY == 1)
366 #define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0
367 #else
368 #error invalid DUK_USE_ALIGN_BY
369 #endif
370 #define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
371 ((duk_hstring **) (void *) ( \
372 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
373 DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \
374 ))
375 #define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
376 ((duk_propvalue *) (void *) ( \
377 DUK_HOBJECT_GET_PROPS((heap), (h)) \
378 ))
379 #define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
380 ((duk_uint8_t *) (void *) ( \
381 DUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \
382 ))
383 #define DUK_HOBJECT_A_GET_BASE(heap,h) \
384 ((duk_tval *) (void *) ( \
385 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
386 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
387 DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \
388 ))
389 #define DUK_HOBJECT_H_GET_BASE(heap,h) \
390 ((duk_uint32_t *) (void *) ( \
391 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
392 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
393 DUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \
394 DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
395 ))
396 #define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \
397 ( \
398 (n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \
399 DUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \
400 (n_arr) * sizeof(duk_tval) + \
401 (n_hash) * sizeof(duk_uint32_t) \
402 )
403 #define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \
404 (set_e_pv) = (duk_propvalue *) (void *) (p_base); \
405 (set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \
406 (set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \
407 (set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \
408 sizeof(duk_uint8_t) * (n_ent) + \
409 DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \
410 (set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \
411 } while (0)
412 #elif defined(DUK_USE_HOBJECT_LAYOUT_3)
413 /* LAYOUT 3 */
414 #define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \
415 ((duk_hstring **) (void *) ( \
416 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
417 DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \
418 DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
419 ))
420 #define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \
421 ((duk_propvalue *) (void *) ( \
422 DUK_HOBJECT_GET_PROPS((heap), (h)) \
423 ))
424 #define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \
425 ((duk_uint8_t *) (void *) ( \
426 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
427 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \
428 DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \
429 DUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \
430 ))
431 #define DUK_HOBJECT_A_GET_BASE(heap,h) \
432 ((duk_tval *) (void *) ( \
433 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
434 DUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \
435 ))
436 #define DUK_HOBJECT_H_GET_BASE(heap,h) \
437 ((duk_uint32_t *) (void *) ( \
438 DUK_HOBJECT_GET_PROPS((heap), (h)) + \
439 DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \
440 DUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \
441 ))
442 #define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \
443 ( \
444 (n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \
445 (n_arr) * sizeof(duk_tval) + \
446 (n_hash) * sizeof(duk_uint32_t) \
447 )
448 #define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash) do { \
449 (set_e_pv) = (duk_propvalue *) (void *) (p_base); \
450 (set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \
451 (set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \
452 (set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \
453 (set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \
454 } while (0)
455 #else
456 #error invalid hobject layout defines
457 #endif /* hobject property layout */
458
459 #define DUK_HOBJECT_E_ALLOC_SIZE(h) \
460 DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))
461
462 #define DUK_HOBJECT_E_GET_KEY(heap,h,i) (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
463 #define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
464 #define DUK_HOBJECT_E_GET_VALUE(heap,h,i) (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
465 #define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
466 #define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
467 #define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
468 #define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
469 #define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
470 #define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i) (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
471 #define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
472 #define DUK_HOBJECT_E_GET_FLAGS(heap,h,i) (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
473 #define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
474 #define DUK_HOBJECT_A_GET_VALUE(heap,h,i) (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
475 #define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i) (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
476 #define DUK_HOBJECT_H_GET_INDEX(heap,h,i) (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
477 #define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i) (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
478
479 #define DUK_HOBJECT_E_SET_KEY(heap,h,i,k) do { \
480 DUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \
481 } while (0)
482 #define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v) do { \
483 DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \
484 } while (0)
485 #define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v) do { \
486 DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \
487 } while (0)
488 #define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v) do { \
489 DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \
490 } while (0)
491 #define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v) do { \
492 DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \
493 } while (0)
494 #define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f) do { \
495 DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (f); \
496 } while (0)
497 #define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v) do { \
498 DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \
499 } while (0)
500 #define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \
501 DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */
502 #define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v) do { \
503 DUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \
504 } while (0)
505
506 #define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask) do { \
507 DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \
508 } while (0)
509
510 #define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask) do { \
511 DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \
512 } while (0)
513
514 #define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)
515 #define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
516 #define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
517 #define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
518
519 #define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
520 #define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
521 #define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
522 #define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i) DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
523
524 #define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
525 #define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
526 #define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
527 #define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i) DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
528
529 #define DUK_PROPDESC_IS_WRITABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)
530 #define DUK_PROPDESC_IS_ENUMERABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
531 #define DUK_PROPDESC_IS_CONFIGURABLE(p) (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
532 #define DUK_PROPDESC_IS_ACCESSOR(p) (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
533
534 #define DUK_HOBJECT_HASHIDX_UNUSED 0xffffffffUL
535 #define DUK_HOBJECT_HASHIDX_DELETED 0xfffffffeUL
536
537 /*
538 * Macros for accessing size fields
539 */
540
541 #if defined(DUK_USE_OBJSIZES16)
542 #define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)
543 #define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0)
544 #define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)
545 #define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0)
546 #define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)
547 #define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16)
548 #define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0)
549 #if defined(DUK_USE_HOBJECT_HASH_PART)
550 #define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)
551 #define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0)
552 #else
553 #define DUK_HOBJECT_GET_HSIZE(h) 0
554 #define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)
555 #endif
556 #else
557 #define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)
558 #define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0)
559 #define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)
560 #define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0)
561 #define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)
562 #define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size)
563 #define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0)
564 #if defined(DUK_USE_HOBJECT_HASH_PART)
565 #define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)
566 #define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0)
567 #else
568 #define DUK_HOBJECT_GET_HSIZE(h) 0
569 #define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)
570 #endif
571 #endif
572
573 /*
574 * Misc
575 */
576
577 /* Maximum prototype traversal depth. Sanity limit which handles e.g.
578 * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).
579 */
580 #define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY 10000L
581
582 /* Maximum traversal depth for "bound function" chains. */
583 #define DUK_HOBJECT_BOUND_CHAIN_SANITY 10000L
584
585 /*
586 * Ecmascript [[Class]]
587 */
588
589 /* range check not necessary because all 4-bit values are mapped */
590 #define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n) duk_class_number_to_stridx[(n)]
591
592 #define DUK_HOBJECT_GET_CLASS_STRING(heap,h) \
593 DUK_HEAP_GET_STRING( \
594 (heap), \
595 DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \
596 )
597
598 /*
599 * Macros for property handling
600 */
601
602 #if defined(DUK_USE_HEAPPTR16)
603 #define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \
604 ((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))
605 #define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \
606 (h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \
607 } while (0)
608 #else
609 #define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \
610 ((h)->prototype)
611 #define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \
612 (h)->prototype = (x); \
613 } while (0)
614 #endif
615
616 /* note: this updates refcounts */
617 #define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p) duk_hobject_set_prototype((thr), (h), (p))
618
619 /*
620 * Resizing and hash behavior
621 */
622
623 /* Sanity limit on max number of properties (allocated, not necessarily used).
624 * This is somewhat arbitrary, but if we're close to 2**32 properties some
625 * algorithms will fail (e.g. hash size selection, next prime selection).
626 * Also, we use negative array/entry table indices to indicate 'not found',
627 * so anything above 0x80000000 will cause trouble now.
628 */
629 #if defined(DUK_USE_OBJSIZES16)
630 #define DUK_HOBJECT_MAX_PROPERTIES 0x0000ffffUL
631 #else
632 #define DUK_HOBJECT_MAX_PROPERTIES 0x7fffffffUL /* 2**31-1 ~= 2G properties */
633 #endif
634
635 /* higher value conserves memory; also note that linear scan is cache friendly */
636 #define DUK_HOBJECT_E_USE_HASH_LIMIT 32
637
638 /* hash size relative to entries size: for value X, approx. hash_prime(e_size + e_size / X) */
639 #define DUK_HOBJECT_H_SIZE_DIVISOR 4 /* hash size approx. 1.25 times entries size */
640
641 /* if new_size < L * old_size, resize without abandon check; L = 3-bit fixed point, e.g. 9 -> 9/8 = 112.5% */
642 #define DUK_HOBJECT_A_FAST_RESIZE_LIMIT 9 /* 112.5%, i.e. new size less than 12.5% higher -> fast resize */
643
644 /* if density < L, abandon array part, L = 3-bit fixed point, e.g. 2 -> 2/8 = 25% */
645 /* limit is quite low: one array entry is 8 bytes, one normal entry is 4+1+8+4 = 17 bytes (with hash entry) */
646 #define DUK_HOBJECT_A_ABANDON_LIMIT 2 /* 25%, i.e. less than 25% used -> abandon */
647
648 /* internal align target for props allocation, must be 2*n for some n */
649 #if (DUK_USE_ALIGN_BY == 4)
650 #define DUK_HOBJECT_ALIGN_TARGET 4
651 #elif (DUK_USE_ALIGN_BY == 8)
652 #define DUK_HOBJECT_ALIGN_TARGET 8
653 #elif (DUK_USE_ALIGN_BY == 1)
654 #define DUK_HOBJECT_ALIGN_TARGET 1
655 #else
656 #error invalid DUK_USE_ALIGN_BY
657 #endif
658
659 /* controls for minimum entry part growth */
660 #define DUK_HOBJECT_E_MIN_GROW_ADD 16
661 #define DUK_HOBJECT_E_MIN_GROW_DIVISOR 8 /* 2^3 -> 1/8 = 12.5% min growth */
662
663 /* controls for minimum array part growth */
664 #define DUK_HOBJECT_A_MIN_GROW_ADD 16
665 #define DUK_HOBJECT_A_MIN_GROW_DIVISOR 8 /* 2^3 -> 1/8 = 12.5% min growth */
666
667 /* probe sequence */
668 #define DUK_HOBJECT_HASH_INITIAL(hash,h_size) ((hash) % (h_size))
669 #define DUK_HOBJECT_HASH_PROBE_STEP(hash) DUK_UTIL_GET_HASH_PROBE_STEP((hash))
670
671 /*
672 * PC-to-line constants
673 */
674
675 #define DUK_PC2LINE_SKIP 64
676
677 /* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */
678 #define DUK_PC2LINE_MAX_DIFF_LENGTH (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)
679
680 /*
681 * Struct defs
682 */
683
684 struct duk_propaccessor {
685 duk_hobject *get;
686 duk_hobject *set;
687 };
688
689 union duk_propvalue {
690 /* The get/set pointers could be 16-bit pointer compressed but it
691 * would make no difference on 32-bit platforms because duk_tval is
692 * 8 bytes or more anyway.
693 */
694 duk_tval v;
695 duk_propaccessor a;
696 };
697
698 struct duk_propdesc {
699 /* read-only values 'lifted' for ease of use */
700 duk_small_int_t flags;
701 duk_hobject *get;
702 duk_hobject *set;
703
704 /* for updating (all are set to < 0 for virtual properties) */
705 duk_int_t e_idx; /* prop index in 'entry part', < 0 if not there */
706 duk_int_t h_idx; /* prop index in 'hash part', < 0 if not there */
707 duk_int_t a_idx; /* prop index in 'array part', < 0 if not there */
708 };
709
710 struct duk_hobject {
711 duk_heaphdr hdr;
712
713 /*
714 * 'props' contains {key,value,flags} entries, optional array entries, and
715 * an optional hash lookup table for non-array entries in a single 'sliced'
716 * allocation. There are several layout options, which differ slightly in
717 * generated code size/speed and alignment/padding; duk_features.h selects
718 * the layout used.
719 *
720 * Layout 1 (DUK_USE_HOBJECT_LAYOUT_1):
721 *
722 * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable)
723 * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable)
724 * e_size * sizeof(duk_uint8_t) bytes of entry flags (e_next gc reachable)
725 * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable)
726 * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size),
727 * 0xffffffffUL = unused, 0xfffffffeUL = deleted
728 *
729 * Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):
730 *
731 * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable)
732 * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable)
733 * e_size * sizeof(duk_uint8_t) + pad bytes of entry flags (e_next gc reachable)
734 * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable)
735 * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size),
736 * 0xffffffffUL = unused, 0xfffffffeUL = deleted
737 *
738 * Layout 3 (DUK_USE_HOBJECT_LAYOUT_3):
739 *
740 * e_size * sizeof(duk_propvalue) bytes of entry values (e_next gc reachable)
741 * a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable)
742 * e_size * sizeof(duk_hstring *) bytes of entry keys (e_next gc reachable)
743 * h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size),
744 * 0xffffffffUL = unused, 0xfffffffeUL = deleted
745 * e_size * sizeof(duk_uint8_t) bytes of entry flags (e_next gc reachable)
746 *
747 * In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms
748 * requiring 4 or 8 byte alignment. This ensures proper alignment
749 * for the entries, at the cost of memory footprint. However, it's
750 * probably preferable to use another layout on such platforms instead.
751 *
752 * In layout 2, the key and value parts are swapped to avoid padding
753 * the key array on platforms requiring alignment by 8. The flags part
754 * is padded to get alignment for array entries. The 'e_next' count does
755 * not need to be rounded as in layout 1.
756 *
757 * In layout 3, entry values and array values are always aligned properly,
758 * and assuming pointers are at most 8 bytes, so are the entry keys. Hash
759 * indices will be properly aligned (assuming pointers are at least 4 bytes).
760 * Finally, flags don't need additional alignment. This layout provides
761 * compact allocations without padding (even on platforms with alignment
762 * requirements) at the cost of a bit slower lookups.
763 *
764 * Objects with few keys don't have a hash index; keys are looked up linearly,
765 * which is cache efficient because the keys are consecutive. Larger objects
766 * have a hash index part which contains integer indexes to the entries part.
767 *
768 * A single allocation reduces memory allocation overhead but requires more
769 * work when any part needs to be resized. A sliced allocation for entries
770 * makes linear key matching faster on most platforms (more locality) and
771 * skimps on flags size (which would be followed by 3 bytes of padding in
772 * most architectures if entries were placed in a struct).
773 *
774 * 'props' also contains internal properties distinguished with a non-BMP
775 * prefix. Often used properties should be placed early in 'props' whenever
776 * possible to make accessing them as fast a possible.
777 */
778
779 #if defined(DUK_USE_HEAPPTR16)
780 /* Located in duk_heaphdr h_extra16. Subclasses of duk_hobject (like
781 * duk_hcompiledfunction) are not free to use h_extra16 for this reason.
782 */
783 #else
784 duk_uint8_t *props;
785 #endif
786
787 /* prototype: the only internal property lifted outside 'e' as it is so central */
788 #if defined(DUK_USE_HEAPPTR16)
789 duk_uint16_t prototype16;
790 #else
791 duk_hobject *prototype;
792 #endif
793
794 #if defined(DUK_USE_OBJSIZES16)
795 duk_uint16_t e_size16;
796 duk_uint16_t e_next16;
797 duk_uint16_t a_size16;
798 #if defined(DUK_USE_HOBJECT_HASH_PART)
799 duk_uint16_t h_size16;
800 #endif
801 #else
802 duk_uint32_t e_size; /* entry part size */
803 duk_uint32_t e_next; /* index for next new key ([0,e_next[ are gc reachable) */
804 duk_uint32_t a_size; /* array part size (entirely gc reachable) */
805 #if defined(DUK_USE_HOBJECT_HASH_PART)
806 duk_uint32_t h_size; /* hash part size or 0 if unused */
807 #endif
808 #endif
809 };
810
811 /*
812 * Exposed data
813 */
814
815 #if !defined(DUK_SINGLE_FILE)
816 DUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32];
817 #endif /* !DUK_SINGLE_FILE */
818
819 /*
820 * Prototypes
821 */
822
823 /* alloc and init */
824 DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_heap *heap, duk_uint_t hobject_flags);
825 #if 0 /* unused */
826 DUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_checked(duk_hthread *thr, duk_uint_t hobject_flags);
827 #endif
828 DUK_INTERNAL_DECL duk_hcompiledfunction *duk_hcompiledfunction_alloc(duk_heap *heap, duk_uint_t hobject_flags);
829 DUK_INTERNAL_DECL duk_hnativefunction *duk_hnativefunction_alloc(duk_heap *heap, duk_uint_t hobject_flags);
830 DUK_INTERNAL duk_hbufferobject *duk_hbufferobject_alloc(duk_heap *heap, duk_uint_t hobject_flags);
831 DUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_heap *heap, duk_uint_t hobject_flags);
832
833 /* low-level property functions */
834 DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);
835 DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);
836 DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs);
837 DUK_INTERNAL_DECL duk_tval *duk_hobject_find_existing_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);
838
839 /* XXX: when optimizing for guaranteed property slots, use a guaranteed
840 * slot for internal value; this call can then access it directly.
841 */
842 #define duk_hobject_get_internal_value_tval_ptr(heap,obj) \
843 duk_hobject_find_existing_entry_tval_ptr((heap), (obj), DUK_HEAP_STRING_INT_VALUE((heap)))
844
845 /* core property functions */
846 DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);
847 DUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);
848 DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag);
849 DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);
850
851 /* internal property functions */
852 #define DUK_DELPROP_FLAG_THROW (1 << 0)
853 #define DUK_DELPROP_FLAG_FORCE (1 << 1)
854 DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);
855 DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);
856 DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);
857 DUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);
858 DUK_INTERNAL_DECL void duk_hobject_define_accessor_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_hobject *getter, duk_hobject *setter, duk_small_uint_t propflags);
859 DUK_INTERNAL_DECL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length); /* XXX: duk_uarridx_t? */
860 DUK_INTERNAL_DECL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj);
861 DUK_INTERNAL_DECL duk_uint32_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj); /* XXX: duk_uarridx_t? */
862
863 /* helpers for defineProperty() and defineProperties() */
864 DUK_INTERNAL_DECL
865 void duk_hobject_prepare_property_descriptor(duk_context *ctx,
866 duk_idx_t idx_in,
867 duk_uint_t *out_defprop_flags,
868 duk_idx_t *out_idx_value,
869 duk_hobject **out_getter,
870 duk_hobject **out_setter);
871 DUK_INTERNAL_DECL
872 void duk_hobject_define_property_helper(duk_context *ctx,
873 duk_uint_t defprop_flags,
874 duk_hobject *obj,
875 duk_hstring *key,
876 duk_idx_t idx_value,
877 duk_hobject *get,
878 duk_hobject *set);
879
880 /* Object built-in methods */
881 DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor(duk_context *ctx);
882 DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);
883 DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);
884 DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags);
885
886 /* internal properties */
887 DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_internal_value(duk_heap *heap, duk_hobject *obj, duk_tval *tv);
888 DUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);
889
890 /* hobject management functions */
891 DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);
892
893 /* ES6 proxy */
894 #if defined(DUK_USE_ES6_PROXY)
895 DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);
896 DUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hthread *thr, duk_hobject *obj);
897 #endif
898
899 /* enumeration */
900 DUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint_t enum_flags);
901 DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags);
902 DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t get_value);
903
904 /* macros */
905 DUK_INTERNAL_DECL void duk_hobject_set_prototype(duk_hthread *thr, duk_hobject *h, duk_hobject *p);
906
907 /* finalization */
908 DUK_INTERNAL_DECL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj);
909
910 /* pc2line */
911 #if defined(DUK_USE_PC2LINE)
912 DUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);
913 DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_idx_t idx_func, duk_uint_fast32_t pc);
914 #endif
915
916 /* misc */
917 DUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop);
918
919 #endif /* DUK_HOBJECT_H_INCLUDED */