summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c b/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c
new file mode 100644
index 000000000..7536689bf
--- /dev/null
+++ b/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c
@@ -0,0 +1,108 @@
+/*
+ * Thread support.
+ */
+
+#include "duk_internal.h"
+
+DUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {
+ DUK_ASSERT(thr != NULL);
+
+ /* Order of unwinding is important */
+
+ duk_hthread_catchstack_unwind(thr, 0);
+
+ duk_hthread_callstack_unwind(thr, 0); /* side effects, possibly errors */
+
+ thr->valstack_bottom = thr->valstack;
+ duk_set_top((duk_context *) 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. Also, doing DECREFs
+ * could trigger finalization, which would run on the current thread
+ * and have access to only some of the built-ins. Garbage collection
+ * deals with this correctly already.
+ */
+
+ /* XXX: Shrink the stacks to minimize memory usage? May not
+ * be worth the effort because terminated threads are usually
+ * garbage collected quite soon.
+ */
+}
+
+DUK_INTERNAL duk_activation *duk_hthread_get_current_activation(duk_hthread *thr) {
+ DUK_ASSERT(thr != NULL);
+
+ if (thr->callstack_top > 0) {
+ return thr->callstack + thr->callstack_top - 1;
+ } else {
+ return NULL;
+ }
+}
+
+#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_COMPILEDFUNCTION(act->func)) {
+ bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *) (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_COMPILEDFUNCTION(act->func)) {
+ bcode = DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, (duk_hcompiledfunction *) (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);
+ act = thr->callstack + thr->callstack_top - 1;
+ 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);
+ act = thr->callstack + thr->callstack_top - 1;
+ act->curr_pc = *thr->ptr_curr_pc;
+ thr->ptr_curr_pc = NULL;
+ }
+}