From 57ecc28936163d3ab40d94dffc279ecf0495a239 Mon Sep 17 00:00:00 2001 From: Shachar Langbeheim Date: Sun, 3 May 2020 11:52:23 +0300 Subject: [PATCH 1/5] Debugging: Add a description of how to handle exceptions. --- site/source/docs/porting/Debugging.rst | 40 +++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/site/source/docs/porting/Debugging.rst b/site/source/docs/porting/Debugging.rst index c91f345f2603f..4e546db05ca32 100644 --- a/site/source/docs/porting/Debugging.rst +++ b/site/source/docs/porting/Debugging.rst @@ -137,6 +137,45 @@ Debug printouts can even execute arbitrary JavaScript. For example:: } +Printing exception messages +=========================== + +Exceptions are thrown from WebAssembly using exception pointers, which means that try/catch/finally blocks in JavaScript will only receive a number, which represents a pointer into linear memory. In order to get the exception message, the user will need to create some WASM code which will extract the meaning from the exception, for example: + +.. code-block:: cpp + + #include + + std::string getExceptionMessage(int exceptionPtr) { + return std::string(reinterpret_cast(exceptionPtr)->what()); + } + + EMSCRIPTEN_BINDINGS(Bindings) { + emscripten::function("getExceptionMessage", &getExceptionMessage); + }; + +And then handling the exceptions in Javascript will look like this: + +.. code-block:: javascript + + try { + ... // some code that calls WebAssembly + } catch (exception) { + console.error(Module.getExceptionMessage(exception)); + } finally { + ... + } + +It's important to notice that this code will work only for thrown statically allocated exceptions. If your code throws other objects, such as strings or dynamically allocated exceptions, the handling code will need to take that into account. For example, in order to handle thrown strings use: + +.. code-block:: javascript + + function getExceptionMessage(exception: any): any { + return typeof exception === 'number' + ? Module.getExceptionMessage(exception) + : exception; + } + Disabling optimizations ======================= @@ -285,4 +324,3 @@ Need help? The :ref:`Emscripten Test Suite ` contains good examples of almost all functionality offered by Emscripten. If you have a problem, it is a good idea to search the suite to determine whether test code with similar behavior is able to run. If you've tried the ideas here and you need more help, please :ref:`contact`. - From 6429a3ae4dfb088c1ce63111f554944199b61fc1 Mon Sep 17 00:00:00 2001 From: Shachar Langbeheim Date: Sun, 3 May 2020 20:04:57 +0300 Subject: [PATCH 2/5] round. --- site/source/docs/porting/Debugging.rst | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/site/source/docs/porting/Debugging.rst b/site/source/docs/porting/Debugging.rst index 4e546db05ca32..0b13f305bab3d 100644 --- a/site/source/docs/porting/Debugging.rst +++ b/site/source/docs/porting/Debugging.rst @@ -140,7 +140,13 @@ Debug printouts can even execute arbitrary JavaScript. For example:: Printing exception messages =========================== -Exceptions are thrown from WebAssembly using exception pointers, which means that try/catch/finally blocks in JavaScript will only receive a number, which represents a pointer into linear memory. In order to get the exception message, the user will need to create some WASM code which will extract the meaning from the exception, for example: +Exceptions are thrown from WebAssembly using exception pointers, which means +that try/catch/finally blocks in JavaScript will only receive a number, which +represents a pointer into linear memory. In order to get the exception message, +the user will need to create some WASM code which will extract the meaning from +the exception. In the example code below we created a function that receives an +``int`` which is pointer to an ``std::exception``, and by casting the pointer +returns the ``what`` function call result. .. code-block:: cpp @@ -154,7 +160,9 @@ Exceptions are thrown from WebAssembly using exception pointers, which means tha emscripten::function("getExceptionMessage", &getExceptionMessage); }; -And then handling the exceptions in Javascript will look like this: +Once such a function has been created, exception handling code in javascript +can call it when receiving an exception from WASM. Here the function is used +in order to log the thrown exception. .. code-block:: javascript @@ -166,7 +174,12 @@ And then handling the exceptions in Javascript will look like this: ... } -It's important to notice that this code will work only for thrown statically allocated exceptions. If your code throws other objects, such as strings or dynamically allocated exceptions, the handling code will need to take that into account. For example, in order to handle thrown strings use: +It's important to notice that this example code will work only for thrown +statically allocated exceptions. If your code throws other objects, such as +strings or dynamically allocated exceptions, the handling code will need to +take that into account. For example, if your code throws either exception +pointers or strings, the javascript code can handle these situations like +this: .. code-block:: javascript From b36fd8d76cd6caa8d99c1b0ec99a872fc93921e6 Mon Sep 17 00:00:00 2001 From: Shachar Langbeheim Date: Mon, 4 May 2020 11:21:43 +0300 Subject: [PATCH 3/5] remove typescript types. --- site/source/docs/porting/Debugging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/source/docs/porting/Debugging.rst b/site/source/docs/porting/Debugging.rst index 0b13f305bab3d..8994d17637cd4 100644 --- a/site/source/docs/porting/Debugging.rst +++ b/site/source/docs/porting/Debugging.rst @@ -183,7 +183,7 @@ this: .. code-block:: javascript - function getExceptionMessage(exception: any): any { + function getExceptionMessage(exception) { return typeof exception === 'number' ? Module.getExceptionMessage(exception) : exception; From 26715384e9ba26fc87ce9fb5891615cfd5945315 Mon Sep 17 00:00:00 2001 From: Shachar Langbeheim Date: Tue, 5 May 2020 11:03:39 +0300 Subject: [PATCH 4/5] c++ exceptions. --- site/source/docs/porting/Debugging.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/source/docs/porting/Debugging.rst b/site/source/docs/porting/Debugging.rst index 8994d17637cd4..02ba0a417f7fa 100644 --- a/site/source/docs/porting/Debugging.rst +++ b/site/source/docs/porting/Debugging.rst @@ -137,10 +137,10 @@ Debug printouts can even execute arbitrary JavaScript. For example:: } -Printing exception messages -=========================== +Printing C++ exception messages +=============================== -Exceptions are thrown from WebAssembly using exception pointers, which means +C++ exceptions are thrown from WebAssembly using exception pointers, which means that try/catch/finally blocks in JavaScript will only receive a number, which represents a pointer into linear memory. In order to get the exception message, the user will need to create some WASM code which will extract the meaning from From 94fe6b8841324f0b7e29996b0e596abf85b1576a Mon Sep 17 00:00:00 2001 From: Shachar Langbeheim Date: Mon, 1 Jun 2020 14:54:41 +0300 Subject: [PATCH 5/5] round --- site/source/docs/porting/Debugging.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/site/source/docs/porting/Debugging.rst b/site/source/docs/porting/Debugging.rst index 02ba0a417f7fa..397c748c13bb3 100644 --- a/site/source/docs/porting/Debugging.rst +++ b/site/source/docs/porting/Debugging.rst @@ -137,22 +137,22 @@ Debug printouts can even execute arbitrary JavaScript. For example:: } -Printing C++ exception messages -=============================== +Handling C++ exceptions from javascript +======================================= C++ exceptions are thrown from WebAssembly using exception pointers, which means that try/catch/finally blocks in JavaScript will only receive a number, which represents a pointer into linear memory. In order to get the exception message, the user will need to create some WASM code which will extract the meaning from -the exception. In the example code below we created a function that receives an -``int`` which is pointer to an ``std::exception``, and by casting the pointer +the exception. In the example code below we created a function that receives the +address of a ``std::exception``, and by casting the pointer returns the ``what`` function call result. .. code-block:: cpp #include - std::string getExceptionMessage(int exceptionPtr) { + std::string getExceptionMessage(intptr_t exceptionPtr) { return std::string(reinterpret_cast(exceptionPtr)->what()); } @@ -177,9 +177,9 @@ in order to log the thrown exception. It's important to notice that this example code will work only for thrown statically allocated exceptions. If your code throws other objects, such as strings or dynamically allocated exceptions, the handling code will need to -take that into account. For example, if your code throws either exception -pointers or strings, the javascript code can handle these situations like -this: +take that into account. For example, if your code needs to handle both native +C++ exceptions and JavaScript exceptions you could use the following code to +distinguish between them: .. code-block:: javascript @@ -189,6 +189,7 @@ this: : exception; } + Disabling optimizations =======================