mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Print JS stack trace when reporting exceptions.
Increase maximum logger message size. Fix GC bug. This was SVN commit r8063.
This commit is contained in:
parent
5cc04d44f8
commit
5e15a0279e
4 changed files with 39 additions and 7 deletions
|
|
@ -129,7 +129,10 @@ template<> jsval ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, SDL_Event_
|
|||
}
|
||||
}
|
||||
|
||||
return OBJECT_TO_JSVAL(obj);
|
||||
jsval rval = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
scope.LeaveWithResult(rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
template<> jsval ScriptInterface::ToJSVal<IGUIObject*>(JSContext* UNUSED(cx), IGUIObject* const& val)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ static const double RENDER_TIMEOUT = 10.0; // seconds before messages are delete
|
|||
static const double RENDER_TIMEOUT_RATE = 10.0; // number of timed-out messages deleted per second
|
||||
static const size_t RENDER_LIMIT = 20; // maximum messages on screen at once
|
||||
|
||||
static const size_t BUFFER_SIZE = 1024;
|
||||
|
||||
extern int g_xres, g_yres;
|
||||
|
||||
// Set up a default logger that throws everything away, because that's
|
||||
|
|
@ -215,7 +217,7 @@ void CLogger::LogUsingMethod(ELogMethod method, const wchar_t* message)
|
|||
void CLogger::Log(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512] = {0};
|
||||
wchar_t buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
va_start(argp, fmt);
|
||||
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
|
||||
|
|
@ -232,7 +234,7 @@ void CLogger::Log(ELogMethod method, const wchar_t* UNUSED(category), const wcha
|
|||
void CLogger::LogOnce(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512] = {0};
|
||||
wchar_t buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
va_start(argp, fmt);
|
||||
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
|
||||
|
|
@ -256,7 +258,7 @@ void CLogger::LogOnce(ELogMethod method, const wchar_t* UNUSED(category), const
|
|||
void CLogger::LogMessage(const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512] = {0};
|
||||
wchar_t buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
va_start(argp, fmt);
|
||||
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
|
||||
|
|
@ -272,7 +274,7 @@ void CLogger::LogMessage(const wchar_t* fmt, ...)
|
|||
void CLogger::LogWarning(const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512] = {0};
|
||||
wchar_t buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
va_start(argp, fmt);
|
||||
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
|
||||
|
|
@ -288,7 +290,7 @@ void CLogger::LogWarning(const wchar_t* fmt, ...)
|
|||
void CLogger::LogError(const wchar_t* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
wchar_t buffer[512] = {0};
|
||||
wchar_t buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
va_start(argp, fmt);
|
||||
if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ JSClass global_class = {
|
|||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
void ErrorReporter(JSContext* UNUSED(cx), const char* message, JSErrorReport* report)
|
||||
void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
|
||||
{
|
||||
// XXX Ugly hack: we want to compile code with 'use strict' and with JSOPTION_STRICT,
|
||||
// but the latter causes the former to be reported as a useless expression, so
|
||||
|
|
@ -92,11 +92,28 @@ void ErrorReporter(JSContext* UNUSED(cx), const char* message, JSErrorReport* re
|
|||
msg << report->filename;
|
||||
msg << " line " << report->lineno << "\n";
|
||||
}
|
||||
|
||||
msg << message;
|
||||
|
||||
// If there is an exception, then print its stack trace
|
||||
jsval excn;
|
||||
if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
|
||||
{
|
||||
jsval rval;
|
||||
const char dumpStack[] = "this.stack.trimRight().replace(/^/mg, ' ')"; // indent each line
|
||||
if (JS_EvaluateScript(cx, JSVAL_TO_OBJECT(excn), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, &rval))
|
||||
{
|
||||
std::string stackTrace;
|
||||
if (ScriptInterface::FromJSVal(cx, rval, stackTrace))
|
||||
msg << "\n" << stackTrace;
|
||||
}
|
||||
}
|
||||
|
||||
if (isWarning)
|
||||
LOGWARNING(L"%hs", msg.str().c_str());
|
||||
else
|
||||
LOGERROR(L"%hs", msg.str().c_str());
|
||||
|
||||
// When running under Valgrind, print more information in the error message
|
||||
VALGRIND_PRINTF_BACKTRACE("->");
|
||||
}
|
||||
|
|
@ -400,6 +417,14 @@ bool ScriptInterface::LocalRootScope::OK()
|
|||
return m_OK;
|
||||
}
|
||||
|
||||
void ScriptInterface::LocalRootScope::LeaveWithResult(jsval val)
|
||||
{
|
||||
if (m_OK)
|
||||
JS_LeaveLocalRootScopeWithResult(m_cx, val);
|
||||
m_OK = false;
|
||||
}
|
||||
|
||||
|
||||
jsval ScriptInterface::CallConstructor(jsval ctor)
|
||||
{
|
||||
// Constructing JS objects similarly to "new Foo" is non-trivial.
|
||||
|
|
|
|||
|
|
@ -221,6 +221,8 @@ public:
|
|||
LocalRootScope(JSContext* cx);
|
||||
// Returns true if the local root scope was successfully entered
|
||||
bool OK();
|
||||
// Leaves the local root scope, but keeps the given return value rooted
|
||||
void LeaveWithResult(jsval val);
|
||||
// Leaves the local root scope
|
||||
~LocalRootScope();
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in a new issue