128 lines
5.2 KiB
C
128 lines
5.2 KiB
C
|
/*
|
||
|
* 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 */
|