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