/* * Reference counting helper macros. The macros take a thread argument * and must thus always be executed in a specific thread context. The * thread argument is not really needed anymore: DECREF can operate with * a heap pointer only, and INCREF needs neither. */ #if !defined(DUK_REFCOUNT_H_INCLUDED) #define DUK_REFCOUNT_H_INCLUDED #if defined(DUK_USE_REFERENCE_COUNTING) #if defined(DUK_USE_ROM_OBJECTS) /* With ROM objects "needs refcount update" is true when the value is * heap allocated and is not a ROM object. */ /* XXX: double evaluation for 'tv' argument. */ #define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \ (DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv)))) #define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) (!DUK_HEAPHDR_HAS_READONLY((h))) #else /* DUK_USE_ROM_OBJECTS */ /* Without ROM objects "needs refcount update" == is heap allocated. */ #define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) DUK_TVAL_IS_HEAP_ALLOCATED((tv)) #define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) 1 #endif /* DUK_USE_ROM_OBJECTS */ /* Fast variants, inline refcount operations except for refzero handling. * Can be used explicitly when speed is always more important than size. * For a good compiler and a single file build, these are basically the * same as a forced inline. */ #define DUK_TVAL_INCREF_FAST(thr, tv) \ do { \ duk_tval *duk__tv = (tv); \ DUK_ASSERT(duk__tv != NULL); \ if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ DUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0); /* No wrapping. */ \ } \ } while (0) #define DUK_TVAL_DECREF_FAST(thr, tv) \ do { \ duk_tval *duk__tv = (tv); \ DUK_ASSERT(duk__tv != NULL); \ if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ duk_heaphdr_refzero((thr), duk__h); \ } \ } \ } while (0) #define DUK_TVAL_DECREF_NORZ_FAST(thr, tv) \ do { \ duk_tval *duk__tv = (tv); \ DUK_ASSERT(duk__tv != NULL); \ if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \ duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ duk_heaphdr_refzero_norz((thr), duk__h); \ } \ } \ } while (0) #define DUK_HEAPHDR_INCREF_FAST(thr, h) \ do { \ duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ if (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \ DUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0); /* No wrapping. */ \ } \ } while (0) #define DUK_HEAPHDR_DECREF_FAST_RAW(thr, h, rzcall, rzcast) \ do { \ duk_heaphdr *duk__h = (duk_heaphdr *) (h); \ DUK_ASSERT(duk__h != NULL); \ DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \ DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \ if (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \ if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \ (rzcall)((thr), (rzcast) duk__h); \ } \ } \ } while (0) #define DUK_HEAPHDR_DECREF_FAST(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero, duk_heaphdr *) #define DUK_HEAPHDR_DECREF_NORZ_FAST(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero_norz, duk_heaphdr *) /* Slow variants, call to a helper to reduce code size. * Can be used explicitly when size is always more important than speed. */ #define DUK_TVAL_INCREF_SLOW(thr, tv) \ do { \ duk_tval_incref((tv)); \ } while (0) #define DUK_TVAL_DECREF_SLOW(thr, tv) \ do { \ duk_tval_decref((thr), (tv)); \ } while (0) #define DUK_TVAL_DECREF_NORZ_SLOW(thr, tv) \ do { \ duk_tval_decref_norz((thr), (tv)); \ } while (0) #define DUK_HEAPHDR_INCREF_SLOW(thr, h) \ do { \ duk_heaphdr_incref((duk_heaphdr *) (h)); \ } while (0) #define DUK_HEAPHDR_DECREF_SLOW(thr, h) \ do { \ duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr, h) \ do { \ duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HSTRING_INCREF_SLOW(thr, h) \ do { \ duk_heaphdr_incref((duk_heaphdr *) (h)); \ } while (0) #define DUK_HSTRING_DECREF_SLOW(thr, h) \ do { \ duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HSTRING_DECREF_NORZ_SLOW(thr, h) \ do { \ duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HBUFFER_INCREF_SLOW(thr, h) \ do { \ duk_heaphdr_incref((duk_heaphdr *) (h)); \ } while (0) #define DUK_HBUFFER_DECREF_SLOW(thr, h) \ do { \ duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HBUFFER_DECREF_NORZ_SLOW(thr, h) \ do { \ duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HOBJECT_INCREF_SLOW(thr, h) \ do { \ duk_heaphdr_incref((duk_heaphdr *) (h)); \ } while (0) #define DUK_HOBJECT_DECREF_SLOW(thr, h) \ do { \ duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \ } while (0) #define DUK_HOBJECT_DECREF_NORZ_SLOW(thr, h) \ do { \ duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); \ } while (0) /* Default variants. Selection depends on speed/size preference. * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary * is about +1kB for _FAST variants. */ #if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) /* XXX: It would be nice to specialize for specific duk_hobject subtypes * but current refzero queue handling prevents that. */ #define DUK_TVAL_INCREF(thr, tv) DUK_TVAL_INCREF_FAST((thr), (tv)) #define DUK_TVAL_DECREF(thr, tv) DUK_TVAL_DECREF_FAST((thr), (tv)) #define DUK_TVAL_DECREF_NORZ(thr, tv) DUK_TVAL_DECREF_NORZ_FAST((thr), (tv)) #define DUK_HEAPHDR_INCREF(thr, h) DUK_HEAPHDR_INCREF_FAST((thr), (h)) #define DUK_HEAPHDR_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero, duk_heaphdr *) #define DUK_HEAPHDR_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_heaphdr_refzero_norz, duk_heaphdr *) #define DUK_HSTRING_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HSTRING_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hstring_refzero, duk_hstring *) #define DUK_HSTRING_DECREF_NORZ(thr, h) \ DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hstring_refzero, duk_hstring *) /* no 'norz' variant */ #define DUK_HOBJECT_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HOBJECT_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *) #define DUK_HOBJECT_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *) #define DUK_HBUFFER_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HBUFFER_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hbuffer_refzero, duk_hbuffer *) #define DUK_HBUFFER_DECREF_NORZ(thr, h) \ DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hbuffer_refzero, duk_hbuffer *) /* no 'norz' variant */ #define DUK_HCOMPFUNC_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HCOMPFUNC_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *) #define DUK_HCOMPFUNC_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *) #define DUK_HNATFUNC_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HNATFUNC_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *) #define DUK_HNATFUNC_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *) #define DUK_HBUFOBJ_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HBUFOBJ_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *) #define DUK_HBUFOBJ_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *) #define DUK_HTHREAD_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HTHREAD_DECREF(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero, duk_hobject *) #define DUK_HTHREAD_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_FAST_RAW((thr), (h), duk_hobject_refzero_norz, duk_hobject *) #else #define DUK_TVAL_INCREF(thr, tv) DUK_TVAL_INCREF_SLOW((thr), (tv)) #define DUK_TVAL_DECREF(thr, tv) DUK_TVAL_DECREF_SLOW((thr), (tv)) #define DUK_TVAL_DECREF_NORZ(thr, tv) DUK_TVAL_DECREF_NORZ_SLOW((thr), (tv)) #define DUK_HEAPHDR_INCREF(thr, h) DUK_HEAPHDR_INCREF_SLOW((thr), (h)) #define DUK_HEAPHDR_DECREF(thr, h) DUK_HEAPHDR_DECREF_SLOW((thr), (h)) #define DUK_HEAPHDR_DECREF_NORZ(thr, h) DUK_HEAPHDR_DECREF_NORZ_SLOW((thr), (h)) #define DUK_HSTRING_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HSTRING_DECREF(thr, h) DUK_HSTRING_DECREF_SLOW((thr), (h)) #define DUK_HSTRING_DECREF_NORZ(thr, h) DUK_HSTRING_DECREF_NORZ_SLOW((thr), (h)) #define DUK_HOBJECT_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HOBJECT_DECREF(thr, h) DUK_HOBJECT_DECREF_SLOW((thr), (h)) #define DUK_HOBJECT_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (h)) #define DUK_HBUFFER_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)) #define DUK_HBUFFER_DECREF(thr, h) DUK_HBUFFER_DECREF_SLOW((thr), (h)) #define DUK_HBUFFER_DECREF_NORZ(thr, h) DUK_HBUFFER_DECREF_NORZ_SLOW((thr), (h)) #define DUK_HCOMPFUNC_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HCOMPFUNC_DECREF(thr, h) DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HCOMPFUNC_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HNATFUNC_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HNATFUNC_DECREF(thr, h) DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HNATFUNC_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HBUFOBJ_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HBUFOBJ_DECREF(thr, h) DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HBUFOB_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HTHREAD_INCREF(thr, h) DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) &(h)->obj) #define DUK_HTHREAD_DECREF(thr, h) DUK_HOBJECT_DECREF_SLOW((thr), (duk_hobject *) &(h)->obj) #define DUK_HTHREAD_DECREF_NORZ(thr, h) DUK_HOBJECT_DECREF_NORZ_SLOW((thr), (duk_hobject *) &(h)->obj) #endif /* Convenience for some situations; the above macros don't allow NULLs * for performance reasons. Macros cover only actually needed cases. */ #define DUK_HEAPHDR_INCREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \ } \ } while (0) #define DUK_HEAPHDR_DECREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \ } \ } while (0) #define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \ } \ } while (0) #define DUK_HOBJECT_INCREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HOBJECT_INCREF((thr), (h)); \ } \ } while (0) #define DUK_HOBJECT_DECREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HOBJECT_DECREF((thr), (h)); \ } \ } while (0) #define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HOBJECT_DECREF_NORZ((thr), (h)); \ } \ } while (0) #define DUK_HBUFFER_INCREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HBUFFER_INCREF((thr), (h)); \ } \ } while (0) #define DUK_HBUFFER_DECREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HBUFFER_DECREF((thr), (h)); \ } \ } while (0) #define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HBUFFER_DECREF_NORZ((thr), (h)); \ } \ } while (0) #define DUK_HTHREAD_INCREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HTHREAD_INCREF((thr), (h)); \ } \ } while (0) #define DUK_HTHREAD_DECREF_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HTHREAD_DECREF((thr), (h)); \ } \ } while (0) #define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ if ((h) != NULL) { \ DUK_HTHREAD_DECREF_NORZ((thr), (h)); \ } \ } while (0) /* Called after one or more DECREF NORZ calls to handle pending side effects. * At present DECREF NORZ does freeing inline but doesn't execute finalizers, * so these macros check for pending finalizers and execute them. The FAST * variant is performance critical. */ #if defined(DUK_USE_FINALIZER_SUPPORT) #define DUK_REFZERO_CHECK_FAST(thr) \ do { \ duk_refzero_check_fast((thr)); \ } while (0) #define DUK_REFZERO_CHECK_SLOW(thr) \ do { \ duk_refzero_check_slow((thr)); \ } while (0) #else /* DUK_USE_FINALIZER_SUPPORT */ #define DUK_REFZERO_CHECK_FAST(thr) \ do { \ } while (0) #define DUK_REFZERO_CHECK_SLOW(thr) \ do { \ } while (0) #endif /* DUK_USE_FINALIZER_SUPPORT */ /* * Macros to set a duk_tval and update refcount of the target (decref the * old value and incref the new value if necessary). This is both performance * and footprint critical; any changes made should be measured for size/speed. */ #define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_UNDEFINED(tv__dst); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_UNDEFINED(tv__dst); \ DUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \ } while (0) #define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_UNUSED(tv__dst); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_NULL(tv__dst); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_NAN(tv__dst); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #if defined(DUK_USE_FASTINT) #define DUK_TVAL_SET_I48_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_I48(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_I32_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_I32(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_U32_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_U32(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #else #define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr, tvptr_dst, newval) \ DUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval)) #endif /* DUK_USE_FASTINT */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr, tvptr_dst, lf_v, lf_fp, lf_flags) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_STRING(tv__dst, (newval)); \ DUK_HSTRING_INCREF((thr), (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \ DUK_HOBJECT_INCREF((thr), (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \ DUK_HBUFFER_INCREF((thr), (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) #define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_POINTER(tv__dst, (newval)); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) /* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups, * etc, so it's very important for performance. Measure when changing. * * NOTE: the source and destination duk_tval pointers may be the same, and * the macros MUST deal with that correctly. */ /* Original idiom used, minimal code size. */ #define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr, tvptr_dst, tvptr_src) \ do { \ duk_tval *tv__dst, *tv__src; \ duk_tval tv__tmp; \ tv__dst = (tvptr_dst); \ tv__src = (tvptr_src); \ DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ DUK_TVAL_INCREF((thr), tv__src); \ DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \ } while (0) /* Faster alternative: avoid making a temporary copy of tvptr_dst and use * fast incref/decref macros. */ #define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr, tvptr_dst, tvptr_src) \ do { \ duk_tval *tv__dst, *tv__src; \ duk_heaphdr *h__obj; \ tv__dst = (tvptr_dst); \ tv__src = (tvptr_src); \ DUK_TVAL_INCREF_FAST((thr), tv__src); \ if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \ h__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \ DUK_ASSERT(h__obj != NULL); \ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ DUK_HEAPHDR_DECREF_FAST((thr), h__obj); /* side effects */ \ } else { \ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ } \ } while (0) /* XXX: no optimized variants yet */ #define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 #define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0 #define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 #define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 #define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 #define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0 #define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0 #define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 #define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 #if defined(DUK_USE_FASTINT) #define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 #define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 #define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 #else #define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast int-to-double */ #define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #endif /* DUK_USE_FASTINT */ #define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 #define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 #define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 #define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0 #define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0 #if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) /* Optimized for speed. */ #define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT1 #define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT1 #define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 #else /* Optimized for size. */ #define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0 #define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0 #define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 #endif #else /* DUK_USE_REFERENCE_COUNTING */ #define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) 0 #define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h) 0 #define DUK_TVAL_INCREF_FAST(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF_FAST(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF_NORZ_FAST(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_INCREF_SLOW(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF_SLOW(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF_NORZ_SLOW(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_INCREF(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF(thr, v) \ do { \ } while (0) /* nop */ #define DUK_TVAL_DECREF_NORZ(thr, v) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_INCREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF_NORZ_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_INCREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HEAPHDR_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_INCREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF_NORZ_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_INCREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF_NORZ_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HSTRING_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_INCREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_NORZ_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_INCREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_NORZ_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_INCREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_NORZ_FAST(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_INCREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_NORZ_SLOW(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HCOMPFUNC_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HCOMPFUNC_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HCOMPFUNC_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HNATFUNC_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HNATFUNC_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HNATFUNC_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFOBJ_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFOBJ_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFOBJ_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HTHREAD_INCREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HTHREAD_DECREF(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HTHREAD_DECREF_NORZ(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_INCREF_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_INCREF_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, h) \ do { \ } while (0) /* nop */ #define DUK_REFZERO_CHECK_FAST(thr) \ do { \ } while (0) /* nop */ #define DUK_REFZERO_CHECK_SLOW(thr) \ do { \ } while (0) /* nop */ #define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_UNDEFINED(tv__dst); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_UNUSED(tv__dst); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_NULL(tv__dst); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_NUMBER(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr, tvptr_dst) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_NAN(tv__dst); \ DUK_UNREF((thr)); \ } while (0) #if defined(DUK_USE_FASTINT) #define DUK_TVAL_SET_I48_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_I48(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_I32_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_I32(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_U32_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_U32(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #else #define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr, tvptr_dst, newval) \ DUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval)) #endif /* DUK_USE_FASTINT */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr, tvptr_dst, lf_v, lf_fp, lf_flags) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_STRING(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_OBJECT(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_BUFFER(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr, tvptr_dst, newval) \ do { \ duk_tval *tv__dst; \ tv__dst = (tvptr_dst); \ DUK_TVAL_SET_POINTER(tv__dst, (newval)); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr, tvptr_dst, tvptr_src) \ do { \ duk_tval *tv__dst, *tv__src; \ tv__dst = (tvptr_dst); \ tv__src = (tvptr_src); \ DUK_TVAL_SET_TVAL(tv__dst, tv__src); \ DUK_UNREF((thr)); \ } while (0) #define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 #define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0 #define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0 #define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0 #define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0 #define DUK_TVAL_SET_NUMBER_UPDREF DUK_TVAL_SET_NUMBER_UPDREF_ALT0 #define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0 #define DUK_TVAL_SET_DOUBLE_UPDREF DUK_TVAL_SET_DOUBLE_UPDREF_ALT0 #define DUK_TVAL_SET_NAN_UPDREF DUK_TVAL_SET_NAN_UPDREF_ALT0 #if defined(DUK_USE_FASTINT) #define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_I48_UPDREF_ALT0 #define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_I32_UPDREF_ALT0 #define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_U32_UPDREF_ALT0 #else #define DUK_TVAL_SET_I48_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF /* XXX: fast-int-to-double */ #define DUK_TVAL_SET_I32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #define DUK_TVAL_SET_U32_UPDREF DUK_TVAL_SET_DOUBLE_CAST_UPDREF #endif /* DUK_USE_FASTINT */ #define DUK_TVAL_SET_FASTINT_UPDREF DUK_TVAL_SET_I48_UPDREF /* convenience */ #define DUK_TVAL_SET_LIGHTFUNC_UPDREF DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0 #define DUK_TVAL_SET_STRING_UPDREF DUK_TVAL_SET_STRING_UPDREF_ALT0 #define DUK_TVAL_SET_OBJECT_UPDREF DUK_TVAL_SET_OBJECT_UPDREF_ALT0 #define DUK_TVAL_SET_BUFFER_UPDREF DUK_TVAL_SET_BUFFER_UPDREF_ALT0 #define DUK_TVAL_SET_POINTER_UPDREF DUK_TVAL_SET_POINTER_UPDREF_ALT0 #define DUK_TVAL_SET_TVAL_UPDREF DUK_TVAL_SET_TVAL_UPDREF_ALT0 #define DUK_TVAL_SET_TVAL_UPDREF_FAST DUK_TVAL_SET_TVAL_UPDREF_ALT0 #define DUK_TVAL_SET_TVAL_UPDREF_SLOW DUK_TVAL_SET_TVAL_UPDREF_ALT0 #endif /* DUK_USE_REFERENCE_COUNTING */ /* * Some convenience macros that don't have optimized implementations now. */ #define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv_dst, tv_src) \ do { \ duk_hthread *duk__thr = (thr); \ duk_tval *duk__dst = (tv_dst); \ duk_tval *duk__src = (tv_src); \ DUK_UNREF(duk__thr); \ DUK_TVAL_DECREF_NORZ(duk__thr, duk__dst); \ DUK_TVAL_SET_TVAL(duk__dst, duk__src); \ DUK_TVAL_INCREF(duk__thr, duk__src); \ } while (0) #define DUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv_dst, val) \ do { \ duk_hthread *duk__thr = (thr); \ duk_tval *duk__dst = (tv_dst); \ duk_uint32_t duk__val = (duk_uint32_t) (val); \ DUK_UNREF(duk__thr); \ DUK_TVAL_DECREF_NORZ(duk__thr, duk__dst); \ DUK_TVAL_SET_U32(duk__dst, duk__val); \ } while (0) #define DUK_TVAL_SET_TVAL_INCREF(thr, tv_dst, tv_src) \ do { \ duk_hthread *duk__thr = (thr); \ duk_tval *duk__dst = (tv_dst); \ duk_tval *duk__src = (tv_src); \ DUK_UNREF(duk__thr); \ DUK_TVAL_SET_TVAL(duk__dst, duk__src); \ DUK_TVAL_INCREF(duk__thr, duk__src); \ } while (0) #define DUK_TVAL_SET_OBJECT_INCREF(thr, tv_dst, obj) \ do { \ duk_hthread *duk__thr = (thr); \ duk_tval *duk__dst = (tv_dst); \ duk_hobject *duk__obj = (duk_hobject *) (obj); \ DUK_ASSERT(duk__obj != NULL); \ DUK_UNREF(duk__thr); \ DUK_TVAL_SET_OBJECT(duk__dst, duk__obj); \ DUK_HOBJECT_INCREF(duk__thr, duk__obj); \ } while (0) #define DUK_TVAL_SET_STRING_INCREF(thr, tv_dst, str) \ do { \ duk_hthread *duk__thr = (thr); \ duk_tval *duk__dst = (tv_dst); \ duk_hstring *duk__str = (duk_hstring *) (str); \ DUK_ASSERT(duk__str != NULL); \ DUK_UNREF(duk__thr); \ DUK_TVAL_SET_STRING(duk__dst, duk__str); \ DUK_HSTRING_INCREF(duk__thr, duk__str); \ } while (0) /* * Prototypes */ #if defined(DUK_USE_REFERENCE_COUNTING) #if defined(DUK_USE_FINALIZER_SUPPORT) DUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr); DUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr); #endif DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr); DUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h); #if 0 /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */ DUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h); DUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h); DUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h); DUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h); DUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h); DUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h); #endif DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h); DUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h); #if defined(DUK_USE_FAST_REFCOUNT_DEFAULT) DUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h); /* no 'norz' variant */ DUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h); /* no 'norz' variant */ DUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h); DUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h); #else DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv); DUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv); DUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv); DUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h); DUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h); DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h); #endif #else /* DUK_USE_REFERENCE_COUNTING */ /* no refcounting */ #endif /* DUK_USE_REFERENCE_COUNTING */ #endif /* DUK_REFCOUNT_H_INCLUDED */