From 0ec9e41aa6888162154fd07adb52e60d42f0abe7 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Wed, 9 Mar 2016 01:32:06 +0900 Subject: [PATCH] Bug 1254174 - Convert uncaught symbol to a descriptive string. r=jorendorff --- js/src/jsapi-tests/moz.build | 1 + js/src/jsapi-tests/testUncaughtSymbol.cpp | 51 +++++++++++++++++++++++ js/src/jsexn.cpp | 11 ++++- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 js/src/jsapi-tests/testUncaughtSymbol.cpp diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build index 405701c05ff8..e10717c52945 100644 --- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -87,6 +87,7 @@ UNIFIED_SOURCES += [ 'testTypedArrays.cpp', 'testUbiNode.cpp', 'testUncaughtError.cpp', + 'testUncaughtSymbol.cpp', 'testUTF8.cpp', 'testWasmLEB128.cpp', 'testWeakMap.cpp', diff --git a/js/src/jsapi-tests/testUncaughtSymbol.cpp b/js/src/jsapi-tests/testUncaughtSymbol.cpp new file mode 100644 index 000000000000..7088b1b53cca --- /dev/null +++ b/js/src/jsapi-tests/testUncaughtSymbol.cpp @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jsapi-tests/tests.h" + +using JS::CreateError; +using JS::Rooted; +using JS::ObjectValue; +using JS::Value; + +static enum { + NONE, + SYMBOL_ITERATOR, + SYMBOL_FOO, + SYMBOL_EMPTY, +} uncaughtType = NONE; + +BEGIN_TEST(testUncaughtSymbol) +{ + JSErrorReporter old = JS_SetErrorReporter(rt, UncaughtSymbolReporter); + + CHECK(uncaughtType == NONE); + exec("throw Symbol.iterator;", __FILE__, __LINE__); + CHECK(uncaughtType == SYMBOL_ITERATOR); + + uncaughtType = NONE; + exec("throw Symbol('foo');", __FILE__, __LINE__); + CHECK(uncaughtType == SYMBOL_FOO); + + uncaughtType = NONE; + exec("throw Symbol();", __FILE__, __LINE__); + CHECK(uncaughtType == SYMBOL_EMPTY); + + JS_SetErrorReporter(rt, old); + + return true; +} + +static void +UncaughtSymbolReporter(JSContext* cx, const char* message, JSErrorReport* report) +{ + if (strcmp(message, "uncaught exception: Symbol(Symbol.iterator)") == 0) + uncaughtType = SYMBOL_ITERATOR; + else if (strcmp(message, "uncaught exception: Symbol(foo)") == 0) + uncaughtType = SYMBOL_FOO; + else if (strcmp(message, "uncaught exception: Symbol()") == 0) + uncaughtType = SYMBOL_EMPTY; +} + +END_TEST(testUncaughtSymbol) diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 0b285b49a73e..664ba7525631 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -811,10 +811,17 @@ ErrorReport::init(JSContext* cx, HandleValue exn) // Be careful not to invoke ToString if we've already successfully extracted // an error report, since the exception might be wrapped in a security // wrapper, and ToString-ing it might throw. - if (reportp) + if (reportp) { str = ErrorReportToString(cx, reportp); - else + } else if (exn.isSymbol()) { + RootedValue strVal(cx); + if (js::SymbolDescriptiveString(cx, exn.toSymbol(), &strVal)) + str = strVal.toString(); + else + str = nullptr; + } else { str = ToString(cx, exn); + } if (!str) cx->clearPendingException();