コード例 #1
0
ファイル: duk_heap_refcount.c プロジェクト: cherry-wb/duktape
static void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h) {
	duk_uint_fast32_t i;

	DUK_ASSERT(h);
	DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);

	/* XXX: better to get base and walk forwards? */

	for (i = 0; i < (duk_uint_fast32_t) h->e_next; i++) {
		duk_hstring *key = DUK_HOBJECT_E_GET_KEY(h, i);
		if (!key) {
			continue;
		}
		duk_heap_heaphdr_decref(thr, (duk_heaphdr *) key);
		if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(h, i)) {
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_GETTER(h, i));
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_SETTER(h, i));
		} else {
			duk_heap_tval_decref(thr, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(h, i));
		}
	}

	for (i = 0; i < (duk_uint_fast32_t) h->a_size; i++) {
		duk_heap_tval_decref(thr, DUK_HOBJECT_A_GET_VALUE_PTR(h, i));
	}

	/* hash part is a 'weak reference' and does not contribute */

	duk_heap_heaphdr_decref(thr, (duk_heaphdr *) h->prototype);

	if (DUK_HOBJECT_IS_COMPILEDFUNCTION(h)) {
		duk_hcompiledfunction *f = (duk_hcompiledfunction *) h;
		duk_tval *tv, *tv_end;
		duk_hobject **funcs, **funcs_end;

		DUK_ASSERT(f->data != NULL);  /* compiled functions must be created 'atomically' */

		tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(f);
		tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(f);
		while (tv < tv_end) {
			duk_heap_tval_decref(thr, tv);
			tv++;
		}

		funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(f);
		funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(f);
		while (funcs < funcs_end) {
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) *funcs);
			funcs++;
		}

		duk_heap_heaphdr_decref(thr, (duk_heaphdr *) f->data);
	} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
		duk_hnativefunction *f = (duk_hnativefunction *) h;
		DUK_UNREF(f);
		/* nothing to finalize */
	} else if (DUK_HOBJECT_IS_THREAD(h)) {
		duk_hthread *t = (duk_hthread *) h;
		duk_tval *tv;

		tv = t->valstack;
		while (tv < t->valstack_end) {
			duk_heap_tval_decref(thr, tv);
			tv++;
		}

		for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
			duk_activation *act = t->callstack + i;
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) act->func);
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) act->var_env);
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) act->lex_env);
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) act->prev_caller);
#endif
		}

#if 0  /* nothing now */
		for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
			duk_catcher *cat = t->catchstack + i;
		}
#endif

		for (i = 0; i < DUK_NUM_BUILTINS; i++) {
			duk_heap_heaphdr_decref(thr, (duk_heaphdr *) t->builtins[i]);
		}

		duk_heap_heaphdr_decref(thr, (duk_heaphdr *) t->resumer);
	}
}
コード例 #2
0
DUK_LOCAL void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h) {
	duk_uint_fast32_t i;

	DUK_ASSERT(h);
	DUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);

	/* XXX: better to get base and walk forwards? */

	for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {
		duk_hstring *key = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);
		if (!key) {
			continue;
		}
		duk_heaphdr_decref(thr, (duk_heaphdr *) key);
		if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i)) {
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, h, i));
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, h, i));
		} else {
			duk_tval_decref(thr, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i));
		}
	}

	for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {
		duk_tval_decref(thr, DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, h, i));
	}

	/* hash part is a 'weak reference' and does not contribute */

	duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h));

	/* XXX: rearrange bits to allow a switch case to be used here? */
	/* XXX: add a fast path for objects (and arrays)? */

	/* DUK_HOBJECT_IS_ARRAY(h): needs no special handling now as there are
	 * no extra fields in need of decref.
	 */
	if (DUK_HOBJECT_IS_COMPFUNC(h)) {
		duk_hcompfunc *f = (duk_hcompfunc *) h;
		duk_tval *tv, *tv_end;
		duk_hobject **funcs, **funcs_end;

		DUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL);  /* compiled functions must be created 'atomically' */

		tv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f);
		tv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f);
		while (tv < tv_end) {
			duk_tval_decref(thr, tv);
			tv++;
		}

		funcs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f);
		funcs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f);
		while (funcs < funcs_end) {
			duk_heaphdr_decref(thr, (duk_heaphdr *) *funcs);
			funcs++;
		}

		duk_heaphdr_decref(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(thr->heap, f));
	} else if (DUK_HOBJECT_IS_NATFUNC(h)) {
		duk_hnatfunc *f = (duk_hnatfunc *) h;
		DUK_UNREF(f);
		/* nothing to finalize */
	} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {
		duk_hbufobj *b = (duk_hbufobj *) h;
		if (b->buf) {
			duk_heaphdr_decref(thr, (duk_heaphdr *) b->buf);
		}
	} else if (DUK_HOBJECT_IS_THREAD(h)) {
		duk_hthread *t = (duk_hthread *) h;
		duk_tval *tv;

		tv = t->valstack;
		while (tv < t->valstack_top) {
			duk_tval_decref(thr, tv);
			tv++;
		}

		for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
			duk_activation *act = t->callstack + i;
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) act->var_env);
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) act->lex_env);
#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) act->prev_caller);
#endif
		}

#if 0  /* nothing now */
		for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
			duk_catcher *cat = t->catchstack + i;
		}
#endif

		for (i = 0; i < DUK_NUM_BUILTINS; i++) {
			duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) t->builtins[i]);
		}

		duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) t->resumer);
	}
}