summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp')
-rw-r--r--src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp b/src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp
new file mode 100644
index 000000000..6fb3194da
--- /dev/null
+++ b/src/civetweb/src/third_party/duktape-1.8.0/examples/cpp-exceptions/cpp_exceptions.cpp
@@ -0,0 +1,274 @@
+/*
+ * Example of how to use DUK_USE_CPP_EXCEPTIONS to support automatic
+ * variables (e.g. destructor calls) in Duktape/C functions.
+ *
+ * Compile with -DDUK_OPT_CPP_EXCEPTIONS:
+ *
+ * $ g++ -otest -DDUK_OPT_CPP_EXCEPTIONS -I<duktape_dist>/src/ \
+ * <duktape_dist>/src/duktape.c cpp_exceptions.cpp -lm
+ *
+ * or ensure duk_config.h has DUK_USE_CPP_EXCEPTIONS enabled using
+ * genconfig. When executed you should see something like:
+ *
+ * $ ./test
+ * my_class instance created
+ * my_class instance destroyed <== destructor gets called
+ * --> rc=1 (SyntaxError: parse error (line 1))
+ * [...]
+ *
+ * Duktape uses a custom exception class (duk_internal_exception) which
+ * doesn't inherit from any base class, so that catching any base classes
+ * in user code won't accidentally catch exceptions thrown by Duktape.
+ */
+
+#if !defined(__cplusplus)
+#error compile using a c++ compiler
+#endif
+
+#include <stdio.h>
+#include <exception>
+#include "duktape.h"
+
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define NOEXCEPT noexcept
+#else
+#define NOEXCEPT throw()
+#endif
+
+/*
+ * Example class with a destructor
+ */
+
+class my_class {
+ public:
+ my_class();
+ ~my_class();
+};
+
+my_class::my_class() {
+ printf("my_class instance created\n");
+}
+
+my_class::~my_class() {
+ printf("my_class instance destroyed\n");
+}
+
+/*
+ * SyntaxError caused by eval exits Duktape/C function but destructors
+ * are executed.
+ */
+
+duk_ret_t test1(duk_context *ctx) {
+ my_class myclass;
+
+ duk_eval_string(ctx, "aiee=");
+
+ return 0;
+}
+
+/*
+ * You can use C++ exceptions inside Duktape/C functions for your own
+ * purposes but you should catch them before they propagate to Duktape.
+ */
+
+duk_ret_t test2(duk_context *ctx) {
+ my_class myclass;
+
+ try {
+ throw 123;
+ } catch (int myvalue) {
+ printf("Caught: %d\n", myvalue);
+ }
+
+ return 0;
+}
+
+/*
+ * If you let your own C++ exceptions propagate out of a Duktape/C function
+ * it will be caught by Duktape and considered a programming error. Duktape
+ * will catch the exception and convert it to a Duktape error.
+ *
+ * This may be allowed in a later version once all the implications have been
+ * worked out.
+ */
+
+duk_ret_t test3(duk_context *ctx) {
+ my_class myclass;
+
+ throw 123; /* ERROR: exception propagated to Duktape */
+
+ return 0;
+}
+
+/*
+ * Same as above, but if the exception inherits from std::exception, it's
+ * "what()" will be included in the error message.
+ */
+
+class my_exception : public std::exception {
+ virtual const char *what() const NOEXCEPT {
+ return "my_exception";
+ }
+};
+
+duk_ret_t test4(duk_context *ctx) {
+ my_class myclass;
+ my_exception myexc;
+
+ throw myexc; /* ERROR: exception propagated to Duktape */
+
+ return 0;
+}
+
+/*
+ * Same as above, but if the exception inherits from std::exception with
+ * a NULL what(). Duktape will describe the error as 'unknown' if so.
+ */
+
+class my_exception2 : public std::exception {
+ virtual const char *what() const NOEXCEPT {
+ return NULL;
+ }
+};
+
+duk_ret_t test5(duk_context *ctx) {
+ my_class myclass;
+ my_exception2 myexc;
+
+ throw myexc; /* ERROR: exception propagated to Duktape */
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ duk_context *ctx = duk_create_heap_default();
+ duk_int_t rc;
+
+ (void) argc; (void) argv; /* suppress warning */
+
+ printf("*** test1 - duk_pcall()\n");
+ duk_push_c_function(ctx, test1, 0);
+ rc = duk_pcall(ctx, 0);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test1 - duk_safe_call()\n");
+ rc = duk_safe_call(ctx, test1, 0, 1);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test1 - ecmascript try-catch\n");
+ duk_push_c_function(ctx, test1, 0);
+ duk_put_global_string(ctx, "test1");
+ duk_eval_string_noresult(ctx,
+ "try {\n"
+ " test1();\n"
+ "} catch (e) {\n"
+ " print(e.stack || e);\n"
+ "}\n");
+ printf("\n");
+
+ printf("*** test2 - duk_pcall()\n");
+ duk_push_c_function(ctx, test2, 0);
+ rc = duk_pcall(ctx, 0);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test2 - duk_safe_call()\n");
+ rc = duk_safe_call(ctx, test2, 0, 1);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test2 - ecmascript try-catch\n");
+ duk_push_c_function(ctx, test2, 0);
+ duk_put_global_string(ctx, "test2");
+ duk_eval_string_noresult(ctx,
+ "try {\n"
+ " test2();\n"
+ "} catch (e) {\n"
+ " print(e.stack || e);\n"
+ "}\n");
+ printf("\n");
+
+ printf("*** test3 - duk_pcall()\n");
+ duk_push_c_function(ctx, test3, 0);
+ rc = duk_pcall(ctx, 0);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test3 - duk_safe_call()\n");
+ rc = duk_safe_call(ctx, test3, 0, 1);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test3 - ecmascript try-catch\n");
+ duk_push_c_function(ctx, test3, 0);
+ duk_put_global_string(ctx, "test3");
+ duk_eval_string_noresult(ctx,
+ "try {\n"
+ " test3();\n"
+ "} catch (e) {\n"
+ " print(e.stack || e);\n"
+ "}\n");
+ printf("\n");
+
+ printf("*** test4 - duk_pcall()\n");
+ duk_push_c_function(ctx, test4, 0);
+ rc = duk_pcall(ctx, 0);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test4 - duk_safe_call()\n");
+ rc = duk_safe_call(ctx, test4, 0, 1);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test4 - ecmascript try-catch\n");
+ duk_push_c_function(ctx, test4, 0);
+ duk_put_global_string(ctx, "test4");
+ duk_eval_string_noresult(ctx,
+ "try {\n"
+ " test4();\n"
+ "} catch (e) {\n"
+ " print(e.stack || e);\n"
+ "}\n");
+ printf("\n");
+
+ printf("*** test5 - duk_pcall()\n");
+ duk_push_c_function(ctx, test5, 0);
+ rc = duk_pcall(ctx, 0);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test5 - duk_safe_call()\n");
+ rc = duk_safe_call(ctx, test5, 0, 1);
+ printf("--> rc=%ld (%s)\n", (long) rc, duk_safe_to_string(ctx, -1));
+ duk_pop(ctx);
+ printf("\n");
+
+ printf("*** test5 - ecmascript try-catch\n");
+ duk_push_c_function(ctx, test5, 0);
+ duk_put_global_string(ctx, "test5");
+ duk_eval_string_noresult(ctx,
+ "try {\n"
+ " test5();\n"
+ "} catch (e) {\n"
+ " print(e.stack || e);\n"
+ "}\n");
+ printf("\n");
+
+ printf("*** done\n");
+
+ duk_destroy_heap(ctx);
+
+ return 0;
+}