Improve JS Exception handling.

- Check for pending exceptions after function calls and script
executions.
- Call LOGERROR instead of JS_ReportError when there is a conversion
error in FromJSVal, since that can only be called from C++ (where JS
errors don't really make sense). Instead, C++ callers of FromJSVal
should handle the failure and, themselves, either report an error or
simply do something else.
- Wrap JS_ReportError since that makes updating it later easier.

This isn't a systematical fix since ToJSVal also ought return a boolean
for failures, and we probably should trigger errors instead of warnings
on 'implicit' conversions, rather a preparation diff.

Part of the SM52 migration, stage: SM45 compatible (actually SM52
incompatible, too).

Based on a patch by: Itms
Comments by: Vladislavbelov, Stan`
Refs #742, #4893

Differential Revision: https://code.wildfiregames.com/D3093
This was SVN commit r24187.
This commit is contained in:
wraitii
2020-11-15 18:29:17 +00:00
parent 88bc973530
commit 25490bfec3
79 changed files with 810 additions and 667 deletions
@@ -40,7 +40,7 @@ public:
ScriptInterface script("Test", "Test", g_ScriptContext);
TestLogger logger;
TS_ASSERT(!script.LoadScript(L"test.js", "1+"));
TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "JavaScript error: test.js line 1\nSyntaxError: expected expression, got end of script");
TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "ERROR: JavaScript error: test.js line 1\nSyntaxError: expected expression, got end of script");
}
void test_loadscript_strict_warning()
@@ -57,7 +57,7 @@ public:
ScriptInterface script("Test", "Test", g_ScriptContext);
TestLogger logger;
TS_ASSERT(!script.LoadScript(L"test.js", "with(1){}"));
TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "JavaScript error: test.js line 1\nSyntaxError: strict mode code may not contain \'with\' statements");
TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "ERROR: JavaScript error: test.js line 1\nSyntaxError: strict mode code may not contain \'with\' statements");
}
void test_clone_basic()
@@ -65,12 +65,12 @@ public:
ScriptInterface script1("Test", "Test", g_ScriptContext);
ScriptInterface script2("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq1(script1);
ScriptRequest rq1(script1);
JS::RootedValue obj1(rq1.cx);
TS_ASSERT(script1.Eval("({'x': 123, 'y': [1, 1.5, '2', 'test', undefined, null, true, false]})", &obj1));
{
ScriptInterface::Request rq2(script2);
ScriptRequest rq2(script2);
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
@@ -86,13 +86,13 @@ public:
ScriptInterface script1("Test", "Test", g_ScriptContext);
ScriptInterface script2("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq1(script1);
ScriptRequest rq1(script1);
JS::RootedValue obj1(rq1.cx);
TS_ASSERT(script1.Eval("var s = '?'; var v = ({get x() { return 123 }, 'y': {'w':{get z() { delete v.y; delete v.n; v = null; s += s; return 4 }}}, 'n': 100}); v", &obj1));
{
ScriptInterface::Request rq2(script2);
ScriptRequest rq2(script2);
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
@@ -107,13 +107,13 @@ public:
ScriptInterface script1("Test", "Test", g_ScriptContext);
ScriptInterface script2("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq1(script1);
ScriptRequest rq1(script1);
JS::RootedValue obj1(rq1.cx);
TS_ASSERT(script1.Eval("var x = []; x[0] = x; ({'a': x, 'b': x})", &obj1));
{
ScriptInterface::Request rq2(script2);
ScriptRequest rq2(script2);
JS::RootedValue obj2(rq2.cx, script2.CloneValueFromOtherCompartment(script1, obj1));
// Use JSAPI function to check if the values of the properties "a", "b" are equals a.x[0]
@@ -138,7 +138,7 @@ public:
{
ScriptInterface script("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq(script);
ScriptRequest rq(script);
JS::RootedValue val(rq.cx);
JS::RootedValue out(rq.cx);
@@ -183,7 +183,7 @@ public:
void handle_templates_test(const ScriptInterface& script, JS::HandleValue val, JS::MutableHandleValue out, JS::HandleValue nbrVal)
{
ScriptInterface::Request rq(script);
ScriptRequest rq(script);
int nbr = 0;
@@ -236,7 +236,7 @@ public:
void test_json()
{
ScriptInterface script("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq(script);
ScriptRequest rq(script);
std::string input = "({'x':1,'z':[2,'3\\u263A\\ud800'],\"y\":true})";
JS::RootedValue val(rq.cx);
@@ -254,7 +254,7 @@ public:
void test_function_override()
{
ScriptInterface script("Test", "Test", g_ScriptContext);
ScriptInterface::Request rq(script);
ScriptRequest rq(script);
TS_ASSERT(script.Eval(
"function f() { return 1; }"