diff options
Diffstat (limited to '')
-rw-r--r-- | src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hthread_misc.c | 108 |
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; + } +} |