]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_error_misc.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / prometheus-cpp / 3rdparty / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_error_misc.c
diff --git a/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_error_misc.c b/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_error_misc.c
new file mode 100644 (file)
index 0000000..5b37855
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *  Error helpers
+ */
+
+#include "duk_internal.h"
+
+/*
+ *  Helper to walk the thread chain and see if there is an active error
+ *  catcher.  Protected calls or finally blocks aren't considered catching.
+ */
+
+#if defined(DUK_USE_DEBUGGER_SUPPORT) && \
+    (defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT))
+DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {
+       /*
+        * XXX: As noted above, a protected API call won't be counted as a
+        * catcher. This is usually convenient, e.g. in the case of a top-
+        * level duk_pcall(), but may not always be desirable. Perhaps add an
+        * argument to treat them as catchers?
+        */
+
+       duk_size_t i;
+
+       DUK_ASSERT(thr != NULL);
+
+       while (thr != NULL) {
+               for (i = 0; i < thr->catchstack_top; i++) {
+                       duk_catcher *cat = thr->catchstack + i;
+                       if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
+                               return 1;  /* all we need to know */
+                       }
+               }
+               thr = thr->resumer;
+       }
+       return 0;
+}
+#endif  /* DUK_USE_DEBUGGER_SUPPORT && (DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT) */
+
+/*
+ *  Get prototype object for an integer error code.
+ */
+
+DUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) {
+       switch (code) {
+       case DUK_ERR_EVAL_ERROR:
+               return thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE];
+       case DUK_ERR_RANGE_ERROR:
+               return thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE];
+       case DUK_ERR_REFERENCE_ERROR:
+               return thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE];
+       case DUK_ERR_SYNTAX_ERROR:
+               return thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE];
+       case DUK_ERR_TYPE_ERROR:
+               return thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE];
+       case DUK_ERR_URI_ERROR:
+               return thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE];
+
+       /* XXX: more specific error classes? */
+       case DUK_ERR_UNIMPLEMENTED_ERROR:
+       case DUK_ERR_INTERNAL_ERROR:
+       case DUK_ERR_ALLOC_ERROR:
+       case DUK_ERR_ASSERTION_ERROR:
+       case DUK_ERR_API_ERROR:
+       case DUK_ERR_ERROR:
+       default:
+               return thr->builtins[DUK_BIDX_ERROR_PROTOTYPE];
+       }
+}
+
+/*
+ *  Exposed helper for setting up heap longjmp state.
+ */
+
+DUK_INTERNAL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type) {
+#if defined(DUK_USE_DEBUGGER_SUPPORT)
+       /* If something is thrown with the debugger attached and nobody will
+        * catch it, execution is paused before the longjmp, turning over
+        * control to the debug client.  This allows local state to be examined
+        * before the stack is unwound.  Errors are not intercepted when debug
+        * message loop is active (e.g. for Eval).
+        */
+
+       /* XXX: Allow customizing the pause and notify behavior at runtime
+        * using debugger runtime flags.  For now the behavior is fixed using
+        * config options.
+        */
+#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY) || defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+       if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap) &&
+           !thr->heap->dbg_processing &&
+           lj_type == DUK_LJ_TYPE_THROW) {
+               duk_context *ctx = (duk_context *) thr;
+               duk_bool_t fatal;
+               duk_hobject *h_obj;
+
+               /* Don't intercept a DoubleError, we may have caused the initial double
+                * fault and attempting to intercept it will cause us to be called
+                * recursively and exhaust the C stack.
+                */
+               h_obj = duk_get_hobject(ctx, -1);
+               if (h_obj == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {
+                       DUK_D(DUK_DPRINT("built-in DoubleError instance thrown, not intercepting"));
+                       goto skip_throw_intercept;
+               }
+
+               DUK_D(DUK_DPRINT("throw with debugger attached, report to client"));
+
+               fatal = !duk__have_active_catcher(thr);
+
+#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)
+               /* Report it to the debug client */
+               duk_debug_send_throw(thr, fatal);
+#endif
+
+#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)
+               if (fatal) {
+                       DUK_D(DUK_DPRINT("throw will be fatal, halt before longjmp"));
+                       duk_debug_halt_execution(thr, 1 /*use_prev_pc*/);
+               }
+#endif
+       }
+
+ skip_throw_intercept:
+#endif  /* DUK_USE_DEBUGGER_THROW_NOTIFY || DUK_USE_DEBUGGER_PAUSE_UNCAUGHT */
+#endif  /* DUK_USE_DEBUGGER_SUPPORT */
+
+       thr->heap->lj.type = lj_type;
+
+       DUK_ASSERT(thr->valstack_top > thr->valstack);
+       DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, thr->valstack_top - 1);  /* side effects */
+
+       duk_pop((duk_context *) thr);
+}