Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_hobject_finalizer.c File Reference
#include "duk_internal.h"

Go to the source code of this file.

Functions

DUK_LOCAL duk_ret_t duk__finalize_helper (duk_context *ctx)
 
DUK_INTERNAL void duk_hobject_run_finalizer (duk_hthread *thr, duk_hobject *obj)
 

Function Documentation

◆ duk__finalize_helper()

DUK_LOCAL duk_ret_t duk__finalize_helper ( duk_context * ctx)

Definition at line 20 of file duktape-1.5.2/src-separate/duk_hobject_finalizer.c.

20 {
21 duk_hthread *thr;
22
23 DUK_ASSERT(ctx != NULL);
24 thr = (duk_hthread *) ctx;
25
26 DUK_DDD(DUK_DDDPRINT("protected finalization helper running"));
27
28 /* [... obj] */
29
30 /* XXX: Finalizer lookup should traverse the prototype chain (to allow
31 * inherited finalizers) but should not invoke accessors or proxy object
32 * behavior. At the moment this lookup will invoke proxy behavior, so
33 * caller must ensure that this function is not called if the target is
34 * a Proxy.
35 */
36
37 duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_FINALIZER); /* -> [... obj finalizer] */
38 if (!duk_is_callable(ctx, -1)) {
39 DUK_DDD(DUK_DDDPRINT("-> no finalizer or finalizer not callable"));
40 return 0;
41 }
42 duk_dup(ctx, -2);
44 DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling finalizer"));
45 duk_call(ctx, 2); /* [ ... obj finalizer obj heapDestruct ] -> [ ... obj retval ] */
46 DUK_DDD(DUK_DDDPRINT("finalizer finished successfully"));
47 return 0;
48
49 /* Note: we rely on duk_safe_call() to fix up the stack for the caller,
50 * so we don't need to pop stuff here. There is no return value;
51 * caller determines rescued status based on object refcount.
52 */
53}
#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
DUK_EXTERNAL void duk_push_boolean(duk_context *ctx, duk_bool_t val)
#define DUK_STRIDX_INT_FINALIZER
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
DUK_EXTERNAL void duk_call(duk_context *ctx, duk_idx_t nargs)
#define duk_is_callable(ctx, index)
#define NULL
Definition gmacros.h:924

References DUK_ASSERT, duk_call(), DUK_DDD, DUK_DDDPRINT, duk_dup(), duk_get_prop_stridx(), DUK_HEAP_HAS_FINALIZER_NORESCUE, duk_is_callable, duk_push_boolean(), DUK_STRIDX_INT_FINALIZER, duk_hthread::heap, and NULL.

Referenced by duk_hobject_run_finalizer().

◆ duk_hobject_run_finalizer()

DUK_INTERNAL void duk_hobject_run_finalizer ( duk_hthread * thr,
duk_hobject * obj )

Definition at line 55 of file duktape-1.5.2/src-separate/duk_hobject_finalizer.c.

55 {
56 duk_context *ctx = (duk_context *) thr;
57 duk_ret_t rc;
58#ifdef DUK_USE_ASSERTIONS
59 duk_idx_t entry_top;
60#endif
61
62 DUK_DDD(DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj));
63
64 DUK_ASSERT(thr != NULL);
65 DUK_ASSERT(ctx != NULL);
66 DUK_ASSERT(obj != NULL);
68
69#ifdef DUK_USE_ASSERTIONS
70 entry_top = duk_get_top(ctx);
71#endif
72 /*
73 * Get and call the finalizer. All of this must be wrapped
74 * in a protected call, because even getting the finalizer
75 * may trigger an error (getter may throw one, for instance).
76 */
77
80 DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj));
81 return;
82 }
83 DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */
85 /* This shouldn't happen; call sites should avoid looking up
86 * _Finalizer "through" a Proxy, but ignore if we come here
87 * with a Proxy to avoid finalizer re-entry.
88 */
89 DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call"));
90 return;
91 }
92
93 /* XXX: use a NULL error handler for the finalizer call? */
94
95 DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling wrapped finalize helper"));
96 duk_push_hobject(ctx, obj); /* this also increases refcount by one */
97 rc = duk_safe_call(ctx, duk__finalize_helper, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */
98 DUK_ASSERT_TOP(ctx, entry_top + 2); /* duk_safe_call discipline */
99
100 if (rc != DUK_EXEC_SUCCESS) {
101 /* Note: we ask for one return value from duk_safe_call to get this
102 * error debugging here.
103 */
104 DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
105 (void *) obj, (duk_tval *) duk_get_tval(ctx, -1)));
106 }
107 duk_pop_2(ctx); /* -> [...] */
108
109 DUK_ASSERT_TOP(ctx, entry_top);
110}
duk_small_int_t duk_ret_t
DUK_EXTERNAL void duk_pop_2(duk_context *ctx)
#define DUK_HEAPHDR_SET_FINALIZED(h)
#define DUK_HEAPHDR_HAS_READONLY(h)
#define DUK_ASSERT_VALSTACK_SPACE(thr, n)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)
DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets)
#define DUK_HEAPHDR_HAS_FINALIZED(h)
#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)
#define DUK_ASSERT_TOP(ctx, n)
DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h)
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
DUK_LOCAL duk_ret_t duk__finalize_helper(duk_context *ctx)

References duk__finalize_helper(), DUK_ASSERT, DUK_ASSERT_TOP, DUK_ASSERT_VALSTACK_SPACE, DUK_D, DUK_DDD, DUK_DDDPRINT, DUK_DPRINT, DUK_EXEC_SUCCESS, duk_get_top(), duk_get_tval(), DUK_HEAPHDR_HAS_FINALIZED, DUK_HEAPHDR_HAS_READONLY, DUK_HEAPHDR_SET_FINALIZED, DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ, duk_pop_2(), duk_push_hobject(), duk_safe_call(), and NULL.