Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_hobject.h File Reference

Go to the source code of this file.

Data Structures

struct  duk_propaccessor
 
union  duk_propvalue
 
struct  duk_propdesc
 
struct  duk_hobject
 

Macros

#define DUK_HOBJECT_FLAG_EXTENSIBLE   DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */
 
#define DUK_HOBJECT_FLAG_CONSTRUCTABLE   DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */
 
#define DUK_HOBJECT_FLAG_BOUND   DUK_HEAPHDR_USER_FLAG(2) /* object established using Function.prototype.bind() */
 
#define DUK_HOBJECT_FLAG_COMPILEDFUNCTION   DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompiledfunction) */
 
#define DUK_HOBJECT_FLAG_NATIVEFUNCTION   DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnativefunction) */
 
#define DUK_HOBJECT_FLAG_BUFFEROBJECT   DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufferobject) (always exotic) */
 
#define DUK_HOBJECT_FLAG_THREAD   DUK_HEAPHDR_USER_FLAG(7) /* object is a thread (duk_hthread) */
 
#define DUK_HOBJECT_FLAG_ARRAY_PART   DUK_HEAPHDR_USER_FLAG(8) /* object has an array part (a_size may still be 0) */
 
#define DUK_HOBJECT_FLAG_STRICT   DUK_HEAPHDR_USER_FLAG(9) /* function: function object is strict */
 
#define DUK_HOBJECT_FLAG_NOTAIL   DUK_HEAPHDR_USER_FLAG(10) /* function: function must not be tail called */
 
#define DUK_HOBJECT_FLAG_NEWENV   DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompiledfunction) */
 
#define DUK_HOBJECT_FLAG_NAMEBINDING   DUK_HEAPHDR_USER_FLAG(12) /* function: create binding for func name (function templates only, used for named function expressions) */
 
#define DUK_HOBJECT_FLAG_CREATEARGS   DUK_HEAPHDR_USER_FLAG(13) /* function: create an arguments object on function call */
 
#define DUK_HOBJECT_FLAG_ENVRECCLOSED   DUK_HEAPHDR_USER_FLAG(14) /* envrec: (declarative) record is closed */
 
#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY   DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */
 
#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ   DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */
 
#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS   DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */
 
#define DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC   DUK_HEAPHDR_USER_FLAG(18) /* Duktape/C (nativefunction) object, exotic 'length' */
 
#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ   DUK_HEAPHDR_USER_FLAG(19) /* 'Proxy' object */
 
#define DUK_HOBJECT_FLAG_CLASS_BASE   DUK_HEAPHDR_USER_FLAG_NUMBER(20)
 
#define DUK_HOBJECT_FLAG_CLASS_BITS   5
 
#define DUK_HOBJECT_GET_CLASS_NUMBER(h)    DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)
 
#define DUK_HOBJECT_SET_CLASS_NUMBER(h, v)    DUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))
 
#define DUK_HOBJECT_GET_CLASS_MASK(h)    (1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))
 
#define DUK_HOBJECT_CLASS_AS_FLAGS(v)   (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)
 
#define DUK_HOBJECT_CLASS_UNUSED   0
 
#define DUK_HOBJECT_CLASS_ARGUMENTS   1
 
#define DUK_HOBJECT_CLASS_ARRAY   2
 
#define DUK_HOBJECT_CLASS_BOOLEAN   3
 
#define DUK_HOBJECT_CLASS_DATE   4
 
#define DUK_HOBJECT_CLASS_ERROR   5
 
#define DUK_HOBJECT_CLASS_FUNCTION   6
 
#define DUK_HOBJECT_CLASS_JSON   7
 
#define DUK_HOBJECT_CLASS_MATH   8
 
#define DUK_HOBJECT_CLASS_NUMBER   9
 
#define DUK_HOBJECT_CLASS_OBJECT   10
 
#define DUK_HOBJECT_CLASS_REGEXP   11
 
#define DUK_HOBJECT_CLASS_STRING   12
 
#define DUK_HOBJECT_CLASS_GLOBAL   13
 
#define DUK_HOBJECT_CLASS_OBJENV   14 /* custom */
 
#define DUK_HOBJECT_CLASS_DECENV   15 /* custom */
 
#define DUK_HOBJECT_CLASS_BUFFER   16 /* custom; implies DUK_HOBJECT_IS_BUFFEROBJECT */
 
#define DUK_HOBJECT_CLASS_POINTER   17 /* custom */
 
#define DUK_HOBJECT_CLASS_THREAD   18 /* custom; implies DUK_HOBJECT_IS_THREAD */
 
#define DUK_HOBJECT_CLASS_ARRAYBUFFER   19 /* implies DUK_HOBJECT_IS_BUFFEROBJECT */
 
#define DUK_HOBJECT_CLASS_DATAVIEW   20
 
#define DUK_HOBJECT_CLASS_INT8ARRAY   21
 
#define DUK_HOBJECT_CLASS_UINT8ARRAY   22
 
#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY   23
 
#define DUK_HOBJECT_CLASS_INT16ARRAY   24
 
#define DUK_HOBJECT_CLASS_UINT16ARRAY   25
 
#define DUK_HOBJECT_CLASS_INT32ARRAY   26
 
#define DUK_HOBJECT_CLASS_UINT32ARRAY   27
 
#define DUK_HOBJECT_CLASS_FLOAT32ARRAY   28
 
#define DUK_HOBJECT_CLASS_FLOAT64ARRAY   29
 
#define DUK_HOBJECT_CLASS_MAX   29
 
#define DUK_HOBJECT_CMASK_ALL   ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)
 
#define DUK_HOBJECT_CMASK_UNUSED   (1UL << DUK_HOBJECT_CLASS_UNUSED)
 
#define DUK_HOBJECT_CMASK_ARGUMENTS   (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)
 
#define DUK_HOBJECT_CMASK_ARRAY   (1UL << DUK_HOBJECT_CLASS_ARRAY)
 
#define DUK_HOBJECT_CMASK_BOOLEAN   (1UL << DUK_HOBJECT_CLASS_BOOLEAN)
 
#define DUK_HOBJECT_CMASK_DATE   (1UL << DUK_HOBJECT_CLASS_DATE)
 
#define DUK_HOBJECT_CMASK_ERROR   (1UL << DUK_HOBJECT_CLASS_ERROR)
 
#define DUK_HOBJECT_CMASK_FUNCTION   (1UL << DUK_HOBJECT_CLASS_FUNCTION)
 
#define DUK_HOBJECT_CMASK_JSON   (1UL << DUK_HOBJECT_CLASS_JSON)
 
#define DUK_HOBJECT_CMASK_MATH   (1UL << DUK_HOBJECT_CLASS_MATH)
 
#define DUK_HOBJECT_CMASK_NUMBER   (1UL << DUK_HOBJECT_CLASS_NUMBER)
 
#define DUK_HOBJECT_CMASK_OBJECT   (1UL << DUK_HOBJECT_CLASS_OBJECT)
 
#define DUK_HOBJECT_CMASK_REGEXP   (1UL << DUK_HOBJECT_CLASS_REGEXP)
 
#define DUK_HOBJECT_CMASK_STRING   (1UL << DUK_HOBJECT_CLASS_STRING)
 
#define DUK_HOBJECT_CMASK_GLOBAL   (1UL << DUK_HOBJECT_CLASS_GLOBAL)
 
#define DUK_HOBJECT_CMASK_OBJENV   (1UL << DUK_HOBJECT_CLASS_OBJENV)
 
#define DUK_HOBJECT_CMASK_DECENV   (1UL << DUK_HOBJECT_CLASS_DECENV)
 
#define DUK_HOBJECT_CMASK_BUFFER   (1UL << DUK_HOBJECT_CLASS_BUFFER)
 
#define DUK_HOBJECT_CMASK_POINTER   (1UL << DUK_HOBJECT_CLASS_POINTER)
 
#define DUK_HOBJECT_CMASK_THREAD   (1UL << DUK_HOBJECT_CLASS_THREAD)
 
#define DUK_HOBJECT_CMASK_ARRAYBUFFER   (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)
 
#define DUK_HOBJECT_CMASK_DATAVIEW   (1UL << DUK_HOBJECT_CLASS_DATAVIEW)
 
#define DUK_HOBJECT_CMASK_INT8ARRAY   (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)
 
#define DUK_HOBJECT_CMASK_UINT8ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)
 
#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY   (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)
 
#define DUK_HOBJECT_CMASK_INT16ARRAY   (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)
 
#define DUK_HOBJECT_CMASK_UINT16ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)
 
#define DUK_HOBJECT_CMASK_INT32ARRAY   (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)
 
#define DUK_HOBJECT_CMASK_UINT32ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)
 
#define DUK_HOBJECT_CMASK_FLOAT32ARRAY   (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)
 
#define DUK_HOBJECT_CMASK_FLOAT64ARRAY   (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)
 
#define DUK_HOBJECT_CMASK_ALL_BUFFEROBJECTS
 
#define DUK_HOBJECT_IS_OBJENV(h)   (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)
 
#define DUK_HOBJECT_IS_DECENV(h)   (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)
 
#define DUK_HOBJECT_IS_ENV(h)   (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))
 
#define DUK_HOBJECT_IS_ARRAY(h)   (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY)
 
#define DUK_HOBJECT_IS_COMPILEDFUNCTION(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
 
#define DUK_HOBJECT_IS_NATIVEFUNCTION(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
 
#define DUK_HOBJECT_IS_BUFFEROBJECT(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
 
#define DUK_HOBJECT_IS_THREAD(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
 
#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)
 
#define DUK_HOBJECT_IS_FUNCTION(h)
 
#define DUK_HOBJECT_IS_CALLABLE(h)
 
#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS
 
#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)
 
#define DUK_HOBJECT_HAS_EXTENSIBLE(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
 
#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
 
#define DUK_HOBJECT_HAS_BOUND(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
 
#define DUK_HOBJECT_HAS_COMPILEDFUNCTION(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
 
#define DUK_HOBJECT_HAS_NATIVEFUNCTION(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
 
#define DUK_HOBJECT_HAS_BUFFEROBJECT(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
 
#define DUK_HOBJECT_HAS_THREAD(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
 
#define DUK_HOBJECT_HAS_ARRAY_PART(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
 
#define DUK_HOBJECT_HAS_STRICT(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
 
#define DUK_HOBJECT_HAS_NOTAIL(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
 
#define DUK_HOBJECT_HAS_NEWENV(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
 
#define DUK_HOBJECT_HAS_NAMEBINDING(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
 
#define DUK_HOBJECT_HAS_CREATEARGS(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
 
#define DUK_HOBJECT_HAS_ENVRECCLOSED(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
 
#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
 
#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
 
#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
 
#define DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
 
#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
 
#define DUK_HOBJECT_SET_EXTENSIBLE(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
 
#define DUK_HOBJECT_SET_CONSTRUCTABLE(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
 
#define DUK_HOBJECT_SET_BOUND(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
 
#define DUK_HOBJECT_SET_COMPILEDFUNCTION(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
 
#define DUK_HOBJECT_SET_NATIVEFUNCTION(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
 
#define DUK_HOBJECT_SET_BUFFEROBJECT(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
 
#define DUK_HOBJECT_SET_THREAD(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
 
#define DUK_HOBJECT_SET_ARRAY_PART(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
 
#define DUK_HOBJECT_SET_STRICT(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
 
#define DUK_HOBJECT_SET_NOTAIL(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
 
#define DUK_HOBJECT_SET_NEWENV(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
 
#define DUK_HOBJECT_SET_NAMEBINDING(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
 
#define DUK_HOBJECT_SET_CREATEARGS(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
 
#define DUK_HOBJECT_SET_ENVRECCLOSED(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
 
#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
 
#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
 
#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
 
#define DUK_HOBJECT_SET_EXOTIC_DUKFUNC(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
 
#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
 
#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)
 
#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)
 
#define DUK_HOBJECT_CLEAR_BOUND(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)
 
#define DUK_HOBJECT_CLEAR_COMPILEDFUNCTION(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)
 
#define DUK_HOBJECT_CLEAR_NATIVEFUNCTION(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)
 
#define DUK_HOBJECT_CLEAR_BUFFEROBJECT(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)
 
#define DUK_HOBJECT_CLEAR_THREAD(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)
 
#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)
 
#define DUK_HOBJECT_CLEAR_STRICT(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)
 
#define DUK_HOBJECT_CLEAR_NOTAIL(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)
 
#define DUK_HOBJECT_CLEAR_NEWENV(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)
 
#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)
 
#define DUK_HOBJECT_CLEAR_CREATEARGS(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)
 
#define DUK_HOBJECT_CLEAR_ENVRECCLOSED(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)
 
#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)
 
#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)
 
#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)
 
#define DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)
 
#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)
 
#define DUK_PROPDESC_FLAG_WRITABLE   (1 << 0) /* E5 Section 8.6.1 */
 
#define DUK_PROPDESC_FLAG_ENUMERABLE   (1 << 1) /* E5 Section 8.6.1 */
 
#define DUK_PROPDESC_FLAG_CONFIGURABLE   (1 << 2) /* E5 Section 8.6.1 */
 
#define DUK_PROPDESC_FLAG_ACCESSOR   (1 << 3) /* accessor */
 
#define DUK_PROPDESC_FLAG_VIRTUAL
 
#define DUK_PROPDESC_FLAGS_MASK
 
#define DUK_PROPDESC_FLAG_NO_OVERWRITE   (1 << 4) /* internal define property: skip write silently if exists */
 
#define DUK_PROPDESC_FLAGS_NONE   0
 
#define DUK_PROPDESC_FLAGS_W   (DUK_PROPDESC_FLAG_WRITABLE)
 
#define DUK_PROPDESC_FLAGS_E   (DUK_PROPDESC_FLAG_ENUMERABLE)
 
#define DUK_PROPDESC_FLAGS_C   (DUK_PROPDESC_FLAG_CONFIGURABLE)
 
#define DUK_PROPDESC_FLAGS_WE   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)
 
#define DUK_PROPDESC_FLAGS_WC   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
 
#define DUK_PROPDESC_FLAGS_EC   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)
 
#define DUK_PROPDESC_FLAGS_WEC
 
#define DUK_GETDESC_FLAG_PUSH_VALUE   (1 << 0) /* push value to stack */
 
#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP   (1 << 1) /* don't throw for prototype loop */
 
#define DUK_ASSERT_HOBJECT_VALID(h)
 
#define DUK_HOBJECT_GET_PROPS(heap, h)    ((h)->props)
 
#define DUK_HOBJECT_SET_PROPS(heap, h, x)
 
#define DUK_HOBJECT_P_ALLOC_SIZE(h)    DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))
 
#define DUK_HOBJECT_E_GET_KEY(heap, h, i)   (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_GET_KEY_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_GET_VALUE(heap, h, i)   (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap, h, i)   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
 
#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)
 
#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h, i)   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
 
#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)
 
#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h, i)   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
 
#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)
 
#define DUK_HOBJECT_E_GET_FLAGS(heap, h, i)   (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap, h, i)   (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_A_GET_VALUE(heap, h, i)   (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i)   (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_H_GET_INDEX(heap, h, i)   (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_H_GET_INDEX_PTR(heap, h, i)   (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])
 
#define DUK_HOBJECT_E_SET_KEY(heap, h, i, k)
 
#define DUK_HOBJECT_E_SET_VALUE(heap, h, i, v)
 
#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap, h, i, v)
 
#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap, h, i, v)
 
#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap, h, i, v)
 
#define DUK_HOBJECT_E_SET_FLAGS(heap, h, i, f)
 
#define DUK_HOBJECT_A_SET_VALUE(heap, h, i, v)
 
#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap, h, i, v)    DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */
 
#define DUK_HOBJECT_H_SET_INDEX(heap, h, i, v)
 
#define DUK_HOBJECT_E_SET_FLAG_BITS(heap, h, i, mask)
 
#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap, h, i, mask)
 
#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap, h, i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)
 
#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap, h, i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
 
#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap, h, i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
 
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
 
#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap, h, i)   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
 
#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap, h, i)   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
 
#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap, h, i)   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
 
#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap, h, i)   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
 
#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap, h, i)   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)
 
#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap, h, i)   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)
 
#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap, h, i)   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)
 
#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap, h, i)   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)
 
#define DUK_PROPDESC_IS_WRITABLE(p)   (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)
 
#define DUK_PROPDESC_IS_ENUMERABLE(p)   (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)
 
#define DUK_PROPDESC_IS_CONFIGURABLE(p)   (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)
 
#define DUK_PROPDESC_IS_ACCESSOR(p)   (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)
 
#define DUK_HOBJECT_HASHIDX_UNUSED   0xffffffffUL
 
#define DUK_HOBJECT_HASHIDX_DELETED   0xfffffffeUL
 
#define DUK_HOBJECT_GET_ESIZE(h)   ((h)->e_size)
 
#define DUK_HOBJECT_SET_ESIZE(h, v)   do { (h)->e_size = (v); } while (0)
 
#define DUK_HOBJECT_GET_ENEXT(h)   ((h)->e_next)
 
#define DUK_HOBJECT_SET_ENEXT(h, v)   do { (h)->e_next = (v); } while (0)
 
#define DUK_HOBJECT_POSTINC_ENEXT(h)   ((h)->e_next++)
 
#define DUK_HOBJECT_GET_ASIZE(h)   ((h)->a_size)
 
#define DUK_HOBJECT_SET_ASIZE(h, v)   do { (h)->a_size = (v); } while (0)
 
#define DUK_HOBJECT_GET_HSIZE(h)   0
 
#define DUK_HOBJECT_SET_HSIZE(h, v)   do { DUK_ASSERT((v) == 0); } while (0)
 
#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY   10000L
 
#define DUK_HOBJECT_BOUND_CHAIN_SANITY   10000L
 
#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n)   duk_class_number_to_stridx[(n)]
 
#define DUK_HOBJECT_GET_CLASS_STRING(heap, h)
 
#define DUK_HOBJECT_GET_PROTOTYPE(heap, h)    ((h)->prototype)
 
#define DUK_HOBJECT_SET_PROTOTYPE(heap, h, x)
 
#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, p)   duk_hobject_set_prototype_updref((thr), (h), (p))
 
#define DUK_HOBJECT_MAX_PROPERTIES   0x7fffffffUL /* 2**31-1 ~= 2G properties */
 
#define DUK_HOBJECT_E_USE_HASH_LIMIT   32
 
#define DUK_HOBJECT_H_SIZE_DIVISOR   4 /* hash size approx. 1.25 times entries size */
 
#define DUK_HOBJECT_A_FAST_RESIZE_LIMIT   9 /* 112.5%, i.e. new size less than 12.5% higher -> fast resize */
 
#define DUK_HOBJECT_A_ABANDON_LIMIT   2 /* 25%, i.e. less than 25% used -> abandon */
 
#define DUK_HOBJECT_E_MIN_GROW_ADD   16
 
#define DUK_HOBJECT_E_MIN_GROW_DIVISOR   8 /* 2^3 -> 1/8 = 12.5% min growth */
 
#define DUK_HOBJECT_A_MIN_GROW_ADD   16
 
#define DUK_HOBJECT_A_MIN_GROW_DIVISOR   8 /* 2^3 -> 1/8 = 12.5% min growth */
 
#define DUK_HOBJECT_HASH_INITIAL(hash, h_size)   ((hash) % (h_size))
 
#define DUK_HOBJECT_HASH_PROBE_STEP(hash)   DUK_UTIL_GET_HASH_PROBE_STEP((hash))
 
#define DUK_PC2LINE_SKIP   64
 
#define DUK_PC2LINE_MAX_DIFF_LENGTH   (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)
 
#define duk_hobject_get_internal_value_tval_ptr(heap, obj)    duk_hobject_find_existing_entry_tval_ptr((heap), (obj), DUK_HEAP_STRING_INT_VALUE((heap)))
 
#define DUK_DELPROP_FLAG_THROW   (1 << 0)
 
#define DUK_DELPROP_FLAG_FORCE   (1 << 1)
 

Functions

DUK_INTERNAL_DECL duk_hobjectduk_hobject_alloc (duk_heap *heap, duk_uint_t hobject_flags)
 
DUK_INTERNAL_DECL duk_hcompiledfunctionduk_hcompiledfunction_alloc (duk_heap *heap, duk_uint_t hobject_flags)
 
DUK_INTERNAL_DECL duk_hnativefunctionduk_hnativefunction_alloc (duk_heap *heap, duk_uint_t hobject_flags)
 
DUK_INTERNAL duk_hbufferobjectduk_hbufferobject_alloc (duk_heap *heap, duk_uint_t hobject_flags)
 
DUK_INTERNAL_DECL duk_hthreadduk_hthread_alloc (duk_heap *heap, duk_uint_t hobject_flags)
 
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)
 
DUK_INTERNAL_DECL duk_tvalduk_hobject_find_existing_entry_tval_ptr (duk_heap *heap, duk_hobject *obj, duk_hstring *key)
 
DUK_INTERNAL_DECL duk_tvalduk_hobject_find_existing_entry_tval_ptr_and_attrs (duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *out_attrs)
 
DUK_INTERNAL_DECL duk_tvalduk_hobject_find_existing_array_entry_tval_ptr (duk_heap *heap, duk_hobject *obj, duk_uarridx_t i)
 
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)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop (duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key)
 
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)
 
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)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop (duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw (duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw (duk_hthread *thr, duk_hobject *obj, duk_hstring *key)
 
DUK_INTERNAL_DECL void duk_hobject_define_property_internal (duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags)
 
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)
 
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)
 
DUK_INTERNAL_DECL void duk_hobject_set_length (duk_hthread *thr, duk_hobject *obj, duk_uint32_t length)
 
DUK_INTERNAL_DECL void duk_hobject_set_length_zero (duk_hthread *thr, duk_hobject *obj)
 
DUK_INTERNAL_DECL duk_uint32_t duk_hobject_get_length (duk_hthread *thr, duk_hobject *obj)
 
DUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor (duk_context *ctx, duk_idx_t idx_in, duk_uint_t *out_defprop_flags, duk_idx_t *out_idx_value, duk_hobject **out_getter, duk_hobject **out_setter)
 
DUK_INTERNAL_DECL void duk_hobject_define_property_helper (duk_context *ctx, duk_uint_t defprop_flags, duk_hobject *obj, duk_hstring *key, duk_idx_t idx_value, duk_hobject *get, duk_hobject *set)
 
DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor (duk_context *ctx)
 
DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper (duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper (duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper (duk_context *ctx, duk_small_uint_t required_desc_flags)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_internal_value (duk_heap *heap, duk_hobject *obj, duk_tval *tv)
 
DUK_INTERNAL_DECL duk_hstringduk_hobject_get_internal_value_string (duk_heap *heap, duk_hobject *obj)
 
DUK_INTERNAL_DECL void duk_hobject_compact_props (duk_hthread *thr, duk_hobject *obj)
 
DUK_INTERNAL_DECL void duk_hobject_enumerator_create (duk_context *ctx, duk_small_uint_t enum_flags)
 
DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys (duk_context *ctx, duk_small_uint_t enum_flags)
 
DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next (duk_context *ctx, duk_bool_t get_value)
 
DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref (duk_hthread *thr, duk_hobject *h, duk_hobject *p)
 
DUK_INTERNAL_DECL void duk_hobject_run_finalizer (duk_hthread *thr, duk_hobject *obj)
 
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)
 

Variables

DUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx [32]
 

Macro Definition Documentation

◆ DUK_ASSERT_HOBJECT_VALID

#define DUK_ASSERT_HOBJECT_VALID ( h)
Value:
do { \
DUK_ASSERT((h) != NULL); \
DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE((h)) || \
DUK_ASSERT(!DUK_HOBJECT_IS_BUFFEROBJECT((h)) || \
} while (0)
#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY
#define DUK_HOBJECT_IS_CALLABLE(h)
#define DUK_HOBJECT_IS_BUFFEROBJECT(h)
#define DUK_HOBJECT_GET_CLASS_NUMBER(h)
#define DUK_HOBJECT_CLASS_ARRAYBUFFER
#define NULL
Definition gmacros.h:924

Definition at line 287 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 || \

◆ DUK_DELPROP_FLAG_FORCE

#define DUK_DELPROP_FLAG_FORCE   (1 << 1)

Definition at line 858 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_DELPROP_FLAG_THROW

#define DUK_DELPROP_FLAG_THROW   (1 << 0)

Definition at line 857 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_GETDESC_FLAG_IGNORE_PROTOLOOP

#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP   (1 << 1) /* don't throw for prototype loop */

Definition at line 279 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_GETDESC_FLAG_PUSH_VALUE

#define DUK_GETDESC_FLAG_PUSH_VALUE   (1 << 0) /* push value to stack */

Definition at line 278 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_ABANDON_LIMIT

#define DUK_HOBJECT_A_ABANDON_LIMIT   2 /* 25%, i.e. less than 25% used -> abandon */

Definition at line 650 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_FAST_RESIZE_LIMIT

#define DUK_HOBJECT_A_FAST_RESIZE_LIMIT   9 /* 112.5%, i.e. new size less than 12.5% higher -> fast resize */

Definition at line 646 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_GET_VALUE

#define DUK_HOBJECT_A_GET_VALUE ( heap,
h,
i )   (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])

Definition at line 478 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_GET_VALUE_PTR

#define DUK_HOBJECT_A_GET_VALUE_PTR ( heap,
h,
i )   (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])

Definition at line 479 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_MIN_GROW_ADD

#define DUK_HOBJECT_A_MIN_GROW_ADD   16

Definition at line 668 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_MIN_GROW_DIVISOR

#define DUK_HOBJECT_A_MIN_GROW_DIVISOR   8 /* 2^3 -> 1/8 = 12.5% min growth */

Definition at line 669 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_A_SET_VALUE

#define DUK_HOBJECT_A_SET_VALUE ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \
} while (0)

Definition at line 501 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \
#define DUK_HOBJECT_E_GET_FLAGS(heap, h, i)

◆ DUK_HOBJECT_A_SET_VALUE_TVAL

#define DUK_HOBJECT_A_SET_VALUE_TVAL ( heap,
h,
i,
v )    DUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v)) /* alias for above */

Definition at line 504 of file duktape-1.5.2/src-separate/duk_hobject.h.

504 DUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \
505 } while (0)
#define DUK_HOBJECT_A_GET_VALUE(heap, h, i)

◆ DUK_HOBJECT_BOUND_CHAIN_SANITY

#define DUK_HOBJECT_BOUND_CHAIN_SANITY   10000L

Definition at line 587 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_ARGUMENTS

#define DUK_HOBJECT_CLASS_ARGUMENTS   1

Definition at line 78 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_ARRAY

#define DUK_HOBJECT_CLASS_ARRAY   2

Definition at line 79 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_ARRAYBUFFER

#define DUK_HOBJECT_CLASS_ARRAYBUFFER   19 /* implies DUK_HOBJECT_IS_BUFFEROBJECT */

Definition at line 96 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_AS_FLAGS

#define DUK_HOBJECT_CLASS_AS_FLAGS ( v)    (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)

Definition at line 74 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_BOOLEAN

#define DUK_HOBJECT_CLASS_BOOLEAN   3

Definition at line 80 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_BUFFER

#define DUK_HOBJECT_CLASS_BUFFER   16 /* custom; implies DUK_HOBJECT_IS_BUFFEROBJECT */

Definition at line 93 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_DATAVIEW

#define DUK_HOBJECT_CLASS_DATAVIEW   20

Definition at line 97 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_DATE

#define DUK_HOBJECT_CLASS_DATE   4

Definition at line 81 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_DECENV

#define DUK_HOBJECT_CLASS_DECENV   15 /* custom */

Definition at line 92 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_ERROR

#define DUK_HOBJECT_CLASS_ERROR   5

Definition at line 82 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_FLOAT32ARRAY

#define DUK_HOBJECT_CLASS_FLOAT32ARRAY   28

Definition at line 105 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_FLOAT64ARRAY

#define DUK_HOBJECT_CLASS_FLOAT64ARRAY   29

Definition at line 106 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_FUNCTION

#define DUK_HOBJECT_CLASS_FUNCTION   6

Definition at line 83 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_GLOBAL

#define DUK_HOBJECT_CLASS_GLOBAL   13

Definition at line 90 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_INT16ARRAY

#define DUK_HOBJECT_CLASS_INT16ARRAY   24

Definition at line 101 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_INT32ARRAY

#define DUK_HOBJECT_CLASS_INT32ARRAY   26

Definition at line 103 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_INT8ARRAY

#define DUK_HOBJECT_CLASS_INT8ARRAY   21

Definition at line 98 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_JSON

#define DUK_HOBJECT_CLASS_JSON   7

Definition at line 84 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_MATH

#define DUK_HOBJECT_CLASS_MATH   8

Definition at line 85 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_MAX

#define DUK_HOBJECT_CLASS_MAX   29

Definition at line 107 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_NUMBER

#define DUK_HOBJECT_CLASS_NUMBER   9

Definition at line 86 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX

#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX ( n)    duk_class_number_to_stridx[(n)]

Definition at line 594 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_OBJECT

#define DUK_HOBJECT_CLASS_OBJECT   10

Definition at line 87 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_OBJENV

#define DUK_HOBJECT_CLASS_OBJENV   14 /* custom */

Definition at line 91 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_POINTER

#define DUK_HOBJECT_CLASS_POINTER   17 /* custom */

Definition at line 94 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_REGEXP

#define DUK_HOBJECT_CLASS_REGEXP   11

Definition at line 88 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_STRING

#define DUK_HOBJECT_CLASS_STRING   12

Definition at line 89 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_THREAD

#define DUK_HOBJECT_CLASS_THREAD   18 /* custom; implies DUK_HOBJECT_IS_THREAD */

Definition at line 95 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_UINT16ARRAY

#define DUK_HOBJECT_CLASS_UINT16ARRAY   25

Definition at line 102 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_UINT32ARRAY

#define DUK_HOBJECT_CLASS_UINT32ARRAY   27

Definition at line 104 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_UINT8ARRAY

#define DUK_HOBJECT_CLASS_UINT8ARRAY   22

Definition at line 99 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY

#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY   23

Definition at line 100 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLASS_UNUSED

#define DUK_HOBJECT_CLASS_UNUSED   0

Definition at line 77 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_ARRAY_PART

#define DUK_HOBJECT_CLEAR_ARRAY_PART ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)

Definition at line 236 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_BOUND

#define DUK_HOBJECT_CLEAR_BOUND ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)

Definition at line 231 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_BUFFEROBJECT

#define DUK_HOBJECT_CLEAR_BUFFEROBJECT ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)

Definition at line 234 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_COMPILEDFUNCTION

#define DUK_HOBJECT_CLEAR_COMPILEDFUNCTION ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)

Definition at line 232 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_CONSTRUCTABLE

#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)

Definition at line 230 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_CREATEARGS

#define DUK_HOBJECT_CLEAR_CREATEARGS ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)

Definition at line 241 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_ENVRECCLOSED

#define DUK_HOBJECT_CLEAR_ENVRECCLOSED ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)

Definition at line 242 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS

#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)

Definition at line 245 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXOTIC_ARRAY

#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)

Definition at line 243 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC

#define DUK_HOBJECT_CLEAR_EXOTIC_DUKFUNC ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)

Definition at line 246 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ

#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)

Definition at line 247 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ

#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)

Definition at line 244 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_EXTENSIBLE

#define DUK_HOBJECT_CLEAR_EXTENSIBLE ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)

Definition at line 229 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_NAMEBINDING

#define DUK_HOBJECT_CLEAR_NAMEBINDING ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)

Definition at line 240 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_NATIVEFUNCTION

#define DUK_HOBJECT_CLEAR_NATIVEFUNCTION ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)

Definition at line 233 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_NEWENV

#define DUK_HOBJECT_CLEAR_NEWENV ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)

Definition at line 239 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_NOTAIL

#define DUK_HOBJECT_CLEAR_NOTAIL ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)

Definition at line 238 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_STRICT

#define DUK_HOBJECT_CLEAR_STRICT ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)

Definition at line 237 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CLEAR_THREAD

#define DUK_HOBJECT_CLEAR_THREAD ( h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)

Definition at line 235 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_ALL

#define DUK_HOBJECT_CMASK_ALL   ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)

Definition at line 110 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_ALL_BUFFEROBJECTS

#define DUK_HOBJECT_CMASK_ALL_BUFFEROBJECTS
Value:
#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY

Definition at line 142 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_CMASK_ARGUMENTS

#define DUK_HOBJECT_CMASK_ARGUMENTS   (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)

Definition at line 112 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_ARRAY

#define DUK_HOBJECT_CMASK_ARRAY   (1UL << DUK_HOBJECT_CLASS_ARRAY)

Definition at line 113 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_ARRAYBUFFER

#define DUK_HOBJECT_CMASK_ARRAYBUFFER   (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)

Definition at line 130 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_BOOLEAN

#define DUK_HOBJECT_CMASK_BOOLEAN   (1UL << DUK_HOBJECT_CLASS_BOOLEAN)

Definition at line 114 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_BUFFER

#define DUK_HOBJECT_CMASK_BUFFER   (1UL << DUK_HOBJECT_CLASS_BUFFER)

Definition at line 127 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_DATAVIEW

#define DUK_HOBJECT_CMASK_DATAVIEW   (1UL << DUK_HOBJECT_CLASS_DATAVIEW)

Definition at line 131 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_DATE

#define DUK_HOBJECT_CMASK_DATE   (1UL << DUK_HOBJECT_CLASS_DATE)

Definition at line 115 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_DECENV

#define DUK_HOBJECT_CMASK_DECENV   (1UL << DUK_HOBJECT_CLASS_DECENV)

Definition at line 126 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_ERROR

#define DUK_HOBJECT_CMASK_ERROR   (1UL << DUK_HOBJECT_CLASS_ERROR)

Definition at line 116 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_FLOAT32ARRAY

#define DUK_HOBJECT_CMASK_FLOAT32ARRAY   (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)

Definition at line 139 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_FLOAT64ARRAY

#define DUK_HOBJECT_CMASK_FLOAT64ARRAY   (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)

Definition at line 140 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_FUNCTION

#define DUK_HOBJECT_CMASK_FUNCTION   (1UL << DUK_HOBJECT_CLASS_FUNCTION)

Definition at line 117 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_GLOBAL

#define DUK_HOBJECT_CMASK_GLOBAL   (1UL << DUK_HOBJECT_CLASS_GLOBAL)

Definition at line 124 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_INT16ARRAY

#define DUK_HOBJECT_CMASK_INT16ARRAY   (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)

Definition at line 135 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_INT32ARRAY

#define DUK_HOBJECT_CMASK_INT32ARRAY   (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)

Definition at line 137 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_INT8ARRAY

#define DUK_HOBJECT_CMASK_INT8ARRAY   (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)

Definition at line 132 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_JSON

#define DUK_HOBJECT_CMASK_JSON   (1UL << DUK_HOBJECT_CLASS_JSON)

Definition at line 118 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_MATH

#define DUK_HOBJECT_CMASK_MATH   (1UL << DUK_HOBJECT_CLASS_MATH)

Definition at line 119 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_NUMBER

#define DUK_HOBJECT_CMASK_NUMBER   (1UL << DUK_HOBJECT_CLASS_NUMBER)

Definition at line 120 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_OBJECT

#define DUK_HOBJECT_CMASK_OBJECT   (1UL << DUK_HOBJECT_CLASS_OBJECT)

Definition at line 121 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_OBJENV

#define DUK_HOBJECT_CMASK_OBJENV   (1UL << DUK_HOBJECT_CLASS_OBJENV)

Definition at line 125 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_POINTER

#define DUK_HOBJECT_CMASK_POINTER   (1UL << DUK_HOBJECT_CLASS_POINTER)

Definition at line 128 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_REGEXP

#define DUK_HOBJECT_CMASK_REGEXP   (1UL << DUK_HOBJECT_CLASS_REGEXP)

Definition at line 122 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_STRING

#define DUK_HOBJECT_CMASK_STRING   (1UL << DUK_HOBJECT_CLASS_STRING)

Definition at line 123 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_THREAD

#define DUK_HOBJECT_CMASK_THREAD   (1UL << DUK_HOBJECT_CLASS_THREAD)

Definition at line 129 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_UINT16ARRAY

#define DUK_HOBJECT_CMASK_UINT16ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)

Definition at line 136 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_UINT32ARRAY

#define DUK_HOBJECT_CMASK_UINT32ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)

Definition at line 138 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_UINT8ARRAY

#define DUK_HOBJECT_CMASK_UINT8ARRAY   (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)

Definition at line 133 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY

#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY   (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)

Definition at line 134 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_CMASK_UNUSED

#define DUK_HOBJECT_CMASK_UNUSED   (1UL << DUK_HOBJECT_CLASS_UNUSED)

Definition at line 111 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_CLEAR_FLAG_BITS

#define DUK_HOBJECT_E_CLEAR_FLAG_BITS ( heap,
h,
i,
mask )
Value:
do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \
} while (0)
#define mask(n)

Definition at line 514 of file duktape-1.5.2/src-separate/duk_hobject.h.

514 } while (0)
515
516#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask) do { \

◆ DUK_HOBJECT_E_GET_FLAGS

#define DUK_HOBJECT_E_GET_FLAGS ( heap,
h,
i )   (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])

Definition at line 476 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_FLAGS_PTR

#define DUK_HOBJECT_E_GET_FLAGS_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])

Definition at line 477 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_KEY

#define DUK_HOBJECT_E_GET_KEY ( heap,
h,
i )   (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])

Definition at line 466 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_KEY_PTR

#define DUK_HOBJECT_E_GET_KEY_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])

Definition at line 467 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE

#define DUK_HOBJECT_E_GET_VALUE ( heap,
h,
i )   (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])

Definition at line 468 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_GETTER

#define DUK_HOBJECT_E_GET_VALUE_GETTER ( heap,
h,
i )   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)

Definition at line 472 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_GETTER_PTR

#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)

Definition at line 473 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_PTR

#define DUK_HOBJECT_E_GET_VALUE_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])

Definition at line 469 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_SETTER

#define DUK_HOBJECT_E_GET_VALUE_SETTER ( heap,
h,
i )   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)

Definition at line 474 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_SETTER_PTR

#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)

Definition at line 475 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_TVAL

#define DUK_HOBJECT_E_GET_VALUE_TVAL ( heap,
h,
i )   (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)

Definition at line 470 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_GET_VALUE_TVAL_PTR

#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR ( heap,
h,
i )   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)

Definition at line 471 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_MIN_GROW_ADD

#define DUK_HOBJECT_E_MIN_GROW_ADD   16

Definition at line 664 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_MIN_GROW_DIVISOR

#define DUK_HOBJECT_E_MIN_GROW_DIVISOR   8 /* 2^3 -> 1/8 = 12.5% min growth */

Definition at line 665 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SET_FLAG_BITS

#define DUK_HOBJECT_E_SET_FLAG_BITS ( heap,
h,
i,
mask )
Value:
do { \
DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \
} while (0)

Definition at line 510 of file duktape-1.5.2/src-separate/duk_hobject.h.

510 } while (0)
511
512#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask) do { \

◆ DUK_HOBJECT_E_SET_FLAGS

#define DUK_HOBJECT_E_SET_FLAGS ( heap,
h,
i,
f )
Value:
do { \
DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \
} while (0)

Definition at line 498 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \
#define DUK_HOBJECT_E_GET_VALUE(heap, h, i)

◆ DUK_HOBJECT_E_SET_KEY

#define DUK_HOBJECT_E_SET_KEY ( heap,
h,
i,
k )
Value:
do { \
DUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \
} while (0)

Definition at line 483 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \

◆ DUK_HOBJECT_E_SET_VALUE

#define DUK_HOBJECT_E_SET_VALUE ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \
} while (0)

Definition at line 486 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \
#define DUK_HOBJECT_E_GET_KEY(heap, h, i)

◆ DUK_HOBJECT_E_SET_VALUE_GETTER

#define DUK_HOBJECT_E_SET_VALUE_GETTER ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \
} while (0)

Definition at line 492 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \

◆ DUK_HOBJECT_E_SET_VALUE_SETTER

#define DUK_HOBJECT_E_SET_VALUE_SETTER ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \
} while (0)

Definition at line 495 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \

◆ DUK_HOBJECT_E_SET_VALUE_TVAL

#define DUK_HOBJECT_E_SET_VALUE_TVAL ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \
} while (0)

Definition at line 489 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \

◆ DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR

#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR ( heap,
h,
i )   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)

Definition at line 531 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE

#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE ( heap,
h,
i )   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)

Definition at line 530 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE

#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE ( heap,
h,
i )   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)

Definition at line 529 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE

#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE ( heap,
h,
i )   DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)

Definition at line 528 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_IS_ACCESSOR

#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR ( heap,
h,
i )   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)

Definition at line 521 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE

#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE ( heap,
h,
i )   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)

Definition at line 520 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_IS_ENUMERABLE

#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE ( heap,
h,
i )   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)

Definition at line 519 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_IS_WRITABLE

#define DUK_HOBJECT_E_SLOT_IS_WRITABLE ( heap,
h,
i )   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)

Definition at line 518 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_SET_ACCESSOR

#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR ( heap,
h,
i )   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)

Definition at line 526 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE

#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE ( heap,
h,
i )   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)

Definition at line 525 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_SET_ENUMERABLE

#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE ( heap,
h,
i )   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)

Definition at line 524 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_SLOT_SET_WRITABLE

#define DUK_HOBJECT_E_SLOT_SET_WRITABLE ( heap,
h,
i )   DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)

Definition at line 523 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_E_USE_HASH_LIMIT

#define DUK_HOBJECT_E_USE_HASH_LIMIT   32

Definition at line 640 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS

#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS
Value:

Definition at line 180 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_FLAG_ARRAY_PART

#define DUK_HOBJECT_FLAG_ARRAY_PART   DUK_HEAPHDR_USER_FLAG(8) /* object has an array part (a_size may still be 0) */

Definition at line 45 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_BOUND

#define DUK_HOBJECT_FLAG_BOUND   DUK_HEAPHDR_USER_FLAG(2) /* object established using Function.prototype.bind() */

Definition at line 40 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_BUFFEROBJECT

#define DUK_HOBJECT_FLAG_BUFFEROBJECT   DUK_HEAPHDR_USER_FLAG(6) /* object is a buffer object (duk_hbufferobject) (always exotic) */

Definition at line 43 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_CLASS_BASE

#define DUK_HOBJECT_FLAG_CLASS_BASE   DUK_HEAPHDR_USER_FLAG_NUMBER(20)

Definition at line 58 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_CLASS_BITS

#define DUK_HOBJECT_FLAG_CLASS_BITS   5

Definition at line 59 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_COMPILEDFUNCTION

#define DUK_HOBJECT_FLAG_COMPILEDFUNCTION   DUK_HEAPHDR_USER_FLAG(4) /* object is a compiled function (duk_hcompiledfunction) */

Definition at line 41 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_CONSTRUCTABLE

#define DUK_HOBJECT_FLAG_CONSTRUCTABLE   DUK_HEAPHDR_USER_FLAG(1) /* object is constructable */

Definition at line 39 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_CREATEARGS

#define DUK_HOBJECT_FLAG_CREATEARGS   DUK_HEAPHDR_USER_FLAG(13) /* function: create an arguments object on function call */

Definition at line 50 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_ENVRECCLOSED

#define DUK_HOBJECT_FLAG_ENVRECCLOSED   DUK_HEAPHDR_USER_FLAG(14) /* envrec: (declarative) record is closed */

Definition at line 51 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS

#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS   DUK_HEAPHDR_USER_FLAG(17) /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */

Definition at line 54 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXOTIC_ARRAY

#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY   DUK_HEAPHDR_USER_FLAG(15) /* 'Array' object, array length and index exotic behavior */

Definition at line 52 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC

#define DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC   DUK_HEAPHDR_USER_FLAG(18) /* Duktape/C (nativefunction) object, exotic 'length' */

Definition at line 55 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ

#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ   DUK_HEAPHDR_USER_FLAG(19) /* 'Proxy' object */

Definition at line 56 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ

#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ   DUK_HEAPHDR_USER_FLAG(16) /* 'String' object, array index exotic behavior */

Definition at line 53 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_EXTENSIBLE

#define DUK_HOBJECT_FLAG_EXTENSIBLE   DUK_HEAPHDR_USER_FLAG(0) /* object is extensible */

Definition at line 38 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_NAMEBINDING

#define DUK_HOBJECT_FLAG_NAMEBINDING   DUK_HEAPHDR_USER_FLAG(12) /* function: create binding for func name (function templates only, used for named function expressions) */

Definition at line 49 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_NATIVEFUNCTION

#define DUK_HOBJECT_FLAG_NATIVEFUNCTION   DUK_HEAPHDR_USER_FLAG(5) /* object is a native function (duk_hnativefunction) */

Definition at line 42 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_NEWENV

#define DUK_HOBJECT_FLAG_NEWENV   DUK_HEAPHDR_USER_FLAG(11) /* function: create new environment when called (see duk_hcompiledfunction) */

Definition at line 48 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_NOTAIL

#define DUK_HOBJECT_FLAG_NOTAIL   DUK_HEAPHDR_USER_FLAG(10) /* function: function must not be tail called */

Definition at line 47 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_STRICT

#define DUK_HOBJECT_FLAG_STRICT   DUK_HEAPHDR_USER_FLAG(9) /* function: function object is strict */

Definition at line 46 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_FLAG_THREAD

#define DUK_HOBJECT_FLAG_THREAD   DUK_HEAPHDR_USER_FLAG(7) /* object is a thread (duk_hthread) */

Definition at line 44 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_GET_ASIZE

#define DUK_HOBJECT_GET_ASIZE ( h)    ((h)->a_size)

Definition at line 566 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_GET_CLASS_MASK

#define DUK_HOBJECT_GET_CLASS_MASK ( h)     (1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))

Definition at line 66 of file duktape-1.5.2/src-separate/duk_hobject.h.

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))

◆ DUK_HOBJECT_GET_CLASS_NUMBER

#define DUK_HOBJECT_GET_CLASS_NUMBER ( h)     DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)

Definition at line 61 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_GET_CLASS_STRING

#define DUK_HOBJECT_GET_CLASS_STRING ( heap,
h )
Value:

Definition at line 596 of file duktape-1.5.2/src-separate/duk_hobject.h.

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), \

◆ DUK_HOBJECT_GET_ENEXT

#define DUK_HOBJECT_GET_ENEXT ( h)    ((h)->e_next)

Definition at line 563 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_GET_ESIZE

#define DUK_HOBJECT_GET_ESIZE ( h)    ((h)->e_size)

Definition at line 561 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_GET_HSIZE

#define DUK_HOBJECT_GET_HSIZE ( h)    0

Definition at line 572 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ duk_hobject_get_internal_value_tval_ptr

#define duk_hobject_get_internal_value_tval_ptr ( heap,
obj )    duk_hobject_find_existing_entry_tval_ptr((heap), (obj), DUK_HEAP_STRING_INT_VALUE((heap)))

Definition at line 847 of file duktape-1.5.2/src-separate/duk_hobject.h.

847 * slot for internal value; this call can then access it directly.
848 */
int value
Definition lsqlite3.c:2155

◆ DUK_HOBJECT_GET_PROPS

#define DUK_HOBJECT_GET_PROPS ( heap,
h )    ((h)->props)

Definition at line 317 of file duktape-1.5.2/src-separate/duk_hobject.h.

317 } while (0)
318#else

◆ DUK_HOBJECT_GET_PROTOTYPE

#define DUK_HOBJECT_GET_PROTOTYPE ( heap,
h )    ((h)->prototype)

Definition at line 613 of file duktape-1.5.2/src-separate/duk_hobject.h.

613 } while (0)
614#else

◆ DUK_HOBJECT_H_GET_INDEX

#define DUK_HOBJECT_H_GET_INDEX ( heap,
h,
i )   (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])

Definition at line 480 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_H_GET_INDEX_PTR

#define DUK_HOBJECT_H_GET_INDEX_PTR ( heap,
h,
i )   (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])

Definition at line 481 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_H_SET_INDEX

#define DUK_HOBJECT_H_SET_INDEX ( heap,
h,
i,
v )
Value:
do { \
DUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \
} while (0)

Definition at line 506 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 { \

◆ DUK_HOBJECT_H_SIZE_DIVISOR

#define DUK_HOBJECT_H_SIZE_DIVISOR   4 /* hash size approx. 1.25 times entries size */

Definition at line 643 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_ARRAY_PART

#define DUK_HOBJECT_HAS_ARRAY_PART ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)

Definition at line 196 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_BOUND

#define DUK_HOBJECT_HAS_BOUND ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)

Definition at line 191 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_BUFFEROBJECT

#define DUK_HOBJECT_HAS_BUFFEROBJECT ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)

Definition at line 194 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_COMPILEDFUNCTION

#define DUK_HOBJECT_HAS_COMPILEDFUNCTION ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)

Definition at line 192 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_CONSTRUCTABLE

#define DUK_HOBJECT_HAS_CONSTRUCTABLE ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)

Definition at line 190 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_CREATEARGS

#define DUK_HOBJECT_HAS_CREATEARGS ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)

Definition at line 201 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_ENVRECCLOSED

#define DUK_HOBJECT_HAS_ENVRECCLOSED ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)

Definition at line 202 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS

#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)

Definition at line 205 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_ARRAY

#define DUK_HOBJECT_HAS_EXOTIC_ARRAY ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)

Definition at line 203 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR

#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)

Definition at line 187 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_DUKFUNC

#define DUK_HOBJECT_HAS_EXOTIC_DUKFUNC ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)

Definition at line 206 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ

#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)

Definition at line 207 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ

#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)

Definition at line 204 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_EXTENSIBLE

#define DUK_HOBJECT_HAS_EXTENSIBLE ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)

Definition at line 189 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_NAMEBINDING

#define DUK_HOBJECT_HAS_NAMEBINDING ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)

Definition at line 200 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_NATIVEFUNCTION

#define DUK_HOBJECT_HAS_NATIVEFUNCTION ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)

Definition at line 193 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_NEWENV

#define DUK_HOBJECT_HAS_NEWENV ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)

Definition at line 199 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_NOTAIL

#define DUK_HOBJECT_HAS_NOTAIL ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)

Definition at line 198 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_STRICT

#define DUK_HOBJECT_HAS_STRICT ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)

Definition at line 197 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HAS_THREAD

#define DUK_HOBJECT_HAS_THREAD ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)

Definition at line 195 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HASH_INITIAL

#define DUK_HOBJECT_HASH_INITIAL ( hash,
h_size )   ((hash) % (h_size))

Definition at line 672 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HASH_PROBE_STEP

#define DUK_HOBJECT_HASH_PROBE_STEP ( hash)    DUK_UTIL_GET_HASH_PROBE_STEP((hash))

Definition at line 673 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HASHIDX_DELETED

#define DUK_HOBJECT_HASHIDX_DELETED   0xfffffffeUL

Definition at line 539 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_HASHIDX_UNUSED

#define DUK_HOBJECT_HASHIDX_UNUSED   0xffffffffUL

Definition at line 538 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_ARRAY

#define DUK_HOBJECT_IS_ARRAY ( h)    (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_ARRAY)

Definition at line 159 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_BUFFEROBJECT

#define DUK_HOBJECT_IS_BUFFEROBJECT ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)

Definition at line 162 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_CALLABLE

#define DUK_HOBJECT_IS_CALLABLE ( h)
Value:

Definition at line 174 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_IS_COMPILEDFUNCTION

#define DUK_HOBJECT_IS_COMPILEDFUNCTION ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)

Definition at line 160 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_DECENV

#define DUK_HOBJECT_IS_DECENV ( h)    (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)

Definition at line 157 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_ENV

#define DUK_HOBJECT_IS_ENV ( h)    (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))

Definition at line 158 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_FUNCTION

#define DUK_HOBJECT_IS_FUNCTION ( h)
Value:

Definition at line 169 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_IS_NATIVEFUNCTION

#define DUK_HOBJECT_IS_NATIVEFUNCTION ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)

Definition at line 161 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_NONBOUND_FUNCTION

#define DUK_HOBJECT_IS_NONBOUND_FUNCTION ( h)
Value:

Definition at line 165 of file duktape-1.5.2/src-separate/duk_hobject.h.

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)

◆ DUK_HOBJECT_IS_OBJENV

#define DUK_HOBJECT_IS_OBJENV ( h)    (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)

Definition at line 156 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_IS_THREAD

#define DUK_HOBJECT_IS_THREAD ( h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)

Definition at line 163 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_MAX_PROPERTIES

#define DUK_HOBJECT_MAX_PROPERTIES   0x7fffffffUL /* 2**31-1 ~= 2G properties */

Definition at line 636 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_P_ALLOC_SIZE

#define DUK_HOBJECT_P_ALLOC_SIZE ( h)     DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))

Definition at line 463 of file duktape-1.5.2/src-separate/duk_hobject.h.

463#endif /* hobject property layout */
464

◆ DUK_HOBJECT_POSTINC_ENEXT

#define DUK_HOBJECT_POSTINC_ENEXT ( h)    ((h)->e_next++)

Definition at line 565 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY

#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY   10000L

Definition at line 584 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_ARRAY_PART

#define DUK_HOBJECT_SET_ARRAY_PART ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)

Definition at line 216 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_ASIZE

#define DUK_HOBJECT_SET_ASIZE ( h,
v )   do { (h)->a_size = (v); } while (0)

Definition at line 567 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_BOUND

#define DUK_HOBJECT_SET_BOUND ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUND)

Definition at line 211 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_BUFFEROBJECT

#define DUK_HOBJECT_SET_BUFFEROBJECT ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFFEROBJECT)

Definition at line 214 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_CLASS_NUMBER

#define DUK_HOBJECT_SET_CLASS_NUMBER ( h,
v )    DUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))

Definition at line 63 of file duktape-1.5.2/src-separate/duk_hobject.h.

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))

◆ DUK_HOBJECT_SET_COMPILEDFUNCTION

#define DUK_HOBJECT_SET_COMPILEDFUNCTION ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPILEDFUNCTION)

Definition at line 212 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_CONSTRUCTABLE

#define DUK_HOBJECT_SET_CONSTRUCTABLE ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)

Definition at line 210 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_CREATEARGS

#define DUK_HOBJECT_SET_CREATEARGS ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)

Definition at line 221 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_ENEXT

#define DUK_HOBJECT_SET_ENEXT ( h,
v )   do { (h)->e_next = (v); } while (0)

Definition at line 564 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_ENVRECCLOSED

#define DUK_HOBJECT_SET_ENVRECCLOSED ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ENVRECCLOSED)

Definition at line 222 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_ESIZE

#define DUK_HOBJECT_SET_ESIZE ( h,
v )   do { (h)->e_size = (v); } while (0)

Definition at line 562 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXOTIC_ARGUMENTS

#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)

Definition at line 225 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXOTIC_ARRAY

#define DUK_HOBJECT_SET_EXOTIC_ARRAY ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)

Definition at line 223 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXOTIC_DUKFUNC

#define DUK_HOBJECT_SET_EXOTIC_DUKFUNC ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_DUKFUNC)

Definition at line 226 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXOTIC_PROXYOBJ

#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)

Definition at line 227 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXOTIC_STRINGOBJ

#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)

Definition at line 224 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_EXTENSIBLE

#define DUK_HOBJECT_SET_EXTENSIBLE ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)

Definition at line 209 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_HSIZE

#define DUK_HOBJECT_SET_HSIZE ( h,
v )   do { DUK_ASSERT((v) == 0); } while (0)

Definition at line 573 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_NAMEBINDING

#define DUK_HOBJECT_SET_NAMEBINDING ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)

Definition at line 220 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_NATIVEFUNCTION

#define DUK_HOBJECT_SET_NATIVEFUNCTION ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATIVEFUNCTION)

Definition at line 213 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_NEWENV

#define DUK_HOBJECT_SET_NEWENV ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)

Definition at line 219 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_NOTAIL

#define DUK_HOBJECT_SET_NOTAIL ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)

Definition at line 218 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_PROPS

#define DUK_HOBJECT_SET_PROPS ( heap,
h,
x )
Value:
do { \
(h)->props = (duk_uint8_t *) (x); \
} while (0)

Definition at line 319 of file duktape-1.5.2/src-separate/duk_hobject.h.

319#define DUK_HOBJECT_GET_PROPS(heap,h) \
320 ((h)->props)
321#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \

◆ DUK_HOBJECT_SET_PROTOTYPE

#define DUK_HOBJECT_SET_PROTOTYPE ( heap,
h,
x )
Value:
do { \
(h)->prototype = (x); \
} while (0)

Definition at line 615 of file duktape-1.5.2/src-separate/duk_hobject.h.

615#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \
616 ((h)->prototype)
617#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \

◆ DUK_HOBJECT_SET_PROTOTYPE_UPDREF

#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF ( thr,
h,
p )   duk_hobject_set_prototype_updref((thr), (h), (p))

Definition at line 621 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_STRICT

#define DUK_HOBJECT_SET_STRICT ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)

Definition at line 217 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_HOBJECT_SET_THREAD

#define DUK_HOBJECT_SET_THREAD ( h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_THREAD)

Definition at line 215 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PC2LINE_MAX_DIFF_LENGTH

#define DUK_PC2LINE_MAX_DIFF_LENGTH   (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)

Definition at line 682 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PC2LINE_SKIP

#define DUK_PC2LINE_SKIP   64

Definition at line 679 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_ACCESSOR

#define DUK_PROPDESC_FLAG_ACCESSOR   (1 << 3) /* accessor */

Definition at line 253 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_CONFIGURABLE

#define DUK_PROPDESC_FLAG_CONFIGURABLE   (1 << 2) /* E5 Section 8.6.1 */

Definition at line 252 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_ENUMERABLE

#define DUK_PROPDESC_FLAG_ENUMERABLE   (1 << 1) /* E5 Section 8.6.1 */

Definition at line 251 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_NO_OVERWRITE

#define DUK_PROPDESC_FLAG_NO_OVERWRITE   (1 << 4) /* internal define property: skip write silently if exists */

Definition at line 263 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_VIRTUAL

#define DUK_PROPDESC_FLAG_VIRTUAL
Value:
(1 << 4) /* property is virtual: used in duk_propdesc, never stored
* (used by e.g. buffer virtual properties)
*/

Definition at line 254 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAG_WRITABLE

#define DUK_PROPDESC_FLAG_WRITABLE   (1 << 0) /* E5 Section 8.6.1 */

Definition at line 250 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_C

#define DUK_PROPDESC_FLAGS_C   (DUK_PROPDESC_FLAG_CONFIGURABLE)

Definition at line 269 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_E

#define DUK_PROPDESC_FLAGS_E   (DUK_PROPDESC_FLAG_ENUMERABLE)

Definition at line 268 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_EC

#define DUK_PROPDESC_FLAGS_EC   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)

Definition at line 272 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_MASK

#define DUK_PROPDESC_FLAGS_MASK

◆ DUK_PROPDESC_FLAGS_NONE

#define DUK_PROPDESC_FLAGS_NONE   0

Definition at line 266 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_W

#define DUK_PROPDESC_FLAGS_W   (DUK_PROPDESC_FLAG_WRITABLE)

Definition at line 267 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_WC

#define DUK_PROPDESC_FLAGS_WC   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)

Definition at line 271 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_WE

#define DUK_PROPDESC_FLAGS_WE   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)

Definition at line 270 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_FLAGS_WEC

#define DUK_PROPDESC_FLAGS_WEC
Value:

Definition at line 273 of file duktape-1.5.2/src-separate/duk_hobject.h.

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 | \

◆ DUK_PROPDESC_IS_ACCESSOR

#define DUK_PROPDESC_IS_ACCESSOR ( p)    (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)

Definition at line 536 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_IS_CONFIGURABLE

#define DUK_PROPDESC_IS_CONFIGURABLE ( p)    (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)

Definition at line 535 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_IS_ENUMERABLE

#define DUK_PROPDESC_IS_ENUMERABLE ( p)    (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)

Definition at line 534 of file duktape-1.5.2/src-separate/duk_hobject.h.

◆ DUK_PROPDESC_IS_WRITABLE

#define DUK_PROPDESC_IS_WRITABLE ( p)    (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)

Definition at line 533 of file duktape-1.5.2/src-separate/duk_hobject.h.

Function Documentation

◆ duk_hbufferobject_alloc()

DUK_INTERNAL duk_hbufferobject * duk_hbufferobject_alloc ( duk_heap * heap,
duk_uint_t hobject_flags )

Definition at line 45950 of file duktape-1.5.2/src-noline/duktape.c.

45953 {
45954 return NULL;
45955 }
45956 DUK_MEMZERO(res, sizeof(duk_hnativefunction));
45957
45958 duk__init_object_parts(heap, &res->obj, hobject_flags);
45959
45960#ifdef DUK_USE_EXPLICIT_NULL_INIT
45961 res->func = NULL;
45962#endif
45963
45964 return res;
45965}
45966
duk_uint_fast32_t duk_uint_t
#define DUK_MEMZERO(p, n)
DUK_INTERNAL duk_hbufferobject * duk_hbufferobject_alloc(duk_heap *heap, duk_uint_t hobject_flags)
DUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_hobject *obj, duk_uint_t hobject_flags)

◆ duk_hcompiledfunction_alloc()

DUK_INTERNAL_DECL duk_hcompiledfunction * duk_hcompiledfunction_alloc ( duk_heap * heap,
duk_uint_t hobject_flags )

Definition at line 45908 of file duktape-1.5.2/src-noline/duktape.c.

45915 {
45916 return NULL;
45917 }
45918 DUK_MEMZERO(res, sizeof(duk_hobject));
45919
45920 duk__init_object_parts(heap, res, hobject_flags);
45921
45922 return res;
45923}
45924
45927
45928 res = (duk_hcompiledfunction *) DUK_ALLOC(heap, sizeof(duk_hcompiledfunction));
45929 if (!res) {
45930 return NULL;
#define DUK_ALLOC(heap, size)
DUK_INTERNAL_DECL duk_hcompiledfunction * duk_hcompiledfunction_alloc(duk_heap *heap, duk_uint_t hobject_flags)

◆ duk_hnativefunction_alloc()

DUK_INTERNAL_DECL duk_hnativefunction * duk_hnativefunction_alloc ( duk_heap * heap,
duk_uint_t hobject_flags )

Definition at line 45932 of file duktape-1.5.2/src-noline/duktape.c.

◆ duk_hobject_alloc()

DUK_INTERNAL_DECL duk_hobject * duk_hobject_alloc ( duk_heap * heap,
duk_uint_t hobject_flags )

Definition at line 45887 of file duktape-1.5.2/src-noline/duktape.c.

45887 : empty objects consume a minimum
45888 * amount of memory. Further, an initial allocation might fail and cause
45889 * 'obj' to "leak" (require a mark-and-sweep) since it is not reachable yet.
45890 */
45891}
45892
45893/*
45894 * Allocate an duk_hobject.
45895 *
45896 * The allocated object has no allocation for properties; the caller may
45897 * want to force a resize if a desired size is known.
45898 *
45899 * The allocated object has zero reference count and is not reachable.
45900 * The caller MUST make the object reachable and increase its reference
45901 * count before invoking any operation that might require memory allocation.
45902 */
45903
45905 duk_hobject *res;
45906
DUK_INTERNAL_DECL duk_hobject * duk_hobject_alloc(duk_heap *heap, duk_uint_t hobject_flags)

◆ duk_hobject_compact_props()

DUK_INTERNAL_DECL void duk_hobject_compact_props ( duk_hthread * thr,
duk_hobject * obj )

Definition at line 48116 of file duktape-1.5.2/src-noline/duktape.c.

48133 {
48134 duk_uint32_t e_size; /* currently used -> new size */
48135 duk_uint32_t a_size; /* currently required */
48136 duk_uint32_t a_used; /* actually used */
48137 duk_uint32_t h_size;
48138 duk_bool_t abandon_array;
48139
48140 DUK_ASSERT(thr != NULL);
48141 DUK_ASSERT(obj != NULL);
48142
48143#if defined(DUK_USE_ROM_OBJECTS)
48145 DUK_DD(DUK_DDPRINT("ignore attempt to compact a rom object"));
48146 return;
48147 }
48148#endif
48149
48150 e_size = duk__count_used_e_keys(thr, obj);
48151 duk__compute_a_stats(thr, obj, &a_used, &a_size);
48152
48153 DUK_DD(DUK_DDPRINT("compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, "
48154 "resized array density would be: %ld/%ld = %lf",
48155 (long) e_size, (long) a_used, (long) a_size,
48156 (long) a_used, (long) a_size,
48157 (double) a_used / (double) a_size));
48158
48159 if (duk__abandon_array_density_check(a_used, a_size)) {
48160 DUK_DD(DUK_DDPRINT("decided to abandon array during compaction, a_used=%ld, a_size=%ld",
48161 (long) a_used, (long) a_size));
48162 abandon_array = 1;
48163 e_size += a_used;
48164 a_size = 0;
48165 } else {
48166 DUK_DD(DUK_DDPRINT("decided to keep array during compaction"));
48167 abandon_array = 0;
duk_small_int_t duk_bool_t
DUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size)
#define DUK_HEAPHDR_HAS_READONLY(h)
DUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj)
DUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size)

◆ duk_hobject_define_accessor_internal()

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 )

Definition at line 51763 of file duktape-1.5.2/src-noline/duktape.c.

51780 {
51781 duk_context *ctx = (duk_context *) thr;
51782 duk_int_t e_idx;
51783 duk_int_t h_idx;
51784
51785 DUK_DDD(DUK_DDDPRINT("define new accessor (internal): thr=%p, obj=%!O, key=%!O, "
51786 "getter=%!O, setter=%!O, flags=0x%02lx",
51787 (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,
51788 (duk_heaphdr *) getter, (duk_heaphdr *) setter,
51789 (unsigned long) propflags));
51790
51791 DUK_ASSERT(thr != NULL);
51792 DUK_ASSERT(thr->heap != NULL);
51793 DUK_ASSERT(obj != NULL);
51794 DUK_ASSERT(key != NULL);
51795 DUK_ASSERT((propflags & ~DUK_PROPDESC_FLAGS_MASK) == 0);
51796 /* setter and/or getter may be NULL */
51798
duk_int_fast32_t duk_int_t
#define DUK_PROPDESC_FLAGS_MASK

◆ duk_hobject_define_property_helper()

DUK_INTERNAL_DECL void duk_hobject_define_property_helper ( duk_context * ctx,
duk_uint_t defprop_flags,
duk_hobject * obj,
duk_hstring * key,
duk_idx_t idx_value,
duk_hobject * get,
duk_hobject * set )

Definition at line 52079 of file duktape-1.5.2/src-noline/duktape.c.

52081 : Ecmascript compliant [[DefineOwnProperty]](P, Desc, Throw) is not
52082 * implemented directly, but Object.defineProperty() serves its purpose.
52083 * We don't need the [[DefineOwnProperty]] internally and we don't have a
52084 * property descriptor with 'missing values' so it's easier to avoid it
52085 * entirely.
52086 *
52087 * Note: this is only called for actual objects, not primitive values.
52088 * This must support virtual properties for full objects (e.g. Strings)
52089 * but not for plain values (e.g. strings). Lightfuncs, even though
52090 * primitive in a sense, are treated like objects and accepted as target
52091 * values.
52092 */
52093
52094/* XXX: this is a major target for size optimization */
52095DUK_INTERNAL
52096void duk_hobject_define_property_helper(duk_context *ctx,
52097 duk_uint_t defprop_flags,
52098 duk_hobject *obj,
52099 duk_hstring *key,
52100 duk_idx_t idx_value,
52101 duk_hobject *get,
52102 duk_hobject *set) {
52103 duk_hthread *thr = (duk_hthread *) ctx;
52104 duk_uint32_t arr_idx;
52105 duk_tval tv;
52106 duk_bool_t has_enumerable;
52107 duk_bool_t has_configurable;
52108 duk_bool_t has_writable;
52109 duk_bool_t has_value;
52110 duk_bool_t has_get;
52111 duk_bool_t has_set;
52112 duk_bool_t is_enumerable;
52113 duk_bool_t is_configurable;
52114 duk_bool_t is_writable;
52115 duk_bool_t throw_flag;
52116 duk_bool_t force_flag;
52117 duk_small_uint_t new_flags;
52118 duk_propdesc curr;
52119 duk_uint32_t arridx_new_array_length; /* != 0 => post-update for array 'length' (used when key is an array index) */
52120 duk_uint32_t arrlen_old_len;
52121 duk_uint32_t arrlen_new_len;
52122 duk_bool_t pending_write_protect;
52123
52124 DUK_ASSERT(thr != NULL);
52125 DUK_ASSERT(thr->heap != NULL);
52126 DUK_ASSERT(ctx != NULL);
52127 DUK_ASSERT(obj != NULL);
52128 DUK_ASSERT(key != NULL);
52129 /* idx_value may be < 0 (no value), set and get may be NULL */
52130
52131 DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
52132
52133 /* All the flags fit in 16 bits, so will fit into duk_bool_t. */
52134
52135 has_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);
52136 has_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);
52137 has_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);
52138 has_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);
52139 has_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);
52140 has_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);
52141 is_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);
52142 is_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);
52143 is_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);
52144 throw_flag = 1; /* Object.defineProperty() calls [[DefineOwnProperty]] with Throw=true */
52145 force_flag = (defprop_flags & DUK_DEFPROP_FORCE);
52146
52147 arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);
52148
52149 arridx_new_array_length = 0;
52150 pending_write_protect = 0;
52151 arrlen_old_len = 0;
52152 arrlen_new_len = 0;
52153
52154 DUK_DDD(DUK_DDDPRINT("has_enumerable=%ld is_enumerable=%ld "
52155 "has_configurable=%ld is_configurable=%ld "
52156 "has_writable=%ld is_writable=%ld "
52157 "has_value=%ld value=%!T "
52158 "has_get=%ld get=%p=%!O "
52159 "has_set=%ld set=%p=%!O "
52160 "arr_idx=%ld",
52161 (long) has_enumerable, (long) is_enumerable,
52162 (long) has_configurable, (long) is_configurable,
52163 (long) has_writable, (long) is_writable,
52164 (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(ctx, idx_value) : NULL),
52165 (long) has_get, (void *) get, (duk_heaphdr *) get,
52166 (long) has_set, (void *) set, (duk_heaphdr *) set,
52167 (long) arr_idx));
52168
52169 /*
52170 * Array exotic behaviors can be implemented at this point. The local variables
52171 * are essentially a 'value copy' of the input descriptor (Desc), which is modified
52172 * by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).
52173 */
52174
52175 if (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {
52176 goto skip_array_exotic;
52177 }
52178
52179 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
52180 /* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */
52181 if (!has_value) {
52182 DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', but no value in descriptor -> normal behavior"));
52183 goto skip_array_exotic;
52184 }
52185
52186 DUK_DDD(DUK_DDDPRINT("exotic array behavior for 'length', value present in descriptor -> exotic behavior"));
52187
52188 /*
52189 * Get old and new length
52190 */
52191
52192 /* Note: reuse 'curr' as a temp propdesc */
52193 arrlen_old_len = duk__get_old_array_length(thr, obj, &curr);
52194
52195 duk_dup(ctx, idx_value);
52196 arrlen_new_len = duk__to_new_array_length_checked(thr);
52197 duk_push_u32(ctx, arrlen_new_len);
52198 duk_replace(ctx, idx_value); /* step 3.e: replace 'Desc.[[Value]]' */
52199
52200 DUK_DDD(DUK_DDDPRINT("old_len=%ld, new_len=%ld", (long) arrlen_old_len, (long) arrlen_new_len));
52201
52202 if (arrlen_new_len >= arrlen_old_len) {
52203 /* standard behavior, step 3.f.i */
52204 DUK_DDD(DUK_DDDPRINT("new length is same or higher as previous => standard behavior"));
52205 goto skip_array_exotic;
52206 }
52207 DUK_DDD(DUK_DDDPRINT("new length is smaller than previous => exotic post behavior"));
52208
52209 /* XXX: consolidated algorithm step 15.f -> redundant? */
52210 if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && !force_flag) {
52211 /* Note: 'curr' refers to 'length' propdesc */
52212 goto fail_not_writable_array_length;
52213 }
52214
52215 /* steps 3.h and 3.i */
52216 if (has_writable && !is_writable) {
52217 DUK_DDD(DUK_DDDPRINT("desc writable is false, force it back to true, and flag pending write protect"));
52218 is_writable = 1;
52219 pending_write_protect = 1;
52220 }
52221
52222 /* remaining actual steps are carried out if standard DefineOwnProperty succeeds */
52223 } else if (arr_idx != DUK__NO_ARRAY_INDEX) {
52224 /* XXX: any chance of unifying this with the 'length' key handling? */
52225
52226 /* E5 Section 15.4.5.1, step 4 */
52227 duk_uint32_t old_len;
52228
52229 /* Note: use 'curr' as a temp propdesc */
52230 old_len = duk__get_old_array_length(thr, obj, &curr);
52231
52232 if (arr_idx >= old_len) {
52233 DUK_DDD(DUK_DDDPRINT("defineProperty requires array length update "
52234 "(arr_idx=%ld, old_len=%ld)",
52235 (long) arr_idx, (long) old_len));
52236
52237 if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
52238 /* Note: 'curr' refers to 'length' propdesc */
52239 goto fail_not_writable_array_length;
52240 }
52241
52242 /* actual update happens once write has been completed without
52243 * error below.
52244 */
52245 DUK_ASSERT(arr_idx != 0xffffffffUL);
52246 arridx_new_array_length = arr_idx + 1;
52247 } else {
52248 DUK_DDD(DUK_DDDPRINT("defineProperty does not require length update "
52249 "(arr_idx=%ld, old_len=%ld) -> standard behavior",
52250 (long) arr_idx, (long) old_len));
52251 }
52252 }
52253 skip_array_exotic:
52254
52255 /* XXX: There is currently no support for writing buffer object
52256 * indexed elements here. Attempt to do so will succeed and
52257 * write a concrete property into the buffer object. This should
52258 * be fixed at some point but because buffers are a custom feature
52259 * anyway, this is relatively unimportant.
52260 */
52261
52262 /*
52263 * Actual Object.defineProperty() default algorithm.
52264 */
52265
52266 /*
52267 * First check whether property exists; if not, simple case. This covers
52268 * steps 1-4.
52269 */
52270
52271 if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {
52272 DUK_DDD(DUK_DDDPRINT("property does not exist"));
52273
52274 if (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {
52275 goto fail_not_extensible;
52276 }
52277
52278 /* XXX: share final setting code for value and flags? difficult because
52279 * refcount code is different. Share entry allocation? But can't allocate
52280 * until array index checked.
52281 */
52282
52283 /* steps 4.a and 4.b are tricky */
52284 if (has_set || has_get) {
52285 duk_int_t e_idx;
52286
52287 DUK_DDD(DUK_DDDPRINT("create new accessor property"));
52288
52289 DUK_ASSERT(has_set || set == NULL);
52290 DUK_ASSERT(has_get || get == NULL);
52291 DUK_ASSERT(!has_value);
52292 DUK_ASSERT(!has_writable);
52293
52294 new_flags = DUK_PROPDESC_FLAG_ACCESSOR; /* defaults, E5 Section 8.6.1, Table 7 */
52295 if (has_enumerable && is_enumerable) {
52296 new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
52297 }
52298 if (has_configurable && is_configurable) {
52299 new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
52300 }
52301
52302 if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
52303 DUK_DDD(DUK_DDDPRINT("accessor cannot go to array part, abandon array"));
52305 }
52306
52307 /* write to entry part */
52308 e_idx = duk__alloc_entry_checked(thr, obj, key);
52309 DUK_ASSERT(e_idx >= 0);
52310
52311 DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);
52312 DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);
52315
52316 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
52317 goto success_exotics;
52318 } else {
52319 duk_int_t e_idx;
52320 duk_tval *tv2;
52321
52322 DUK_DDD(DUK_DDDPRINT("create new data property"));
52323
52324 DUK_ASSERT(!has_set);
52325 DUK_ASSERT(!has_get);
52326
52327 new_flags = 0; /* defaults, E5 Section 8.6.1, Table 7 */
52328 if (has_writable && is_writable) {
52329 new_flags |= DUK_PROPDESC_FLAG_WRITABLE;
52330 }
52331 if (has_enumerable && is_enumerable) {
52332 new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
52333 }
52334 if (has_configurable && is_configurable) {
52335 new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
52336 }
52337 if (has_value) {
52338 duk_tval *tv_tmp = duk_require_tval(ctx, idx_value);
52339 DUK_TVAL_SET_TVAL(&tv, tv_tmp);
52340 } else {
52341 DUK_TVAL_SET_UNDEFINED(&tv); /* default value */
52342 }
52343
52344 if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
52345 if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
52346#if 0
52347 DUK_DDD(DUK_DDDPRINT("new data property attributes match array defaults, attempt to write to array part"));
52348 /* may become sparse...*/
52349#endif
52350 /* XXX: handling for array part missing now; this doesn't affect
52351 * compliance but causes array entry writes using defineProperty()
52352 * to always abandon array part.
52353 */
52354 }
52355 DUK_DDD(DUK_DDDPRINT("new data property cannot go to array part, abandon array"));
52357 /* fall through */
52358 }
52359
52360 /* write to entry part */
52361 e_idx = duk__alloc_entry_checked(thr, obj, key);
52362 DUK_ASSERT(e_idx >= 0);
52363 tv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
52364 DUK_TVAL_SET_TVAL(tv2, &tv);
52365 DUK_TVAL_INCREF(thr, tv2);
52366
52367 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);
52368 goto success_exotics;
52369 }
52371 }
52372
52373 /* we currently assume virtual properties are not configurable (as none of them are) */
52374 DUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));
52375
52376 /* [obj key desc value get set curr_value] */
52377
52378 /*
52379 * Property already exists. Steps 5-6 detect whether any changes need
52380 * to be made.
52381 */
52382
52383 if (has_enumerable) {
52384 if (is_enumerable) {
52385 if (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {
52386 goto need_check;
52387 }
52388 } else {
52389 if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {
52390 goto need_check;
52391 }
52392 }
52393 }
52394 if (has_configurable) {
52395 if (is_configurable) {
52396 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {
52397 goto need_check;
52398 }
52399 } else {
52400 if (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {
52401 goto need_check;
52402 }
52403 }
52404 }
52405 if (has_value) {
52406 duk_tval *tmp1;
52407 duk_tval *tmp2;
52408
52409 /* attempt to change from accessor to data property */
52410 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52411 goto need_check;
52412 }
52413
52414 tmp1 = duk_require_tval(ctx, -1); /* curr value */
52415 tmp2 = duk_require_tval(ctx, idx_value); /* new value */
52416 if (!duk_js_samevalue(tmp1, tmp2)) {
52417 goto need_check;
52418 }
52419 }
52420 if (has_writable) {
52421 /* attempt to change from accessor to data property */
52422 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52423 goto need_check;
52424 }
52425
52426 if (is_writable) {
52427 if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
52428 goto need_check;
52429 }
52430 } else {
52431 if (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {
52432 goto need_check;
52433 }
52434 }
52435 }
52436 if (has_set) {
52437 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52438 if (set != curr.set) {
52439 goto need_check;
52440 }
52441 } else {
52442 goto need_check;
52443 }
52444 }
52445 if (has_get) {
52446 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52447 if (get != curr.get) {
52448 goto need_check;
52449 }
52450 } else {
52451 goto need_check;
52452 }
52453 }
52454
52455 /* property exists, either 'desc' is empty, or all values
52456 * match (SameValue)
52457 */
52458 goto success_no_exotics;
52459
52460 need_check:
52461
52462 /*
52463 * Some change(s) need to be made. Steps 7-11.
52464 */
52465
52466 /* shared checks for all descriptor types */
52467 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
52468 if (has_configurable && is_configurable) {
52469 goto fail_not_configurable;
52470 }
52471 if (has_enumerable) {
52472 if (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {
52473 if (!is_enumerable) {
52474 goto fail_not_configurable;
52475 }
52476 } else {
52477 if (is_enumerable) {
52478 goto fail_not_configurable;
52479 }
52480 }
52481 }
52482 }
52483
52484 /* Reject attempt to change virtual properties: not part of the
52485 * standard algorithm, applies currently to e.g. virtual index
52486 * properties of buffer objects (which are virtual but writable).
52487 * (Cannot "force" modification of a virtual property.)
52488 */
52489 if (curr.flags & DUK_PROPDESC_FLAG_VIRTUAL) {
52490 goto fail_virtual;
52491 }
52492
52493 /* Reject attempt to change a read-only object. */
52494#if defined(DUK_USE_ROM_OBJECTS)
52496 DUK_DD(DUK_DDPRINT("attempt to define property on read-only target object"));
52497 goto fail_not_configurable;
52498 }
52499#endif
52500
52501 /* descriptor type specific checks */
52502 if (has_set || has_get) {
52503 /* IsAccessorDescriptor(desc) == true */
52504 DUK_ASSERT(!has_writable);
52505 DUK_ASSERT(!has_value);
52506
52507 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52508 /* curr and desc are accessors */
52509 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
52510 if (has_set && set != curr.set) {
52511 goto fail_not_configurable;
52512 }
52513 if (has_get && get != curr.get) {
52514 goto fail_not_configurable;
52515 }
52516 }
52517 } else {
52518 duk_bool_t rc;
52519 duk_tval *tv1;
52520 duk_tval tv_tmp;
52521
52522 /* curr is data, desc is accessor */
52523 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
52524 goto fail_not_configurable;
52525 }
52526
52527 DUK_DDD(DUK_DDDPRINT("convert property to accessor property"));
52528 if (curr.a_idx >= 0) {
52529 DUK_DDD(DUK_DDDPRINT("property to convert is stored in an array entry, abandon array and re-lookup"));
52531 duk_pop(ctx); /* remove old value */
52532 rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
52533 DUK_UNREF(rc);
52534 DUK_ASSERT(rc != 0);
52535 DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
52536 }
52537
52538 DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52539
52540 /* Avoid side effects that might disturb curr.e_idx until
52541 * we're done editing the slot.
52542 */
52543 tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
52544 DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
52546
52547 DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
52548 DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
52549 DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
52550 DUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);
52551
52552 DUK_DDD(DUK_DDDPRINT("flags after data->accessor conversion: 0x%02lx",
52553 (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
52554
52555 DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
52556
52557 /* re-lookup to update curr.flags
52558 * XXX: would be faster to update directly
52559 */
52560 duk_pop(ctx); /* remove old value */
52561 rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
52562 DUK_UNREF(rc);
52563 DUK_ASSERT(rc != 0);
52564 }
52565 } else if (has_value || has_writable) {
52566 /* IsDataDescriptor(desc) == true */
52567 DUK_ASSERT(!has_set);
52568 DUK_ASSERT(!has_get);
52569
52570 if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
52571 duk_bool_t rc;
52572 duk_hobject *h_get;
52573 duk_hobject *h_set;
52574
52575 /* curr is accessor, desc is data */
52576 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
52577 goto fail_not_configurable;
52578 }
52579
52580 /* curr is accessor -> cannot be in array part */
52581 DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
52582
52583 DUK_DDD(DUK_DDDPRINT("convert property to data property"));
52584
52585 /* Avoid side effects that might disturb curr.e_idx until
52586 * we're done editing the slot.
52587 */
52588 DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52589 h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
52590 DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
52591 h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
52592 DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
52593
52594 DUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));
52595 DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
52596 DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);
52597
52598 DUK_DDD(DUK_DDDPRINT("flags after accessor->data conversion: 0x%02lx",
52599 (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
52600
52601 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get); /* side effects */
52602 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set); /* side effects */
52603
52604 /* re-lookup to update curr.flags
52605 * XXX: would be faster to update directly
52606 */
52607 duk_pop(ctx); /* remove old value */
52608 rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
52609 DUK_UNREF(rc);
52610 DUK_ASSERT(rc != 0);
52611 } else {
52612 /* curr and desc are data */
52613 if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
52614 if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {
52615 goto fail_not_configurable;
52616 }
52617 /* Note: changing from writable to non-writable is OK */
52618 if (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {
52619 duk_tval *tmp1 = duk_require_tval(ctx, -1); /* curr value */
52620 duk_tval *tmp2 = duk_require_tval(ctx, idx_value); /* new value */
52621 if (!duk_js_samevalue(tmp1, tmp2)) {
52622 goto fail_not_configurable;
52623 }
52624 }
52625 }
52626 }
52627 } else {
52628 /* IsGenericDescriptor(desc) == true; this means in practice that 'desc'
52629 * only has [[Enumerable]] or [[Configurable]] flag updates, which are
52630 * allowed at this point.
52631 */
52632
52633 DUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);
52634 }
52635
52636 /*
52637 * Start doing property attributes updates. Steps 12-13.
52638 *
52639 * Start by computing new attribute flags without writing yet.
52640 * Property type conversion is done above if necessary.
52641 */
52642
52643 new_flags = curr.flags;
52644
52645 if (has_enumerable) {
52646 if (is_enumerable) {
52647 new_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;
52648 } else {
52649 new_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;
52650 }
52651 }
52652 if (has_configurable) {
52653 if (is_configurable) {
52654 new_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;
52655 } else {
52656 new_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;
52657 }
52658 }
52659 if (has_writable) {
52660 if (is_writable) {
52661 new_flags |= DUK_PROPDESC_FLAG_WRITABLE;
52662 } else {
52663 new_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;
52664 }
52665 }
52666
52667 /* XXX: write protect after flag? -> any chance of handling it here? */
52668
52669 DUK_DDD(DUK_DDDPRINT("new flags that we want to write: 0x%02lx",
52670 (unsigned long) new_flags));
52671
52672 /*
52673 * Check whether we need to abandon an array part (if it exists)
52674 */
52675
52676 if (curr.a_idx >= 0) {
52677 duk_bool_t rc;
52678
52679 DUK_ASSERT(curr.e_idx < 0);
52680
52681 if (new_flags == DUK_PROPDESC_FLAGS_WEC) {
52682 duk_tval *tv1, *tv2;
52683
52684 DUK_DDD(DUK_DDDPRINT("array index, new property attributes match array defaults, update in-place"));
52685
52686 DUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC); /* must have been, since in array part */
52687 DUK_ASSERT(!has_set);
52688 DUK_ASSERT(!has_get);
52689
52690 tv2 = duk_require_tval(ctx, idx_value);
52691 tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);
52692 DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
52693 goto success_exotics;
52694 }
52695
52696 DUK_DDD(DUK_DDDPRINT("array index, new property attributes do not match array defaults, abandon array and re-lookup"));
52698 duk_pop(ctx); /* remove old value */
52699 rc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);
52700 DUK_UNREF(rc);
52701 DUK_ASSERT(rc != 0);
52702 DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
52703 }
52704
52705 DUK_DDD(DUK_DDDPRINT("updating existing property in entry part"));
52706
52707 /* array case is handled comprehensively above */
52708 DUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);
52709
52710 DUK_DDD(DUK_DDDPRINT("update existing property attributes"));
52711 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);
52712
52713 if (has_set) {
52714 duk_hobject *tmp;
52715
52716 DUK_DDD(DUK_DDDPRINT("update existing property setter"));
52717 DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52718
52719 tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
52720 DUK_UNREF(tmp);
52721 DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);
52723 DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
52724 }
52725 if (has_get) {
52726 duk_hobject *tmp;
52727
52728 DUK_DDD(DUK_DDDPRINT("update existing property getter"));
52729 DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52730
52731 tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
52732 DUK_UNREF(tmp);
52733 DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);
52735 DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
52736 }
52737 if (has_value) {
52738 duk_tval *tv1, *tv2;
52739
52740 DUK_DDD(DUK_DDDPRINT("update existing property value"));
52741 DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52742
52743 tv2 = duk_require_tval(ctx, idx_value);
52744 tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
52745 DUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2); /* side effects */
52746 }
52747
52748 /*
52749 * Standard algorithm succeeded without errors, check for exotic post-behaviors.
52750 *
52751 * Arguments exotic behavior in E5 Section 10.6 occurs after the standard
52752 * [[DefineOwnProperty]] has completed successfully.
52753 *
52754 * Array exotic behavior in E5 Section 15.4.5.1 is implemented partly
52755 * prior to the default [[DefineOwnProperty]], but:
52756 * - for an array index key (e.g. "10") the final 'length' update occurs here
52757 * - for 'length' key the element deletion and 'length' update occurs here
52758 */
52759
52760 success_exotics:
52761
52762 /* [obj key desc value get set curr_value] */
52763
52765 if (arridx_new_array_length > 0) {
52766 duk_tval *tmp;
52767 duk_bool_t rc;
52768
52769 /*
52770 * Note: zero works as a "no update" marker because the new length
52771 * can never be zero after a new property is written.
52772 */
52773
52774 /* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */
52775
52776 DUK_DDD(DUK_DDDPRINT("defineProperty successful, pending array length update to: %ld",
52777 (long) arridx_new_array_length));
52778
52779 /* Note: reuse 'curr' */
52780 rc = duk__get_own_propdesc_raw(thr, obj, DUK_HTHREAD_STRING_LENGTH(thr), DUK__NO_ARRAY_INDEX, &curr, 0 /*flags*/); /* don't push value */
52781 DUK_UNREF(rc);
52782 DUK_ASSERT(rc != 0);
52783 DUK_ASSERT(curr.e_idx >= 0);
52784
52785 tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
52787 /* no need for decref/incref because value is a number */
52788 DUK_TVAL_SET_FASTINT_U32(tmp, arridx_new_array_length);
52789 }
52790 if (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {
52791 /*
52792 * E5 Section 15.4.5.1, steps 3.k - 3.n. The order at the end combines
52793 * the error case 3.l.iii and the success case 3.m-3.n.
52794 *
52795 * Note: 'length' is always in entries part, so no array abandon issues for
52796 * 'writable' update.
52797 */
52798
52799 /* XXX: investigate whether write protect can be handled above, if we
52800 * just update length here while ignoring its protected status
52801 */
52802
52803 duk_tval *tmp;
52804 duk_uint32_t result_len;
52805 duk_bool_t rc;
52806
52807 DUK_DDD(DUK_DDDPRINT("defineProperty successful, key is 'length', exotic array behavior, "
52808 "doing array element deletion and length update"));
52809
52810 rc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);
52811
52812 /* update length (curr points to length, and we assume it's still valid) */
52813 DUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);
52814
52815 DUK_ASSERT(curr.e_idx >= 0);
52816 DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
52817 tmp = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
52819 /* no decref needed for a number */
52820 DUK_TVAL_SET_FASTINT_U32(tmp, result_len);
52822
52823 if (pending_write_protect) {
52824 DUK_DDD(DUK_DDDPRINT("setting array length non-writable (pending writability update)"));
52825 DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
52826 }
52827
52828 /*
52829 * XXX: shrink array allocation or entries compaction here?
52830 */
52831
52832 if (!rc) {
52833 goto fail_array_length_partial;
52834 }
52835 }
52836 } else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {
52837 duk_hobject *map;
52838 duk_hobject *varenv;
52839
52840 DUK_ASSERT(arridx_new_array_length == 0);
52841 DUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)); /* traits are separate; in particular, arguments not an array */
52842
52843 map = NULL;
52844 varenv = NULL;
52845 if (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {
52846 goto success_no_exotics;
52847 }
52848 DUK_ASSERT(map != NULL);
52849 DUK_ASSERT(varenv != NULL);
52850
52851 /* [obj key desc value get set curr_value varname] */
52852
52853 if (has_set || has_get) {
52854 /* = IsAccessorDescriptor(Desc) */
52855 DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map' "
52856 "changed to an accessor, delete arguments binding"));
52857
52858 (void) duk_hobject_delprop_raw(thr, map, key, 0); /* ignore result */
52859 } else {
52860 /* Note: this order matters (final value before deleting map entry must be done) */
52861 DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
52862 "check for value update / binding deletion"));
52863
52864 if (has_value) {
52865 duk_hstring *varname;
52866
52867 DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
52868 "update bound value (variable/argument)"));
52869
52870 varname = duk_require_hstring(ctx, -1);
52871 DUK_ASSERT(varname != NULL);
52872
52873 DUK_DDD(DUK_DDDPRINT("arguments object automatic putvar for a bound variable; "
52874 "key=%!O, varname=%!O, value=%!T",
52875 (duk_heaphdr *) key,
52876 (duk_heaphdr *) varname,
52877 (duk_tval *) duk_require_tval(ctx, idx_value)));
52878
52879 /* strict flag for putvar comes from our caller (currently: fixed) */
52880 duk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(ctx, idx_value), throw_flag);
52881 }
52882 if (has_writable && !is_writable) {
52883 DUK_DDD(DUK_DDDPRINT("defineProperty successful, key mapped to arguments 'map', "
52884 "changed to non-writable, delete arguments binding"));
52885
52886 (void) duk_hobject_delprop_raw(thr, map, key, 0); /* ignore result */
52887 }
52888 }
52889
52890 /* 'varname' is in stack in this else branch, leaving an unbalanced stack below,
52891 * but this doesn't matter now.
52892 */
52893 }
52894
52895 success_no_exotics:
52896 return;
52897
52898 fail_virtual:
52900 return;
guint index
#define DUK_TVAL_DECREF(thr, tv)
#define DUK_TVAL_SET_TVAL(v, x)
#define DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i)
#define DUK_HOBJECT_DECREF_ALLOWNULL(thr, h)
#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)
#define DUK_TVAL_SET_FASTINT_U32(tv, val)
#define DUK_TVAL_IS_NUMBER(tv)
#define DUK_ERROR_TYPE(thr, msg)
DUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags)
DUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict)
#define DUK_GETDESC_FLAG_PUSH_VALUE
DUK_LOCAL duk_bool_t duk__lookup_arguments_map(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_hobject **out_map, duk_hobject **out_varenv)
#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h, i)
#define DUK_PROPDESC_FLAG_VIRTUAL
#define duk_js_samevalue(tv_x, tv_y)
#define DUK_TVAL_INCREF(thr, tv)
#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h, i)
#define DUK_PROPDESC_FLAG_ACCESSOR
DUK_LOCAL duk_bool_t duk__alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key)
DUK_LOCAL void duk__abandon_array_checked(duk_hthread *thr, duk_hobject *obj)
#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap, h, i)
#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags)
#define DUK_HOBJECT_HAS_ARRAY_PART(h)
#define DUK_TVAL_SET_TVAL_UPDREF
#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap, h, i)
#define DUK_PROPDESC_FLAG_CONFIGURABLE
#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap, h, i, v)
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)
#define DUK_HOBJECT_E_SET_FLAGS(heap, h, i, f)
#define DUK_PROPDESC_FLAG_WRITABLE
DUK_INTERNAL_DECL duk_tval * duk_require_tval(duk_context *ctx, duk_idx_t index)
#define DUK_STR_PROPERTY_IS_VIRTUAL
#define DUK_PROPDESC_FLAGS_WEC
#define DUK_PROPDESC_FLAG_ENUMERABLE
#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap, h, i, v)
DUK_EXTERNAL void duk_pop(duk_context *ctx)
DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len)
#define DUK_HOBJECT_E_GET_FLAGS(heap, h, i)
#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h, i)
DUK_INTERNAL_DECL duk_hstring * duk_require_hstring(duk_context *ctx, duk_idx_t index)
#define DUK_HTHREAD_STRING_LENGTH(thr)
#define DUK_TVAL_SET_UNDEFINED(tv)
#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap, h, i)
#define DUK_HOBJECT_INCREF_ALLOWNULL(thr, h)
union Value Value

◆ duk_hobject_define_property_internal()

DUK_INTERNAL_DECL void duk_hobject_define_property_internal ( duk_hthread * thr,
duk_hobject * obj,
duk_hstring * key,
duk_small_uint_t flags )

Definition at line 51590 of file duktape-1.5.2/src-noline/duktape.c.

51594 :
51595 * - virtual properties (error if write attempted)
51596 * - getter/setter properties (error if write attempted)
51597 * - non-default (!= WEC) attributes for array entries (error if attempted)
51598 * - array abandoning: if array part exists, it is always extended
51599 * - array 'length' updating
51600 *
51601 * Stack: [... in_val] -> []
51602 *
51603 * Used for e.g. built-in initialization and environment record
51604 * operations.
51605 */
51606
51608 duk_context *ctx = (duk_context *) thr;
51609 duk_propdesc desc;
51610 duk_uint32_t arr_idx;
51611 duk_int_t e_idx;
51612 duk_tval *tv1 = NULL;
51613 duk_tval *tv2 = NULL;
51614 duk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK; /* mask out flags not actually stored */
51615
51616 DUK_DDD(DUK_DDDPRINT("define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T",
51617 (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,
51618 (unsigned long) flags, (duk_tval *) duk_get_tval(ctx, -1)));
51619
51620 DUK_ASSERT(thr != NULL);
51621 DUK_ASSERT(thr->heap != NULL);
51622 DUK_ASSERT(obj != NULL);
51623 DUK_ASSERT(key != NULL);
51626 DUK_ASSERT(duk_is_valid_index(ctx, -1)); /* contains value */
51627
51628 arr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);
51629
51630 if (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
51631 if (desc.e_idx >= 0) {
51632 if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
51633 DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> skip as requested"));
51634 goto pop_exit;
51635 }
51636 DUK_DDD(DUK_DDDPRINT("property already exists in the entry part -> update value and attributes"));
51637 if (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {
51638 DUK_D(DUK_DPRINT("existing property is an accessor, not supported"));
51639 goto error_internal;
51640 }
51641
51642 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);
51643 tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
51644 } else if (desc.a_idx >= 0) {
51645 if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
51646 DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> skip as requested"));
51647 goto pop_exit;
51648 }
51649 DUK_DDD(DUK_DDDPRINT("property already exists in the array part -> update value (assert attributes)"));
51650 if (propflags != DUK_PROPDESC_FLAGS_WEC) {
51651 DUK_D(DUK_DPRINT("existing property in array part, but propflags not WEC (0x%02lx)",
51652 (unsigned long) propflags));
51653 goto error_internal;
51654 }
51655
51656 tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
51657 } else {
51658 if (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {
51659 DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> skip as requested"));
51660 goto pop_exit;
51661 }
51662 DUK_DDD(DUK_DDDPRINT("property already exists but is virtual -> failure"));
51663 goto error_virtual;
51664 }
51665
51666 goto write_value;
51667 }
51668
51669 if (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
51670 if (arr_idx != DUK__NO_ARRAY_INDEX) {
51671 DUK_DDD(DUK_DDDPRINT("property does not exist, object has array part -> possibly extend array part and write value (assert attributes)"));
51672 DUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);
51673
51674 /* always grow the array, no sparse / abandon support here */
51675 if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
51676 duk__grow_props_for_array_item(thr, obj, arr_idx);
51677 }
51678
51679 DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
51680 tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
51681 goto write_value;
51682 }
51683 }
51684
51685 DUK_DDD(DUK_DDDPRINT("property does not exist, object belongs in entry part -> allocate new entry and write value and attributes"));
51686 e_idx = duk__alloc_entry_checked(thr, obj, key); /* increases key refcount */
51687 DUK_ASSERT(e_idx >= 0);
51688 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);
51689 tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);
51690 /* new entry: previous value is garbage; set to undefined to share write_value */
51692 goto write_value;
51693
51694 write_value:
51695 /* tv1 points to value storage */
51696
51697 tv2 = duk_require_tval(ctx, -1); /* late lookup, avoid side effects */
51698 DUK_DDD(DUK_DDDPRINT("writing/updating value: %!T -> %!T",
unsigned int duk_small_uint_t
DUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_GET_ASIZE(h)
#define DUK_PROPDESC_FLAG_NO_OVERWRITE
#define DUK_ASSERT_VALSTACK_SPACE(thr, n)
DUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx)
DUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags)
#define DUK_HSTRING_GET_ARRIDX_SLOW(h)
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
static void error(LoadState *S, const char *why)

◆ duk_hobject_define_property_internal_arridx()

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 )

Definition at line 51706 of file duktape-1.5.2/src-noline/duktape.c.

51708 :
51710 return;
51711
51712 error_virtual:
51714 return;
51715}
51716
51717/*
51718 * Fast path for defining array indexed values without interning the key.
51719 * This is used by e.g. code for Array prototype and traceback creation so
51720 * must avoid interning.
51721 */
51722
51724 duk_context *ctx = (duk_context *) thr;
51725 duk_hstring *key;
51726 duk_tval *tv1, *tv2;
51727
51728 DUK_DDD(DUK_DDDPRINT("define new property (internal) arr_idx fast path: thr=%p, obj=%!O, "
51729 "arr_idx=%ld, flags=0x%02lx, val=%!T",
51730 (void *) thr, obj, (long) arr_idx, (unsigned long) flags,
51731 (duk_tval *) duk_get_tval(ctx, -1)));
51732
51733 DUK_ASSERT(thr != NULL);
51734 DUK_ASSERT(thr->heap != NULL);
51735 DUK_ASSERT(obj != NULL);
51737
51738 if (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&
51739 arr_idx != DUK__NO_ARRAY_INDEX &&
51740 flags == DUK_PROPDESC_FLAGS_WEC) {
51741 DUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0); /* covered by comparison */
51742
51743 DUK_DDD(DUK_DDDPRINT("define property to array part (property may or may not exist yet)"));
51744
51745 /* always grow the array, no sparse / abandon support here */
51746 if (arr_idx >= DUK_HOBJECT_GET_ASIZE(obj)) {
51747 duk__grow_props_for_array_item(thr, obj, arr_idx);
51748 }
51749
51750 DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));
51751 tv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);
51752 tv2 = duk_require_tval(ctx, -1);
51753
#define DUK_STR_REDEFINE_VIRT_PROP
#define DUK_ERROR_INTERNAL_DEFMSG(thr)
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)

◆ duk_hobject_delprop()

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 )

Definition at line 51383 of file duktape-1.5.2/src-noline/duktape.c.

51387 :
51388 DUK_DDD(DUK_DDDPRINT("delete failed: property found, not configurable"));
51389
51390 if (throw_flag) {
51392 }
51393 return 0;
51394}
51395
51396/*
51397 * DELPROP: Ecmascript property deletion.
51398 */
51399
51401 duk_context *ctx = (duk_context *) thr;
51402 duk_hstring *key = NULL;
51403#if defined(DUK_USE_ES6_PROXY)
51404 duk_propdesc desc;
51405#endif
51406 duk_int_t entry_top;
51407 duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;
51408 duk_bool_t rc;
51409
51410 DUK_DDD(DUK_DDDPRINT("delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
51411 (void *) thr, (void *) tv_obj, (void *) tv_key,
51412 (duk_tval *) tv_obj, (duk_tval *) tv_key));
51413
51414 DUK_ASSERT(ctx != NULL);
51415 DUK_ASSERT(thr != NULL);
51416 DUK_ASSERT(thr->heap != NULL);
51417 DUK_ASSERT(tv_obj != NULL);
51418 DUK_ASSERT(tv_key != NULL);
51419
51421
51422 /* Storing the entry top is cheaper here to ensure stack is correct at exit,
51423 * as there are several paths out.
51424 */
51425 entry_top = duk_get_top(ctx);
51426
51427 if (DUK_TVAL_IS_UNDEFINED(tv_obj) ||
51428 DUK_TVAL_IS_NULL(tv_obj)) {
51429 DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject"));
51430 goto fail_invalid_base_uncond;
51431 }
51432
51433 duk_push_tval(ctx, tv_obj);
51434 duk_push_tval(ctx, tv_key);
51435
51436 tv_obj = DUK_GET_TVAL_NEGIDX(ctx, -2);
51437 if (DUK_TVAL_IS_OBJECT(tv_obj)) {
51438 duk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);
51439 DUK_ASSERT(obj != NULL);
51440
51441#if defined(DUK_USE_ES6_PROXY)
51443 duk_hobject *h_target;
51444 duk_bool_t tmp_bool;
51445
51446 /* Note: proxy handling must happen before key is string coerced. */
51447
51448 if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {
51449 /* -> [ ... trap handler ] */
51450 DUK_DDD(DUK_DDDPRINT("-> proxy object 'deleteProperty' for key %!T", (duk_tval *) tv_key));
51451 duk_push_hobject(ctx, h_target); /* target */
51452 duk_push_tval(ctx, tv_key); /* P */
51453 duk_call_method(ctx, 2 /*nargs*/);
51454 tmp_bool = duk_to_boolean(ctx, -1);
51455 duk_pop(ctx);
51456 if (!tmp_bool) {
51457 goto fail_proxy_rejected; /* retval indicates delete failed */
51458 }
51459
51460 /* Target object must be checked for a conflicting
51461 * non-configurable property.
51462 */
51463 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
51464 DUK_ASSERT(key != NULL);
51465
51466 if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
51467 int desc_reject;
51468
51469 DUK_DDD(DUK_DDDPRINT("proxy 'deleteProperty': target has matching property %!O, check for "
51470 "conflicting property; desc.flags=0x%08lx, "
51471 "desc.get=%p, desc.set=%p",
51472 (duk_heaphdr *) key, (unsigned long) desc.flags,
51473 (void *) desc.get, (void *) desc.set));
51474
51475 desc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);
51476 if (desc_reject) {
51477 /* unconditional */
51479 }
51480 }
51481 rc = 1; /* success */
51482 goto done_rc;
51483 }
51484
51485 obj = h_target; /* resume delete to target */
51486 }
51487#endif /* DUK_USE_ES6_PROXY */
51488
51489 duk_to_string(ctx, -1);
51490 key = duk_get_hstring(ctx, -1);
51491 DUK_ASSERT(key != NULL);
51492
51493 rc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);
51494 goto done_rc;
51495 } else if (DUK_TVAL_IS_STRING(tv_obj)) {
51496 /* XXX: unnecessary string coercion for array indices,
51497 * intentional to keep small.
51498 */
51499 duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
51500 DUK_ASSERT(h != NULL);
51501
51502 duk_to_string(ctx, -1);
51503 key = duk_get_hstring(ctx, -1);
51504 DUK_ASSERT(key != NULL);
51505
51506 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
51507 goto fail_not_configurable;
51508 }
51509
51510 arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);
51511
51512 if (arr_idx != DUK__NO_ARRAY_INDEX &&
51513 arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
51514 goto fail_not_configurable;
51515 }
51516 } else if (DUK_TVAL_IS_BUFFER(tv_obj)) {
51517 /* XXX: unnecessary string coercion for array indices,
51518 * intentional to keep small; some overlap with string
51519 * handling.
51520 */
51521 duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
51522 DUK_ASSERT(h != NULL);
51523
51524 duk_to_string(ctx, -1);
51525 key = duk_get_hstring(ctx, -1);
51526 DUK_ASSERT(key != NULL);
51527
51528 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
51529 goto fail_not_configurable;
51530 }
51531
51532 arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);
51533
51534 if (arr_idx != DUK__NO_ARRAY_INDEX &&
51535 arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
51536 goto fail_not_configurable;
51537 }
51538 } else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
51539 /* Lightfunc virtual properties are non-configurable, so
51540 * reject if match any of them.
51541 */
51542
51543 duk_to_string(ctx, -1);
51544 key = duk_get_hstring(ctx, -1);
51545 DUK_ASSERT(key != NULL);
51546
51547 if (duk__key_is_lightfunc_ownprop(thr, key)) {
51548 goto fail_not_configurable;
51549 }
51550 }
51551
51552 /* non-object base, no offending virtual property */
51553 rc = 1;
51554 goto done_rc;
51555
51556 done_rc:
51557 duk_set_top(ctx, entry_top);
51558 return rc;
51559
51560 fail_invalid_base_uncond:
51561 /* Note: unconditional throw */
51562 DUK_ASSERT(duk_get_top(ctx) == entry_top);
51563#if defined(DUK_USE_PARANOID_ERRORS)
51565#else
51566 DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot delete property %s of %s",
51568#endif
51569 return 0;
#define DUK_HSTRING_GET_ARRIDX_FAST(h)
#define DUK_DELPROP_FLAG_THROW
#define DUK_TVAL_GET_OBJECT(tv)
#define DUK_TVAL_IS_NULL(tv)
#define DUK_TVAL_IS_BUFFER(tv)
#define DUK_TVAL_IS_UNDEFINED(tv)
#define DUK_TVAL_IS_OBJECT(tv)
#define DUK_TVAL_GET_BUFFER(tv)
#define DUK_HSTRING_GET_CHARLEN(x)
DUK_EXTERNAL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t index)
#define DUK_TVAL_GET_STRING(tv)
DUK_LOCAL duk_uint32_t duk__push_tval_to_hstring_arr_idx(duk_context *ctx, duk_tval *tv, duk_hstring **out_h)
#define DUK_STRIDX_DELETE_PROPERTY
#define DUK_TVAL_IS_STRING(tv)
#define DUK_TVAL_IS_LIGHTFUNC(tv)
DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index)
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)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)
DUK_INTERNAL_DECL void duk_push_tval(duk_context *ctx, duk_tval *tv)
#define DUK_ERROR_FMT2(thr, err, fmt, arg1, arg2)
#define DUK_STR_NOT_CONFIGURABLE
DUK_EXTERNAL void duk_call_method(duk_context *ctx, duk_idx_t nargs)
#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)
#define DUK_GET_TVAL_NEGIDX(ctx, idx)
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h)
DUK_INTERNAL_DECL duk_hstring * duk_get_hstring(duk_context *ctx, duk_idx_t index)
DUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target)
DUK_INTERNAL_DECL const char * duk_push_string_tval_readable(duk_context *ctx, duk_tval *tv)
#define DUK_HBUFFER_GET_SIZE(x)
DUK_LOCAL duk_bool_t duk__key_is_lightfunc_ownprop(duk_hthread *thr, duk_hstring *key)
#define DUK_STR_PROXY_REJECTED

◆ duk_hobject_delprop_raw()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw ( duk_hthread * thr,
duk_hobject * obj,
duk_hstring * key,
duk_small_uint_t flags )

Definition at line 51215 of file duktape-1.5.2/src-noline/duktape.c.

51219 :
51220 DUK_DDD(DUK_DDDPRINT("result: error, internal"));
51221 if (throw_flag) {
51223 }
51224 duk_pop(ctx); /* remove key */
51225 return 0;
51226}
51227
51228/*
51229 * Ecmascript compliant [[Delete]](P, Throw).
51230 */
51231
51233 duk_propdesc desc;
51234 duk_tval *tv;
51235 duk_uint32_t arr_idx;
51236 duk_bool_t throw_flag;
51237 duk_bool_t force_flag;
51238
51239 throw_flag = (flags & DUK_DELPROP_FLAG_THROW);
51240 force_flag = (flags & DUK_DELPROP_FLAG_FORCE);
51241
51242 DUK_DDD(DUK_DDDPRINT("delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)",
51243 (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,
51244 (duk_heaphdr *) obj, (duk_heaphdr *) key));
51245
51246 DUK_ASSERT(thr != NULL);
51247 DUK_ASSERT(thr->heap != NULL);
51248 DUK_ASSERT(obj != NULL);
51249 DUK_ASSERT(key != NULL);
51250
51252
51253 arr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);
51254
51255 /* 0 = don't push current value */
51256 if (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
51257 DUK_DDD(DUK_DDDPRINT("property not found, succeed always"));
51258 goto success;
51259 }
51260
51261#if defined(DUK_USE_ROM_OBJECTS)
51263 DUK_DD(DUK_DDPRINT("attempt to delprop on read-only target object"));
51264 goto fail_not_configurable;
51265 }
51266#endif
51267
51268 if ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {
51269 goto fail_not_configurable;
51270 }
51271 if (desc.a_idx < 0 && desc.e_idx < 0) {
51272 /* Currently there are no deletable virtual properties, but
51273 * with force_flag we might attempt to delete one.
51274 */
51275 goto fail_virtual;
51276 }
51277
51278 if (desc.a_idx >= 0) {
51279 DUK_ASSERT(desc.e_idx < 0);
51280
51281 tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);
51282 DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */
51283 goto success;
51284 } else {
51285 duk_hobject *h_get = NULL;
51286 duk_hobject *h_set = NULL;
51287 duk_tval tv_tmp;
51288
51289 DUK_ASSERT(desc.a_idx < 0);
51290
51291 /* Set property slot to an empty state. Careful not to invoke
51292 * any side effects while using desc.e_idx so that it doesn't
51293 * get invalidated by a finalizer mutating our object.
51294 */
51295
51296 /* remove hash entry (no decref) */
51297#if defined(DUK_USE_HOBJECT_HASH_PART)
51298 if (desc.h_idx >= 0) {
51299 duk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);
51300
51301 DUK_DDD(DUK_DDDPRINT("removing hash entry at h_idx %ld", (long) desc.h_idx));
51303 DUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));
51304 h_base[desc.h_idx] = DUK__HASH_DELETED;
51305 } else {
51307 }
51308#else
51310#endif
51311
51312 /* remove value */
51313 DUK_DDD(DUK_DDDPRINT("before removing value, e_idx %ld, key %p, key at slot %p",
51314 (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
51315 DUK_DDD(DUK_DDDPRINT("removing value at e_idx %ld", (long) desc.e_idx));
51316 DUK_MEMSET((void *) &tv_tmp, 0, sizeof(tv_tmp));
51317 DUK_TVAL_SET_UNDEFINED(&tv_tmp);
51318 if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {
51319 h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
51320 h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
51321 DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);
51322 DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);
51323 } else {
51324 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
51325 DUK_TVAL_SET_TVAL(&tv_tmp, tv);
51327 }
51328#if 0
51329 /* Not strictly necessary because if key == NULL, flag MUST be ignored. */
51330 DUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);
51331#endif
51332
51333 /* remove key */
51334 DUK_DDD(DUK_DDDPRINT("before removing key, e_idx %ld, key %p, key at slot %p",
51335 (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
51336 DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx));
51337 DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));
51338 DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);
51339
51340 /* Do decrefs only with safe pointers to avoid side effects
51341 * disturbing e_idx.
51342 */
51343 DUK_TVAL_DECREF(thr, &tv_tmp);
51344 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get);
51345 DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set);
51346 DUK_HSTRING_DECREF(thr, key);
51347 goto success;
51348 }
51349
51351
51352 success:
51353 /*
51354 * Argument exotic [[Delete]] behavior (E5 Section 10.6) is
51355 * a post-check, keeping arguments internal 'map' in sync with
51356 * any successful deletes (note that property does not need to
51357 * exist for delete to 'succeed').
51358 *
51359 * Delete key from 'map'. Since 'map' only contains array index
51360 * keys, we can use arr_idx for a fast skip.
51361 */
51362
51363 DUK_DDD(DUK_DDDPRINT("delete successful, check for arguments exotic behavior"));
51364
51366 /* Note: only numbered indices are relevant, so arr_idx fast reject
51367 * is good (this is valid unless there are more than 4**32-1 arguments).
51368 */
51369
51370 DUK_DDD(DUK_DDDPRINT("delete successful, arguments exotic behavior needed"));
51371
51372 /* Note: we can reuse 'desc' here */
51373 (void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);
51374 }
51375
51376 DUK_DDD(DUK_DDDPRINT("delete successful"));
51377 return 1;
#define DUK_TVAL_SET_UNUSED_UPDREF
#define DUK_HOBJECT_E_GET_KEY(heap, h, i)
#define DUK_HOBJECT_E_SET_KEY(heap, h, i, k)
#define DUK_HSTRING_DECREF(thr, h)
#define DUK_HOBJECT_GET_HSIZE(h)
#define DUK_DELPROP_FLAG_FORCE
DUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc)
#define DUK_HOBJECT_H_GET_BASE(heap, h)

◆ duk_hobject_enumerator_create()

DUK_INTERNAL_DECL void duk_hobject_enumerator_create ( duk_context * ctx,
duk_small_uint_t enum_flags )

Definition at line 46200 of file duktape-1.5.2/src-noline/duktape.c.

46217 {
46218 duk_hthread *thr = (duk_hthread *) ctx;
46219 duk_hobject *enum_target;
46220 duk_hobject *curr;
46221 duk_hobject *res;
46222#if defined(DUK_USE_ES6_PROXY)
46223 duk_hobject *h_proxy_target;
46224 duk_hobject *h_proxy_handler;
46225 duk_hobject *h_trap_result;
46226#endif
46227 duk_uint_fast32_t i, len; /* used for array, stack, and entry indices */
46228
46229 DUK_ASSERT(ctx != NULL);
46230
46231 DUK_DDD(DUK_DDDPRINT("create enumerator, stack top: %ld", (long) duk_get_top(ctx)));
46232
46233 enum_target = duk_require_hobject(ctx, -1);
46234 DUK_ASSERT(enum_target != NULL);
46235
46237 res = duk_require_hobject(ctx, -1);
46238
46239 DUK_DDD(DUK_DDDPRINT("created internal object"));
46240
46241 /* [enum_target res] */
46242
46243 /* Target must be stored so that we can recheck whether or not
46244 * keys still exist when we enumerate. This is not done if the
46245 * enumeration result comes from a proxy trap as there is no
46246 * real object to check against.
46247 */
46248 duk_push_hobject(ctx, enum_target);
46250
46251 /* Initialize index so that we skip internal control keys. */
46254
46255 /*
46256 * Proxy object handling
46257 */
46258
46259#if defined(DUK_USE_ES6_PROXY)
46260 if (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {
46261 goto skip_proxy;
46262 }
46264 enum_target,
46265 &h_proxy_target,
46266 &h_proxy_handler))) {
46267 goto skip_proxy;
46268 }
46269
46270 DUK_DDD(DUK_DDDPRINT("proxy enumeration"));
46271 duk_push_hobject(ctx, h_proxy_handler);
46273 /* No need to replace the 'enum_target' value in stack, only the
46274 * enum_target reference. This also ensures that the original
46275 * enum target is reachable, which keeps the proxy and the proxy
46276 * target reachable. We do need to replace the internal _Target.
46277 */
46278 DUK_DDD(DUK_DDDPRINT("no enumerate trap, enumerate proxy target instead"));
46279 DUK_DDD(DUK_DDDPRINT("h_proxy_target=%!O", (duk_heaphdr *) h_proxy_target));
46280 enum_target = h_proxy_target;
46281
46282 duk_push_hobject(ctx, enum_target); /* -> [ ... enum_target res handler undefined target ] */
46284
46285 duk_pop_2(ctx); /* -> [ ... enum_target res ] */
46286 goto skip_proxy;
46287 }
46288
46289 /* [ ... enum_target res handler trap ] */
46290 duk_insert(ctx, -2);
46291 duk_push_hobject(ctx, h_proxy_target); /* -> [ ... enum_target res trap handler target ] */
46292 duk_call_method(ctx, 1 /*nargs*/); /* -> [ ... enum_target res trap_result ] */
46293 h_trap_result = duk_require_hobject(ctx, -1);
46294 DUK_UNREF(h_trap_result);
46295
46296 /* Copy trap result keys into the enumerator object. */
46297 len = (duk_uint_fast32_t) duk_get_length(ctx, -1);
46298 for (i = 0; i < len; i++) {
46299 /* XXX: not sure what the correct semantic details are here,
46300 * e.g. handling of missing values (gaps), handling of non-array
46301 * trap results, etc.
46302 *
46303 * For keys, we simply skip non-string keys which seems to be
46304 * consistent with how e.g. Object.keys() will process proxy trap
46305 * results (ES6, Section 19.1.2.14).
46306 */
46307 if (duk_get_prop_index(ctx, -1, i) && duk_is_string(ctx, -1)) {
46308 /* [ ... enum_target res trap_result val ] */
46309 duk_push_true(ctx);
46310 /* [ ... enum_target res trap_result val true ] */
46311 duk_put_prop(ctx, -4);
46312 } else {
46313 duk_pop(ctx);
46314 }
46315 }
46316 /* [ ... enum_target res trap_result ] */
46317 duk_pop(ctx);
46318 duk_remove(ctx, -2);
46319
46320 /* [ ... res ] */
46321
46322 /* The internal _Target property is kept pointing to the original
46323 * enumeration target (the proxy object), so that the enumerator
46324 * 'next' operation can read property values if so requested. The
46325 * fact that the _Target is a proxy disables key existence check
46326 * during enumeration.
46327 */
46328 DUK_DDD(DUK_DDDPRINT("proxy enumeration, final res: %!O", (duk_heaphdr *) res));
46329 goto compact_and_return;
46330
46331 skip_proxy:
46332#endif /* DUK_USE_ES6_PROXY */
46333
46334 curr = enum_target;
46335 while (curr) {
46336 /*
46337 * Virtual properties.
46338 *
46339 * String and buffer indices are virtual and always enumerable,
46340 * 'length' is virtual and non-enumerable. Array and arguments
46341 * object props have special behavior but are concrete.
46342 */
46343
46346 /* String and buffer enumeration behavior is identical now,
46347 * so use shared handler.
46348 */
46350 duk_hstring *h_val;
46351 h_val = duk_hobject_get_internal_value_string(thr->heap, curr);
46352 DUK_ASSERT(h_val != NULL); /* string objects must not created without internal value */
46354 } else {
46355 duk_hbufferobject *h_bufobj;
46357 h_bufobj = (duk_hbufferobject *) curr;
46358 if (h_bufobj == NULL) {
46359 /* Neutered buffer, zero length seems
46360 * like good behavior here.
46361 */
46362 len = 0;
46363 } else {
46364 /* There's intentionally no check for
46365 * current underlying buffer length.
46366 */
46367 len = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);
46368 }
46369 }
46370
46371 for (i = 0; i < len; i++) {
46372 duk_hstring *k;
46373
46375 DUK_ASSERT(k);
46376 duk_push_hstring(ctx, k);
46377 duk_push_true(ctx);
46378
46379 /* [enum_target res key true] */
46380 duk_put_prop(ctx, -3);
46381
46382 /* [enum_target res] */
46383 }
46384
46385 /* 'length' and other virtual properties are not
46386 * enumerable, but are included if non-enumerable
46387 * properties are requested.
46388 */
46389
46390 if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
46392
46393 if (DUK_HOBJECT_IS_BUFFEROBJECT(curr)) {
46394 n = sizeof(duk__bufferobject_virtual_props) / sizeof(duk_uint16_t);
46395 } else {
46398 n = 1; /* only 'length' */
46399 }
46400
46401 for (i = 0; i < n; i++) {
46403 duk_push_true(ctx);
46404 duk_put_prop(ctx, -3);
46405 }
46406
46407 }
46408 } else if (DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(curr)) {
46409 if (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {
46411 duk_push_true(ctx);
46412 duk_put_prop(ctx, -3);
46413 }
46414 }
46415
46416 /*
46417 * Array part
46418 *
46419 * Note: ordering between array and entry part must match 'abandon array'
46420 * behavior in duk_hobject_props.c: key order after an array is abandoned
46421 * must be the same.
46422 */
46423
46424 for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {
46425 duk_hstring *k;
46426 duk_tval *tv;
46427
46428 tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);
46429 if (DUK_TVAL_IS_UNUSED(tv)) {
46430 continue;
46431 }
46433 DUK_ASSERT(k);
46434
46435 duk_push_hstring(ctx, k);
46436 duk_push_true(ctx);
46437
46438 /* [enum_target res key true] */
46439 duk_put_prop(ctx, -3);
46440
46441 /* [enum_target res] */
46442 }
46443
46444 /*
46445 * Entries part
46446 */
46447
46448 for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {
46449 duk_hstring *k;
46450
46451 k = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);
46452 if (!k) {
46453 continue;
46454 }
46455 if (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i) &&
46456 !(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {
46457 continue;
46458 }
46459 if (DUK_HSTRING_HAS_INTERNAL(k) &&
46460 !(enum_flags & DUK_ENUM_INCLUDE_INTERNAL)) {
46461 continue;
46462 }
46463 if ((enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) &&
46465 continue;
46466 }
46467
46470
46471 duk_push_hstring(ctx, k);
46472 duk_push_true(ctx);
46473
46474 /* [enum_target res key true] */
46475 duk_put_prop(ctx, -3);
46476
46477 /* [enum_target res] */
46478 }
46479
46480 if (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {
46481 break;
46482 }
46483
46484 curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
46485 }
46486
46487 /* [enum_target res] */
46488
46489 duk_remove(ctx, -2);
46490
46491 /* [res] */
46492
46495 /*
46496 * Some E5/E5.1 algorithms require that array indices are iterated
46497 * in a strictly ascending order. This is the case for e.g.
46498 * Array.prototype.forEach() and JSON.stringify() PropertyList
46499 * handling.
46500 *
46501 * To ensure this property for arrays with an array part (and
46502 * arbitrary objects too, since e.g. forEach() can be applied
46503 * to an array), the caller can request that we sort the keys
46504 * here.
46505 */
46506
46507 /* XXX: avoid this at least when enum_target is an Array, it has an
46508 * array part, and no ancestor properties were included? Not worth
duk_uint32_t duk_uint_fast32_t
DUK_EXTERNAL void duk_pop_2(duk_context *ctx)
DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
#define DUK_HOBJECT_GET_PROTOTYPE(heap, h)
DUK_INTERNAL_DECL duk_hobject * duk_require_hobject(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
DUK_EXTERNAL void duk_push_true(duk_context *ctx)
#define DUK_HOBJECT_HAS_EXOTIC_DUKFUNC(h)
#define DUK_HSTRING_NO_ARRAY_INDEX
#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap, h, i)
#define DUK_HOBJECT_GET_ENEXT(h)
DUK_INTERNAL_DECL duk_hstring * duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj)
#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)
DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t stridx)
DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index)
#define DUK_TVAL_IS_UNUSED(tv)
DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val)
#define DUK_HOBJECT_IS_BUFFEROBJECT(h)
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)
DUK_INTERNAL_DECL duk_hstring * duk_heap_string_intern_u32_checked(duk_hthread *thr, duk_uint32_t val)
DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index)
#define DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)
#define DUK_STRIDX_INT_TARGET
#define DUK_HSTRING_HAS_INTERNAL(x)
DUK_INTERNAL_DECL duk_idx_t duk_push_object_internal(duk_context *ctx)
DUK_LOCAL const duk_uint16_t duk__bufferobject_virtual_props[]
DUK_INTERNAL_DECL void duk_push_hstring(duk_context *ctx, duk_hstring *h)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hthread *thr, duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler)
DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx)
#define DUK_ENUM_ARRAY_INDICES_ONLY
#define DUK_ENUM_SORT_ARRAY_INDICES
#define DUK_ENUM_NO_PROXY_BEHAVIOR
#define DUK_ENUM_OWN_PROPERTIES_ONLY
#define DUK_ENUM_INCLUDE_INTERNAL
#define DUK_ENUM_INCLUDE_NONENUMERABLE

◆ duk_hobject_enumerator_next()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next ( duk_context * ctx,
duk_bool_t get_value )

Definition at line 46518 of file duktape-1.5.2/src-noline/duktape.c.

46519 :
46520#endif
46521 /* compact; no need to seal because object is internal */
46522 duk_hobject_compact_props(thr, res);
46523
46524 DUK_DDD(DUK_DDDPRINT("created enumerator object: %!iT", (duk_tval *) duk_get_tval(ctx, -1)));
46525}
46526
46527/*
46528 * Returns non-zero if a key and/or value was enumerated, and:
46529 *
46530 * [enum] -> [key] (get_value == 0)
46531 * [enum] -> [key value] (get_value == 1)
46532 *
46533 * Returns zero without pushing anything on the stack otherwise.
46534 */
46536 duk_hthread *thr = (duk_hthread *) ctx;
46537 duk_hobject *e;
46538 duk_hobject *enum_target;
46539 duk_hstring *res = NULL;
46541 duk_bool_t check_existence;
46542
46543 DUK_ASSERT(ctx != NULL);
46544
46545 /* [... enum] */
46546
46547 e = duk_require_hobject(ctx, -1);
46548
46549 /* XXX use get tval ptr, more efficient */
46551 idx = (duk_uint_fast32_t) duk_require_uint(ctx, -1);
46552 duk_pop(ctx);
46553 DUK_DDD(DUK_DDDPRINT("enumeration: index is: %ld", (long) idx));
46554
46555 /* Enumeration keys are checked against the enumeration target (to see
46556 * that they still exist). In the proxy enumeration case _Target will
46557 * be the proxy, and checking key existence against the proxy is not
46558 * required (or sensible, as the keys may be fully virtual).
46559 */
46561 enum_target = duk_require_hobject(ctx, -1);
46562 DUK_ASSERT(enum_target != NULL);
46563#if defined(DUK_USE_ES6_PROXY)
46564 check_existence = (!DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(enum_target));
46565#else
46566 check_existence = 1;
46567#endif
46568 duk_pop(ctx); /* still reachable */
46569
46570 DUK_DDD(DUK_DDDPRINT("getting next enum value, enum_target=%!iO, enumerator=%!iT",
46571 (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(ctx, -1)));
46572
46573 /* no array part */
46574 for (;;) {
46575 duk_hstring *k;
46576
46577 if (idx >= DUK_HOBJECT_GET_ENEXT(e)) {
46578 DUK_DDD(DUK_DDDPRINT("enumeration: ran out of elements"));
46579 break;
46580 }
46581
46582 /* we know these because enum objects are internally created */
46583 k = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);
46584 DUK_ASSERT(k != NULL);
46587
46588 idx++;
46589
46590 /* recheck that the property still exists */
46591 if (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {
46592 DUK_DDD(DUK_DDDPRINT("property deleted during enumeration, skip"));
46593 continue;
46594 }
46595
46596 DUK_DDD(DUK_DDDPRINT("enumeration: found element, key: %!O", (duk_heaphdr *) k));
46597 res = k;
46598 break;
46599 }
46600
46601 DUK_DDD(DUK_DDDPRINT("enumeration: updating next index to %ld", (long) idx));
46602
46603 duk_push_u32(ctx, (duk_uint32_t) idx);
46605
46606 /* [... enum] */
46607
DUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key)
#define DUK_HOBJECT_E_GET_VALUE(heap, h, i)
DUK_EXTERNAL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t index)
#define duk_push_u32(ctx, val)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_context *ctx, duk_bool_t get_value)

◆ duk_hobject_find_existing_array_entry_tval_ptr()

DUK_INTERNAL_DECL duk_tval * duk_hobject_find_existing_array_entry_tval_ptr ( duk_heap * heap,
duk_hobject * obj,
duk_uarridx_t i )

Definition at line 48300 of file duktape-1.5.2/src-noline/duktape.c.

48307 {
48308 *out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);
48309 return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
48310 } else {
48311 *out_attrs = 0;
48312 return NULL;
48313 }
48314}

◆ duk_hobject_find_existing_entry()

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 )

Definition at line 48179 of file duktape-1.5.2/src-noline/duktape.c.

48196 {
48197 DUK_ASSERT(obj != NULL);
48198 DUK_ASSERT(key != NULL);
48199 DUK_ASSERT(e_idx != NULL);
48200 DUK_ASSERT(h_idx != NULL);
48201 DUK_UNREF(heap);
48202
48203 if (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))
48204 {
48205 /* Linear scan: more likely because most objects are small.
48206 * This is an important fast path.
48207 *
48208 * XXX: this might be worth inlining for property lookups.
48209 */
48212 duk_hstring **h_keys_base;
48213 DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using linear scan for lookup"));
48214
48215 h_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);
48216 n = DUK_HOBJECT_GET_ENEXT(obj);
48217 for (i = 0; i < n; i++) {
48218 if (h_keys_base[i] == key) {
48219 *e_idx = i;
48220 *h_idx = -1;
48221 return;
48222 }
48223 }
48224 }
48225#if defined(DUK_USE_HOBJECT_HASH_PART)
48226 else
48227 {
48228 /* hash lookup */
48229 duk_uint32_t n;
48230 duk_uint32_t i, step;
48231 duk_uint32_t *h_base;
48232
48233 DUK_DDD(DUK_DDDPRINT("duk_hobject_find_existing_entry() using hash part for lookup"));
48234
48235 h_base = DUK_HOBJECT_H_GET_BASE(heap, obj);
48236 n = DUK_HOBJECT_GET_HSIZE(obj);
48239
48240 for (;;) {
48241 duk_uint32_t t;
48242
48243 DUK_ASSERT_DISABLE(i >= 0); /* unsigned */
48245 t = h_base[i];
48247 (t < DUK_HOBJECT_GET_ESIZE(obj))); /* t >= 0 always true, unsigned */
48248
48249 if (t == DUK__HASH_UNUSED) {
48250 break;
48251 } else if (t == DUK__HASH_DELETED) {
48252 DUK_DDD(DUK_DDDPRINT("lookup miss (deleted) i=%ld, t=%ld",
48253 (long) i, (long) t));
48254 } else {
48256 if (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {
48257 DUK_DDD(DUK_DDDPRINT("lookup hit i=%ld, t=%ld -> key %p",
48258 (long) i, (long) t, (void *) key));
48259 *e_idx = t;
48260 *h_idx = i;
#define DUK_HOBJECT_E_GET_KEY_BASE(heap, h)
#define DUK_HSTRING_GET_HASH(x)
#define DUK_ASSERT_DISABLE(x)
#define DUK__HASH_INITIAL(hash, h_size)
#define DUK__HASH_PROBE_STEP(hash)
#define DUK_HOBJECT_GET_ESIZE(h)

◆ duk_hobject_find_existing_entry_tval_ptr()

DUK_INTERNAL_DECL duk_tval * duk_hobject_find_existing_entry_tval_ptr ( duk_heap * heap,
duk_hobject * obj,
duk_hstring * key )

Definition at line 48263 of file duktape-1.5.2/src-noline/duktape.c.

◆ duk_hobject_find_existing_entry_tval_ptr_and_attrs()

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 )

Definition at line 48280 of file duktape-1.5.2/src-noline/duktape.c.

48280 {
48281 duk_int_t e_idx;
48282 duk_int_t h_idx;
48283
48284 DUK_ASSERT(obj != NULL);
48285 DUK_ASSERT(key != NULL);
48286 DUK_UNREF(heap);
48287
48288 duk_hobject_find_existing_entry(heap, obj, key, &e_idx, &h_idx);
48289 if (e_idx >= 0 && !DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {
48290 return DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);
48291 } else {
48292 return NULL;
48293 }
48294}
48295
48296/* For internal use: get non-accessor entry value and attributes */
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)
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)

◆ duk_hobject_get_enumerated_keys()

DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys ( duk_context * ctx,
duk_small_uint_t enum_flags )

Definition at line 46614 of file duktape-1.5.2/src-noline/duktape.c.

46616 {
46617 duk_remove(ctx, -2); /* -> [... key] */
46618 }
46619 return 1;
46620 } else {
46621 duk_pop(ctx); /* -> [...] */
46622 return 0;
46623 }
46624}
46625
46626/*
46627 * Get enumerated keys in an Ecmascript array. Matches Object.keys() behavior
46628 * described in E5 Section 15.2.3.14.
46629 */
46630
46632 duk_hthread *thr = (duk_hthread *) ctx;
46633 duk_hobject *e;
46636
46637 DUK_ASSERT(ctx != NULL);
46638 DUK_ASSERT(duk_get_hobject(ctx, -1) != NULL);
46639 DUK_UNREF(thr);
46640
46641 /* Create a temporary enumerator to get the (non-duplicated) key list;
46642 * the enumerator state is initialized without being needed, but that
46643 * has little impact.
46644 */
46645
46646 duk_hobject_enumerator_create(ctx, enum_flags);
46647 duk_push_array(ctx);
46648
46649 /* [enum_target enum res] */
46650
46651 e = duk_require_hobject(ctx, -2);
46652 DUK_ASSERT(e != NULL);
46653
46654 idx = 0;
46656 duk_hstring *k;
duk_small_int_t duk_ret_t
DUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_context *ctx, duk_small_uint_t enum_flags)
DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags)
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx)

◆ duk_hobject_get_internal_value()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_get_internal_value ( duk_heap * heap,
duk_hobject * obj,
duk_tval * tv )

Definition at line 48403 of file duktape-1.5.2/src-noline/duktape.c.

48420 {

◆ duk_hobject_get_internal_value_string()

DUK_INTERNAL_DECL duk_hstring * duk_hobject_get_internal_value_string ( duk_heap * heap,
duk_hobject * obj )

Definition at line 48422 of file duktape-1.5.2/src-noline/duktape.c.

48430 {
48431 DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx));
48432 DUK_TVAL_SET_TVAL(tv_out, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx));
48433 return 1;
48434 }
48435 DUK_TVAL_SET_UNDEFINED(tv_out);
48436 return 0;
48437}
48438
48440 duk_tval tv;
48441

◆ duk_hobject_get_length()

DUK_INTERNAL_DECL duk_uint32_t duk_hobject_get_length ( duk_hthread * thr,
duk_hobject * obj )

Definition at line 51823 of file duktape-1.5.2/src-noline/duktape.c.

51823 {
51824 duk_context *ctx = (duk_context *) thr;
51825 duk_push_hobject(ctx, obj);
51827 duk_push_u32(ctx, length);
51828 (void) duk_hobject_putprop(thr,
51829 DUK_GET_TVAL_NEGIDX(ctx, -3),
51830 DUK_GET_TVAL_NEGIDX(ctx, -2),
51831 DUK_GET_TVAL_NEGIDX(ctx, -1),
51832 0);
51833 duk_pop_n(ctx, 3);
51834}
51835
51837 duk_hobject_set_length(thr, obj, 0);
DUK_INTERNAL_DECL void duk_hobject_set_length_zero(duk_hthread *thr, duk_hobject *obj)
DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count)
DUK_INTERNAL_DECL void duk_hobject_set_length(duk_hthread *thr, duk_hobject *obj, duk_uint32_t length)
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)

◆ duk_hobject_get_own_propdesc()

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 )

Definition at line 48945 of file duktape-1.5.2/src-noline/duktape.c.

48950 {
48951 DUK_DDD(DUK_DDDPRINT("-> arguments exotic behavior overrides result: %!T -> %!T",
48952 (duk_tval *) duk_get_tval(ctx, -2),
48953 (duk_tval *) duk_get_tval(ctx, -1)));

◆ duk_hobject_getprop()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop ( duk_hthread * thr,
duk_tval * tv_obj,
duk_tval * tv_key )

Definition at line 49284 of file duktape-1.5.2/src-noline/duktape.c.

49286 {
49287 data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
49288 duk_hbufferobject_validated_write(ctx, h_bufobj, data, elem_size);
49289 } else {
49290 DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (write skipped)"));
49291 }
49292
49293 duk_pop(ctx);
49294 return 1;
49295}
49296
49297/*
49298 * GETPROP: Ecmascript property read.
49299 */
49300
49302 duk_context *ctx = (duk_context *) thr;
49303 duk_tval tv_obj_copy;
49304 duk_tval tv_key_copy;
49305 duk_hobject *curr = NULL;
49306 duk_hstring *key = NULL;
49307 duk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;
49308 duk_propdesc desc;
49309 duk_uint_t sanity;
49310
49311 DUK_DDD(DUK_DDDPRINT("getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
49312 (void *) thr, (void *) tv_obj, (void *) tv_key,
49313 (duk_tval *) tv_obj, (duk_tval *) tv_key));
49314
49315 DUK_ASSERT(ctx != NULL);
49316 DUK_ASSERT(thr != NULL);
49317 DUK_ASSERT(thr->heap != NULL);
49318 DUK_ASSERT(tv_obj != NULL);
49319 DUK_ASSERT(tv_key != NULL);
49320
49322
49323 /*
49324 * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
49325 * them being invalidated by a valstack resize.
49326 *
49327 * XXX: this is now an overkill for many fast paths. Rework this
49328 * to be faster (although switching to a valstack discipline might
49329 * be a better solution overall).
49330 */
49331
49332 DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);
49333 DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
49334 tv_obj = &tv_obj_copy;
49335 tv_key = &tv_key_copy;
49336
49337 /*
49338 * Coercion and fast path processing
49339 */
49340
49341 switch (DUK_TVAL_GET_TAG(tv_obj)) {
49342 case DUK_TAG_UNDEFINED:
49343 case DUK_TAG_NULL: {
49344 /* Note: unconditional throw */
49345 DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject"));
49346#if defined(DUK_USE_PARANOID_ERRORS)
49348#else
49349 DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot read property %s of %s",
49351#endif
49352 return 0;
49353 }
49354
49355 case DUK_TAG_BOOLEAN: {
49356 DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype"));
49357 curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];
49358 break;
49359 }
49360
49361 case DUK_TAG_STRING: {
49362 duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
49363 duk_int_t pop_count;
49364
49365#if defined(DUK_USE_FASTINT)
49366 if (DUK_TVAL_IS_FASTINT(tv_key)) {
49367 arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
49368 DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
49369 pop_count = 0;
49370 } else
49371#endif
49372 if (DUK_TVAL_IS_NUMBER(tv_key)) {
49373 arr_idx = duk__tval_number_to_arr_idx(tv_key);
49374 DUK_DDD(DUK_DDDPRINT("base object string, key is a fast-path number; arr_idx %ld", (long) arr_idx));
49375 pop_count = 0;
49376 } else {
49377 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49378 DUK_ASSERT(key != NULL);
49379 DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
49380 "coercion key is %!T, arr_idx %ld",
49381 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
49382 pop_count = 1;
49383 }
49384
49385 if (arr_idx != DUK__NO_ARRAY_INDEX &&
49386 arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
49387 duk_pop_n(ctx, pop_count);
49388 duk_push_hstring(ctx, h);
49389 duk_substring(ctx, -1, arr_idx, arr_idx + 1); /* [str] -> [substr] */
49390
49391 DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is an index inside string length "
49392 "after coercion -> return char)",
49393 (duk_tval *) duk_get_tval(ctx, -1)));
49394 return 1;
49395 }
49396
49397 if (pop_count == 0) {
49398 /* This is a pretty awkward control flow, but we need to recheck the
49399 * key coercion here.
49400 */
49401 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49402 DUK_ASSERT(key != NULL);
49403 DUK_DDD(DUK_DDDPRINT("base object string, key is a non-fast-path number; after "
49404 "coercion key is %!T, arr_idx %ld",
49405 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
49406 }
49407
49408 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
49409 duk_pop(ctx); /* [key] -> [] */
49410 duk_push_uint(ctx, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); /* [] -> [res] */
49411
49412 DUK_DDD(DUK_DDDPRINT("-> %!T (base is string, key is 'length' after coercion -> "
49413 "return string length)",
49414 (duk_tval *) duk_get_tval(ctx, -1)));
49415 return 1;
49416 }
49417 DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype"));
49418 curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];
49419 goto lookup; /* avoid double coercion */
49420 }
49421
49422 case DUK_TAG_OBJECT: {
49423 duk_tval *tmp;
49424
49425 curr = DUK_TVAL_GET_OBJECT(tv_obj);
49426 DUK_ASSERT(curr != NULL);
49427
49428 tmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);
49429 if (tmp) {
49430 duk_push_tval(ctx, tmp);
49431
49432 DUK_DDD(DUK_DDDPRINT("-> %!T (base is object, key is a number, array part "
49433 "fast path)",
49434 (duk_tval *) duk_get_tval(ctx, -1)));
49435 return 1;
49436 }
49437
49438 if (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {
49439 /* Read value pushed on stack. */
49440 DUK_DDD(DUK_DDDPRINT("-> %!T (base is bufobj, key is a number, bufferobject "
49441 "fast path)",
49442 (duk_tval *) duk_get_tval(ctx, -1)));
49443 return 1;
49444 }
49445
49446#if defined(DUK_USE_ES6_PROXY)
49448 duk_hobject *h_target;
49449
49450 if (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {
49451 /* -> [ ... trap handler ] */
49452 DUK_DDD(DUK_DDDPRINT("-> proxy object 'get' for key %!T", (duk_tval *) tv_key));
49453 duk_push_hobject(ctx, h_target); /* target */
49454 duk_push_tval(ctx, tv_key); /* P */
49455 duk_push_tval(ctx, tv_obj); /* Receiver: Proxy object */
49456 duk_call_method(ctx, 3 /*nargs*/);
49457
49458 /* Target object must be checked for a conflicting
49459 * non-configurable property.
49460 */
49461 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49462 DUK_ASSERT(key != NULL);
49463
49464 if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
49465 duk_tval *tv_hook = duk_require_tval(ctx, -3); /* value from hook */
49466 duk_tval *tv_targ = duk_require_tval(ctx, -1); /* value from target */
49467 duk_bool_t datadesc_reject;
49468 duk_bool_t accdesc_reject;
49469
49470 DUK_DDD(DUK_DDDPRINT("proxy 'get': target has matching property %!O, check for "
49471 "conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, "
49472 "desc.get=%p, desc.set=%p",
49473 (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,
49474 (unsigned long) desc.flags,
49475 (void *) desc.get, (void *) desc.set));
49476
49477 datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
49480 !duk_js_samevalue(tv_hook, tv_targ);
49481 accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
49483 (desc.get == NULL) &&
49484 !DUK_TVAL_IS_UNDEFINED(tv_hook);
49485 if (datadesc_reject || accdesc_reject) {
49487 }
49488
49489 duk_pop_2(ctx);
49490 } else {
49491 duk_pop(ctx);
49492 }
49493 return 1; /* return value */
49494 }
49495
49496 curr = h_target; /* resume lookup from target */
49497 DUK_TVAL_SET_OBJECT(tv_obj, curr);
49498 }
49499#endif /* DUK_USE_ES6_PROXY */
49500
49502 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49503 DUK_ASSERT(key != NULL);
49504
49505 if (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {
49506 DUK_DDD(DUK_DDDPRINT("-> %!T (base is object with arguments exotic behavior, "
49507 "key matches magically bound property -> skip standard "
49508 "Get with replacement value)",
49509 (duk_tval *) duk_get_tval(ctx, -1)));
49510
49511 /* no need for 'caller' post-check, because 'key' must be an array index */
49512
49513 duk_remove(ctx, -2); /* [key result] -> [result] */
49514 return 1;
49515 }
49516
49517 goto lookup; /* avoid double coercion */
49518 }
49519 break;
49520 }
49521
49522 /* Buffer has virtual properties similar to string, but indexed values
49523 * are numbers, not 1-byte buffers/strings which would perform badly.
49524 */
49525 case DUK_TAG_BUFFER: {
49526 duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
49527 duk_int_t pop_count;
49528
49529 /*
49530 * Because buffer values are often looped over, a number fast path
49531 * is important.
49532 */
49533
49534#if defined(DUK_USE_FASTINT)
49535 if (DUK_TVAL_IS_FASTINT(tv_key)) {
49536 arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
49537 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
49538 pop_count = 0;
49539 }
49540 else
49541#endif
49542 if (DUK_TVAL_IS_NUMBER(tv_key)) {
49543 arr_idx = duk__tval_number_to_arr_idx(tv_key);
49544 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
49545 pop_count = 0;
49546 } else {
49547 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49548 DUK_ASSERT(key != NULL);
49549 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
49550 "coercion key is %!T, arr_idx %ld",
49551 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
49552 pop_count = 1;
49553 }
49554
49555 if (arr_idx != DUK__NO_ARRAY_INDEX &&
49556 arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
49557 duk_pop_n(ctx, pop_count);
49558 duk_push_uint(ctx, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);
49559
49560 DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is an index inside buffer length "
49561 "after coercion -> return byte as number)",
49562 (duk_tval *) duk_get_tval(ctx, -1)));
49563 return 1;
49564 }
49565
49566 if (pop_count == 0) {
49567 /* This is a pretty awkward control flow, but we need to recheck the
49568 * key coercion here.
49569 */
49570 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49571 DUK_ASSERT(key != NULL);
49572 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
49573 "coercion key is %!T, arr_idx %ld",
49574 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
49575 }
49576
49577 if (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
49578 key == DUK_HTHREAD_STRING_BYTE_LENGTH(thr)) {
49579 duk_pop(ctx); /* [key] -> [] */
49580 duk_push_uint(ctx, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h)); /* [] -> [res] */
49581
49582 DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'length' or 'byteLength' "
49583 "after coercion -> return buffer length)",
49584 (duk_tval *) duk_get_tval(ctx, -1)));
49585 return 1;
49586 } else if (key == DUK_HTHREAD_STRING_BYTE_OFFSET(thr)) {
49587 duk_pop(ctx); /* [key] -> [] */
49588 duk_push_uint(ctx, 0); /* [] -> [res] */
49589
49590 DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'byteOffset' after coercion -> "
49591 "return 0 for consistency with Buffer objects)",
49592 (duk_tval *) duk_get_tval(ctx, -1)));
49593 return 1;
49594 } else if (key == DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr)) {
49595 duk_pop(ctx); /* [key] -> [] */
49596 duk_push_uint(ctx, 1); /* [] -> [res] */
49597
49598 DUK_DDD(DUK_DDDPRINT("-> %!T (base is buffer, key is 'BYTES_PER_ELEMENT' after coercion -> "
49599 "return 1 for consistency with Buffer objects)",
49600 (duk_tval *) duk_get_tval(ctx, -1)));
49601 return 1;
49602 }
49603
49604 DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from buffer prototype"));
49605 curr = thr->builtins[DUK_BIDX_BUFFER_PROTOTYPE];
49606 goto lookup; /* avoid double coercion */
49607 }
49608
49609 case DUK_TAG_POINTER: {
49610 DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype"));
49611 curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];
49612 break;
49613 }
49614
49615 case DUK_TAG_LIGHTFUNC: {
49616 duk_int_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_obj);
49617
49618 /* Must coerce key: if key is an object, it may coerce to e.g. 'length'. */
49619 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49620
49621 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
49622 duk_int_t lf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);
49623 duk_pop(ctx);
49624 duk_push_int(ctx, lf_len);
49625 return 1;
49626 } else if (key == DUK_HTHREAD_STRING_NAME(thr)) {
49627 duk_pop(ctx);
49628 duk_push_lightfunc_name(ctx, tv_obj);
49629 return 1;
49630 }
49631
49632 DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
49633 curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
49634 goto lookup; /* avoid double coercion */
49635 }
49636
49637#if defined(DUK_USE_FASTINT)
49638 case DUK_TAG_FASTINT:
49639#endif
49640 default: {
49641 /* number */
49642 DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype"));
49645 curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];
49646 break;
49647 }
49648 }
49649
49650 /* key coercion (unless already coerced above) */
49651 DUK_ASSERT(key == NULL);
49652 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49653 DUK_ASSERT(key != NULL);
49654
49655 /*
49656 * Property lookup
49657 */
49658
49659 lookup:
49660 /* [key] (coerced) */
49661 DUK_ASSERT(curr != NULL);
49662 DUK_ASSERT(key != NULL);
49663
49665 do {
49666 if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
49667 goto next_in_chain;
49668 }
49669
49670 if (desc.get != NULL) {
49671 /* accessor with defined getter */
49673
49674 duk_pop(ctx); /* [key undefined] -> [key] */
49675 duk_push_hobject(ctx, desc.get);
49676 duk_push_tval(ctx, tv_obj); /* note: original, uncoerced base */
49677#ifdef DUK_USE_NONSTD_GETTER_KEY_ARGUMENT
49678 duk_dup(ctx, -3);
49679 duk_call_method(ctx, 1); /* [key getter this key] -> [key retval] */
49680#else
49681 duk_call_method(ctx, 0); /* [key getter this] -> [key retval] */
49682#endif
49683 } else {
49684 /* [key value] or [key undefined] */
49685
49686 /* data property or accessor without getter */
49688 (desc.get == NULL));
49689
49690 /* if accessor without getter, return value is undefined */
49692 duk_is_undefined(ctx, -1));
49693
49694 /* Note: for an accessor without getter, falling through to
49695 * check for "caller" exotic behavior is unnecessary as
49696 * "undefined" will never activate the behavior. But it does
49697 * no harm, so we'll do it anyway.
49698 */
49699 }
49700
49701 goto found; /* [key result] */
49702
49703 next_in_chain:
49704 /* XXX: option to pretend property doesn't exist if sanity limit is
49705 * hit might be useful.
49706 */
49707 if (sanity-- == 0) {
49709 }
49710 curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
49711 } while (curr);
49712
49713 /*
49714 * Not found
49715 */
49716
49717 duk_to_undefined(ctx, -1); /* [key] -> [undefined] (default value) */
49718
49719 DUK_DDD(DUK_DDDPRINT("-> %!T (not found)", (duk_tval *) duk_get_tval(ctx, -1)));
49720 return 0;
49721
49722 /*
49723 * Found; post-processing (Function and arguments objects)
49724 */
49725
49726 found:
49727 /* [key result] */
49728
49729#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)
49730 /* Special behavior for 'caller' property of (non-bound) function objects
49731 * and non-strict Arguments objects: if 'caller' -value- (!) is a strict
49732 * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).
49733 * Quite interestingly, a non-strict function with no formal arguments
49734 * will get an arguments object -without- special 'caller' behavior!
49735 *
49736 * The E5.1 spec is a bit ambiguous if this special behavior applies when
49737 * a bound function is the base value (not the 'caller' value): Section
49738 * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions
49739 * matches that of Section 15.3.5.4 ([[Get]] for Function instances).
49740 * However, Section 13.3.5.4 has "NOTE: Function objects created using
49741 * Function.prototype.bind use the default [[Get]] internal method."
49742 * The current implementation assumes this means that bound functions
49743 * should not have the special [[Get]] behavior.
49744 *
49745 * The E5.1 spec is also a bit unclear if the TypeError throwing is
49746 * applied if the 'caller' value is a strict bound function. The
49747 * current implementation will throw even for both strict non-bound
49748 * and strict bound functions.
49749 *
49750 * See test-dev-strict-func-as-caller-prop-value.js for quite extensive
49751 * tests.
49752 *
49753 * This exotic behavior is disabled when the non-standard 'caller' property
49754 * is enabled, as it conflicts with the free use of 'caller'.
49755 */
49756 if (key == DUK_HTHREAD_STRING_CALLER(thr) &&
49757 DUK_TVAL_IS_OBJECT(tv_obj)) {
49758 duk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);
49759 DUK_ASSERT(orig != NULL);
49760
49763 duk_hobject *h;
49764
49765 /* XXX: The TypeError is currently not applied to bound
49766 * functions because the 'strict' flag is not copied by
49767 * bind(). This may or may not be correct, the specification
49768 * only refers to the value being a "strict mode Function
49769 * object" which is ambiguous.
49770 */
#define DUK_HTHREAD_STRING_BYTES_PER_ELEMENT(thr)
#define DUK_ERROR_RANGE(thr, msg)
DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_HAS_BOUND(h)
DUK_INTERNAL_DECL void duk_hbufferobject_validated_write(duk_context *ctx, duk_hbufferobject *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size)
DUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key)
#define DUK_TVAL_SET_OBJECT(tv, hptr)
DUK_EXTERNAL void duk_to_undefined(duk_context *ctx, duk_idx_t index)
DUK_LOCAL duk_tval * duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key)
DUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_context *ctx, duk_tval *tv)
#define DUK_BIDX_POINTER_PROTOTYPE
#define DUK_HTHREAD_STRING_BYTE_LENGTH(thr)
#define DUK_BIDX_FUNCTION_PROTOTYPE
#define DUK_TVAL_GET_TAG(tv)
#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)
#define DUK_BIDX_STRING_PROTOTYPE
DUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key)
#define DUK_BIDX_NUMBER_PROTOTYPE
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
#define DUK_STR_PROTOTYPE_CHAIN_LIMIT
#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY
DUK_EXTERNAL void duk_push_uint(duk_context *ctx, duk_uint_t val)
#define DUK_BIDX_BOOLEAN_PROTOTYPE
#define DUK_HTHREAD_STRING_NAME(thr)
#define DUK_BIDX_BUFFER_PROTOTYPE
#define DUK_HTHREAD_STRING_BYTE_OFFSET(thr)
DUK_EXTERNAL void duk_substring(duk_context *ctx, duk_idx_t index, duk_size_t start_offset, duk_size_t end_offset)
DUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv)
#define DUK_HBUFFER_GET_DATA_PTR(heap, x)
#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags)
#define DUK_HTHREAD_STRING_CALLER(thr)
#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)

◆ duk_hobject_hasprop()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop ( duk_hthread * thr,
duk_tval * tv_obj,
duk_tval * tv_key )

Definition at line 49780 of file duktape-1.5.2/src-noline/duktape.c.

49797 {
49798 duk_context *ctx = (duk_context *) thr;
49799 duk_tval tv_key_copy;
49800 duk_hobject *obj;
49801 duk_hstring *key;
49802 duk_uint32_t arr_idx;
49803 duk_bool_t rc;
49804 duk_propdesc desc;
49805
49806 DUK_DDD(DUK_DDDPRINT("hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)",
49807 (void *) thr, (void *) tv_obj, (void *) tv_key,
49808 (duk_tval *) tv_obj, (duk_tval *) tv_key));
49809
49810 DUK_ASSERT(thr != NULL);
49811 DUK_ASSERT(thr->heap != NULL);
49812 DUK_ASSERT(tv_obj != NULL);
49813 DUK_ASSERT(tv_key != NULL);
49815
49816 DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
49817 tv_key = &tv_key_copy;
49818
49819 /*
49820 * The 'in' operator requires an object as its right hand side,
49821 * throwing a TypeError unconditionally if this is not the case.
49822 *
49823 * However, lightfuncs need to behave like fully fledged objects
49824 * here to be maximally transparent, so we need to handle them
49825 * here.
49826 */
49827
49828 /* XXX: Refactor key coercion so that it's only called once. It can't
49829 * be trivially lifted here because the object must be type checked
49830 * first.
49831 */
49832
49833 if (DUK_TVAL_IS_OBJECT(tv_obj)) {
49834 obj = DUK_TVAL_GET_OBJECT(tv_obj);
49835 DUK_ASSERT(obj != NULL);
49836
49837 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49838 } else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {
49839 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
49840 if (duk__key_is_lightfunc_ownprop(thr, key)) {
49841 /* FOUND */
49842 rc = 1;
49843 goto pop_and_return;
49844 }
49845
49846 /* If not found, resume existence check from Function.prototype.
49847 * We can just substitute the value in this case; nothing will
49848 * need the original base value (as would be the case with e.g.
49849 * setters/getters.
49850 */
49851 obj = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
49852 } else {
49853 /* Note: unconditional throw */
49854 DUK_DDD(DUK_DDDPRINT("base object is not an object -> reject"));
49856 }
49857
49858 /* XXX: fast path for arrays? */
49859
49860 DUK_ASSERT(key != NULL);
49861 DUK_ASSERT(obj != NULL);
49862 DUK_UNREF(arr_idx);
49863
49864#if defined(DUK_USE_ES6_PROXY)
49866 duk_hobject *h_target;
49867 duk_bool_t tmp_bool;
49868
49869 /* XXX: the key in 'key in obj' is string coerced before we're called
49870 * (which is the required behavior in E5/E5.1/E6) so the key is a string
49871 * here already.
49872 */
49873
49874 if (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {
49875 /* [ ... key trap handler ] */
49876 DUK_DDD(DUK_DDDPRINT("-> proxy object 'has' for key %!T", (duk_tval *) tv_key));
49877 duk_push_hobject(ctx, h_target); /* target */
49878 duk_push_tval(ctx, tv_key); /* P */
49879 duk_call_method(ctx, 2 /*nargs*/);
49880 tmp_bool = duk_to_boolean(ctx, -1);
49881 if (!tmp_bool) {
49882 /* Target object must be checked for a conflicting
49883 * non-configurable property.
49884 */
49885
49886 if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
49887 DUK_DDD(DUK_DDDPRINT("proxy 'has': target has matching property %!O, check for "
49888 "conflicting property; desc.flags=0x%08lx, "
49889 "desc.get=%p, desc.set=%p",
49890 (duk_heaphdr *) key, (unsigned long) desc.flags,
49891 (void *) desc.get, (void *) desc.set));
49892 /* XXX: Extensibility check for target uses IsExtensible(). If we
49893 * implemented the isExtensible trap and didn't reject proxies as
49894 * proxy targets, it should be respected here.
49895 */
49896 if (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && /* property is configurable and */
49897 DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) { /* ... target is extensible */
49899 }
49900 }
49901 }
49902
#define DUK_HOBJECT_HAS_EXTENSIBLE(h)

◆ duk_hobject_hasprop_raw()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw ( duk_hthread * thr,
duk_hobject * obj,
duk_hstring * key )

Definition at line 49916 of file duktape-1.5.2/src-noline/duktape.c.

49916 :
49917 duk_pop(ctx); /* [ key ] -> [] */
49918 return rc;
49919}
49920
49921/*
49922 * HASPROP variant used internally.
49923 *
49924 * This primitive must never throw an error, callers rely on this.
49925 * In particular, don't throw an error for prototype loops; instead,
49926 * pretend like the property doesn't exist if a prototype sanity limit
49927 * is reached.

◆ duk_hobject_object_get_own_property_descriptor()

DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor ( duk_context * ctx)

Definition at line 51845 of file duktape-1.5.2/src-noline/duktape.c.

51850 {
51851 return (duk_uint32_t) val;
51852 }
51853 return 0;
51854}
51855
51856/*
51857 * Object.getOwnPropertyDescriptor() (E5 Sections 15.2.3.3, 8.10.4)
51858 *
51859 * This is an actual function call.
51860 */
51861
51863 duk_hthread *thr = (duk_hthread *) ctx;
51864 duk_hobject *obj;
51865 duk_hstring *key;
51866 duk_propdesc pd;
51867 duk_bool_t rc;
51868
51869 DUK_ASSERT(ctx != NULL);
51870 DUK_ASSERT(thr != NULL);
51871 DUK_ASSERT(thr->heap != NULL);
51872
51874 (void) duk_to_string(ctx, 1);
51875 key = duk_require_hstring(ctx, 1);
51876
51877 DUK_ASSERT(obj != NULL);
51878 DUK_ASSERT(key != NULL);
51879
51881
51883 if (!rc) {
51884 duk_push_undefined(ctx);
51885
51886 /* [obj key undefined] */
51887 return 1;
51888 }
51889
51890 duk_push_object(ctx);
51891
51892 /* [obj key value desc] */
51893
51894 if (DUK_PROPDESC_IS_ACCESSOR(&pd)) {
51895 /* If a setter/getter is missing (undefined), the descriptor must
51896 * still have the property present with the value 'undefined'.
51897 */
51898 if (pd.get) {
51899 duk_push_hobject(ctx, pd.get);
51900 } else {
51901 duk_push_undefined(ctx);
51902 }
51904 if (pd.set) {
51905 duk_push_hobject(ctx, pd.set);
51906 } else {
51907 duk_push_undefined(ctx);
51908 }
DUK_INTERNAL_DECL duk_hobject * duk_require_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx)
DUK_EXTERNAL void duk_push_undefined(duk_context *ctx)
#define DUK_PROPDESC_IS_ACCESSOR(p)
DUK_INTERNAL_DECL duk_ret_t duk_hobject_object_get_own_property_descriptor(duk_context *ctx)
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)

◆ duk_hobject_object_is_sealed_frozen_helper()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper ( duk_hthread * thr,
duk_hobject * obj,
duk_bool_t is_frozen )

Definition at line 53002 of file duktape-1.5.2/src-noline/duktape.c.

53019 {
53021
53022 DUK_ASSERT(obj != NULL);
53023 DUK_UNREF(thr);
53024
53025 /* Note: no allocation pressure, no need to check refcounts etc */
53026
53027 /* must not be extensible */
53028 if (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {
53029 return 0;
53030 }
53031
53032 /* all virtual properties are non-configurable and non-writable */
53033
53034 /* entry part must not contain any configurable properties, or
53035 * writable properties (if is_frozen).
53036 */
53037 for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
53038 duk_small_uint_t flags;
53039
53040 if (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {
53041 continue;
53042 }
53043
53044 /* avoid multiple computations of flags address; bypasses macros */
53045 flags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);
53046
53047 if (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {
53048 return 0;
53049 }
53050 if (is_frozen &&
53051 !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&

◆ duk_hobject_object_ownprop_helper()

DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper ( duk_context * ctx,
duk_small_uint_t required_desc_flags )

Definition at line 52906 of file duktape-1.5.2/src-noline/duktape.c.

52906 :
52908 return;
52909
52910 fail_not_configurable:
52912 return;
52913
52914 fail_array_length_partial:
52916 return;
52917}
52918
52919/*
52920 * Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().
52921 */
52922
52924 duk_hthread *thr = (duk_hthread *) ctx;
#define DUK_STR_ARRAY_LENGTH_WRITE_FAILED
#define DUK_STR_NOT_EXTENSIBLE
DUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_context *ctx, duk_small_uint_t required_desc_flags)

◆ duk_hobject_object_seal_freeze_helper()

DUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper ( duk_hthread * thr,
duk_hobject * obj,
duk_bool_t is_freeze )

Definition at line 52941 of file duktape-1.5.2/src-noline/duktape.c.

52958 {
52960
52961 DUK_ASSERT(thr != NULL);
52962 DUK_ASSERT(thr->heap != NULL);
52963 DUK_ASSERT(obj != NULL);
52964
52966
52967#if defined(DUK_USE_ROM_OBJECTS)
52969 DUK_DD(DUK_DDPRINT("attempt to seal/freeze a readonly object, reject"));
52971 }
52972#endif
52973
52974 /*
52975 * Abandon array part because all properties must become non-configurable.
52976 * Note that this is now done regardless of whether this is always the case
52977 * (skips check, but performance problem if caller would do this many times
52978 * for the same object; not likely).
52979 */
52980
52983
52984 for (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {
52985 duk_uint8_t *fp;
52986
52987 /* since duk__abandon_array_checked() causes a resize, there should be no gaps in keys */
52988 DUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);
52989

◆ duk_hobject_prepare_property_descriptor()

DUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor ( duk_context * ctx,
duk_idx_t idx_in,
duk_uint_t * out_defprop_flags,
duk_idx_t * out_idx_value,
duk_hobject ** out_getter,
duk_hobject ** out_setter )

Definition at line 51926 of file duktape-1.5.2/src-noline/duktape.c.

51948 {
51949 duk_hthread *thr = (duk_hthread *) ctx;
51950 duk_idx_t idx_value = -1;
51951 duk_hobject *getter = NULL;
51952 duk_hobject *setter = NULL;
51953 duk_bool_t is_data_desc = 0;
51954 duk_bool_t is_acc_desc = 0;
51955 duk_uint_t defprop_flags = 0;
51956
51957 DUK_ASSERT(ctx != NULL);
51958 DUK_ASSERT(out_defprop_flags != NULL);
51959 DUK_ASSERT(out_idx_value != NULL);
51960 DUK_ASSERT(out_getter != NULL);
51961 DUK_ASSERT(out_setter != NULL);
51962
51963 /* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */
51964 idx_in = duk_require_normalize_index(ctx, idx_in);
51965 (void) duk_require_hobject(ctx, idx_in);
51966
51967 /* The coercion order must match the ToPropertyDescriptor() algorithm
51968 * so that side effects in coercion happen in the correct order.
51969 * (This order also happens to be compatible with duk_def_prop(),
51970 * although it doesn't matter in practice.)
51971 */
51972
51973 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_VALUE)) {
51974 is_data_desc = 1;
51975 defprop_flags |= DUK_DEFPROP_HAVE_VALUE;
51976 idx_value = duk_get_top_index(ctx);
51977 /* Leave 'value' on stack */
51978 } else {
51979 duk_pop(ctx);
51980 }
51981
51982 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_WRITABLE)) {
51983 is_data_desc = 1;
51984 if (duk_to_boolean(ctx, -1)) {
51986 } else {
51987 defprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;
51988 }
51989 }
51990 duk_pop(ctx);
51991
51992 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_GET)) {
51993 duk_tval *tv = duk_require_tval(ctx, -1);
51994 duk_hobject *h_get;
51995
51996 if (DUK_TVAL_IS_UNDEFINED(tv)) {
51997 /* undefined is accepted */
51998 DUK_ASSERT(getter == NULL);
51999 } else {
52000 /* NOTE: lightfuncs are coerced to full functions because
52001 * lightfuncs don't fit into a property value slot. This
52002 * has some side effects, see test-dev-lightfunc-accessor.js.
52003 */
52004 h_get = duk_get_hobject_or_lfunc_coerce(ctx, -1);
52005 if (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {
52006 goto type_error;
52007 }
52008 getter = h_get;
52009 }
52010 is_acc_desc = 1;
52011 defprop_flags |= DUK_DEFPROP_HAVE_GETTER;
52012 /* Leave 'getter' on stack */
52013 } else {
52014 duk_pop(ctx);
52015 }
52016
52017 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_SET)) {
52018 duk_tval *tv = duk_require_tval(ctx, -1);
52019 duk_hobject *h_set;
52020
52021 if (DUK_TVAL_IS_UNDEFINED(tv)) {
52022 /* undefined is accepted */
52023 DUK_ASSERT(setter == NULL);
52024 } else {
52025 /* NOTE: lightfuncs are coerced to full functions because
52026 * lightfuncs don't fit into a property value slot. This
52027 * has some side effects, see test-dev-lightfunc-accessor.js.
52028 */
52029 h_set = duk_get_hobject_or_lfunc_coerce(ctx, -1);
52030 if (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {
52031 goto type_error;
52032 }
52033 setter = h_set;
52034 }
52035 is_acc_desc = 1;
52036 defprop_flags |= DUK_DEFPROP_HAVE_SETTER;
52037 /* Leave 'setter' on stack */
52038 } else {
52039 duk_pop(ctx);
52040 }
52041
52042 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_ENUMERABLE)) {
52043 if (duk_to_boolean(ctx, -1)) {
52045 } else {
52046 defprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;
52047 }
52048 }
52049 duk_pop(ctx);
52050
52051 if (duk_get_prop_stridx(ctx, idx_in, DUK_STRIDX_CONFIGURABLE)) {
52052 if (duk_to_boolean(ctx, -1)) {
52054 } else {
52055 defprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;
52056 }
52057 }
#define DUK_STRIDX_ENUMERABLE
DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index)
#define DUK_STRIDX_WRITABLE
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_IS_CALLABLE(h)
DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx)
#define DUK_STRIDX_CONFIGURABLE
#define DUK_DEFPROP_HAVE_GETTER
#define DUK_DEFPROP_HAVE_VALUE
#define DUK_DEFPROP_CONFIGURABLE
#define DUK_DEFPROP_HAVE_WRITABLE
#define DUK_DEFPROP_HAVE_SETTER
#define DUK_DEFPROP_HAVE_CONFIGURABLE
#define DUK_DEFPROP_ENUMERABLE
#define DUK_DEFPROP_HAVE_ENUMERABLE
#define DUK_DEFPROP_WRITABLE

◆ duk_hobject_prototype_chain_contains()

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 )

Definition at line 46773 of file duktape-1.5.2/src-noline/duktape.c.

46773 {
46774 /* Note: we ask for one return value from duk_safe_call to get this
46775 * error debugging here.
46776 */
46777 DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
46778 (void *) obj, (duk_tval *) duk_get_tval(ctx, -1)));
46779 }
46780 duk_pop_2(ctx); /* -> [...] */
46781
46782 DUK_ASSERT_TOP(ctx, entry_top);
46783}
46784/*
46785 * Misc support functions
46786 */
46787
46788/* include removed: duk_internal.h */
46789
46791 duk_uint_t sanity;
46792
46793 DUK_ASSERT(thr != NULL);
46794
46795 /* False if the object is NULL or the prototype 'p' is NULL.
46796 * In particular, false if both are NULL (don't compare equal).
46797 */
46798 if (h == NULL || p == NULL) {
46799 return 0;
46800 }
46801
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)
#define DUK_ASSERT_TOP(ctx, n)

◆ duk_hobject_putprop()

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 )

Definition at line 50306 of file duktape-1.5.2/src-noline/duktape.c.

50307 :
50308 *
50309 * - Preprocessing before and postprocessing after an actual property
50310 * write. For example, array index write requires pre-checking the
50311 * array 'length' property for access control, and may require an
50312 * array 'length' update after the actual write has succeeded (but
50313 * not if it fails).
50314 *
50315 * - Deletion of multiple entries, as a result of array 'length' write.
50316 *
50317 * * Input values are taken as pointers which may point to the valstack.
50318 * If valstack is resized because of the put (this may happen at least
50319 * when the array part is abandoned), the pointers can be invalidated.
50320 * (We currently make a copy of all of the input values to avoid issues.)
50321 */
50322
50323DUK_INTERNAL 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) {
50324 duk_context *ctx = (duk_context *) thr;
50325 duk_tval tv_obj_copy;
50326 duk_tval tv_key_copy;
50327 duk_tval tv_val_copy;
50328 duk_hobject *orig = NULL; /* NULL if tv_obj is primitive */
50329 duk_hobject *curr;
50330 duk_hstring *key = NULL;
50331 duk_propdesc desc;
50332 duk_tval *tv;
50333 duk_uint32_t arr_idx;
50334 duk_bool_t rc;
50335 duk_int_t e_idx;
50336 duk_uint_t sanity;
50337 duk_uint32_t new_array_length = 0; /* 0 = no update */
50338
50339 DUK_DDD(DUK_DDDPRINT("putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld "
50340 "(obj -> %!T, key -> %!T, val -> %!T)",
50341 (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,
50342 (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));
50343
50344 DUK_ASSERT(thr != NULL);
50345 DUK_ASSERT(thr->heap != NULL);
50346 DUK_ASSERT(ctx != NULL);
50347 DUK_ASSERT(tv_obj != NULL);
50348 DUK_ASSERT(tv_key != NULL);
50349 DUK_ASSERT(tv_val != NULL);
50350
50352
50353 /*
50354 * Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
50355 * them being invalidated by a valstack resize.
50356 *
50357 * XXX: this is an overkill for some paths, so optimize this later
50358 * (or maybe switch to a stack arguments model entirely).
50359 */
50360
50361 DUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);
50362 DUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);
50363 DUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);
50364 tv_obj = &tv_obj_copy;
50365 tv_key = &tv_key_copy;
50366 tv_val = &tv_val_copy;
50367
50368 /*
50369 * Coercion and fast path processing.
50370 */
50371
50372 switch (DUK_TVAL_GET_TAG(tv_obj)) {
50373 case DUK_TAG_UNDEFINED:
50374 case DUK_TAG_NULL: {
50375 /* Note: unconditional throw */
50376 DUK_DDD(DUK_DDDPRINT("base object is undefined or null -> reject (object=%!iT)",
50377 (duk_tval *) tv_obj));
50378#if defined(DUK_USE_PARANOID_ERRORS)
50380#else
50381 DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
50383#endif
50384 return 0;
50385 }
50386
50387 case DUK_TAG_BOOLEAN: {
50388 DUK_DDD(DUK_DDDPRINT("base object is a boolean, start lookup from boolean prototype"));
50389 curr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];
50390 break;
50391 }
50392
50393 case DUK_TAG_STRING: {
50394 duk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);
50395
50396 /*
50397 * Note: currently no fast path for array index writes.
50398 * They won't be possible anyway as strings are immutable.
50399 */
50400
50401 DUK_ASSERT(key == NULL);
50402 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50403 DUK_ASSERT(key != NULL);
50404
50405 if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {
50406 goto fail_not_writable;
50407 }
50408
50409 if (arr_idx != DUK__NO_ARRAY_INDEX &&
50410 arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {
50411 goto fail_not_writable;
50412 }
50413
50414 DUK_DDD(DUK_DDDPRINT("base object is a string, start lookup from string prototype"));
50415 curr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];
50416 goto lookup; /* avoid double coercion */
50417 }
50418
50419 case DUK_TAG_OBJECT: {
50420 orig = DUK_TVAL_GET_OBJECT(tv_obj);
50421 DUK_ASSERT(orig != NULL);
50422
50423#if defined(DUK_USE_ROM_OBJECTS)
50424 /* With this check in place fast paths won't need read-only
50425 * object checks. This is technically incorrect if there are
50426 * setters that cause no writes to ROM objects, but current
50427 * built-ins don't have such setters.
50428 */
50429 if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
50430 DUK_DD(DUK_DDPRINT("attempt to putprop on read-only target object"));
50431 goto fail_not_writable_no_pop; /* Must avoid duk_pop() in exit path */
50432 }
50433#endif
50434
50435 /* The fast path for array property put is not fully compliant:
50436 * If one places conflicting number-indexed properties into
50437 * Array.prototype (for example, a non-writable Array.prototype[7])
50438 * the fast path will incorrectly ignore them.
50439 *
50440 * This fast path could be made compliant by falling through
50441 * to the slow path if the previous value was UNUSED. This would
50442 * also remove the need to check for extensibility. Right now a
50443 * non-extensible array is slower than an extensible one as far
50444 * as writes are concerned.
50445 *
50446 * The fast path behavior is documented in more detail here:
50447 * tests/ecmascript/test-misc-array-fast-write.js
50448 */
50449
50450 if (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val, &desc) != 0) {
50451 DUK_DDD(DUK_DDDPRINT("array fast path success"));
50452 return 1;
50453 }
50454
50455 if (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {
50456 DUK_DDD(DUK_DDDPRINT("base is bufobj, key is a number, bufferobject fast path"));
50457 return 1;
50458 }
50459
50460#if defined(DUK_USE_ES6_PROXY)
50462 duk_hobject *h_target;
50463 duk_bool_t tmp_bool;
50464
50465 if (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {
50466 /* -> [ ... trap handler ] */
50467 DUK_DDD(DUK_DDDPRINT("-> proxy object 'set' for key %!T", (duk_tval *) tv_key));
50468 duk_push_hobject(ctx, h_target); /* target */
50469 duk_push_tval(ctx, tv_key); /* P */
50470 duk_push_tval(ctx, tv_val); /* V */
50471 duk_push_tval(ctx, tv_obj); /* Receiver: Proxy object */
50472 duk_call_method(ctx, 4 /*nargs*/);
50473 tmp_bool = duk_to_boolean(ctx, -1);
50474 duk_pop(ctx);
50475 if (!tmp_bool) {
50476 goto fail_proxy_rejected;
50477 }
50478
50479 /* Target object must be checked for a conflicting
50480 * non-configurable property.
50481 */
50482 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50483 DUK_ASSERT(key != NULL);
50484
50485 if (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {
50486 duk_tval *tv_targ = duk_require_tval(ctx, -1);
50487 duk_bool_t datadesc_reject;
50488 duk_bool_t accdesc_reject;
50489
50490 DUK_DDD(DUK_DDDPRINT("proxy 'set': target has matching property %!O, check for "
50491 "conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, "
50492 "desc.get=%p, desc.set=%p",
50493 (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,
50494 (unsigned long) desc.flags,
50495 (void *) desc.get, (void *) desc.set));
50496
50497 datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
50500 !duk_js_samevalue(tv_val, tv_targ);
50501 accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
50503 (desc.set == NULL);
50504 if (datadesc_reject || accdesc_reject) {
50506 }
50507
50508 duk_pop_2(ctx);
50509 } else {
50510 duk_pop(ctx);
50511 }
50512 return 1; /* success */
50513 }
50514
50515 orig = h_target; /* resume write to target */
50516 DUK_TVAL_SET_OBJECT(tv_obj, orig);
50517 }
50518#endif /* DUK_USE_ES6_PROXY */
50519
50520 curr = orig;
50521 break;
50522 }
50523
50524 case DUK_TAG_BUFFER: {
50525 duk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);
50526 duk_int_t pop_count = 0;
50527
50528 /*
50529 * Because buffer values may be looped over and read/written
50530 * from, an array index fast path is important.
50531 */
50532
50533#if defined(DUK_USE_FASTINT)
50534 if (DUK_TVAL_IS_FASTINT(tv_key)) {
50535 arr_idx = duk__tval_fastint_to_arr_idx(tv_key);
50536 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path fastint; arr_idx %ld", (long) arr_idx));
50537 pop_count = 0;
50538 } else
50539#endif
50540 if (DUK_TVAL_IS_NUMBER(tv_key)) {
50541 arr_idx = duk__tval_number_to_arr_idx(tv_key);
50542 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a fast-path number; arr_idx %ld", (long) arr_idx));
50543 pop_count = 0;
50544 } else {
50545 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50546 DUK_ASSERT(key != NULL);
50547 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
50548 "coercion key is %!T, arr_idx %ld",
50549 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
50550 pop_count = 1;
50551 }
50552
50553 if (arr_idx != DUK__NO_ARRAY_INDEX &&
50554 arr_idx < DUK_HBUFFER_GET_SIZE(h)) {
50555 duk_uint8_t *data;
50556 DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));
50557 data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);
50558
50559 /* XXX: duk_to_int() ensures we'll get 8 lowest bits as
50560 * as input is within duk_int_t range (capped outside it).
50561 */
50562#if defined(DUK_USE_FASTINT)
50563 /* Buffer writes are often integers. */
50564 if (DUK_TVAL_IS_FASTINT(tv_val)) {
50565 data[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);
50566 }
50567 else
50568#endif
50569 {
50570 duk_push_tval(ctx, tv_val);
50571 data[arr_idx] = (duk_uint8_t) duk_to_uint32(ctx, -1);
50572 pop_count++;
50573 }
50574
50575 duk_pop_n(ctx, pop_count);
50576 DUK_DDD(DUK_DDDPRINT("result: success (buffer data write)"));
50577 return 1;
50578 }
50579
50580 if (pop_count == 0) {
50581 /* This is a pretty awkward control flow, but we need to recheck the
50582 * key coercion here.
50583 */
50584 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50585 DUK_ASSERT(key != NULL);
50586 DUK_DDD(DUK_DDDPRINT("base object buffer, key is a non-fast-path number; after "
50587 "coercion key is %!T, arr_idx %ld",
50588 (duk_tval *) duk_get_tval(ctx, -1), (long) arr_idx));
50589 }
50590
50591 if (key == DUK_HTHREAD_STRING_LENGTH(thr) ||
50592 key == DUK_HTHREAD_STRING_BYTE_LENGTH(thr) ||
50593 key == DUK_HTHREAD_STRING_BYTE_OFFSET(thr) ||
50595 goto fail_not_writable;
50596 }
50597
50598 DUK_DDD(DUK_DDDPRINT("base object is a buffer, start lookup from buffer prototype"));
50599 curr = thr->builtins[DUK_BIDX_BUFFER_PROTOTYPE];
50600 goto lookup; /* avoid double coercion */
50601 }
50602
50603 case DUK_TAG_POINTER: {
50604 DUK_DDD(DUK_DDDPRINT("base object is a pointer, start lookup from pointer prototype"));
50605 curr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];
50606 break;
50607 }
50608
50609 case DUK_TAG_LIGHTFUNC: {
50610 /* All lightfunc own properties are non-writable and the lightfunc
50611 * is considered non-extensible. However, the write may be captured
50612 * by an inherited setter which means we can't stop the lookup here.
50613 */
50614
50615 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50616
50617 if (duk__key_is_lightfunc_ownprop(thr, key)) {
50618 goto fail_not_writable;
50619 }
50620
50621 DUK_DDD(DUK_DDDPRINT("base object is a lightfunc, start lookup from function prototype"));
50622 curr = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];
50623 goto lookup; /* avoid double coercion */
50624 }
50625
50626#if defined(DUK_USE_FASTINT)
50627 case DUK_TAG_FASTINT:
50628#endif
50629 default: {
50630 /* number */
50631 DUK_DDD(DUK_DDDPRINT("base object is a number, start lookup from number prototype"));
50633 curr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];
50634 break;
50635 }
50636 }
50637
50638 DUK_ASSERT(key == NULL);
50639 arr_idx = duk__push_tval_to_hstring_arr_idx(ctx, tv_key, &key);
50640 DUK_ASSERT(key != NULL);
50641
50642 lookup:
50643
50644 /*
50645 * Check whether the property already exists in the prototype chain.
50646 * Note that the actual write goes into the original base object
50647 * (except if an accessor property captures the write).
50648 */
50649
50650 /* [key] */
50651
50652 DUK_ASSERT(curr != NULL);
50654 do {
50655 if (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) { /* don't push value */
50656 goto next_in_chain;
50657 }
50658
50659 if (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
50660 /*
50661 * Found existing accessor property (own or inherited).
50662 * Call setter with 'this' set to orig, and value as the only argument.
50663 * Setter calls are OK even for ROM objects.
50664 *
50665 * Note: no exotic arguments object behavior, because [[Put]] never
50666 * calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).
50667 */
50668
50669 duk_hobject *setter;
50670
50671 DUK_DD(DUK_DDPRINT("put to an own or inherited accessor, calling setter"));
50672
50673 setter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);
50674 if (!setter) {
50675 goto fail_no_setter;
50676 }
50677 duk_push_hobject(ctx, setter);
50678 duk_push_tval(ctx, tv_obj); /* note: original, uncoerced base */
50679 duk_push_tval(ctx, tv_val); /* [key setter this val] */
50680#ifdef DUK_USE_NONSTD_SETTER_KEY_ARGUMENT
50681 duk_dup(ctx, -4);
50682 duk_call_method(ctx, 2); /* [key setter this val key] -> [key retval] */
50683#else
50684 duk_call_method(ctx, 1); /* [key setter this val] -> [key retval] */
50685#endif
50686 duk_pop(ctx); /* ignore retval -> [key] */
50687 goto success_no_arguments_exotic;
50688 }
50689
50690 if (orig == NULL) {
50691 /*
50692 * Found existing own or inherited plain property, but original
50693 * base is a primitive value.
50694 */
50695 DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object"));
50696 goto fail_base_primitive;
50697 }
50698
50699 if (curr != orig) {
50700 /*
50701 * Found existing inherited plain property.
50702 * Do an access control check, and if OK, write
50703 * new property to 'orig'.
50704 */
50705 if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {
50706 DUK_DD(DUK_DDPRINT("found existing inherited plain property, but original object is not extensible"));
50707 goto fail_not_extensible;
50708 }
50709 if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
50710 DUK_DD(DUK_DDPRINT("found existing inherited plain property, original object is extensible, but inherited property is not writable"));
50711 goto fail_not_writable;
50712 }
50713 DUK_DD(DUK_DDPRINT("put to new property, object extensible, inherited property found and is writable"));
50714 goto create_new;
50715 } else {
50716 /*
50717 * Found existing own (non-inherited) plain property.
50718 * Do an access control check and update in place.
50719 */
50720
50721 if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
50722 DUK_DD(DUK_DDPRINT("found existing own (non-inherited) plain property, but property is not writable"));
50723 goto fail_not_writable;
50724 }
50725 if (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {
50726 DUK_DD(DUK_DDPRINT("found existing own (non-inherited) virtual property, property is writable"));
50727 if (DUK_HOBJECT_IS_BUFFEROBJECT(curr)) {
50728 duk_hbufferobject *h_bufobj;
50729 duk_uint_t byte_off;
50730 duk_small_uint_t elem_size;
50731
50732 h_bufobj = (duk_hbufferobject *) curr;
50734
50735 DUK_DD(DUK_DDPRINT("writable virtual property is in buffer object"));
50736
50737 /* Careful with wrapping: arr_idx upshift may easily wrap, whereas
50738 * length downshift won't.
50739 */
50740 if (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {
50741 duk_uint8_t *data;
50742 DUK_DDD(DUK_DDDPRINT("writing to buffer data at index %ld", (long) arr_idx));
50743
50744 DUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX); /* index/length check guarantees */
50745 byte_off = arr_idx << h_bufobj->shift; /* no wrap assuming h_bufobj->length is valid */
50746 elem_size = 1 << h_bufobj->shift;
50747
50748 /* Coerce to number before validating pointers etc so that the
50749 * number coercions in duk_hbufferobject_validated_write() are
50750 * guaranteed to be side effect free and not invalidate the
50751 * pointer checks we do here.
50752 */
50753 duk_push_tval(ctx, tv_val);
50754 duk_to_number(ctx, -1);
50755
50756 if (h_bufobj->buf != NULL && DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {
50757 data = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;
50758 duk_hbufferobject_validated_write(ctx, h_bufobj, data, elem_size);
50759 } else {
50760 DUK_D(DUK_DPRINT("bufferobject access out of underlying buffer, ignoring (write skipped)"));
50761 }
50762 duk_pop(ctx);
50763 goto success_no_arguments_exotic;
50764 }
50765 }
50766
50767 goto fail_internal; /* should not happen */
50768 }
50769 DUK_DD(DUK_DDPRINT("put to existing own plain property, property is writable"));
50770 goto update_old;
50771 }
50773
50774 next_in_chain:
50775 /* XXX: option to pretend property doesn't exist if sanity limit is
50776 * hit might be useful.
50777 */
50778 if (sanity-- == 0) {
50780 }
50781 curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);
50782 } while (curr);
50783
50784 /*
50785 * Property not found in prototype chain.
50786 */
50787
50788 DUK_DDD(DUK_DDDPRINT("property not found in prototype chain"));
50789
50790 if (orig == NULL) {
50791 DUK_DD(DUK_DDPRINT("attempt to create a new property in a primitive base object"));
50792 goto fail_base_primitive;
50793 }
50794
50795 if (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {
50796 DUK_DD(DUK_DDPRINT("put to a new property (not found in prototype chain), but original object not extensible"));
50797 goto fail_not_extensible;
50798 }
50799
50800 goto create_new;
50801
50802 update_old:
50803
50804 /*
50805 * Update an existing property of the base object.
50806 */
50807
50808 /* [key] */
50809
50810 DUK_DDD(DUK_DDDPRINT("update an existing property of the original object"));
50811
50812 DUK_ASSERT(orig != NULL);
50813#if defined(DUK_USE_ROM_OBJECTS)
50814 /* This should not happen because DUK_TAG_OBJECT case checks
50815 * for this already, but check just in case.
50816 */
50817 if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
50818 goto fail_not_writable;
50819 }
50820#endif
50821
50822 /* Although there are writable virtual properties (e.g. plain buffer
50823 * and buffer object number indices), they are handled before we come
50824 * here.
50825 */
50827 DUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);
50828
50829 if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&
50830 key == DUK_HTHREAD_STRING_LENGTH(thr)) {
50831 /*
50832 * Write to 'length' of an array is a very complex case
50833 * handled in a helper which updates both the array elements
50834 * and writes the new 'length'. The write may result in an
50835 * unconditional RangeError or a partial write (indicated
50836 * by a return code).
50837 *
50838 * Note: the helper has an unnecessary writability check
50839 * for 'length', we already know it is writable.
50840 */
50841
50842 DUK_DDD(DUK_DDDPRINT("writing existing 'length' property to array exotic, invoke complex helper"));
50843
50844 /* XXX: the helper currently assumes stack top contains new
50845 * 'length' value and the whole calling convention is not very
50846 * compatible with what we need.
50847 */
50848
50849 duk_push_tval(ctx, tv_val); /* [key val] */
50850 rc = duk__handle_put_array_length(thr, orig);
50851 duk_pop(ctx); /* [key val] -> [key] */
50852 if (!rc) {
50853 goto fail_array_length_partial;
50854 }
50855
50856 /* key is 'length', cannot match argument exotic behavior */
50857 goto success_no_arguments_exotic;
50858 }
50859
50860 if (desc.e_idx >= 0) {
50861 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
50862 DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv));
50863 DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */
50864 /* don't touch property attributes or hash part */
50865 DUK_DD(DUK_DDPRINT("put to an existing entry at index %ld -> new value %!iT",
50866 (long) desc.e_idx, (duk_tval *) tv));
50867 } else {
50868 /* Note: array entries are always writable, so the writability check
50869 * above is pointless for them. The check could be avoided with some
50870 * refactoring but is probably not worth it.
50871 */
50872
50873 DUK_ASSERT(desc.a_idx >= 0);
50874 tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);
50875 DUK_DDD(DUK_DDDPRINT("previous array value: %!iT", (duk_tval *) tv));
50876 DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects */
50877 DUK_DD(DUK_DDPRINT("put to an existing array entry at index %ld -> new value %!iT",
50878 (long) desc.a_idx, (duk_tval *) tv));
50879 }
50880
50881 /* Regardless of whether property is found in entry or array part,
50882 * it may have arguments exotic behavior (array indices may reside
50883 * in entry part for abandoned / non-existent array parts).
50884 */
50885 goto success_with_arguments_exotic;
50886
50887 create_new:
50888
50889 /*
50890 * Create a new property in the original object.
50891 *
50892 * Exotic properties need to be reconsidered here from a write
50893 * perspective (not just property attributes perspective).
50894 * However, the property does not exist in the object already,
50895 * so this limits the kind of exotic properties that apply.
50896 */
50897
50898 /* [key] */
50899
50900 DUK_DDD(DUK_DDDPRINT("create new property to original object"));
50901
50902 DUK_ASSERT(orig != NULL);
50903
50904#if defined(DUK_USE_ROM_OBJECTS)
50905 /* This should not happen because DUK_TAG_OBJECT case checks
50906 * for this already, but check just in case.
50907 */
50908 if (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {
50909 goto fail_not_writable;
50910 }
50911#endif
50912
50913 /* Not possible because array object 'length' is present
50914 * from its creation and cannot be deleted, and is thus
50915 * caught as an existing property above.
50916 */
50918 key == DUK_HTHREAD_STRING_LENGTH(thr)));
50919
50920 if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&
50921 arr_idx != DUK__NO_ARRAY_INDEX) {
50922 /* automatic length update */
50923 duk_uint32_t old_len;
50924
50925 old_len = duk__get_old_array_length(thr, orig, &desc);
50926
50927 if (arr_idx >= old_len) {
50928 DUK_DDD(DUK_DDDPRINT("write new array entry requires length update "
50929 "(arr_idx=%ld, old_len=%ld)",
50930 (long) arr_idx, (long) old_len));
50931
50932 if (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {
50933 DUK_DD(DUK_DDPRINT("attempt to extend array, but array 'length' is not writable"));
50934 goto fail_not_writable;
50935 }
50936
50937 /* Note: actual update happens once write has been completed
50938 * without error below. The write should always succeed
50939 * from a specification viewpoint, but we may e.g. run out
50940 * of memory. It's safer in this order.
50941 */
50942
50943 DUK_ASSERT(arr_idx != 0xffffffffUL);
50944 new_array_length = arr_idx + 1; /* flag for later write */
50945 } else {
50946 DUK_DDD(DUK_DDDPRINT("write new array entry does not require length update "
50947 "(arr_idx=%ld, old_len=%ld)",
50948 (long) arr_idx, (long) old_len));
50949 }
50950 }
50951
50952 /* write_to_array_part: */
50953
50954 /*
50955 * Write to array part?
50956 *
50957 * Note: array abandonding requires a property resize which uses
50958 * 'rechecks' valstack for temporaries and may cause any existing
50959 * valstack pointers to be invalidated. To protect against this,
50960 * tv_obj, tv_key, and tv_val are copies of the original inputs.
50961 */
50962
50963 if (arr_idx != DUK__NO_ARRAY_INDEX &&
50965 if (arr_idx < DUK_HOBJECT_GET_ASIZE(orig)) {
50966 goto no_array_growth;
50967 }
50968
50969 /*
50970 * Array needs to grow, but we don't want it becoming too sparse.
50971 * If it were to become sparse, abandon array part, moving all
50972 * array entries into the entries part (for good).
50973 *
50974 * Since we don't keep track of actual density (used vs. size) of
50975 * the array part, we need to estimate somehow. The check is made
50976 * in two parts:
50977 *
50978 * - Check whether the resize need is small compared to the
50979 * current size (relatively); if so, resize without further
50980 * checking (essentially we assume that the original part is
50981 * "dense" so that the result would be dense enough).
50982 *
50983 * - Otherwise, compute the resize using an actual density
50984 * measurement based on counting the used array entries.
50985 */
50986
50987 DUK_DDD(DUK_DDDPRINT("write to new array requires array resize, decide whether to do a "
50988 "fast resize without abandon check (arr_idx=%ld, old_size=%ld)",
50989 (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(orig)));
50990
50992 duk_uint32_t old_used;
50993 duk_uint32_t old_size;
50994
50995 DUK_DDD(DUK_DDDPRINT("=> fast check is NOT OK, do slow check for array abandon"));
50996
50997 duk__compute_a_stats(thr, orig, &old_used, &old_size);
50998
50999 DUK_DDD(DUK_DDDPRINT("abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld",
51000 (long) old_used, (long) old_size, (long) arr_idx));
51001
51002 /* Note: intentionally use approximations to shave a few instructions:
51003 * a_used = old_used (accurate: old_used + 1)
51004 * a_size = arr_idx (accurate: arr_idx + 1)
51005 */
51006 if (duk__abandon_array_density_check(old_used, arr_idx)) {
51007 DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
51008 "decided to abandon array part (would become too sparse)"));
51009
51010 /* abandoning requires a props allocation resize and
51011 * 'rechecks' the valstack, invalidating any existing
51012 * valstack value pointers!
51013 */
51014 duk__abandon_array_checked(thr, orig);
51016
51017 goto write_to_entry_part;
51018 }
51019
51020 DUK_DDD(DUK_DDDPRINT("=> decided to keep array part"));
51021 } else {
51022 DUK_DDD(DUK_DDDPRINT("=> fast resize is OK"));
51023 }
51024
51025 DUK_DD(DUK_DDPRINT("write to new array entry beyond current length, "
51026 "decided to extend current allocation"));
51027
51028 duk__grow_props_for_array_item(thr, orig, arr_idx);
51029
51030 no_array_growth:
51031
51032 /* Note: assume array part is comprehensive, so that either
51033 * the write goes to the array part, or we've abandoned the
51034 * array above (and will not come here).
51035 */
51036
51038 DUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(orig));
51039
51040 tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, arr_idx);
51041 /* prev value must be unused, no decref */
51043 DUK_TVAL_SET_TVAL(tv, tv_val);
51044 DUK_TVAL_INCREF(thr, tv);
51045 DUK_DD(DUK_DDPRINT("put to new array entry: %ld -> %!T",
51046 (long) arr_idx, (duk_tval *) tv));
51047
51048 /* Note: array part values are [[Writable]], [[Enumerable]],
51049 * and [[Configurable]] which matches the required attributes
51050 * here.
51051 */
51052 goto entry_updated;
51053 }
51054
51055 write_to_entry_part:
51056
51057 /*
51058 * Write to entry part
51059 */
51060
51061 /* entry allocation updates hash part and increases the key
51062 * refcount; may need a props allocation resize but doesn't
51063 * 'recheck' the valstack.
51064 */
51065 e_idx = duk__alloc_entry_checked(thr, orig, key);
51066 DUK_ASSERT(e_idx >= 0);
51067
51068 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);
51069 /* prev value can be garbage, no decref */
51070 DUK_TVAL_SET_TVAL(tv, tv_val);
51071 DUK_TVAL_INCREF(thr, tv);
51072 DUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);
51073 goto entry_updated;
51074
51075 entry_updated:
51076
51077 /*
51078 * Possible pending array length update, which must only be done
51079 * if the actual entry write succeeded.
51080 */
51081
51082 if (new_array_length > 0) {
51083 /*
51084 * Note: zero works as a "no update" marker because the new length
51085 * can never be zero after a new property is written.
51086 *
51087 * Note: must re-lookup because calls above (e.g. duk__alloc_entry_checked())
51088 * may realloc and compact properties and hence change e_idx.
51089 */
51090
51091 DUK_DDD(DUK_DDDPRINT("write successful, pending array length update to: %ld",
51092 (long) new_array_length));
51093
51094 rc = duk__get_own_propdesc_raw(thr, orig, DUK_HTHREAD_STRING_LENGTH(thr), DUK__NO_ARRAY_INDEX, &desc, 0 /*flags*/); /* don't push value */
51095 DUK_UNREF(rc);
51096 DUK_ASSERT(rc != 0);
51097 DUK_ASSERT(desc.e_idx >= 0);
51098
51099 tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
51101 /* no need for decref/incref because value is a number */
51102 DUK_TVAL_SET_FASTINT_U32(tv, new_array_length);
51103 }
51104
51105 /*
51106 * Arguments exotic behavior not possible for new properties: all
51107 * magically bound properties are initially present in the arguments
51108 * object, and if they are deleted, the binding is also removed from
51109 * parameter map.
51110 */
51111
51112 goto success_no_arguments_exotic;
51113
51114 success_with_arguments_exotic:
51115
51116 /*
51117 * Arguments objects have exotic [[DefineOwnProperty]] which updates
51118 * the internal 'map' of arguments for writes to currently mapped
51119 * arguments. More conretely, writes to mapped arguments generate
51120 * a write to a bound variable.
51121 *
51122 * The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing
51123 * data properties and new properties, but not for existing accessors.
51124 * Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we
51125 * have a Desc with 'Value' (and possibly other properties too), and
51126 * we end up in step 5.b.i.
51127 */
51128
51129 if (arr_idx != DUK__NO_ARRAY_INDEX &&
51131 /* Note: only numbered indices are relevant, so arr_idx fast reject
51132 * is good (this is valid unless there are more than 4**32-1 arguments).
51133 */
51134
51135 DUK_DDD(DUK_DDDPRINT("putprop successful, arguments exotic behavior needed"));
51136
51137 /* Note: we can reuse 'desc' here */
51138
51139 /* XXX: top of stack must contain value, which helper doesn't touch,
51140 * rework to use tv_val directly?
51141 */
51142
51143 duk_push_tval(ctx, tv_val);
51144 (void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);
51145 duk_pop(ctx);
51146 }
51147 /* fall thru */
51148
51149 success_no_arguments_exotic:
51150 /* shared exit path now */
51151 DUK_DDD(DUK_DDDPRINT("result: success"));
51152 duk_pop(ctx); /* remove key */
51153 return 1;
51154
51155#if defined(DUK_USE_ES6_PROXY)
51156 fail_proxy_rejected:
51157 DUK_DDD(DUK_DDDPRINT("result: error, proxy rejects"));
51158 if (throw_flag) {
51160 }
51161 /* Note: no key on stack */
51162 return 0;
51163#endif
51164
51165 fail_base_primitive:
51166 DUK_DDD(DUK_DDDPRINT("result: error, base primitive"));
51167 if (throw_flag) {
51168#if defined(DUK_USE_PARANOID_ERRORS)
51170#else
51171 DUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, "cannot write property %s of %s",
51173#endif
51174 }
51175 duk_pop(ctx); /* remove key */
51176 return 0;
51177
51178 fail_not_extensible:
51179 DUK_DDD(DUK_DDDPRINT("result: error, not extensible"));
51180 if (throw_flag) {
51182 }
51183 duk_pop(ctx); /* remove key */
51184 return 0;
51185
51186 fail_not_writable:
51187 DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
51188 if (throw_flag) {
51190 }
51191 duk_pop(ctx); /* remove key */
51192 return 0;
51193
51194#if defined(DUK_USE_ROM_OBJECTS)
51195 fail_not_writable_no_pop:
51196 DUK_DDD(DUK_DDDPRINT("result: error, not writable"));
51197 if (throw_flag) {
51199 }
51200 return 0;
51201#endif
51202
51203 fail_array_length_partial:
51204 DUK_DDD(DUK_DDDPRINT("result: error, array length write only partially successful"));
51205 if (throw_flag) {
51207 }
51208 duk_pop(ctx); /* remove key */
51209 return 0;
#define DUK_HBUFFEROBJECT_VALID_BYTEOFFSET_EXCL(h, off)
DUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val, duk_propdesc *temp_desc)
#define DUK_ASSERT_HBUFFEROBJECT_VALID(h)
DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t index)
DUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj)
DUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag)
DUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size)
DUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val)
DUK_LOCAL duk_uint32_t duk__get_old_array_length(duk_hthread *thr, duk_hobject *obj, duk_propdesc *temp_desc)

◆ duk_hobject_run_finalizer()

DUK_INTERNAL_DECL void duk_hobject_run_finalizer ( duk_hthread * thr,
duk_hobject * obj )

Definition at line 46711 of file duktape-1.5.2/src-noline/duktape.c.

46711 {
46712 DUK_DDD(DUK_DDDPRINT("-> no finalizer or finalizer not callable"));
46713 return 0;
46714 }
46715 duk_dup(ctx, -2);
46717 DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling finalizer"));
46718 duk_call(ctx, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */
46719 DUK_DDD(DUK_DDDPRINT("finalizer finished successfully"));
46720 return 0;
46721
46722 /* Note: we rely on duk_safe_call() to fix up the stack for the caller,
46723 * so we don't need to pop stuff here. There is no return value;
46724 * caller determines rescued status based on object refcount.
46725 */
46726}
46727
46729 duk_context *ctx = (duk_context *) thr;
46730 duk_ret_t rc;
46731#ifdef DUK_USE_ASSERTIONS
46732 duk_idx_t entry_top;
46733#endif
46734
46735 DUK_DDD(DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj));
46736
46737 DUK_ASSERT(thr != NULL);
46738 DUK_ASSERT(ctx != NULL);
46739 DUK_ASSERT(obj != NULL);
46741
46742#ifdef DUK_USE_ASSERTIONS
46743 entry_top = duk_get_top(ctx);
46744#endif
46745 /*
46746 * Get and call the finalizer. All of this must be wrapped
46747 * in a protected call, because even getting the finalizer
46748 * may trigger an error (getter may throw one, for instance).
46749 */
46750
46753 DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj));
46754 return;
46755 }
46756 DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */
46758 /* This shouldn't happen; call sites should avoid looking up
46759 * _Finalizer "through" a Proxy, but ignore if we come here
46760 * with a Proxy to avoid finalizer re-entry.
46761 */
46762 DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call"));
46763 return;
46764 }
46765
46766 /* XXX: use a NULL error handler for the finalizer call? */
#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)
DUK_EXTERNAL void duk_push_boolean(duk_context *ctx, duk_bool_t val)
#define DUK_HEAPHDR_SET_FINALIZED(h)
#define DUK_HEAPHDR_HAS_FINALIZED(h)
DUK_EXTERNAL void duk_call(duk_context *ctx, duk_idx_t nargs)
DUK_INTERNAL_DECL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj)

◆ duk_hobject_set_length()

DUK_INTERNAL_DECL void duk_hobject_set_length ( duk_hthread * thr,
duk_hobject * obj,
duk_uint32_t length )

Definition at line 51806 of file duktape-1.5.2/src-noline/duktape.c.

◆ duk_hobject_set_length_zero()

DUK_INTERNAL_DECL void duk_hobject_set_length_zero ( duk_hthread * thr,
duk_hobject * obj )

Definition at line 51819 of file duktape-1.5.2/src-noline/duktape.c.

◆ duk_hobject_set_prototype_updref()

DUK_INTERNAL_DECL void duk_hobject_set_prototype_updref ( duk_hthread * thr,
duk_hobject * h,
duk_hobject * p )

Definition at line 46804 of file duktape-1.5.2/src-noline/duktape.c.

46804 {
46805 return 1;
46806 }
46807
46808 if (sanity-- == 0) {
46809 if (ignore_loop) {
46810 break;
46811 } else {
46813 }
46814 }
46815 h = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);
46816 } while (h);
46817
46818 return 0;

◆ duk_hthread_alloc()

DUK_INTERNAL_DECL duk_hthread * duk_hthread_alloc ( duk_heap * heap,
duk_uint_t hobject_flags )

Definition at line 45977 of file duktape-1.5.2/src-noline/duktape.c.

45994 {
45995 duk_hthread *res;
45996
45997 res = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));
45998 if (!res) {
45999 return NULL;
46000 }
46001 DUK_MEMZERO(res, sizeof(duk_hthread));
46002
46003 duk__init_object_parts(heap, &res->obj, hobject_flags);
46004
46005#ifdef DUK_USE_EXPLICIT_NULL_INIT
46006 res->ptr_curr_pc = NULL;
46007 res->heap = NULL;
46008 res->valstack = NULL;
46009 res->valstack_end = NULL;
46010 res->valstack_bottom = NULL;
46011 res->valstack_top = NULL;
46012 res->callstack = NULL;
46013 res->catchstack = NULL;
46014 res->resumer = NULL;
46015 res->compile_ctx = NULL,
46016#ifdef DUK_USE_HEAPPTR16
46017 res->strs16 = NULL;
46018#else
46019 res->strs = NULL;
46020#endif

Variable Documentation

◆ duk_class_number_to_stridx

DUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32]

Definition at line 820 of file duktape-1.5.2/src-separate/duk_hobject.h.