Add protection against exception fall though one Java machine running another Java machine.

When one TeaVM program calls `eval` and code passed to eval is itself generated
with TeaVM, the inner code can throw uncaught Java exception. The outer code could
try to catch this exception as a native JavaScript exception, but this is not possible,
since the exception is marked as Java exception, and inner scripts's Java class
does not inherit java.lang.Throwable of outer script. The solution for each script
to generate own tag (Symbol) and only treat JS exception as Java exception when
this exception has this tag.
This commit is contained in:
Alexey Andreev 2020-04-30 16:05:24 +03:00
parent 9f823ee450
commit 1232f20ae4

View File

@ -255,6 +255,7 @@ function $rt_voidcls() {
function $rt_throw(ex) { function $rt_throw(ex) {
throw $rt_exception(ex); throw $rt_exception(ex);
} }
var $rt_exceptionTag = Symbol("teavmException")
function $rt_exception(ex) { function $rt_exception(ex) {
var err = ex.$jsException; var err = ex.$jsException;
if (!err) { if (!err) {
@ -263,6 +264,7 @@ function $rt_exception(ex) {
Error.captureStackTrace(err); Error.captureStackTrace(err);
} }
err.$javaException = ex; err.$javaException = ex;
err[$rt_exceptionTag] = true;
ex.$jsException = err; ex.$jsException = err;
$rt_fillStack(err, ex); $rt_fillStack(err, ex);
} }
@ -648,16 +650,18 @@ function $rt_intBitsToFloat(n) {
} }
function $rt_javaException(e) { function $rt_javaException(e) {
return e instanceof Error && typeof e.$javaException === 'object' ? e.$javaException : null; return e instanceof Error && $rt_exceptionTag in e
&& typeof e.$javaException === 'object' ? e.$javaException : null;
} }
function $rt_jsException(e) { function $rt_jsException(e) {
return typeof e.$jsException === 'object' ? e.$jsException : null; return typeof e.$jsException === 'object' ? e.$jsException : null;
} }
function $rt_wrapException(err) { function $rt_wrapException(err) {
var ex = err.$javaException; var ex = err.$javaException;
if (!ex) { if (!ex || !($rt_exceptionTag in err)) {
ex = $rt_createException($rt_str("(JavaScript) " + err.toString())); ex = $rt_createException($rt_str("(JavaScript) " + err.toString()));
err.$javaException = ex; err.$javaException = ex;
err[$rt_exceptionTag] = true;
ex.$jsException = err; ex.$jsException = err;
$rt_fillStack(err, ex); $rt_fillStack(err, ex);
} }