File: duk_hthread_misc.c

package info (click to toggle)
duktape 2.7.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 21,160 kB
  • sloc: ansic: 215,359; python: 5,961; javascript: 4,555; makefile: 477; cpp: 205
file content (97 lines) | stat: -rw-r--r-- 2,692 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 *  Thread support.
 */

#include "duk_internal.h"

DUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {
	DUK_ASSERT(thr != NULL);

	while (thr->callstack_curr != NULL) {
		duk_hthread_activation_unwind_norz(thr);
	}

	thr->valstack_bottom = thr->valstack;
	duk_set_top(thr, 0); /* unwinds valstack, updating refcounts */

	thr->state = DUK_HTHREAD_STATE_TERMINATED;

	/* Here we could remove references to built-ins, but it may not be
	 * worth the effort because built-ins are quite likely to be shared
	 * with another (unterminated) thread, and terminated threads are also
	 * usually garbage collected quite quickly.
	 *
	 * We could also shrink the value stack here, but that also may not
	 * be worth the effort for the same reason.
	 */

	DUK_REFZERO_CHECK_SLOW(thr);
}

#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) {
	duk_instr_t *bcode;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(act != NULL);
	DUK_UNREF(thr);

	/* XXX: store 'bcode' pointer to activation for faster lookup? */
	if (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {
		bcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));
		return (duk_uint_fast32_t) (act->curr_pc - bcode);
	}
	return 0;
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */

DUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) {
	duk_instr_t *bcode;
	duk_uint_fast32_t ret;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(act != NULL);
	DUK_UNREF(thr);

	if (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {
		bcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));
		ret = (duk_uint_fast32_t) (act->curr_pc - bcode);
		if (ret > 0) {
			ret--;
		}
		return ret;
	}
	return 0;
}

/* Write bytecode executor's curr_pc back to topmost activation (if any). */
DUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {
	duk_activation *act;

	DUK_ASSERT(thr != NULL);

	if (thr->ptr_curr_pc != NULL) {
		/* ptr_curr_pc != NULL only when bytecode executor is active. */
		DUK_ASSERT(thr->callstack_top > 0);
		DUK_ASSERT(thr->callstack_curr != NULL);
		act = thr->callstack_curr;
		DUK_ASSERT(act != NULL);
		act->curr_pc = *thr->ptr_curr_pc;
	}
}

DUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {
	duk_activation *act;

	DUK_ASSERT(thr != NULL);

	if (thr->ptr_curr_pc != NULL) {
		/* ptr_curr_pc != NULL only when bytecode executor is active. */
		DUK_ASSERT(thr->callstack_top > 0);
		DUK_ASSERT(thr->callstack_curr != NULL);
		act = thr->callstack_curr;
		DUK_ASSERT(act != NULL);
		act->curr_pc = *thr->ptr_curr_pc;
		thr->ptr_curr_pc = NULL;
	}
}