]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_error_throw.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.5.2 / src-separate / duk_error_throw.c
diff --git a/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_error_throw.c b/ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_error_throw.c
new file mode 100644 (file)
index 0000000..69b75f0
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ *  Create and throw an Ecmascript error object based on a code and a message.
+ *
+ *  Used when we throw errors internally.  Ecmascript generated error objects
+ *  are created by Ecmascript code, and the throwing is handled by the bytecode
+ *  executor.
+ */
+
+#include "duk_internal.h"
+
+/*
+ *  Create and throw an error (originating from Duktape internally)
+ *
+ *  Push an error object on top of the stack, possibly throw augmenting
+ *  the error, and finally longjmp.
+ *
+ *  If an error occurs while we're dealing with the current error, we might
+ *  enter an infinite recursion loop.  This is prevented by detecting a
+ *  "double fault" through the heap->handling_error flag; the recursion
+ *  then stops at the second level.
+ */
+
+#ifdef DUK_USE_VERBOSE_ERRORS
+DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {
+#else
+DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {
+#endif
+       duk_context *ctx = (duk_context *) thr;
+       duk_bool_t double_error = thr->heap->handling_error;
+
+#ifdef DUK_USE_VERBOSE_ERRORS
+       DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld",
+                          (long) code, (const char *) msg,
+                          (const char *) filename, (long) line));
+#else
+       DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld", (long) code));
+#endif
+
+       DUK_ASSERT(thr != NULL);
+       DUK_ASSERT(ctx != NULL);
+
+       thr->heap->handling_error = 1;
+
+       if (!double_error) {
+               /* Allow headroom for calls during error handling (see GH-191).
+                * We allow space for 10 additional recursions, with one extra
+                * for, e.g. a print() call at the deepest level.
+                */
+               DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX);
+               thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP + 11;
+       }
+
+       DUK_ASSERT(thr->callstack_max == DUK_CALLSTACK_DEFAULT_MAX + DUK_CALLSTACK_GROW_STEP + 11);  /* just making sure */
+
+       /* Sync so that augmentation sees up-to-date activations, NULL
+        * thr->ptr_curr_pc so that it's not used if side effects occur
+        * in augmentation or longjmp handling.
+        */
+       duk_hthread_sync_and_null_currpc(thr);
+
+       /*
+        *  Create and push an error object onto the top of stack.
+        *  If a "double error" occurs, use a fixed error instance
+        *  to avoid further trouble.
+        */
+
+       /* XXX: if attempt to push beyond allocated valstack, this double fault
+        * handling fails miserably.  We should really write the double error
+        * directly to thr->heap->lj.value1 and avoid valstack use entirely.
+        */
+
+       if (double_error) {
+               if (thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {
+                       DUK_D(DUK_DPRINT("double fault detected -> push built-in fixed 'double error' instance"));
+                       duk_push_hobject_bidx(ctx, DUK_BIDX_DOUBLE_ERROR);
+               } else {
+                       DUK_D(DUK_DPRINT("double fault detected; there is no built-in fixed 'double error' instance "
+                                        "-> push the error code as a number"));
+                       duk_push_int(ctx, (duk_int_t) code);
+               }
+       } else {
+               /* Error object is augmented at its creation here. */
+               duk_require_stack(ctx, 1);
+               /* XXX: unnecessary '%s' formatting here, but cannot use
+                * 'msg' as a format string directly.
+                */
+#ifdef DUK_USE_VERBOSE_ERRORS
+               duk_push_error_object_raw(ctx,
+                                         code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
+                                         filename,
+                                         line,
+                                         "%s",
+                                         (const char *) msg);
+#else
+               duk_push_error_object_raw(ctx,
+                                         code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
+                                         NULL,
+                                         0,
+                                         NULL);
+#endif
+       }
+
+       /*
+        *  Augment error (throw time), unless alloc/double error
+        */
+
+       if (double_error || code == DUK_ERR_ALLOC_ERROR) {
+               DUK_D(DUK_DPRINT("alloc or double error: skip throw augmenting to avoid further trouble"));
+       } else {
+#if defined(DUK_USE_AUGMENT_ERROR_THROW)
+               DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)",
+                                    (duk_tval *) duk_get_tval(ctx, -1)));
+               duk_err_augment_error_throw(thr);
+#endif
+       }
+
+       /*
+        *  Finally, longjmp
+        */
+
+       duk_err_setup_heap_ljstate(thr, DUK_LJ_TYPE_THROW);
+
+       thr->callstack_max = DUK_CALLSTACK_DEFAULT_MAX;  /* reset callstack limit */
+       thr->heap->handling_error = 0;
+
+       DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)",
+                            (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));
+
+       duk_err_longjmp(thr);
+       DUK_UNREACHABLE();
+}
+
+/*
+ *  Helper for C function call negative return values.
+ */
+
+DUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {
+       duk_context *ctx = (duk_context *) thr;
+       const char *msg;
+       duk_errcode_t code;
+
+       DUK_ASSERT(thr != NULL);
+       DUK_ASSERT(rc < 0);
+
+       /* XXX: this generates quite large code - perhaps select the error
+        * class based on the code and then just use the error 'name'?
+        */
+       /* XXX: shared strings */
+
+       code = -rc;
+
+       switch (rc) {
+       case DUK_RET_UNIMPLEMENTED_ERROR:  msg = "unimplemented"; break;
+       case DUK_RET_UNSUPPORTED_ERROR:    msg = "unsupported"; break;
+       case DUK_RET_INTERNAL_ERROR:       msg = "internal"; break;
+       case DUK_RET_ALLOC_ERROR:          msg = "alloc"; break;
+       case DUK_RET_ASSERTION_ERROR:      msg = "assertion"; break;
+       case DUK_RET_API_ERROR:            msg = "api"; break;
+       case DUK_RET_UNCAUGHT_ERROR:       msg = "uncaught"; break;
+       case DUK_RET_ERROR:                msg = "error"; break;
+       case DUK_RET_EVAL_ERROR:           msg = "eval"; break;
+       case DUK_RET_RANGE_ERROR:          msg = "range"; break;
+       case DUK_RET_REFERENCE_ERROR:      msg = "reference"; break;
+       case DUK_RET_SYNTAX_ERROR:         msg = "syntax"; break;
+       case DUK_RET_TYPE_ERROR:           msg = "type"; break;
+       case DUK_RET_URI_ERROR:            msg = "uri"; break;
+       default:                           msg = "unknown"; break;
+       }
+
+       DUK_ASSERT(msg != NULL);
+
+       /*
+        *  The __FILE__ and __LINE__ information is intentionally not used in the
+        *  creation of the error object, as it isn't useful in the tracedata.  The
+        *  tracedata still contains the function which returned the negative return
+        *  code, and having the file/line of this function isn't very useful.
+        */
+
+       duk_error_raw(ctx, code, NULL, 0, "%s error (rc %ld)", (const char *) msg, (long) rc);
+       DUK_UNREACHABLE();
+}