/*
 *  Run an duk_hobject finalizer.  Used for both reference counting
 *  and mark-and-sweep algorithms.  Must never throw an error.
 *
 *  There is no return value.  Any return value or error thrown by
 *  the finalizer is ignored (although errors are debug logged).
 *
 *  Notes:
 *
 *    - The thread used for calling the finalizer is the same as the
 *      'thr' argument.  This may need to change later.
 *
 *    - The finalizer thread 'top' assertions are there because it is
 *      critical that strict stack policy is observed (i.e. no cruft
 *      left on the finalizer stack).
 */

#include "duk_internal.h"

DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx) {
	duk_hthread *thr;

	DUK_ASSERT(ctx != NULL);
	thr = (duk_hthread *) ctx;

	DUK_DDD(DUK_DDDPRINT("protected finalization helper running"));

	/* [... obj] */

	/* XXX: Finalizer lookup should traverse the prototype chain (to allow
	 * inherited finalizers) but should not invoke accessors or proxy object
	 * behavior.  At the moment this lookup will invoke proxy behavior, so
	 * caller must ensure that this function is not called if the target is
	 * a Proxy.
	 */

	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_FINALIZER);  /* -> [... obj finalizer] */
	if (!duk_is_callable(ctx, -1)) {
		DUK_DDD(DUK_DDDPRINT("-> no finalizer or finalizer not callable"));
		return 0;
	}
	duk_dup(ctx, -2);
	duk_push_boolean(ctx, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));
	DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling finalizer"));
	duk_call(ctx, 2);  /* [ ... obj finalizer obj heapDestruct ]  -> [ ... obj retval ] */
	DUK_DDD(DUK_DDDPRINT("finalizer finished successfully"));
	return 0;

	/* Note: we rely on duk_safe_call() to fix up the stack for the caller,
	 * so we don't need to pop stuff here.  There is no return value;
	 * caller determines rescued status based on object refcount.
	 */
}

DUK_INTERNAL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj) {
	duk_context *ctx = (duk_context *) thr;
	duk_ret_t rc;
#ifdef DUK_USE_ASSERTIONS
	duk_idx_t entry_top;
#endif

	DUK_DDD(DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj));

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(ctx != NULL);
	DUK_ASSERT(obj != NULL);
	DUK_ASSERT_VALSTACK_SPACE(thr, 1);

#ifdef DUK_USE_ASSERTIONS
	entry_top = duk_get_top(ctx);
#endif
	/*
	 *  Get and call the finalizer.  All of this must be wrapped
	 *  in a protected call, because even getting the finalizer
	 *  may trigger an error (getter may throw one, for instance).
	 */

	DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
	if (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {
		DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj));
		return;
	}
	DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj);  /* ensure never re-entered until rescue cycle complete */
	if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) {
		/* This shouldn't happen; call sites should avoid looking up
		 * _Finalizer "through" a Proxy, but ignore if we come here
		 * with a Proxy to avoid finalizer re-entry.
		 */
		DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call"));
		return;
	}

	/* XXX: use a NULL error handler for the finalizer call? */

	DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling wrapped finalize helper"));
	duk_push_hobject(ctx, obj);  /* this also increases refcount by one */
	rc = duk_safe_call(ctx, duk__finalize_helper, 0 /*nargs*/, 1 /*nrets*/);  /* -> [... obj retval/error] */
	DUK_ASSERT_TOP(ctx, entry_top + 2);  /* duk_safe_call discipline */

	if (rc != DUK_EXEC_SUCCESS) {
		/* Note: we ask for one return value from duk_safe_call to get this
		 * error debugging here.
		 */
		DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
		                 (void *) obj, (duk_tval *) duk_get_tval(ctx, -1)));
	}
	duk_pop_2(ctx);  /* -> [...] */

	DUK_ASSERT_TOP(ctx, entry_top);
}
