/* * duk_hobject and subclass assertion helpers */ #include "duk_internal.h" #if defined(DUK_USE_ASSERTIONS) DUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION); DUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) || (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY || DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY)); /* Object is an Array <=> object has exotic array behavior */ DUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) || (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h))); } DUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h)); DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h)); } DUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h)); DUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) || (DUK_TVAL_IS_OBJECT(&h->target) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target)))); DUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding)); DUK_ASSERT(h->nargs == 0 || h->args != NULL); } #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) DUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(h->shift <= 3); DUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX); DUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) || (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) || (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) || (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) || (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) || (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) || (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) || (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) || (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64)); DUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1); DUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h)); if (h->buf == NULL) { DUK_ASSERT(h->offset == 0); DUK_ASSERT(h->length == 0); } else { /* No assertions for offset or length; in particular, * it's OK for length to be longer than underlying * buffer. Just ensure they don't wrap when added. */ DUK_ASSERT(h->offset + h->length >= h->offset); } } #endif /* DUK_USE_BUFFEROBJECT_SUPPORT */ DUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) { DUK_ASSERT(h != NULL); } DUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) { DUK_ASSERT(h != NULL); } DUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h)); DUK_ASSERT(h->thread == NULL || h->varmap != NULL); } DUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h)); DUK_ASSERT(h->target != NULL); DUK_ASSERT(h->has_this == 0 || h->has_this == 1); } DUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) { DUK_ASSERT(h != NULL); DUK_ASSERT(h->target != NULL); DUK_ASSERT(h->handler != NULL); DUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h)); } DUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) { DUK_ASSERT(thr != NULL); DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT); DUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr)); DUK_ASSERT(thr->unused1 == 0); DUK_ASSERT(thr->unused2 == 0); } DUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) { DUK_ASSERT(thr != NULL); DUK_HTHREAD_ASSERT_VALID(thr); DUK_ASSERT(thr->valstack != NULL); DUK_ASSERT(thr->valstack_bottom != NULL); DUK_ASSERT(thr->valstack_top != NULL); DUK_ASSERT(thr->valstack_end != NULL); DUK_ASSERT(thr->valstack_alloc_end != NULL); DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack); DUK_ASSERT(thr->valstack_end >= thr->valstack); DUK_ASSERT(thr->valstack_top >= thr->valstack); DUK_ASSERT(thr->valstack_top >= thr->valstack_bottom); DUK_ASSERT(thr->valstack_end >= thr->valstack_top); DUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end); } #endif /* DUK_USE_ASSERTIONS */