Bug 1053944 - Change RegExp.$N getters to return '' instead of `undefined` for non-matched groups. r=waldo
authorTill Schneidereit <till@tillschneidereit.net>
Wed, 27 Aug 2014 15:19:30 +0200
changeset 223605 df3b50b23153732e91dbf24bf85f152937106ea4
parent 223604 1c5714615dd7f1b301d0b37db5e53be6f50afef9
child 223606 6ab766a8e39cc897252742d7e63eae5b430ad8a9
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1053944
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1053944 - Change RegExp.$N getters to return '' instead of `undefined` for non-matched groups. r=waldo
js/src/builtin/RegExp.cpp
js/src/tests/ecma_3/extensions/regress-220367-002.js
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -366,16 +366,23 @@ static const JSFunctionSpec regexp_metho
 #endif
     JS_FN(js_toString_str,  regexp_toString,    0,0),
     JS_FN("compile",        regexp_compile,     2,0),
     JS_FN("exec",           regexp_exec,        1,0),
     JS_FN("test",           regexp_test,        1,0),
     JS_FS_END
 };
 
+#define STATIC_PAREN_GETTER_CODE(parenNum)                                      \
+    if (!res->createParen(cx, parenNum, args.rval()))                           \
+        return false;                                                           \
+    if (args.rval().isUndefined())                                              \
+        args.rval().setString(cx->runtime()->emptyString);                      \
+    return true
+
 /*
  * RegExp static properties.
  *
  * RegExp class static properties and their Perl counterparts:
  *
  *  RegExp.input                $_
  *  RegExp.multiline            $*
  *  RegExp.lastMatch            $&
@@ -398,25 +405,25 @@ static const JSFunctionSpec regexp_metho
 DEFINE_STATIC_GETTER(static_input_getter,        return res->createPendingInput(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_multiline_getter,    args.rval().setBoolean(res->multiline());
                                                  return true)
 DEFINE_STATIC_GETTER(static_lastMatch_getter,    return res->createLastMatch(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_lastParen_getter,    return res->createLastParen(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_leftContext_getter,  return res->createLeftContext(cx, args.rval()))
 DEFINE_STATIC_GETTER(static_rightContext_getter, return res->createRightContext(cx, args.rval()))
 
-DEFINE_STATIC_GETTER(static_paren1_getter,       return res->createParen(cx, 1, args.rval()))
-DEFINE_STATIC_GETTER(static_paren2_getter,       return res->createParen(cx, 2, args.rval()))
-DEFINE_STATIC_GETTER(static_paren3_getter,       return res->createParen(cx, 3, args.rval()))
-DEFINE_STATIC_GETTER(static_paren4_getter,       return res->createParen(cx, 4, args.rval()))
-DEFINE_STATIC_GETTER(static_paren5_getter,       return res->createParen(cx, 5, args.rval()))
-DEFINE_STATIC_GETTER(static_paren6_getter,       return res->createParen(cx, 6, args.rval()))
-DEFINE_STATIC_GETTER(static_paren7_getter,       return res->createParen(cx, 7, args.rval()))
-DEFINE_STATIC_GETTER(static_paren8_getter,       return res->createParen(cx, 8, args.rval()))
-DEFINE_STATIC_GETTER(static_paren9_getter,       return res->createParen(cx, 9, args.rval()))
+DEFINE_STATIC_GETTER(static_paren1_getter,       STATIC_PAREN_GETTER_CODE(1))
+DEFINE_STATIC_GETTER(static_paren2_getter,       STATIC_PAREN_GETTER_CODE(2))
+DEFINE_STATIC_GETTER(static_paren3_getter,       STATIC_PAREN_GETTER_CODE(3))
+DEFINE_STATIC_GETTER(static_paren4_getter,       STATIC_PAREN_GETTER_CODE(4))
+DEFINE_STATIC_GETTER(static_paren5_getter,       STATIC_PAREN_GETTER_CODE(5))
+DEFINE_STATIC_GETTER(static_paren6_getter,       STATIC_PAREN_GETTER_CODE(6))
+DEFINE_STATIC_GETTER(static_paren7_getter,       STATIC_PAREN_GETTER_CODE(7))
+DEFINE_STATIC_GETTER(static_paren8_getter,       STATIC_PAREN_GETTER_CODE(8))
+DEFINE_STATIC_GETTER(static_paren9_getter,       STATIC_PAREN_GETTER_CODE(9))
 
 #define DEFINE_STATIC_SETTER(name, code)                                        \
     static bool                                                                 \
     name(JSContext *cx, unsigned argc, Value *vp)                               \
     {                                                                           \
         RegExpStatics *res = cx->global()->getRegExpStatics(cx);                \
         if (!res)                                                               \
             return false;                                                       \
--- a/js/src/tests/ecma_3/extensions/regress-220367-002.js
+++ b/js/src/tests/ecma_3/extensions/regress-220367-002.js
@@ -27,23 +27,23 @@ var re = /(a)|(b)/;
 re.test('a');
 status = inSection(1);
 actual = RegExp.$1;
 expect = 'a';
 addThis();
 
 status = inSection(2);
 actual = RegExp.$2;
-expect = undefined;
+expect = '';
 addThis();
 
 re.test('b');
 status = inSection(3);
 actual = RegExp.$1;
-expect = undefined;
+expect = '';
 addThis();
 
 status = inSection(4);
 actual = RegExp.$2;
 expect = 'b';
 addThis();