Bug 1147817 - Part 1: Add RegExpInitialize. r=till
authorTooru Fujisawa <arai_a@mac.com>
Fri, 10 Apr 2015 23:49:16 +0900
changeset 238531 224db47e1e20984aae2a30227d78feddb9bbf40f
parent 238530 94a0aa18d1b0e935d4644e3ba63e9e64c5445c47
child 238532 ad1cd598bb350306283e0ae63e4da6a7770b69a8
push id58254
push userarai_a@mac.com
push dateFri, 10 Apr 2015 14:51:46 +0000
treeherdermozilla-inbound@ad1cd598bb35 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1147817
milestone40.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 1147817 - Part 1: Add RegExpInitialize. r=till
js/src/builtin/RegExp.cpp
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -134,25 +134,76 @@ js::ExecuteRegExpLegacy(JSContext* cx, R
         /* Forbid an array, as an optimization. */
         rval.setBoolean(true);
         return true;
     }
 
     return CreateRegExpMatchResult(cx, input, matches, rval);
 }
 
+/* ES6 draft rc4 21.2.3.2.2. */
+bool
+RegExpInitialize(JSContext* cx, RegExpObjectBuilder& builder,
+                 HandleValue patternValue, HandleValue flagsValue,
+                 RegExpStaticsUse staticsUse, MutableHandleObject result)
+{
+    RootedAtom pattern(cx);
+    if (patternValue.isUndefined()) {
+        /* Step 1. */
+        pattern = cx->runtime()->emptyString;
+    } else {
+        /* Steps 2-3. */
+        pattern = ToAtom<CanGC>(cx, patternValue);
+        if (!pattern)
+            return false;
+    }
+
+    /* Step 4. */
+    RegExpFlag flags = RegExpFlag(0);
+    if (!flagsValue.isUndefined()) {
+        /* Steps 5-6. */
+        RootedString flagStr(cx, ToString<CanGC>(cx, flagsValue));
+        if (!flagStr)
+            return false;
+        /* Step 7. */
+        if (!ParseRegExpFlags(cx, flagStr, &flags))
+            return false;
+    }
+
+    /* Steps 9-10. */
+    CompileOptions options(cx);
+    frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr);
+    if (!irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), pattern))
+        return false;
+
+    if (staticsUse == UseRegExpStatics) {
+        RegExpStatics* res = cx->global()->getRegExpStatics(cx);
+        if (!res)
+            return false;
+        flags = RegExpFlag(flags | res->getFlags());
+    }
+
+    /* Steps 11-15. */
+    RootedObject reobj(cx, builder.build(pattern, flags));
+    if (!reobj)
+        return false;
+
+    /* Step 16. */
+    result.set(reobj);
+    return true;
+}
+
 /*
  * Compile a new |RegExpShared| for the |RegExpObject|.
  */
 static bool
 CompileRegExpObject(JSContext* cx, RegExpObjectBuilder& builder, CallArgs args,
-                    RegExpStaticsUse staticsUse, RegExpCreationMode creationMode)
+                    RegExpCreationMode creationMode)
 {
     if (args.length() == 0) {
-        MOZ_ASSERT(staticsUse == UseRegExpStatics);
         RegExpStatics* res = cx->global()->getRegExpStatics(cx);
         if (!res)
             return false;
         Rooted<JSAtom*> empty(cx, cx->runtime()->emptyString);
         RegExpObject* reobj = builder.build(empty, res->getFlags());
         if (!reobj)
             return false;
         args.rval().setObject(*reobj);
@@ -209,49 +260,18 @@ CompileRegExpObject(JSContext* cx, RegEx
         RegExpObject* reobj = builder.build(sourceAtom, flags);
         if (!reobj)
             return false;
 
         args.rval().setObject(*reobj);
         return true;
     }
 
-    RootedAtom source(cx);
-    if (sourceValue.isUndefined()) {
-        source = cx->runtime()->emptyString;
-    } else {
-        /* Coerce to string and compile. */
-        source = ToAtom<CanGC>(cx, sourceValue);
-        if (!source)
-            return false;
-    }
-
-    RegExpFlag flags = RegExpFlag(0);
-    if (args.hasDefined(1)) {
-        RootedString flagStr(cx, ToString<CanGC>(cx, args[1]));
-        if (!flagStr)
-            return false;
-        if (!ParseRegExpFlags(cx, flagStr, &flags))
-            return false;
-    }
-
-    CompileOptions options(cx);
-    frontend::TokenStream dummyTokenStream(cx, options, nullptr, 0, nullptr);
-
-    if (!irregexp::ParsePatternSyntax(dummyTokenStream, cx->tempLifoAlloc(), source))
-        return false;
-
-    if (staticsUse == UseRegExpStatics) {
-        RegExpStatics* res = cx->global()->getRegExpStatics(cx);
-        if (!res)
-            return false;
-        flags = RegExpFlag(flags | res->getFlags());
-    }
-    RegExpObject* reobj = builder.build(source, flags);
-    if (!reobj)
+    RootedObject reobj(cx);
+    if (!RegExpInitialize(cx, builder, sourceValue, args.get(1), UseRegExpStatics, &reobj))
         return false;
 
     args.rval().setObject(*reobj);
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 IsRegExpObject(HandleValue v)
@@ -287,17 +307,17 @@ js::IsRegExp(JSContext* cx, HandleValue 
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 regexp_compile_impl(JSContext* cx, CallArgs args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     RegExpObjectBuilder builder(cx, &args.thisv().toObject().as<RegExpObject>());
-    return CompileRegExpObject(cx, builder, args, UseRegExpStatics, CreateForCompile);
+    return CompileRegExpObject(cx, builder, args, CreateForCompile);
 }
 
 static bool
 regexp_compile(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsRegExpObject, regexp_compile_impl>(cx, args);
 }
@@ -318,31 +338,36 @@ js::regexp_construct(JSContext* cx, unsi
             !args.hasDefined(1))
         {
             args.rval().set(args[0]);
             return true;
         }
     }
 
     RegExpObjectBuilder builder(cx);
-    return CompileRegExpObject(cx, builder, args, UseRegExpStatics, CreateForConstruct);
+    return CompileRegExpObject(cx, builder, args, CreateForConstruct);
 }
 
 bool
 js::regexp_construct_no_statics(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     MOZ_ASSERT(args.length() == 1 || args.length() == 2);
     MOZ_ASSERT(args[0].isString());
     MOZ_ASSERT_IF(args.length() == 2, args[1].isString());
     MOZ_ASSERT(!args.isConstructing());
 
     RegExpObjectBuilder builder(cx);
-    return CompileRegExpObject(cx, builder, args, DontUseRegExpStatics, CreateForConstruct);
+    RootedObject reobj(cx);
+    if (!RegExpInitialize(cx, builder, args[0], args.get(1), DontUseRegExpStatics, &reobj))
+        return false;
+
+    args.rval().setObject(*reobj);
+    return true;
 }
 
 /* ES6 draft rev32 21.2.5.4. */
 MOZ_ALWAYS_INLINE bool
 regexp_global_impl(JSContext* cx, CallArgs args)
 {
     MOZ_ASSERT(IsRegExpObject(args.thisv()));
     Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());