summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/RegExp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/builtin/RegExp.cpp')
-rw-r--r--js/src/builtin/RegExp.cpp140
1 files changed, 84 insertions, 56 deletions
diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp
index 80a4bb5bd..b20f41c53 100644
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -577,14 +577,29 @@ js::regexp_clone(JSContext* cx, unsigned argc, Value* vp)
return true;
}
-/* ES6 draft rev32 21.2.5.4. */
+MOZ_ALWAYS_INLINE bool
+IsRegExpInstanceOrPrototype(HandleValue v)
+{
+ if (!v.isObject())
+ return false;
+
+ return StandardProtoKeyOrNull(&v.toObject()) == JSProto_RegExp;
+}
+
+// ES 2017 draft 21.2.5.4.
MOZ_ALWAYS_INLINE bool
regexp_global_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
- /* Steps 4-6. */
+ // Step 3.a.
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ // Steps 4-6.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
args.rval().setBoolean(reObj->global());
return true;
}
@@ -592,19 +607,25 @@ regexp_global_impl(JSContext* cx, const CallArgs& args)
bool
js::regexp_global(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-3. */
+ // Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_global_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_global_impl>(cx, args);
}
-/* ES6 draft rev32 21.2.5.5. */
+// ES 2017 draft 21.2.5.5.
MOZ_ALWAYS_INLINE bool
regexp_ignoreCase_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
- /* Steps 4-6. */
+ // Step 3.a
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ // Steps 4-6.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
args.rval().setBoolean(reObj->ignoreCase());
return true;
}
@@ -612,19 +633,25 @@ regexp_ignoreCase_impl(JSContext* cx, const CallArgs& args)
bool
js::regexp_ignoreCase(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-3. */
+ // Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_ignoreCase_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_ignoreCase_impl>(cx, args);
}
-/* ES6 draft rev32 21.2.5.7. */
+// ES 2017 draft 21.2.5.7.
MOZ_ALWAYS_INLINE bool
regexp_multiline_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
- /* Steps 4-6. */
+ // Step 3.a.
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ // Steps 4-6.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
args.rval().setBoolean(reObj->multiline());
return true;
}
@@ -632,24 +659,30 @@ regexp_multiline_impl(JSContext* cx, const CallArgs& args)
bool
js::regexp_multiline(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-3. */
+ // Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_multiline_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_multiline_impl>(cx, args);
}
-/* ES6 draft rev32 21.2.5.10. */
+// ES 2017 draft rev32 21.2.5.10.
MOZ_ALWAYS_INLINE bool
regexp_source_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
+
+ // Step 3.a.
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setString(cx->names().emptyRegExp);
+ return true;
+ }
- /* Step 5. */
+ // Step 5.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
RootedAtom src(cx, reObj->getSource());
if (!src)
return false;
- /* Step 7. */
+ // Step 7.
RootedString str(cx, EscapeRegExpPattern(cx, src));
if (!str)
return false;
@@ -661,19 +694,25 @@ regexp_source_impl(JSContext* cx, const CallArgs& args)
static bool
regexp_source(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-4. */
+ // Steps 1-4.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_source_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_source_impl>(cx, args);
}
-/* ES6 draft rev32 21.2.5.12. */
+// ES 2017 draft 21.2.5.12.
MOZ_ALWAYS_INLINE bool
regexp_sticky_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
- /* Steps 4-6. */
+ // Step 3.a.
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ // Steps 4-6.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
args.rval().setBoolean(reObj->sticky());
return true;
}
@@ -681,27 +720,35 @@ regexp_sticky_impl(JSContext* cx, const CallArgs& args)
bool
js::regexp_sticky(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-3. */
+ // Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_sticky_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_sticky_impl>(cx, args);
}
-/* ES6 21.2.5.15. */
+// ES 2017 draft 21.2.5.15.
MOZ_ALWAYS_INLINE bool
regexp_unicode_impl(JSContext* cx, const CallArgs& args)
{
- MOZ_ASSERT(IsRegExpObject(args.thisv()));
- /* Steps 4-6. */
- args.rval().setBoolean(args.thisv().toObject().as<RegExpObject>().unicode());
+ MOZ_ASSERT(IsRegExpInstanceOrPrototype(args.thisv()));
+
+ // Step 3.a.
+ if (!IsRegExpObject(args.thisv())) {
+ args.rval().setUndefined();
+ return true;
+ }
+
+ // Steps 4-6.
+ Rooted<RegExpObject*> reObj(cx, &args.thisv().toObject().as<RegExpObject>());
+ args.rval().setBoolean(reObj->unicode());
return true;
}
bool
js::regexp_unicode(JSContext* cx, unsigned argc, JS::Value* vp)
{
- /* Steps 1-3. */
+ // Steps 1-3.
CallArgs args = CallArgsFromVp(argc, vp);
- return CallNonGenericMethod<IsRegExpObject, regexp_unicode_impl>(cx, args);
+ return CallNonGenericMethod<IsRegExpInstanceOrPrototype, regexp_unicode_impl>(cx, args);
}
const JSPropertySpec js::regexp_properties[] = {
@@ -829,25 +876,6 @@ const JSPropertySpec js::regexp_static_props[] = {
JS_PS_END
};
-JSObject*
-js::CreateRegExpPrototype(JSContext* cx, JSProtoKey key)
-{
- MOZ_ASSERT(key == JSProto_RegExp);
-
- Rooted<RegExpObject*> proto(cx, cx->global()->createBlankPrototype<RegExpObject>(cx));
- if (!proto)
- return nullptr;
- proto->NativeObject::setPrivate(nullptr);
-
- if (!RegExpObject::assignInitialShape(cx, proto))
- return nullptr;
-
- RootedAtom source(cx, cx->names().empty);
- proto->initAndZeroLastIndex(source, RegExpFlag(0), cx);
-
- return proto;
-}
-
template <typename CharT>
static bool
IsTrailSurrogateWithLeadSurrogateImpl(JSContext* cx, HandleLinearString input, size_t index)